silgi 0.7.1 → 0.7.3

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.
Files changed (83) hide show
  1. package/dist/_chunks/index.mjs +5 -0
  2. package/dist/cli/{utils/compatibility.mjs → compatibility.mjs} +1 -1
  3. package/dist/cli/config/index.d.mts +11 -0
  4. package/dist/cli/config/index.d.ts +11 -0
  5. package/dist/{core/config/types.mjs → cli/config/index.mjs} +19 -2
  6. package/dist/cli/index.mjs +3 -3
  7. package/dist/cli/loader.mjs +581 -0
  8. package/dist/cli/prepare.mjs +1621 -0
  9. package/dist/core/index.d.mts +2 -37
  10. package/dist/core/index.d.ts +2 -37
  11. package/dist/core/index.mjs +809 -16
  12. package/dist/ecosystem/nitro/index.mjs +62 -1
  13. package/dist/ecosystem/nuxt/module.mjs +1 -1
  14. package/dist/kit/index.mjs +299 -10
  15. package/dist/meta/index.d.mts +1 -1
  16. package/dist/meta/index.d.ts +1 -1
  17. package/dist/meta/index.mjs +1 -1
  18. package/package.json +5 -1
  19. package/dist/cli/build/framework/h3.mjs +0 -46
  20. package/dist/cli/build/framework/index.mjs +0 -7
  21. package/dist/cli/build/framework/nitro.mjs +0 -28
  22. package/dist/cli/build/framework/nuxt.mjs +0 -9
  23. package/dist/cli/build/prepare.mjs +0 -7
  24. package/dist/cli/build/scanURIs.mjs +0 -27
  25. package/dist/cli/build/template/framework.mjs +0 -91
  26. package/dist/cli/build/template/schema.mjs +0 -115
  27. package/dist/cli/build/template/silgi.mjs +0 -149
  28. package/dist/cli/build/types.mjs +0 -130
  29. package/dist/cli/commands/prepare.mjs +0 -49
  30. package/dist/cli/common.mjs +0 -13
  31. package/dist/cli/core/app.mjs +0 -89
  32. package/dist/cli/core/scan.mjs +0 -40
  33. package/dist/cli/core/silgi.mjs +0 -77
  34. package/dist/cli/core/storage.mjs +0 -11
  35. package/dist/cli/core/templates.mjs +0 -29
  36. package/dist/cli/module/exportScan.mjs +0 -69
  37. package/dist/cli/module/install.mjs +0 -52
  38. package/dist/cli/module/scan.mjs +0 -141
  39. package/dist/cli/utils/generateRouterDTS.mjs +0 -84
  40. package/dist/cli/utils/ignore.mjs +0 -46
  41. package/dist/cli/utils/readCoreFile.mjs +0 -47
  42. package/dist/cli/utils/scan.mjs +0 -147
  43. package/dist/cli/utils/storage.mjs +0 -21
  44. package/dist/cli/utils/uri.mjs +0 -71
  45. package/dist/core/config/defaults.mjs +0 -96
  46. package/dist/core/config/loader.mjs +0 -98
  47. package/dist/core/config/resolvers/compatibility.mjs +0 -90
  48. package/dist/core/config/resolvers/imports.mjs +0 -96
  49. package/dist/core/config/resolvers/paths.mjs +0 -194
  50. package/dist/core/config/resolvers/storage.mjs +0 -25
  51. package/dist/core/config/resolvers/url.mjs +0 -7
  52. package/dist/core/createSilgi.mjs +0 -84
  53. package/dist/core/error.mjs +0 -227
  54. package/dist/core/fetch/ofetch.mjs +0 -35
  55. package/dist/core/parser.mjs +0 -136
  56. package/dist/core/silgi.mjs +0 -114
  57. package/dist/core/silgiApp.mjs +0 -15
  58. package/dist/core/unctx.mjs +0 -27
  59. package/dist/core/uris/uri.mjs +0 -33
  60. package/dist/core/uris/utils.mjs +0 -127
  61. package/dist/core/utils/event.mjs +0 -5
  62. package/dist/core/utils/global.mjs +0 -12
  63. package/dist/core/utils/merge.mjs +0 -25
  64. package/dist/core/utils/schema.mjs +0 -5
  65. package/dist/core/utils/service.mjs +0 -5
  66. package/dist/core/utils/shared.mjs +0 -5
  67. package/dist/core/utils/storage.mjs +0 -70
  68. package/dist/ecosystem/nitro/module.mjs +0 -62
  69. package/dist/kit/esm.mjs +0 -10
  70. package/dist/kit/fs.mjs +0 -25
  71. package/dist/kit/isFramework.mjs +0 -25
  72. package/dist/kit/logger.mjs +0 -8
  73. package/dist/kit/module.mjs +0 -73
  74. package/dist/kit/path.mjs +0 -34
  75. package/dist/kit/preset.mjs +0 -6
  76. package/dist/kit/resolve.mjs +0 -78
  77. package/dist/kit/template.mjs +0 -47
  78. package/dist/kit/utils.mjs +0 -20
  79. package/dist/package.json.mjs +0 -5
  80. package/dist/schema/common.mjs +0 -43
  81. package/dist/schema/index.mjs +0 -9
  82. package/dist/schema/internal.mjs +0 -22
  83. /package/dist/cli/{commands/init.mjs → init.mjs} +0 -0
