silgi 0.40.1 → 0.41.1

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.
@@ -581,7 +581,7 @@ function resolveGroupSyntax(group) {
581
581
  return groups;
582
582
  }
583
583
 
584
- const DEFAULT_FUNCTION_EXPORT_NAMES = ["createSchema", "createService", "createRoute", "createShared", "createMiddleware"];
584
+ const DEFAULT_FUNCTION_EXPORT_NAMES = ["createSchema", "createService", "createResolver", "createShared", "createMiddleware"];
585
585
  const DEFAULT_INTERFACE_EXTENDS_NAMES = ["ExtendShared", "ExtendContext"];
586
586
  function generateUniqueIdentifier(filePath, exportName) {
587
587
  const fileBaseName = basename(filePath);
@@ -592,7 +592,7 @@ function categorizeExports(exportedEntities, filePath, functionExportCategories
592
592
  createService: "service",
593
593
  createSchema: "schema",
594
594
  createShared: "shared",
595
- createRoute: "route",
595
+ createResolver: "resolver",
596
596
  createMiddleware: "middleware"
597
597
  }, interfaceExportCategories = {
598
598
  ExtendShared: "shared",
@@ -659,8 +659,8 @@ function registerExportsWithHooks(silgiInstance, runtimeExports, typeExports, pa
659
659
  case "schema":
660
660
  options.schemas.push(uniqueId);
661
661
  break;
662
- case "route":
663
- options.routers.push(uniqueId);
662
+ case "resolvers":
663
+ options.resolvers.push(uniqueId);
664
664
  break;
665
665
  case "middleware":
666
666
  options.middlewares?.push?.(uniqueId);
@@ -763,8 +763,8 @@ async function scanSilgiExports(path, packageName, silgiInstance = useSilgiCLI()
763
763
  functionExportCategories[name] = "schema";
764
764
  else if (name === "createShared")
765
765
  functionExportCategories[name] = "shared";
766
- else if (name === "createRoute")
767
- functionExportCategories[name] = "route";
766
+ else if (name === "createResolver")
767
+ functionExportCategories[name] = "resolver";
768
768
  else if (name === "createMiddleware")
769
769
  functionExportCategories[name] = "middleware";
770
770
  else functionExportCategories[name] = name;
@@ -1196,7 +1196,7 @@ async function prepareScanFile(silgi) {
1196
1196
  const scanned = {
1197
1197
  services: [],
1198
1198
  shareds: [],
1199
- routers: [],
1199
+ resolvers: [],
1200
1200
  schemas: [],
1201
1201
  middlewares: [],
1202
1202
  addImportItem,
@@ -1233,7 +1233,7 @@ async function prepareScanFile(silgi) {
1233
1233
  ...generateExport("schemas", scanned.schemas),
1234
1234
  ...generateExport("services", scanned.services),
1235
1235
  ...generateExport("shareds", scanned.shareds, "undefined"),
1236
- ...generateExport("routers", scanned.routers),
1236
+ ...generateExport("resolvers", scanned.resolvers, "[]"),
1237
1237
  ...generateExport("middlewares", scanned.middlewares)
1238
1238
  ];
1239
1239
  await silgi.callHook("after:scan.ts", importData);
@@ -1276,7 +1276,7 @@ async function readScanFile(silgi) {
1276
1276
  silgi.schemas = scanFile.schemas || {};
1277
1277
  silgi.services = scanFile.services || {};
1278
1278
  silgi.shareds = scanFile.shareds || {};
1279
- silgi.routers = scanFile.routers || {};
1279
+ silgi.resolvers = scanFile.resolvers || {};
1280
1280
  return {
1281
1281
  context,
1282
1282
  object: {
@@ -1488,7 +1488,7 @@ async function createSilgiCLI(config = {}, opts = {}) {
1488
1488
  middleware: [],
1489
1489
  shareds: {},
1490
1490
  schemas: {},
1491
- routers: {},
1491
+ resolvers: [],
1492
1492
  unimport: void 0,
1493
1493
  options,
1494
1494
  hooks,
@@ -1702,7 +1702,7 @@ async function prepareCoreFile(silgi) {
1702
1702
  name: "middlewares"
1703
1703
  },
1704
1704
  {
1705
- name: "routers"
1705
+ name: "resolvers"
1706
1706
  }
1707
1707
  ]
1708
1708
  },
@@ -1794,7 +1794,7 @@ async function prepareCoreFile(silgi) {
1794
1794
  " services: services,",
1795
1795
  " middlewares: middlewares,",
1796
1796
  " schemas: schemas,",
1797
- " routers: routers,",
1797
+ " resolvers: resolvers,",
1798
1798
  ` plugins: [${plugins.join(", ")}],`,
1799
1799
  "",
1800
1800
  _data.silgiConfigs.length > 0 ? _data.silgiConfigs.map((item) => {
@@ -1870,6 +1870,7 @@ async function prepareSchema(silgi) {
1870
1870
  contexts: [],
1871
1871
  setupModuleOption: [],
1872
1872
  shareds: [],
1873
+ resolvers: [],
1873
1874
  events: [],
1874
1875
  hooks: [],
1875
1876
  runtimeHooks: [],
@@ -1894,7 +1895,8 @@ async function prepareSchema(silgi) {
1894
1895
  "",
1895
1896
  `type SchemaExtends = typeof import('${silgiScanTS}')['schemas']`,
1896
1897
  `type BaseServices = typeof import('${silgiScanTS}')['services']`,
1897
- `type RoutersExtend = typeof import('${silgiScanTS}')['routers']`,
1898
+ `type ResolversExtend = ${data.resolvers?.length ? data.resolvers.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
1899
+ "",
1898
1900
  "",
1899
1901
  `type SilgiModuleContextExtends = ${data.contexts.length ? data.contexts.map(({ value }) => value).join(" & ") : "{}"}`,
1900
1902
  "",
@@ -1977,8 +1979,9 @@ async function prepareSchema(silgi) {
1977
1979
  SilgiRuntimeConfig: [{}, { extends: ["SilgiRuntimeConfigExtends"] }],
1978
1980
  SilgiHooks: [{}, { extends: ["ModuleHooksExtend"] }],
1979
1981
  SilgiRuntimeMethods: [{}, { extends: ["RuntimeMethodExtends"] }],
1980
- Routers: [{}, { extends: ["RoutersExtend"] }],
1982
+ Resolvers: [{}, { extends: ["ResolversExtend"] }],
1981
1983
  SilgiModuleOptions: [{}, { extends: ["SilgiModuleOptionExtend"] }],
1984
+ // TODO: bunu kontrol et.
1982
1985
  RouteRules: [{}, { extends: ["RouteRulesExtend"] }],
1983
1986
  MetaData: [{}, { extends: ["MetaDataExtend"] }]
1984
1987
  }).replace(/,\s*/g, "\n"),
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from 'citty';
3
3
 
4
- const version = "0.40.1";
4
+ const version = "0.41.1";
5
5
  const packageJson = {
6
6
  version: version};
7
7
 
@@ -351,10 +351,13 @@ async function resolvePathOptions(options) {
351
351
  }
352
352
  options.alias = {
353
353
  ...options.alias,
354
- "~/": join(options.srcDir, "/"),
355
- "@/": join(options.srcDir, "/"),
356
- "~~/": join(options.rootDir, "/"),
357
- "@@/": join(options.rootDir, "/")
354
+ // '~/': join(options.srcDir, '/'),
355
+ // '@/': join(options.srcDir, '/'),
356
+ // '~~/': join(options.rootDir, '/'),
357
+ // '@@/': join(options.rootDir, '/'),
358
+ "#server/*": join(options.silgi.serverDir, "/*"),
359
+ "#silgi/*": join(options.build.dir, "/*"),
360
+ "#types/*": join(options.build.typesDir, "/*")
358
361
  };
359
362
  if (options.preset === "npm-package") {
360
363
  options.alias = {
@@ -1,4 +1,5 @@
1
- import { SilgiConfig, Silgi, SilgiEvent, SilgiSchema, RouteEntry, CustomRequestInit, SilgiRuntimeContext, Routers, HTTPMethod, HasPathParams, BaseMethodSchema, WithPathParams, MergeAll, ServiceSetup, HttpMethod, MiddlewareSetup, SilgiRuntimeShareds, RouterConfig, SilgiURL, StorageConfig, SilgiCLI, SilgiStorageBase, SilgiRuntimeConfig } from 'silgi/types';
1
+ import { SilgiConfig, Silgi, SilgiEvent, SilgiSchema, RouteEntry, CustomRequestInit, SilgiRuntimeContext, BaseMethodSchema, MergeAll, HTTPMethod, ServiceSetup, ServicesObject, HttpMethod, MiddlewareSetup, SilgiRuntimeShareds, Resolvers, SilgiURL, StorageConfig, SilgiCLI, SilgiStorageBase, SilgiRuntimeConfig } from 'silgi/types';
2
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
3
  import { Storage, StorageValue } from 'unstorage';
3
4
  import { UseContext } from 'unctx';
4
5
 
@@ -138,15 +139,11 @@ declare function getEventContext<T extends SilgiRuntimeContext>(event?: SilgiEve
138
139
  * }
139
140
  * });
140
141
  */
141
- declare function createSchema<Path extends keyof Routers, Method extends HTTPMethod & string, UsedMethod extends readonly Method[], Schema extends HasPathParams<Path> extends true ? BaseMethodSchema & WithPathParams<Path> : BaseMethodSchema>(params: {
142
- /** Complete API path */
143
- path: Path;
144
- /** HTTP method(s) this schema applies to (optional) */
145
- method?: UsedMethod;
146
- /** Schema definition */
142
+ declare function createSchema<Key extends string, Schema extends BaseMethodSchema>(params: {
143
+ key: Key;
147
144
  setup: Schema;
148
145
  }): {
149
- [K in `${UsedMethod[number]}:${string & Path}`]: Schema;
146
+ [K in Key]: Schema;
150
147
  };
151
148
 
152
149
  /**
@@ -162,51 +159,50 @@ declare function deepMergeObjects<T extends readonly Record<string, any>[]>(sche
162
159
  * ServiceSetup tipinden oluşan bir yardımcı fonksiyon.
163
160
  * Tip güvenliğini artırmak için ServiceSetup objesini doğrudan döndürür.
164
161
  */
165
- declare function defineServiceSetup<Schema extends SilgiSchema = SilgiSchema, Route extends keyof Schema = keyof Schema, Resolved extends boolean = false, HiddenParameters extends boolean = false>(path: Route, setup: ServiceSetup<Schema, Route, Resolved, HiddenParameters>): ServiceSetup<Schema, Route, Resolved, HiddenParameters>;
166
- declare function createService<Schema extends SilgiSchema, Path extends keyof Schema, Resolved extends boolean = false, HiddenParameters extends boolean = false>(params: {
167
- path: Path;
168
- setup: ServiceSetup<Schema, Path, Resolved, HiddenParameters>;
162
+ type SlashCount<S extends string, Count extends any[] = []> = S extends `${infer _Prefix}/${infer Rest}` ? SlashCount<Rest, [any, ...Count]> : Count['length'];
163
+ type Max4Slashes<S extends string> = SlashCount<S> extends 0 | 1 | 2 | 3 | 4 ? S : never;
164
+ declare function createService<Path extends string = string, Input extends StandardSchemaV1 = StandardSchemaV1, Output extends StandardSchemaV1 = StandardSchemaV1, PathParams extends StandardSchemaV1 | never | undefined = never, QueryParams extends StandardSchemaV1 | never | undefined = never, Resolved extends boolean = false, HiddenParameters extends boolean = false>(params: {
165
+ path: Max4Slashes<Path>;
166
+ methods: HTTPMethod[];
167
+ input?: Input;
168
+ output?: Output;
169
+ queryParams?: {
170
+ path?: PathParams;
171
+ query?: QueryParams;
172
+ };
173
+ setup: ServiceSetup<Input, Output, PathParams, QueryParams, Resolved, HiddenParameters>;
169
174
  }): {
170
- [K in Path]: ServiceSetup<Schema, Path, Resolved, HiddenParameters>;
175
+ [K in Path]: {
176
+ setup: ServiceSetup<Input, Output, PathParams, QueryParams, Resolved, HiddenParameters>;
177
+ methods: HTTPMethod[];
178
+ input?: Input;
179
+ output?: Output;
180
+ queryParams?: {
181
+ path?: PathParams;
182
+ query?: QueryParams;
183
+ };
184
+ };
171
185
  };
172
186
 
173
187
  type WildcardVariants<Path extends string, Acc extends string = ''> = Path extends `${infer Head}/${infer Tail}` ? Tail extends '' ? `${Acc}${Head}` : `${Acc}${Head}/${Tail}` | `${Acc}${Head}/*` | `${Acc}${Head}/**` | WildcardVariants<Tail, `${Acc}${Head}/`> : `${Acc}${Path}`;
174
- declare function createMiddleware<S extends WildcardVariants<keyof Routers>, Method extends HttpMethod, UsedMethod extends readonly Method[]>(params: {
175
- path: S;
176
- method: UsedMethod;
177
- setup: MiddlewareSetup;
178
- global?: undefined;
179
- }): {
180
- [K in `${UsedMethod[number]}:${S}`]: {
181
- setup: MiddlewareSetup;
182
- method: UsedMethod[number];
183
- global: undefined;
184
- };
185
- };
186
- declare function createMiddleware<Global extends string>(params: {
187
- global: Global;
188
+ type MiddlewarePath<S extends WildcardVariants<keyof ServicesObject>> = S | 'global';
189
+ type CreateMiddlewareParams<S extends WildcardVariants<keyof ServicesObject>, UsedMethod extends readonly HttpMethod[] = readonly HttpMethod[], Key extends string = string> = {
190
+ path: MiddlewarePath<S>;
191
+ methods?: UsedMethod;
188
192
  setup: MiddlewareSetup;
189
- method?: undefined | readonly [];
190
- path?: undefined;
191
- }): {
192
- [K in `GLOBAL:${Global}`]: {
193
- setup: MiddlewareSetup;
194
- global: Global;
195
- method: false;
196
- };
193
+ key: Key;
197
194
  };
198
- declare function createMiddleware<Global extends string, Method extends HttpMethod, UsedMethod extends readonly Method[]>(params: {
199
- global: Global;
200
- setup: MiddlewareSetup;
201
- method: UsedMethod;
202
- path?: undefined;
203
- }): {
204
- [K in `${UsedMethod[number]}:${Global}`]: {
195
+ type CreateMiddlewareResult<Path extends string, UsedMethod extends readonly HttpMethod[] = readonly HttpMethod[], Key extends string = string> = {
196
+ [K in `${Key}:${Path}`]: {
205
197
  setup: MiddlewareSetup;
206
- global: Global;
207
- method: UsedMethod[number];
198
+ methods?: UsedMethod;
199
+ key: Key;
200
+ path: Path;
208
201
  };
209
202
  };
203
+ declare function createMiddleware<S extends WildcardVariants<keyof ServicesObject>, UsedMethod extends readonly HttpMethod[] = readonly HttpMethod[], Path extends MiddlewarePath<S> = MiddlewarePath<S>, Key extends string = string>(params: CreateMiddlewareParams<S, UsedMethod, Key> & {
204
+ path: Path;
205
+ }): CreateMiddlewareResult<Path, UsedMethod, Key>;
210
206
 
211
207
  declare function createShared(shared: Partial<SilgiRuntimeShareds>): SilgiRuntimeShareds;
212
208
 
@@ -215,9 +211,7 @@ declare function createShared(shared: Partial<SilgiRuntimeShareds>): SilgiRuntim
215
211
  */
216
212
  declare function replaceRuntimeValues(obj: any, runtime: any): any;
217
213
 
218
- declare function createRoute<URL extends string>(params: RouterConfig<URL>): {
219
- [K in URL]: RouterConfig<URL>;
220
- };
214
+ declare function createResolver(resolver: Resolvers): Resolvers;
221
215
  declare function getUrlPrefix(path: string, method?: string): SilgiURL;
222
216
 
223
217
  declare function createStorage(silgi: Silgi): Promise<Storage<StorageValue>>;
@@ -259,4 +253,4 @@ declare function useRuntime(): SilgiRuntimeConfig;
259
253
 
260
254
  declare const autoImportTypes: string[];
261
255
 
262
- export { SilgiError, autoImportTypes, createError, createMiddleware, createRoute, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, defineServiceSetup, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCLICtx, silgiCtx, silgiFetch, storageMount, tryUseSilgi, tryUseSilgiCLI, updateRuntimeStorage, useRuntime, useSilgi, useSilgiCLI, useSilgiStorage };
256
+ export { SilgiError, autoImportTypes, createError, createMiddleware, createResolver, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCLICtx, silgiCtx, silgiFetch, storageMount, tryUseSilgi, tryUseSilgiCLI, updateRuntimeStorage, useRuntime, useSilgi, useSilgiCLI, useSilgiStorage };
@@ -270,7 +270,7 @@ async function createSilgi(config) {
270
270
  routerPrefixs: [],
271
271
  schemas: config.schemas ?? {},
272
272
  services: config.services ?? {},
273
- routers: config.routers ?? {},
273
+ resolvers: config.resolvers ?? [],
274
274
  middlewares: config.middlewares ?? {},
275
275
  globalMiddlewares: config.globalMiddlewares ?? [],
276
276
  shared: config.shared ?? {},
@@ -297,14 +297,7 @@ async function createSilgi(config) {
297
297
  if (!silgi.router) {
298
298
  silgi.router = createRouter();
299
299
  }
300
- for (const routeKey in silgi.services) {
301
- let method = "GLOBAL";
302
- let route = routeKey;
303
- if (routeKey.includes(":")) {
304
- const [methodPart, ...routeParts2] = routeKey.split(":");
305
- method = methodPart.toUpperCase();
306
- route = routeParts2.join(":");
307
- }
300
+ for (const [route, object] of Object.entries(silgi.services)) {
308
301
  const routeParts = route.split("/").filter(Boolean);
309
302
  if (routeParts.length > 0) {
310
303
  const prefix = `/${routeParts[0]}`;
@@ -312,44 +305,41 @@ async function createSilgi(config) {
312
305
  silgi.routerPrefixs.push(prefix);
313
306
  }
314
307
  }
315
- const methodObject = silgi.services[routeKey];
316
- if (methodObject) {
317
- const schemaWrapper = silgi.schemas?.[routeKey];
318
- if (!schemaWrapper) {
319
- silgi.logger.warn(`Schema not found for ${routeKey}`);
320
- continue;
321
- }
322
- addRoute(silgi.router, method, route, {
323
- method,
308
+ const methods = object.methods?.length ? object.methods : ["ALL"];
309
+ for (const method of methods) {
310
+ const globalMethod = method === "ALL" ? "" : method.toUpperCase();
311
+ addRoute(silgi.router, globalMethod, route, {
312
+ method: [method],
324
313
  route,
325
- service: methodObject,
326
- schema: schemaWrapper
314
+ service: object
327
315
  });
328
316
  }
329
317
  }
330
318
  if (!silgi._middlewareRouter) {
331
319
  silgi._middlewareRouter = createRouter();
332
320
  }
333
- for (const routeKey in silgi.middlewares) {
334
- const routeObject = silgi.middlewares[routeKey];
335
- let method = "ALL";
336
- let route = routeKey;
337
- if (routeKey.includes(":")) {
338
- const [methodPart, ...routeParts] = routeKey.split(":");
339
- method = methodPart.toUpperCase();
340
- route = routeParts.join(":");
321
+ for (const [route, routeObject] of Object.entries(silgi.middlewares)) {
322
+ let _route = "";
323
+ if (route.includes(":")) {
324
+ const [methodPart, ...routeParts] = route.split(":");
325
+ methodPart.toUpperCase();
326
+ _route = routeParts.join(":");
341
327
  }
342
- if (routeObject.global) {
328
+ if (_route === "global") {
343
329
  silgi.globalMiddlewares.push({
344
330
  middleware: routeObject.setup,
345
- method,
346
- route
331
+ method: routeObject.methods?.length ? routeObject.methods : ["ALL"],
332
+ route: _route
347
333
  });
348
- } else {
349
- addRoute(silgi._middlewareRouter, method, route, {
334
+ continue;
335
+ }
336
+ const methods = routeObject.methods?.length ? routeObject.methods : ["ALL"];
337
+ for (const method of methods) {
338
+ const globalMethod = method === "ALL" ? "" : method.toUpperCase();
339
+ addRoute(silgi._middlewareRouter, globalMethod, _route, {
350
340
  middleware: routeObject.setup,
351
- method,
352
- route
341
+ method: [method],
342
+ route: _route
353
343
  });
354
344
  }
355
345
  }
@@ -561,12 +551,8 @@ function getRouterParams(event, opts = {}) {
561
551
  return params;
562
552
  }
563
553
 
564
- function createRoute(params) {
565
- return {
566
- [params.route]: {
567
- ...params
568
- }
569
- };
554
+ function createResolver(resolver) {
555
+ return resolver;
570
556
  }
571
557
  function getUrlPrefix(path, method) {
572
558
  const parse = path.includes("://") ? new FastURL(path) : new URL(path, "http://localhost");
@@ -593,7 +579,7 @@ function getUrlPrefix(path, method) {
593
579
  async function orchestrate(route, event, _input, graphql) {
594
580
  const silgiCtx = useSilgi();
595
581
  const silgiURL = getUrlPrefix(route.route || event.req.url, route.method);
596
- const input = _input || (route.service?.rules?.readBeforeBody === false || graphql ? {} : await parseRequestInput(event.req));
582
+ const input = _input || (route.service?.setup.rules?.readBeforeBody === false || graphql ? {} : await parseRequestInput(event.req));
597
583
  const hookContext = { earlyReturnValue: false };
598
584
  const routerParams = _input ? input.path : getRouterParams(event);
599
585
  const queryParams = _input ? input.query : getQuery(event);
@@ -611,8 +597,7 @@ async function orchestrate(route, event, _input, graphql) {
611
597
  }
612
598
  };
613
599
  try {
614
- const setup = route.service;
615
- if (!setup) {
600
+ if (!route.service) {
616
601
  throw createError({
617
602
  statusCode: 404,
618
603
  statusMessage: "Service not found"
@@ -647,11 +632,10 @@ async function orchestrate(route, event, _input, graphql) {
647
632
  }
648
633
  silgiCtx.shared.$fetch = silgiFetch;
649
634
  silgiCtx.shared.silgi = silgiCtx;
650
- const result = await setup?.handler(
635
+ const result = await route.service?.setup.handler(
651
636
  inputData,
652
637
  silgiCtx.shared,
653
- event,
654
- event.context.source
638
+ event
655
639
  );
656
640
  await silgiCtx.callHook("fetch:after", {
657
641
  event,
@@ -662,12 +646,12 @@ async function orchestrate(route, event, _input, graphql) {
662
646
  route,
663
647
  hookContext
664
648
  });
665
- if (setup.storage && cacheData?.cachedKey) {
666
- await useSilgiStorage(setup.storage.base).setItem(
649
+ if (route.service.setup.storage && cacheData?.cachedKey) {
650
+ await useSilgiStorage(route.service.setup.storage.base).setItem(
667
651
  cacheData.cachedKey,
668
652
  result,
669
653
  // Cast to StorageValue if needed
670
- setup.storage.options
654
+ route.service.setup.storage.options
671
655
  );
672
656
  }
673
657
  return result;
@@ -697,18 +681,17 @@ async function orchestrate(route, event, _input, graphql) {
697
681
  }
698
682
  }
699
683
  async function cacheExecute(input, route, silgiURL, event) {
700
- const setup = route.service;
701
- if (!setup || !setup.storage)
684
+ if (!route.service || !route.service.setup.storage)
702
685
  return;
703
- const cacheKey = setup.storage ? await generateStorageKey({
686
+ const cacheKey = route.service.setup.storage ? await generateStorageKey({
704
687
  url: silgiURL,
705
688
  input,
706
- keyGenerator: setup.storage.key,
707
- storageOptions: setup.storage,
689
+ keyGenerator: route.service.setup.storage.key,
690
+ storageOptions: route.service.setup.storage,
708
691
  requestId: event?.requestId
709
692
  }) : null;
710
693
  if (cacheKey) {
711
- const cachedResult = await useSilgiStorage(setup.storage.base).getItem(cacheKey);
694
+ const cachedResult = await useSilgiStorage(route.service.setup.storage.base).getItem(cacheKey);
712
695
  if (cachedResult !== null) {
713
696
  return {
714
697
  success: true,
@@ -929,7 +912,15 @@ async function middleware(event, url) {
929
912
  if (_previous !== void 0 && _previous !== kNotFound) {
930
913
  return _previous;
931
914
  }
932
- if (m.method && m.method !== "GLOBAL" && m.method !== event.req.method || !m.middleware) {
915
+ let allowedMethods = m.method ?? [];
916
+ if (!Array.isArray(allowedMethods)) {
917
+ allowedMethods = [allowedMethods];
918
+ }
919
+ const methodIsAllowed = allowedMethods.length === 0 || allowedMethods.includes("ALL") || allowedMethods.includes(event.req.method);
920
+ if (!methodIsAllowed) {
921
+ return;
922
+ }
923
+ if (!m.middleware) {
933
924
  return;
934
925
  }
935
926
  try {
@@ -959,7 +950,12 @@ async function middleware(event, url) {
959
950
  if (_previous !== void 0 && _previous !== kNotFound) {
960
951
  return _previous;
961
952
  }
962
- if (match.data.method && match.data.method !== event.req.method || !match.data.middleware) {
953
+ let allowedMethods = match.data.method ?? [];
954
+ if (!Array.isArray(allowedMethods)) {
955
+ allowedMethods = [allowedMethods];
956
+ }
957
+ const methodIsAllowed = allowedMethods.length === 0 || allowedMethods.includes("ALL") || allowedMethods.includes(event.req.method);
958
+ if (!methodIsAllowed || !match.data.middleware) {
963
959
  return;
964
960
  }
965
961
  event.context.params = match.params;
@@ -1027,15 +1023,12 @@ function getEventContext(event) {
1027
1023
  }
1028
1024
 
1029
1025
  function createSchema(params) {
1030
- const { path, method, setup } = params;
1026
+ const { key, setup } = params;
1031
1027
  const result = {};
1032
- if (!method) {
1033
- throw new Error(`Method is required createSchema ${path}`);
1034
- }
1035
- for (let i = 0; i < method.length; i++) {
1036
- const methodName = method[i];
1037
- result[`${String(methodName)}:${path}`] = setup;
1038
- }
1028
+ result[key] = {
1029
+ setup,
1030
+ key
1031
+ };
1039
1032
  return result;
1040
1033
  }
1041
1034
 
@@ -1062,47 +1055,34 @@ function deepMergeObjects(schemas) {
1062
1055
  return merged;
1063
1056
  }
1064
1057
 
1065
- function defineServiceSetup(path, setup) {
1066
- return setup;
1067
- }
1068
1058
  function createService(params) {
1069
- const { path, setup } = params;
1070
- return {
1071
- [path]: setup
1059
+ const slashCount = (params.path.match(/\//g) || []).length;
1060
+ if (slashCount > 4) {
1061
+ throw new Error(
1062
+ `Path '${params.path}' is invalid: maximum 4 '/' allowed (found ${slashCount})`
1063
+ );
1064
+ }
1065
+ const result = {};
1066
+ const { path, setup, methods, input, output, queryParams } = params;
1067
+ result[path] = {
1068
+ setup,
1069
+ methods,
1070
+ input,
1071
+ output,
1072
+ queryParams
1072
1073
  };
1074
+ return result;
1073
1075
  }
1074
1076
 
1075
1077
  function createMiddleware(params) {
1076
- if (params.global) {
1077
- const globalKey = params.global;
1078
- if (!params.method || params.method.length === 0) {
1079
- return {
1080
- [`GLOBAL:${globalKey}`]: {
1081
- setup: params.setup,
1082
- global: globalKey,
1083
- method: false
1084
- }
1085
- };
1086
- }
1087
- const result2 = {};
1088
- for (const m of params.method) {
1089
- result2[`${m}:${globalKey}`] = {
1090
- setup: params.setup,
1091
- global: globalKey,
1092
- method: m
1093
- };
1094
- }
1095
- return result2;
1096
- }
1097
- const result = {};
1098
- for (const m of params.method) {
1099
- result[`${m}:${params.path}`] = {
1078
+ return {
1079
+ [`${params.key}:${params.path}`]: {
1100
1080
  setup: params.setup,
1101
- method: m,
1102
- global: void 0
1103
- };
1104
- }
1105
- return result;
1081
+ methods: params.methods?.length ? params.methods : ["ALL"],
1082
+ key: params.key,
1083
+ path: params.path
1084
+ }
1085
+ };
1106
1086
  }
1107
1087
 
1108
1088
  function createShared(shared) {
@@ -1148,4 +1128,4 @@ const autoImportTypes = [
1148
1128
  "ExtractQueryParamsFromURI"
1149
1129
  ];
1150
1130
 
1151
- export { SilgiError, autoImportTypes, createError, createMiddleware, createRoute, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, defineServiceSetup, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCtx, silgiFetch, storageMount, tryUseSilgi, updateRuntimeStorage, useRuntime, useSilgi, useSilgiStorage };
1131
+ export { SilgiError, autoImportTypes, createError, createMiddleware, createResolver, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCtx, silgiFetch, storageMount, tryUseSilgi, updateRuntimeStorage, useRuntime, useSilgi, useSilgiStorage };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- export { SilgiError, autoImportTypes, createError, createMiddleware, createRoute, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, defineServiceSetup, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCLICtx, silgiCtx, silgiFetch, storageMount, tryUseSilgi, tryUseSilgiCLI, updateRuntimeStorage, useRuntime, useSilgi, useSilgiCLI, useSilgiStorage } from './core/index.mjs';
1
+ export { SilgiError, autoImportTypes, createError, createMiddleware, createResolver, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCLICtx, silgiCtx, silgiFetch, storageMount, tryUseSilgi, tryUseSilgiCLI, updateRuntimeStorage, useRuntime, useSilgi, useSilgiCLI, useSilgiStorage } from './core/index.mjs';
2
2
  import 'silgi/types';
3
+ import '@standard-schema/spec';
3
4
  import 'unstorage';
4
5
  import 'unctx';
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { SilgiError, autoImportTypes, createError, createMiddleware, createRoute, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, defineServiceSetup, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCtx, silgiFetch, storageMount, tryUseSilgi, updateRuntimeStorage, useRuntime, useSilgi, useSilgiStorage } from './core/index.mjs';
1
+ export { SilgiError, autoImportTypes, createError, createMiddleware, createResolver, createSchema, createService, createShared, createSilgi, createStorage, deepMergeObjects, getEvent, getEventContext, getUrlPrefix, handleResponse, handler, isError, middleware, replaceRuntimeValues, silgiCtx, silgiFetch, storageMount, tryUseSilgi, updateRuntimeStorage, useRuntime, useSilgi, useSilgiStorage } from './core/index.mjs';
2
2
  export { s as silgiCLICtx, t as tryUseSilgiCLI, u as useSilgiCLI } from './_chunks/silgiApp.mjs';
3
3
  import 'consola';
4
4
  import 'defu';
@@ -76,11 +76,14 @@ function removeExtension(filePath, force = false) {
76
76
  return filePath;
77
77
  }
78
78
  function getServicePath(_route) {
79
- let method = "ALL";
79
+ let method = "";
80
80
  let route = _route;
81
81
  if (route.includes(":")) {
82
82
  const [methodPart, ...routeParts] = route.split(":");
83
83
  method = methodPart.toUpperCase();
84
+ if (method === "GLOBAL") {
85
+ method = "";
86
+ }
84
87
  route = routeParts.join(":");
85
88
  }
86
89
  return {
@@ -94,7 +94,6 @@ interface SilgiRuntimeContext extends Record<string, any> {
94
94
  matchedRoute?: SilgiRoute;
95
95
  sessions?: Record<string, Session>;
96
96
  clientAddress?: string;
97
- source?: any;
98
97
  silgi: {
99
98
  runtimeConfig?: SilgiRuntimeConfig;
100
99
  };
@@ -130,13 +129,11 @@ interface SilgiEvent extends Record<string, unknown> {
130
129
  }
131
130
 
132
131
  /**
133
- * Main interface containing all route definitions.
134
- * Example:
135
- * {
136
- * "/api/blueSpace/basket/getBook": { ... }
137
- * }
132
+ * Route configuration interface.
138
133
  */
139
- interface Routers {
134
+ interface Resolvers {
135
+ }
136
+ interface RouteRules extends Record<string, unknown> {
140
137
  }
141
138
  /**
142
139
  * Extracts the prefix (first segment) from a URL, including the leading slash.
@@ -157,7 +154,7 @@ type ExtractRoute<URL extends string> = URL extends `/${string}/${string}/${infe
157
154
  * Gets all route keys from Routers as strings.
158
155
  * All keys should start with a leading slash.
159
156
  */
160
- type RouterKeys = keyof Routers & string;
157
+ type RouterKeys = keyof ServicesObject & string;
161
158
  /**
162
159
  * Extracts all prefixes (first segment) in the system, including the leading slash.
163
160
  * @example AllPrefixes // '/api' | ...
@@ -181,100 +178,6 @@ type RoutesForPrefixAndNamespace<P extends string, N extends string> = RouterKey
181
178
  * ExtractPathParamKeys<'/users/:id?'> // 'id'
182
179
  */
183
180
  type ExtractPathParamKeys<S extends string> = S extends `${string}:${infer Param}/${infer Rest}` ? Param extends `${infer Key}?` ? Key | ExtractPathParamKeys<Rest> : Param | ExtractPathParamKeys<Rest> : S extends `${string}:${infer Param}` ? Param extends `${infer Key}?` ? Key : Param : never;
184
- /**
185
- * Route configuration interface.
186
- */
187
- interface RouterConfig<T extends string = string> {
188
- route: T;
189
- setup?: any;
190
- readBeforeBody?: boolean;
191
- }
192
- type RouterConfigService<T extends string = string> = Omit<RouterConfig<T>, 'route' | 'setup'>;
193
-
194
- interface SilgiSchema {
195
- }
196
- interface MergedSilgiSchema {
197
- }
198
- type ExtractMethod<T extends string> = T extends `${infer M}:${string}` ? M : never;
199
- type ExtractPath<T extends string> = T extends `${string}:${infer P}` ? P : never;
200
- type RouteEntry<Schema> = {
201
- [K in keyof Schema & string]: {
202
- method: ExtractMethod<K>;
203
- path: ExtractPath<K>;
204
- raw: K;
205
- schema: Schema[K];
206
- };
207
- }[keyof Schema & string];
208
- /**
209
- * Creates an object type representing path parameters extracted from a URL pattern.
210
- *
211
- * @example
212
- * PathParamsObject<'/users/:id/posts/:postId'> // { id?: string | number, postId?: string | number }
213
- */
214
- type PathParamsObject<S extends string> = {
215
- [K in ExtractPathParamKeys<S>]?: string | number;
216
- };
217
- /**
218
- * Determines if a URL pattern contains any path parameters.
219
- *
220
- * @example
221
- * HasPathParams<'/users/:id'> // true
222
- * HasPathParams<'/users'> // false
223
- */
224
- type HasPathParams<S extends string> = ExtractPathParamKeys<S> extends never ? false : true;
225
- /**
226
- * Base schema definition for API method handlers.
227
- * Defines the structure of input/output data.
228
- */
229
- interface BaseMethodSchema {
230
- /** Schema for request body */
231
- input?: StandardSchemaV1;
232
- /** Schema for response body */
233
- output?: StandardSchemaV1;
234
- /** Schema for URL query parameters */
235
- queryParams?: StandardSchemaV1;
236
- /** Schema for source data (contextual information) */
237
- source?: StandardSchemaV1;
238
- }
239
- /**
240
- * Interface for adding path parameters schema to method definitions.
241
- */
242
- interface WithPathParams<PathParamsStr extends string> {
243
- /** Schema for path parameters */
244
- pathParams: StandardSchemaV1<PathParamsObject<PathParamsStr>>;
245
- }
246
- /**
247
- * Defines the schema structure for HTTP methods, conditionally including
248
- * path parameters based on the URL pattern.
249
- *
250
- * @example
251
- * // For a route with path parameters:
252
- * type UserMethodSchema = MethodSchemas<'/:id'>
253
- * // Result includes required pathParams for each method
254
- *
255
- * // For a route without path parameters:
256
- * type ListMethodSchema = MethodSchemas<''>
257
- * // Result doesn't allow pathParams property
258
- */
259
- type MethodSchemas<PathParamsStr extends string = ''> = {
260
- [K in HTTPMethod]?: HasPathParams<PathParamsStr> extends true ? BaseMethodSchema & WithPathParams<PathParamsStr> : BaseMethodSchema & {
261
- pathParams?: never;
262
- };
263
- };
264
- /**
265
- * Represents a fully resolved schema definition that maps API route paths
266
- * to their method schemas.
267
- */
268
- interface ResolvedSchema {
269
- [routePath: string]: MethodSchemas<string>;
270
- }
271
- /**
272
- * Represents a schema definition that has been fully resolved,
273
- * typically after processing and validating all schema components.
274
- */
275
- interface ResolvedSchemaDefinition {
276
- [methodAndRoutePath: string]: BaseMethodSchema;
277
- }
278
181
 
279
182
  type CustomDriverName = string & {
280
183
  _custom?: any;
@@ -313,60 +216,61 @@ interface SilgiRuntimeSharedsExtend {
313
216
  interface ExtendShared {
314
217
  }
315
218
 
219
+ interface ServicesObject {
220
+ }
316
221
  /**
317
222
  * Yardımcı tipler
318
223
  */
319
224
  type InferInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> : unknown;
320
225
  type InferOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : unknown;
321
- /**
322
- * Direct parameter type inference for combined route strings
323
- */
324
- type ServiceHandlerParameters<S, R extends keyof S> = S[R] extends {
325
- pathParams?: infer P;
326
- } ? S[R] extends {
327
- queryParams?: infer Q;
328
- } ? (P extends undefined ? object : {
329
- path: InferInput<P>;
330
- }) & (Q extends undefined ? object : {
331
- query: InferInput<Q>;
332
- }) : (P extends undefined ? object : {
333
- path: InferInput<P>;
334
- }) : S[R] extends {
335
- queryParams?: infer Q;
336
- } ? (Q extends undefined ? object : {
337
- query: InferInput<Q>;
338
- }) : object;
339
226
  /**
340
227
  * Route ve method'a göre input, output, params çıkarımı
228
+ *
229
+ * - Eğer PathParams veya QueryParams never/undefined ise parameters alanı eklenmez.
230
+ * - args her zaman zorunlu.
341
231
  */
342
- type ServiceHandlerInput<Schema extends SilgiSchema, Route extends keyof Schema, HiddenParameters extends boolean = false> = (Schema[Route] extends {
343
- input?: infer I;
344
- } ? {
345
- args: InferInput<I>;
346
- } : unknown) & (HiddenParameters extends false ? (keyof ServiceHandlerParameters<Schema, Route> extends never ? unknown : {
347
- parameters: ServiceHandlerParameters<Schema, Route>;
348
- }) : unknown);
349
- type ServiceHandlerOutput<Schema extends SilgiSchema, Route extends keyof Schema> = Schema[Route] extends {
350
- output?: infer O;
351
- } ? InferOutput<O> : unknown;
352
- type ServiceHandlerSource<Schema extends SilgiSchema, Route extends keyof Schema> = Schema[Route] extends {
353
- source?: infer S;
354
- } ? InferInput<S> : unknown;
232
+ type IsNever<T> = [T] extends [never] ? true : false;
233
+ type IsUndefined<T> = [undefined] extends [T] ? true : false;
234
+ type HasPath<T> = IsNever<T> extends true ? false : IsUndefined<T> extends true ? false : true;
235
+ type HasQuery<T> = IsNever<T> extends true ? false : IsUndefined<T> extends true ? false : true;
236
+ type ServiceHandlerInput<Input extends StandardSchemaV1 = StandardSchemaV1, PathParams extends StandardSchemaV1 | never | undefined = never, QueryParams extends StandardSchemaV1 | never | undefined = never, HiddenParameters extends boolean = false> = HiddenParameters extends true ? {
237
+ args: InferInput<Input>;
238
+ } : HasPath<PathParams> extends true ? HasQuery<QueryParams> extends true ? {
239
+ args: InferInput<Input>;
240
+ parameters: {
241
+ path: InferInput<PathParams>;
242
+ query: Partial<InferInput<QueryParams>>;
243
+ };
244
+ } : {
245
+ args: InferInput<Input>;
246
+ parameters: {
247
+ path: InferInput<PathParams>;
248
+ };
249
+ } : HasQuery<QueryParams> extends true ? {
250
+ args: InferInput<Input>;
251
+ parameters: {
252
+ query: InferInput<QueryParams>;
253
+ };
254
+ } : {
255
+ args: InferInput<Input>;
256
+ };
355
257
  /**
356
258
  * Handler fonksiyon tipi
357
259
  *
358
260
  * Resolved = false -> handler(input, shared, event, source) // all required
359
261
  * Resolved = true -> handler(input, shared?, event?, source?) // only input required
360
262
  */
361
- type ServiceHandler<Schema extends SilgiSchema, Route extends keyof Schema, Resolved extends boolean = false, HiddenParameters extends boolean = false> = Resolved extends true ? (input: ServiceHandlerInput<Schema, Route, HiddenParameters>, shared?: SilgiRuntimeShareds, event?: SilgiEvent, source?: ServiceHandlerSource<Schema, Route>) => Promise<ServiceHandlerOutput<Schema, Route>> : (input: ServiceHandlerInput<Schema, Route, HiddenParameters>, shared: SilgiRuntimeShareds, event: SilgiEvent, source: ServiceHandlerSource<Schema, Route>) => Promise<ServiceHandlerOutput<Schema, Route>>;
263
+ type ServiceHandler<Input extends StandardSchemaV1, Output extends StandardSchemaV1, PathParams extends StandardSchemaV1 | never | undefined = never, QueryParams extends StandardSchemaV1 | never | undefined = never, Resolved extends boolean = false, HiddenParameters extends boolean = false> = Resolved extends true ? (input: ServiceHandlerInput<Input, PathParams, QueryParams, HiddenParameters>, shared?: SilgiRuntimeShareds, event?: SilgiEvent) => Promise<InferOutput<Output>> : (input: ServiceHandlerInput<Input, PathParams, QueryParams, HiddenParameters>, shared: SilgiRuntimeShareds, event: SilgiEvent) => Promise<InferOutput<Output>>;
362
264
  /**
363
265
  * Servis setup tipi
364
266
  */
365
- interface ServiceSetup<Schema extends SilgiSchema = SilgiSchema, Route extends keyof Schema = keyof Schema, Resolved extends boolean = false, HiddenParameters extends boolean = false> {
366
- handler: ServiceHandler<Schema, Route, Resolved, HiddenParameters>;
367
- rules?: RouterConfigService;
267
+ interface ServiceSetup<Input extends StandardSchemaV1 = StandardSchemaV1, Output extends StandardSchemaV1 = StandardSchemaV1, PathParams extends StandardSchemaV1 | never | undefined = never, QueryParams extends StandardSchemaV1 | never | undefined = never, Resolved extends boolean = false, HiddenParameters extends boolean = false> {
268
+ handler: ServiceHandler<Input, Output, PathParams, QueryParams, Resolved, HiddenParameters>;
269
+ rules?: RouteRules & {
270
+ readBeforeBody?: boolean;
271
+ };
368
272
  modules?: Partial<SetupModuleOption>;
369
- storage?: StorageConfig<ServiceHandlerInput<Schema, Route, HiddenParameters>>;
273
+ storage?: StorageConfig<ServiceHandlerInput<Input, PathParams, QueryParams, HiddenParameters>>;
370
274
  }
371
275
  /**
372
276
  * Represents a fully resolved service definition that maps route paths
@@ -375,13 +279,19 @@ interface ServiceSetup<Schema extends SilgiSchema = SilgiSchema, Route extends k
375
279
  * This interface is designed to be compatible with the structure created
376
280
  * by the createService function.
377
281
  *
378
- * Format: "METHOD:routePath" => handler + config
282
+ * Format: "routePath" => setup + methods + input + output + queryParams
379
283
  */
380
284
  interface ResolvedServiceDefinition {
381
- [methodAndRoutePath: string]: {
382
- handler: (...args: any[]) => Promise<any>;
383
- storage?: StorageConfig<any>;
384
- } & Omit<ServiceSetup, 'handler' | 'storage'>;
285
+ [routePath: string]: {
286
+ setup: ServiceSetup<any, any, any, any, any, any>;
287
+ methods: HTTPMethod[];
288
+ input?: StandardSchemaV1;
289
+ output?: StandardSchemaV1;
290
+ queryParams?: {
291
+ path?: StandardSchemaV1;
292
+ query?: StandardSchemaV1;
293
+ };
294
+ };
385
295
  }
386
296
  /**
387
297
  * SilgiURL tipi
@@ -405,7 +315,7 @@ interface SilgiCLI {
405
315
  services: ResolvedServiceDefinition;
406
316
  middleware: SilgiRoute[];
407
317
  shareds: SilgiRuntimeShareds;
408
- routers: Record<string, RouterConfig>;
318
+ resolvers: any[];
409
319
  schemas: Record<string, any>;
410
320
  templates: SilgiTemplate[];
411
321
  hooks: Hookable<SilgiCLIHooks>;
@@ -592,8 +502,6 @@ interface SilgiModule<TOptions extends ModuleOptionsCustom = ModuleOptionsCustom
592
502
  getMeta?: () => Promise<ModuleMeta>;
593
503
  }
594
504
 
595
- interface RouteRules extends Record<string, unknown> {
596
- }
597
505
  type MiddlewareHandler<Response extends EventHandlerResponse = EventHandlerResponse> = (event: SilgiEvent, silgi: Silgi) => Response;
598
506
  /**
599
507
  * Middleware Setup tipi
@@ -607,8 +515,7 @@ interface MiddlewareSetup {
607
515
  interface ResolvedMiddlewareDefinition {
608
516
  [methodAndPath: string]: {
609
517
  setup: MiddlewareSetup;
610
- global?: string | undefined;
611
- method?: HTTPMethod | false;
518
+ methods?: HTTPMethod[];
612
519
  };
613
520
  }
614
521
 
@@ -698,15 +605,99 @@ interface SilgiOptions {
698
605
  [key: string]: any;
699
606
  }
700
607
 
701
- type StandardHTTPMethod = 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'GLOBAL';
608
+ interface SilgiSchema {
609
+ }
610
+ interface MergedSilgiSchema {
611
+ }
612
+ type ExtractMethod<T extends string> = T extends `${infer M}:${string}` ? M : never;
613
+ type ExtractPath<T extends string> = T extends `${string}:${infer P}` ? P : never;
614
+ type RouteEntry<Schema> = {
615
+ [K in keyof Schema & string]: {
616
+ method: ExtractMethod<K>;
617
+ path: ExtractPath<K>;
618
+ raw: K;
619
+ schema: Schema[K];
620
+ };
621
+ }[keyof Schema & string];
622
+ /**
623
+ * Creates an object type representing path parameters extracted from a URL pattern.
624
+ *
625
+ * @example
626
+ * PathParamsObject<'/users/:id/posts/:postId'> // { id?: string | number, postId?: string | number }
627
+ */
628
+ type PathParamsObject<S extends string> = {
629
+ [K in ExtractPathParamKeys<S>]?: string | number;
630
+ };
631
+ /**
632
+ * Determines if a URL pattern contains any path parameters.
633
+ *
634
+ * @example
635
+ * HasPathParams<'/users/:id'> // true
636
+ * HasPathParams<'/users'> // false
637
+ */
638
+ type HasPathParams<S extends string> = ExtractPathParamKeys<S> extends never ? false : true;
639
+ /**
640
+ * Base schema definition for API method handlers.
641
+ * Defines the structure of input/output data.
642
+ */
643
+ interface BaseMethodSchema {
644
+ /** Schema for request body */
645
+ input?: StandardSchemaV1;
646
+ /** Schema for response body */
647
+ output?: StandardSchemaV1;
648
+ /** Schema for URL query parameters */
649
+ queryParams?: StandardSchemaV1;
650
+ /** Schema for source data (contextual information) */
651
+ source?: StandardSchemaV1;
652
+ }
653
+ /**
654
+ * Interface for adding path parameters schema to method definitions.
655
+ */
656
+ interface WithPathParams<PathParamsStr extends string> {
657
+ /** Schema for path parameters */
658
+ pathParams: StandardSchemaV1<PathParamsObject<PathParamsStr>>;
659
+ }
660
+ /**
661
+ * Defines the schema structure for HTTP methods, conditionally including
662
+ * path parameters based on the URL pattern.
663
+ *
664
+ * @example
665
+ * // For a route with path parameters:
666
+ * type UserMethodSchema = MethodSchemas<'/:id'>
667
+ * // Result includes required pathParams for each method
668
+ *
669
+ * // For a route without path parameters:
670
+ * type ListMethodSchema = MethodSchemas<''>
671
+ * // Result doesn't allow pathParams property
672
+ */
673
+ type MethodSchemas<PathParamsStr extends string = ''> = {
674
+ [K in HTTPMethod]?: HasPathParams<PathParamsStr> extends true ? BaseMethodSchema & WithPathParams<PathParamsStr> : BaseMethodSchema & {
675
+ pathParams?: never;
676
+ };
677
+ };
678
+ /**
679
+ * Represents a fully resolved schema definition that maps API route paths
680
+ * to their method schemas.
681
+ */
682
+ interface ResolvedSchema {
683
+ [routePath: string]: MethodSchemas<string>;
684
+ }
685
+ /**
686
+ * Represents a schema definition that has been fully resolved,
687
+ * typically after processing and validating all schema components.
688
+ */
689
+ interface ResolvedSchemaDefinition {
690
+ [methodAndRoutePath: string]: BaseMethodSchema;
691
+ }
692
+
693
+ type StandardHTTPMethod = 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'ALL';
702
694
  type HTTPMethod = SilgiRuntimeMethods extends Record<string, any> ? keyof SilgiRuntimeMethods | StandardHTTPMethod : StandardHTTPMethod;
703
695
  interface MetaData extends Record<string, unknown> {
704
696
  }
705
697
  interface SilgiRoute {
706
698
  route?: string;
707
- method?: HTTPMethod;
708
- schema?: ResolvedSchemaDefinition;
709
- service?: ServiceSetup;
699
+ method?: HTTPMethod | HTTPMethod[];
700
+ service?: ResolvedServiceDefinition[string];
710
701
  middleware?: MiddlewareSetup;
711
702
  }
712
703
  interface Silgi {
@@ -716,7 +707,7 @@ interface Silgi {
716
707
  globalMiddlewares: SilgiRoute[];
717
708
  routerPrefixs: string[];
718
709
  schemas: ResolvedSchemaDefinition;
719
- routers: Record<string, RouterConfig>;
710
+ resolvers: any[];
720
711
  services: ResolvedServiceDefinition;
721
712
  shared: SilgiRuntimeShareds;
722
713
  plugins: SilgiAppPlugin[];
@@ -847,7 +838,7 @@ interface SilgiCLIHooks extends SilgiHooks {
847
838
  'before:scan.ts': (data: {
848
839
  services: string[];
849
840
  shareds: string[];
850
- routers: string[];
841
+ resolvers: string[];
851
842
  schemas: string[];
852
843
  middlewares: string[];
853
844
  addImportItem: (data: GenImport | GenImport[]) => void;
@@ -865,6 +856,10 @@ interface SilgiCLIHooks extends SilgiHooks {
865
856
  key: string;
866
857
  value: string;
867
858
  }[];
859
+ resolvers: {
860
+ key: string;
861
+ value: string;
862
+ }[];
868
863
  methods: {
869
864
  key: string;
870
865
  value: string;
@@ -1226,4 +1221,4 @@ interface LoadConfigOptions {
1226
1221
  consola?: ConsolaInstance;
1227
1222
  }
1228
1223
 
1229
- export type { AllPaths, AllPrefixes, AppConfig, Awaitable, BaseMethodSchema, BuildSilgi, CaptureError, CapturedErrorContext, CommandType, Commands, CustomRequestInit, DeepPartial, DeepRequired, DefaultHooks, DefineFrameworkOptions, DotenvOptions, EnvOptions, EventHandlerResponse, ExtendContext, ExtendShared, ExtractNamespace, ExtractPathParamKeys, ExtractPathParams, ExtractPrefix, ExtractRoute, GenImport, GenerateAppOptions, HTTPMethod, HasPathParams, HookResult, HttpMethod, LoadConfigOptions, MergeAll, MergedSilgiSchema, MetaData, MethodSchemas, MiddlewareHandler, MiddlewareSetup, ModuleDefinition, ModuleHookContext, ModuleMeta, ModuleOptionsCustom, ModuleSetupInstallResult, ModuleSetupReturn, NamespacesForPrefix, NitroBuildInfo, RequiredServiceType, ResolvedMiddlewareDefinition, ResolvedModuleMeta, ResolvedModuleOptions, ResolvedSchema, ResolvedSchemaDefinition, ResolvedServiceDefinition, ResolvedSilgiTemplate, RouteEntry, RouteRules, RouterConfig, RouterConfigService, RouterParams, Routers, RoutesForPrefixAndNamespace, ScanFile, Schema, ServiceHandler, ServiceHandlerInput, ServiceHandlerOutput, ServiceHandlerSource, ServiceSetup, SetupModuleOption, Silgi, SilgiAppPlugin, SilgiCLI, SilgiCLIConfig, SilgiCLIHooks, SilgiCLIOptions, SilgiCommands, SilgiCompatibility, SilgiCompatibilityIssue, SilgiCompatibilityIssues, SilgiConfig, SilgiEvent, SilgiFetchClient, SilgiFetchOptions, SilgiFrameworkInfo, SilgiHooks, SilgiModule, SilgiModuleInput, SilgiModuleOptions, SilgiOptions, SilgiPreset, SilgiPresetMeta, SilgiRoute, SilgiRouterTypes, SilgiRuntimeConfig, SilgiRuntimeContext, SilgiRuntimeDefaultConfig, SilgiRuntimeHooks, SilgiRuntimeMethods, SilgiRuntimeOptions, SilgiRuntimeShareds, SilgiRuntimeSharedsExtend, SilgiSchema, SilgiStorageBase, SilgiTemplate, SilgiURL, StandardHTTPMethod, StorageConfig, StorageKeyGenerator, StorageKeyParams, StorageMounts, TSReference, TrimAfterFourSlashes, WithPathParams };
1224
+ export type { AllPaths, AllPrefixes, AppConfig, Awaitable, BaseMethodSchema, BuildSilgi, CaptureError, CapturedErrorContext, CommandType, Commands, CustomRequestInit, DeepPartial, DeepRequired, DefaultHooks, DefineFrameworkOptions, DotenvOptions, EnvOptions, EventHandlerResponse, ExtendContext, ExtendShared, ExtractNamespace, ExtractPathParamKeys, ExtractPathParams, ExtractPrefix, ExtractRoute, GenImport, GenerateAppOptions, HTTPMethod, HasPathParams, HookResult, HttpMethod, LoadConfigOptions, MergeAll, MergedSilgiSchema, MetaData, MethodSchemas, MiddlewareHandler, MiddlewareSetup, ModuleDefinition, ModuleHookContext, ModuleMeta, ModuleOptionsCustom, ModuleSetupInstallResult, ModuleSetupReturn, NamespacesForPrefix, NitroBuildInfo, RequiredServiceType, ResolvedMiddlewareDefinition, ResolvedModuleMeta, ResolvedModuleOptions, ResolvedSchema, ResolvedSchemaDefinition, ResolvedServiceDefinition, ResolvedSilgiTemplate, Resolvers, RouteEntry, RouteRules, RouterParams, RoutesForPrefixAndNamespace, ScanFile, Schema, ServiceHandler, ServiceHandlerInput, ServiceSetup, ServicesObject, SetupModuleOption, Silgi, SilgiAppPlugin, SilgiCLI, SilgiCLIConfig, SilgiCLIHooks, SilgiCLIOptions, SilgiCommands, SilgiCompatibility, SilgiCompatibilityIssue, SilgiCompatibilityIssues, SilgiConfig, SilgiEvent, SilgiFetchClient, SilgiFetchOptions, SilgiFrameworkInfo, SilgiHooks, SilgiModule, SilgiModuleInput, SilgiModuleOptions, SilgiOptions, SilgiPreset, SilgiPresetMeta, SilgiRoute, SilgiRouterTypes, SilgiRuntimeConfig, SilgiRuntimeContext, SilgiRuntimeDefaultConfig, SilgiRuntimeHooks, SilgiRuntimeMethods, SilgiRuntimeOptions, SilgiRuntimeShareds, SilgiRuntimeSharedsExtend, SilgiSchema, SilgiStorageBase, SilgiTemplate, SilgiURL, StandardHTTPMethod, StorageConfig, StorageKeyGenerator, StorageKeyParams, StorageMounts, TSReference, TrimAfterFourSlashes, WithPathParams };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.40.1",
4
+ "version": "0.41.1",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {