silgi 0.24.16 → 0.24.18

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,13 +1,14 @@
1
- import { e as createRouteRules } from './shared/silgi.CvG35CGc.mjs';
2
- export { c as createSilgiCLI, a as prepare, d as prepareBuild, f as silgiCLICtx, t as tryUseSilgiCLI, u as useSilgiCLI, b as writeCoreFile, w as writeTypesAndFiles } from './shared/silgi.CvG35CGc.mjs';
3
- import { createConsola } from 'consola';
4
- import defu, { defu as defu$1 } from 'defu';
5
- import { createHooks } from 'hookable';
6
- import { getContext } from 'unctx';
7
- import { Buffer } from 'node:buffer';
8
- import { klona } from 'klona';
9
- import { useSilgiRuntimeConfig } from 'silgi/runtime';
10
- import { createStorage as createStorage$1, builtinDrivers, prefixStorage } from 'unstorage';
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 { c as createSilgiCLI, a as prepare, p as prepareBuild, w as writeCoreFile, b as writeTypesAndFiles } from './cli/writeTypesAndFiles.mjs';
3
+ export { s as silgiCLICtx, t as tryUseSilgiCLI, u as useSilgiCLI } from './_chunks/routeRules.mjs';
4
+ import 'unctx';
5
+ import 'consola';
6
+ import 'defu';
7
+ import 'hookable';
8
+ import 'node:buffer';
9
+ import 'klona';
10
+ import 'silgi/runtime';
11
+ import 'unstorage';
11
12
  import 'knitwork';
12
13
  import 'pathe';
13
14
  import 'silgi/kit';
@@ -16,21 +17,21 @@ import 'node:fs/promises';
16
17
  import 'silgi';
17
18
  import 'silgi/runtime/meta';
18
19
  import 'unimport';
19
- import 'ufo';
20
20
  import '@clack/prompts';
21
21
  import 'dotenv';
22
22
  import 'mlly';
23
23
  import 'dev-jiti';
24
- import './shared/silgi.DWfN_DdY.mjs';
24
+ import './cli/compatibility.mjs';
25
25
  import 'semver/functions/satisfies.js';
26
26
  import 'silgi/meta';
27
27
  import 'node:url';
28
28
  import 'exsolve';
29
+ import 'ufo';
29
30
  import 'untyped';
30
31
  import 'globby';
31
32
  import 'ignore';
32
33
  import '@oxc-parser/wasm';
33
- import './shared/silgi.BIBmUBIR.mjs';
34
+ import './cli/types.mjs';
34
35
  import 'c12';
35
36
  import 'compatx';
36
37
  import 'klona/full';
@@ -39,755 +40,3 @@ import 'consola/utils';
39
40
  import 'escape-string-regexp';
40
41
  import 'pkg-types';
41
42
  import 'pathe/utils';