@@ -0,0 +1,1621 @@
1
+ import { defineCommand } from 'citty';
2
+ import { join, resolve, isAbsolute, relative, dirname, basename, extname } from 'pathe';
3
+ import { version } from 'silgi/meta';
4
+ import { runtimeDir } from 'silgi/runtime/meta';
5
+ import { promises, existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
6
+ import { readdir } from 'node:fs/promises';
7
+ import { resolvePath, parseNodeModulePath, lookupNodeModuleSubpath, resolve as resolve$1 } from 'mlly';
8
+ import { resolveAlias } from 'pathe/utils';
9
+ import { silgiGenerateType, useSilgiCLI, 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
+ import { readPackageJSON } from 'pkg-types';
14
+ import { hash } from 'ohash';
15
+ import { consola } from 'consola';
16
+ import { createHooks, createDebugger } from 'hookable';
17
+ import { pascalCase } from 'scule';
18
+ import { h as hasInstalledModule } from './compatibility.mjs';
19
+ import { pathToFileURL, fileURLToPath } from 'node:url';
20
+ import { isRelative, withTrailingSlash } from 'ufo';
21
+ import { globby } from 'globby';
22
+ import ignore from 'ignore';
23
+ import { parseSync } from '@oxc-parser/wasm';
24
+ import { klona } from 'klona';
25
+ import { createStorage, builtinDrivers } from 'unstorage';
26
+ import { l as loadOptions } from './loader.mjs';
27
+ import 'semver/functions/satisfies.js';
28
+ import 'c12';
29
+ import 'compatx';
30
+ import 'klona/full';
31
+ import 'std-env';
32
+ import 'consola/utils';
33
+ import 'escape-string-regexp';
34
+
35
+ async function h3Framework(silgi, skip = false) {
36
+ if (silgi.options.preset !== "h3" && skip === false)
37
+ return;
38
+ if (silgi.options.preset === "h3") {
39
+ silgi.hook("after:prepare:schema.ts", (data) => {
40
+ data.unshift("type FrameworkContextExtends = NitroApp");
41
+ });
42
+ }
43
+ silgi.hook("prepare:schema.ts", (data) => {
44
+ data.importItems.nitropack = {
45
+ import: [
46
+ { name: "NitroApp", type: true }
47
+ ],
48
+ from: "nitropack/types"
49
+ };
50
+ data.importItems.h3 = {
51
+ import: [
52
+ { name: "H3Event", type: true }
53
+ ],
54
+ from: "h3"
55
+ };
56
+ data.events.push({
57
+ key: "H3Event",
58
+ value: "H3Event",
59
+ extends: true,
60
+ isSilgiContext: false
61
+ });
62
+ });
63
+ silgi.hook("prepare:createDTSFramework", (data) => {
64
+ data.importItems["silgi/types"] = {
65
+ import: [
66
+ { name: "ModuleRuntimeContext", type: true }
67
+ ],
68
+ from: "silgi/types"
69
+ };
70
+ data.customContent?.push(
71
+ "",
72
+ 'declare module "h3" {',
73
+ " interface H3EventContext extends ModuleRuntimeContext {}",
74
+ "}",
75
+ ""
76
+ );
77
+ });
78
+ }
79
+
80
+ async function nitroFramework(silgi, skip = false) {
81
+ if (silgi.options.preset !== "nitro" && skip === false)
82
+ return;
83
+ silgi.hook("prepare:schema.ts", (data) => {
84
+ data.importItems.nitropack = {
85
+ import: [
86
+ { name: "NitroApp", type: true }
87
+ ],
88
+ from: "nitropack/types"
89
+ };
90
+ });
91
+ silgi.hook("after:prepare:schema.ts", (data) => {
92
+ data.unshift("type FrameworkContextExtends = NitroApp");
93
+ });
94
+ silgi.options.plugins.push({
95
+ packageImport: "silgi/runtime/internal/nitro",
96
+ path: join(runtimeDir, "internal/nitro")
97
+ });
98
+ silgi.hook("prepare:core.ts", (_data) => {
99
+ });
100
+ await h3Framework(silgi, true);
101
+ }
102
+
103
+ async function nuxtFramework(silgi, skip = false) {
104
+ if (silgi.options.preset !== "nuxt" && skip === false)
105
+ return;
106
+ await nitroFramework(silgi, true);
107
+ }
108
+
109
+ const frameworkSetup = [h3Framework, nitroFramework, nuxtFramework];
110
+
111
+ async function prepare$1(_silgi) {
112
+ }
113
+
114
+ async function generateSilgiStorageBaseType(silgi) {
115
+ silgi.hook("prepare:schema.ts", async (options) => {
116
+ if (silgi.options.storage) {
117
+ for (const [key, _value] of Object.entries(silgi.options.storage)) {
118
+ options.storeBase.push(key);
119
+ }
120
+ }
121
+ });
122
+ }
123
+
124
+ async function generateRouterDTS(silgi) {
125
+ silgi.hook("finish:types", async (data) => {
126
+ const uris = data.object.uris;
127
+ const subPath = "srn";
128
+ const groupedPaths = /* @__PURE__ */ new Map();
129
+ Object.entries(uris || {}).forEach(([key, params]) => {
130
+ const [service, resource, method, action] = key.split("/");
131
+ const basePath = params ? `${subPath}/${service}/${resource}/${action}/${params}` : `${subPath}/${service}/${resource}/${action}`;
132
+ const fullPath = `${subPath}/${service}/${resource}/${action}`;
133
+ if (!groupedPaths.has(basePath)) {
134
+ groupedPaths.set(basePath, /* @__PURE__ */ new Map());
135
+ }
136
+ groupedPaths.get(basePath)?.set(method.toLowerCase(), fullPath);
137
+ });
138
+ const keys = [
139
+ " keys: {",
140
+ Array.from(groupedPaths.entries()).map(([basePath, methods]) => {
141
+ return ` '/${basePath}': {${Array.from(methods.entries()).map(([method, path]) => `
142
+ ${method}: '/${path}'`).join(",")}
143
+ }`;
144
+ }).join(",\n"),
145
+ " }",
146
+ ""
147
+ ].join("\n");
148
+ const groupedRoutes = Object.entries(uris || {}).reduce((acc, [key, _params]) => {
149
+ const [service, resource, method, action] = key.split("/");
150
+ const routePath = `${subPath}/${service}/${resource}/${action}`;
151
+ if (!acc[routePath]) {
152
+ acc[routePath] = {};
153
+ }
154
+ acc[routePath][method] = {
155
+ input: `ExtractInputFromURI<'${key}'>`,
156
+ output: `ExtractOutputFromURI<'${key}'>`,
157
+ params: `ExtractRouterParamsFromURI<'${key}'>['params']`
158
+ };
159
+ return acc;
160
+ }, {});
161
+ const routerTypes = Object.entries(groupedRoutes).map(([path, methods]) => {
162
+ const methodEntries = Object.entries(methods).map(([method, { input, output, params }]) => {
163
+ return ` '${method}': {
164
+ input: ${input},
165
+ output: ${output}
166
+ params: ${params}
167
+ }`;
168
+ }).join(",\n");
169
+ return ` '/${path}': {
170
+ ${methodEntries}
171
+ }`;
172
+ });
173
+ const nitro = [
174
+ "declare module 'nitropack/types' {",
175
+ " interface InternalApi extends RouterTypes {}",
176
+ "}"
177
+ ];
178
+ const content = [
179
+ keys.slice(0, -1),
180
+ // son satırdaki boş satırı kaldır
181
+ ...routerTypes
182
+ ].join(",\n");
183
+ const context = [
184
+ "import type { ExtractInputFromURI, ExtractOutputFromURI, ExtractRouterParamsFromURI } from 'silgi/types'",
185
+ "",
186
+ "export interface RouterTypes {",
187
+ content,
188
+ "}",
189
+ "",
190
+ "declare module 'silgi/types' {",
191
+ " interface SilgiRouterTypes extends RouterTypes {",
192
+ " }",
193
+ "}",
194
+ "",
195
+ silgi.options.preset === "h3" || silgi.options.preset === "nitro" ? nitro.join("\n") : "",
196
+ "",
197
+ "export {}"
198
+ ].join("\n");
199
+ const outputPath = resolve(silgi.options.build.typesDir, "silgi-routes.d.ts");
200
+ await promises.writeFile(outputPath, context);
201
+ });
202
+ }
203
+
204
+ async function readCoreFile(silgi) {
205
+ const path = resolve(silgi.options.silgi.serverDir, "core.ts");
206
+ const context = await promises.readFile(path, { encoding: "utf-8" });
207
+ const injectedResult = await silgi.unimport.injectImports(context, path);
208
+ if (!injectedResult) {
209
+ throw new Error("Failed to inject imports");
210
+ }
211
+ const jiti = createJiti(silgi.options.rootDir, {
212
+ fsCache: false,
213
+ moduleCache: false,
214
+ debug: silgi.options.debug,
215
+ alias: silgi.options.alias
216
+ });
217
+ const coreFile = await jiti.evalModule(
218
+ injectedResult.code,
219
+ {
220
+ filename: path,
221
+ async: true,
222
+ conditions: silgi.options.conditions
223
+ },
224
+ async (data, name) => {
225
+ return (await silgi.unimport.injectImports(data, name)).code;
226
+ }
227
+ );
228
+ silgi.uris = coreFile.uris;
229
+ silgi.schemas = coreFile.schemas;
230
+ silgi.services = coreFile.services;
231
+ silgi.shareds = coreFile.shareds;
232
+ silgi.modulesURIs = coreFile.modulesURIs;
233
+ return {
234
+ context,
235
+ object: {
236
+ schemas: coreFile.schemas,
237
+ uris: coreFile.uris,
238
+ services: coreFile.services,
239
+ shareds: coreFile.shareds,
240
+ modulesURIs: coreFile.modulesURIs
241
+ },
242
+ path
243
+ };
244
+ }
245
+
246
+ function traverseObject(silgi, obj, currentPath = []) {
247
+ const uriMap = /* @__PURE__ */ new Map();
248
+ function traverse(node, path = []) {
249
+ if (!node || typeof node !== "object")
250
+ return;
251
+ if (path.length === 4) {
252
+ const basePath = path.join("/");
253
+ let paramString = "";
254
+ if (node.router) {
255
+ let params = null;
256
+ if (node.router?._def?.typeName !== void 0) {
257
+ try {
258
+ const shape = node.router?.shape?.params?.shape;
259
+ params = shape ? Object.keys(shape) : null;
260
+ } catch {
261
+ params = null;
262
+ }
263
+ }
264
+ if (params?.length) {
265
+ paramString = params.map((p) => `:${p}`).join("/");
266
+ }
267
+ }
268
+ uriMap.set(basePath, paramString);
269
+ return;
270
+ }
271
+ for (const key in node) {
272
+ if (!["_type", "fields"].includes(key)) {
273
+ traverse(node[key], [...path, key]);
274
+ }
275
+ }
276
+ }
277
+ traverse(obj, currentPath);
278
+ return uriMap;
279
+ }
280
+ function scanActionModulesUris(silgi, obj, currentPath = []) {
281
+ const uriMap = {};
282
+ function traverse(node, path = []) {
283
+ if (!node || typeof node !== "object")
284
+ return;
285
+ if (path.length === 4) {
286
+ const basePath = path.join("/");
287
+ let moduleName = "";
288
+ if (node.modules?.yoga) {
289
+ let rootFieldName = null;
290
+ if (node.modules?.yoga?.rootFieldName) {
291
+ moduleName = "yoga";
292
+ rootFieldName = node.modules?.yoga?.rootFieldName;
293
+ }
294
+ if (!rootFieldName) {
295
+ return;
296
+ }
297
+ uriMap[moduleName] ??= {};
298
+ if (uriMap[moduleName].rootFieldName) {
299
+ silgi.logger.withTag("scanActionModulesUris").error(`Hata ${moduleName} ${rootFieldName} ${basePath} bu zaten burada kullanilmis.`);
300
+ }
301
+ uriMap[moduleName].rootFieldName ??= {};
302
+ uriMap[moduleName].rootFieldName[rootFieldName] = basePath;
303
+ }
304
+ return;
305
+ }
306
+ for (const key in node) {
307
+ if (!["_type", "fields"].includes(key)) {
308
+ traverse(node[key], [...path, key]);
309
+ }
310
+ }
311
+ }
312
+ traverse(obj, currentPath);
313
+ return uriMap;
314
+ }
315
+
316
+ async function scanUris(silgi) {
317
+ const { context, object, path } = await readCoreFile(silgi);
318
+ const uriMap = traverseObject(silgi, object.schemas, []);
319
+ const modulesURIs = scanActionModulesUris(silgi, object.services, []);
320
+ const uriContent = Array.from(uriMap.entries()).map(([uri, params]) => ` '${uri}': '${params}',`).join("\n");
321
+ let newContext = "";
322
+ if (uriMap.size > 0) {
323
+ newContext = context.replace(
324
+ /export const uris = \{[^}]*\}/,
325
+ `export const uris = {
326
+ ${uriContent}
327
+ }`
328
+ ).replace(
329
+ /export const modulesURIs = \{[^}]*\}/,
330
+ `export const modulesURIs = ${JSON.stringify(modulesURIs, null, 2)}`
331
+ );
332
+ } else {
333
+ newContext = context;
334
+ }
335
+ await promises.writeFile(path, newContext);
336
+ }
337
+
338
+ async function createCoreFramework(silgi) {
339
+ const relativeRootDir = relativeWithDot(silgi.options.rootDir, silgi.options.serverDir);
340
+ if (silgi.options.preset !== "nitro" && silgi.options.preset !== "h3")
341
+ return;
342
+ const importItems = {
343
+ "silgi/types": {
344
+ import: [
345
+ { name: "ModuleRuntimeContext", type: true }
346
+ ],
347
+ from: "silgi/types"
348
+ }
349
+ };
350
+ await Promise.all([...silgi.options.modules, ...silgi.options._modules].map(async (id) => {
351
+ if (typeof id !== "string") {
352
+ return;
353
+ }
354
+ const pkg = await readPackageJSON(id, { url: silgi.options.modulesDir }).catch(() => null);
355
+ if (!pkg?.name) {
356
+ return;
357
+ }
358
+ if (importItems[pkg.name]) {
359
+ importItems[pkg.name].from = isAbsolute(id) ? relativeWithDot(relativeRootDir, id) : id;
360
+ }
361
+ }));
362
+ const customImports = [];
363
+ const functions = [];
364
+ await silgi.callHook("prepare:createCoreFramework", {
365
+ importItems,
366
+ customImports,
367
+ functions
368
+ });
369
+ const content = [
370
+ ...functions.map((f) => f.params?.length ? ` await ${f.name}(framework, ${f.params.join(",")})` : ` await ${f.name}(framework)`)
371
+ ];
372
+ return {
373
+ content,
374
+ importItems,
375
+ customImports
376
+ };
377
+ }
378
+ async function createDTSFramework(silgi) {
379
+ const relativeRootDir = relativeWithDot(silgi.options.rootDir, silgi.options.serverDir);
380
+ const importItems = {
381
+ "silgi/types": {
382
+ import: [
383
+ { name: "ModuleRuntimeContext", type: true }
384
+ ],
385
+ from: "silgi/types"
386
+ }
387
+ };
388
+ await Promise.all([...silgi.options.modules, ...silgi.options._modules].map(async (id) => {
389
+ if (typeof id !== "string") {
390
+ return;
391
+ }
392
+ const pkg = await readPackageJSON(id, { url: silgi.options.modulesDir }).catch(() => null);
393
+ if (!pkg?.name) {
394
+ return;
395
+ }
396
+ if (importItems[pkg.name]) {
397
+ importItems[pkg.name].from = isAbsolute(id) ? relativeWithDot(relativeRootDir, id) : id;
398
+ }
399
+ }));
400
+ const customImports = [];
401
+ const customContent = [];
402
+ await silgi.callHook("prepare:createDTSFramework", {
403
+ importItems,
404
+ customImports,
405
+ customContent
406
+ });
407
+ const content = [
408
+ ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
409
+ const path = isAbsolute(from) ? relativeWithDot(silgi.options.build.typesDir, from) : from;
410
+ return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${path}'`;
411
+ }),
412
+ "",
413
+ ...customImports,
414
+ "",
415
+ ...customContent,
416
+ ""
417
+ ];
418
+ return {
419
+ content,
420
+ importItems
421
+ };
422
+ }
423
+
424
+ async function schemaTemplate(silgi) {
425
+ const relativeRootDir = relativeWithDot(silgi.options.rootDir, silgi.options.serverDir);
426
+ const importItems = {
427
+ "silgi/types": {
428
+ import: [
429
+ { name: "URIsTypes", type: true },
430
+ { name: "Namespaces", type: true },
431
+ { name: "ModuleRuntimeContext", type: true }
432
+ ],
433
+ from: "silgi/types"
434
+ }
435
+ };
436
+ await Promise.all([...silgi.options.modules, ...silgi.options._modules].map(async (id) => {
437
+ if (typeof id !== "string") {
438
+ return;
439
+ }
440
+ const pkg = await readPackageJSON(id, { url: silgi.options.modulesDir }).catch(() => null);
441
+ if (!pkg?.name) {
442
+ return;
443
+ }
444
+ if (importItems[pkg.name]) {
445
+ importItems[pkg.name].from = isAbsolute(id) ? relativeWithDot(relativeRootDir, id) : id;
446
+ }
447
+ }));
448
+ const data = {
449
+ importItems,
450
+ customImports: [],
451
+ configs: [],
452
+ contexts: [],
453
+ methods: [],
454
+ shareds: [],
455
+ events: [],
456
+ storeBase: [],
457
+ hooks: [],
458
+ runtimeHooks: []
459
+ };
460
+ const storeBase = [];
461
+ await silgi.callHook("prepare:schema.ts", data);
462
+ const silgiExport = relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/core.ts`);
463
+ let addSilgiContext = false;
464
+ const importsContent = [
465
+ ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
466
+ const path = isAbsolute(from) ? relativeWithDot(silgi.options.build.typesDir, from) : from;
467
+ return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${path}'`;
468
+ }),
469
+ "",
470
+ ...data.customImports,
471
+ ""
472
+ ];
473
+ const importData = [
474
+ "interface InferredNamespaces {",
475
+ ...(silgi.options.namespaces || []).map((key) => ` ${key}: string,`),
476
+ "}",
477
+ "",
478
+ `type SchemaExtends = Namespaces<typeof import('${silgiExport}')['schemas']>`,
479
+ "",
480
+ `type SilgiURIsMerge = URIsTypes<typeof import('${silgiExport}')['uris']>`,
481
+ "",
482
+ `type SilgiModuleContextExtends = ${data.contexts.length ? data.contexts.map(({ value }) => value).join(" & ") : "{}"}`,
483
+ "",
484
+ data.events.length ? `interface SilgiModuleEventsExtends extends ${data.events.map((item) => item.extends ? item.value : "").join(", ")} {
485
+ ${data.events.map((item) => {
486
+ if (item.isSilgiContext) {
487
+ addSilgiContext = true;
488
+ }
489
+ return !item.extends && !addSilgiContext ? ` ${item.key}: ${item.value}` : item.isSilgiContext ? " context: ModuleRuntimeContext" : "";
490
+ }).join(",\n")}
491
+ }` : "interface SilgiModuleEventsExtends {}",
492
+ "",
493
+ data.shareds.length ? `type SilgiModuleSharedExtends = ${data.shareds.map(({ value }) => value).join(" & ")}` : "type SilgiModuleSharedExtends = {}",
494
+ "",
495
+ "interface SilgiModuleMethodsExtends {",
496
+ ...(data.methods || []).map(({ key, value }) => ` ${key}: ${value},`),
497
+ "}",
498
+ "",
499
+ "interface SilgiModuleOptionsExtends {",
500
+ ...(data.configs || []).map(({ key, value }) => ` ${key}: ${value},`),
501
+ "}",
502
+ "",
503
+ "interface SilgiStorageBaseExtends {",
504
+ ...(storeBase || []).map((value) => ` ${value}: ''`),
505
+ "}",
506
+ "",
507
+ `type ModuleHooksExtend = ${data.hooks?.length ? data.hooks.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
508
+ "",
509
+ `type SilgiRuntimeHooksExtends = ${data.runtimeHooks?.length ? data.runtimeHooks.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
510
+ "",
511
+ "declare module 'silgi/types' {",
512
+ " interface FrameworkContext extends FrameworkContextExtends {}",
513
+ " interface SilgiSchema extends SchemaExtends {}",
514
+ " interface SilgiNamespaces extends InferredNamespaces {}",
515
+ " interface SilgiStorageBase extends SilgiStorageBaseExtends {}",
516
+ " interface SilgiModules extends SilgiModuleOptionsExtends {}",
517
+ " interface SilgiURIs extends SilgiURIsMerge {}",
518
+ " interface ModuleRuntimeContext extends SilgiModuleContextExtends {}",
519
+ " interface SilgiEvent extends SilgiModuleEventsExtends {}",
520
+ " interface SilgiDefaultShared extends SilgiModuleSharedExtends {}",
521
+ " interface ModuleRuntimeMethods extends SilgiModuleMethodsExtends {}",
522
+ " interface ModuleOptions extends SilgiModuleOptionsExtends {}",
523
+ " interface ModuleRuntimeHooks extends SilgiRuntimeHooksExtends {}",
524
+ " interface ModuleHooks extends ModuleHooksExtend {}",
525
+ "}",
526
+ "",
527
+ "export {}"
528
+ ];
529
+ await silgi.callHook("after:prepare:schema.ts", importData);
530
+ importData.unshift(...importsContent);
531
+ return importData;
532
+ }
533
+
534
+ async function silgiCoreFile(data, frameworkContext, silgi) {
535
+ const relativeRootDir = relativeWithDot(silgi.options.rootDir, silgi.options.serverDir);
536
+ let importItems = {
537
+ "silgi/core": {
538
+ import: [
539
+ { name: "createSilgi" }
540
+ ],
541
+ from: "silgi/core"
542
+ },
543
+ "silgi/types": {
544
+ import: [
545
+ { name: "ModuleOptions", type: true },
546
+ { name: "SilgiOptions", type: true },
547
+ { name: "FrameworkContext", type: true },
548
+ { name: "DeepPartial", type: true },
549
+ { name: "BuildConfig", type: true }
550
+ ],
551
+ from: "silgi/types"
552
+ },
553
+ "#silgi/vfs": {
554
+ import: [],
555
+ from: "./vfs"
556
+ }
557
+ };
558
+ importItems = { ...data._importItems, ...importItems };
559
+ await Promise.all([...silgi.options.modules, ...silgi.options._modules].map(async (id) => {
560
+ if (typeof id !== "string") {
561
+ return;
562
+ }
563
+ const pkg = await readPackageJSON(id, { url: silgi.options.modulesDir }).catch(() => null);
564
+ if (!pkg?.name) {
565
+ return;
566
+ }
567
+ if (importItems[pkg.name]) {
568
+ importItems[pkg.name].from = isAbsolute(id) ? relativeWithDot(relativeRootDir, id) : id;
569
+ }
570
+ }));
571
+ const customImports = data._customImports || [];
572
+ const uris = [];
573
+ const services = [];
574
+ const shareds = [];
575
+ const schemas = [];
576
+ const buildSilgiExtraContent = [];
577
+ const _silgiOptions = {};
578
+ const _silgiConfigs = [];
579
+ for (const module of silgi.scanModules) {
580
+ _silgiOptions[module.meta.configKey] = {
581
+ ...module.options
582
+ };
583
+ }
584
+ await silgi.callHook("prepare:core.ts", {
585
+ importItems,
586
+ customImports,
587
+ uris,
588
+ services,
589
+ shareds,
590
+ schemas,
591
+ buildSilgiExtraContent,
592
+ _silgiOptions,
593
+ _silgiConfigs
594
+ });
595
+ if (importItems["#silgi/vfs"].import.length === 0) {
596
+ delete importItems["#silgi/vfs"];
597
+ }
598
+ if (services.length > 0) {
599
+ importItems["silgi/core"].import.push({ name: "mergeServices" });
600
+ }
601
+ if (shareds.length > 0) {
602
+ importItems["silgi/core"].import.push({ name: "mergeShared" });
603
+ }
604
+ if (schemas.length > 0) {
605
+ importItems["silgi/core"].import.push({ name: "mergeSchemas" });
606
+ }
607
+ const plugins = [];
608
+ for (const plugin of silgi.options.plugins) {
609
+ const pluginImportName = `_${hash(plugin.packageImport)}`;
610
+ customImports.push(`import ${pluginImportName} from '${plugin.packageImport}'`);
611
+ plugins.push(pluginImportName);
612
+ }
613
+ const importsContent = [
614
+ ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
615
+ return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
616
+ }),
617
+ "",
618
+ ...customImports,
619
+ ""
620
+ ];
621
+ const importData = [
622
+ "export const uris = {}",
623
+ "",
624
+ "export const modulesURIs = {}",
625
+ "",
626
+ schemas.length > 0 ? "export const schemas = mergeSchemas([" : "export const schemas = {",
627
+ ...schemas.map((name) => {
628
+ return ` ${name},`;
629
+ }),
630
+ schemas.length > 0 ? "])" : "}",
631
+ "",
632
+ services.length > 0 ? "export const services = mergeServices([" : "export const services = {",
633
+ ...services.map((name) => {
634
+ return ` ${name},`;
635
+ }),
636
+ services.length > 0 ? "])" : "}",
637
+ "",
638
+ shareds.length > 0 ? "export const shareds = mergeShared([" : "export const shareds = {",
639
+ ...shareds.map((name) => {
640
+ return ` ${name},`;
641
+ }),
642
+ shareds.length > 0 ? "])" : "}",
643
+ "",
644
+ `export const _silgiOptions: DeepPartial<ModuleOptions> = ${JSON.stringify(_silgiOptions, null, 2)}`,
645
+ "",
646
+ "export async function buildSilgi(framework: FrameworkContext, moduleOptions?: Partial<ModuleOptions>,buildOptions?: Partial<BuildConfig>, ) {",
647
+ " const silgi = await createSilgi({",
648
+ " framework,",
649
+ " shared: shareds as any,",
650
+ " services: services as any,",
651
+ " schemas: schemas as any,",
652
+ " uris,",
653
+ " modulesURIs,",
654
+ ` plugins: [${plugins.join(", ")}],`,
655
+ _silgiConfigs.length > 0 ? ` ${_silgiConfigs.map((config) => Object.entries(config).map(([key, value]) => `${key}: ${value}`)).join(",\n ")},` : "",
656
+ " ...buildOptions,",
657
+ " options: {",
658
+ ` present: '${silgi.options.preset}',`,
659
+ " ..._silgiOptions,",
660
+ " ...moduleOptions,",
661
+ " },",
662
+ " })",
663
+ "",
664
+ ...frameworkContext,
665
+ "",
666
+ ...buildSilgiExtraContent,
667
+ "",
668
+ " return silgi",
669
+ "}",
670
+ ""
671
+ ];
672
+ await silgi.callHook("after:prepare:core.ts", importData);
673
+ importData.unshift(...importsContent);
674
+ return importData;
675
+ }
676
+
677
+ async function writeTypesAndFiles(silgi) {
678
+ const data = await createCoreFramework(silgi);
679
+ await generateSilgiStorageBaseType(silgi);
680
+ await generateRouterDTS(silgi);
681
+ silgi.hook("prepare:types", (opts) => {
682
+ opts.references.push({ path: "./schema.d.ts" });
683
+ opts.references.push({ path: "./silgi-routes.d.ts" });
684
+ opts.references.push({ path: "./framework.d.ts" });
685
+ });
686
+ const schemaContent = await schemaTemplate(silgi);
687
+ const coreContent = await silgiCoreFile({
688
+ _importItems: data?.importItems ?? {},
689
+ _customImports: data?.customImports ?? []
690
+ }, data?.content ?? [], silgi);
691
+ const frameworkDTS = await createDTSFramework(silgi);
692
+ const { declarations, tsConfig } = await silgiGenerateType(silgi);
693
+ const tsConfigPath = resolve(
694
+ silgi.options.typescript.generateTsConfig ? silgi.options.build.dir : silgi.options.rootDir,
695
+ silgi.options.typescript.tsconfigPath
696
+ );
697
+ const typesDir = resolve(silgi.options.build.typesDir);
698
+ const silgiDir = resolve(silgi.options.silgi.serverDir);
699
+ let autoImportedTypes = [];
700
+ let autoImportExports = "";
701
+ if (silgi.unimport) {
702
+ await silgi.unimport.init();
703
+ const allImports = await silgi.unimport.getImports();
704
+ autoImportExports = toExports(allImports).replace(
705
+ /#internal\/nitro/g,
706
+ relative(typesDir, runtimeDir)
707
+ );
708
+ const resolvedImportPathMap = /* @__PURE__ */ new Map();
709
+ for (const i of allImports.filter((i2) => !i2.type)) {
710
+ if (resolvedImportPathMap.has(i.from)) {
711
+ continue;
712
+ }
713
+ let path = resolveAlias(i.from, silgi.options.alias);
714
+ if (isAbsolute(path)) {
715
+ const resolvedPath = await resolvePath(i.from, {
716
+ url: silgi.options.nodeModulesDirs
717
+ }).catch(() => null);
718
+ if (resolvedPath) {
719
+ const { dir, name } = parseNodeModulePath(resolvedPath);
720
+ if (!dir || !name) {
721
+ path = resolvedPath;
722
+ } else {
723
+ const subpath = await lookupNodeModuleSubpath(resolvedPath);
724
+ path = join(dir, name, subpath || "");
725
+ }
726
+ }
727
+ }
728
+ if (existsSync(path) && !await isDirectory(path)) {
729
+ path = path.replace(/\.[a-z]+$/, "");
730
+ }
731
+ if (isAbsolute(path)) {
732
+ path = relative(typesDir, path);
733
+ }
734
+ resolvedImportPathMap.set(i.from, path);
735
+ }
736
+ autoImportedTypes = [
737
+ silgi.options.imports && silgi.options.imports.autoImport !== false ? (await silgi.unimport.generateTypeDeclarations({
738
+ exportHelper: false,
739
+ resolvePath: (i) => resolvedImportPathMap.get(i.from) ?? i.from
740
+ })).trim() : ""
741
+ ];
742
+ }
743
+ const buildFiles = [];
744
+ buildFiles.push({
745
+ path: join(typesDir, "silgi-routes.d.ts"),
746
+ // contents: uris.join('\n'),
747
+ contents: ""
748
+ });
749
+ buildFiles.push({
750
+ path: join(silgiDir, "core.ts"),
751
+ contents: coreContent.join("\n")
752
+ });
753
+ buildFiles.push({
754
+ path: join(typesDir, "schema.d.ts"),
755
+ contents: schemaContent.join("\n")
756
+ });
757
+ buildFiles.push({
758
+ path: join(typesDir, "silgi-imports.d.ts"),
759
+ contents: [...autoImportedTypes, autoImportExports || "export {}"].join(
760
+ "\n"
761
+ )
762
+ });
763
+ buildFiles.push({
764
+ path: join(typesDir, "silgi.d.ts"),
765
+ contents: declarations.join("\n")
766
+ });
767
+ buildFiles.push({
768
+ path: tsConfigPath,
769
+ contents: JSON.stringify(tsConfig, null, 2)
770
+ });
771
+ buildFiles.push({
772
+ path: join(typesDir, "framework.d.ts"),
773
+ contents: frameworkDTS.content.join("\n")
774
+ });
775
+ for await (const file of buildFiles) {
776
+ await writeFile(
777
+ resolve(silgi.options.build.dir, file.path),
778
+ file.contents
779
+ );
780
+ }
781
+ await scanUris(silgi);
782
+ const readCore = await readCoreFile(silgi);
783
+ silgi.uris = readCore.object.uris;
784
+ silgi.modulesURIs = readCore.object.modulesURIs;
785
+ silgi.schemas = readCore.object.schemas;
786
+ silgi.shareds = readCore.object.shareds;
787
+ await silgi.hooks.callHook("finish:types", readCore);
788
+ }
789
+
790
+ const commonArgs = {
791
+ dir: {
792
+ type: "string",
793
+ description: "project root directory"
794
+ },
795
+ _dir: {
796
+ type: "positional",
797
+ default: ".",
798
+ description: "project root directory (prefer using `--dir`)"
799
+ }
800
+ };
801
+
802
+ async function registerModuleExportScan(silgi) {
803
+ silgi.hook("prepare:schema.ts", async (options) => {
804
+ for (const module of silgi.scanModules) {
805
+ const exports = module.meta.exports;
806
+ if (!exports?.length)
807
+ continue;
808
+ const configKey = module.meta.configKey;
809
+ const moduleName = module.meta.name || module.meta._packageName;
810
+ options.importItems[configKey] = {
811
+ import: [],
812
+ from: module.meta._packageName ? moduleName : relativeWithDot(silgi.options.build.typesDir, module.entryPath)
813
+ };
814
+ const exportedTypes = exports.filter((exp) => exp.type).map((exp) => exp.name);
815
+ if (exportedTypes.includes("ModuleOptions")) {
816
+ const importName = pascalCase(`${configKey}Config`);
817
+ options.importItems[configKey].import.push({
818
+ name: `ModuleOptions as ${importName}`,
819
+ type: true
820
+ });
821
+ options.configs.push({ key: configKey, value: importName });
822
+ }
823
+ if (exportedTypes.includes("ModuleRuntimeContext")) {
824
+ const importName = pascalCase(`${configKey}Context`);
825
+ options.importItems[configKey].import.push({
826
+ name: `ModuleRuntimeContext as ${importName}`,
827
+ type: true
828
+ });
829
+ options.contexts.push({ key: configKey, value: importName });
830
+ }
831
+ if (exportedTypes.includes("ModuleRuntimeMethods")) {
832
+ const importName = pascalCase(`${configKey}Method`);
833
+ options.importItems[configKey].import.push({
834
+ name: `ModuleRuntimeMethods as ${importName}`,
835
+ type: true
836
+ });
837
+ options.methods.push({ key: configKey, value: importName });
838
+ }
839
+ if (exportedTypes.includes("ModuleRuntimeShared")) {
840
+ const importName = pascalCase(`${configKey}Shared`);
841
+ options.importItems[configKey].import.push({
842
+ name: `ModuleRuntimeShared as ${importName}`,
843
+ type: true
844
+ });
845
+ options.shareds.push({ key: configKey, value: importName });
846
+ }
847
+ if (exportedTypes.includes("ModuleHooks")) {
848
+ const importName = pascalCase(`${configKey}Hooks`);
849
+ options.importItems[configKey].import.push({
850
+ name: `ModuleHooks as ${importName}`,
851
+ type: true
852
+ });
853
+ options.hooks.push({ key: configKey, value: importName });
854
+ }
855
+ if (exportedTypes.includes("ModuleRuntimeHooks")) {
856
+ const importName = pascalCase(`${configKey}RuntimeHooks`);
857
+ options.importItems[configKey].import.push({
858
+ name: `ModuleRuntimeHooks as ${importName}`,
859
+ type: true
860
+ });
861
+ options.runtimeHooks.push({ key: configKey, value: importName });
862
+ }
863
+ }
864
+ });
865
+ }
866
+
867
+ async function loadSilgiModuleInstance(silgiModule) {
868
+ if (typeof silgiModule === "string") {
869
+ throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
870
+ }
871
+ if (typeof silgiModule !== "function") {
872
+ throw new TypeError(`Nuxt module should be a function: ${silgiModule}`);
873
+ }
874
+ return { silgiModule };
875
+ }
876
+ async function installModules(silgi) {
877
+ const jiti = createJiti(silgi.options.rootDir, {
878
+ alias: silgi.options.alias
879
+ });
880
+ for (const module of silgi.scanModules) {
881
+ if (hasInstalledModule(module.meta.configKey)) {
882
+ silgi.logger.info(`Module ${module.meta.configKey} installed`);
883
+ }
884
+ try {
885
+ const silgiModule = await jiti.import(module.entryPath, {
886
+ default: true,
887
+ conditions: silgi.options.conditions
888
+ });
889
+ if (silgiModule.name !== "silgiNormalizedModule") {
890
+ silgi.scanModules = silgi.scanModules.filter((m) => m.entryPath !== module.entryPath);
891
+ continue;
892
+ }
893
+ await installModule(silgiModule, silgi);
894
+ } catch (err) {
895
+ silgi.logger.error(err);
896
+ }
897
+ }
898
+ }
899
+ async function installModule(moduleToInstall, silgi = useSilgiCLI(), inlineOptions) {
900
+ const { silgiModule } = await loadSilgiModuleInstance(moduleToInstall);
901
+ const res = await silgiModule({}, silgi) ?? {};
902
+ if (res === false) {
903
+ return false;
904
+ }
905
+ const metaData = await silgiModule.getMeta?.();
906
+ const installedModule = silgi.scanModules.find((m) => m.meta.configKey === metaData?.configKey);
907
+ if (installedModule) {
908
+ installedModule.installed = true;
909
+ } else {
910
+ throw new Error(`Module ${metaData?.name} not found`);
911
+ }
912
+ }
913
+
914
+ const logger$1 = consola;
915
+ async function _resolveSilgiModule(mod, silgi) {
916
+ let _url;
917
+ let buildTimeModuleMeta = {};
918
+ const jiti = createJiti(silgi.options.rootDir, {
919
+ alias: silgi.options.alias
920
+ });
921
+ if (typeof mod === "string") {
922
+ const paths = /* @__PURE__ */ new Set();
923
+ mod = resolveAlias$1(mod, silgi.options.alias);
924
+ if (isRelative(mod)) {
925
+ mod = resolve(silgi.options.rootDir, mod);
926
+ }
927
+ paths.add(join(mod, "module"));
928
+ paths.add(mod);
929
+ for (const path of paths) {
930
+ try {
931
+ const src = isAbsolute(path) ? pathToFileURL(await resolvePath$1(path, { fallbackToOriginal: false, extensions: silgi.options.extensions })).href : await resolve$1(path, { url: silgi.options.modulesDir.map((m) => pathToFileURL(m.replace(/\/node_modules\/?$/, ""))), extensions: silgi.options.extensions });
932
+ mod = await jiti.import(src, {
933
+ default: true,
934
+ conditions: silgi.options.conditions
935
+ });
936
+ _url = fileURLToPath(new URL(src));
937
+ const moduleMetadataPath = new URL("module.json", src);
938
+ if (existsSync(moduleMetadataPath)) {
939
+ buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
940
+ } else {
941
+ if (typeof mod === "function") {
942
+ const meta = await mod.getMeta?.();
943
+ const _exports = await scanExports(_url, true);
944
+ buildTimeModuleMeta = {
945
+ ...meta,
946
+ exports: _exports.map(({ from, ...rest }) => rest)
947
+ };
948
+ }
949
+ }
950
+ break;
951
+ } catch (error) {
952
+ const code = error.code;
953
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
954
+ continue;
955
+ }
956
+ logger$1.error(`Error while importing module \`${mod}\`: ${error}`);
957
+ throw error;
958
+ }
959
+ }
960
+ }
961
+ if (!buildTimeModuleMeta) {
962
+ throw new Error(`Module ${mod} is not a valid Silgi module`);
963
+ }
964
+ if (typeof mod === "function") {
965
+ if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
966
+ throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
967
+ }
968
+ silgi.scanModules.push({
969
+ meta: buildTimeModuleMeta,
970
+ entryPath: _url,
971
+ installed: false,
972
+ options: await mod.getOptions?.() || {}
973
+ });
974
+ }
975
+ }
976
+ async function scanModules$1(silgi) {
977
+ const _modules = [
978
+ ...silgi.options._modules,
979
+ ...silgi.options.modules
980
+ ];
981
+ for await (const mod of _modules) {
982
+ await _resolveSilgiModule(mod, silgi);
983
+ }
984
+ const moduleMap = new Map(
985
+ silgi.scanModules.map((m) => [m.meta?.configKey, m])
986
+ );
987
+ const graph = createDependencyGraph(silgi.scanModules);
988
+ const sortedKeys = topologicalSort(graph);
989
+ const modules = sortedKeys.map((key) => moduleMap.get(key)).filter((module) => Boolean(module));
990
+ silgi.scanModules = modules;
991
+ }
992
+ function createDependencyGraph(modules) {
993
+ const graph = /* @__PURE__ */ new Map();
994
+ modules.forEach((module) => {
995
+ const key = module.meta?.configKey;
996
+ if (key) {
997
+ graph.set(key, /* @__PURE__ */ new Set());
998
+ }
999
+ });
1000
+ modules.forEach((module) => {
1001
+ const key = module.meta?.configKey;
1002
+ const deps = module.meta?.dependencies || [];
1003
+ if (key && deps.length > 0) {
1004
+ const modulesDeps = graph.get(key) || /* @__PURE__ */ new Set();
1005
+ deps.forEach((dep) => {
1006
+ if (graph.has(dep)) {
1007
+ modulesDeps.add(dep);
1008
+ }
1009
+ });
1010
+ graph.set(key, modulesDeps);
1011
+ }
1012
+ });
1013
+ return graph;
1014
+ }
1015
+ function topologicalSort(graph) {
1016
+ const visited = /* @__PURE__ */ new Set();
1017
+ const temp = /* @__PURE__ */ new Set();
1018
+ const order = [];
1019
+ function visit(node) {
1020
+ if (temp.has(node))
1021
+ throw new Error(`Circular dependency detected: ${node}`);
1022
+ if (visited.has(node))
1023
+ return;
1024
+ temp.add(node);
1025
+ const deps = graph.get(node) || /* @__PURE__ */ new Set();
1026
+ for (const dep of deps) {
1027
+ visit(dep);
1028
+ }
1029
+ temp.delete(node);
1030
+ visited.add(node);
1031
+ order.unshift(node);
1032
+ }
1033
+ for (const [node, deps] of graph.entries()) {
1034
+ if (deps.size === 0 && !visited.has(node))
1035
+ visit(node);
1036
+ }
1037
+ for (const node of graph.keys()) {
1038
+ if (!visited.has(node))
1039
+ visit(node);
1040
+ }
1041
+ return order;
1042
+ }
1043
+
1044
+ function resolveIgnorePatterns(silgi, relativePath) {
1045
+ if (!silgi) {
1046
+ return [];
1047
+ }
1048
+ const ignorePatterns = silgi.options.ignore.flatMap((s) => resolveGroupSyntax(s));
1049
+ const nuxtignoreFile = join(silgi.options.rootDir, ".nuxtignore");
1050
+ if (existsSync(nuxtignoreFile)) {
1051
+ const contents = readFileSync(nuxtignoreFile, "utf-8");
1052
+ ignorePatterns.push(...contents.trim().split(/\r?\n/));
1053
+ }
1054
+ return ignorePatterns;
1055
+ }
1056
+ function isIgnored(pathname, silgi, _stats) {
1057
+ if (!silgi) {
1058
+ return false;
1059
+ }
1060
+ if (!silgi._ignore) {
1061
+ silgi._ignore = ignore(silgi.options.ignoreOptions);
1062
+ silgi._ignore.add(resolveIgnorePatterns(silgi));
1063
+ }
1064
+ const relativePath = relative(silgi.options.rootDir, pathname);
1065
+ if (relativePath[0] === "." && relativePath[1] === ".") {
1066
+ return false;
1067
+ }
1068
+ return !!(relativePath && silgi._ignore.ignores(relativePath));
1069
+ }
1070
+ function resolveGroupSyntax(group) {
1071
+ let groups = [group];
1072
+ while (groups.some((group2) => group2.includes("{"))) {
1073
+ groups = groups.flatMap((group2) => {
1074
+ const [head, ...tail] = group2.split("{");
1075
+ if (tail.length) {
1076
+ const [body = "", ...rest] = tail.join("{").split("}");
1077
+ return body.split(",").map((part) => `${head}${part}${rest.join("")}`);
1078
+ }
1079
+ return group2;
1080
+ });
1081
+ }
1082
+ return groups;
1083
+ }
1084
+
1085
+ class SchemaParser {
1086
+ options = {
1087
+ debug: false
1088
+ };
1089
+ /**
1090
+ *
1091
+ */
1092
+ constructor(options) {
1093
+ this.options = {
1094
+ ...this.options,
1095
+ ...options
1096
+ };
1097
+ }
1098
+ parseExports(content, filePath) {
1099
+ const ast = parseSync(content, { sourceType: "module", sourceFilename: filePath });
1100
+ if (this.options.debug)
1101
+ writeFileSync(`${filePath}.ast.json`, JSON.stringify(ast.program, null, 2));
1102
+ return {
1103
+ exportVariables: (search, path) => this.parseTypeDeclarations(ast, search, path),
1104
+ parseInterfaceDeclarations: (search, path) => this.parseInterfaceDeclarations(ast, search, path)
1105
+ // parsePlugin: (path: string) => this.parsePlugin(ast, path),
1106
+ };
1107
+ }
1108
+ parseVariableDeclaration(ast) {
1109
+ return ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "VariableDeclaration");
1110
+ }
1111
+ parseTSInterfaceDeclaration(ast) {
1112
+ return ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "TSInterfaceDeclaration");
1113
+ }
1114
+ parseTypeDeclarations(ast, find = "", path = "") {
1115
+ const data = [];
1116
+ for (const item of this.parseVariableDeclaration(ast)) {
1117
+ for (const declaration of item.declaration.declarations) {
1118
+ if (declaration.init?.callee?.name === find) {
1119
+ const options = {};
1120
+ if (declaration.init.arguments) {
1121
+ for (const argument of declaration.init.arguments) {
1122
+ for (const propertie of argument.properties) {
1123
+ if (propertie.key.name === "name")
1124
+ options.pluginName = propertie.value.value;
1125
+ }
1126
+ }
1127
+ }
1128
+ for (const key in declaration.init.properties) {
1129
+ const property = declaration.init.properties[key];
1130
+ if (property.type === "ObjectProperty") {
1131
+ if (property.key.name === "options") {
1132
+ for (const key2 in property.value.properties) {
1133
+ const option = property.value.properties[key2];
1134
+ if (option.type === "ObjectProperty") {
1135
+ options[option.key.name] = option.value.value;
1136
+ }
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+ options.type = false;
1142
+ data.push({
1143
+ exportName: declaration.id.name,
1144
+ options,
1145
+ // object: declaration.init,
1146
+ path
1147
+ });
1148
+ }
1149
+ }
1150
+ }
1151
+ return data;
1152
+ }
1153
+ parseInterfaceDeclarations(ast, find = "", path = "") {
1154
+ const data = [];
1155
+ for (const item of this.parseTSInterfaceDeclaration(ast)) {
1156
+ if (!item?.declaration?.extends)
1157
+ continue;
1158
+ for (const declaration of item?.declaration?.extends) {
1159
+ if (declaration.expression.name === find) {
1160
+ const options = {};
1161
+ options.type = true;
1162
+ data.push({
1163
+ exportName: item.declaration.id.name,
1164
+ options,
1165
+ // object: declaration.init,
1166
+ path
1167
+ });
1168
+ }
1169
+ }
1170
+ }
1171
+ return data;
1172
+ }
1173
+ // private parsePlugin(ast: any, path: string = '') {
1174
+ // const data = {
1175
+ // export: [],
1176
+ // name: '',
1177
+ // path: '',
1178
+ // } as DataTypePlugin
1179
+ // for (const item of this.parseVariableDeclaration(ast)) {
1180
+ // for (const declaration of item.declaration.declarations) {
1181
+ // if (declaration.init.callee?.name === 'defineSilgiModule') {
1182
+ // if (declaration.init.arguments) {
1183
+ // for (const argument of declaration.init.arguments) {
1184
+ // for (const propertie of argument.properties) {
1185
+ // if (propertie.key.name === 'name')
1186
+ // data.name = propertie.value.value
1187
+ // }
1188
+ // }
1189
+ // }
1190
+ // data.export.push({
1191
+ // name: data.name,
1192
+ // as: camelCase(`${data.name}DefineSilgiModule`),
1193
+ // type: false,
1194
+ // })
1195
+ // }
1196
+ // }
1197
+ // }
1198
+ // for (const item of this.parseTSInterfaceDeclaration(ast)) {
1199
+ // if (!item?.declaration?.extends)
1200
+ // continue
1201
+ // for (const declaration of item?.declaration?.extends) {
1202
+ // if (declaration.expression.name === 'ModuleOptions') {
1203
+ // data.export.push({
1204
+ // name: item.declaration.id.name,
1205
+ // as: camelCase(`${data.name}ModuleOptions`),
1206
+ // type: true,
1207
+ // })
1208
+ // }
1209
+ // // TODO add other plugins
1210
+ // }
1211
+ // }
1212
+ // data.path = path
1213
+ // return data
1214
+ // }
1215
+ }
1216
+
1217
+ async function scanFiles$1(silgi) {
1218
+ const filePaths = /* @__PURE__ */ new Set();
1219
+ const scannedPaths = [];
1220
+ const dir = silgi.options.serverDir;
1221
+ const files = (await globby(dir, { cwd: silgi.options.rootDir, ignore: silgi.options.ignore })).sort();
1222
+ if (files.length) {
1223
+ const siblings = await readdir(dirname(dir)).catch(() => []);
1224
+ const directory = basename(dir);
1225
+ if (!siblings.includes(directory)) {
1226
+ const directoryLowerCase = directory.toLowerCase();
1227
+ const caseCorrected = siblings.find((sibling) => sibling.toLowerCase() === directoryLowerCase);
1228
+ if (caseCorrected) {
1229
+ const original = relative(silgi.options.serverDir, dir);
1230
+ const corrected = relative(silgi.options.serverDir, join(dirname(dir), caseCorrected));
1231
+ consola.warn(`Components not scanned from \`~/${corrected}\`. Did you mean to name the directory \`~/${original}\` instead?`);
1232
+ }
1233
+ }
1234
+ }
1235
+ for (const _file of files) {
1236
+ const filePath = resolve(dir, _file);
1237
+ if (scannedPaths.find((d) => filePath.startsWith(withTrailingSlash(d))) || isIgnored(filePath, silgi)) {
1238
+ continue;
1239
+ }
1240
+ if (filePaths.has(filePath)) {
1241
+ continue;
1242
+ }
1243
+ filePaths.add(filePath);
1244
+ if (silgi.options.extensions.includes(extname(filePath))) {
1245
+ const parser = new SchemaParser({
1246
+ debug: false
1247
+ });
1248
+ const readfile = readFileSync(filePath, "utf-8");
1249
+ const { exportVariables, parseInterfaceDeclarations } = parser.parseExports(readfile, filePath);
1250
+ const createServices = exportVariables("createService", filePath);
1251
+ if (createServices.length > 0) {
1252
+ for (const createService of createServices) {
1253
+ const { exportName, path } = createService;
1254
+ silgi.hook("prepare:core.ts", (options) => {
1255
+ options.services.push(exportName);
1256
+ });
1257
+ silgi.hook("prepare:core.ts", (options) => {
1258
+ options.importItems[path] ??= {
1259
+ import: [],
1260
+ from: relativeWithDot(silgi.options.silgi.serverDir, path)
1261
+ };
1262
+ options.importItems[path].import.push({
1263
+ name: exportName
1264
+ });
1265
+ });
1266
+ }
1267
+ }
1268
+ const createSchemas = exportVariables("createSchema", filePath);
1269
+ if (createSchemas.length > 0) {
1270
+ for (const createSchema of createSchemas) {
1271
+ const { exportName, path } = createSchema;
1272
+ silgi.hook("prepare:core.ts", (options) => {
1273
+ options.schemas.push(exportName);
1274
+ });
1275
+ silgi.hook("prepare:core.ts", (options) => {
1276
+ options.importItems[path] ??= {
1277
+ import: [],
1278
+ from: relativeWithDot(silgi.options.silgi.serverDir, path)
1279
+ };
1280
+ options.importItems[path].import.push({
1281
+ name: exportName
1282
+ });
1283
+ });
1284
+ }
1285
+ }
1286
+ const createShareds = exportVariables("createShared", filePath);
1287
+ if (createShareds.length > 0) {
1288
+ for (const createShared of createShareds) {
1289
+ const { exportName, path } = createShared;
1290
+ silgi.hook("prepare:core.ts", (options) => {
1291
+ options.shareds.push(exportName);
1292
+ });
1293
+ silgi.hook("prepare:core.ts", (options) => {
1294
+ options.importItems[path] ??= {
1295
+ import: [],
1296
+ // Relative path kaldirmamiz gerekiyor bunlar hooklarin bittigi yerde karar verilmeli.
1297
+ from: relativeWithDot(silgi.options.silgi.serverDir, path)
1298
+ };
1299
+ options.importItems[path].import.push({
1300
+ name: exportName
1301
+ });
1302
+ });
1303
+ }
1304
+ }
1305
+ const sharedsTypes = parseInterfaceDeclarations("ExtendShared", filePath);
1306
+ if (sharedsTypes.length > 0) {
1307
+ for (const sharedType of sharedsTypes) {
1308
+ const { exportName, path } = sharedType;
1309
+ silgi.hook("prepare:schema.ts", (options) => {
1310
+ options.shareds.push({
1311
+ key: exportName,
1312
+ value: exportName
1313
+ });
1314
+ });
1315
+ silgi.hook("prepare:schema.ts", (options) => {
1316
+ options.importItems[path] ??= {
1317
+ import: [],
1318
+ from: path
1319
+ };
1320
+ options.importItems[path].import.push({
1321
+ name: exportName,
1322
+ type: true
1323
+ });
1324
+ });
1325
+ }
1326
+ }
1327
+ const contextTypes = parseInterfaceDeclarations("ExtendContext", filePath);
1328
+ if (contextTypes.length > 0) {
1329
+ for (const contextType of contextTypes) {
1330
+ const { exportName, path } = contextType;
1331
+ silgi.hook("prepare:schema.ts", (options) => {
1332
+ options.contexts.push({
1333
+ key: exportName,
1334
+ value: exportName
1335
+ });
1336
+ });
1337
+ silgi.hook("prepare:schema.ts", (options) => {
1338
+ options.importItems[path] ??= {
1339
+ import: [],
1340
+ from: path
1341
+ };
1342
+ options.importItems[path].import.push({
1343
+ name: exportName,
1344
+ type: true
1345
+ });
1346
+ });
1347
+ }
1348
+ }
1349
+ }
1350
+ }
1351
+ }
1352
+
1353
+ async function createStorageCLI(silgi) {
1354
+ const storage = createStorage();
1355
+ const mounts = klona({
1356
+ ...silgi.options.storage,
1357
+ ...silgi.options.devStorage
1358
+ });
1359
+ for (const [path, opts] of Object.entries(mounts)) {
1360
+ if (opts.driver) {
1361
+ const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
1362
+ storage.mount(path, driver(opts));
1363
+ } else {
1364
+ silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
1365
+ }
1366
+ }
1367
+ return storage;
1368
+ }
1369
+
1370
+ const vueShim = {
1371
+ filename: "types/vue-shim.d.ts",
1372
+ getContents: ({ app }) => {
1373
+ if (!app.options.typescript.shim) {
1374
+ return "";
1375
+ }
1376
+ return [
1377
+ "declare module '*.vue' {",
1378
+ " import { DefineComponent } from 'vue'",
1379
+ " const component: DefineComponent<{}, {}, any>",
1380
+ " export default component",
1381
+ "}"
1382
+ ].join("\n");
1383
+ }
1384
+ };
1385
+ const pluginsDeclaration = {
1386
+ filename: "types/plugins.d.ts",
1387
+ getContents: async () => {
1388
+ return `
1389
+ declare module 'nuxt' {
1390
+ interface NuxtApp {
1391
+ $myPlugin: any;
1392
+ }
1393
+ }
1394
+ `;
1395
+ }
1396
+ };
1397
+
1398
+ const defaultTemplates = {
1399
+ __proto__: null,
1400
+ pluginsDeclaration: pluginsDeclaration,
1401
+ vueShim: vueShim
1402
+ };
1403
+
1404
+ const postTemplates = [
1405
+ pluginsDeclaration.filename
1406
+ ];
1407
+ const logger = useLogger("silgi");
1408
+ async function generateApp(app, options = {}) {
1409
+ app.templates = Object.values(defaultTemplates).concat(app.options.build.templates);
1410
+ await app.callHook("app:templates", app);
1411
+ app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl, app.options.silgi.vfsDir));
1412
+ const filteredTemplates = {
1413
+ pre: [],
1414
+ post: []
1415
+ };
1416
+ for (const template of app.templates) {
1417
+ if (options.filter && !options.filter(template)) {
1418
+ continue;
1419
+ }
1420
+ const key = template.filename && postTemplates.includes(template.filename) ? "post" : "pre";
1421
+ filteredTemplates[key].push(template);
1422
+ }
1423
+ const templateContext = { app };
1424
+ const writes = [];
1425
+ const indexImports = [];
1426
+ const dirs = /* @__PURE__ */ new Set();
1427
+ const changedTemplates = [];
1428
+ async function processTemplate(template) {
1429
+ const fullPath = template.dst || resolve(app.options.silgi.vfsDir, template.filename);
1430
+ const start = performance.now();
1431
+ const contents = await compileTemplate(template, templateContext).catch((e) => {
1432
+ logger.error(`Could not compile template \`${template.filename}\`.`);
1433
+ logger.error(e);
1434
+ throw e;
1435
+ });
1436
+ template.modified = true;
1437
+ if (template.modified) {
1438
+ changedTemplates.push(template);
1439
+ }
1440
+ const perf = performance.now() - start;
1441
+ const setupTime = Math.round(perf * 100) / 100;
1442
+ if (app.options.debug || setupTime > 500) {
1443
+ logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`);
1444
+ }
1445
+ if (template.modified && template.write) {
1446
+ dirs.add(dirname(fullPath));
1447
+ if (!fullPath.endsWith(".d.ts")) {
1448
+ indexImports.push(relativeWithDot(app.options.silgi.serverDir, fullPath));
1449
+ }
1450
+ writes.push(() => writeFileSync(fullPath, contents, "utf8"));
1451
+ }
1452
+ }
1453
+ await Promise.allSettled(filteredTemplates.pre.map(processTemplate));
1454
+ await Promise.allSettled(filteredTemplates.post.map(processTemplate));
1455
+ for (const dir of dirs) {
1456
+ mkdirSync(dir, { recursive: true });
1457
+ }
1458
+ for (const write of writes) {
1459
+ write();
1460
+ }
1461
+ writeFileSync(resolve(app.options.silgi.serverDir, "index.ts"), `${indexImports.map((i) => `export * from '${i}'`).join("\n")}
1462
+ `, "utf8");
1463
+ if (changedTemplates.length) {
1464
+ await app.callHook("app:templatesGenerated", app, changedTemplates, options);
1465
+ }
1466
+ }
1467
+ async function compileTemplate(template, ctx) {
1468
+ delete ctx.utils;
1469
+ if (template.src) {
1470
+ try {
1471
+ return await promises.readFile(template.src, "utf-8");
1472
+ } catch (err) {
1473
+ logger.error(`[nuxt] Error reading template from \`${template.src}\``);
1474
+ throw err;
1475
+ }
1476
+ }
1477
+ if (template.getContents) {
1478
+ return template.getContents({
1479
+ ...ctx,
1480
+ options: template.options
1481
+ });
1482
+ }
1483
+ throw new Error(`[nuxt] Invalid template. Templates must have either \`src\` or \`getContents\`: ${JSON.stringify(template)}`);
1484
+ }
1485
+
1486
+ const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
1487
+ async function scanAndSyncOptions(silgi) {
1488
+ const scannedModules = await scanModules(silgi);
1489
+ silgi.options.modules = silgi.options.modules || [];
1490
+ for (const modPath of scannedModules) {
1491
+ if (!silgi.options.modules.includes(modPath)) {
1492
+ silgi.options.modules.push(modPath);
1493
+ }
1494
+ }
1495
+ }
1496
+ async function scanModules(silgi) {
1497
+ const files = await scanFiles(silgi, "silgi/modules");
1498
+ return files.map((f) => f.fullPath);
1499
+ }
1500
+ async function scanFiles(silgi, name) {
1501
+ const files = await Promise.all(
1502
+ silgi.options.scanDirs.map((dir) => scanDir(silgi, dir, name))
1503
+ ).then((r) => r.flat());
1504
+ return files;
1505
+ }
1506
+ async function scanDir(silgi, dir, name) {
1507
+ const fileNames = await globby(join(name, GLOB_SCAN_PATTERN), {
1508
+ cwd: dir,
1509
+ dot: true,
1510
+ ignore: silgi.options.ignore,
1511
+ absolute: true
1512
+ });
1513
+ return fileNames.map((fullPath) => {
1514
+ return {
1515
+ fullPath,
1516
+ path: relative(join(dir, name), fullPath)
1517
+ };
1518
+ }).sort((a, b) => a.path.localeCompare(b.path));
1519
+ }
1520
+
1521
+ async function createSilgiCLI(config = {}, opts = {}) {
1522
+ const options = await loadOptions(config, opts);
1523
+ const hooks = createHooks();
1524
+ const silgi = {
1525
+ modulesURIs: {},
1526
+ scannedURIs: /* @__PURE__ */ new Map(),
1527
+ services: {},
1528
+ uris: {},
1529
+ shareds: {},
1530
+ schemas: {},
1531
+ unimport: void 0,
1532
+ options,
1533
+ hooks,
1534
+ // vfs: {}
1535
+ _requiredModules: {},
1536
+ logger: consola.withTag("silgi"),
1537
+ close: () => silgi.hooks.callHook("close", silgi),
1538
+ storage: void 0,
1539
+ scanModules: [],
1540
+ templates: [],
1541
+ callHook: hooks.callHook,
1542
+ addHooks: hooks.addHooks,
1543
+ hook: hooks.hook,
1544
+ async updateConfig(_config) {
1545
+ }
1546
+ };
1547
+ if (silgiCLICtx.tryUse()) {
1548
+ silgiCLICtx.unset();
1549
+ silgiCLICtx.set(silgi);
1550
+ } else {
1551
+ silgiCLICtx.set(silgi);
1552
+ silgi.hook("close", () => silgiCLICtx.unset());
1553
+ }
1554
+ if (silgi.options.debug) {
1555
+ createDebugger(silgi.hooks, { tag: "silgi" });
1556
+ silgi.options.plugins.push({
1557
+ path: join(runtimeDir, "internal/debug"),
1558
+ packageImport: "silgi/runtime/internal/debug"
1559
+ });
1560
+ }
1561
+ await scanAndSyncOptions(silgi);
1562
+ await scanModules$1(silgi);
1563
+ await scanFiles$1(silgi);
1564
+ silgi.storage = await createStorageCLI(silgi);
1565
+ silgi.hooks.hook("close", async () => {
1566
+ await silgi.storage.dispose();
1567
+ });
1568
+ if (silgi.options.logLevel !== void 0) {
1569
+ silgi.logger.level = silgi.options.logLevel;
1570
+ }
1571
+ silgi.hooks.addHooks(silgi.options.hooks);
1572
+ await installModules(silgi);
1573
+ await silgi.hooks.callHook("scanFiles:done", silgi);
1574
+ await generateApp(silgi);
1575
+ if (silgi.options.imports) {
1576
+ silgi.unimport = createUnimport(silgi.options.imports);
1577
+ await silgi.unimport.init();
1578
+ }
1579
+ await registerModuleExportScan(silgi);
1580
+ return silgi;
1581
+ }
1582
+
1583
+ const prepare = defineCommand({
1584
+ meta: {
1585
+ name: "prepare",
1586
+ description: "Generate types for the project",
1587
+ version: version
1588
+ },
1589
+ args: {
1590
+ ...commonArgs,
1591
+ preset: {
1592
+ type: "string",
1593
+ description: "The build preset to use (you can also use `SILGI_PRESET` environment variable)."
1594
+ },
1595
+ stub: {
1596
+ type: "boolean",
1597
+ description: "Run in silgi development mode"
1598
+ }
1599
+ },
1600
+ async run({ args }) {
1601
+ const rootDir = resolve(args.dir || args._dir || ".");
1602
+ const silgi = await createSilgiCLI({
1603
+ rootDir,
1604
+ dev: args.stub,
1605
+ stub: args.stub,
1606
+ typescript: { internalPaths: args.stub }
1607
+ });
1608
+ await prepare$1();
1609
+ for (const framework of frameworkSetup) {
1610
+ await framework(silgi);
1611
+ }
1612
+ await writeTypesAndFiles(silgi);
1613
+ await silgi.callHook("read:core.ts", async () => {
1614
+ const data = await readCoreFile(silgi);
1615
+ return data;
1616
+ });
1617
+ await silgi.close();
1618
+ }
1619
+ });
1620
+
1621
+ export { prepare as default };