silgi 0.24.19 → 0.24.21

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.
package/dist/index.mjs CHANGED
@@ -1,4165 +1,11 @@
1
- import consola$1, { consola, createConsola } from 'consola';
2
- import { getContext, createContext } from 'unctx';
3
- import defu, { defu as defu$1 } from 'defu';
4
- import { createHooks, createDebugger } from 'hookable';
5
- import { withoutTrailingSlash, withLeadingSlash, withTrailingSlash, isRelative } from 'ufo';
6
- import { Buffer } from 'node:buffer';
7
- import { klona } from 'klona';
8
- import { useSilgiRuntimeConfig, initRuntimeConfig } from 'silgi/runtime';
9
- import { createStorage as createStorage$1, builtinDrivers, prefixStorage } from 'unstorage';
10
- import { genObjectFromRawEntries, genObjectFromRaw, genObjectFromValues } from 'knitwork';
11
- import { relative, join, resolve, dirname, isAbsolute, basename, extname } from 'pathe';
12
- import { resolveSilgiPath, relativeWithDot, resolveSilgiModule, writeFile, normalizeTemplate, useLogger, addTemplate, hash, resolveAlias, directoryToURL, hasError, parseServices, genEnsureSafeVar, isDirectory } from 'silgi/kit';
13
- import { existsSync, promises, lstatSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
14
- import { readdir, readFile } from 'node:fs/promises';
15
- import { useSilgi as useSilgi$1, replaceRuntimeValues as replaceRuntimeValues$1, silgiCtx as silgiCtx$1, autoImportTypes as autoImportTypes$1 } from 'silgi';
16
- import * as dotenv from 'dotenv';
17
- import { runtimeDir, pkgDir } from 'silgi/runtime/meta';
18
- import { scanExports, createUnimport, toExports } from 'unimport';
19
- import { peerDependencies } from 'silgi/meta';
20
- import { globby } from 'globby';
21
- import { resolveModuleExportNames, findTypeExports, findExports, resolvePath, parseNodeModulePath, lookupNodeModuleSubpath } from 'mlly';
22
- import { createJiti } from 'dev-jiti';
23
- import { h as hasInstalledModule, r as resolveSilgiPath$1 } from './_chunks/path.mjs';
24
- import { fileURLToPath } from 'node:url';
25
- import { resolveModuleURL } from 'exsolve';
26
- import { generateTypes, resolveSchema } from 'untyped';
27
- import ignore from 'ignore';
28
- import { parseSync } from '@oxc-parser/wasm';
29
- import { p as prepareEnv } from './cli/env.mjs';
30
- import { watchConfig, loadConfig } from 'c12';
31
- import { resolveCompatibilityDatesFromEnv, formatDate, resolveCompatibilityDates } from 'compatx';
32
- import { klona as klona$1 } from 'klona/full';
33
- import { isDebug, isTest } from 'std-env';
34
- import { colors } from 'consola/utils';
35
- import escapeRE from 'escape-string-regexp';
36
- import { findWorkspaceDir, readPackageJSON } from 'pkg-types';
37
- import { resolveAlias as resolveAlias$1 } from 'pathe/utils';
38
- import 'semver/functions/satisfies.js';
39
- import 'dot-prop';
40
- import '@clack/prompts';
41
-
42
- const silgiAppCtx = getContext("silgi");
43
- const silgiCtx = createContext();
44
- function useSilgiApp() {
45
- const instance = silgiAppCtx.tryUse();
46
- if (!instance) {
47
- throw new Error("Silgi instance is unavailable!");
48
- }
49
- return instance;
50
- }
51
- function normalizeResult(result) {
52
- if (Array.isArray(result)) {
53
- return [...result];
54
- }
55
- if (result && typeof result === "object") {
56
- if (Object.keys(result).every((key) => !Number.isNaN(Number(key)))) {
57
- return Object.values(result);
58
- }
59
- return { ...result };
60
- }
61
- return result;
62
- }
63
- function tryUseSilgiApp() {
64
- return silgiAppCtx.tryUse();
65
- }
66
- function useSilgi() {
67
- const instance = silgiCtx.tryUse();
68
- if (!instance) {
69
- throw new Error("Silgi instance is unavailable!");
70
- }
71
- return instance;
72
- }
73
- async function silgiClose() {
74
- const silgi = silgiCtx.tryUse();
75
- if (!silgi) {
76
- return;
77
- }
78
- await silgi.close();
79
- await silgi.callHook("close", silgi);
80
- consola.withTag("silgi").success("Process terminated");
81
- }
82
- function tryUseSilgi() {
83
- return silgiCtx.tryUse();
84
- }
85
-
86
- function patternToRegex(pattern) {
87
- let regexStr = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
88
- regexStr = regexStr.replace(/\*\*/g, ".+");
89
- regexStr = regexStr.replace(/\*/g, "[^/]+");
90
- regexStr = regexStr.replace(/:([^/]+)/g, "([^/]+)");
91
- return new RegExp(`^${regexStr}$`);
92
- }
93
- function extractParams(url, pattern) {
94
- url = withoutTrailingSlash(withLeadingSlash(url));
95
- pattern = withoutTrailingSlash(withLeadingSlash(pattern));
96
- if (!pattern.includes(":"))
97
- return null;
98
- const paramNames = [];
99
- const patternRegex = pattern.replace(/:([^/]+)/g, (_, name) => {
100
- paramNames.push(name);
101
- return "([^/]+)";
102
- });
103
- const regex = new RegExp(`^${patternRegex}$`);
104
- const matches = url.match(regex);
105
- if (!matches)
106
- return null;
107
- const params = {};
108
- paramNames.forEach((name, i) => {
109
- params[name] = matches[i + 1];
110
- });
111
- return Object.keys(params).length > 0 ? params : null;
112
- }
113
- function matchesPattern(url, pattern) {
114
- url = withoutTrailingSlash(withLeadingSlash(url));
115
- pattern = withoutTrailingSlash(withLeadingSlash(pattern));
116
- if (url === pattern)
117
- return true;
118
- if (pattern.endsWith("/**")) {
119
- const basePath = pattern.slice(0, -3);
120
- return url === basePath || url.startsWith(`${basePath}/`);
121
- }
122
- const urlParts = url.split("/");
123
- const patternParts = pattern.split("/");
124
- if (!pattern.includes("**") && urlParts.length !== patternParts.length) {
125
- return false;
126
- }
127
- if (pattern.includes("/**/")) {
128
- const [prefix, ...suffixParts] = pattern.split("/**/");
129
- const suffix = suffixParts.join("/");
130
- return url.startsWith(prefix) && (!suffix || url.endsWith(`/${suffix}`));
131
- }
132
- return patternToRegex(pattern).test(url);
133
- }
134
- function deepClone(obj) {
135
- if (obj === null || typeof obj !== "object")
136
- return obj;
137
- if (typeof obj === "function")
138
- return obj;
139
- if (Array.isArray(obj))
140
- return obj.map(deepClone);
141
- const cloned = {};
142
- for (const key in obj) {
143
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
144
- cloned[key] = deepClone(obj[key]);
145
- }
146
- }
147
- return cloned;
148
- }
149
- function mergeConfigs(...configs) {
150
- const result = {};
151
- for (const config of configs) {
152
- if (!config)
153
- continue;
154
- for (const key in config) {
155
- const value = config[key];
156
- if (value && typeof value === "object" && !Array.isArray(value) && result[key] && typeof result[key] === "object" && typeof result[key] !== "function") {
157
- const resultValue = result[key];
158
- const valueToMerge = value;
159
- result[key] = mergeConfigs(resultValue, valueToMerge);
160
- } else {
161
- result[key] = value;
162
- }
163
- }
164
- }
165
- return result;
166
- }
167
- function createRouteRules() {
168
- let _rules = {};
169
- let _mergedRules = {};
170
- let _rulesModified = false;
171
- function getRules() {
172
- return deepClone(_rules);
173
- }
174
- function importRules(config) {
175
- const normalizedConfig = {};
176
- for (const pattern in config) {
177
- normalizedConfig[withoutTrailingSlash(withLeadingSlash(pattern))] = deepClone(config[pattern]);
178
- }
179
- _rules = normalizedConfig;
180
- _rulesModified = true;
181
- updateMergeRules();
182
- }
183
- function exportRules() {
184
- return deepClone(_rules);
185
- }
186
- function addRule(pattern, config) {
187
- _rules[withoutTrailingSlash(withLeadingSlash(pattern))] = deepClone(config);
188
- _rulesModified = true;
189
- updateMergeRules();
190
- }
191
- function updateRule(pattern, config) {
192
- const normalizedPattern = withoutTrailingSlash(withLeadingSlash(pattern));
193
- if (_rules[normalizedPattern]) {
194
- _rules[normalizedPattern] = { ..._rules[normalizedPattern], ...deepClone(config) };
195
- } else {
196
- _rules[normalizedPattern] = deepClone(config);
197
- }
198
- _rulesModified = true;
199
- updateMergeRules();
200
- }
201
- function removeRule(pattern) {
202
- delete _rules[withoutTrailingSlash(withLeadingSlash(pattern))];
203
- _rulesModified = true;
204
- updateMergeRules();
205
- }
206
- function matchesRule(url, pattern) {
207
- return matchesPattern(withoutTrailingSlash(withLeadingSlash(url)), withoutTrailingSlash(withLeadingSlash(pattern)));
208
- }
209
- function getMatchingPatterns(url) {
210
- const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
211
- return Object.keys(_rules).filter((pattern) => matchesPattern(normalizedUrl, pattern)).sort((a, b) => {
212
- if (a === url)
213
- return -1;
214
- if (b === url)
215
- return 1;
216
- const aSegments = a.split("/").filter(Boolean).length;
217
- const bSegments = b.split("/").filter(Boolean).length;
218
- if (aSegments !== bSegments)
219
- return bSegments - aSegments;
220
- const aWildcards = (a.match(/\*/g) || []).length;
221
- const bWildcards = (b.match(/\*/g) || []).length;
222
- if (aWildcards !== bWildcards)
223
- return aWildcards - bWildcards;
224
- const aDoubleWildcards = (a.match(/\*\*/g) || []).length;
225
- const bDoubleWildcards = (b.match(/\*\*/g) || []).length;
226
- if (aDoubleWildcards !== bDoubleWildcards)
227
- return aDoubleWildcards - bDoubleWildcards;
228
- return b.length - a.length;
229
- });
230
- }
231
- function getConfig(url) {
232
- const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
233
- if (_rulesModified) {
234
- updateMergeRules();
235
- }
236
- if (_mergedRules[normalizedUrl]) {
237
- return deepClone(_mergedRules[normalizedUrl]);
238
- }
239
- const patterns = getMatchingPatterns(normalizedUrl);
240
- if (!patterns.length)
241
- return null;
242
- const mergedConfig = {};
243
- for (let i = patterns.length - 1; i >= 0; i--) {
244
- const pattern = patterns[i];
245
- const patternConfig = _mergedRules[pattern] || _rules[pattern];
246
- Object.assign(mergedConfig, deepClone(patternConfig));
247
- }
248
- _mergedRules[normalizedUrl] = deepClone(mergedConfig);
249
- return mergedConfig;
250
- }
251
- function computeMergedConfig(url, patterns) {
252
- const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
253
- const matchingPatterns = patterns || getMatchingPatterns(normalizedUrl);
254
- if (!matchingPatterns.length)
255
- return {};
256
- const allPatternsHaveCache = matchingPatterns.every((pattern) => !!_mergedRules[pattern]);
257
- if (allPatternsHaveCache) {
258
- return matchingPatterns.reduceRight((result, pattern) => mergeConfigs(result, deepClone(_mergedRules[pattern])), {});
259
- }
260
- return matchingPatterns.reduceRight((result, pattern) => mergeConfigs(result, deepClone(_rules[pattern])), {});
261
- }
262
- function getParams(url, pattern) {
263
- return extractParams(withoutTrailingSlash(withLeadingSlash(url)), withoutTrailingSlash(withLeadingSlash(pattern)));
264
- }
265
- function match(url) {
266
- const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
267
- const patterns = getMatchingPatterns(normalizedUrl);
268
- if (!patterns.length)
269
- return null;
270
- const bestPattern = patterns[0];
271
- return {
272
- pattern: bestPattern,
273
- config: deepClone(_rules[bestPattern]),
274
- params: getParams(normalizedUrl, bestPattern)
275
- };
276
- }
277
- function clear() {
278
- _rules = {};
279
- clearMergedRules();
280
- _rulesModified = false;
281
- }
282
- function clearMergedRules() {
283
- _mergedRules = {};
284
- _rulesModified = true;
285
- }
286
- function precomputeMergedRules(urls) {
287
- if (_rulesModified) {
288
- updateMergeRules();
289
- }
290
- for (const url of urls) {
291
- const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
292
- if (!_mergedRules[normalizedUrl]) {
293
- const patterns = getMatchingPatterns(normalizedUrl);
294
- if (patterns.length) {
295
- _mergedRules[normalizedUrl] = computeMergedConfig(normalizedUrl, patterns);
296
- }
297
- }
298
- }
299
- }
300
- function setMergedRule(url, config) {
301
- const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
302
- _mergedRules[normalizedUrl] = deepClone(config);
303
- if (url.includes("*") || url.includes(":")) {
304
- _rulesModified = false;
305
- }
306
- }
307
- function getMergedRules() {
308
- return deepClone(_mergedRules);
309
- }
310
- function configure(config) {
311
- importRules(config);
312
- }
313
- function updateMergeRules() {
314
- if (!_rulesModified) {
315
- return _mergedRules;
316
- }
317
- _mergedRules = {};
318
- const rulePatterns = Object.keys(_rules);
319
- for (const pattern of rulePatterns) {
320
- const patterns = getMatchingPatterns(pattern);
321
- _mergedRules[pattern] = computeMergedConfig(pattern, patterns);
322
- }
323
- for (const pattern of rulePatterns) {
324
- if (pattern.includes("/:")) {
325
- const segments = pattern.split("/");
326
- let partialPath = "";
327
- for (const segment of segments) {
328
- if (segment) {
329
- partialPath += `/${segment}`;
330
- if (segment.startsWith(":") && partialPath !== pattern) {
331
- const samplePath = partialPath.replace(/:\w+/g, "sample");
332
- const patterns = getMatchingPatterns(samplePath);
333
- _mergedRules[samplePath] = computeMergedConfig(samplePath, patterns);
334
- }
335
- }
336
- }
337
- }
338
- }
339
- _rulesModified = false;
340
- return _mergedRules;
341
- }
342
- return {
343
- // Public getters that return a cloned version to prevent direct modification
344
- get rules() {
345
- return getRules();
346
- },
347
- get mergedRules() {
348
- return getMergedRules();
349
- },
350
- // API methods
351
- importRules,
352
- exportRules,
353
- addRule,
354
- updateRule,
355
- removeRule,
356
- matchesRule,
357
- getMatchingPatterns,
358
- getConfig,
359
- getParams,
360
- match,
361
- clear,
362
- clearMergedRules,
363
- precomputeMergedRules,
364
- setMergedRule,
365
- getMergedRules,
366
- configure,
367
- updateMergeRules
368
- };
369
- }
370
-
371
- var HttpStatus = /* @__PURE__ */ ((HttpStatus2) => {
372
- HttpStatus2[HttpStatus2["CONTINUE"] = 100] = "CONTINUE";
373
- HttpStatus2[HttpStatus2["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
374
- HttpStatus2[HttpStatus2["PROCESSING"] = 102] = "PROCESSING";
375
- HttpStatus2[HttpStatus2["EARLY_HINTS"] = 103] = "EARLY_HINTS";
376
- HttpStatus2[HttpStatus2["OK"] = 200] = "OK";
377
- HttpStatus2[HttpStatus2["CREATED"] = 201] = "CREATED";
378
- HttpStatus2[HttpStatus2["ACCEPTED"] = 202] = "ACCEPTED";
379
- HttpStatus2[HttpStatus2["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
380
- HttpStatus2[HttpStatus2["NO_CONTENT"] = 204] = "NO_CONTENT";
381
- HttpStatus2[HttpStatus2["RESET_CONTENT"] = 205] = "RESET_CONTENT";
382
- HttpStatus2[HttpStatus2["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
383
- HttpStatus2[HttpStatus2["MULTI_STATUS"] = 207] = "MULTI_STATUS";
384
- HttpStatus2[HttpStatus2["ALREADY_REPORTED"] = 208] = "ALREADY_REPORTED";
385
- HttpStatus2[HttpStatus2["IM_USED"] = 226] = "IM_USED";
386
- HttpStatus2[HttpStatus2["MULTIPLE_CHOICES"] = 300] = "MULTIPLE_CHOICES";
387
- HttpStatus2[HttpStatus2["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
388
- HttpStatus2[HttpStatus2["FOUND"] = 302] = "FOUND";
389
- HttpStatus2[HttpStatus2["SEE_OTHER"] = 303] = "SEE_OTHER";
390
- HttpStatus2[HttpStatus2["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
391
- HttpStatus2[HttpStatus2["USE_PROXY"] = 305] = "USE_PROXY";
392
- HttpStatus2[HttpStatus2["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
393
- HttpStatus2[HttpStatus2["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
394
- HttpStatus2[HttpStatus2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
395
- HttpStatus2[HttpStatus2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
396
- HttpStatus2[HttpStatus2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
397
- HttpStatus2[HttpStatus2["FORBIDDEN"] = 403] = "FORBIDDEN";
398
- HttpStatus2[HttpStatus2["NOT_FOUND"] = 404] = "NOT_FOUND";
399
- HttpStatus2[HttpStatus2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
400
- HttpStatus2[HttpStatus2["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
401
- HttpStatus2[HttpStatus2["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
402
- HttpStatus2[HttpStatus2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
403
- HttpStatus2[HttpStatus2["CONFLICT"] = 409] = "CONFLICT";
404
- HttpStatus2[HttpStatus2["GONE"] = 410] = "GONE";
405
- HttpStatus2[HttpStatus2["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
406
- HttpStatus2[HttpStatus2["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
407
- HttpStatus2[HttpStatus2["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
408
- HttpStatus2[HttpStatus2["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
409
- HttpStatus2[HttpStatus2["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
410
- HttpStatus2[HttpStatus2["RANGE_NOT_SATISFIABLE"] = 416] = "RANGE_NOT_SATISFIABLE";
411
- HttpStatus2[HttpStatus2["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
412
- HttpStatus2[HttpStatus2["IM_A_TEAPOT"] = 418] = "IM_A_TEAPOT";
413
- HttpStatus2[HttpStatus2["MISDIRECTED_REQUEST"] = 421] = "MISDIRECTED_REQUEST";
414
- HttpStatus2[HttpStatus2["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
415
- HttpStatus2[HttpStatus2["LOCKED"] = 423] = "LOCKED";
416
- HttpStatus2[HttpStatus2["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
417
- HttpStatus2[HttpStatus2["TOO_EARLY"] = 425] = "TOO_EARLY";
418
- HttpStatus2[HttpStatus2["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
419
- HttpStatus2[HttpStatus2["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
420
- HttpStatus2[HttpStatus2["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
421
- HttpStatus2[HttpStatus2["REQUEST_HEADER_FIELDS_TOO_LARGE"] = 431] = "REQUEST_HEADER_FIELDS_TOO_LARGE";
422
- HttpStatus2[HttpStatus2["UNAVAILABLE_FOR_LEGAL_REASONS"] = 451] = "UNAVAILABLE_FOR_LEGAL_REASONS";
423
- HttpStatus2[HttpStatus2["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
424
- HttpStatus2[HttpStatus2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
425
- HttpStatus2[HttpStatus2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
426
- HttpStatus2[HttpStatus2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
427
- HttpStatus2[HttpStatus2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
428
- HttpStatus2[HttpStatus2["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
429
- HttpStatus2[HttpStatus2["VARIANT_ALSO_NEGOTIATES"] = 506] = "VARIANT_ALSO_NEGOTIATES";
430
- HttpStatus2[HttpStatus2["INSUFFICIENT_STORAGE"] = 507] = "INSUFFICIENT_STORAGE";
431
- HttpStatus2[HttpStatus2["LOOP_DETECTED"] = 508] = "LOOP_DETECTED";
432
- HttpStatus2[HttpStatus2["NOT_EXTENDED"] = 510] = "NOT_EXTENDED";
433
- HttpStatus2[HttpStatus2["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
434
- return HttpStatus2;
435
- })(HttpStatus || {});
436
- var ErrorSeverity = /* @__PURE__ */ ((ErrorSeverity2) => {
437
- ErrorSeverity2["DEBUG"] = "DEBUG";
438
- ErrorSeverity2["INFO"] = "INFO";
439
- ErrorSeverity2["WARNING"] = "WARNING";
440
- ErrorSeverity2["ERROR"] = "ERROR";
441
- ErrorSeverity2["CRITICAL"] = "CRITICAL";
442
- return ErrorSeverity2;
443
- })(ErrorSeverity || {});
444
- var ErrorCategory = /* @__PURE__ */ ((ErrorCategory2) => {
445
- ErrorCategory2["AUTHENTICATION"] = "auth";
446
- ErrorCategory2["AUTHORIZATION"] = "authorization";
447
- ErrorCategory2["VALIDATION"] = "validation";
448
- ErrorCategory2["BUSINESS"] = "business";
449
- ErrorCategory2["INFRASTRUCTURE"] = "infrastructure";
450
- ErrorCategory2["EXTERNAL"] = "external";
451
- ErrorCategory2["UNKNOWN"] = "unknown";
452
- return ErrorCategory2;
453
- })(ErrorCategory || {});
454
- class ErrorFactory {
455
- static createMetadata(metadata) {
456
- return {
457
- timestamp: Date.now(),
458
- ...metadata
459
- };
460
- }
461
- static create(options) {
462
- return new SilgiError({
463
- code: options.code ?? options.httpStatus ?? 500 /* INTERNAL_SERVER_ERROR */,
464
- message: options.message,
465
- category: options.category ?? "unknown" /* UNKNOWN */,
466
- severity: options.severity ?? "ERROR" /* ERROR */,
467
- httpStatus: options.httpStatus ?? 500 /* INTERNAL_SERVER_ERROR */,
468
- metadata: this.createMetadata(options.metadata),
469
- cause: options.cause,
470
- context: options.context
471
- });
472
- }
473
- // Predefined error creators
474
- static authenticationError(message, context) {
475
- return this.create({
476
- message,
477
- code: 401,
478
- category: "auth" /* AUTHENTICATION */,
479
- severity: "ERROR" /* ERROR */,
480
- httpStatus: 401 /* UNAUTHORIZED */,
481
- context
482
- });
483
- }
484
- static authorizationError(message, context) {
485
- return this.create({
486
- message,
487
- code: 403,
488
- category: "authorization" /* AUTHORIZATION */,
489
- severity: "ERROR" /* ERROR */,
490
- httpStatus: 403 /* FORBIDDEN */,
491
- context
492
- });
493
- }
494
- static validationError(message, context) {
495
- return this.create({
496
- message,
497
- code: 400,
498
- category: "validation" /* VALIDATION */,
499
- severity: "WARNING" /* WARNING */,
500
- httpStatus: 400 /* BAD_REQUEST */,
501
- context
502
- });
503
- }
504
- static notFoundError(message, context) {
505
- return this.create({
506
- message,
507
- code: 404,
508
- category: "business" /* BUSINESS */,
509
- severity: "WARNING" /* WARNING */,
510
- httpStatus: 404 /* NOT_FOUND */,
511
- context
512
- });
513
- }
514
- static internalError(message, cause) {
515
- return this.create({
516
- message,
517
- code: 500,
518
- category: "infrastructure" /* INFRASTRUCTURE */,
519
- severity: "CRITICAL" /* CRITICAL */,
520
- httpStatus: 500 /* INTERNAL_SERVER_ERROR */,
521
- cause
522
- });
523
- }
524
- }
525
- class SilgiError extends Error {
526
- code;
527
- category;
528
- severity;
529
- httpStatus;
530
- metadata;
531
- context;
532
- cause;
533
- constructor(error) {
534
- super(error.message);
535
- this.name = "SilgiError";
536
- this.code = error.code;
537
- this.category = error.category;
538
- this.severity = error.severity;
539
- this.httpStatus = error.httpStatus;
540
- this.metadata = error.metadata ?? { timestamp: Date.now() };
541
- this.context = error.context;
542
- this.cause = error.cause;
543
- if (Error.captureStackTrace) {
544
- Error.captureStackTrace(this, this.constructor);
545
- }
546
- }
547
- toString() {
548
- let str = `${this.name} [${this.code}] ${this.severity}: ${this.message}`;
549
- str += `
550
- Category: ${this.category}`;
551
- str += `
552
- HTTP Status: ${this.httpStatus}`;
553
- if (this.context) {
554
- str += `
555
- Context: ${JSON.stringify(this.context, null, 2)}`;
556
- }
557
- if (this.metadata) {
558
- str += `
559
- Metadata: ${JSON.stringify(this.metadata, null, 2)}`;
560
- }
561
- if (this.stack) {
562
- str += `
563
- ${this.stack}`;
564
- }
565
- return str;
566
- }
567
- toJSON() {
568
- return {
569
- name: this.name,
570
- code: this.code,
571
- message: this.message,
572
- category: this.category,
573
- severity: this.severity,
574
- httpStatus: this.httpStatus,
575
- metadata: this.metadata,
576
- context: this.context,
577
- stack: this.stack
578
- };
579
- }
580
- static isError(error) {
581
- return error instanceof SilgiError || typeof error === "object" && error !== null && "name" in error && error.name === "SilgiError";
582
- }
583
- static from(error) {
584
- if (error instanceof SilgiError) {
585
- return error;
586
- }
587
- return ErrorFactory.internalError(
588
- error instanceof Error ? error.message : String(error),
589
- error instanceof Error ? error : void 0
590
- );
591
- }
592
- }
593
- function isBaseError(error) {
594
- return typeof error === "object" && error !== null && "code" in error && "message" in error && "category" in error && "severity" in error && "httpStatus" in error;
595
- }
596
-
597
- function parseURI(uri, uris) {
598
- if (!uri) {
599
- throw ErrorFactory.create({
600
- message: "URI cannot be empty",
601
- httpStatus: HttpStatus.BAD_REQUEST,
602
- context: { uri }
603
- });
604
- }
605
- if (!uris) {
606
- throw ErrorFactory.create({
607
- message: "URIs configuration is not provided",
608
- httpStatus: HttpStatus.INTERNAL_SERVER_ERROR,
609
- context: { uri }
610
- });
611
- }
612
- const cleanUri = uri.replace(/^\/*(srn\/)?/, "").replace(/\/*$/, "");
613
- const [path, queryString] = cleanUri.split("?");
614
- const parts = path.split("/");
615
- const query = queryString ? Object.fromEntries(
616
- queryString.split("&").map((param) => param.split("="))
617
- ) : void 0;
618
- const method = query?.method ? query?.method.toLowerCase() : void 0;
619
- const namespaceName = parts[0];
620
- const serviceName = parts[1];
621
- const methodName = method || parts[2];
622
- const actionName = method ? parts[2] : parts[3];
623
- if (!namespaceName || !serviceName || !methodName || !actionName) {
624
- throw ErrorFactory.create({
625
- message: "Invalid URI format: Insufficient path segments",
626
- httpStatus: HttpStatus.BAD_REQUEST,
627
- context: {
628
- uri,
629
- cleanUri,
630
- partsLength: parts.length,
631
- method,
632
- namespaceName,
633
- serviceName,
634
- methodName,
635
- actionName
636
- }
637
- });
638
- }
639
- const baseUri = `${namespaceName}/${serviceName}/${methodName}/${actionName}`;
640
- const paramStartIndex = method ? 3 : 4;
641
- const parameters = parts.slice(paramStartIndex);
642
- const normalizedUri = method ? `${namespaceName}/${serviceName}/${method}/${actionName}${parameters.length ? `/${parameters.join("/")}` : ""}` : cleanUri;
643
- const template = uris[baseUri];
644
- if (template === void 0) {
645
- throw ErrorFactory.create({
646
- message: "No route found for URI",
647
- httpStatus: HttpStatus.NOT_FOUND,
648
- context: {
649
- uri,
650
- baseUri
651
- }
652
- });
653
- }
654
- if (template === "") {
655
- if (parameters.length > 0) {
656
- throw ErrorFactory.create({
657
- message: "No parameters expected for this route",
658
- httpStatus: HttpStatus.BAD_REQUEST,
659
- context: {
660
- uri,
661
- baseUri,
662
- extraParams: parameters
663
- }
664
- });
665
- }
666
- if (query && query.method) {
667
- delete query.method;
668
- }
669
- return {
670
- namespaceName,
671
- serviceName,
672
- methodName,
673
- actionName,
674
- raw: normalizedUri,
675
- parts: [namespaceName, serviceName, methodName, actionName],
676
- routerParams: {},
677
- query,
678
- uri: baseUri
679
- };
680
- }
681
- const routeTemplate = typeof template === "string" ? template : template.pattern;
682
- const validators = typeof template === "string" ? void 0 : template.validators;
683
- const routerParams = {};
684
- const templateParts = routeTemplate.split("/").filter(Boolean);
685
- const paramValues = parameters;
686
- let valueIndex = 0;
687
- templateParts.forEach((part) => {
688
- if (part.startsWith(":")) {
689
- const paramName = part.substring(1);
690
- const paramValue = paramValues[valueIndex];
691
- if (validators?.[paramName] && paramValue) {
692
- if (!validators[paramName](paramValue)) {
693
- throw ErrorFactory.create({
694
- message: "Invalid value for parameter",
695
- httpStatus: HttpStatus.UNPROCESSABLE_ENTITY,
696
- context: {
697
- uri,
698
- paramName,
699
- paramValue,
700
- validatorName: paramName
701
- }
702
- });
703
- }
704
- }
705
- routerParams[paramName] = paramValue || void 0;
706
- valueIndex++;
707
- } else if (part && part === paramValues[valueIndex]) {
708
- valueIndex++;
709
- }
710
- });
711
- return {
712
- namespaceName,
713
- serviceName,
714
- methodName,
715
- actionName,
716
- raw: normalizedUri,
717
- parts: [namespaceName, serviceName, methodName, actionName],
718
- routerParams,
719
- query: method ? void 0 : query,
720
- uri: baseUri
721
- };
722
- }
723
-
724
- async function findAction(silgi, uri) {
725
- const { parts } = parseURI(uri, silgi.uris);
726
- let result = silgi.services;
727
- for (const part of parts) {
728
- if (result && Object.prototype.hasOwnProperty.call(result, part)) {
729
- result = Object.assign({}, result[part]);
730
- } else {
731
- silgi.logger.fail("Action not found:", `${parts.join("/")}`);
732
- continue;
733
- }
734
- }
735
- return result;
736
- }
737
- async function scanAction(silgi) {
738
- for (const [key, _value] of Object.entries(silgi.uris)) {
739
- const segments = key.split("/").filter(Boolean);
740
- if (segments.length !== 4) {
741
- console.error(`Invalid URI format for key "${key}". URI must have exactly 4 segments in format: namespace/service/method/action`);
742
- continue;
743
- }
744
- const [namespace, service, method, action] = segments;
745
- if (!namespace || !service || !method || !action) {
746
- console.error(`Invalid URI segments for key "${key}". All segments must be non-empty`);
747
- continue;
748
- }
749
- const handler = await findAction(silgi, key);
750
- silgi.scannedHandlers.set(key, handler);
751
- }
752
- }
753
-
754
- function replaceRuntimeValues(obj, runtime) {
755
- if (!obj || typeof obj !== "object")
756
- return obj;
757
- for (const key in obj) {
758
- if (typeof obj[key] === "string" && obj[key].startsWith("runtime.")) {
759
- const runtimePath = obj[key].substring(8).split(".");
760
- let value = runtime;
761
- for (const segment of runtimePath) {
762
- if (value === void 0 || value === null)
763
- break;
764
- value = value[segment];
765
- }
766
- if (value !== void 0)
767
- obj[key] = value;
768
- } else if (typeof obj[key] === "object" && obj[key] !== null) {
769
- obj[key] = replaceRuntimeValues(obj[key], runtime);
770
- }
771
- }
772
- return obj;
773
- }
774
-
775
- async function createStorage(silgi) {
776
- const storage = createStorage$1();
777
- const runtime = useSilgiRuntimeConfig();
778
- const mounts = klona({
779
- ...silgi.options.storage,
780
- ...silgi.options.devStorage
781
- });
782
- for (const [path, opts] of Object.entries(mounts)) {
783
- if (opts.driver) {
784
- const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
785
- const processedOpts = replaceRuntimeValues({ ...opts }, runtime);
786
- storage.mount(path, driver(processedOpts));
787
- } else {
788
- silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
789
- }
790
- }
791
- return storage;
792
- }
793
- function useSilgiStorage(base = "/memory:cache") {
794
- const silgi = useSilgiApp();
795
- return base ? prefixStorage(silgi.storage, base) : silgi.storage;
796
- }
797
- async function generateStorageKey(params) {
798
- const {
799
- operation,
800
- input,
801
- keyGenerator,
802
- requestId,
803
- storageOptions
804
- } = params;
805
- const cacheScopePrefix = storageOptions?.scope === "request" ? "req" : "global";
806
- const parts = [
807
- cacheScopePrefix,
808
- // Always include scope prefix first
809
- operation.namespaceName,
810
- operation.serviceName,
811
- operation.methodName
812
- ].filter(Boolean);
813
- if (storageOptions?.scope === "request") {
814
- if (!requestId) {
815
- throw ErrorFactory.create({
816
- code: HttpStatus.BAD_REQUEST,
817
- message: "Request ID is required for request-scoped cache",
818
- context: {
819
- requestId,
820
- operation,
821
- input,
822
- storageOptions,
823
- keyGenerator
824
- }
825
- });
826
- }
827
- parts.push(requestId);
828
- }
829
- if (keyGenerator) {
830
- const customKey = await Promise.resolve(keyGenerator(input));
831
- parts.push(customKey);
832
- } else {
833
- parts.push(typeof input === "object" ? JSON.stringify(input) : String(input));
834
- }
835
- return Buffer.from(parts.join(":")).toString("base64");
836
- }
837
-
838
- async function runSilgiPlugins(silgi) {
839
- for (const plugin of silgi.plugins) {
840
- try {
841
- await plugin(silgi);
842
- } catch (error) {
843
- silgi.captureError(error, { tags: ["plugin"] });
844
- throw error;
845
- }
846
- }
847
- }
848
- async function createSilgiApp(config) {
849
- const hooks = createHooks();
850
- const silgi = {
851
- schemas: config.schemas,
852
- services: config.services ?? {},
853
- shared: config.shared ?? void 0,
854
- uris: config.uris ?? {},
855
- modulesURIs: config.modulesURIs ?? {},
856
- scannedHandlers: /* @__PURE__ */ new Map(),
857
- plugins: config.plugins ?? [],
858
- framework: config.framework ?? void 0,
859
- storage: config.options.putStorage ?? void 0,
860
- options: config.options ?? {},
861
- hooks,
862
- callHook: hooks.callHook,
863
- addHooks: hooks.addHooks,
864
- hook: hooks.hook,
865
- ready: () => {
866
- return hooks.callHook("ready", silgi);
867
- },
868
- envOptions: config.envOptions ?? {},
869
- close: () => hooks.callHook("close", silgi),
870
- logger: createConsola(defu(config.options?.consolaOptions ?? {}, {
871
- tag: "silgi"
872
- })).withTag("silgi"),
873
- captureError: config.captureError ?? (() => {
874
- }),
875
- routeRules: void 0
876
- };
877
- const routeRules = createRouteRules();
878
- routeRules.importRules(config.options.routeRules ?? {});
879
- silgi.routeRules = routeRules;
880
- silgi.hooks.addHooks(silgi.options.hooks);
881
- await runSilgiPlugins(silgi);
882
- await scanAction(silgi);
883
- if (!silgi.storage) {
884
- silgi.storage = await createStorage(silgi);
885
- }
886
- silgi.shared.storage = (...data) => {
887
- return useSilgiStorage(...data);
888
- };
889
- silgi.shared.runtimeConfig = silgi.options.runtimeConfig;
890
- if (silgiAppCtx.tryUse()) {
891
- silgiAppCtx.unset();
892
- silgiAppCtx.set(silgi);
893
- } else {
894
- silgiAppCtx.set(silgi);
895
- silgi.hook("close", () => silgiAppCtx.unset());
896
- }
897
- silgi.logger.info("Silgi installed");
898
- hooks.hookOnce("close", async () => {
899
- hooks.removeAllHooks();
900
- await silgi.storage.dispose();
901
- });
902
- return silgi;
903
- }
904
-
905
- function silgi(event) {
906
- return {
907
- execute: (uriString, input, source, queryParams) => {
908
- return execute(uriString, input, event, source, queryParams);
909
- }
910
- };
911
- }
912
- async function execute(uriString, input, event, source, queryParams) {
913
- const silgiAppCtx = useSilgiApp();
914
- const config = {
915
- returnNull: false
916
- };
917
- try {
918
- const operation = parseURI(uriString, silgiAppCtx.uris);
919
- if (!operation) {
920
- throw ErrorFactory.create({ message: "Invalid URI", httpStatus: HttpStatus.BAD_REQUEST });
921
- }
922
- let success = false;
923
- let cached = false;
924
- let result;
925
- const handler = silgiAppCtx.scannedHandlers.get(operation.uri);
926
- if (!handler) {
927
- throw ErrorFactory.create({
928
- message: "execute not found",
929
- httpStatus: HttpStatus.NOT_FOUND,
930
- context: {
931
- uri: uriString
932
- }
933
- });
934
- }
935
- await silgiAppCtx.callHook("execute:before", {
936
- operation,
937
- input,
938
- event,
939
- modules: handler.modules,
940
- source,
941
- config
942
- });
943
- if (config.returnNull) {
944
- return result;
945
- }
946
- const cacheData = await cacheExecute(input, operation, handler, event);
947
- if (cacheData?.success) {
948
- result = cacheData.data;
949
- success = cacheData.success;
950
- cached = cacheData.cached;
951
- } else {
952
- let parameters = defu$1(operation.routerParams, operation.query) || {};
953
- if (queryParams) {
954
- parameters = defu$1(queryParams, parameters);
955
- }
956
- silgiAppCtx.shared.silgi = silgi(event);
957
- result = await handler?.handler(
958
- defu$1(input, { parameters }),
959
- silgiAppCtx.shared,
960
- event,
961
- source
962
- );
963
- success = true;
964
- }
965
- await silgiAppCtx.callHook("execute:after", {
966
- operation,
967
- input,
968
- event,
969
- result,
970
- success,
971
- source,
972
- modules: handler.modules,
973
- config
974
- });
975
- if (!cached) {
976
- if (success && cacheData?.cachedKey && handler.storage) {
977
- await useSilgiStorage(handler.storage.base).setItem(cacheData.cachedKey, result, handler.storage.options);
978
- }
979
- }
980
- return result;
981
- } catch (err) {
982
- await silgiAppCtx.callHook("execute:error", {
983
- input,
984
- event,
985
- source,
986
- error: err instanceof Error ? err : new Error(String(err)),
987
- timestamp: Date.now(),
988
- config
989
- });
990
- silgiAppCtx.captureError(SilgiError.from(err), {
991
- event,
992
- tags: ["execute"]
993
- });
994
- throw err;
995
- }
996
- }
997
- async function cacheExecute(input, operation, handler, event) {
998
- if (!handler.storage)
999
- return;
1000
- const cacheKey = handler.storage ? await generateStorageKey({
1001
- operation,
1002
- input,
1003
- keyGenerator: handler.storage.key,
1004
- storageOptions: handler.storage,
1005
- requestId: event?.requestId
1006
- }) : null;
1007
- if (cacheKey) {
1008
- const cachedResult = await useSilgiStorage(handler.storage.base).getItem(cacheKey);
1009
- if (cachedResult !== null) {
1010
- return {
1011
- success: true,
1012
- data: normalizeResult(cachedResult),
1013
- cached: true,
1014
- cachedKey: cacheKey
1015
- };
1016
- }
1017
- }
1018
- return {
1019
- success: false,
1020
- data: null,
1021
- cached: false,
1022
- cachedKey: cacheKey
1023
- };
1024
- }
1025
-
1026
- function merge(items, maxLevel = 4, currentLevel = 1) {
1027
- const arrayItems = Array.isArray(items) ? items : [items];
1028
- return arrayItems.reduce((acc, item) => {
1029
- if (!item)
1030
- return acc;
1031
- Object.keys(item).forEach((key) => {
1032
- if (typeof item[key] === "object" && item[key] !== null && currentLevel < maxLevel) {
1033
- if (!acc[key] || typeof acc[key] !== "object") {
1034
- acc[key] = {};
1035
- }
1036
- acc[key] = merge([acc[key], item[key]], maxLevel, currentLevel + 1);
1037
- } else if (acc[key] === void 0) {
1038
- acc[key] = item[key];
1039
- }
1040
- });
1041
- return acc;
1042
- }, {});
1043
- }
1044
- function mergeSchemas(typesOrArray) {
1045
- return merge(typesOrArray);
1046
- }
1047
- function mergeServices(servicesOrArray) {
1048
- return merge(servicesOrArray);
1049
- }
1050
- function mergeShared(sharedOrArray) {
1051
- return merge(sharedOrArray, 1, 1);
1052
- }
1053
-
1054
- function getEvent(event) {
1055
- const silgi = useSilgiApp();
1056
- if (silgi.options.present === "h3" || silgi.options.present === "nitro" || silgi.options.present === "nuxt") {
1057
- return event.event;
1058
- }
1059
- return event;
1060
- }
1061
- function getEventContext(event) {
1062
- const _event = getEvent(event);
1063
- return _event.context;
1064
- }
1065
-
1066
- function createSchema(silgiType) {
1067
- return silgiType;
1068
- }
1069
-
1070
- function createService(variables) {
1071
- return variables;
1072
- }
1073
-
1074
- function createShared(shared) {
1075
- return shared;
1076
- }
1077
-
1078
- function storageMount(silgi) {
1079
- const _silgi = silgi || useSilgiApp();
1080
- return (base, driver) => {
1081
- const existingStorage = _silgi.storage.getMount(base);
1082
- if (existingStorage) {
1083
- return existingStorage.driver;
1084
- }
1085
- const storage = _silgi.storage.mount(base, driver);
1086
- return storage;
1087
- };
1088
- }
1089
-
1090
- const SilgiCLIDefaults = {
1091
- // General
1092
- debug: isDebug,
1093
- // timing: isDebug,
1094
- logLevel: isTest ? 1 : 3,
1095
- // runtimeConfig: { app: {}, silgi: {} },
1096
- appConfig: {},
1097
- appConfigFiles: [],
1098
- commandType: "prepare",
1099
- runtimeConfig: {
1100
- silgi: {
1101
- version: "0.0.1"
1102
- }
1103
- },
1104
- serviceParseModules: [],
1105
- storages: [],
1106
- devServer: {
1107
- watch: []
1108
- },
1109
- // Dirs
1110
- scanDirs: [],
1111
- build: {
1112
- dir: ".silgi",
1113
- typesDir: "{{ build.dir }}/types",
1114
- templates: []
1115
- },
1116
- output: {
1117
- dir: "{{ rootDir }}/.output",
1118
- serverDir: "{{ output.dir }}/server",
1119
- publicDir: "{{ output.dir }}/public"
1120
- },
1121
- serverDir: "{{ rootDir }}/server",
1122
- clientDir: "{{ rootDir }}/client",
1123
- silgi: {
1124
- serverDir: "{{ serverDir }}/silgi",
1125
- clientDir: "{{ clientDir }}/silgi",
1126
- publicDir: "{{ silgi.serverDir }}/public",
1127
- utilsDir: "{{ silgi.serverDir }}/utils",
1128
- vfsDir: "{{ silgi.serverDir }}/vfs",
1129
- typesDir: "{{ silgi.serverDir }}/types"
1130
- },
1131
- // Modules
1132
- _modules: [],
1133
- modules: [],
1134
- routeRules: {},
1135
- // Features
1136
- // experimental: {},
1137
- future: {},
1138
- storage: {},
1139
- devStorage: {},
1140
- stub: false,
1141
- // bundledStorage: [],
1142
- // publicAssets: [],
1143
- // serverAssets: [],
1144
- plugins: [],
1145
- // tasks: {},
1146
- // scheduledTasks: {},
1147
- imports: {
1148
- exclude: [],
1149
- dirs: [],
1150
- presets: [],
1151
- virtualImports: ["#silgiImports"]
1152
- },
1153
- // virtual: {},
1154
- // compressPublicAssets: false,
1155
- ignore: [],
1156
- // Dev
1157
- dev: false,
1158
- // devServer: { watch: [] },
1159
- watchOptions: {
1160
- ignoreInitial: true,
1161
- ignored: [
1162
- "**/node_modules/**",
1163
- "**/.git/**",
1164
- "**/.silgi/**",
1165
- "**/.output/**",
1166
- "**/.vscode/**",
1167
- "**/.idea/**",
1168
- "**/.nuxt/**",
1169
- "**/.next/**",
1170
- "**/.gitignore",
1171
- "**/.gitattributes",
1172
- "**/assets/**",
1173
- "**/dist/**",
1174
- "**/build/**",
1175
- "**/coverage/**",
1176
- "**/test/**",
1177
- "**/tests/**",
1178
- "**/tmp/**"
1179
- ]
1180
- },
1181
- // devProxy: {},
1182
- // Logging
1183
- // logging: {
1184
- // compressedSizes: true,
1185
- // buildSuccess: true,
1186
- // },
1187
- // Routing
1188
- // baseURL: process.env.NITRO_APP_BASE_URL || '/',
1189
- // handlers: [],
1190
- // devHandlers: [],
1191
- // errorHandler: undefined,
1192
- // Advanced
1193
- typescript: {
1194
- strict: false,
1195
- generateTsConfig: true,
1196
- // generateRuntimeConfigTypes: true,
1197
- tsconfigPath: ".silgi/types/silgi.tsconfig.json",
1198
- tsConfig: {},
1199
- customConditions: [],
1200
- generateRuntimeConfigTypes: true,
1201
- removeFileExtension: false
1202
- },
1203
- conditions: [],
1204
- nodeModulesDirs: [],
1205
- // hooks: {},
1206
- commands: {},
1207
- // Framework
1208
- framework: {
1209
- name: "h3",
1210
- version: ""
1211
- },
1212
- extensions: [".js", ".jsx", ".mjs", ".ts", ".tsx", ".vue"],
1213
- ignoreOptions: void 0
1214
- };
1215
-
1216
- const fallbackCompatibilityDate = "2025-02-04";
1217
- async function resolveCompatibilityOptions(options) {
1218
- options.compatibilityDate = resolveCompatibilityDatesFromEnv(
1219
- options.compatibilityDate
1220
- );
1221
- if (!options.compatibilityDate.default) {
1222
- options.compatibilityDate.default = await _resolveDefault(options);
1223
- }
1224
- }
1225
- let _fallbackInfoShown = false;
1226
- let _promptedUserToUpdate = false;
1227
- async function _resolveDefault(options) {
1228
- const _todayDate = formatDate(/* @__PURE__ */ new Date());
1229
- const consola = consola$1.withTag("silgi");
1230
- consola.warn(`No valid compatibility date is specified.`);
1231
- const onFallback = () => {
1232
- if (!_fallbackInfoShown) {
1233
- consola.info(
1234
- [
1235
- `Using \`${fallbackCompatibilityDate}\` as fallback.`,
1236
- ` Please specify compatibility date to avoid unwanted behavior changes:`,
1237
- ` - Add \`compatibilityDate: '${_todayDate}'\` to the config file.`,
1238
- ` - Or set \`COMPATIBILITY_DATE=${_todayDate}\` environment variable.`,
1239
- ``
1240
- ].join("\n")
1241
- );
1242
- _fallbackInfoShown = true;
1243
- }
1244
- return fallbackCompatibilityDate;
1245
- };
1246
- const shallUpdate = !_promptedUserToUpdate && await consola.prompt(
1247
- `Do you want to auto update config file to set ${colors.cyan(`compatibilityDate: '${_todayDate}'`)}?`,
1248
- {
1249
- type: "confirm",
1250
- default: true
1251
- }
1252
- );
1253
- _promptedUserToUpdate = true;
1254
- if (!shallUpdate) {
1255
- return onFallback();
1256
- }
1257
- const { updateConfig } = await import('c12/update');
1258
- const updateResult = await updateConfig({
1259
- configFile: "silgi.config",
1260
- cwd: options.rootDir,
1261
- async onCreate({ configFile }) {
1262
- const shallCreate = await consola.prompt(
1263
- `Do you want to initialize a new config in ${colors.cyan(relative(".", configFile))}?`,
1264
- {
1265
- type: "confirm",
1266
- default: true
1267
- }
1268
- );
1269
- if (shallCreate !== true) {
1270
- return false;
1271
- }
1272
- return _getDefaultNitroConfig();
1273
- },
1274
- async onUpdate(config) {
1275
- config.compatibilityDate = _todayDate;
1276
- }
1277
- }).catch((error) => {
1278
- consola.error(`Failed to update config: ${error.message}`);
1279
- return null;
1280
- });
1281
- if (updateResult?.configFile) {
1282
- consola.success(
1283
- `Compatibility date set to \`${_todayDate}\` in \`${relative(".", updateResult.configFile)}\``
1284
- );
1285
- return _todayDate;
1286
- }
1287
- return onFallback();
1288
- }
1289
- function _getDefaultNitroConfig() {
1290
- return (
1291
- /* js */
1292
- `
1293
- import { defineSilgiConfig } from 'silgi/config'
1294
-
1295
- export default defineSilgiConfig({})
1296
- `
1297
- );
1298
- }
1299
-
1300
- async function resolveImportsOptions(options) {
1301
- if (options.imports === false) {
1302
- return;
1303
- }
1304
- options.imports.presets ??= [];
1305
- options.imports.presets.push(...getSilgiImportsPreset());
1306
- if (options.preset === "h3") {
1307
- const h3Exports = await resolveModuleExportNames("h3", {
1308
- url: import.meta.url
1309
- });
1310
- options.imports.presets ??= [];
1311
- options.imports.presets.push({
1312
- from: "h3",
1313
- imports: h3Exports.filter((n) => !/^[A-Z]/.test(n) && n !== "use")
1314
- });
1315
- }
1316
- options.imports.dirs ??= [];
1317
- options.imports.dirs.push(
1318
- ...options.scanDirs.map((dir) => join(dir, "utils/**/*"))
1319
- );
1320
- if (Array.isArray(options.imports.exclude) && options.imports.exclude.length === 0) {
1321
- options.imports.exclude.push(/[/\\]\.git[/\\]/);
1322
- options.imports.exclude.push(options.build.dir);
1323
- const scanDirsInNodeModules = options.scanDirs.map((dir) => dir.match(/(?<=\/)node_modules\/(.+)$/)?.[1]).filter(Boolean);
1324
- options.imports.exclude.push(
1325
- scanDirsInNodeModules.length > 0 ? new RegExp(
1326
- `node_modules\\/(?!${scanDirsInNodeModules.map((dir) => escapeRE(dir)).join("|")})`
1327
- ) : /[/\\]node_modules[/\\]/
1328
- );
1329
- }
1330
- }
1331
- function getSilgiImportsPreset() {
1332
- return [
1333
- // TODO: buraya bizim importlarimiz gelecek.
1334
- {
1335
- from: "silgi",
1336
- imports: [
1337
- "createShared",
1338
- "useSilgiApp",
1339
- "createService",
1340
- "createSchema"
1341
- ]
1342
- },
1343
- // {
1344
- // from: 'nitropack/runtime',
1345
- // imports: ['useRuntimeConfig', 'useAppConfig'],
1346
- // },
1347
- // {
1348
- // from: 'nitropack/runtime',
1349
- // imports: ['defineNitroPlugin', 'nitroPlugin'],
1350
- // },
1351
- // {
1352
- // from: 'nitropack/runtime/internal/cache',
1353
- // imports: [
1354
- // 'defineCachedFunction',
1355
- // 'defineCachedEventHandler',
1356
- // 'cachedFunction',
1357
- // 'cachedEventHandler',
1358
- // ],
1359
- // },
1360
- {
1361
- from: "silgi",
1362
- imports: ["useSilgiStorage"]
1363
- }
1364
- // {
1365
- // from: 'nitropack/runtime/internal/renderer',
1366
- // imports: ['defineRenderHandler'],
1367
- // },
1368
- // {
1369
- // from: 'nitropack/runtime/internal/meta',
1370
- // imports: ['defineRouteMeta'],
1371
- // },
1372
- // {
1373
- // from: 'nitropack/runtime/internal/route-rules',
1374
- // imports: ['getRouteRules'],
1375
- // },
1376
- // {
1377
- // from: 'nitropack/runtime/internal/context',
1378
- // imports: ['useEvent'],
1379
- // },
1380
- // {
1381
- // from: 'nitropack/runtime/internal/task',
1382
- // imports: ['defineTask', 'runTask'],
1383
- // },
1384
- // {
1385
- // from: 'nitropack/runtime/internal/error/utils',
1386
- // imports: ['defineNitroErrorHandler'],
1387
- // },
1388
- ];
1389
- }
1390
-
1391
- async function resolvePathOptions(options) {
1392
- options.rootDir = resolve(options.rootDir || ".");
1393
- options.workspaceDir = await findWorkspaceDir(options.rootDir).catch(
1394
- () => options.rootDir
1395
- );
1396
- options.srcDir = resolve(options.srcDir || options.rootDir);
1397
- for (const key of ["srcDir"]) {
1398
- options[key] = resolve(options.rootDir, options[key]);
1399
- }
1400
- options.build.dir = resolve(options.rootDir, options.build.dir);
1401
- options.build.typesDir = resolveSilgiPath(
1402
- options.build.typesDir || SilgiCLIDefaults.build.typesDir,
1403
- options,
1404
- options.rootDir
1405
- );
1406
- if (options.preset === "npm-package") {
1407
- const packageJsonPath = resolve(options.rootDir, "package.json");
1408
- const packageJson = await readPackageJSON(packageJsonPath);
1409
- if (packageJson.name === void 0) {
1410
- throw new Error("Package name is undefined");
1411
- }
1412
- options.alias ||= {};
1413
- options.alias[packageJson.name] = join(options.rootDir, "src/module");
1414
- options.alias[`${packageJson.name}/runtime/`] = join(options.rootDir, "src/runtime");
1415
- options.alias[`${packageJson.name}/runtime/*`] = join(options.rootDir, "src/runtime/*");
1416
- options.alias[`${packageJson.name}/types`] = join(options.rootDir, "src/types");
1417
- }
1418
- if (options.stub) {
1419
- options.alias = {
1420
- ...options.alias,
1421
- "silgi/runtime": join(runtimeDir),
1422
- "#internal/silgi": join(runtimeDir),
1423
- "silgi/runtime/*": join(runtimeDir, "*"),
1424
- "#internal/silgi/*": join(runtimeDir, "*")
1425
- };
1426
- }
1427
- options.alias = {
1428
- ...options.alias,
1429
- "~/": join(options.srcDir, "/"),
1430
- "@/": join(options.srcDir, "/"),
1431
- "~~/": join(options.rootDir, "/"),
1432
- "@@/": join(options.rootDir, "/")
1433
- };
1434
- if (options.preset === "npm-package") {
1435
- options.alias = {
1436
- ...options.alias
1437
- // '#silgi/app/': join(options.build.dir, '/'),
1438
- };
1439
- }
1440
- if (options.alias && typeof options.alias === "object") {
1441
- ((options.typescript.tsConfig ??= {}).compilerOptions ??= {}).paths ??= {};
1442
- const paths = options.typescript.tsConfig.compilerOptions.paths;
1443
- for (const [key, value] of Object.entries(options.alias)) {
1444
- if (typeof paths === "object") {
1445
- paths[key] = [value];
1446
- }
1447
- }
1448
- }
1449
- if (options.typescript.tsConfig.compilerOptions?.paths && typeof options.typescript.tsConfig.compilerOptions.paths === "object") {
1450
- ((options.typescript.tsConfig ??= {}).compilerOptions ??= {}).paths ??= {};
1451
- const paths = options.typescript.tsConfig.compilerOptions.paths;
1452
- for (const [key, value] of Object.entries(options.alias)) {
1453
- if (typeof paths === "object") {
1454
- paths[key] = [value];
1455
- }
1456
- }
1457
- }
1458
- options.modulesDir = [resolve(options.rootDir, "node_modules")];
1459
- options.output.dir = resolveSilgiPath(
1460
- options.output.dir || SilgiCLIDefaults.output.dir,
1461
- options,
1462
- options.rootDir
1463
- );
1464
- options.output.publicDir = resolveSilgiPath(
1465
- options.output.publicDir || SilgiCLIDefaults.output.publicDir,
1466
- options,
1467
- options.rootDir
1468
- );
1469
- options.output.serverDir = resolveSilgiPath(
1470
- options.output.serverDir || SilgiCLIDefaults.output.serverDir,
1471
- options,
1472
- options.rootDir
1473
- );
1474
- options.serverDir = resolveSilgiPath(
1475
- options.serverDir || SilgiCLIDefaults.serverDir,
1476
- options,
1477
- options.rootDir
1478
- );
1479
- options.clientDir = resolveSilgiPath(
1480
- options.clientDir || SilgiCLIDefaults.clientDir,
1481
- options,
1482
- options.rootDir
1483
- );
1484
- options.silgi.serverDir = resolveSilgiPath(
1485
- options.silgi.serverDir || SilgiCLIDefaults.silgi.serverDir,
1486
- options,
1487
- options.rootDir
1488
- );
1489
- options.silgi.clientDir = resolveSilgiPath(
1490
- options.silgi.clientDir || SilgiCLIDefaults.silgi.clientDir,
1491
- options,
1492
- options.rootDir
1493
- );
1494
- options.silgi.publicDir = resolveSilgiPath(
1495
- options.silgi.publicDir || SilgiCLIDefaults.silgi.publicDir,
1496
- options,
1497
- options.rootDir
1498
- );
1499
- options.silgi.utilsDir = resolveSilgiPath(
1500
- options.silgi.utilsDir || SilgiCLIDefaults.silgi.utilsDir,
1501
- options,
1502
- options.rootDir
1503
- );
1504
- options.silgi.vfsDir = resolveSilgiPath(
1505
- options.silgi.vfsDir || SilgiCLIDefaults.silgi.vfsDir,
1506
- options,
1507
- options.rootDir
1508
- );
1509
- options.silgi.typesDir = resolveSilgiPath(
1510
- options.silgi.typesDir || SilgiCLIDefaults.silgi.typesDir,
1511
- options,
1512
- options.rootDir
1513
- );
1514
- options.nodeModulesDirs.push(resolve(options.workspaceDir, "node_modules"));
1515
- options.nodeModulesDirs.push(resolve(options.rootDir, "node_modules"));
1516
- options.nodeModulesDirs.push(resolve(pkgDir, "node_modules"));
1517
- options.nodeModulesDirs.push(resolve(pkgDir, ".."));
1518
- options.nodeModulesDirs = [
1519
- ...new Set(
1520
- options.nodeModulesDirs.map((dir) => resolve(options.rootDir, dir))
1521
- )
1522
- ];
1523
- options.scanDirs.unshift(options.srcDir);
1524
- options.scanDirs = options.scanDirs.map(
1525
- (dir) => resolve(options.srcDir, dir)
1526
- );
1527
- options.scanDirs = [...new Set(options.scanDirs)];
1528
- options.appConfigFiles ??= [];
1529
- options.appConfigFiles = options.appConfigFiles.map((file) => _tryResolve(resolveSilgiPath(file, options))).filter(Boolean);
1530
- for (const dir of options.scanDirs) {
1531
- const configFile = _tryResolve("app.config", dir);
1532
- if (configFile && !options.appConfigFiles.includes(configFile)) {
1533
- options.appConfigFiles.push(configFile);
1534
- }
1535
- }
1536
- }
1537
- function _tryResolve(path, base = ".", extensions = ["", ".js", ".ts", ".mjs", ".cjs", ".json"]) {
1538
- path = resolve(base, path);
1539
- if (existsSync(path)) {
1540
- return path;
1541
- }
1542
- for (const ext of extensions) {
1543
- const p = path + ext;
1544
- if (existsSync(p)) {
1545
- return p;
1546
- }
1547
- }
1548
- }
1549
-
1550
- async function resolveStorageOptions(options) {
1551
- const fsMounts = {
1552
- root: resolve(options.rootDir),
1553
- src: resolve(options.srcDir),
1554
- build: resolve(options.build.dir),
1555
- cache: resolve(options.build.dir, "cache")
1556
- };
1557
- for (const p in fsMounts) {
1558
- options.devStorage[p] = options.devStorage[p] || {
1559
- driver: "fs",
1560
- readOnly: p === "root" || p === "src",
1561
- base: fsMounts[p]
1562
- };
1563
- }
1564
- if (options.dev && options.storage.data === void 0 && options.devStorage.data === void 0) {
1565
- options.devStorage.data = {
1566
- driver: "fs",
1567
- base: resolve(options.rootDir, ".data/kv")
1568
- };
1569
- }
1570
- }
1571
-
1572
- async function resolveURLOptions(options) {
1573
- options.baseURL = withLeadingSlash(withTrailingSlash(options.baseURL));
1574
- }
1575
-
1576
- const configResolvers = [
1577
- resolveCompatibilityOptions,
1578
- resolvePathOptions,
1579
- resolveImportsOptions,
1580
- // resolveRouteRulesOptions,
1581
- // resolveDatabaseOptions,
1582
- // resolveFetchOptions,
1583
- // resolveExportConditionsOptions,
1584
- // resolveRuntimeConfigOptions,
1585
- // resolveOpenAPIOptions,
1586
- resolveURLOptions,
1587
- // resolveAssetsOptions,
1588
- resolveStorageOptions
1589
- // resolveErrorOptions,
1590
- ];
1591
- async function loadOptions(configOverrides = {}, opts = {}) {
1592
- const options = await _loadUserConfig(configOverrides, opts);
1593
- for (const resolver of configResolvers) {
1594
- await resolver(options);
1595
- }
1596
- return options;
1597
- }
1598
- async function _loadUserConfig(configOverrides = {}, opts = {}) {
1599
- const presetOverride = configOverrides.preset || process.env.SILGI_PRESET;
1600
- if (configOverrides.dev) ;
1601
- configOverrides = klona$1(configOverrides);
1602
- globalThis.defineSilgiConfig = globalThis.defineSilgiConfig || ((c) => c);
1603
- let compatibilityDate = configOverrides.compatibilityDate || opts.compatibilityDate || (process.env.SILGI_COMPATIBILITY_DATE || process.env.SERVER_COMPATIBILITY_DATE || process.env.COMPATIBILITY_DATE);
1604
- const { resolvePreset } = await import('silgi/presets');
1605
- const loadedConfig = await (opts.watch ? watchConfig : loadConfig)({
1606
- name: "silgi",
1607
- cwd: configOverrides.rootDir,
1608
- dotenv: configOverrides.dev,
1609
- extend: { extendKey: ["extends", "preset"] },
1610
- overrides: {
1611
- ...configOverrides,
1612
- preset: presetOverride
1613
- },
1614
- async defaultConfig({ configs }) {
1615
- const getConf = (key) => configs.main?.[key] ?? configs.rc?.[key] ?? configs.packageJson?.[key];
1616
- if (!compatibilityDate) {
1617
- compatibilityDate = getConf("compatibilityDate");
1618
- }
1619
- return {
1620
- // typescript: {
1621
- // generateRuntimeConfigTypes:
1622
- // !framework?.name || framework.name === 'nitro',
1623
- // },
1624
- preset: presetOverride || (await resolvePreset("", {
1625
- static: getConf("static"),
1626
- compatibilityDate: compatibilityDate || fallbackCompatibilityDate
1627
- }))?._meta?.name
1628
- };
1629
- },
1630
- defaults: SilgiCLIDefaults,
1631
- jitiOptions: {
1632
- alias: {
1633
- "silgi/config": "silgi/config"
1634
- }
1635
- },
1636
- async resolve(id) {
1637
- const preset = await resolvePreset(id, {
1638
- static: configOverrides.static,
1639
- compatibilityDate: compatibilityDate || fallbackCompatibilityDate
1640
- });
1641
- if (preset) {
1642
- return {
1643
- config: klona$1(preset)
1644
- };
1645
- }
1646
- },
1647
- ...opts.c12
1648
- });
1649
- delete globalThis.defineSilgiConfig;
1650
- const options = klona$1(loadedConfig.config);
1651
- options._config = configOverrides;
1652
- options._c12 = loadedConfig;
1653
- const _presetName = (loadedConfig.layers || []).find((l) => l.config?._meta?.name)?.config?._meta?.name || presetOverride;
1654
- options.preset = _presetName;
1655
- options.compatibilityDate = resolveCompatibilityDates(
1656
- compatibilityDate,
1657
- options.compatibilityDate
1658
- );
1659
- return options;
1660
- }
1661
-
1662
- function getDirectory(p) {
1663
- try {
1664
- return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
1665
- } catch {
1666
- }
1667
- return p;
1668
- }
1669
- function renderAttrs(obj) {
1670
- const attrs = [];
1671
- for (const key in obj) {
1672
- attrs.push(renderAttr(key, obj[key]));
1673
- }
1674
- return attrs.join(" ");
1675
- }
1676
- function renderAttr(key, value) {
1677
- return value ? `${key}="${value}"` : "";
1678
- }
1679
- async function silgiGenerateType(silgi) {
1680
- const rootDirWithSlash = withTrailingSlash(silgi.options.rootDir);
1681
- const tsConfigPath = resolve(
1682
- silgi.options.rootDir,
1683
- silgi.options.typescript.tsconfigPath
1684
- );
1685
- const tsconfigDir = dirname(tsConfigPath);
1686
- const include = /* @__PURE__ */ new Set([
1687
- relativeWithDot(tsconfigDir, join(silgi.options.build.typesDir, "silgi.d.ts")).replace(
1688
- /^(?=[^.])/,
1689
- "./"
1690
- ),
1691
- join(relativeWithDot(tsconfigDir, silgi.options.rootDir), "**/*"),
1692
- ...silgi.options.srcDir === silgi.options.rootDir ? [] : [join(relativeWithDot(tsconfigDir, silgi.options.srcDir), "**/*")]
1693
- ]);
1694
- const exclude = /* @__PURE__ */ new Set([
1695
- // nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
1696
- relativeWithDot(tsconfigDir, "node_modules"),
1697
- relativeWithDot(tsconfigDir, "dist")
1698
- ]);
1699
- for (const dir of silgi.options.modulesDir) {
1700
- exclude.add(relativeWithDot(silgi.options.build.dir, dir));
1701
- }
1702
- const moduleEntryPaths = [];
1703
- for (const m of silgi.scanModules) {
1704
- if (m.entryPath) {
1705
- moduleEntryPaths.push(getDirectory(m.entryPath));
1706
- }
1707
- }
1708
- const modulePaths = await resolveSilgiModule(rootDirWithSlash, moduleEntryPaths);
1709
- for (const path of modulePaths) {
1710
- const relative2 = relativeWithDot(tsconfigDir, path);
1711
- include.add(join(relative2, "runtime"));
1712
- exclude.add(join(relative2, "runtime/server"));
1713
- include.add(join(relative2, "dist/runtime"));
1714
- exclude.add(join(relative2, "dist/runtime/server"));
1715
- }
1716
- const userTsConfig = {
1717
- compilerOptions: {
1718
- /* Base options: */
1719
- esModuleInterop: true,
1720
- allowSyntheticDefaultImports: true,
1721
- skipLibCheck: true,
1722
- allowImportingTsExtensions: true,
1723
- /* Target options: */
1724
- target: "ESNext",
1725
- allowJs: true,
1726
- resolveJsonModule: true,
1727
- moduleDetection: "force",
1728
- isolatedModules: true,
1729
- verbatimModuleSyntax: true,
1730
- /* Strictness */
1731
- strict: silgi.options.typescript.strict,
1732
- noUncheckedIndexedAccess: true,
1733
- noImplicitOverride: true,
1734
- forceConsistentCasingInFileNames: true,
1735
- /* If NOT transpiling with TypeScript: */
1736
- module: "Preserve",
1737
- customConditions: silgi.options.typescript.customConditions,
1738
- paths: {
1739
- // '#silgiImports': [
1740
- // relativeWithDot(tsconfigDir, join(silgi.options.build.typesDir, 'silgi-imports')),
1741
- // ],
1742
- ...silgi.scanModules.reduce((acc, m) => {
1743
- if (m.entryPath) {
1744
- acc[m.meta.name] = [relativeWithDot(tsconfigDir, m.entryPath)];
1745
- }
1746
- return acc;
1747
- }, {}),
1748
- ...silgi.scanModules.reduce((acc, m) => {
1749
- if (m.entryPath) {
1750
- const directory = getDirectory(m.entryPath);
1751
- acc[`${m.meta.name}/*`] = [`${relativeWithDot(tsconfigDir, directory)}/*`];
1752
- }
1753
- return acc;
1754
- }, {})
1755
- }
1756
- },
1757
- include: [...include],
1758
- exclude: [...exclude]
1759
- };
1760
- const npmPackageTsConfig = {
1761
- compilerOptions: {
1762
- target: "es2022",
1763
- lib: ["es2022", "webworker", "dom.iterable"],
1764
- moduleDetection: "force",
1765
- /* If NOT transpiling with TypeScript: */
1766
- module: "preserve",
1767
- paths: {},
1768
- resolveJsonModule: true,
1769
- allowJs: true,
1770
- /* Strictness */
1771
- strict: true,
1772
- noImplicitOverride: true,
1773
- noEmit: true,
1774
- allowSyntheticDefaultImports: true,
1775
- /* Base options: */
1776
- esModuleInterop: false,
1777
- forceConsistentCasingInFileNames: true,
1778
- isolatedModules: true,
1779
- verbatimModuleSyntax: true,
1780
- skipLibCheck: true
1781
- },
1782
- // include: ['src', 'test', './moduleTypes.d.ts'],
1783
- // exclude: ['dist', 'examples', 'playground', 'test/fixture'],
1784
- include: [...include],
1785
- exclude: [...exclude]
1786
- };
1787
- const tsConfig = defu$1(
1788
- silgi.options.typescript?.tsConfig,
1789
- silgi.options.preset === "npm-package" ? npmPackageTsConfig : userTsConfig
1790
- );
1791
- tsConfig.compilerOptions ||= {};
1792
- tsConfig.compilerOptions.paths ||= {};
1793
- tsConfig.include ||= [];
1794
- for (const alias in tsConfig.compilerOptions.paths) {
1795
- const paths = tsConfig.compilerOptions.paths[alias];
1796
- tsConfig.compilerOptions.paths[alias] = await Promise.all(
1797
- paths.map(async (path) => {
1798
- if (!isAbsolute(path)) {
1799
- return path;
1800
- }
1801
- const stats = await promises.stat(path).catch(
1802
- () => null
1803
- /* file does not exist */
1804
- );
1805
- return relativeWithDot(
1806
- tsconfigDir,
1807
- stats?.isFile() ? path.replace(/\b\.\w+$/g, "") : path
1808
- );
1809
- })
1810
- );
1811
- }
1812
- const references = [];
1813
- await Promise.all([...silgi.options.modules, ...silgi.options._modules].map(async (id) => {
1814
- if (typeof id !== "string") {
1815
- return;
1816
- }
1817
- if (id === "./src" && silgi.options.preset === "npm-package") {
1818
- id = resolve(silgi.options.rootDir);
1819
- }
1820
- const pkg = await readPackageJSON(id, { url: silgi.options.rootDir }).catch(() => null);
1821
- references.push({ types: pkg?.name || id });
1822
- }));
1823
- const declarations = [];
1824
- await silgi.callHook("prepare:types", { references, declarations, tsConfig });
1825
- tsConfig.include = [...new Set(tsConfig.include.map((p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p))];
1826
- tsConfig.exclude = [...new Set(tsConfig.exclude.map((p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p))];
1827
- const _declarations = [
1828
- ...references.map((ref) => {
1829
- if ("path" in ref && isAbsolute(ref.path)) {
1830
- ref.path = relative(silgi.options.build.dir, ref.path);
1831
- }
1832
- return `/// <reference ${renderAttrs(ref)} />`;
1833
- }),
1834
- ...declarations,
1835
- "",
1836
- "export {}",
1837
- ""
1838
- ];
1839
- return {
1840
- declarations: _declarations,
1841
- tsConfig
1842
- };
1843
- }
1844
-
1845
- async function prepareBuild(silgi) {
1846
- try {
1847
- if (!silgi?.routeRules?.exportRules) {
1848
- throw new Error("Invalid silgi configuration: routeRules or exportRules is undefined");
1849
- }
1850
- const exportedRules = silgi.routeRules.exportRules();
1851
- if (!exportedRules || typeof exportedRules !== "object") {
1852
- throw new Error("No valid route rules to export");
1853
- }
1854
- const content = `/* eslint-disable */
1855
- // @ts-nocheck
1856
- // This file is auto-generated at build time by Silgi
1857
- // Contains route rules with preserved functions
1858
- // DO NOT MODIFY THIS FILE DIRECTLY
1859
-
1860
- export const routeRules = ${genObjectFromRawEntries(
1861
- Object.entries(exportedRules).map(([key, value]) => {
1862
- if (typeof value === "function") {
1863
- return [key, genObjectFromRaw(value)];
1864
- }
1865
- return [key, genObjectFromValues(value)];
1866
- })
1867
- )}
1868
- `;
1869
- const serverDir = silgi.options.silgi.serverDir;
1870
- if (!serverDir) {
1871
- throw new Error("Server directory not defined in configuration");
1872
- }
1873
- const file = join(serverDir, "rules.ts");
1874
- if (!silgi.errors.length) {
1875
- await writeFile(file, content);
1876
- }
1877
- } catch (error) {
1878
- console.error("\u274C Failed to prepare build:", error instanceof Error ? error.message : String(error));
1879
- throw error;
1880
- }
1881
- }
1882
-
1883
- async function prepare(_silgi) {
1884
- }
1885
-
1886
- async function reloadScan(path, _stats) {
1887
- const silgi = useSilgi$1();
1888
- await silgi.callHook("reload:scan", path, _stats);
1889
- }
1890
-
1891
- async function setupDotenv(options) {
1892
- const targetEnvironment = options.env ?? process.env;
1893
- const environment = await loadDotenv({
1894
- cwd: options.cwd,
1895
- fileName: options.fileName ?? ".env",
1896
- env: targetEnvironment,
1897
- interpolate: options.interpolate ?? true
1898
- });
1899
- for (const key in environment) {
1900
- if (!key.startsWith("_") && targetEnvironment[key] === void 0) {
1901
- targetEnvironment[key] = environment[key];
1902
- }
1903
- }
1904
- return environment;
1905
- }
1906
- async function loadDotenv(options) {
1907
- const environment = /* @__PURE__ */ Object.create(null);
1908
- const dotenvFile = resolve(options.cwd, options.fileName);
1909
- if (existsSync(dotenvFile)) {
1910
- const parsed = dotenv.parse(await promises.readFile(dotenvFile, "utf8"));
1911
- Object.assign(environment, parsed);
1912
- }
1913
- if (!options.env?._applied) {
1914
- Object.assign(environment, options.env);
1915
- environment._applied = true;
1916
- }
1917
- if (options.interpolate) {
1918
- interpolate(environment);
1919
- }
1920
- return environment;
1921
- }
1922
- function interpolate(target, source = {}, parse = (v) => v) {
1923
- function getValue(key) {
1924
- return source[key] === void 0 ? target[key] : source[key];
1925
- }
1926
- function interpolate2(value, parents = []) {
1927
- if (typeof value !== "string") {
1928
- return value;
1929
- }
1930
- const matches = value.match(/(.?\$\{?[\w:]*\}?)/g) || [];
1931
- return parse(
1932
- matches.reduce((newValue, match) => {
1933
- const parts = /(.?)\$\{?([\w:]+)?\}?/.exec(match) || [];
1934
- const prefix = parts[1];
1935
- let value2, replacePart;
1936
- if (prefix === "\\") {
1937
- replacePart = parts[0] || "";
1938
- value2 = replacePart.replace(String.raw`\$`, "$");
1939
- } else {
1940
- const key = parts[2];
1941
- replacePart = (parts[0] || "").slice(prefix.length);
1942
- if (parents.includes(key)) {
1943
- console.warn(
1944
- `Please avoid recursive environment variables ( loop: ${parents.join(
1945
- " > "
1946
- )} > ${key} )`
1947
- );
1948
- return "";
1949
- }
1950
- value2 = getValue(key);
1951
- value2 = interpolate2(value2, [...parents, key]);
1952
- }
1953
- return value2 === void 0 ? newValue : newValue.replace(replacePart, value2);
1954
- }, value)
1955
- );
1956
- }
1957
- for (const key in target) {
1958
- target[key] = interpolate2(getValue(key));
1959
- }
1960
- }
1961
-
1962
- const vueShim = {
1963
- filename: "delete/testtest.d.ts",
1964
- where: ".silgi",
1965
- getContents: ({ app }) => {
1966
- if (!app.options.typescript.shim) {
1967
- return "";
1968
- }
1969
- return [
1970
- "declare module '*.vue' {",
1971
- " import { DefineComponent } from 'vue'",
1972
- " const component: DefineComponent<{}, {}, any>",
1973
- " export default component",
1974
- "}"
1975
- ].join("\n");
1976
- }
1977
- };
1978
- const pluginsDeclaration = {
1979
- filename: "delete/testtest1.d.ts",
1980
- where: ".silgi",
1981
- getContents: async () => {
1982
- return `
1983
- declare module 'nuxt' {
1984
- interface NuxtApp {
1985
- $myPlugin: any;
1986
- }
1987
- }
1988
- `;
1989
- }
1990
- };
1991
-
1992
- const defaultTemplates = {
1993
- __proto__: null,
1994
- pluginsDeclaration: pluginsDeclaration,
1995
- vueShim: vueShim
1996
- };
1997
-
1998
- const postTemplates = [
1999
- pluginsDeclaration.filename
2000
- ];
2001
- const logger = useLogger("silgi");
2002
- async function generateApp(app, options = {}) {
2003
- app.templates = Object.values(defaultTemplates).concat(app.options.build.templates);
2004
- await app.callHook("app:templates", app);
2005
- app.templates = app.templates.map((tmpl) => {
2006
- const dir = tmpl.where === ".silgi" ? app.options.build.dir : tmpl.where === "server" ? app.options.silgi.serverDir : tmpl.where === "client" ? app.options.silgi.clientDir : app.options.silgi.vfsDir;
2007
- return normalizeTemplate(tmpl, dir);
2008
- });
2009
- const filteredTemplates = {
2010
- pre: [],
2011
- post: []
2012
- };
2013
- for (const template of app.templates) {
2014
- if (options.filter && !options.filter(template)) {
2015
- continue;
2016
- }
2017
- const key = template.filename && postTemplates.includes(template.filename) ? "post" : "pre";
2018
- filteredTemplates[key].push(template);
2019
- }
2020
- const templateContext = { app };
2021
- const writes = [];
2022
- const dirs = /* @__PURE__ */ new Set();
2023
- const changedTemplates = [];
2024
- async function processTemplate(template) {
2025
- const dir = template.where === ".silgi" ? app.options.build.dir : template.where === "server" ? app.options.silgi.serverDir : template.where === "client" ? app.options.silgi.clientDir : app.options.silgi.vfsDir;
2026
- const fullPath = template.dst || resolve(dir, template.filename);
2027
- const start = performance.now();
2028
- const contents = await compileTemplate(template, templateContext).catch((e) => {
2029
- logger.error(`Could not compile template \`${template.filename}\`.`);
2030
- logger.error(e);
2031
- throw e;
2032
- });
2033
- template.modified = true;
2034
- if (template.modified) {
2035
- changedTemplates.push(template);
2036
- }
2037
- const perf = performance.now() - start;
2038
- const setupTime = Math.round(perf * 100) / 100;
2039
- if (app.options.debug || setupTime > 500) {
2040
- logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`);
2041
- }
2042
- if (template.modified && template.write) {
2043
- dirs.add(dirname(fullPath));
2044
- if (template.skipIfExists && existsSync(fullPath)) {
2045
- return;
2046
- }
2047
- writes.push(() => writeFileSync(fullPath, contents, "utf8"));
2048
- }
2049
- }
2050
- await Promise.allSettled(filteredTemplates.pre.map(processTemplate));
2051
- await Promise.allSettled(filteredTemplates.post.map(processTemplate));
2052
- for (const dir of dirs) {
2053
- mkdirSync(dir, { recursive: true });
2054
- }
2055
- for (const write of writes) {
2056
- if (!app.errors.length) {
2057
- write();
2058
- }
2059
- }
2060
- if (changedTemplates.length) {
2061
- await app.callHook("app:templatesGenerated", app, changedTemplates, options);
2062
- }
2063
- }
2064
- async function compileTemplate(template, ctx) {
2065
- delete ctx.utils;
2066
- if (template.src) {
2067
- try {
2068
- return await promises.readFile(template.src, "utf-8");
2069
- } catch (err) {
2070
- logger.error(`[nuxt] Error reading template from \`${template.src}\``);
2071
- throw err;
2072
- }
2073
- }
2074
- if (template.getContents) {
2075
- return template.getContents({
2076
- ...ctx,
2077
- options: template.options
2078
- });
2079
- }
2080
- throw new Error(`[nuxt] Invalid template. Templates must have either \`src\` or \`getContents\`: ${JSON.stringify(template)}`);
2081
- }
2082
-
2083
- async function installPackages(silgi) {
2084
- const packages = {
2085
- dependencies: {
2086
- "@fastify/deepmerge": peerDependencies["@fastify/deepmerge"],
2087
- "@silgi/ecosystem": peerDependencies["@silgi/ecosystem"],
2088
- ...silgi.options.installPackages?.dependencies
2089
- },
2090
- devDependencies: {
2091
- ...silgi.options.installPackages?.devDependencies
2092
- }
2093
- };
2094
- await silgi.callHook("prepare:installPackages", packages);
2095
- if (silgi.options.preset === "npm-package") {
2096
- packages.devDependencies = {
2097
- ...packages.devDependencies,
2098
- ...packages.dependencies
2099
- };
2100
- packages.dependencies = {};
2101
- }
2102
- addTemplate({
2103
- filename: "install.json",
2104
- where: ".silgi",
2105
- write: true,
2106
- getContents: () => JSON.stringify(packages, null, 2)
2107
- });
2108
- }
2109
-
2110
- function useCLIRuntimeConfig(silgi) {
2111
- const safeRuntimeConfig = JSON.parse(JSON.stringify(silgi.options.runtimeConfig));
2112
- silgi.hook("prepare:configs.ts", (data) => {
2113
- data.runtimeConfig = safeRuntimeConfig;
2114
- silgi.options.envOptions = silgi.options.envOptions;
2115
- });
2116
- const _sharedRuntimeConfig = initRuntimeConfig(silgi.options.envOptions, silgi.options.runtimeConfig);
2117
- silgi.options.runtimeConfig = _sharedRuntimeConfig;
2118
- return _sharedRuntimeConfig;
2119
- }
2120
-
2121
- const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
2122
- async function scanAndSyncOptions(silgi) {
2123
- const scannedModules = await scanModules$1(silgi);
2124
- silgi.options.modules = silgi.options.modules || [];
2125
- for (const modPath of scannedModules) {
2126
- if (!silgi.options.modules.includes(modPath)) {
2127
- silgi.options.modules.push(modPath);
2128
- }
2129
- }
2130
- }
2131
- async function scanModules$1(silgi) {
2132
- const files = await scanFiles(silgi, "silgi/modules");
2133
- return files.map((f) => f.fullPath);
2134
- }
2135
- async function scanFiles(silgi, name) {
2136
- const files = await Promise.all(
2137
- silgi.options.scanDirs.map((dir) => scanDir(silgi, dir, name))
2138
- ).then((r) => r.flat());
2139
- return files;
2140
- }
2141
- async function scanDir(silgi, dir, name) {
2142
- const fileNames = await globby(join(name, GLOB_SCAN_PATTERN), {
2143
- cwd: dir,
2144
- dot: true,
2145
- ignore: silgi.options.ignore,
2146
- absolute: true
2147
- });
2148
- return fileNames.map((fullPath) => {
2149
- return {
2150
- fullPath,
2151
- path: relative(join(dir, name), fullPath)
2152
- };
2153
- }).sort((a, b) => a.path.localeCompare(b.path));
2154
- }
2155
-
2156
- async function emptyFramework(silgi) {
2157
- if (silgi.options.preset === "npm-package" || !silgi.options.preset) {
2158
- silgi.hook("after:prepare:schema.ts", (data) => {
2159
- data.unshift("type FrameworkContextExtends = {}");
2160
- });
2161
- }
2162
- }
2163
-
2164
- async function h3Framework(silgi, skip = false) {
2165
- if (silgi.options.preset !== "h3" && skip === false)
2166
- return;
2167
- if (silgi.options.preset === "h3") {
2168
- silgi.hook("after:prepare:schema.ts", (data) => {
2169
- data.unshift("type FrameworkContextExtends = NitroApp");
2170
- });
2171
- }
2172
- silgi.hook("prepare:schema.ts", (data) => {
2173
- data.importItems.nitropack = {
2174
- import: [
2175
- {
2176
- name: "NitroApp",
2177
- type: true,
2178
- key: "NitroApp"
2179
- }
2180
- ],
2181
- from: "nitropack/types"
2182
- };
2183
- data.importItems.h3 = {
2184
- import: [
2185
- {
2186
- name: "H3Event",
2187
- type: true,
2188
- key: "H3Event"
2189
- }
2190
- ],
2191
- from: "h3"
2192
- };
2193
- data.events.push({
2194
- key: "H3Event",
2195
- value: "H3Event",
2196
- extends: true,
2197
- isSilgiContext: false
2198
- });
2199
- });
2200
- silgi.hook("prepare:createDTSFramework", (data) => {
2201
- data.importItems["silgi/types"] = {
2202
- import: [
2203
- {
2204
- name: "SilgiRuntimeContext",
2205
- type: true,
2206
- key: "SilgiRuntimeContext"
2207
- }
2208
- ],
2209
- from: "silgi/types"
2210
- };
2211
- data.customContent?.push(
2212
- "",
2213
- 'declare module "h3" {',
2214
- " interface H3EventContext extends SilgiRuntimeContext {}",
2215
- "}",
2216
- ""
2217
- );
2218
- });
2219
- silgi.hook("prepare:core.ts", (data) => {
2220
- data._silgiConfigs.push(`captureError: (error, context = {}) => {
2221
- const promise = silgi.hooks
2222
- .callHookParallel('error', error, context)
2223
- .catch((error_) => {
2224
- console.error('Error while capturing another error', error_)
2225
- })
2226
-
2227
- if (context.event && isEvent(context.event)) {
2228
- const errors = context.event.context.nitro?.errors
2229
- if (errors) {
2230
- errors.push({ error, context })
2231
- }
2232
- if (context.event.waitUntil) {
2233
- context.event.waitUntil(promise)
2234
- }
2235
- }
2236
- }`);
2237
- });
2238
- if (silgi.options.imports !== false) {
2239
- const h3Exports = await resolveModuleExportNames("h3", {
2240
- url: import.meta.url
2241
- });
2242
- silgi.options.imports.presets ??= [];
2243
- silgi.options.imports.presets.push({
2244
- from: "h3",
2245
- imports: h3Exports.filter((n) => !/^[A-Z]/.test(n) && n !== "use")
2246
- });
2247
- }
2248
- }
2249
-
2250
- async function nitroFramework(silgi, skip = false) {
2251
- if (silgi.options.preset !== "nitro" && skip === false)
2252
- return;
2253
- silgi.hook("prepare:schema.ts", (data) => {
2254
- data.importItems.nitropack = {
2255
- import: [
2256
- {
2257
- name: "NitroApp",
2258
- type: true,
2259
- key: "NitroApp"
2260
- }
2261
- ],
2262
- from: "nitropack/types"
2263
- };
2264
- });
2265
- silgi.hook("after:prepare:schema.ts", (data) => {
2266
- data.unshift("type FrameworkContextExtends = NitroApp");
2267
- });
2268
- silgi.options.plugins.push({
2269
- packageImport: "silgi/runtime/internal/nitro",
2270
- path: join(runtimeDir, "internal/nitro")
2271
- });
2272
- silgi.hook("prepare:createDTSFramework", (data) => {
2273
- data.importItems["nitropack/types"] = {
2274
- import: [
2275
- {
2276
- name: "NitroRuntimeConfig",
2277
- type: true,
2278
- key: "NitroRuntimeConfig"
2279
- }
2280
- ],
2281
- from: "nitropack/types"
2282
- };
2283
- data.customContent?.push(
2284
- "",
2285
- 'declare module "silgi/types" {',
2286
- " interface SilgiRuntimeConfig extends NitroRuntimeConfig {}",
2287
- "}",
2288
- ""
2289
- );
2290
- });
2291
- if (silgi.options.imports !== false) {
2292
- silgi.options.imports.presets ??= [];
2293
- silgi.options.imports.presets.push(...getNitroImportsPreset());
2294
- }
2295
- await h3Framework(silgi, true);
2296
- }
2297
- function getNitroImportsPreset() {
2298
- return [
2299
- {
2300
- from: "nitropack/runtime/internal/app",
2301
- imports: ["useNitroApp"]
2302
- },
2303
- {
2304
- from: "nitropack/runtime/internal/config",
2305
- imports: ["useRuntimeConfig", "useAppConfig"]
2306
- },
2307
- {
2308
- from: "nitropack/runtime/internal/plugin",
2309
- imports: ["defineNitroPlugin", "nitroPlugin"]
2310
- },
2311
- {
2312
- from: "nitropack/runtime/internal/cache",
2313
- imports: [
2314
- "defineCachedFunction",
2315
- "defineCachedEventHandler",
2316
- "cachedFunction",
2317
- "cachedEventHandler"
2318
- ]
2319
- },
2320
- {
2321
- from: "nitropack/runtime/internal/storage",
2322
- imports: ["useStorage"]
2323
- },
2324
- {
2325
- from: "nitropack/runtime/internal/renderer",
2326
- imports: ["defineRenderHandler"]
2327
- },
2328
- {
2329
- from: "nitropack/runtime/internal/meta",
2330
- imports: ["defineRouteMeta"]
2331
- },
2332
- {
2333
- from: "nitropack/runtime/internal/route-rules",
2334
- imports: ["getRouteRules"]
2335
- },
2336
- {
2337
- from: "nitropack/runtime/internal/context",
2338
- imports: ["useEvent"]
2339
- },
2340
- {
2341
- from: "nitropack/runtime/internal/task",
2342
- imports: ["defineTask", "runTask"]
2343
- },
2344
- {
2345
- from: "nitropack/runtime/internal/error/utils",
2346
- imports: ["defineNitroErrorHandler"]
2347
- }
2348
- ];
2349
- }
2350
-
2351
- async function nuxtFramework(silgi, skip = false) {
2352
- if (silgi.options.preset !== "nuxt" && skip === false)
2353
- return;
2354
- await nitroFramework(silgi, true);
2355
- }
2356
-
2357
- const frameworkSetup = [emptyFramework, h3Framework, nitroFramework, nuxtFramework];
2358
-
2359
- async function registerModuleExportScan(silgi) {
2360
- silgi.hook("prepare:schema.ts", async (options) => {
2361
- for (const module of silgi.scanModules) {
2362
- const moduleReExports = [];
2363
- if (!module.entryPath) {
2364
- continue;
2365
- }
2366
- const moduleTypes = await promises.readFile(module.entryPath.replace(/\.mjs$/, "Types.d.ts"), "utf8").catch(() => "");
2367
- const normalisedModuleTypes = moduleTypes.replace(/export\s*\{.*?\}/gs, (match) => match.replace(/\b(type|interface)\b/g, ""));
2368
- for (const e of findTypeExports(normalisedModuleTypes)) {
2369
- moduleReExports.push(e);
2370
- }
2371
- for (const e of findExports(normalisedModuleTypes)) {
2372
- moduleReExports.push(e);
2373
- }
2374
- const hasTypeExport = (name) => moduleReExports.find((exp) => exp.names?.includes(name));
2375
- const configKey = module.meta.configKey;
2376
- const moduleName = module.meta.name || module.meta._packageName;
2377
- options.importItems[configKey] = {
2378
- import: [],
2379
- from: module.meta._packageName ? moduleName : relativeWithDot(silgi.options.build.typesDir, module.entryPath)
2380
- };
2381
- if (hasTypeExport("ModuleOptions")) {
2382
- const importName = `_${hash(`${configKey}ModuleOptions`)}`;
2383
- options.importItems[configKey].import.push({
2384
- name: `ModuleOptions as ${importName}`,
2385
- type: true,
2386
- key: importName
2387
- });
2388
- options.options.push({ key: configKey, value: importName });
2389
- }
2390
- if (hasTypeExport("ModuleRuntimeOptions")) {
2391
- const importName = `_${hash(`${configKey}ModuleRuntimeOptions`)}`;
2392
- options.importItems[configKey].import.push({
2393
- name: `ModuleRuntimeOptions as ${importName}`,
2394
- type: true,
2395
- key: importName
2396
- });
2397
- options.runtimeOptions.push({ key: configKey, value: importName });
2398
- }
2399
- if (hasTypeExport("ModuleRuntimeShareds")) {
2400
- const importName = `_${hash(`${configKey}ModuleRuntimeShareds`)}`;
2401
- options.importItems[configKey].import.push({
2402
- name: `ModuleRuntimeShareds as ${importName}`,
2403
- type: true,
2404
- key: importName
2405
- });
2406
- options.shareds.push({ key: configKey, value: importName });
2407
- }
2408
- if (hasTypeExport("ModuleEvents")) {
2409
- const importName = `_${hash(`${configKey}ModuleEvents`)}`;
2410
- options.importItems[configKey].import.push({
2411
- name: `ModuleEvents as ${importName}`,
2412
- type: true,
2413
- key: importName
2414
- });
2415
- options.events.push({ key: configKey, value: importName });
2416
- }
2417
- if (hasTypeExport("ModuleRuntimeContexts")) {
2418
- const importName = `_${hash(`${configKey}ModuleRuntimeContexts`)}`;
2419
- options.importItems[configKey].import.push({
2420
- name: `ModuleRuntimeContexts as ${importName}`,
2421
- type: true,
2422
- key: importName
2423
- });
2424
- options.contexts.push({ key: configKey, value: importName });
2425
- }
2426
- if (hasTypeExport("ModuleHooks")) {
2427
- const importName = `_${hash(`${configKey}ModuleHooks`)}`;
2428
- options.importItems[configKey].import.push({
2429
- name: `ModuleHooks as ${importName}`,
2430
- type: true,
2431
- key: importName
2432
- });
2433
- options.hooks.push({ key: configKey, value: importName });
2434
- }
2435
- if (hasTypeExport("ModuleRuntimeHooks")) {
2436
- const importName = `_${hash(`${configKey}RuntimeHooks`)}`;
2437
- options.importItems[configKey].import.push({
2438
- name: `ModuleRuntimeHooks as ${importName}`,
2439
- type: true,
2440
- key: importName
2441
- });
2442
- options.runtimeHooks.push({ key: configKey, value: importName });
2443
- }
2444
- if (hasTypeExport("ModuleRuntimeActions")) {
2445
- const importName = `_${hash(`${configKey}ModuleRuntimeActions`)}`;
2446
- options.importItems[configKey].import.push({
2447
- name: `ModuleRuntimeActions as ${importName}`,
2448
- type: true,
2449
- key: importName
2450
- });
2451
- options.actions.push({ key: configKey, value: importName });
2452
- }
2453
- if (hasTypeExport("ModuleRuntimeMethods")) {
2454
- const importName = `_${hash(`${configKey}ModuleRuntimeMethods`)}`;
2455
- options.importItems[configKey].import.push({
2456
- name: `ModuleRuntimeMethods as ${importName}`,
2457
- type: true,
2458
- key: importName
2459
- });
2460
- options.methods.push({ key: configKey, value: importName });
2461
- }
2462
- if (hasTypeExport("ModuleRuntimeRouteRules")) {
2463
- const importName = `_${hash(`${configKey}ModuleRuntimeRouteRules`)}`;
2464
- options.importItems[configKey].import.push({
2465
- name: `ModuleRuntimeRouteRules as ${importName}`,
2466
- type: true,
2467
- key: importName
2468
- });
2469
- options.routeRules.push({ key: configKey, value: importName });
2470
- }
2471
- if (hasTypeExport("ModuleRuntimeRouteRulesConfig")) {
2472
- const importName = `_${hash(`${configKey}ModuleRuntimeRouteRulesConfig`)}`;
2473
- options.importItems[configKey].import.push({
2474
- name: `ModuleRuntimeRouteRulesConfig as ${importName}`,
2475
- type: true,
2476
- key: importName
2477
- });
2478
- options.routeRulesConfig.push({ key: configKey, value: importName });
2479
- }
2480
- }
2481
- });
2482
- }
2483
-
2484
- async function loadSilgiModuleInstance(silgiModule) {
2485
- if (typeof silgiModule === "string") {
2486
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
2487
- }
2488
- if (typeof silgiModule !== "function") {
2489
- throw new TypeError(`Nuxt module should be a function: ${silgiModule}`);
2490
- }
2491
- return { silgiModule };
2492
- }
2493
- async function installModules(silgi, prepare = false) {
2494
- silgi.options.isPreparingModules = prepare;
2495
- const jiti = createJiti(silgi.options.rootDir, {
2496
- alias: silgi.options.alias,
2497
- fsCache: true,
2498
- moduleCache: true
2499
- });
2500
- for (const module of silgi.scanModules) {
2501
- if (hasInstalledModule(module.meta.configKey) && !silgi.options.dev) {
2502
- silgi.logger.info(`Module ${module.meta.configKey} installed`);
2503
- }
2504
- try {
2505
- const silgiModule = module.entryPath !== void 0 ? await jiti.import(module.entryPath, {
2506
- default: true,
2507
- conditions: silgi.options.conditions
2508
- }) : module.module;
2509
- if (silgiModule.name !== "silgiNormalizedModule") {
2510
- silgi.scanModules = silgi.scanModules.filter((m) => m.entryPath !== module.entryPath);
2511
- continue;
2512
- }
2513
- await installModule(silgiModule, silgi, prepare);
2514
- } catch (err) {
2515
- silgi.logger.error(err);
2516
- }
2517
- }
2518
- silgi.options.isPreparingModules = false;
2519
- }
2520
- async function installModule(moduleToInstall, silgi = useSilgi$1(), inlineOptions, prepare = false) {
2521
- const { silgiModule } = await loadSilgiModuleInstance(moduleToInstall);
2522
- const res = await silgiModule(inlineOptions || {}, silgi) ?? {};
2523
- if (res === false) {
2524
- return false;
2525
- }
2526
- const metaData = await silgiModule.getMeta?.();
2527
- if (prepare) {
2528
- return metaData;
2529
- }
2530
- const installedModule = silgi.scanModules.find((m) => m.meta.configKey === metaData?.configKey);
2531
- if (installedModule) {
2532
- installedModule.installed = true;
2533
- } else {
2534
- throw new Error(`Module ${metaData?.name} not found`);
2535
- }
2536
- }
2537
-
2538
- const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
2539
- async function _resolveSilgiModule(silgiModule, silgi) {
2540
- let resolvedModulePath;
2541
- let buildTimeModuleMeta = {};
2542
- const jiti = createJiti(silgi.options.rootDir, {
2543
- alias: silgi.options.alias,
2544
- fsCache: true,
2545
- moduleCache: true
2546
- });
2547
- if (typeof silgiModule === "string") {
2548
- silgiModule = resolveAlias(silgiModule, silgi.options.alias);
2549
- if (isRelative(silgiModule)) {
2550
- silgiModule = resolve(silgi.options.rootDir, silgiModule);
2551
- }
2552
- try {
2553
- const src = resolveModuleURL(silgiModule, {
2554
- from: silgi.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
2555
- suffixes: ["silgi", "silgi/index", "module", "module/index", "", "index"],
2556
- extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
2557
- // Maybe add https://github.com/unjs/exsolve/blob/dfff3e9bbc4a3a173a2d56b9b9ff731ab15598be/src/resolve.ts#L7
2558
- // conditions: silgi.options.conditions,
2559
- });
2560
- resolvedModulePath = fileURLToPath(src);
2561
- const resolvedSilgiModule = await jiti.import(src, { default: true });
2562
- if (typeof resolvedSilgiModule !== "function") {
2563
- throw new TypeError(`Nuxt module should be a function: ${silgiModule}.`);
2564
- }
2565
- silgiModule = await jiti.import(src, {
2566
- default: true,
2567
- conditions: silgi.options.conditions
2568
- });
2569
- const moduleMetadataPath = new URL("module.json", src);
2570
- if (existsSync(moduleMetadataPath)) {
2571
- buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
2572
- } else {
2573
- if (typeof silgiModule === "function") {
2574
- const meta = await silgiModule.getMeta?.();
2575
- const _exports = await scanExports(resolvedModulePath, true);
2576
- buildTimeModuleMeta = {
2577
- ...meta,
2578
- exports: _exports.map(({ from, ...rest }) => rest)
2579
- };
2580
- }
2581
- }
2582
- } catch (error) {
2583
- const code = error.code;
2584
- if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
2585
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
2586
- }
2587
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
2588
- const module = MissingModuleMatcher.exec(error.message)?.[1];
2589
- if (module && !module.includes(silgiModule)) {
2590
- throw new TypeError(`Error while importing module \`${silgiModule}\`: ${error}`);
2591
- }
2592
- }
2593
- }
2594
- }
2595
- if (!buildTimeModuleMeta) {
2596
- throw new Error(`Module ${silgiModule} is not a valid Silgi module`);
2597
- }
2598
- if (typeof silgiModule === "function") {
2599
- if (!buildTimeModuleMeta.configKey) {
2600
- const meta = await silgiModule.getMeta?.();
2601
- buildTimeModuleMeta = {
2602
- ...meta,
2603
- exports: []
2604
- };
2605
- }
2606
- if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
2607
- throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
2608
- }
2609
- const options = await silgiModule.getOptions?.() || {};
2610
- if (options) {
2611
- silgi.options._c12.config[buildTimeModuleMeta.configKey] = defu(
2612
- silgi.options._c12.config[buildTimeModuleMeta.configKey] || {},
2613
- options || {}
2614
- );
2615
- } else {
2616
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
2617
- }
2618
- silgi.scanModules.push({
2619
- meta: buildTimeModuleMeta,
2620
- entryPath: resolvedModulePath || void 0,
2621
- installed: false,
2622
- options,
2623
- module: silgiModule
2624
- });
2625
- }
2626
- }
2627
- async function scanModules(silgi) {
2628
- const _modules = [
2629
- ...silgi.options._modules,
2630
- ...silgi.options.modules
2631
- ];
2632
- for await (const mod of _modules) {
2633
- await _resolveSilgiModule(mod, silgi);
2634
- }
2635
- const moduleMap = new Map(
2636
- silgi.scanModules.map((m) => [m.meta?.configKey, m])
2637
- );
2638
- const graphData = createDependencyGraph(silgi.scanModules);
2639
- const sortedKeys = topologicalSort(graphData);
2640
- const modules = sortedKeys.map((key) => moduleMap.get(key)).filter((module) => Boolean(module));
2641
- silgi.scanModules = modules;
2642
- }
2643
- function createDependencyGraph(modules) {
2644
- const graph = /* @__PURE__ */ new Map();
2645
- const inDegree = /* @__PURE__ */ new Map();
2646
- modules.forEach((module) => {
2647
- const key = module.meta?.configKey;
2648
- if (key) {
2649
- graph.set(key, /* @__PURE__ */ new Set());
2650
- inDegree.set(key, 0);
2651
- }
2652
- });
2653
- modules.forEach((module) => {
2654
- const key = module.meta?.configKey;
2655
- if (!key) {
2656
- return;
2657
- }
2658
- const requiredDeps = module.meta?.requiredDependencies || [];
2659
- const beforeDeps = module.meta?.beforeDependencies || [];
2660
- const afterDeps = module.meta?.afterDependencies || [];
2661
- const processedDeps = /* @__PURE__ */ new Set();
2662
- requiredDeps.forEach((dep) => {
2663
- if (!graph.has(dep)) {
2664
- throw new Error(`Required dependency "${dep}" for module "${key}" is missing`);
2665
- }
2666
- graph.get(dep)?.add(key);
2667
- inDegree.set(key, (inDegree.get(key) || 0) + 1);
2668
- processedDeps.add(dep);
2669
- });
2670
- beforeDeps.forEach((dep) => {
2671
- if (!graph.has(dep)) {
2672
- return;
2673
- }
2674
- graph.get(key)?.add(dep);
2675
- inDegree.set(dep, (inDegree.get(dep) || 0) + 1);
2676
- });
2677
- afterDeps.forEach((dep) => {
2678
- if (processedDeps.has(dep)) {
2679
- return;
2680
- }
2681
- if (!graph.has(dep)) {
2682
- return;
2683
- }
2684
- graph.get(dep)?.add(key);
2685
- inDegree.set(key, (inDegree.get(key) || 0) + 1);
2686
- });
2687
- });
2688
- return { graph, inDegree };
2689
- }
2690
- function findCyclicDependencies(graph) {
2691
- const visited = /* @__PURE__ */ new Set();
2692
- const recursionStack = /* @__PURE__ */ new Set();
2693
- const cycles = [];
2694
- function dfs(node, path = []) {
2695
- visited.add(node);
2696
- recursionStack.add(node);
2697
- path.push(node);
2698
- for (const neighbor of graph.get(node) || []) {
2699
- if (recursionStack.has(neighbor)) {
2700
- const cycleStart = path.indexOf(neighbor);
2701
- if (cycleStart !== -1) {
2702
- cycles.push([...path.slice(cycleStart), neighbor]);
2703
- }
2704
- } else if (!visited.has(neighbor)) {
2705
- dfs(neighbor, [...path]);
2706
- }
2707
- }
2708
- recursionStack.delete(node);
2709
- path.pop();
2710
- }
2711
- for (const node of graph.keys()) {
2712
- if (!visited.has(node)) {
2713
- dfs(node, []);
2714
- }
2715
- }
2716
- return cycles;
2717
- }
2718
- function topologicalSort(graphData) {
2719
- const { graph, inDegree } = graphData;
2720
- const order = [];
2721
- const queue = [];
2722
- for (const [node, degree] of inDegree.entries()) {
2723
- if (degree === 0) {
2724
- queue.push(node);
2725
- }
2726
- }
2727
- while (queue.length > 0) {
2728
- const node = queue.shift();
2729
- order.push(node);
2730
- const neighbors = Array.from(graph.get(node) || []);
2731
- for (const neighbor of neighbors) {
2732
- const newDegree = (inDegree.get(neighbor) || 0) - 1;
2733
- inDegree.set(neighbor, newDegree);
2734
- if (newDegree === 0) {
2735
- queue.push(neighbor);
2736
- }
2737
- }
2738
- }
2739
- if (order.length !== graph.size) {
2740
- const cycles = findCyclicDependencies(graph);
2741
- if (cycles.length > 0) {
2742
- const cycleStr = cycles.map((cycle) => ` ${cycle.join(" -> ")}`).join("\n");
2743
- throw new Error(`Circular dependencies detected:
2744
- ${cycleStr}`);
2745
- } else {
2746
- const unresolvedModules = Array.from(graph.keys()).filter((key) => !order.includes(key));
2747
- throw new Error(`Unable to resolve dependencies for modules: ${unresolvedModules.join(", ")}`);
2748
- }
2749
- }
2750
- return order;
2751
- }
2752
-
2753
- async function commands(silgi) {
2754
- const commands2 = {
2755
- ...silgi.options.commands
2756
- };
2757
- await silgi.callHook("prepare:commands", commands2);
2758
- addTemplate({
2759
- filename: "cli.json",
2760
- where: ".silgi",
2761
- write: true,
2762
- getContents: () => JSON.stringify(commands2, null, 2)
2763
- });
2764
- silgi.commands = commands2;
2765
- silgi.hook("prepare:schema.ts", async (object) => {
2766
- const allTags = Object.values(commands2).reduce((acc, commandGroup) => {
2767
- Object.values(commandGroup).forEach((command) => {
2768
- if (command.tags) {
2769
- command.tags.forEach((tag) => acc.add(tag));
2770
- }
2771
- });
2772
- return acc;
2773
- }, /* @__PURE__ */ new Set());
2774
- const data = [
2775
- "",
2776
- generateTypes(
2777
- await resolveSchema(
2778
- {
2779
- ...Object.fromEntries(Array.from(allTags.values()).map((tag) => [tag, "string"]))
2780
- }
2781
- ),
2782
- {
2783
- interfaceName: "SilgiCommandsExtended",
2784
- addExport: false,
2785
- addDefaults: false,
2786
- allowExtraKeys: false,
2787
- indentation: 0
2788
- }
2789
- ),
2790
- ""
2791
- ];
2792
- object.customImports?.push(...data);
2793
- });
2794
- }
2795
-
2796
- function resolveIgnorePatterns(silgi, relativePath) {
2797
- if (!silgi) {
2798
- return [];
2799
- }
2800
- const ignorePatterns = silgi.options.ignore.flatMap((s) => resolveGroupSyntax(s));
2801
- const nuxtignoreFile = join(silgi.options.rootDir, ".nuxtignore");
2802
- if (existsSync(nuxtignoreFile)) {
2803
- const contents = readFileSync(nuxtignoreFile, "utf-8");
2804
- ignorePatterns.push(...contents.trim().split(/\r?\n/));
2805
- }
2806
- return ignorePatterns;
2807
- }
2808
- function isIgnored(pathname, silgi, _stats) {
2809
- if (!silgi) {
2810
- return false;
2811
- }
2812
- if (!silgi._ignore) {
2813
- silgi._ignore = ignore(silgi.options.ignoreOptions);
2814
- silgi._ignore.add(resolveIgnorePatterns(silgi));
2815
- }
2816
- const relativePath = relative(silgi.options.rootDir, pathname);
2817
- if (relativePath[0] === "." && relativePath[1] === ".") {
2818
- return false;
2819
- }
2820
- return !!(relativePath && silgi._ignore.ignores(relativePath));
2821
- }
2822
- function resolveGroupSyntax(group) {
2823
- let groups = [group];
2824
- while (groups.some((group2) => group2.includes("{"))) {
2825
- groups = groups.flatMap((group2) => {
2826
- const [head, ...tail] = group2.split("{");
2827
- if (tail.length) {
2828
- const [body = "", ...rest] = tail.join("{").split("}");
2829
- return body.split(",").map((part) => `${head}${part}${rest.join("")}`);
2830
- }
2831
- return group2;
2832
- });
2833
- }
2834
- return groups;
2835
- }
2836
-
2837
- const safeFiles = [
2838
- "silgi/configs",
2839
- "silgi",
2840
- "silgi/rules",
2841
- "silgi/scan",
2842
- "silgi/vfs"
2843
- ];
2844
- class SchemaParser {
2845
- options = {
2846
- debug: false
2847
- };
2848
- /**
2849
- *
2850
- */
2851
- constructor(options) {
2852
- this.options = {
2853
- ...this.options,
2854
- ...options
2855
- };
2856
- }
2857
- parseExports(content, filePath) {
2858
- const ast = parseSync(content, { sourceType: "module", sourceFilename: filePath });
2859
- if (this.options.debug)
2860
- writeFileSync(`${filePath}.ast.json`, JSON.stringify(ast.program, null, 2));
2861
- return {
2862
- exportVariables: (search, path) => this.parseTypeDeclarations(ast, search, path),
2863
- parseInterfaceDeclarations: (search, path) => this.parseInterfaceDeclarations(ast, search, path)
2864
- // parsePlugin: (path: string) => this.parsePlugin(ast, path),
2865
- };
2866
- }
2867
- parseVariableDeclaration(ast, path) {
2868
- const silgi = useSilgi$1();
2869
- if (ast.program.body.length === 0) {
2870
- if (safeFiles.find((i) => path.includes(i)))
2871
- return [];
2872
- silgi.errors.push({
2873
- type: "Parser",
2874
- path
2875
- });
2876
- consola$1.warn("This file has a problem:", path);
2877
- }
2878
- const variableDeclarations = ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "VariableDeclaration");
2879
- return variableDeclarations;
2880
- }
2881
- parseTSInterfaceDeclaration(ast, path = "") {
2882
- const silgi = useSilgi$1();
2883
- if (ast.program.body.length === 0) {
2884
- if (safeFiles.find((i) => path.includes(i)))
2885
- return [];
2886
- silgi.errors.push({
2887
- type: "Parser",
2888
- path
2889
- });
2890
- consola$1.warn("This file has a problem:", path);
2891
- }
2892
- const interfaceDeclarations = ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "TSInterfaceDeclaration");
2893
- return interfaceDeclarations;
2894
- }
2895
- parseTypeDeclarations(ast, find = "", path = "") {
2896
- const data = [];
2897
- const variableDeclarations = this.parseVariableDeclaration(ast, path);
2898
- for (const item of variableDeclarations) {
2899
- for (const declaration of item.declaration.declarations) {
2900
- if (declaration.init?.callee?.name === find) {
2901
- const options = {};
2902
- if (declaration.init.arguments) {
2903
- for (const argument of declaration.init.arguments) {
2904
- for (const propertie of argument.properties) {
2905
- if (propertie.key.name === "name")
2906
- options.pluginName = propertie.value.value;
2907
- }
2908
- }
2909
- }
2910
- for (const key in declaration.init.properties) {
2911
- const property = declaration.init.properties[key];
2912
- if (property.type === "ObjectProperty") {
2913
- if (property.key.name === "options") {
2914
- for (const key2 in property.value.properties) {
2915
- const option = property.value.properties[key2];
2916
- if (option.type === "ObjectProperty") {
2917
- options[option.key.name] = option.value.value;
2918
- }
2919
- }
2920
- }
2921
- }
2922
- }
2923
- options.type = false;
2924
- data.push({
2925
- exportName: declaration.id.name,
2926
- options,
2927
- // object: declaration.init,
2928
- path
2929
- });
2930
- }
2931
- }
2932
- }
2933
- return data;
2934
- }
2935
- parseInterfaceDeclarations(ast, find = "", path = "") {
2936
- const data = [];
2937
- for (const item of this.parseTSInterfaceDeclaration(ast, path)) {
2938
- if (!item?.declaration?.extends)
2939
- continue;
2940
- for (const declaration of item?.declaration?.extends) {
2941
- if (declaration.expression.name === find) {
2942
- const options = {};
2943
- options.type = true;
2944
- data.push({
2945
- exportName: item.declaration.id.name,
2946
- options,
2947
- // object: declaration.init,
2948
- path
2949
- });
2950
- }
2951
- }
2952
- }
2953
- return data;
2954
- }
2955
- // private parsePlugin(ast: any, path: string = '') {
2956
- // const data = {
2957
- // export: [],
2958
- // name: '',
2959
- // path: '',
2960
- // } as DataTypePlugin
2961
- // for (const item of this.parseVariableDeclaration(ast)) {
2962
- // for (const declaration of item.declaration.declarations) {
2963
- // if (declaration.init.callee?.name === 'defineSilgiModule') {
2964
- // if (declaration.init.arguments) {
2965
- // for (const argument of declaration.init.arguments) {
2966
- // for (const propertie of argument.properties) {
2967
- // if (propertie.key.name === 'name')
2968
- // data.name = propertie.value.value
2969
- // }
2970
- // }
2971
- // }
2972
- // data.export.push({
2973
- // name: data.name,
2974
- // as: camelCase(`${data.name}DefineSilgiModule`),
2975
- // type: false,
2976
- // })
2977
- // }
2978
- // }
2979
- // }
2980
- // for (const item of this.parseTSInterfaceDeclaration(ast)) {
2981
- // if (!item?.declaration?.extends)
2982
- // continue
2983
- // for (const declaration of item?.declaration?.extends) {
2984
- // if (declaration.expression.name === 'ModuleOptions') {
2985
- // data.export.push({
2986
- // name: item.declaration.id.name,
2987
- // as: camelCase(`${data.name}ModuleOptions`),
2988
- // type: true,
2989
- // })
2990
- // }
2991
- // // TODO add other plugins
2992
- // }
2993
- // }
2994
- // data.path = path
2995
- // return data
2996
- // }
2997
- }
2998
-
2999
- async function scanExportFile(silgi) {
3000
- const filePaths = /* @__PURE__ */ new Set();
3001
- const scannedPaths = [];
3002
- const dir = silgi.options.serverDir;
3003
- const files = (await globby(dir, { cwd: silgi.options.rootDir, ignore: silgi.options.ignore })).sort();
3004
- if (files.length) {
3005
- const siblings = await readdir(dirname(dir)).catch(() => []);
3006
- const directory = basename(dir);
3007
- if (!siblings.includes(directory)) {
3008
- const directoryLowerCase = directory.toLowerCase();
3009
- const caseCorrected = siblings.find((sibling) => sibling.toLowerCase() === directoryLowerCase);
3010
- if (caseCorrected) {
3011
- const original = relative(silgi.options.serverDir, dir);
3012
- const corrected = relative(silgi.options.serverDir, join(dirname(dir), caseCorrected));
3013
- consola.warn(`Components not scanned from \`~/${corrected}\`. Did you mean to name the directory \`~/${original}\` instead?`);
3014
- }
3015
- }
3016
- }
3017
- for (const _file of files) {
3018
- const filePath = resolve(dir, _file);
3019
- if (scannedPaths.find((d) => filePath.startsWith(withTrailingSlash(d))) || isIgnored(filePath, silgi)) {
3020
- continue;
3021
- }
3022
- if (filePaths.has(filePath)) {
3023
- continue;
3024
- }
3025
- filePaths.add(filePath);
3026
- if (silgi.options.extensions.includes(extname(filePath))) {
3027
- const parser = new SchemaParser({
3028
- debug: false
3029
- });
3030
- const readfile = await readFile(filePath, "utf-8");
3031
- const { exportVariables, parseInterfaceDeclarations } = parser.parseExports(readfile, filePath);
3032
- const createServices = exportVariables("createService", filePath);
3033
- if (hasError("Parser", silgi)) {
3034
- return;
3035
- }
3036
- const scanTS = [];
3037
- const schemaTS = [];
3038
- if (createServices.length > 0) {
3039
- scanTS.push(...createServices.map(({ exportName, path }) => {
3040
- const randomString = hash(basename(path) + exportName);
3041
- const _name = `_v${randomString}`;
3042
- return { exportName, path, _name, type: "service" };
3043
- }));
3044
- }
3045
- const createSchemas = exportVariables("createSchema", filePath);
3046
- if (hasError("Parser", silgi)) {
3047
- return;
3048
- }
3049
- if (createSchemas.length > 0) {
3050
- scanTS.push(...createSchemas.map(({ exportName, path }) => {
3051
- const randomString = hash(basename(path) + exportName);
3052
- const _name = `_v${randomString}`;
3053
- return { exportName, path, _name, type: "schema" };
3054
- }));
3055
- }
3056
- const createShareds = exportVariables("createShared", filePath);
3057
- if (hasError("Parser", silgi)) {
3058
- return;
3059
- }
3060
- if (createShareds.length > 0) {
3061
- scanTS.push(...createShareds.map(({ exportName, path }) => {
3062
- const randomString = hash(basename(path) + exportName);
3063
- const _name = `_v${randomString}`;
3064
- return { exportName, path, _name, type: "shared" };
3065
- }));
3066
- }
3067
- const sharedsTypes = parseInterfaceDeclarations("ExtendShared", filePath);
3068
- if (hasError("Parser", silgi)) {
3069
- return;
3070
- }
3071
- if (sharedsTypes.length > 0) {
3072
- schemaTS.push(...sharedsTypes.map(({ exportName, path }) => {
3073
- const randomString = hash(basename(path) + exportName);
3074
- const _name = `_v${randomString}`;
3075
- return { exportName, path, _name, type: "shared" };
3076
- }));
3077
- }
3078
- const contextTypes = parseInterfaceDeclarations("ExtendContext", filePath);
3079
- if (hasError("Parser", silgi)) {
3080
- return;
3081
- }
3082
- if (contextTypes.length > 0) {
3083
- schemaTS.push(...contextTypes.map(({ exportName, path }) => {
3084
- const randomString = hash(basename(path) + exportName);
3085
- const _name = `_v${randomString}`;
3086
- return { exportName, path, _name, type: "context" };
3087
- }));
3088
- }
3089
- silgi.hook("prepare:scan.ts", (options) => {
3090
- for (const { exportName, path, _name, type } of scanTS) {
3091
- if (!path.includes("vfs")) {
3092
- silgi.options.devServer.watch.push(path);
3093
- }
3094
- if (type === "service") {
3095
- options.services.push(_name);
3096
- }
3097
- if (type === "shared") {
3098
- options.shareds.push(_name);
3099
- }
3100
- if (type === "schema") {
3101
- options.schemas.push(_name);
3102
- }
3103
- options.importItems[path] ??= {
3104
- import: [],
3105
- from: relativeWithDot(silgi.options.silgi.serverDir, path)
3106
- };
3107
- options.importItems[path].import.push({
3108
- name: `${exportName} as ${_name}`,
3109
- key: _name
3110
- });
3111
- }
3112
- });
3113
- silgi.hook("prepare:schema.ts", (options) => {
3114
- for (const { exportName, path, _name, type } of schemaTS) {
3115
- if (!path.includes("vfs")) {
3116
- silgi.options.devServer.watch.push(path);
3117
- }
3118
- if (type === "shared") {
3119
- options.shareds.push({
3120
- key: _name,
3121
- value: _name
3122
- });
3123
- }
3124
- if (type === "context") {
3125
- options.contexts.push({
3126
- key: _name,
3127
- value: _name
3128
- });
3129
- }
3130
- options.importItems[path] ??= {
3131
- import: [],
3132
- from: relativeWithDot(silgi.options.build.typesDir, path)
3133
- };
3134
- options.importItems[path].import.push({
3135
- name: `${exportName} as ${_name}`,
3136
- key: _name
3137
- });
3138
- }
3139
- });
3140
- }
3141
- }
3142
- }
3143
-
3144
- function buildUriMap(silgi, currentPath = []) {
3145
- const uriMap = /* @__PURE__ */ new Map();
3146
- function traverse(node, path = []) {
3147
- if (!node || typeof node !== "object")
3148
- return;
3149
- if (path.length === 4) {
3150
- const basePath = path.join("/");
3151
- let pathString = "";
3152
- if (node.pathParams) {
3153
- let paths = null;
3154
- if (node.pathParams?._def?.typeName !== void 0) {
3155
- try {
3156
- const shape = node.pathParams?.shape;
3157
- paths = shape ? Object.keys(shape) : null;
3158
- } catch {
3159
- paths = null;
3160
- }
3161
- }
3162
- if (paths?.length) {
3163
- pathString = paths.map((p) => `:${p}`).join("/");
3164
- }
3165
- }
3166
- uriMap.set(basePath, pathString);
3167
- return;
3168
- }
3169
- for (const key in node) {
3170
- if (!["_type", "fields"].includes(key)) {
3171
- traverse(node[key], [...path, key]);
3172
- }
3173
- }
3174
- }
3175
- traverse(silgi.schemas, currentPath);
3176
- silgi.uris = defu$1(silgi.uris, Object.fromEntries(uriMap));
3177
- return uriMap;
3178
- }
3179
-
3180
- async function readScanFile(silgi) {
3181
- const path = resolve(silgi.options.silgi.serverDir, "scan.ts");
3182
- const context = await promises.readFile(path, { encoding: "utf-8" });
3183
- silgi.unimport = createUnimport(silgi.options.imports || {});
3184
- await silgi.unimport.init();
3185
- const injectedResult = await silgi.unimport.injectImports(context, path);
3186
- if (!injectedResult) {
3187
- throw new Error("Failed to inject imports");
3188
- }
3189
- const jiti = createJiti(silgi.options.rootDir, {
3190
- fsCache: true,
3191
- moduleCache: false,
3192
- debug: silgi.options.debug,
3193
- alias: silgi.options.alias
3194
- });
3195
- try {
3196
- if (silgi.options.commandType === "prepare") {
3197
- globalThis.$silgiSharedRuntimeConfig = silgi.options.runtimeConfig;
3198
- injectedResult.code = `globalThis.$silgiSharedRuntimeConfig = ${JSON.stringify(silgi.options.runtimeConfig)};
3199
- ${injectedResult.code}`;
3200
- injectedResult.code = injectedResult.code.replace(/runtimeConfig: \{\}/, `runtimeConfig: ${JSON.stringify(silgi.options.runtimeConfig)}`);
3201
- }
3202
- const scanFile = await jiti.evalModule(
3203
- injectedResult.code,
3204
- {
3205
- filename: path,
3206
- async: true,
3207
- conditions: silgi.options.conditions
3208
- },
3209
- async (data, name) => {
3210
- return (await silgi.unimport.injectImports(data, name)).code;
3211
- }
3212
- );
3213
- silgi.uris = defu$1(silgi.uris, scanFile.uris) || {};
3214
- silgi.schemas = defu$1(scanFile.schemas, scanFile.uris) || {};
3215
- silgi.services = defu$1(scanFile.services, scanFile.uris) || {};
3216
- silgi.shareds = defu$1(scanFile.shareds, scanFile.shareds) || {};
3217
- silgi.modulesURIs = defu$1(scanFile.modulesURIs, scanFile.modulesURIs) || {};
3218
- return {
3219
- context,
3220
- object: {
3221
- schemas: scanFile.schemas,
3222
- uris: scanFile.uris,
3223
- services: scanFile.services,
3224
- shareds: scanFile.shareds,
3225
- modulesURIs: scanFile.modulesURIs
3226
- },
3227
- path
3228
- };
3229
- } catch (error) {
3230
- if (silgi.options.debug) {
3231
- console.error("Failed to read scan.ts file:", error);
3232
- } else {
3233
- if (error instanceof Error) {
3234
- consola.withTag("silgi").info(error.message);
3235
- }
3236
- }
3237
- return {
3238
- context,
3239
- object: {
3240
- schemas: {},
3241
- uris: {},
3242
- services: {},
3243
- shareds: {},
3244
- modulesURIs: {}
3245
- },
3246
- path
3247
- };
3248
- }
3249
- }
3250
-
3251
- async function prepareServerFiles(silgi) {
3252
- const importItems = {
3253
- "silgi": {
3254
- import: [
3255
- { name: "createSilgi", key: "createSilgi" },
3256
- { name: "createShared", key: "createShared" }
3257
- ],
3258
- from: "silgi"
3259
- },
3260
- "silgi/types": {
3261
- import: [
3262
- { name: "SilgiRuntimeOptions", type: true, key: "SilgiRuntimeOptions" },
3263
- { name: "FrameworkContext", type: true, key: "FrameworkContext" }
3264
- ],
3265
- from: "silgi/types"
3266
- },
3267
- "#silgi/vfs": {
3268
- import: [],
3269
- from: "./vfs"
3270
- },
3271
- "configs.ts": {
3272
- import: [
3273
- {
3274
- name: "cliConfigs",
3275
- type: false,
3276
- key: "cliConfigs"
3277
- }
3278
- ],
3279
- from: "./configs.ts"
3280
- }
3281
- };
3282
- const scanned = {
3283
- uris: {},
3284
- services: [],
3285
- shareds: [
3286
- `createShared({
3287
- modulesURIs,
3288
- })`
3289
- ],
3290
- schemas: [],
3291
- modulesURIs: {},
3292
- customImports: [],
3293
- importItems
3294
- };
3295
- if (silgi.uris) {
3296
- defu$1(scanned.uris, silgi.uris);
3297
- }
3298
- if (silgi.modulesURIs) {
3299
- defu$1(scanned.modulesURIs, silgi.modulesURIs);
3300
- }
3301
- await silgi.callHook("prepare:scan.ts", scanned);
3302
- if (importItems["#silgi/vfs"].import.length === 0) {
3303
- delete importItems["#silgi/vfs"];
3304
- }
3305
- if (scanned.services.length > 0) {
3306
- importItems.silgi.import.push({ name: "mergeServices", key: "mergeServices" });
3307
- }
3308
- if (scanned.shareds.length > 0) {
3309
- importItems.silgi.import.push({ name: "mergeShared", key: "mergeShared" });
3310
- }
3311
- if (scanned.schemas.length > 0) {
3312
- importItems.silgi.import.push({ name: "mergeSchemas", key: "mergeSchemas" });
3313
- }
3314
- for (const key in importItems) {
3315
- importItems[key].import = deduplicateImportsByKey(importItems[key].import);
3316
- }
3317
- const importsContent = [
3318
- ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
3319
- if (silgi.options.typescript.removeFileExtension) {
3320
- from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
3321
- }
3322
- return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
3323
- }),
3324
- "",
3325
- ...scanned.customImports,
3326
- ""
3327
- ];
3328
- const importData = [
3329
- `export const uris = ${JSON.stringify(scanned.uris, null, 2)}`,
3330
- "",
3331
- `export const modulesURIs = ${JSON.stringify(scanned.modulesURIs, null, 2)}`,
3332
- "",
3333
- scanned.schemas.length > 0 ? "export const schemas = mergeSchemas([" : "export const schemas = {",
3334
- ...scanned.schemas.map((name) => {
3335
- return ` ${name},`;
3336
- }),
3337
- scanned.schemas.length > 0 ? "])" : "}",
3338
- "",
3339
- scanned.services.length > 0 ? "export const services = mergeServices([" : "export const services = {",
3340
- ...scanned.services.map((name) => {
3341
- return ` ${name},`;
3342
- }),
3343
- scanned.services.length > 0 ? "])" : "}",
3344
- "",
3345
- scanned.shareds.length > 0 ? "export const shareds = mergeShared([" : "export const shareds = {",
3346
- ...scanned.shareds.map((name) => {
3347
- return ` ${name},`;
3348
- }),
3349
- scanned.shareds.length > 0 ? "])" : "}",
3350
- ""
3351
- ];
3352
- await silgi.callHook("after:prepare:scan.ts", importData);
3353
- importData.unshift(...importsContent);
3354
- return importData;
3355
- }
3356
- function deduplicateImportsByKey(imports) {
3357
- const seenKeys = /* @__PURE__ */ new Map();
3358
- return imports.filter((item) => {
3359
- if (seenKeys.has(item.key)) {
3360
- return false;
3361
- }
3362
- seenKeys.set(item.key, true);
3363
- return true;
3364
- });
3365
- }
3366
-
3367
- async function writeScanFiles(silgi) {
3368
- const data = await prepareServerFiles(silgi);
3369
- if (!silgi.errors.length) {
3370
- await writeFile(
3371
- resolve(silgi.options.silgi.serverDir, "scan.ts"),
3372
- data.join("\n")
3373
- );
3374
- }
3375
- await readScanFile(silgi);
3376
- buildUriMap(silgi);
3377
- parseServices(silgi);
3378
- silgi.hook("prepare:scan.ts", (file) => {
3379
- file.uris = {
3380
- ...file.uris,
3381
- ...silgi.uris
3382
- };
3383
- file.modulesURIs = {
3384
- ...file.modulesURIs,
3385
- ...silgi.modulesURIs
3386
- };
3387
- });
3388
- }
3389
-
3390
- async function createStorageCLI(silgi) {
3391
- const storage = createStorage$1();
3392
- const runtime = useSilgiRuntimeConfig();
3393
- const mounts = klona({
3394
- ...silgi.options.storage,
3395
- ...silgi.options.devStorage
3396
- });
3397
- for (const [path, opts] of Object.entries(mounts)) {
3398
- if (opts.driver) {
3399
- const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
3400
- const processedOpts = replaceRuntimeValues$1({ ...opts }, runtime);
3401
- storage.mount(path, driver(processedOpts));
3402
- } else {
3403
- silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
3404
- }
3405
- }
3406
- return storage;
3407
- }
3408
-
3409
- async function createSilgi(config = {}, opts = {}) {
3410
- const options = await loadOptions(config, opts);
3411
- const hooks = createHooks();
3412
- const silgi = {
3413
- modulesURIs: {},
3414
- scannedURIs: /* @__PURE__ */ new Map(),
3415
- services: {},
3416
- uris: {},
3417
- shareds: {},
3418
- schemas: {},
3419
- unimport: void 0,
3420
- options,
3421
- hooks,
3422
- errors: [],
3423
- commands: {},
3424
- _requiredModules: {},
3425
- logger: consola.withTag("silgi"),
3426
- close: () => silgi.hooks.callHook("close", silgi),
3427
- storage: void 0,
3428
- scanModules: [],
3429
- templates: [],
3430
- callHook: hooks.callHook,
3431
- addHooks: hooks.addHooks,
3432
- hook: hooks.hook,
3433
- async updateConfig(_config) {
3434
- },
3435
- routeRules: void 0
3436
- };
3437
- await prepareEnv(options);
3438
- const routeRules = createRouteRules();
3439
- routeRules.importRules(options.routeRules ?? {});
3440
- silgi.routeRules = routeRules;
3441
- if (silgiCtx$1.tryUse()) {
3442
- silgiCtx$1.unset();
3443
- silgiCtx$1.set(silgi);
3444
- } else {
3445
- silgiCtx$1.set(silgi);
3446
- silgi.hook("close", () => silgiCtx$1.unset());
3447
- }
3448
- if (silgi.options.debug) {
3449
- createDebugger(silgi.hooks, { tag: "silgi" });
3450
- silgi.options.plugins.push({
3451
- path: join(runtimeDir, "internal/debug"),
3452
- packageImport: "silgi/runtime/internal/debug"
3453
- });
3454
- }
3455
- for (const framework of frameworkSetup) {
3456
- await framework(silgi);
3457
- }
3458
- await scanAndSyncOptions(silgi);
3459
- await scanModules(silgi);
3460
- await scanExportFile(silgi);
3461
- await installModules(silgi, true);
3462
- useCLIRuntimeConfig(silgi);
3463
- await writeScanFiles(silgi);
3464
- silgi.storage = await createStorageCLI(silgi);
3465
- silgi.hooks.hook("close", async () => {
3466
- await silgi.storage.dispose();
3467
- });
3468
- if (silgi.options.logLevel !== void 0) {
3469
- silgi.logger.level = silgi.options.logLevel;
3470
- }
3471
- silgi.hooks.addHooks(silgi.options.hooks);
3472
- await installModules(silgi);
3473
- await silgi.hooks.callHook("scanFiles:done", silgi);
3474
- await commands(silgi);
3475
- await installPackages(silgi);
3476
- await generateApp(silgi);
3477
- if (silgi.options.imports) {
3478
- silgi.options.imports.dirs ??= [];
3479
- silgi.options.imports.dirs = silgi.options.imports.dirs.map((dir) => {
3480
- if (typeof dir === "string") {
3481
- if (dir.startsWith("!")) {
3482
- return `!${resolveSilgiPath$1(dir.slice(1), options, silgi.options.rootDir)}`;
3483
- }
3484
- return resolveSilgiPath$1(dir, options, silgi.options.rootDir);
3485
- }
3486
- return dir;
3487
- });
3488
- silgi.options.imports.presets.push({
3489
- from: "silgi/types",
3490
- imports: autoImportTypes$1.map((type) => type),
3491
- type: true
3492
- });
3493
- silgi.options.imports.presets.push({
3494
- from: "silgi/types",
3495
- imports: autoImportTypes$1.map((type) => type),
3496
- type: true
3497
- });
3498
- silgi.options.imports.presets.push({
3499
- from: "silgi/runtime/internal/ofetch",
3500
- imports: ["createSilgiFetch", "silgi$fetch"]
3501
- });
3502
- silgi.unimport = createUnimport(silgi.options.imports);
3503
- await silgi.unimport.init();
3504
- }
3505
- await registerModuleExportScan(silgi);
3506
- await writeScanFiles(silgi);
3507
- return silgi;
3508
- }
3509
-
3510
- async function prepareConfigs(silgi) {
3511
- const _data = {
3512
- runtimeConfig: {}
3513
- };
3514
- for (const module of silgi.scanModules) {
3515
- if (module.meta.cliToRuntimeOptionsKeys && module.meta.cliToRuntimeOptionsKeys?.length > 0) {
3516
- for (const key of module.meta.cliToRuntimeOptionsKeys) {
3517
- _data[module.meta.configKey] = {
3518
- ..._data[module.meta.configKey],
3519
- [key]: module.options[key]
3520
- };
3521
- }
3522
- } else {
3523
- _data[module.meta.configKey] = {};
3524
- }
3525
- }
3526
- await silgi.callHook("prepare:configs.ts", _data);
3527
- const importData = [
3528
- "import type { SilgiRuntimeOptions, SilgiRuntimeConfig, SilgiOptions } from 'silgi/types'",
3529
- "import { useSilgiRuntimeConfig } from 'silgi/runtime'",
3530
- "",
3531
- `export const runtimeConfig: Partial<SilgiRuntimeConfig> = ${genObjectFromRawEntries(
3532
- Object.entries(_data.runtimeConfig).map(([key, value]) => [key, genEnsureSafeVar(value)]),
3533
- ""
3534
- )}`,
3535
- "",
3536
- "const runtime = useSilgiRuntimeConfig(undefined, runtimeConfig)",
3537
- ""
3538
- ];
3539
- delete _data.runtimeConfig;
3540
- importData.push(`export const cliConfigs: Partial<SilgiRuntimeOptions & SilgiOptions> = ${genObjectFromRawEntries(
3541
- Object.entries(_data).map(
3542
- ([key, value]) => [key, genEnsureSafeVar(value)]
3543
- ).concat(
3544
- [
3545
- ["runtimeConfig", "runtime"]
3546
- ]
3547
- )
3548
- )}`);
3549
- return importData;
3550
- }
3551
-
3552
- async function prepareCoreFile(data, frameworkContext, silgi) {
3553
- let importItems = {
3554
- "silgi": {
3555
- import: [
3556
- {
3557
- name: "createSilgi",
3558
- key: "createSilgi"
3559
- }
3560
- ],
3561
- from: "silgi"
3562
- },
3563
- "silgi/types": {
3564
- import: [
3565
- {
3566
- name: "SilgiRuntimeOptions",
3567
- type: true,
3568
- key: "SilgiRuntimeOptions"
3569
- },
3570
- {
3571
- name: "FrameworkContext",
3572
- type: true,
3573
- key: "FrameworkContext"
3574
- },
3575
- {
3576
- name: "SilgiOptions",
3577
- type: true,
3578
- key: "SilgiOptions"
3579
- }
3580
- ],
3581
- from: "silgi/types"
3582
- },
3583
- "#silgi/vfs": {
3584
- import: [],
3585
- from: "./vfs"
3586
- },
3587
- "scan.ts": {
3588
- import: [
3589
- {
3590
- name: "uris",
3591
- type: false,
3592
- key: "uris"
3593
- },
3594
- {
3595
- name: "services",
3596
- type: false,
3597
- key: "services"
3598
- },
3599
- {
3600
- name: "shareds",
3601
- type: false,
3602
- key: "shareds"
3603
- },
3604
- {
3605
- name: "schemas",
3606
- type: false,
3607
- key: "schemas"
3608
- },
3609
- {
3610
- name: "modulesURIs",
3611
- type: false,
3612
- key: "modulesURIs"
3613
- }
3614
- ],
3615
- from: "./scan.ts"
3616
- },
3617
- "configs.ts": {
3618
- import: [
3619
- {
3620
- name: "cliConfigs",
3621
- type: false,
3622
- key: "cliConfigs"
3623
- }
3624
- ],
3625
- from: "./configs.ts"
3626
- },
3627
- "rules.ts": {
3628
- import: [
3629
- {
3630
- name: "routeRules",
3631
- key: "routeRules"
3632
- }
3633
- ],
3634
- from: "./rules.ts"
3635
- }
3636
- };
3637
- importItems = { ...data._importItems, ...importItems };
3638
- const _data = {
3639
- customImports: data._customImports || [],
3640
- buildSilgiExtraContent: [],
3641
- beforeBuildSilgiExtraContent: [],
3642
- afterCliOptions: [],
3643
- _silgiConfigs: [],
3644
- customContent: [],
3645
- importItems
3646
- };
3647
- await silgi.callHook("prepare:core.ts", _data);
3648
- if (importItems["#silgi/vfs"].import.length === 0) {
3649
- delete importItems["#silgi/vfs"];
3650
- }
3651
- const plugins = [];
3652
- for (const plugin of silgi.options.plugins) {
3653
- const pluginImportName = `_${hash(plugin.packageImport)}`;
3654
- _data.customImports.push(`import ${pluginImportName} from '${plugin.packageImport}'`);
3655
- plugins.push(pluginImportName);
3656
- }
3657
- const importsContent = [
3658
- 'import deepmerge from "@fastify/deepmerge"',
3659
- ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
3660
- if (silgi.options.typescript.removeFileExtension) {
3661
- from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
3662
- }
3663
- return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
3664
- }),
3665
- "",
3666
- ..._data.customImports,
3667
- ""
3668
- ];
3669
- const importData = [
3670
- "",
3671
- "const mergeDeep = deepmerge({all: true})",
3672
- "",
3673
- "export async function buildSilgi(framework: FrameworkContext, moduleOptions?: Partial<SilgiRuntimeOptions>,buildOptions?: Partial<SilgiOptions>) {",
3674
- "",
3675
- _data.beforeBuildSilgiExtraContent.length > 0 ? _data.beforeBuildSilgiExtraContent.map(({ value, type }) => {
3676
- return type === "function" ? value : `const ${value}`;
3677
- }) : "",
3678
- "",
3679
- " const silgi = await createSilgi({",
3680
- " framework,",
3681
- " shared: shareds as any,",
3682
- " services: services as any,",
3683
- " schemas: schemas as any,",
3684
- " uris,",
3685
- " modulesURIs,",
3686
- ` plugins: [${plugins.join(", ")}],`,
3687
- _data._silgiConfigs.length > 0 ? ` ${_data._silgiConfigs.map((config) => typeof config === "string" ? config : typeof config === "object" ? Object.entries(config).map(([key, value]) => `${key}: ${value}`).join(",\n ") : "").join(",\n ")},` : "",
3688
- " options: mergeDeep(",
3689
- " {",
3690
- " runtimeConfig: {} as SilgiRuntimeOptions,",
3691
- " routeRules: routeRules as any,",
3692
- " },",
3693
- " moduleOptions || {},",
3694
- " {",
3695
- ` present: '${silgi.options.preset}',`,
3696
- " ...cliConfigs,",
3697
- " },",
3698
- " buildOptions,",
3699
- " ) as any,",
3700
- " })",
3701
- "",
3702
- ...frameworkContext,
3703
- "",
3704
- ..._data.buildSilgiExtraContent,
3705
- "",
3706
- " return silgi",
3707
- "}",
3708
- ""
3709
- ];
3710
- await silgi.callHook("after:prepare:core.ts", importData);
3711
- importData.unshift(...importsContent);
3712
- return importData;
3713
- }
3714
-
3715
- async function prepareFramework(silgi) {
3716
- const importItems = {
3717
- "silgi/types": {
3718
- import: [
3719
- {
3720
- name: "SilgiRuntimeContext",
3721
- type: true,
3722
- key: "SilgiRuntimeContext"
3723
- }
3724
- ],
3725
- from: "silgi/types"
3726
- }
3727
- };
3728
- const customImports = [];
3729
- const functions = [];
3730
- await silgi.callHook("prepare:createCoreFramework", {
3731
- importItems,
3732
- customImports,
3733
- functions
3734
- });
3735
- const content = [
3736
- ...functions.map((f) => f.params?.length ? ` await ${f.name}(framework, ${f.params.join(",")})` : ` await ${f.name}(framework)`)
3737
- ];
3738
- return {
3739
- content,
3740
- importItems,
3741
- customImports
3742
- };
3743
- }
3744
- async function createDTSFramework(silgi) {
3745
- const importItems = {
3746
- "silgi/types": {
3747
- import: [
3748
- {
3749
- name: "SilgiRuntimeContext",
3750
- type: true,
3751
- key: "SilgiRuntimeContext"
3752
- }
3753
- ],
3754
- from: "silgi/types"
3755
- }
3756
- };
3757
- const customImports = [];
3758
- const customContent = [];
3759
- await silgi.callHook("prepare:createDTSFramework", {
3760
- importItems,
3761
- customImports,
3762
- customContent
3763
- });
3764
- const content = [
3765
- ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
3766
- const path = isAbsolute(from) ? relativeWithDot(silgi.options.build.typesDir, from) : from;
3767
- if (silgi.options.typescript.removeFileExtension) {
3768
- from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
3769
- }
3770
- return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${path}'`;
3771
- }),
3772
- "",
3773
- ...customImports,
3774
- "",
3775
- ...customContent,
3776
- ""
3777
- ];
3778
- return {
3779
- content,
3780
- importItems
3781
- };
3782
- }
3783
-
3784
- async function writeCoreFile(silgi) {
3785
- const data = await prepareFramework(silgi);
3786
- const coreContent = await prepareCoreFile({
3787
- _importItems: data?.importItems ?? {},
3788
- _customImports: data?.customImports ?? []
3789
- }, data?.content ?? [], silgi);
3790
- const configs = await prepareConfigs(silgi);
3791
- const silgiDir = resolve(silgi.options.silgi.serverDir);
3792
- const buildFiles = [];
3793
- buildFiles.push({
3794
- path: join(silgiDir, "core.ts"),
3795
- contents: coreContent.join("\n")
3796
- });
3797
- buildFiles.push({
3798
- path: join(silgiDir, "configs.ts"),
3799
- contents: configs.join("\n")
3800
- });
3801
- for await (const file of buildFiles) {
3802
- if (!silgi.errors.length) {
3803
- await writeFile(
3804
- resolve(silgi.options.build.dir, file.path),
3805
- file.contents
3806
- );
3807
- }
3808
- }
3809
- }
3810
-
3811
- async function generateRouterDTS(silgi) {
3812
- const uris = silgi.uris;
3813
- const subPath = "srn";
3814
- const groupedPaths = /* @__PURE__ */ new Map();
3815
- Object.entries(uris || {}).forEach(([key, params]) => {
3816
- const [service, resource, method, action] = key.split("/");
3817
- const basePath = params ? `${subPath}/${service}/${resource}/${action}/${params}` : `${subPath}/${service}/${resource}/${action}`;
3818
- const fullPath = `${subPath}/${service}/${resource}/${action}`;
3819
- if (!groupedPaths.has(basePath)) {
3820
- groupedPaths.set(basePath, /* @__PURE__ */ new Map());
3821
- }
3822
- groupedPaths.get(basePath)?.set(method.toLowerCase(), fullPath);
3823
- });
3824
- const keys = [
3825
- " keys: {",
3826
- Array.from(groupedPaths.entries()).map(([basePath, methods]) => {
3827
- return ` '/${basePath}': {${Array.from(methods.entries()).map(([method, path]) => `
3828
- ${method}: '/${path}'`).join(",")}
3829
- }`;
3830
- }).join(",\n"),
3831
- " }",
3832
- ""
3833
- ].join("\n");
3834
- const groupedRoutes = Object.entries(uris || {}).reduce((acc, [key, _params]) => {
3835
- const [service, resource, method, action] = key.split("/");
3836
- const routePath = `${subPath}/${service}/${resource}/${action}`;
3837
- if (!acc[routePath]) {
3838
- acc[routePath] = {};
3839
- }
3840
- acc[routePath][method] = {
3841
- input: `ExtractInputFromURI<'${key}'>`,
3842
- output: `ExtractOutputFromURI<'${key}'>`,
3843
- queryParams: `ExtractQueryParamsFromURI<'${key}'>`,
3844
- pathParams: `ExtractPathParamsFromURI<'${key}'>`
3845
- };
3846
- return acc;
3847
- }, {});
3848
- const routerTypes = Object.entries(groupedRoutes).map(([path, methods]) => {
3849
- const methodEntries = Object.entries(methods).map(([method, { input, output, queryParams, pathParams }]) => {
3850
- return ` '${method}': {
3851
- input: ${input},
3852
- output: ${output},
3853
- queryParams: ${queryParams},
3854
- pathParams: ${pathParams}
3855
- }`;
3856
- }).join(",\n");
3857
- return ` '/${path}': {
3858
- ${methodEntries}
3859
- }`;
3860
- });
3861
- const nitro = [
3862
- "declare module 'nitropack/types' {",
3863
- " interface InternalApi extends RouterTypes {}",
3864
- "}"
3865
- ];
3866
- const content = [
3867
- keys.slice(0, -1),
3868
- // son satırdaki boş satırı kaldır
3869
- ...routerTypes
3870
- ].join(",\n");
3871
- const context = [
3872
- "import type { ExtractInputFromURI, ExtractOutputFromURI, ExtractQueryParamsFromURI, ExtractPathParamsFromURI } from 'silgi/types'",
3873
- "",
3874
- "export interface RouterTypes {",
3875
- content,
3876
- "}",
3877
- "",
3878
- "declare module 'silgi/types' {",
3879
- " interface SilgiRouterTypes extends RouterTypes {",
3880
- " }",
3881
- "}",
3882
- "",
3883
- silgi.options.preset === "h3" || silgi.options.preset === "nitro" ? nitro.join("\n") : "",
3884
- "",
3885
- "export {}"
3886
- ];
3887
- return context;
3888
- }
3889
-
3890
- async function prepareSchema(silgi) {
3891
- const importItems = {
3892
- "silgi/types": {
3893
- import: [
3894
- {
3895
- name: "URIsTypes",
3896
- type: true,
3897
- key: "URIsTypes"
3898
- },
3899
- {
3900
- name: "Namespaces",
3901
- type: true,
3902
- key: "Namespaces"
3903
- },
3904
- {
3905
- name: "SilgiRuntimeContext",
3906
- type: true,
3907
- key: "SilgiRuntimeContext"
3908
- }
3909
- ],
3910
- from: "silgi/types"
3911
- },
3912
- "silgi/scan": {
3913
- import: [{
3914
- key: "modulesURIs",
3915
- name: "modulesURIs",
3916
- type: false
3917
- }],
3918
- from: relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/scan.ts`)
3919
- }
3920
- };
3921
- const data = {
3922
- importItems,
3923
- customImports: [],
3924
- options: [],
3925
- contexts: [],
3926
- actions: [],
3927
- shareds: [
3928
- {
3929
- key: "modulesURIs",
3930
- value: "{ modulesURIs: typeof modulesURIs }"
3931
- }
3932
- ],
3933
- events: [],
3934
- hooks: [],
3935
- runtimeHooks: [],
3936
- runtimeOptions: [],
3937
- methods: [],
3938
- routeRules: [],
3939
- routeRulesConfig: []
3940
- };
3941
- await silgi.callHook("prepare:schema.ts", data);
3942
- relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/core.ts`);
3943
- const silgiScanTS = relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/scan.ts`);
3944
- let addSilgiContext = false;
3945
- const importsContent = [
3946
- ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
3947
- const path = isAbsolute(from) ? relativeWithDot(silgi.options.build.typesDir, from) : from;
3948
- if (silgi.options.typescript.removeFileExtension) {
3949
- from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
3950
- }
3951
- return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${path}'`;
3952
- }),
3953
- "",
3954
- ...data.customImports,
3955
- ""
3956
- ];
3957
- const importData = [
3958
- "interface InferredNamespaces {",
3959
- ...(silgi.options.namespaces || []).map((key) => ` ${key}: string,`),
3960
- "}",
3961
- "",
3962
- `type SchemaExtends = Namespaces<typeof import('${silgiScanTS}')['schemas']>`,
3963
- "",
3964
- `type SilgiURIsMerge = URIsTypes<typeof import('${silgiScanTS}')['uris']>`,
3965
- "",
3966
- `type SilgiModuleContextExtends = ${data.contexts.length ? data.contexts.map(({ value }) => value).join(" & ") : "{}"}`,
3967
- "",
3968
- data.events.length ? `interface SilgiModuleEventsExtends extends ${data.events.map((item) => item.extends ? item.value : "").join(", ")} {
3969
- ${data.events.map((item) => {
3970
- if (item.isSilgiContext) {
3971
- addSilgiContext = true;
3972
- }
3973
- return !item.extends && !addSilgiContext ? ` ${item.key}: ${item.value}` : item.isSilgiContext ? " context: SilgiRuntimeContext" : "";
3974
- }).join(",\n")}
3975
- }` : "interface SilgiModuleEventsExtends {}",
3976
- "",
3977
- `type RuntimeActionExtends = ${data.actions?.length ? data.actions.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3978
- "",
3979
- `type RuntimeMethodExtends = ${data.methods?.length ? data.methods.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3980
- "",
3981
- `type RuntimeRouteRulesExtends = ${data.routeRules?.length ? data.routeRules.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3982
- "",
3983
- `type RuntimeRouteRulesConfigExtends = ${data.routeRulesConfig?.length ? data.routeRulesConfig.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3984
- "",
3985
- `type SilgiModuleSharedExtends = ${data.shareds.length ? data.shareds.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3986
- "",
3987
- `type SilgiModuleOptionExtend = ${data.options?.length ? data.options.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3988
- "",
3989
- `type SilgiRuntimeOptionExtends = ${data.runtimeOptions?.length ? data.runtimeOptions.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
3990
- "",
3991
- silgi.options.typescript.generateRuntimeConfigTypes ? generateTypes(
3992
- await resolveSchema(
3993
- {
3994
- ...Object.fromEntries(
3995
- Object.entries(silgi.options.runtimeConfig).filter(
3996
- ([key]) => !["app", "nitro", "nuxt"].includes(key)
3997
- )
3998
- )
3999
- }
4000
- ),
4001
- {
4002
- interfaceName: "SilgiRuntimeConfigExtends",
4003
- addExport: false,
4004
- addDefaults: false,
4005
- allowExtraKeys: false,
4006
- indentation: 0
4007
- }
4008
- ) : "",
4009
- "",
4010
- generateTypes(
4011
- await resolveSchema(
4012
- {
4013
- ...silgi.options.storages?.reduce((acc, key) => ({ ...acc, [key]: "" }), {}) || {},
4014
- // 'redis': {} -> 'redis': string
4015
- ...Object.entries(silgi.options.storage).map(([key]) => ({
4016
- [key]: ""
4017
- })).reduce((acc, obj) => ({ ...acc, ...obj }), {})
4018
- }
4019
- ),
4020
- {
4021
- interfaceName: "SilgiStorageBaseExtends",
4022
- addExport: false,
4023
- addDefaults: false,
4024
- allowExtraKeys: false,
4025
- indentation: 0
4026
- }
4027
- ),
4028
- "",
4029
- `type ModuleHooksExtend = ${data.hooks?.length ? data.hooks.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
4030
- "",
4031
- `type SilgiRuntimeHooksExtends = ${data.runtimeHooks?.length ? data.runtimeHooks.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
4032
- "",
4033
- "declare module 'silgi/types' {",
4034
- " interface FrameworkContext extends FrameworkContextExtends {}",
4035
- " interface SilgiSchema extends SchemaExtends {}",
4036
- " interface SilgiNamespaces extends InferredNamespaces {}",
4037
- " interface SilgiStorageBase extends SilgiStorageBaseExtends {}",
4038
- " interface SilgiURIs extends SilgiURIsMerge {}",
4039
- " interface SilgiRuntimeContext extends SilgiModuleContextExtends {}",
4040
- " interface SilgiEvents extends SilgiModuleEventsExtends {}",
4041
- " interface SilgiRuntimeSharedsExtend extends SilgiModuleSharedExtends {}",
4042
- " interface SilgiRuntimeActions extends RuntimeActionExtends {}",
4043
- " interface SilgiModuleOptions extends SilgiModuleOptionExtend {}",
4044
- " interface SilgiRuntimeOptions extends SilgiRuntimeOptionExtends {}",
4045
- " interface SilgiRuntimeHooks extends SilgiRuntimeHooksExtends {}",
4046
- " interface SilgiRuntimeConfig extends SilgiRuntimeConfigExtends {}",
4047
- " interface SilgiHooks extends ModuleHooksExtend {}",
4048
- " interface SilgiRuntimeMethods extends RuntimeMethodExtends {}",
4049
- " interface SilgiRuntimeRouteRules extends RuntimeRouteRulesExtends {}",
4050
- " interface SilgiRuntimeRouteRulesConfig extends RuntimeRouteRulesConfigExtends {}",
4051
- " interface SilgiCommands extends SilgiCommandsExtended {}",
4052
- "",
4053
- "}",
4054
- "",
4055
- "export {}"
4056
- ];
4057
- await silgi.callHook("after:prepare:schema.ts", importData);
4058
- importData.unshift(...importsContent);
4059
- return importData;
4060
- }
4061
-
4062
- async function writeTypesAndFiles(silgi) {
4063
- const routerDTS = await generateRouterDTS(silgi);
4064
- silgi.hook("prepare:types", (opts) => {
4065
- opts.references.push({ path: "./schema.d.ts" });
4066
- opts.references.push({ path: "./silgi-routes.d.ts" });
4067
- opts.references.push({ path: "./framework.d.ts" });
4068
- });
4069
- const schemaContent = await prepareSchema(silgi);
4070
- const frameworkDTS = await createDTSFramework(silgi);
4071
- const { declarations, tsConfig } = await silgiGenerateType(silgi);
4072
- const tsConfigPath = resolve(
4073
- silgi.options.rootDir,
4074
- silgi.options.typescript.tsconfigPath
4075
- );
4076
- const typesDir = resolve(silgi.options.build.typesDir);
4077
- let autoImportedTypes = [];
4078
- let autoImportExports = "";
4079
- if (silgi.unimport) {
4080
- await silgi.unimport.init();
4081
- const allImports = await silgi.unimport.getImports();
4082
- autoImportExports = toExports(allImports).replace(
4083
- /#internal\/nitro/g,
4084
- relative(typesDir, runtimeDir)
4085
- );
4086
- const resolvedImportPathMap = /* @__PURE__ */ new Map();
4087
- for (const i of allImports.filter((i2) => !i2.type)) {
4088
- if (resolvedImportPathMap.has(i.from)) {
4089
- continue;
4090
- }
4091
- let path = resolveAlias$1(i.from, silgi.options.alias);
4092
- if (isAbsolute(path)) {
4093
- const resolvedPath = await resolvePath(i.from, {
4094
- url: silgi.options.nodeModulesDirs
4095
- }).catch(() => null);
4096
- if (resolvedPath) {
4097
- const { dir, name } = parseNodeModulePath(resolvedPath);
4098
- if (!dir || !name) {
4099
- path = resolvedPath;
4100
- } else {
4101
- const subpath = await lookupNodeModuleSubpath(resolvedPath);
4102
- path = join(dir, name, subpath || "");
4103
- }
4104
- }
4105
- }
4106
- if (existsSync(path) && !await isDirectory(path)) {
4107
- path = path.replace(/\.[a-z]+$/, "");
4108
- }
4109
- if (isAbsolute(path)) {
4110
- path = relative(typesDir, path);
4111
- }
4112
- resolvedImportPathMap.set(i.from, path);
4113
- }
4114
- autoImportedTypes = [
4115
- silgi.options.imports && silgi.options.imports.autoImport !== false ? (await silgi.unimport.generateTypeDeclarations({
4116
- exportHelper: false,
4117
- resolvePath: (i) => resolvedImportPathMap.get(i.from) ?? i.from
4118
- })).trim() : ""
4119
- ];
4120
- }
4121
- const buildFiles = [];
4122
- buildFiles.push({
4123
- path: join(typesDir, "silgi-routes.d.ts"),
4124
- contents: routerDTS.join("\n")
4125
- });
4126
- buildFiles.push({
4127
- path: join(typesDir, "silgi-imports.d.ts"),
4128
- contents: [...autoImportedTypes, autoImportExports || "export {}"].join(
4129
- "\n"
4130
- )
4131
- });
4132
- buildFiles.push({
4133
- path: join(typesDir, "schema.d.ts"),
4134
- contents: schemaContent.join("\n")
4135
- });
4136
- buildFiles.push({
4137
- path: join(typesDir, "silgi.d.ts"),
4138
- contents: declarations.join("\n")
4139
- });
4140
- buildFiles.push({
4141
- path: tsConfigPath,
4142
- contents: JSON.stringify(tsConfig, null, 2)
4143
- });
4144
- buildFiles.push({
4145
- path: join(typesDir, "framework.d.ts"),
4146
- contents: frameworkDTS.content.join("\n")
4147
- });
4148
- for await (const file of buildFiles) {
4149
- if (!silgi.errors.length) {
4150
- await writeFile(
4151
- resolve(silgi.options.build.dir, file.path),
4152
- file.contents
4153
- );
4154
- }
4155
- }
4156
- }
4157
-
4158
- const autoImportTypes = [
4159
- "ExtractInputFromURI",
4160
- "ExtractOutputFromURI",
4161
- "ExtractPathParamsFromURI",
4162
- "ExtractQueryParamsFromURI"
4163
- ];
4164
-
4165
- export { ErrorCategory, ErrorFactory, ErrorSeverity, HttpStatus, SilgiError, autoImportTypes, createSchema, createService, createShared, createSilgi, createSilgiApp, createStorage, getEvent, getEventContext, isBaseError, loadOptions, mergeSchemas, mergeServices, mergeShared, parseURI, prepare, prepareBuild, reloadScan, replaceRuntimeValues, setupDotenv, silgi, silgiAppCtx, silgiClose, silgiCtx, storageMount, tryUseSilgi, tryUseSilgiApp, useSilgi, useSilgiApp, useSilgiStorage, writeCoreFile, writeTypesAndFiles };
1
+ export { ErrorCategory, ErrorFactory, ErrorSeverity, HttpStatus, SilgiError, autoImportTypes, createSchema, createService, createShared, createSilgi, createStorage, getEvent, getEventContext, isBaseError, mergeSchemas, mergeServices, mergeShared, parseURI, replaceRuntimeValues, silgi, silgiCtx, storageMount, tryUseSilgi, useSilgi, useSilgiStorage } from './core/index.mjs';
2
+ export { s as silgiCLICtx, t as tryUseSilgiCLI, u as useSilgiCLI } from './_chunks/silgiApp.mjs';
3
+ import 'consola';
4
+ import 'defu';
5
+ import 'hookable';
6
+ import 'unctx';
7
+ import 'node:buffer';
8
+ import 'klona';
9
+ import 'silgi/runtime';
10
+ import 'unstorage';
11
+ import 'ufo';