silgi 0.27.6 → 0.27.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1578 +1,16 @@
1
1
  import { defineCommand, runCommand } from 'citty';
2
- import { resolve, join, relative, dirname, basename, extname } from 'pathe';
3
- import { peerDependencies, version } from 'silgi/meta';
4
- import { g as generateApp, b as build } from './build.mjs';
5
- import consola, { consola as consola$1 } from 'consola';
6
- import { createHooks, createDebugger } from 'hookable';
7
- import { useSilgiCLI, replaceRuntimeValues, silgiCLICtx, autoImportTypes } from 'silgi';
8
- import { relativeWithDot, hash, resolveAlias, directoryToURL, addTemplate, hasError, writeFile, parseServices, resolveSilgiPath } from 'silgi/kit';
9
- import { runtimeDir } from 'silgi/runtime/meta';
10
- import { scanExports, createUnimport } from 'unimport';
11
- import { c as createRouteRules, a as silgiCLIIClose } from '../_chunks/silgiApp.mjs';
2
+ import { resolve } from 'pathe';
3
+ import { version } from 'silgi/meta';
4
+ import { p as prepareEnv, c as createSilgiCLI, b as build } from './silgi.mjs';
5
+ import { execSync } from 'node:child_process';
6
+ import { readFileSync } from 'node:fs';
12
7
  import * as p from '@clack/prompts';
13
- import { existsSync, promises, readFileSync, writeFileSync } from 'node:fs';
14
- import * as dotenv from 'dotenv';
15
- import { resolveModuleExportNames, findTypeExports, findExports } from 'mlly';
8
+ import { consola } from 'consola';
16
9
  import { createJiti } from 'dev-jiti';
17
- import { h as hasInstalledModule } from './compatibility.mjs';
18
- import { fileURLToPath } from 'node:url';
19
- import { defu } from 'defu';
20
- import { resolveModuleURL } from 'exsolve';
21
- import { isRelative, withTrailingSlash } from 'ufo';
22
- import { generateTypes, resolveSchema } from 'untyped';
23
- import { readdir, readFile } from 'node:fs/promises';
24
- import { globby } from 'globby';
25
- import ignore from 'ignore';
26
- import { parseSync } from '@oxc-parser/wasm';
27
- import { klona } from 'klona';
28
- import { useSilgiRuntimeConfig, initRuntimeConfig } from 'silgi/runtime';
29
- import { createStorage, builtinDrivers } from 'unstorage';
30
- import { snakeCase } from 'scule';
31
- import { l as loadOptions } from './loader.mjs';
32
- import { execSync } from 'node:child_process';
33
10
  import color from 'picocolors';