42
-
43
- const silgiCtx = getContext("silgi");
44
- function useSilgi() {
45
- const instance = silgiCtx.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 tryUseSilgi() {
64
- return silgiCtx.tryUse();
65
- }
66
-
67
- var HttpStatus = /* @__PURE__ */ ((HttpStatus2) => {
68
- HttpStatus2[HttpStatus2["CONTINUE"] = 100] = "CONTINUE";
69
- HttpStatus2[HttpStatus2["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
70
- HttpStatus2[HttpStatus2["PROCESSING"] = 102] = "PROCESSING";
71
- HttpStatus2[HttpStatus2["EARLY_HINTS"] = 103] = "EARLY_HINTS";
72
- HttpStatus2[HttpStatus2["OK"] = 200] = "OK";
73
- HttpStatus2[HttpStatus2["CREATED"] = 201] = "CREATED";
74
- HttpStatus2[HttpStatus2["ACCEPTED"] = 202] = "ACCEPTED";
75
- HttpStatus2[HttpStatus2["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
76
- HttpStatus2[HttpStatus2["NO_CONTENT"] = 204] = "NO_CONTENT";
77
- HttpStatus2[HttpStatus2["RESET_CONTENT"] = 205] = "RESET_CONTENT";
78
- HttpStatus2[HttpStatus2["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
79
- HttpStatus2[HttpStatus2["MULTI_STATUS"] = 207] = "MULTI_STATUS";
80
- HttpStatus2[HttpStatus2["ALREADY_REPORTED"] = 208] = "ALREADY_REPORTED";
81
- HttpStatus2[HttpStatus2["IM_USED"] = 226] = "IM_USED";
82
- HttpStatus2[HttpStatus2["MULTIPLE_CHOICES"] = 300] = "MULTIPLE_CHOICES";
83
- HttpStatus2[HttpStatus2["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
84
- HttpStatus2[HttpStatus2["FOUND"] = 302] = "FOUND";
85
- HttpStatus2[HttpStatus2["SEE_OTHER"] = 303] = "SEE_OTHER";
86
- HttpStatus2[HttpStatus2["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
87
- HttpStatus2[HttpStatus2["USE_PROXY"] = 305] = "USE_PROXY";
88
- HttpStatus2[HttpStatus2["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
89
- HttpStatus2[HttpStatus2["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
90
- HttpStatus2[HttpStatus2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
91
- HttpStatus2[HttpStatus2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
92
- HttpStatus2[HttpStatus2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
93
- HttpStatus2[HttpStatus2["FORBIDDEN"] = 403] = "FORBIDDEN";
94
- HttpStatus2[HttpStatus2["NOT_FOUND"] = 404] = "NOT_FOUND";
95
- HttpStatus2[HttpStatus2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
96
- HttpStatus2[HttpStatus2["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
97
- HttpStatus2[HttpStatus2["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
98
- HttpStatus2[HttpStatus2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
99
- HttpStatus2[HttpStatus2["CONFLICT"] = 409] = "CONFLICT";
100
- HttpStatus2[HttpStatus2["GONE"] = 410] = "GONE";
101
- HttpStatus2[HttpStatus2["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
102
- HttpStatus2[HttpStatus2["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
103
- HttpStatus2[HttpStatus2["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
104
- HttpStatus2[HttpStatus2["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
105
- HttpStatus2[HttpStatus2["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
106
- HttpStatus2[HttpStatus2["RANGE_NOT_SATISFIABLE"] = 416] = "RANGE_NOT_SATISFIABLE";
107
- HttpStatus2[HttpStatus2["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
108
- HttpStatus2[HttpStatus2["IM_A_TEAPOT"] = 418] = "IM_A_TEAPOT";
109
- HttpStatus2[HttpStatus2["MISDIRECTED_REQUEST"] = 421] = "MISDIRECTED_REQUEST";
110
- HttpStatus2[HttpStatus2["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
111
- HttpStatus2[HttpStatus2["LOCKED"] = 423] = "LOCKED";
112
- HttpStatus2[HttpStatus2["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
113
- HttpStatus2[HttpStatus2["TOO_EARLY"] = 425] = "TOO_EARLY";
114
- HttpStatus2[HttpStatus2["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
115
- HttpStatus2[HttpStatus2["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
116
- HttpStatus2[HttpStatus2["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
117
- HttpStatus2[HttpStatus2["REQUEST_HEADER_FIELDS_TOO_LARGE"] = 431] = "REQUEST_HEADER_FIELDS_TOO_LARGE";
118
- HttpStatus2[HttpStatus2["UNAVAILABLE_FOR_LEGAL_REASONS"] = 451] = "UNAVAILABLE_FOR_LEGAL_REASONS";
119
- HttpStatus2[HttpStatus2["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
120
- HttpStatus2[HttpStatus2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
121
- HttpStatus2[HttpStatus2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
122
- HttpStatus2[HttpStatus2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
123
- HttpStatus2[HttpStatus2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
124
- HttpStatus2[HttpStatus2["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
125
- HttpStatus2[HttpStatus2["VARIANT_ALSO_NEGOTIATES"] = 506] = "VARIANT_ALSO_NEGOTIATES";
126
- HttpStatus2[HttpStatus2["INSUFFICIENT_STORAGE"] = 507] = "INSUFFICIENT_STORAGE";
127
- HttpStatus2[HttpStatus2["LOOP_DETECTED"] = 508] = "LOOP_DETECTED";
128
- HttpStatus2[HttpStatus2["NOT_EXTENDED"] = 510] = "NOT_EXTENDED";
129
- HttpStatus2[HttpStatus2["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
130
- return HttpStatus2;
131
- })(HttpStatus || {});
132
- var ErrorSeverity = /* @__PURE__ */ ((ErrorSeverity2) => {
133
- ErrorSeverity2["DEBUG"] = "DEBUG";
134
- ErrorSeverity2["INFO"] = "INFO";
135
- ErrorSeverity2["WARNING"] = "WARNING";
136
- ErrorSeverity2["ERROR"] = "ERROR";
137
- ErrorSeverity2["CRITICAL"] = "CRITICAL";
138
- return ErrorSeverity2;
139
- })(ErrorSeverity || {});
140
- var ErrorCategory = /* @__PURE__ */ ((ErrorCategory2) => {
141
- ErrorCategory2["AUTHENTICATION"] = "auth";
142
- ErrorCategory2["AUTHORIZATION"] = "authorization";
143
- ErrorCategory2["VALIDATION"] = "validation";
144
- ErrorCategory2["BUSINESS"] = "business";
145
- ErrorCategory2["INFRASTRUCTURE"] = "infrastructure";
146
- ErrorCategory2["EXTERNAL"] = "external";
147
- ErrorCategory2["UNKNOWN"] = "unknown";
148
- return ErrorCategory2;
149
- })(ErrorCategory || {});
150
- class ErrorFactory {
151
- static createMetadata(metadata) {
152
- return {
153
- timestamp: Date.now(),
154
- ...metadata
155
- };
156
- }
157
- static create(options) {
158
- return new SilgiError({
159
- code: options.code ?? options.httpStatus ?? 500 /* INTERNAL_SERVER_ERROR */,
160
- message: options.message,
161
- category: options.category ?? "unknown" /* UNKNOWN */,
162
- severity: options.severity ?? "ERROR" /* ERROR */,
163
- httpStatus: options.httpStatus ?? 500 /* INTERNAL_SERVER_ERROR */,
164
- metadata: this.createMetadata(options.metadata),
165
- cause: options.cause,
166
- context: options.context
167
- });
168
- }
169
- // Predefined error creators
170
- static authenticationError(message, context) {
171
- return this.create({
172
- message,
173
- code: 401,
174
- category: "auth" /* AUTHENTICATION */,
175
- severity: "ERROR" /* ERROR */,
176
- httpStatus: 401 /* UNAUTHORIZED */,
177
- context
178
- });
179
- }
180
- static authorizationError(message, context) {
181
- return this.create({
182
- message,
183
- code: 403,
184
- category: "authorization" /* AUTHORIZATION */,
185
- severity: "ERROR" /* ERROR */,
186
- httpStatus: 403 /* FORBIDDEN */,
187
- context
188
- });
189
- }
190
- static validationError(message, context) {
191
- return this.create({
192
- message,
193
- code: 400,
194
- category: "validation" /* VALIDATION */,
195
- severity: "WARNING" /* WARNING */,
196
- httpStatus: 400 /* BAD_REQUEST */,
197
- context
198
- });
199
- }
200
- static notFoundError(message, context) {
201
- return this.create({
202
- message,
203
- code: 404,
204
- category: "business" /* BUSINESS */,
205
- severity: "WARNING" /* WARNING */,
206
- httpStatus: 404 /* NOT_FOUND */,
207
- context
208
- });
209
- }
210
- static internalError(message, cause) {
211
- return this.create({
212
- message,
213
- code: 500,
214
- category: "infrastructure" /* INFRASTRUCTURE */,
215
- severity: "CRITICAL" /* CRITICAL */,
216
- httpStatus: 500 /* INTERNAL_SERVER_ERROR */,
217
- cause
218
- });
219
- }
220
- }
221
- class SilgiError extends Error {
222
- code;
223
- category;
224
- severity;
225
- httpStatus;
226
- metadata;
227
- context;
228
- cause;
229
- constructor(error) {
230
- super(error.message);
231
- this.name = "SilgiError";
232
- this.code = error.code;
233
- this.category = error.category;
234
- this.severity = error.severity;
235
- this.httpStatus = error.httpStatus;
236
- this.metadata = error.metadata ?? { timestamp: Date.now() };
237
- this.context = error.context;
238
- this.cause = error.cause;
239
- if (Error.captureStackTrace) {
240
- Error.captureStackTrace(this, this.constructor);
241
- }
242
- }
243
- toString() {
244
- let str = `${this.name} [${this.code}] ${this.severity}: ${this.message}`;
245
- str += `
246
- Category: ${this.category}`;
247
- str += `
248
- HTTP Status: ${this.httpStatus}`;
249
- if (this.context) {
250
- str += `
251
- Context: ${JSON.stringify(this.context, null, 2)}`;
252
- }
253
- if (this.metadata) {
254
- str += `
255
- Metadata: ${JSON.stringify(this.metadata, null, 2)}`;
256
- }
257
- if (this.stack) {
258
- str += `
259
- ${this.stack}`;
260
- }
261
- return str;
262
- }
263
- toJSON() {
264
- return {
265
- name: this.name,
266
- code: this.code,
267
- message: this.message,
268
- category: this.category,
269
- severity: this.severity,
270
- httpStatus: this.httpStatus,
271
- metadata: this.metadata,
272
- context: this.context,
273
- stack: this.stack
274
- };
275
- }
276
- static isError(error) {
277
- return error instanceof SilgiError || typeof error === "object" && error !== null && "name" in error && error.name === "SilgiError";
278
- }
279
- static from(error) {
280
- if (error instanceof SilgiError) {
281
- return error;
282
- }
283
- return ErrorFactory.internalError(
284
- error instanceof Error ? error.message : String(error),
285
- error instanceof Error ? error : void 0
286
- );
287
- }
288
- }
289
- function isBaseError(error) {
290
- return typeof error === "object" && error !== null && "code" in error && "message" in error && "category" in error && "severity" in error && "httpStatus" in error;
291
- }
292
-
293
- function parseURI(uri, uris) {
294
- if (!uri) {
295
- throw ErrorFactory.create({
296
- message: "URI cannot be empty",
297
- httpStatus: HttpStatus.BAD_REQUEST,
298
- context: { uri }
299
- });
300
- }
301
- if (!uris) {
302
- throw ErrorFactory.create({
303
- message: "URIs configuration is not provided",
304
- httpStatus: HttpStatus.INTERNAL_SERVER_ERROR,
305
- context: { uri }
306
- });
307
- }
308
- const cleanUri = uri.replace(/^\/*(srn\/)?/, "").replace(/\/*$/, "");
309
- const [path, queryString] = cleanUri.split("?");
310
- const parts = path.split("/");
311
- const query = queryString ? Object.fromEntries(
312
- queryString.split("&").map((param) => param.split("="))
313
- ) : void 0;
314
- const method = query?.method ? query?.method.toLowerCase() : void 0;
315
- const namespaceName = parts[0];
316
- const serviceName = parts[1];
317
- const methodName = method || parts[2];
318
- const actionName = method ? parts[2] : parts[3];
319
- if (!namespaceName || !serviceName || !methodName || !actionName) {
320
- throw ErrorFactory.create({
321
- message: "Invalid URI format: Insufficient path segments",
322
- httpStatus: HttpStatus.BAD_REQUEST,
323
- context: {
324
- uri,
325
- cleanUri,
326
- partsLength: parts.length,
327
- method,
328
- namespaceName,
329
- serviceName,
330
- methodName,
331
- actionName
332
- }
333
- });
334
- }
335
- const baseUri = `${namespaceName}/${serviceName}/${methodName}/${actionName}`;
336
- const paramStartIndex = method ? 3 : 4;
337
- const parameters = parts.slice(paramStartIndex);
338
- const normalizedUri = method ? `${namespaceName}/${serviceName}/${method}/${actionName}${parameters.length ? `/${parameters.join("/")}` : ""}` : cleanUri;
339
- const template = uris[baseUri];
340
- if (template === void 0) {
341
- throw ErrorFactory.create({
342
- message: "No route found for URI",
343
- httpStatus: HttpStatus.NOT_FOUND,
344
- context: {
345
- uri,
346
- baseUri
347
- }
348
- });
349
- }
350
- if (template === "") {
351
- if (parameters.length > 0) {
352
- throw ErrorFactory.create({
353
- message: "No parameters expected for this route",
354
- httpStatus: HttpStatus.BAD_REQUEST,
355
- context: {
356
- uri,
357
- baseUri,
358
- extraParams: parameters
359
- }
360
- });
361
- }
362
- if (query && query.method) {
363
- delete query.method;
364
- }
365
- return {
366
- namespaceName,
367
- serviceName,
368
- methodName,
369
- actionName,
370
- raw: normalizedUri,
371
- parts: [namespaceName, serviceName, methodName, actionName],
372
- routerParams: {},
373
- query,
374
- uri: baseUri
375
- };
376
- }
377
- const routeTemplate = typeof template === "string" ? template : template.pattern;
378
- const validators = typeof template === "string" ? void 0 : template.validators;
379
- const routerParams = {};
380
- const templateParts = routeTemplate.split("/").filter(Boolean);
381
- const paramValues = parameters;
382
- let valueIndex = 0;
383
- templateParts.forEach((part) => {
384
- if (part.startsWith(":")) {
385
- const paramName = part.substring(1);
386
- const paramValue = paramValues[valueIndex];
387
- if (validators?.[paramName] && paramValue) {
388
- if (!validators[paramName](paramValue)) {
389
- throw ErrorFactory.create({
390
- message: "Invalid value for parameter",
391
- httpStatus: HttpStatus.UNPROCESSABLE_ENTITY,
392
- context: {
393
- uri,
394
- paramName,
395
- paramValue,
396
- validatorName: paramName
397
- }
398
- });
399
- }
400
- }
401
- routerParams[paramName] = paramValue || void 0;
402
- valueIndex++;
403
- } else if (part && part === paramValues[valueIndex]) {
404
- valueIndex++;
405
- }
406
- });
407
- return {
408
- namespaceName,
409
- serviceName,
410
- methodName,
411
- actionName,
412
- raw: normalizedUri,
413
- parts: [namespaceName, serviceName, methodName, actionName],
414
- routerParams,
415
- query: method ? void 0 : query,
416
- uri: baseUri
417
- };
418
- }
419
-
420
- async function findAction(silgi, uri) {
421
- const { parts } = parseURI(uri, silgi.uris);
422
- let result = silgi.services;
423
- for (const part of parts) {
424
- if (result && Object.prototype.hasOwnProperty.call(result, part)) {
425
- result = Object.assign({}, result[part]);
426
- } else {
427
- silgi.logger.fail("Action not found:", `${parts.join("/")}`);
428
- continue;
429
- }
430
- }
431
- return result;
432
- }
433
- async function scanAction(silgi) {
434
- for (const [key, _value] of Object.entries(silgi.uris)) {
435
- const segments = key.split("/").filter(Boolean);
436
- if (segments.length !== 4) {
437
- console.error(`Invalid URI format for key "${key}". URI must have exactly 4 segments in format: namespace/service/method/action`);
438
- continue;
439
- }
440
- const [namespace, service, method, action] = segments;
441
- if (!namespace || !service || !method || !action) {
442
- console.error(`Invalid URI segments for key "${key}". All segments must be non-empty`);
443
- continue;
444
- }
445
- const handler = await findAction(silgi, key);
446
- silgi.scannedHandlers.set(key, handler);
447
- }
448
- }
449
-
450
- function replaceRuntimeValues(obj, runtime) {
451
- if (!obj || typeof obj !== "object")
452
- return obj;
453
- for (const key in obj) {
454
- if (typeof obj[key] === "string" && obj[key].startsWith("runtime.")) {
455
- const runtimePath = obj[key].substring(8).split(".");
456
- let value = runtime;
457
- for (const segment of runtimePath) {
458
- if (value === void 0 || value === null)
459
- break;
460
- value = value[segment];
461
- }
462
- if (value !== void 0)
463
- obj[key] = value;
464
- } else if (typeof obj[key] === "object" && obj[key] !== null) {
465
- obj[key] = replaceRuntimeValues(obj[key], runtime);
466
- }
467
- }
468
- return obj;
469
- }
470
-
471
- async function createStorage(silgi) {
472
- const storage = createStorage$1();
473
- const runtime = useSilgiRuntimeConfig();
474
- const mounts = klona({
475
- ...silgi.options.storage,
476
- ...silgi.options.devStorage
477
- });
478
- for (const [path, opts] of Object.entries(mounts)) {
479
- if (opts.driver) {
480
- const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
481
- const processedOpts = replaceRuntimeValues({ ...opts }, runtime);
482
- storage.mount(path, driver(processedOpts));
483
- } else {
484
- silgi.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
485
- }
486
- }
487
- return storage;
488
- }
489
- function useSilgiStorage(base = "/memory:cache") {
490
- const silgi = useSilgi();
491
- return base ? prefixStorage(silgi.storage, base) : silgi.storage;
492
- }
493
- async function generateStorageKey(params) {
494
- const {
495
- operation,
496
- input,
497
- keyGenerator,
498
- requestId,
499
- storageOptions
500
- } = params;
501
- const cacheScopePrefix = storageOptions?.scope === "request" ? "req" : "global";
502
- const parts = [
503
- cacheScopePrefix,
504
- // Always include scope prefix first
505
- operation.namespaceName,
506
- operation.serviceName,
507
- operation.methodName
508
- ].filter(Boolean);
509
- if (storageOptions?.scope === "request") {
510
- if (!requestId) {
511
- throw ErrorFactory.create({
512
- code: HttpStatus.BAD_REQUEST,
513
- message: "Request ID is required for request-scoped cache",
514
- context: {
515
- requestId,
516
- operation,
517
- input,
518
- storageOptions,
519
- keyGenerator
520
- }
521
- });
522
- }
523
- parts.push(requestId);
524
- }
525
- if (keyGenerator) {
526
- const customKey = await Promise.resolve(keyGenerator(input));
527
- parts.push(customKey);
528
- } else {
529
- parts.push(typeof input === "object" ? JSON.stringify(input) : String(input));
530
- }
531
- return Buffer.from(parts.join(":")).toString("base64");
532
- }
533
-
534
- async function runSilgiPlugins(silgi) {
535
- for (const plugin of silgi.plugins) {
536
- try {
537
- await plugin(silgi);
538
- } catch (error) {
539
- silgi.captureError(error, { tags: ["plugin"] });
540
- throw error;
541
- }
542
- }
543
- }
544
- async function createSilgi(config) {
545
- const hooks = createHooks();
546
- const silgi = {
547
- schemas: config.schemas,
548
- services: config.services ?? {},
549
- shared: config.shared ?? void 0,
550
- uris: config.uris ?? {},
551
- modulesURIs: config.modulesURIs ?? {},
552
- scannedHandlers: /* @__PURE__ */ new Map(),
553
- plugins: config.plugins ?? [],
554
- framework: config.framework ?? void 0,
555
- storage: config.options.putStorage ?? void 0,
556
- options: config.options ?? {},
557
- hooks,
558
- callHook: hooks.callHook,
559
- addHooks: hooks.addHooks,
560
- hook: hooks.hook,
561
- ready: () => {
562
- return hooks.callHook("ready", silgi);
563
- },
564
- envOptions: config.envOptions ?? {},
565
- close: () => hooks.callHook("close", silgi),
566
- logger: createConsola(defu(config.options?.consolaOptions ?? {}, {
567
- tag: "silgi"
568
- })).withTag("silgi"),
569
- captureError: config.captureError ?? (() => {
570
- }),
571
- routeRules: void 0
572
- };
573
- const routeRules = createRouteRules();
574
- routeRules.importRules(config.options.routeRules ?? {});
575
- silgi.routeRules = routeRules;
576
- silgi.hooks.addHooks(silgi.options.hooks);
577
- await runSilgiPlugins(silgi);
578
- await scanAction(silgi);
579
- if (!silgi.storage) {
580
- silgi.storage = await createStorage(silgi);
581
- }
582
- silgi.shared.storage = (...data) => {
583
- return useSilgiStorage(...data);
584
- };
585
- silgi.shared.runtimeConfig = silgi.options.runtimeConfig;
586
- if (silgiCtx.tryUse()) {
587
- silgiCtx.unset();
588
- silgiCtx.set(silgi);
589
- } else {
590
- silgiCtx.set(silgi);
591
- silgi.hook("close", () => silgiCtx.unset());
592
- }
593
- silgi.logger.info("Silgi installed");
594
- hooks.hookOnce("close", async () => {
595
- hooks.removeAllHooks();
596
- await silgi.storage.dispose();
597
- });
598
- return silgi;
599
- }
600
-
601
- function silgi(event) {
602
- return {
603
- execute: (uriString, input, source, queryParams) => {
604
- return execute(uriString, input, event, source, queryParams);
605
- }
606
- };
607
- }
608
- async function execute(uriString, input, event, source, queryParams) {
609
- const silgiCtx = useSilgi();
610
- const config = {
611
- returnNull: false
612
- };
613
- try {
614
- const operation = parseURI(uriString, silgiCtx.uris);
615
- if (!operation) {
616
- throw ErrorFactory.create({ message: "Invalid URI", httpStatus: HttpStatus.BAD_REQUEST });
617
- }
618
- let success = false;
619
- let cached = false;
620
- let result;
621
- const handler = silgiCtx.scannedHandlers.get(operation.uri);
622
- if (!handler) {
623
- throw ErrorFactory.create({
624
- message: "execute not found",
625
- httpStatus: HttpStatus.NOT_FOUND,
626
- context: {
627
- uri: uriString
628
- }
629
- });
630
- }
631
- await silgiCtx.callHook("execute:before", {
632
- operation,
633
- input,
634
- event,
635
- modules: handler.modules,
636
- source,
637
- config
638
- });
639
- if (config.returnNull) {
640
- return result;
641
- }
642
- const cacheData = await cacheExecute(input, operation, handler, event);
643
- if (cacheData?.success) {
644
- result = cacheData.data;
645
- success = cacheData.success;
646
- cached = cacheData.cached;
647
- } else {
648
- let parameters = defu$1(operation.routerParams, operation.query) || {};
649
- if (queryParams) {
650
- parameters = defu$1(queryParams, parameters);
651
- }
652
- silgiCtx.shared.silgi = silgi(event);
653
- result = await handler?.handler(
654
- defu$1(input, { parameters }),
655
- silgiCtx.shared,
656
- event,
657
- source
658
- );
659
- success = true;
660
- }
661
- await silgiCtx.callHook("execute:after", {
662
- operation,
663
- input,
664
- event,
665
- result,
666
- success,
667
- source,
668
- modules: handler.modules,
669
- config
670
- });
671
- if (!cached) {
672
- if (success && cacheData?.cachedKey && handler.storage) {
673
- await useSilgiStorage(handler.storage.base).setItem(cacheData.cachedKey, result, handler.storage.options);
674
- }
675
- }
676
- return result;
677
- } catch (err) {
678
- await silgiCtx.callHook("execute:error", {
679
- input,
680
- event,
681
- source,
682
- error: err instanceof Error ? err : new Error(String(err)),
683
- timestamp: Date.now(),
684
- config
685
- });
686
- silgiCtx.captureError(SilgiError.from(err), {
687
- event,
688
- tags: ["execute"]
689
- });
690
- throw err;
691
- }
692
- }
693
- async function cacheExecute(input, operation, handler, event) {
694
- if (!handler.storage)
695
- return;
696
- const cacheKey = handler.storage ? await generateStorageKey({
697
- operation,
698
- input,
699
- keyGenerator: handler.storage.key,
700
- storageOptions: handler.storage,
701
- requestId: event?.requestId
702
- }) : null;
703
- if (cacheKey) {
704
- const cachedResult = await useSilgiStorage(handler.storage.base).getItem(cacheKey);
705
- if (cachedResult !== null) {
706
- return {
707
- success: true,
708
- data: normalizeResult(cachedResult),
709
- cached: true,
710
- cachedKey: cacheKey
711
- };
712
- }
713
- }
714
- return {
715
- success: false,
716
- data: null,
717
- cached: false,
718
- cachedKey: cacheKey
719
- };
720
- }
721
-
722
- function merge(items, maxLevel = 4, currentLevel = 1) {
723
- const arrayItems = Array.isArray(items) ? items : [items];
724
- return arrayItems.reduce((acc, item) => {
725
- if (!item)
726
- return acc;
727
- Object.keys(item).forEach((key) => {
728
- if (typeof item[key] === "object" && item[key] !== null && currentLevel < maxLevel) {
729
- if (!acc[key] || typeof acc[key] !== "object") {
730
- acc[key] = {};
731
- }
732
- acc[key] = merge([acc[key], item[key]], maxLevel, currentLevel + 1);
733
- } else if (acc[key] === void 0) {
734
- acc[key] = item[key];
735
- }
736
- });
737
- return acc;
738
- }, {});
739
- }
740
- function mergeSchemas(typesOrArray) {
741
- return merge(typesOrArray);
742
- }
743
- function mergeServices(servicesOrArray) {
744
- return merge(servicesOrArray);
745
- }
746
- function mergeShared(sharedOrArray) {
747
- return merge(sharedOrArray, 1, 1);
748
- }
749
-
750
- function getEvent(event) {
751
- const silgi = useSilgi();
752
- if (silgi.options.present === "h3" || silgi.options.present === "nitro" || silgi.options.present === "nuxt") {
753
- return event.event;
754
- }
755
- return event;
756
- }
757
- function getEventContext(event) {
758
- const _event = getEvent(event);
759
- return _event.context;
760
- }
761
-
762
- function createSchema(silgiType) {
763
- return silgiType;
764
- }
765
-
766
- function createService(variables) {
767
- return variables;
768
- }
769
-
770
- function createShared(shared) {
771
- return shared;
772
- }
773
-
774
- function storageMount(silgi) {
775
- const _silgi = silgi || useSilgi();
776
- return (base, driver) => {
777
- const existingStorage = _silgi.storage.getMount(base);
778
- if (existingStorage) {
779
- return existingStorage.driver;
780
- }
781
- const storage = _silgi.storage.mount(base, driver);
782
- return storage;
783
- };
784
- }
785
-
786
- const autoImportTypes = [
787
- "ExtractInputFromURI",
788
- "ExtractOutputFromURI",
789
- "ExtractPathParamsFromURI",
790
- "ExtractQueryParamsFromURI"
791
- ];
792
-
793
- 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 };