34
-
35
- async function setupDotenv(options) {
36
- const targetEnvironment = options.env ?? process.env;
37
- const environment = await loadDotenv({
38
- cwd: options.cwd,
39
- fileName: options.fileName ?? ".env",
40
- env: targetEnvironment,
41
- interpolate: options.interpolate ?? true
42
- });
43
- for (const key in environment) {
44
- if (!key.startsWith("_") && targetEnvironment[key] === void 0) {
45
- targetEnvironment[key] = environment[key];
46
- }
47
- }
48
- return environment;
49
- }
50
- async function loadDotenv(options) {
51
- const environment = /* @__PURE__ */ Object.create(null);
52
- const dotenvFile = resolve(options.cwd, options.fileName);
53
- if (existsSync(dotenvFile)) {
54
- const parsed = dotenv.parse(await promises.readFile(dotenvFile, "utf8"));
55
- Object.assign(environment, parsed);
56
- }
57
- if (!options.env?._applied) {
58
- Object.assign(environment, options.env);
59
- environment._applied = true;
60
- }
61
- if (options.interpolate) {
62
- interpolate(environment);
63
- }
64
- return environment;
65
- }
66
- function interpolate(target, source = {}, parse = (v) => v) {
67
- function getValue(key) {
68
- return source[key] === void 0 ? target[key] : source[key];
69
- }
70
- function interpolate2(value, parents = []) {
71
- if (typeof value !== "string") {
72
- return value;
73
- }
74
- const matches = value.match(/(.?\$\{?[\w:]*\}?)/g) || [];
75
- return parse(
76
- matches.reduce((newValue, match) => {
77
- const parts = /(.?)\$\{?([\w:]+)?\}?/.exec(match) || [];
78
- const prefix = parts[1];
79
- let value2, replacePart;
80
- if (prefix === "\\") {
81
- replacePart = parts[0] || "";
82
- value2 = replacePart.replace(String.raw`\$`, "$");
83
- } else {
84
- const key = parts[2];
85
- replacePart = (parts[0] || "").slice(prefix.length);
86
- if (parents.includes(key)) {
87
- console.warn(
88
- `Please avoid recursive environment variables ( loop: ${parents.join(
89
- " > "
90
- )} > ${key} )`
91
- );
92
- return "";
93
- }
94
- value2 = getValue(key);
95
- value2 = interpolate2(value2, [...parents, key]);
96
- }
97
- return value2 === void 0 ? newValue : newValue.replace(replacePart, value2);
98
- }, value)
99
- );
100
- }
101
- for (const key in target) {
102
- target[key] = interpolate2(getValue(key));
103
- }
104
- }
105
-
106
- let initialized = false;
107
- async function prepareEnv(silgiConfig) {
108
- if (initialized)
109
- return;
110
- initialized = true;
111
- const customEnvironments = silgiConfig.environments;
112
- const environment = silgiConfig.activeEnvironment ? silgiConfig.activeEnvironment : await p.select({
113
- message: "Select an environment",
114
- options: customEnvironments?.length > 0 ? customEnvironments.map((env) => ({
115
- label: env.fileName,
116
- value: env.fileName
117
- })) : [
118
- { label: "Development (.env)", value: ".env" },
119
- { label: "Docker (.env.docker)", value: "docker" },
120
- { label: "Staging (.env.staging)", value: "staging" },
121
- { label: "Testing (.env.testing)", value: "testing" },
122
- { label: "Production (.env.prod)", value: "prod" }
123
- ]
124
- });
125
- const findEnv = customEnvironments?.find((env) => env.fileName === environment);
126
- if (findEnv) {
127
- await setupDotenv({
128
- cwd: findEnv.cwd || silgiConfig.rootDir,
129
- interpolate: findEnv.interpolate,
130
- fileName: findEnv.fileName,
131
- env: findEnv.env
132
- });
133
- } else {
134
- await setupDotenv({
135
- cwd: silgiConfig.rootDir,
136
- interpolate: true,
137
- fileName: environment === ".env" ? ".env" : `.env.${environment}`
138
- });
139
- }
140
- }
141
-
142
- async function emptyFramework(silgi) {
143
- if (silgi.options.preset === "npm-package" || !silgi.options.preset) {
144
- silgi.hook("after:prepare:schema.ts", (data) => {
145
- data.unshift("type FrameworkContextExtends = {}");
146
- });
147
- }
148
- }
149
-
150
- async function h3Framework(silgi, skip = false) {
151
- if (silgi.options.preset !== "h3" && skip === false)
152
- return;
153
- if (silgi.options.preset === "h3") {
154
- silgi.hook("after:prepare:schema.ts", (data) => {
155
- data.unshift("type FrameworkContextExtends = NitroApp");
156
- });
157
- }
158
- silgi.hook("prepare:schema.ts", (data) => {
159
- data.importItems.nitropack = {
160
- import: [
161
- {
162
- name: "NitroApp",
163
- type: true,
164
- key: "NitroApp"
165
- }
166
- ],
167
- from: "nitropack/types"
168
- };
169
- data.importItems.h3 = {
170
- import: [
171
- {
172
- name: "H3Event",
173
- type: true,
174
- key: "H3Event"
175
- }
176
- ],
177
- from: "h3"
178
- };
179
- data.events.push({
180
- key: "H3Event",
181
- value: "H3Event",
182
- extends: true,
183
- isSilgiContext: false
184
- });
185
- });
186
- silgi.hook("prepare:createDTSFramework", (data) => {
187
- data.importItems["silgi/types"] = {
188
- import: [
189
- {
190
- name: "SilgiRuntimeContext",
191
- type: true,
192
- key: "SilgiRuntimeContext"
193
- }
194
- ],
195
- from: "silgi/types"
196
- };
197
- data.customContent?.push(
198
- "",
199
- 'declare module "h3" {',
200
- " interface H3EventContext extends SilgiRuntimeContext {}",
201
- "}",
202
- ""
203
- );
204
- });
205
- silgi.hook("prepare:core.ts", (data) => {
206
- data._silgiConfigs.push(`captureError: (silgi, error, context = {}) => {
207
- const promise = silgi.hooks
208
- .callHookParallel('error', silgi, error, context)
209
- .catch((error_) => {
210
- console.error('Error while capturing another error', error_)
211
- })
212
-
213
- if (context.event && isEvent(context.event)) {
214
- const errors = context.event.context.nitro?.errors
215
- if (errors) {
216
- errors.push({ error, context })
217
- }
218
- if (context.event.waitUntil) {
219
- context.event.waitUntil(promise)
220
- }
221
- }
222
- }`);
223
- });
224
- if (silgi.options.imports !== false) {
225
- const h3Exports = await resolveModuleExportNames("h3", {
226
- url: import.meta.url
227
- });
228
- silgi.options.imports.presets ??= [];
229
- silgi.options.imports.presets.push({
230
- from: "h3",
231
- imports: h3Exports.filter((n) => !/^[A-Z]/.test(n) && n !== "use")
232
- });
233
- }
234
- }
235
-
236
- async function nitroFramework(silgi, skip = false) {
237
- if (silgi.options.preset !== "nitro" && skip === false)
238
- return;
239
- silgi.hook("prepare:schema.ts", (data) => {
240
- data.importItems.nitropack = {
241
- import: [
242
- {
243
- name: "NitroApp",
244
- type: true,
245
- key: "NitroApp"
246
- }
247
- ],
248
- from: "nitropack/types"
249
- };
250
- });
251
- silgi.hook("after:prepare:schema.ts", (data) => {
252
- data.unshift("type FrameworkContextExtends = NitroApp");
253
- });
254
- silgi.options.plugins.push({
255
- packageImport: "silgi/runtime/internal/nitro",
256
- path: join(runtimeDir, "internal/nitro")
257
- });
258
- silgi.hook("prepare:createDTSFramework", (data) => {
259
- data.importItems["nitropack/types"] = {
260
- import: [
261
- {
262
- name: "NitroRuntimeConfig",
263
- type: true,
264
- key: "NitroRuntimeConfig"
265
- }
266
- ],
267
- from: "nitropack/types"
268
- };
269
- data.customContent?.push(
270
- "",
271
- 'declare module "silgi/types" {',
272
- " interface SilgiRuntimeConfig extends NitroRuntimeConfig {}",
273
- "}",
274
- ""
275
- );
276
- });
277
- if (silgi.options.imports !== false) {
278
- silgi.options.imports.presets ??= [];
279
- }
280
- await h3Framework(silgi, true);
281
- }
282
-
283
- async function nuxtFramework(silgi, skip = false) {
284
- if (silgi.options.preset !== "nuxt" && skip === false)
285
- return;
286
- await nitroFramework(silgi, true);
287
- }
288
-
289
- const frameworkSetup = [
290
- emptyFramework,
291
- h3Framework,
292
- nitroFramework,
293
- nuxtFramework
294
- ];
295
-
296
- async function registerModuleExportScan(silgi) {
297
- silgi.hook("prepare:schema.ts", async (options) => {
298
- for (const module of silgi.scanModules) {
299
- const moduleReExports = [];
300
- if (!module.entryPath) {
301
- continue;
302
- }
303
- const moduleTypes = await promises.readFile(module.entryPath.replace(/\.mjs$/, "Types.d.ts"), "utf8").catch(() => "");
304
- const normalisedModuleTypes = moduleTypes.replace(/export\s*\{.*?\}/gs, (match) => match.replace(/\b(type|interface)\b/g, ""));
305
- for (const e of findTypeExports(normalisedModuleTypes)) {
306
- moduleReExports.push(e);
307
- }
308
- for (const e of findExports(normalisedModuleTypes)) {
309
- moduleReExports.push(e);
310
- }
311
- const hasTypeExport = (name) => moduleReExports.find((exp) => exp.names?.includes(name));
312
- const configKey = module.meta.configKey;
313
- const moduleName = module.meta.name || module.meta._packageName;
314
- options.importItems[configKey] = {
315
- import: [],
316
- from: module.meta._packageName ? moduleName : relativeWithDot(silgi.options.build.typesDir, module.entryPath)
317
- };
318
- if (hasTypeExport("ModuleOptions")) {
319
- const importName = `_${hash(`${configKey}ModuleOptions`)}`;
320
- options.importItems[configKey].import.push({
321
- name: `ModuleOptions as ${importName}`,
322
- type: true,
323
- key: importName
324
- });
325
- options.options.push({ key: configKey, value: importName });
326
- }
327
- if (hasTypeExport("ModuleRuntimeOptions")) {
328
- const importName = `_${hash(`${configKey}ModuleRuntimeOptions`)}`;
329
- options.importItems[configKey].import.push({
330
- name: `ModuleRuntimeOptions as ${importName}`,
331
- type: true,
332
- key: importName
333
- });
334
- options.runtimeOptions.push({ key: configKey, value: importName });
335
- }
336
- if (hasTypeExport("ModuleRuntimeShareds")) {
337
- const importName = `_${hash(`${configKey}ModuleRuntimeShareds`)}`;
338
- options.importItems[configKey].import.push({
339
- name: `ModuleRuntimeShareds as ${importName}`,
340
- type: true,
341
- key: importName
342
- });
343
- options.shareds.push({ key: configKey, value: importName });
344
- }
345
- if (hasTypeExport("ModuleEvents")) {
346
- const importName = `_${hash(`${configKey}ModuleEvents`)}`;
347
- options.importItems[configKey].import.push({
348
- name: `ModuleEvents as ${importName}`,
349
- type: true,
350
- key: importName
351
- });
352
- options.events.push({ key: configKey, value: importName });
353
- }
354
- if (hasTypeExport("ModuleRuntimeContexts")) {
355
- const importName = `_${hash(`${configKey}ModuleRuntimeContexts`)}`;
356
- options.importItems[configKey].import.push({
357
- name: `ModuleRuntimeContexts as ${importName}`,
358
- type: true,
359
- key: importName
360
- });
361
- options.contexts.push({ key: configKey, value: importName });
362
- }
363
- if (hasTypeExport("ModuleHooks")) {
364
- const importName = `_${hash(`${configKey}ModuleHooks`)}`;
365
- options.importItems[configKey].import.push({
366
- name: `ModuleHooks as ${importName}`,
367
- type: true,
368
- key: importName
369
- });
370
- options.hooks.push({ key: configKey, value: importName });
371
- }
372
- if (hasTypeExport("ModuleRuntimeHooks")) {
373
- const importName = `_${hash(`${configKey}RuntimeHooks`)}`;
374
- options.importItems[configKey].import.push({
375
- name: `ModuleRuntimeHooks as ${importName}`,
376
- type: true,
377
- key: importName
378
- });
379
- options.runtimeHooks.push({ key: configKey, value: importName });
380
- }
381
- if (hasTypeExport("ModuleRuntimeActions")) {
382
- const importName = `_${hash(`${configKey}ModuleRuntimeActions`)}`;
383
- options.importItems[configKey].import.push({
384
- name: `ModuleRuntimeActions as ${importName}`,
385
- type: true,
386
- key: importName
387
- });
388
- options.actions.push({ key: configKey, value: importName });
389
- }
390
- if (hasTypeExport("ModuleRuntimeMethods")) {
391
- const importName = `_${hash(`${configKey}ModuleRuntimeMethods`)}`;
392
- options.importItems[configKey].import.push({
393
- name: `ModuleRuntimeMethods as ${importName}`,
394
- type: true,
395
- key: importName
396
- });
397
- options.methods.push({ key: configKey, value: importName });
398
- }
399
- if (hasTypeExport("ModuleRuntimeRouteRules")) {
400
- const importName = `_${hash(`${configKey}ModuleRuntimeRouteRules`)}`;
401
- options.importItems[configKey].import.push({
402
- name: `ModuleRuntimeRouteRules as ${importName}`,
403
- type: true,
404
- key: importName
405
- });
406
- options.routeRules.push({ key: configKey, value: importName });
407
- }
408
- if (hasTypeExport("ModuleRuntimeRouteRulesConfig")) {
409
- const importName = `_${hash(`${configKey}ModuleRuntimeRouteRulesConfig`)}`;
410
- options.importItems[configKey].import.push({
411
- name: `ModuleRuntimeRouteRulesConfig as ${importName}`,
412
- type: true,
413
- key: importName
414
- });
415
- options.routeRulesConfig.push({ key: configKey, value: importName });
416
- }
417
- }
418
- });
419
- }
420
-
421
- async function loadSilgiModuleInstance(silgiModule) {
422
- if (typeof silgiModule === "string") {
423
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
424
- }
425
- if (typeof silgiModule !== "function") {
426
- throw new TypeError(`Nuxt module should be a function: ${silgiModule}`);
427
- }
428
- return { silgiModule };
429
- }
430
- async function installModules(silgi, prepare = false) {
431
- silgi.options.isPreparingModules = prepare;
432
- const jiti = createJiti(silgi.options.rootDir, {
433
- alias: silgi.options.alias,
434
- fsCache: true,
435
- moduleCache: true
436
- });
437
- for (const module of silgi.scanModules) {
438
- if (hasInstalledModule(module.meta.configKey) && !silgi.options.dev) {
439
- silgi.logger.info(`Module ${module.meta.configKey} installed`);
440
- }
441
- try {
442
- const silgiModule = module.entryPath !== void 0 ? await jiti.import(module.entryPath, {
443
- default: true,
444
- conditions: silgi.options.conditions
445
- }) : module.module;
446
- if (silgiModule.name !== "silgiNormalizedModule") {
447
- silgi.scanModules = silgi.scanModules.filter((m) => m.entryPath !== module.entryPath);
448
- continue;
449
- }
450
- await installModule(silgiModule, silgi, prepare);
451
- } catch (err) {
452
- silgi.logger.error(err);
453
- }
454
- }
455
- silgi.options.isPreparingModules = false;
456
- }
457
- async function installModule(moduleToInstall, silgi = useSilgiCLI(), inlineOptions, prepare = false) {
458
- const { silgiModule } = await loadSilgiModuleInstance(moduleToInstall);
459
- const res = await silgiModule(inlineOptions || {}, silgi) ?? {};
460
- if (res === false) {
461
- return false;
462
- }
463
- const metaData = await silgiModule.getMeta?.();
464
- if (prepare) {
465
- return metaData;
466
- }
467
- const installedModule = silgi.scanModules.find((m) => m.meta.configKey === metaData?.configKey);
468
- if (installedModule) {
469
- installedModule.installed = true;
470
- } else {
471
- throw new Error(`Module ${metaData?.name} not found`);
472
- }
473
- }
474
-
475
- const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
476
- async function _resolveSilgiModule(silgiModule, silgi) {
477
- let resolvedModulePath;
478
- let buildTimeModuleMeta = {};
479
- const jiti = createJiti(silgi.options.rootDir, {
480
- alias: silgi.options.alias,
481
- fsCache: true,
482
- moduleCache: true
483
- });
484
- if (typeof silgiModule === "string") {
485
- silgiModule = resolveAlias(silgiModule, silgi.options.alias);
486
- if (isRelative(silgiModule)) {
487
- silgiModule = resolve(silgi.options.rootDir, silgiModule);
488
- }
489
- try {
490
- const src = resolveModuleURL(silgiModule, {
491
- from: silgi.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
492
- suffixes: ["silgi", "silgi/index", "module", "module/index", "", "index"],
493
- extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
494
- // Maybe add https://github.com/unjs/exsolve/blob/dfff3e9bbc4a3a173a2d56b9b9ff731ab15598be/src/resolve.ts#L7
495
- // conditions: silgi.options.conditions,
496
- });
497
- resolvedModulePath = fileURLToPath(src);
498
- const resolvedSilgiModule = await jiti.import(src, { default: true });
499
- if (typeof resolvedSilgiModule !== "function") {
500
- throw new TypeError(`Nuxt module should be a function: ${silgiModule}.`);
501
- }
502
- silgiModule = await jiti.import(src, {
503
- default: true,
504
- conditions: silgi.options.conditions
505
- });
506
- const moduleMetadataPath = new URL("module.json", src);
507
- if (existsSync(moduleMetadataPath)) {
508
- buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
509
- } else {
510
- if (typeof silgiModule === "function") {
511
- const meta = await silgiModule.getMeta?.();
512
- const _exports = await scanExports(resolvedModulePath, true);
513
- buildTimeModuleMeta = {
514
- ...meta,
515
- exports: _exports.map(({ from, ...rest }) => rest)
516
- };
517
- }
518
- }
519
- } catch (error) {
520
- const code = error.code;
521
- if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
522
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
523
- }
524
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
525
- const module = MissingModuleMatcher.exec(error.message)?.[1];
526
- if (module && !module.includes(silgiModule)) {
527
- throw new TypeError(`Error while importing module \`${silgiModule}\`: ${error}`);
528
- }
529
- }
530
- }
531
- }
532
- if (!buildTimeModuleMeta) {
533
- throw new Error(`Module ${silgiModule} is not a valid Silgi module`);
534
- }
535
- if (typeof silgiModule === "function") {
536
- if (!buildTimeModuleMeta.configKey) {
537
- const meta = await silgiModule.getMeta?.();
538
- buildTimeModuleMeta = {
539
- ...meta,
540
- exports: []
541
- };
542
- }
543
- if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
544
- throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
545
- }
546
- const options = await silgiModule.getOptions?.() || {};
547
- if (options) {
548
- silgi.options._c12.config[buildTimeModuleMeta.configKey] = defu(
549
- silgi.options._c12.config[buildTimeModuleMeta.configKey] || {},
550
- options || {}
551
- );
552
- } else {
553
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
554
- }
555
- silgi.scanModules.push({
556
- meta: buildTimeModuleMeta,
557
- entryPath: resolvedModulePath || void 0,
558
- installed: false,
559
- options,
560
- module: silgiModule
561
- });
562
- }
563
- }
564
- async function scanModules$1(silgi) {
565
- const _modules = [
566
- ...silgi.options._modules,
567
- ...silgi.options.modules
568
- ];
569
- for await (const mod of _modules) {
570
- await _resolveSilgiModule(mod, silgi);
571
- }
572
- const moduleMap = new Map(
573
- silgi.scanModules.map((m) => [m.meta?.configKey, m])
574
- );
575
- const graphData = createDependencyGraph(silgi.scanModules);
576
- const sortedKeys = topologicalSort(graphData);
577
- const modules = sortedKeys.map((key) => moduleMap.get(key)).filter((module) => Boolean(module));
578
- silgi.scanModules = modules;
579
- }
580
- function createDependencyGraph(modules) {
581
- const graph = /* @__PURE__ */ new Map();
582
- const inDegree = /* @__PURE__ */ new Map();
583
- modules.forEach((module) => {
584
- const key = module.meta?.configKey;
585
- if (key) {
586
- graph.set(key, /* @__PURE__ */ new Set());
587
- inDegree.set(key, 0);
588
- }
589
- });
590
- modules.forEach((module) => {
591
- const key = module.meta?.configKey;
592
- if (!key) {
593
- return;
594
- }
595
- const requiredDeps = module.meta?.requiredDependencies || [];
596
- const beforeDeps = module.meta?.beforeDependencies || [];
597
- const afterDeps = module.meta?.afterDependencies || [];
598
- const processedDeps = /* @__PURE__ */ new Set();
599
- requiredDeps.forEach((dep) => {
600
- if (!graph.has(dep)) {
601
- throw new Error(`Required dependency "${dep}" for module "${key}" is missing`);
602
- }
603
- graph.get(dep)?.add(key);
604
- inDegree.set(key, (inDegree.get(key) || 0) + 1);
605
- processedDeps.add(dep);
606
- });
607
- beforeDeps.forEach((dep) => {
608
- if (!graph.has(dep)) {
609
- return;
610
- }
611
- graph.get(key)?.add(dep);
612
- inDegree.set(dep, (inDegree.get(dep) || 0) + 1);
613
- });
614
- afterDeps.forEach((dep) => {
615
- if (processedDeps.has(dep)) {
616
- return;
617
- }
618
- if (!graph.has(dep)) {
619
- return;
620
- }
621
- graph.get(dep)?.add(key);
622
- inDegree.set(key, (inDegree.get(key) || 0) + 1);
623
- });
624
- });
625
- return { graph, inDegree };
626
- }
627
- function findCyclicDependencies(graph) {
628
- const visited = /* @__PURE__ */ new Set();
629
- const recursionStack = /* @__PURE__ */ new Set();
630
- const cycles = [];
631
- function dfs(node, path = []) {
632
- visited.add(node);
633
- recursionStack.add(node);
634
- path.push(node);
635
- for (const neighbor of graph.get(node) || []) {
636
- if (recursionStack.has(neighbor)) {
637
- const cycleStart = path.indexOf(neighbor);
638
- if (cycleStart !== -1) {
639
- cycles.push([...path.slice(cycleStart), neighbor]);
640
- }
641
- } else if (!visited.has(neighbor)) {
642
- dfs(neighbor, [...path]);
643
- }
644
- }
645
- recursionStack.delete(node);
646
- path.pop();
647
- }
648
- for (const node of graph.keys()) {
649
- if (!visited.has(node)) {
650
- dfs(node, []);
651
- }
652
- }
653
- return cycles;
654
- }
655
- function topologicalSort(graphData) {
656
- const { graph, inDegree } = graphData;
657
- const order = [];
658
- const queue = [];
659
- for (const [node, degree] of inDegree.entries()) {
660
- if (degree === 0) {
661
- queue.push(node);
662
- }
663
- }
664
- while (queue.length > 0) {
665
- const node = queue.shift();
666
- order.push(node);
667
- const neighbors = Array.from(graph.get(node) || []);
668
- for (const neighbor of neighbors) {
669
- const newDegree = (inDegree.get(neighbor) || 0) - 1;
670
- inDegree.set(neighbor, newDegree);
671
- if (newDegree === 0) {
672
- queue.push(neighbor);
673
- }
674
- }
675
- }
676
- if (order.length !== graph.size) {
677
- const cycles = findCyclicDependencies(graph);
678
- if (cycles.length > 0) {
679
- const cycleStr = cycles.map((cycle) => ` ${cycle.join(" -> ")}`).join("\n");
680
- throw new Error(`Circular dependencies detected:
681
- ${cycleStr}`);
682
- } else {
683
- const unresolvedModules = Array.from(graph.keys()).filter((key) => !order.includes(key));
684
- throw new Error(`Unable to resolve dependencies for modules: ${unresolvedModules.join(", ")}`);
685
- }
686
- }
687
- return order;
688
- }
689
-
690
- async function commands(silgi) {
691
- const commands2 = {
692
- ...silgi.options.commands
693
- };
694
- await silgi.callHook("prepare:commands", commands2);
695
- addTemplate({
696
- filename: "cli.json",
697
- where: ".silgi",
698
- write: true,
699
- getContents: () => JSON.stringify(commands2, null, 2)
700
- });
701
- silgi.commands = commands2;
702
- silgi.hook("prepare:schema.ts", async (object) => {
703
- const allTags = Object.values(commands2).reduce((acc, commandGroup) => {
704
- Object.values(commandGroup).forEach((command) => {
705
- if (command.tags) {
706
- command.tags.forEach((tag) => acc.add(tag));
707
- }
708
- });
709
- return acc;
710
- }, /* @__PURE__ */ new Set());
711
- const data = [
712
- "",
713
- generateTypes(
714
- await resolveSchema(
715
- {
716
- ...Object.fromEntries(Array.from(allTags.values()).map((tag) => [tag, "string"]))
717
- }
718
- ),
719
- {
720
- interfaceName: "SilgiCommandsExtended",
721
- addExport: false,
722
- addDefaults: false,
723
- allowExtraKeys: false,
724
- indentation: 0
725
- }
726
- ),
727
- ""
728
- ];
729
- object.customImports?.push(...data);
730
- });
731
- }
732
-
733
- function resolveIgnorePatterns(silgi, relativePath) {
734
- if (!silgi) {
735
- return [];
736
- }
737
- const ignorePatterns = silgi.options.ignore.flatMap((s) => resolveGroupSyntax(s));
738
- const nuxtignoreFile = join(silgi.options.rootDir, ".nuxtignore");
739
- if (existsSync(nuxtignoreFile)) {
740
- const contents = readFileSync(nuxtignoreFile, "utf-8");
741
- ignorePatterns.push(...contents.trim().split(/\r?\n/));
742
- }
743
- return ignorePatterns;
744
- }
745
- function isIgnored(pathname, silgi, _stats) {
746
- if (!silgi) {
747
- return false;
748
- }
749
- if (!silgi._ignore) {
750
- silgi._ignore = ignore(silgi.options.ignoreOptions);
751
- silgi._ignore.add(resolveIgnorePatterns(silgi));
752
- }
753
- const relativePath = relative(silgi.options.rootDir, pathname);
754
- if (relativePath[0] === "." && relativePath[1] === ".") {
755
- return false;
756
- }
757
- return !!(relativePath && silgi._ignore.ignores(relativePath));
758
- }
759
- function resolveGroupSyntax(group) {
760
- let groups = [group];
761
- while (groups.some((group2) => group2.includes("{"))) {
762
- groups = groups.flatMap((group2) => {
763
- const [head, ...tail] = group2.split("{");
764
- if (tail.length) {
765
- const [body = "", ...rest] = tail.join("{").split("}");
766
- return body.split(",").map((part) => `${head}${part}${rest.join("")}`);
767
- }
768
- return group2;
769
- });
770
- }
771
- return groups;
772
- }
773
-
774
- const safeFiles = [
775
- "silgi/configs",
776
- "silgi",
777
- "silgi/rules",
778
- "silgi/scan",
779
- "silgi/vfs"
780
- ];
781
- class SchemaParser {
782
- options = {
783
- debug: false
784
- };
785
- /**
786
- *
787
- */
788
- constructor(options) {
789
- this.options = {
790
- ...this.options,
791
- ...options
792
- };
793
- }
794
- parseExports(content, filePath) {
795
- const ast = parseSync(content, { sourceType: "module", sourceFilename: filePath });
796
- if (this.options.debug)
797
- writeFileSync(`${filePath}.ast.json`, JSON.stringify(ast.program, null, 2));
798
- return {
799
- exportVariables: (search, path) => this.parseTypeDeclarations(ast, search, path),
800
- parseInterfaceDeclarations: (search, path) => this.parseInterfaceDeclarations(ast, search, path)
801
- // parsePlugin: (path: string) => this.parsePlugin(ast, path),
802
- };
803
- }
804
- parseVariableDeclaration(ast, path) {
805
- const silgi = useSilgiCLI();
806
- if (ast.program.body.length === 0) {
807
- if (safeFiles.find((i) => path.includes(i)))
808
- return [];
809
- silgi.errors.push({
810
- type: "Parser",
811
- path
812
- });
813
- consola.warn("This file has a problem:", path);
814
- }
815
- const variableDeclarations = ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "VariableDeclaration");
816
- return variableDeclarations;
817
- }
818
- parseTSInterfaceDeclaration(ast, path = "") {
819
- const silgi = useSilgiCLI();
820
- if (ast.program.body.length === 0) {
821
- if (safeFiles.find((i) => path.includes(i)))
822
- return [];
823
- silgi.errors.push({
824
- type: "Parser",
825
- path
826
- });
827
- consola.warn("This file has a problem:", path);
828
- }
829
- const interfaceDeclarations = ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "TSInterfaceDeclaration");
830
- return interfaceDeclarations;
831
- }
832
- parseTypeDeclarations(ast, find = "", path = "") {
833
- const data = [];
834
- const variableDeclarations = this.parseVariableDeclaration(ast, path);
835
- for (const item of variableDeclarations) {
836
- for (const declaration of item.declaration.declarations) {
837
- if (declaration.init?.callee?.name === find) {
838
- const options = {};
839
- if (declaration.init.arguments) {
840
- for (const argument of declaration.init.arguments) {
841
- for (const propertie of argument.properties) {
842
- if (propertie.key.name === "name")
843
- options.pluginName = propertie.value.value;
844
- }
845
- }
846
- }
847
- for (const key in declaration.init.properties) {
848
- const property = declaration.init.properties[key];
849
- if (property.type === "ObjectProperty") {
850
- if (property.key.name === "options") {
851
- for (const key2 in property.value.properties) {
852
- const option = property.value.properties[key2];
853
- if (option.type === "ObjectProperty") {
854
- options[option.key.name] = option.value.value;
855
- }
856
- }
857
- }
858
- }
859
- }
860
- options.type = false;
861
- data.push({
862
- exportName: declaration.id.name,
863
- options,
864
- // object: declaration.init,
865
- path
866
- });
867
- }
868
- }
869
- }
870
- return data;
871
- }
872
- parseInterfaceDeclarations(ast, find = "", path = "") {
873
- const data = [];
874
- for (const item of this.parseTSInterfaceDeclaration(ast, path)) {
875
- if (!item?.declaration?.extends)
876
- continue;
877
- for (const declaration of item?.declaration?.extends) {
878
- if (declaration.expression.name === find) {
879
- const options = {};
880
- options.type = true;
881
- data.push({
882
- exportName: item.declaration.id.name,
883
- options,
884
- // object: declaration.init,
885
- path
886
- });
887
- }
888
- }
889
- }
890
- return data;
891
- }
892
- // private parsePlugin(ast: any, path: string = '') {
893
- // const data = {
894
- // export: [],
895
- // name: '',
896
- // path: '',
897
- // } as DataTypePlugin
898
- // for (const item of this.parseVariableDeclaration(ast)) {
899
- // for (const declaration of item.declaration.declarations) {
900
- // if (declaration.init.callee?.name === 'defineSilgiModule') {
901
- // if (declaration.init.arguments) {
902
- // for (const argument of declaration.init.arguments) {
903
- // for (const propertie of argument.properties) {
904
- // if (propertie.key.name === 'name')
905
- // data.name = propertie.value.value
906
- // }
907
- // }
908
- // }
909
- // data.export.push({
910
- // name: data.name,
911
- // as: camelCase(`${data.name}DefineSilgiModule`),
912
- // type: false,
913
- // })
914
- // }
915
- // }
916
- // }
917
- // for (const item of this.parseTSInterfaceDeclaration(ast)) {
918
- // if (!item?.declaration?.extends)
919
- // continue
920
- // for (const declaration of item?.declaration?.extends) {
921
- // if (declaration.expression.name === 'ModuleOptions') {
922
- // data.export.push({
923
- // name: item.declaration.id.name,
924
- // as: camelCase(`${data.name}ModuleOptions`),
925
- // type: true,
926
- // })
927
- // }
928
- // // TODO add other plugins
929
- // }
930
- // }
931
- // data.path = path
932
- // return data
933
- // }
934
- }
935
-
936
- async function scanExportFile(silgi) {
937
- const filePaths = /* @__PURE__ */ new Set();
938
- const scannedPaths = [];
939
- const dir = silgi.options.serverDir;
940
- const files = (await globby(dir, { cwd: silgi.options.rootDir, ignore: silgi.options.ignore })).sort();
941
- if (files.length) {
942
- const siblings = await readdir(dirname(dir)).catch(() => []);
943
- const directory = basename(dir);
944
- if (!siblings.includes(directory)) {
945
- const directoryLowerCase = directory.toLowerCase();
946
- const caseCorrected = siblings.find((sibling) => sibling.toLowerCase() === directoryLowerCase);
947
- if (caseCorrected) {
948
- const original = relative(silgi.options.serverDir, dir);
949
- const corrected = relative(silgi.options.serverDir, join(dirname(dir), caseCorrected));
950
- consola$1.warn(`Components not scanned from \`~/${corrected}\`. Did you mean to name the directory \`~/${original}\` instead?`);
951
- }
952
- }
953
- }
954
- for (const _file of files) {
955
- const filePath = resolve(dir, _file);
956
- if (scannedPaths.find((d) => filePath.startsWith(withTrailingSlash(d))) || isIgnored(filePath, silgi)) {
957
- continue;
958
- }
959
- if (filePaths.has(filePath)) {
960
- continue;
961
- }
962
- filePaths.add(filePath);
963
- if (silgi.options.extensions.includes(extname(filePath))) {
964
- const parser = new SchemaParser({
965
- debug: false
966
- });
967
- const readfile = await readFile(filePath, "utf-8");
968
- const { exportVariables, parseInterfaceDeclarations } = parser.parseExports(readfile, filePath);
969
- const createServices = exportVariables("createService", filePath);
970
- if (hasError("Parser", silgi)) {
971
- return;
972
- }
973
- const scanTS = [];
974
- const schemaTS = [];
975
- if (createServices.length > 0) {
976
- scanTS.push(...createServices.map(({ exportName, path }) => {
977
- const randomString = hash(basename(path) + exportName);
978
- const _name = `_v${randomString}`;
979
- return { exportName, path, _name, type: "service" };
980
- }));
981
- }
982
- const createSchemas = exportVariables("createSchema", filePath);
983
- if (hasError("Parser", silgi)) {
984
- return;
985
- }
986
- if (createSchemas.length > 0) {
987
- scanTS.push(...createSchemas.map(({ exportName, path }) => {
988
- const randomString = hash(basename(path) + exportName);
989
- const _name = `_v${randomString}`;
990
- return { exportName, path, _name, type: "schema" };
991
- }));
992
- }
993
- const createShareds = exportVariables("createShared", filePath);
994
- if (hasError("Parser", silgi)) {
995
- return;
996
- }
997
- if (createShareds.length > 0) {
998
- scanTS.push(...createShareds.map(({ exportName, path }) => {
999
- const randomString = hash(basename(path) + exportName);
1000
- const _name = `_v${randomString}`;
1001
- return { exportName, path, _name, type: "shared" };
1002
- }));
1003
- }
1004
- const sharedsTypes = parseInterfaceDeclarations("ExtendShared", filePath);
1005
- if (hasError("Parser", silgi)) {
1006
- return;
1007
- }
1008
- if (sharedsTypes.length > 0) {
1009
- schemaTS.push(...sharedsTypes.map(({ exportName, path }) => {
1010
- const randomString = hash(basename(path) + exportName);
1011
- const _name = `_v${randomString}`;
1012
- return { exportName, path, _name, type: "shared" };
1013
- }));
1014
- }
1015
- const contextTypes = parseInterfaceDeclarations("ExtendContext", filePath);
1016
- if (hasError("Parser", silgi)) {
1017
- return;
1018
- }
1019
- if (contextTypes.length > 0) {
1020
- schemaTS.push(...contextTypes.map(({ exportName, path }) => {
1021
- const randomString = hash(basename(path) + exportName);
1022
- const _name = `_v${randomString}`;
1023
- return { exportName, path, _name, type: "context" };
1024
- }));
1025
- }
1026
- silgi.hook("prepare:scan.ts", (options) => {
1027
- for (const { exportName, path, _name, type } of scanTS) {
1028
- if (!path.includes("vfs")) {
1029
- silgi.options.devServer.watch.push(path);
1030
- }
1031
- if (type === "service") {
1032
- options.services.push(_name);
1033
- }
1034
- if (type === "shared") {
1035
- options.shareds.push(_name);
1036
- }
1037
- if (type === "schema") {
1038
- options.schemas.push(_name);
1039
- }
1040
- options.importItems[path] ??= {
1041
- import: [],
1042
- from: relativeWithDot(silgi.options.silgi.serverDir, path)
1043
- };
1044
- options.importItems[path].import.push({
1045
- name: `${exportName} as ${_name}`,
1046
- key: _name
1047
- });
1048
- }
1049
- });
1050
- silgi.hook("prepare:schema.ts", (options) => {
1051
- for (const { exportName, path, _name, type } of schemaTS) {
1052
- if (!path.includes("vfs")) {
1053
- silgi.options.devServer.watch.push(path);
1054
- }
1055
- if (type === "shared") {
1056
- options.shareds.push({
1057
- key: _name,
1058
- value: _name
1059
- });
1060
- }
1061
- if (type === "context") {
1062
- options.contexts.push({
1063
- key: _name,
1064
- value: _name
1065
- });
1066
- }
1067
- options.importItems[path] ??= {
1068
- import: [],
1069
- from: relativeWithDot(silgi.options.build.typesDir, path)
1070
- };
1071
- options.importItems[path].import.push({
1072
- name: `${exportName} as ${_name}`,
1073
- key: _name
1074
- });
1075
- }
1076
- });
1077
- }
1078
- }
1079
- }
1080
-
1081
- function buildUriMap(silgi, currentPath = []) {
1082
- const uriMap = /* @__PURE__ */ new Map();
1083
- function traverse(node, path = []) {
1084
- if (!node || typeof node !== "object")
1085
- return;
1086
- if (path.length === 4) {
1087
- const basePath = path.join("/");
1088
- let pathString = "";
1089
- if (node.pathParams) {
1090
- let paths = null;
1091
- if (node.pathParams?._def?.typeName !== void 0) {
1092
- try {
1093
- const shape = node.pathParams?.shape;
1094
- paths = shape ? Object.keys(shape) : null;
1095
- } catch {
1096
- paths = null;
1097
- }
1098
- }
1099
- if (paths?.length) {
1100
- pathString = paths.map((p) => `:${p}`).join("/");
1101
- }
1102
- }
1103
- uriMap.set(basePath, pathString);
1104
- return;
1105
- }
1106
- for (const key in node) {
1107
- if (!["_type", "fields"].includes(key)) {
1108
- traverse(node[key], [...path, key]);
1109
- }
1110
- }
1111
- }
1112
- traverse(silgi.schemas, currentPath);
1113
- silgi.uris = defu(silgi.uris, Object.fromEntries(uriMap));
1114
- return uriMap;
1115
- }
1116
-
1117
- async function readScanFile(silgi) {
1118
- const path = resolve(silgi.options.silgi.serverDir, "scan.ts");
1119
- const context = await promises.readFile(path, { encoding: "utf-8" });
1120
- silgi.unimport = createUnimport(silgi.options.imports || {});
1121
- await silgi.unimport.init();
1122
- const injectedResult = await silgi.unimport.injectImports(context, path);
1123
- if (!injectedResult) {
1124
- throw new Error("Failed to inject imports");
1125
- }
1126
- const jiti = createJiti(silgi.options.rootDir, {
1127
- fsCache: true,
1128
- moduleCache: false,
1129
- debug: silgi.options.debug,
1130
- alias: silgi.options.alias
1131
- });
1132
- try {
1133
- if (silgi.options.commandType === "prepare") {
1134
- globalThis._silgi_runtime = silgi.options.runtimeConfig;
1135
- injectedResult.code = `globalThis._silgi_runtime = ${JSON.stringify(silgi.options.runtimeConfig)};
1136
- ${injectedResult.code}`;
1137
- injectedResult.code = injectedResult.code.replace(/runtimeConfig: \{\}/, `runtimeConfig: ${JSON.stringify(silgi.options.runtimeConfig)}`);
1138
- }
1139
- const scanFile = await jiti.evalModule(
1140
- injectedResult.code,
1141
- {
1142
- filename: path,
1143
- async: true,
1144
- conditions: silgi.options.conditions
1145
- },
1146
- async (data, name) => {
1147
- return (await silgi.unimport.injectImports(data, name)).code;
1148
- }
1149
- );
1150
- silgi.uris = defu(silgi.uris, scanFile.uris) || {};
1151
- silgi.schemas = defu(scanFile.schemas, scanFile.uris) || {};
1152
- silgi.services = defu(scanFile.services, scanFile.uris) || {};
1153
- silgi.shareds = defu(scanFile.shareds, scanFile.shareds) || {};
1154
- silgi.modulesURIs = defu(scanFile.modulesURIs, scanFile.modulesURIs) || {};
1155
- return {
1156
- context,
1157
- object: {
1158
- schemas: scanFile.schemas,
1159
- uris: scanFile.uris,
1160
- services: scanFile.services,
1161
- shareds: scanFile.shareds,
1162
- modulesURIs: scanFile.modulesURIs
1163
- },
1164
- path
1165
- };
1166
- } catch (error) {
1167
- if (silgi.options.debug) {
1168
- console.error("Failed to read scan.ts file:", error);
1169
- } else {
1170
- consola$1.withTag("silgi").error(error);
1171
- }
1172
- return {
1173
- context,
1174
- object: {
1175
- schemas: {},
1176
- uris: {},
1177
- services: {},
1178
- shareds: {},
1179
- modulesURIs: {}
1180
- },
1181
- path
1182
- };
1183
- }
1184
- }
1185
-
1186
- async function prepareServerFiles(silgi) {
1187
- const importItems = {
1188
- "silgi": {
1189
- import: [
1190
- { name: "createSilgi", key: "createSilgi" },
1191
- { name: "createShared", key: "createShared" }
1192
- ],
1193
- from: "silgi"
1194
- },
1195
- "silgi/types": {
1196
- import: [
1197
- { name: "SilgiRuntimeOptions", type: true, key: "SilgiRuntimeOptions" },
1198
- { name: "FrameworkContext", type: true, key: "FrameworkContext" }
1199
- ],
1200
- from: "silgi/types"
1201
- },
1202
- "#silgi/vfs": {
1203
- import: [],
1204
- from: "./vfs"
1205
- },
1206
- "configs.ts": {
1207
- import: [
1208
- {
1209
- name: "cliConfigs",
1210
- type: false,
1211
- key: "cliConfigs"
1212
- }
1213
- ],
1214
- from: "./configs.ts"
1215
- }
1216
- };
1217
- const scanned = {
1218
- uris: {},
1219
- services: [],
1220
- shareds: [
1221
- `createShared({
1222
- modulesURIs,
1223
- })`
1224
- ],
1225
- schemas: [],
1226
- modulesURIs: {},
1227
- customImports: [],
1228
- importItems
1229
- };
1230
- if (silgi.uris) {
1231
- defu(scanned.uris, silgi.uris);
1232
- }
1233
- if (silgi.modulesURIs) {
1234
- defu(scanned.modulesURIs, silgi.modulesURIs);
1235
- }
1236
- await silgi.callHook("prepare:scan.ts", scanned);
1237
- if (importItems["#silgi/vfs"].import.length === 0) {
1238
- delete importItems["#silgi/vfs"];
1239
- }
1240
- if (scanned.services.length > 0) {
1241
- importItems.silgi.import.push({ name: "mergeServices", key: "mergeServices" });
1242
- }
1243
- if (scanned.shareds.length > 0) {
1244
- importItems.silgi.import.push({ name: "mergeShared", key: "mergeShared" });
1245
- }
1246
- if (scanned.schemas.length > 0) {
1247
- importItems.silgi.import.push({ name: "mergeSchemas", key: "mergeSchemas" });
1248
- }
1249
- for (const key in importItems) {
1250
- importItems[key].import = deduplicateImportsByKey(importItems[key].import);
1251
- }
1252
- const importsContent = [
1253
- ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
1254
- if (silgi.options.typescript.removeFileExtension) {
1255
- from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
1256
- }
1257
- return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
1258
- }),
1259
- "",
1260
- ...scanned.customImports,
1261
- ""
1262
- ];
1263
- const importData = [
1264
- `export const uris = ${JSON.stringify(scanned.uris, null, 2)}`,
1265
- "",
1266
- `export const modulesURIs = ${JSON.stringify(scanned.modulesURIs, null, 2)}`,
1267
- "",
1268
- scanned.schemas.length > 0 ? "export const schemas = mergeSchemas([" : "export const schemas = {",
1269
- ...scanned.schemas.map((name) => {
1270
- return ` ${name},`;
1271
- }),
1272
- scanned.schemas.length > 0 ? "])" : "}",
1273
- "",
1274
- scanned.services.length > 0 ? "export const services = mergeServices([" : "export const services = {",
1275
- ...scanned.services.map((name) => {
1276
- return ` ${name},`;
1277
- }),
1278
- scanned.services.length > 0 ? "])" : "}",
1279
- "",
1280
- scanned.shareds.length > 0 ? "export const shareds = mergeShared([" : "export const shareds = {",
1281
- ...scanned.shareds.map((name) => {
1282
- return ` ${name},`;
1283
- }),
1284
- scanned.shareds.length > 0 ? "])" : "}",
1285
- ""
1286
- ];
1287
- await silgi.callHook("after:prepare:scan.ts", importData);
1288
- importData.unshift(...importsContent);
1289
- return importData;
1290
- }
1291
- function deduplicateImportsByKey(imports) {
1292
- const seenKeys = /* @__PURE__ */ new Map();
1293
- return imports.filter((item) => {
1294
- if (seenKeys.has(item.key)) {
1295
- return false;
1296
- }
1297
- seenKeys.set(item.key, true);
1298
- return true;
1299
- });
1300
- }
1301
-
1302
- async function writeScanFiles(silgi) {
1303
- const data = await prepareServerFiles(silgi);
1304
- if (!silgi.errors.length) {
1305
- await writeFile(
1306
- resolve(silgi.options.silgi.serverDir, "scan.ts"),
1307
- data.join("\n")
1308
- );
1309
- }
1310
- await readScanFile(silgi);
1311
- buildUriMap(silgi);
1312
- parseServices(silgi);
1313
- silgi.hook("prepare:scan.ts", (file) => {
1314
- file.uris = {
1315
- ...file.uris,
1316
- ...silgi.uris
1317
- };
1318
- file.modulesURIs = {
1319
- ...file.modulesURIs,
1320
- ...silgi.modulesURIs
1321
- };
1322
- });
1323
- }
1324
-
1325
- async function createStorageCLI(silgi) {
1326
- const storage = createStorage();
1327
- const runtime = useSilgiRuntimeConfig();
1328
- const mounts = klona({
1329
- ...silgi.options.storage,
1330
- ...silgi.options.devStorage
1331
- });
1332
- for (const [path, opts] of Object.entries(mounts)) {
1333
- if (opts.driver) {
1334
- const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
1335
- const processedOpts = replaceRuntimeValues({ ...opts }, runtime);
1336
- storage.mount(path, driver(processedOpts));
1337
- } else {
1338
- silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
1339
- }
1340
- }
1341
- return storage;
1342
- }
1343
-
1344
- async function installPackages(silgi) {
1345
- const packages = {
1346
- dependencies: {
1347
- "@fastify/deepmerge": peerDependencies["@fastify/deepmerge"],
1348
- "@silgi/ecosystem": peerDependencies["@silgi/ecosystem"],
1349
- ...silgi.options.installPackages?.dependencies
1350
- },
1351
- devDependencies: {
1352
- ...silgi.options.installPackages?.devDependencies
1353
- }
1354
- };
1355
- await silgi.callHook("prepare:installPackages", packages);
1356
- if (silgi.options.preset === "npm-package") {
1357
- packages.devDependencies = {
1358
- ...packages.devDependencies,
1359
- ...packages.dependencies
1360
- };
1361
- packages.dependencies = {};
1362
- }
1363
- addTemplate({
1364
- filename: "install.json",
1365
- where: ".silgi",
1366
- write: true,
1367
- getContents: () => JSON.stringify(packages, null, 2)
1368
- });
1369
- }
1370
-
1371
- function useCLIRuntimeConfig(silgi) {
1372
- const safeRuntimeConfig = JSON.parse(JSON.stringify(silgi.options.runtimeConfig));
1373
- silgi.hook("prepare:configs.ts", (data) => {
1374
- data.runtimeConfig = safeRuntimeConfig;
1375
- silgi.options.envOptions = silgi.options.envOptions;
1376
- });
1377
- addTemplate({
1378
- filename: "env.example",
1379
- write: true,
1380
- where: ".silgi",
1381
- getContents() {
1382
- console.log("Generating env.example");
1383
- const flattenedConfig = flattenObject(safeRuntimeConfig);
1384
- const groupedVars = {};
1385
- Object.entries(flattenedConfig).forEach(([key, { value, originalPath }]) => {
1386
- const shouldExclude = silgi.options.codegen.env.safeList.some((safePath) => {
1387
- if (safePath.length !== originalPath.length)
1388
- return false;
1389
- return safePath.every((segment, index) => segment.toLowerCase() === originalPath[index].toLowerCase());
1390
- });
1391
- if (shouldExclude)
1392
- return;
1393
- if (originalPath.length > 0) {
1394
- const firstKey = originalPath[0];
1395
- const categoryName = extractCategoryFromCamel(firstKey);
1396
- if (!groupedVars[categoryName]) {
1397
- groupedVars[categoryName] = {};
1398
- }
1399
- groupedVars[categoryName][key] = value;
1400
- } else {
1401
- if (!groupedVars.OTHER) {
1402
- groupedVars.OTHER = {};
1403
- }
1404
- groupedVars.OTHER[key] = value;
1405
- }
1406
- });
1407
- return Object.entries(groupedVars).map(([category, vars]) => {
1408
- const varsContent = Object.entries(vars).map(([key, value]) => `${key}=${value}`).join("\n");
1409
- return `# ${category}
1410
- ${varsContent}`;
1411
- }).join("\n\n");
1412
- }
1413
- });
1414
- const _sharedRuntimeConfig = initRuntimeConfig(silgi.options.envOptions, silgi.options.runtimeConfig);
1415
- silgi.options.runtimeConfig = safeRuntimeConfig;
1416
- return _sharedRuntimeConfig;
1417
- }
1418
- function extractCategoryFromCamel(str) {
1419
- if (/^[a-z]+[A-Z]/.test(str)) {
1420
- const matches = str.match(/^([a-z]+)([A-Z][a-z0-9]*)?/);
1421
- if (matches && matches[2]) {
1422
- return `${matches[1].toUpperCase()}_${matches[2].toUpperCase()}`;
1423
- }
1424
- }
1425
- return str.toUpperCase();
1426
- }
1427
- function flattenObject(obj, prefix = "SILGI", originalPath = []) {
1428
- return Object.entries(obj).reduce((acc, [key, value]) => {
1429
- const formattedKey = snakeCase(key).toUpperCase();
1430
- const newKey = `${prefix}_${formattedKey}`;
1431
- const newPath = [...originalPath, key];
1432
- if (typeof value === "object" && value !== null) {
1433
- Object.assign(acc, flattenObject(value, newKey, newPath));
1434
- } else {
1435
- acc[newKey] = { value, originalPath: newPath };
1436
- }
1437
- return acc;
1438
- }, {});
1439
- }
1440
-
1441
- const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
1442
- async function scanAndSyncOptions(silgi) {
1443
- const scannedModules = await scanModules(silgi);
1444
- silgi.options.modules = silgi.options.modules || [];
1445
- for (const modPath of scannedModules) {
1446
- if (!silgi.options.modules.includes(modPath)) {
1447
- silgi.options.modules.push(modPath);
1448
- }
1449
- }
1450
- }
1451
- async function scanModules(silgi) {
1452
- const files = await scanFiles(silgi, "silgi/modules");
1453
- return files.map((f) => f.fullPath);
1454
- }
1455
- async function scanFiles(silgi, name) {
1456
- const files = await Promise.all(
1457
- silgi.options.scanDirs.map((dir) => scanDir(silgi, dir, name))
1458
- ).then((r) => r.flat());
1459
- return files;
1460
- }
1461
- async function scanDir(silgi, dir, name) {
1462
- const fileNames = await globby(join(name, GLOB_SCAN_PATTERN), {
1463
- cwd: dir,
1464
- dot: true,
1465
- ignore: silgi.options.ignore,
1466
- absolute: true
1467
- });
1468
- return fileNames.map((fullPath) => {
1469
- return {
1470
- fullPath,
1471
- path: relative(join(dir, name), fullPath)
1472
- };
1473
- }).sort((a, b) => a.path.localeCompare(b.path));
1474
- }
1475
-
1476
- async function createSilgiCLI(config = {}, opts = {}) {
1477
- const options = await loadOptions(config, opts);
1478
- const hooks = createHooks();
1479
- const silgi = {
1480
- modulesURIs: {},
1481
- scannedURIs: /* @__PURE__ */ new Map(),
1482
- services: {},
1483
- uris: {},
1484
- shareds: {},
1485
- schemas: {},
1486
- unimport: void 0,
1487
- options,
1488
- hooks,
1489
- errors: [],
1490
- commands: {},
1491
- _requiredModules: {},
1492
- logger: consola$1.withTag("silgi"),
1493
- close: () => silgi.hooks.callHook("close", silgi),
1494
- storage: void 0,
1495
- scanModules: [],
1496
- templates: [],
1497
- callHook: hooks.callHook,
1498
- addHooks: hooks.addHooks,
1499
- hook: hooks.hook,
1500
- async updateConfig(_config) {
1501
- },
1502
- routeRules: void 0
1503
- };
1504
- await prepareEnv(options);
1505
- const routeRules = createRouteRules();
1506
- routeRules.importRules(options.routeRules ?? {});
1507
- silgi.routeRules = routeRules;
1508
- if (silgiCLICtx.tryUse()) {
1509
- silgiCLICtx.unset();
1510
- silgiCLICtx.set(silgi);
1511
- } else {
1512
- silgiCLICtx.set(silgi);
1513
- silgi.hook("close", () => silgiCLICtx.unset());
1514
- }
1515
- if (silgi.options.debug) {
1516
- createDebugger(silgi.hooks, { tag: "silgi" });
1517
- silgi.options.plugins.push({
1518
- path: join(runtimeDir, "internal/debug"),
1519
- packageImport: "silgi/runtime/internal/debug"
1520
- });
1521
- }
1522
- for (const framework of frameworkSetup) {
1523
- await framework(silgi);
1524
- }
1525
- await scanAndSyncOptions(silgi);
1526
- await scanModules$1(silgi);
1527
- await scanExportFile(silgi);
1528
- await installModules(silgi, true);
1529
- useCLIRuntimeConfig(silgi);
1530
- await writeScanFiles(silgi);
1531
- silgi.storage = await createStorageCLI(silgi);
1532
- silgi.hooks.hook("close", async () => {
1533
- await silgi.storage.dispose();
1534
- });
1535
- if (silgi.options.logLevel !== void 0) {
1536
- silgi.logger.level = silgi.options.logLevel;
1537
- }
1538
- silgi.hooks.addHooks(silgi.options.hooks);
1539
- await installModules(silgi);
1540
- await silgi.hooks.callHook("scanFiles:done", silgi);
1541
- await commands(silgi);
1542
- await installPackages(silgi);
1543
- await generateApp(silgi);
1544
- if (silgi.options.imports) {
1545
- silgi.options.imports.dirs ??= [];
1546
- silgi.options.imports.dirs = silgi.options.imports.dirs.map((dir) => {
1547
- if (typeof dir === "string") {
1548
- if (dir.startsWith("!")) {
1549
- return `!${resolveSilgiPath(dir.slice(1), options, silgi.options.rootDir)}`;
1550
- }
1551
- return resolveSilgiPath(dir, options, silgi.options.rootDir);
1552
- }
1553
- return dir;
1554
- });
1555
- silgi.options.imports.presets.push({
1556
- from: "silgi/types",
1557
- imports: autoImportTypes.map((type) => type),
1558
- type: true
1559
- });
1560
- silgi.options.imports.presets.push({
1561
- from: "silgi/types",
1562
- imports: autoImportTypes.map((type) => type),
1563
- type: true
1564
- });
1565
- silgi.options.imports.presets.push({
1566
- from: "silgi/runtime/internal/ofetch",
1567
- imports: ["createSilgiFetch", "silgi$fetch"]
1568
- });
1569
- silgi.unimport = createUnimport(silgi.options.imports);
1570
- await silgi.unimport.init();
1571
- }
1572
- await registerModuleExportScan(silgi);
1573
- await writeScanFiles(silgi);
1574
- return silgi;
1575
- }
11
+ import { useSilgiCLI } from 'silgi';
12
+ import { a as silgiCLIIClose } from '../_chunks/silgiApp.mjs';
13
+ import { l as loadOptions } from './types.mjs';
1576
14
 
1577
15
  const commonArgs = {
1578
16
  dir: {
@@ -1616,7 +54,7 @@ const command$1 = defineCommand({
1616
54
  return data?.result?.silgi?.options?.runtimeConfig || {};
1617
55
  };
1618
56
  if (!data?.result?.silgi && args.active) {
1619
- consola$1.error("Silgi not found");
57
+ consola.error("Silgi not found");
1620
58
  return;
1621
59
  }
1622
60
  const silgi = useSilgiCLI();
@@ -1647,11 +85,11 @@ const command$1 = defineCommand({
1647
85
  }
1648
86
  } else {
1649
87
  if (!silgi) {
1650
- consola$1.error("Silgi not found");
88
+ consola.error("Silgi not found");
1651
89
  return;
1652
90
  }
1653
91
  if (Object.keys(cliJson).length === 0) {
1654
- consola$1.warn("No commands found in cli.json");
92
+ consola.warn("No commands found in cli.json");
1655
93
  return;
1656
94
  }
1657
95
  const allTags = Object.values(silgi.commands).reduce((acc, commandGroup) => {