silgi 0.38.19 → 0.39.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.
@@ -1160,9 +1160,9 @@ async function prepareScanFile(silgi) {
1160
1160
  const hasItems = items.length > 0;
1161
1161
  if (hasItems) {
1162
1162
  return [
1163
- `export const ${name} = deepMergeObjects([`,
1164
- ...items.map((item) => ` ${item},`),
1165
- "])",
1163
+ `export const ${name} = {`,
1164
+ ...items.map((item) => ` ...${item},`),
1165
+ "}",
1166
1166
  ""
1167
1167
  ];
1168
1168
  } else {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from 'citty';
3
3
 
4
- const version = "0.38.19";
4
+ const version = "0.39.1";
5
5
  const packageJson = {
6
6
  version: version};
7
7
 
@@ -1,4 +1,4 @@
1
- import { SilgiConfig, Silgi, SilgiEvent, SilgiSchema, CustomRequestInit, SilgiRuntimeContext, AllPrefixes, NamespacesForPrefix, RoutesForPrefixAndNamespace, MethodSchemas, MergeAll, MiddlewareDefinition, HttpMethod, ServiceMethods, SilgiRuntimeShareds, RouteConfig, SilgiURL, StorageConfig, SilgiCLI, SilgiStorageBase, SilgiRuntimeConfig } from 'silgi/types';
1
+ import { SilgiConfig, Silgi, SilgiEvent, SilgiSchema, RouteEntry, CustomRequestInit, SilgiRuntimeContext, Routers, HTTPMethod, HasPathParams, BaseMethodSchema, WithPathParams, MergeAll, MiddlewareDefinition, HttpMethod, ServiceSetup, SilgiRuntimeShareds, RouteConfig, SilgiURL, StorageConfig, SilgiCLI, SilgiStorageBase, SilgiRuntimeConfig } from 'silgi/types';
2
2
  import { Storage, StorageValue } from 'unstorage';
3
3
  import { UseContext } from 'unctx';
4
4
 
@@ -7,7 +7,11 @@ declare function createSilgi(config: SilgiConfig): Promise<Silgi>;
7
7
  /**
8
8
  * Fetch API for Silgi framework
9
9
  */
10
- declare function silgiFetch<Schema extends SilgiSchema = SilgiSchema, Route extends keyof Schema = keyof Schema, Method extends keyof Schema[Route] = keyof Schema[Route], Resolved extends boolean = true, HiddenParameters extends boolean = true>(_request: Route, options?: CustomRequestInit<Schema, Route, Method, Resolved, HiddenParameters>, context?: SilgiRuntimeContext): Promise<Response | Promise<Response>>;
10
+ declare function silgiFetch<Schema extends SilgiSchema = SilgiSchema, Method extends RouteEntry<Schema>['method'] = RouteEntry<Schema>['method'], Path extends Extract<RouteEntry<Schema>, {
11
+ method: Method;
12
+ }>['path'] = Extract<RouteEntry<Schema>, {
13
+ method: Method;
14
+ }>['path'], Resolved extends boolean = true, HiddenParameters extends boolean = true>(_request: Path, options?: CustomRequestInit<Schema, Method, Path, Resolved, HiddenParameters>, context?: SilgiRuntimeContext): Promise<Response | Promise<Response>>;
11
15
  /**
12
16
  * Fetch API for Silgi framework using standard Request options
13
17
  */
@@ -112,120 +116,37 @@ declare function getEventContext<T extends SilgiRuntimeContext>(event?: SilgiEve
112
116
  * This utility function helps you define API schemas with proper typing for
113
117
  * input, output, path parameters, and query parameters.
114
118
  *
115
- * @template P - API prefix (e.g., '/api')
116
- * @template N - API namespace (e.g., '/v1')
117
- * @template R - Route path (e.g., '/users' or '/users/:id')
118
- * @template Methods - HTTP method definitions
119
+ * @template Path - API path from Routers type
120
+ * @template Method - HTTP method
119
121
  *
120
122
  * @param params - Schema configuration parameters
121
- * @param params.prefix - API prefix, such as '/api'
122
- * @param params.namespace - API namespace, such as '/v1'
123
- * @param params.path - Route path, such as '/users' or '/users/:id'
124
- * @param params.methods - HTTP method schemas
123
+ * @param params.path - Complete API path
124
+ * @param params.method - HTTP method(s) as an array (required)
125
+ * @param params.setup - Schema definition for the specified methods
125
126
  * @returns Route schema object with complete type information
126
127
  *
127
128
  * @example
128
- * // Define a user API schema with GET and POST methods
129
+ * // Define a user API schema with GET and POST methods sharing the same schema
129
130
  * const userSchema = createSchema({
130
- * prefix: '/api',
131
- * namespace: '/v1',
132
- * path: '/users',
133
- * methods: {
134
- * GET: {
135
- * output: z.object({
136
- * users: z.array(z.object({ id: z.string(), name: z.string() }))
137
- * })
138
- * },
139
- * POST: {
140
- * input: z.object({
141
- * name: z.string().min(2),
142
- * email: z.string().email()
143
- * }),
144
- * output: z.object({
145
- * id: z.string(),
146
- * created: z.boolean()
147
- * })
148
- * }
149
- * }
150
- * });
151
- *
152
- * // Define a user detail API with path parameters
153
- * const userDetailSchema = createSchema({
154
- * prefix: '/api',
155
- * namespace: '/v1',
156
- * path: '/users/:id',
157
- * methods: {
158
- * GET: {
159
- * pathParams: z.object({
160
- * id: z.string().uuid()
161
- * }),
162
- * output: z.object({
163
- * name: z.string(),
164
- * email: z.string(),
165
- * createdAt: z.date()
166
- * })
167
- * },
168
- * PUT: {
169
- * pathParams: z.object({
170
- * id: z.string().uuid()
171
- * }),
172
- * input: z.object({
173
- * name: z.string().optional(),
174
- * email: z.string().email().optional()
175
- * }),
176
- * queryParams: z.object({
177
- * version: z.number().optional()
178
- * })
179
- * },
180
- * DELETE: {
181
- * pathParams: z.object({
182
- * id: z.string().uuid()
183
- * }),
184
- * output: z.object({
185
- * success: z.boolean()
186
- * })
187
- * }
188
- * }
189
- * });
190
- *
191
- * // Example with nested route parameters
192
- * const postCommentSchema = createSchema({
193
- * prefix: '/api',
194
- * namespace: '/v1',
195
- * path: '/posts/:postId/comments/:commentId',
196
- * methods: {
197
- * GET: {
198
- * pathParams: z.object({
199
- * postId: z.string(),
200
- * commentId: z.string()
201
- * }),
202
- * output: z.object({
203
- * content: z.string(),
204
- * author: z.string()
205
- * })
206
- * },
207
- * PATCH: {
208
- * pathParams: z.object({
209
- * postId: z.string(),
210
- * commentId: z.string()
211
- * }),
212
- * input: z.object({
213
- * content: z.string().min(1).max(500)
214
- * })
215
- * }
131
+ * path: '/api/v1/users',
132
+ * method: ['GET', 'POST'],
133
+ * setup: {
134
+ * output: z.object({
135
+ * users: z.array(z.object({ id: z.string(), name: z.string() }))
136
+ * })
216
137
  * }
217
138
  * });
218
139
  */
219
- declare function createSchema<P extends AllPrefixes, N extends NamespacesForPrefix<P>, R extends RoutesForPrefixAndNamespace<P, N>, Methods extends MethodSchemas<R> = MethodSchemas<R>>(params: {
220
- /** API prefix, such as '/api' */
221
- prefix: P;
222
- /** API namespace, such as '/v1' */
223
- namespace: N;
224
- /** Route path, such as '/users' or '/users/:id' */
225
- path: R;
226
- /** HTTP method schemas */
227
- methods: Methods;
228
- }): Record<`${P}${N}${R}`, Methods>;
140
+ 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: {
141
+ /** Complete API path */
142
+ path: Path;
143
+ /** HTTP method(s) this schema applies to (required) */
144
+ method: UsedMethod;
145
+ /** Schema definition */
146
+ setup: Schema;
147
+ }): {
148
+ [K in `${UsedMethod[number]}:${string & Path}`]: Schema;
149
+ };
229
150
 
230
151
  /**
231
152
  * Merges multiple service definition objects into a single object.
@@ -236,36 +157,47 @@ declare function createSchema<P extends AllPrefixes, N extends NamespacesForPref
236
157
  */
237
158
  declare function deepMergeObjects<T extends readonly Record<string, any>[]>(schemas: [...T]): MergeAll<T>;
238
159
 
239
- declare function createService<Schema extends SilgiSchema, Path extends keyof Schema, Resolved extends boolean = false, Methods extends ServiceMethods<Schema, Path, Resolved> = ServiceMethods<Schema, Path, Resolved>>(params: {
160
+ declare function createService<Schema extends SilgiSchema, Path extends keyof Schema, Resolved extends boolean = false, HiddenParameters extends boolean = false>(params: {
240
161
  path: Path;
241
- methods: Methods;
162
+ setup: ServiceSetup<Schema, Path, Resolved, HiddenParameters>;
242
163
  }): {
243
- [R in Path]: {
244
- [M in keyof Methods]: Methods[M];
245
- };
164
+ [K in Path]: ServiceSetup<Schema, Path, Resolved, HiddenParameters>;
246
165
  };
247
166
  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}`;
248
- type MiddlewareParams<Schema extends SilgiSchema, Path extends keyof Schema & string, S extends string = WildcardVariants<Path>, Service extends MiddlewareDefinition = MiddlewareDefinition, Method extends string = HttpMethod, UsedMethod extends readonly Method[] = readonly never[], Global extends boolean = false> = Global extends true ? {
167
+ declare function createMiddleware<Global extends string, Service extends MiddlewareDefinition>(params: {
249
168
  global: Global;
250
- key: string;
251
169
  setup: Service;
252
- method?: UsedMethod;
253
- } : {
254
- global?: Global;
170
+ method?: undefined | readonly [];
171
+ }): {
172
+ [K in `GLOBAL:${Global}`]: {
173
+ setup: Service;
174
+ global: Global;
175
+ method: false;
176
+ };
177
+ };
178
+ declare function createMiddleware<Global extends string, Service extends MiddlewareDefinition, Method extends HttpMethod, UsedMethod extends readonly Method[]>(params: {
179
+ global: Global;
180
+ setup: Service;
181
+ method: UsedMethod;
182
+ }): {
183
+ [K in `${UsedMethod[number]}:${Global}`]: {
184
+ setup: Service;
185
+ global: Global;
186
+ method: UsedMethod[number];
187
+ };
188
+ };
189
+ declare function createMiddleware<S extends WildcardVariants<keyof Routers>, Service extends MiddlewareDefinition, Method extends HttpMethod, UsedMethod extends readonly Method[]>(params: {
255
190
  path: S;
256
191
  method: UsedMethod;
257
192
  setup: Service;
258
- };
259
- type MiddlewareReturn<S extends string, Service extends MiddlewareDefinition, UsedMethod extends readonly string[]> = {
260
- [K in S]: {
261
- method: boolean;
262
- global: boolean;
263
- methods: UsedMethod extends readonly [] | undefined ? object : {
264
- [M in UsedMethod[number]]: Service;
265
- };
193
+ global?: undefined;
194
+ }): {
195
+ [K in `${UsedMethod[number]}:${S}`]: {
196
+ setup: Service;
197
+ method: UsedMethod[number];
198
+ global: undefined;
266
199
  };
267
200
  };
268
- declare function createMiddleware<Schema extends SilgiSchema, Path extends keyof Schema & string, S extends string = WildcardVariants<Path>, Service extends MiddlewareDefinition = MiddlewareDefinition, Method extends string = HttpMethod, UsedMethod extends readonly Method[] = readonly never[], Global extends boolean = false>(params: MiddlewareParams<Schema, Path, S, Service, Method, UsedMethod, Global>): MiddlewareReturn<S, Service, UsedMethod>;
269
201
 
270
202
  declare function createShared(shared: Partial<SilgiRuntimeShareds>): SilgiRuntimeShareds;
271
203
 
@@ -296,7 +296,14 @@ async function createSilgi(config) {
296
296
  if (!silgi.router) {
297
297
  silgi.router = createRouter();
298
298
  }
299
- for (const route in silgi.services) {
299
+ for (const routeKey in silgi.services) {
300
+ let method = "ALL";
301
+ let route = routeKey;
302
+ if (routeKey.includes(":")) {
303
+ const [methodPart, ...routeParts2] = routeKey.split(":");
304
+ method = methodPart.toUpperCase();
305
+ route = routeParts2.join(":");
306
+ }
300
307
  const routeParts = route.split("/").filter(Boolean);
301
308
  if (routeParts.length > 0) {
302
309
  const prefix = `/${routeParts[0]}`;
@@ -304,64 +311,46 @@ async function createSilgi(config) {
304
311
  silgi.routerPrefixs.push(prefix);
305
312
  }
306
313
  }
307
- const methods = silgi.services[route];
308
- for (const method in methods) {
309
- const methodObject = methods[method];
310
- if (methodObject) {
311
- const _method = (method || "").toUpperCase();
312
- const schemaWrapper = silgi.schemas?.[route]?.[method];
313
- if (!schemaWrapper) {
314
- silgi.logger.warn(`Schema not found for ${route}`);
315
- continue;
316
- }
317
- addRoute(silgi.router, _method, route, {
318
- method: _method,
319
- route,
320
- setup: methodObject,
321
- schema: schemaWrapper
322
- });
314
+ const methodObject = silgi.services[routeKey];
315
+ if (methodObject) {
316
+ const schemaWrapper = silgi.schemas?.[routeKey];
317
+ if (!schemaWrapper) {
318
+ silgi.logger.warn(`Schema not found for ${routeKey}`);
319
+ continue;
323
320
  }
321
+ addRoute(silgi.router, method, route, {
322
+ method,
323
+ route,
324
+ service: methodObject,
325
+ schema: schemaWrapper
326
+ });
324
327
  }
325
328
  }
326
329
  if (!silgi._middlewareRouter) {
327
330
  silgi._middlewareRouter = createRouter();
328
331
  }
329
- for (const route in silgi.middlewares) {
330
- const routeObject = silgi.middlewares[route];
332
+ for (const routeKey in silgi.middlewares) {
333
+ const routeObject = silgi.middlewares[routeKey];
331
334
  const global = routeObject.global ?? false;
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(":");
341
+ }
332
342
  if (global) {
333
- if ("methods" in routeObject && routeObject.methods && Object.keys(routeObject.methods).length > 0) {
334
- for (const methodKey in routeObject.methods) {
335
- const _method = (methodKey || "").toUpperCase();
336
- const object = routeObject.methods[methodKey];
337
- if (!object)
338
- continue;
339
- silgi.globalMiddlewares.push({
340
- setup: object.setup,
341
- method: _method,
342
- route
343
- });
344
- }
345
- } else {
346
- silgi.globalMiddlewares.push({
347
- setup: routeObject.setup,
348
- route
349
- });
350
- }
343
+ silgi.globalMiddlewares.push({
344
+ middleware: routeObject.setup,
345
+ method,
346
+ route
347
+ });
351
348
  } else {
352
- if ("methods" in routeObject && routeObject.methods) {
353
- for (const method in routeObject.methods) {
354
- const _method = (method || "").toUpperCase();
355
- const routeObjectMethod = routeObject.methods[method];
356
- if (!routeObjectMethod)
357
- continue;
358
- addRoute(silgi._middlewareRouter, _method, route, {
359
- setup: routeObjectMethod.setup,
360
- method: _method,
361
- route
362
- });
363
- }
364
- }
349
+ addRoute(silgi._middlewareRouter, method, route, {
350
+ middleware: routeObject.setup,
351
+ method,
352
+ route
353
+ });
365
354
  }
366
355
  }
367
356
  silgi.hooks.addHooks(silgi.options.hooks);
@@ -604,7 +593,7 @@ function getUrlPrefix(path, method) {
604
593
  async function orchestrate(route, event, _input) {
605
594
  const silgiCtx = useSilgi();
606
595
  const silgiURL = getUrlPrefix(route.route || event.req.url, route.method);
607
- const input = _input || (route.setup.rules?.readBeforeBody === false ? {} : await parseRequestInput(event.req));
596
+ const input = _input || (route.service?.rules?.readBeforeBody === false ? {} : await parseRequestInput(event.req));
608
597
  const hookContext = { earlyReturnValue: false };
609
598
  const routerParams = _input ? input.path : getRouterParams(event);
610
599
  const queryParams = _input ? input.query : getQuery(event);
@@ -622,7 +611,13 @@ async function orchestrate(route, event, _input) {
622
611
  }
623
612
  };
624
613
  try {
625
- const setup = route.setup;
614
+ const setup = route.service;
615
+ if (!setup) {
616
+ throw createError({
617
+ statusCode: 404,
618
+ statusMessage: "Service not found"
619
+ });
620
+ }
626
621
  const cachePromise = cacheExecute(input, route, silgiURL, event);
627
622
  const beforeHookPromise = silgiCtx.callHook("fetch:before", {
628
623
  url: silgiURL,
@@ -702,8 +697,8 @@ async function orchestrate(route, event, _input) {
702
697
  }
703
698
  }
704
699
  async function cacheExecute(input, route, silgiURL, event) {
705
- const setup = route.setup;
706
- if (!setup.storage)
700
+ const setup = route.service;
701
+ if (!setup || !setup.storage)
707
702
  return;
708
703
  const cacheKey = setup.storage ? await generateStorageKey({
709
704
  url: silgiURL,
@@ -934,11 +929,11 @@ async function middleware(event, url) {
934
929
  if (_previous !== void 0 && _previous !== kNotFound) {
935
930
  return _previous;
936
931
  }
937
- if (m.method && m.method !== event.req.method) {
932
+ if (m.method && m.method !== event.req.method || !m.middleware) {
938
933
  return;
939
934
  }
940
935
  try {
941
- await silgiContext.callHook("middleware:global:on", event, m.setup);
936
+ await silgiContext.callHook("middleware:global:on", event, m.middleware);
942
937
  } catch (error) {
943
938
  if (isError(error)) {
944
939
  throw error;
@@ -950,7 +945,7 @@ async function middleware(event, url) {
950
945
  cause: error
951
946
  });
952
947
  }
953
- return m.setup.handler(event, silgiContext);
948
+ return m.middleware.handler(event, silgiContext);
954
949
  });
955
950
  }
956
951
  }
@@ -964,13 +959,13 @@ async function middleware(event, url) {
964
959
  if (_previous !== void 0 && _previous !== kNotFound) {
965
960
  return _previous;
966
961
  }
967
- if (match.data.method && match.data.method !== event.req.method) {
962
+ if (match.data.method && match.data.method !== event.req.method || !match.data.middleware) {
968
963
  return;
969
964
  }
970
965
  event.context.params = match.params;
971
966
  event.context.matchedRoute = match.data;
972
967
  try {
973
- await silgiContext.callHook("middleware:router:on", event, match.data.setup);
968
+ await silgiContext.callHook("middleware:router:on", event, match.data.middleware);
974
969
  } catch (error) {
975
970
  if (isError(error)) {
976
971
  throw error;
@@ -982,7 +977,7 @@ async function middleware(event, url) {
982
977
  cause: error
983
978
  });
984
979
  }
985
- return match.data.setup.handler(event, silgiContext);
980
+ return match.data.middleware.handler(event, silgiContext);
986
981
  });
987
982
  }
988
983
  }
@@ -1032,11 +1027,13 @@ function getEventContext(event) {
1032
1027
  }
1033
1028
 
1034
1029
  function createSchema(params) {
1035
- const { namespace, prefix, path, methods } = params;
1036
- const routeWithPrefix = `${prefix}${namespace}${path}`;
1037
- return {
1038
- [routeWithPrefix]: methods
1039
- };
1030
+ const { path, method, setup } = params;
1031
+ const result = {};
1032
+ for (let i = 0; i < method.length; i++) {
1033
+ const methodName = method[i];
1034
+ result[`${String(methodName)}:${path}`] = setup;
1035
+ }
1036
+ return result;
1040
1037
  }
1041
1038
 
1042
1039
  function deepMerge(target, source) {
@@ -1063,54 +1060,42 @@ function deepMergeObjects(schemas) {
1063
1060
  }
1064
1061
 
1065
1062
  function createService(params) {
1066
- const { path, methods } = params;
1063
+ const { path, setup } = params;
1067
1064
  return {
1068
- [path]: methods
1065
+ [path]: setup
1069
1066
  };
1070
1067
  }
1071
1068
  function createMiddleware(params) {
1072
- if (params.key) {
1069
+ if (params.global) {
1070
+ const globalKey = params.global;
1073
1071
  if (!params.method || params.method.length === 0) {
1074
1072
  return {
1075
- [params.key]: {
1076
- method: false,
1077
- global: params.global,
1078
- methods: {},
1079
- setup: params.setup
1073
+ [`GLOBAL:${globalKey}`]: {
1074
+ setup: params.setup,
1075
+ global: globalKey,
1076
+ method: false
1080
1077
  }
1081
1078
  };
1082
1079
  }
1083
- const methods2 = {};
1080
+ const result2 = {};
1084
1081
  for (const m of params.method) {
1085
- methods2[m] = {
1082
+ result2[`${m}:${globalKey}`] = {
1086
1083
  setup: params.setup,
1087
- global: true,
1084
+ global: globalKey,
1088
1085
  method: m
1089
1086
  };
1090
1087
  }
1091
- return {
1092
- [params.key]: {
1093
- global: params.global,
1094
- method: true,
1095
- methods: methods2
1096
- }
1097
- };
1088
+ return result2;
1098
1089
  }
1099
- const methods = {};
1090
+ const result = {};
1100
1091
  for (const m of params.method) {
1101
- methods[m] = {
1092
+ result[`${m}:${params.path}`] = {
1102
1093
  setup: params.setup,
1103
1094
  method: m,
1104
- global: false
1095
+ global: void 0
1105
1096
  };
1106
1097
  }
1107
- return {
1108
- [params.path]: {
1109
- method: true,
1110
- global: false,
1111
- methods
1112
- }
1113
- };
1098
+ return result;
1114
1099
  }
1115
1100
 
1116
1101
  function createShared(shared) {
@@ -195,6 +195,16 @@ interface SilgiSchema {
195
195
  }
196
196
  interface MergedSilgiSchema {
197
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];
198
208
  /**
199
209
  * Creates an object type representing path parameters extracted from a URL pattern.
200
210
  *
@@ -263,9 +273,7 @@ interface ResolvedSchema {
263
273
  * typically after processing and validating all schema components.
264
274
  */
265
275
  interface ResolvedSchemaDefinition {
266
- [key: string]: {
267
- [method: string]: BaseMethodSchema;
268
- };
276
+ [methodAndRoutePath: string]: BaseMethodSchema;
269
277
  }
270
278
 
271
279
  type CustomDriverName = string & {
@@ -305,17 +313,17 @@ interface SilgiRuntimeSharedsExtend {
305
313
  interface ExtendShared {
306
314
  }
307
315
 
308
- type ServiceMethods<Schema extends SilgiSchema, Path extends keyof Schema, Resolved extends boolean = false, HiddenParameters extends boolean = false> = {
309
- [M in keyof Schema[Path]]?: ServiceSetup<Schema, Path, M, Resolved, HiddenParameters>;
310
- };
311
316
  /**
312
317
  * Yardımcı tipler
313
318
  */
314
319
  type InferInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> : unknown;
315
320
  type InferOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : unknown;
316
- type ServiceHandlerParameters<S, R extends keyof S, M extends keyof S[R]> = S[R][M] extends {
321
+ /**
322
+ * Direct parameter type inference for combined route strings
323
+ */
324
+ type ServiceHandlerParameters<S, R extends keyof S> = S[R] extends {
317
325
  pathParams?: infer P;
318
- } ? S[R][M] extends {
326
+ } ? S[R] extends {
319
327
  queryParams?: infer Q;
320
328
  } ? (P extends undefined ? object : {
321
329
  path: InferInput<P>;
@@ -323,7 +331,7 @@ type ServiceHandlerParameters<S, R extends keyof S, M extends keyof S[R]> = S[R]
323
331
  query: InferInput<Q>;
324
332
  }) : (P extends undefined ? object : {
325
333
  path: InferInput<P>;
326
- }) : S[R][M] extends {
334
+ }) : S[R] extends {
327
335
  queryParams?: infer Q;
328
336
  } ? (Q extends undefined ? object : {
329
337
  query: InferInput<Q>;
@@ -331,17 +339,17 @@ type ServiceHandlerParameters<S, R extends keyof S, M extends keyof S[R]> = S[R]
331
339
  /**
332
340
  * Route ve method'a göre input, output, params çıkarımı
333
341
  */
334
- type ServiceHandlerInput<Schema extends SilgiSchema, Route extends keyof Schema, Method extends keyof Schema[Route], HiddenParameters extends boolean = false> = (Schema[Route][Method] extends {
342
+ type ServiceHandlerInput<Schema extends SilgiSchema, Route extends keyof Schema, HiddenParameters extends boolean = false> = (Schema[Route] extends {
335
343
  input?: infer I;
336
344
  } ? {
337
345
  args: InferInput<I>;
338
- } : unknown) & (HiddenParameters extends false ? (keyof ServiceHandlerParameters<Schema, Route, Method> extends never ? unknown : {
339
- parameters: ServiceHandlerParameters<Schema, Route, Method>;
346
+ } : unknown) & (HiddenParameters extends false ? (keyof ServiceHandlerParameters<Schema, Route> extends never ? unknown : {
347
+ parameters: ServiceHandlerParameters<Schema, Route>;
340
348
  }) : unknown);
341
- type ServiceHandlerOutput<Schema extends SilgiSchema, Route extends keyof Schema, Method extends keyof Schema[Route]> = Schema[Route][Method] extends {
349
+ type ServiceHandlerOutput<Schema extends SilgiSchema, Route extends keyof Schema> = Schema[Route] extends {
342
350
  output?: infer O;
343
351
  } ? InferOutput<O> : unknown;
344
- type ServiceHandlerSource<Schema extends SilgiSchema, Route extends keyof Schema, Method extends keyof Schema[Route]> = Schema[Route][Method] extends {
352
+ type ServiceHandlerSource<Schema extends SilgiSchema, Route extends keyof Schema> = Schema[Route] extends {
345
353
  source?: infer S;
346
354
  } ? InferInput<S> : unknown;
347
355
  /**
@@ -350,29 +358,29 @@ type ServiceHandlerSource<Schema extends SilgiSchema, Route extends keyof Schema
350
358
  * Resolved = false -> handler(input, shared, event, source) // all required
351
359
  * Resolved = true -> handler(input, shared?, event?, source?) // only input required
352
360
  */
353
- type ServiceHandler<Schema extends SilgiSchema, Route extends keyof Schema, Method extends keyof Schema[Route], Resolved extends boolean = false, HiddenParameters extends boolean = false> = Resolved extends true ? (input: ServiceHandlerInput<Schema, Route, Method, HiddenParameters>, shared?: SilgiRuntimeShareds, event?: SilgiEvent, source?: ServiceHandlerSource<Schema, Route, Method>) => Promise<ServiceHandlerOutput<Schema, Route, Method>> : (input: ServiceHandlerInput<Schema, Route, Method, HiddenParameters>, shared: SilgiRuntimeShareds, event: SilgiEvent, source: ServiceHandlerSource<Schema, Route, Method>) => Promise<ServiceHandlerOutput<Schema, Route, Method>>;
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>>;
354
362
  /**
355
363
  * Servis setup tipi
356
364
  */
357
- interface ServiceSetup<Schema extends SilgiSchema = SilgiSchema, Route extends keyof Schema = keyof Schema, Method extends keyof Schema[Route] = keyof Schema[Route], Resolved extends boolean = false, HiddenParameters extends boolean = false> {
358
- handler: ServiceHandler<Schema, Route, Method, Resolved, HiddenParameters>;
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>;
359
367
  rules?: RouteConfigService;
360
368
  modules?: Partial<SetupModuleOption>;
361
- storage?: StorageConfig<ServiceHandlerInput<Schema, Route, Method, HiddenParameters>>;
369
+ storage?: StorageConfig<ServiceHandlerInput<Schema, Route, HiddenParameters>>;
362
370
  }
363
371
  /**
364
372
  * Represents a fully resolved service definition that maps route paths
365
- * to their method handlers and configurations.
373
+ * to their handler and configurations.
366
374
  *
367
375
  * This interface is designed to be compatible with the structure created
368
376
  * by the createService function.
377
+ *
378
+ * Format: "METHOD:routePath" => handler + config
369
379
  */
370
380
  interface ResolvedServiceDefinition {
371
- [routePath: string]: {
372
- [method: string]: {
373
- handler: (...args: any[]) => Promise<any>;
374
- } & Omit<ServiceSetup, 'handler'>;
375
- };
381
+ [methodAndRoutePath: string]: {
382
+ handler: (...args: any[]) => Promise<any>;
383
+ } & Omit<ServiceSetup, 'handler'>;
376
384
  }
377
385
  /**
378
386
  * SilgiURL tipi
@@ -400,19 +408,10 @@ interface MiddlewareSetup {
400
408
  }
401
409
  type MiddlewareDefinition = MiddlewareSetup;
402
410
  interface ResolvedMiddlewareDefinition {
403
- [routePath: string]: {
404
- global: true;
405
- method: false;
411
+ [methodAndPath: string]: {
406
412
  setup: MiddlewareSetup;
407
- } | {
408
- global: false;
409
- method: true;
410
- methods: {
411
- [method: string]: {
412
- setup: MiddlewareSetup;
413
- method: string;
414
- };
415
- };
413
+ global?: string | undefined;
414
+ method: HTTPMethod | false;
416
415
  };
417
416
  }
418
417
 
@@ -703,21 +702,17 @@ type HTTPMethod = SilgiRuntimeMethods extends Record<string, any> ? keyof SilgiR
703
702
  interface MetaData extends Record<string, unknown> {
704
703
  }
705
704
  interface SilgiRoute {
706
- route: string;
707
- method?: HTTPMethod;
708
- schema?: ResolvedSchemaDefinition;
709
- setup: ServiceSetup;
710
- }
711
- interface MiddlewareRoute {
712
705
  route?: string;
713
706
  method?: HTTPMethod;
714
- setup: MiddlewareSetup;
707
+ schema?: ResolvedSchemaDefinition;
708
+ service?: ServiceSetup;
709
+ middleware?: MiddlewareSetup;
715
710
  }
716
711
  interface Silgi {
717
712
  router: RouterContext<SilgiRoute>;
718
- _middlewareRouter: RouterContext<MiddlewareRoute>;
713
+ _middlewareRouter: RouterContext<SilgiRoute>;
719
714
  middlewares: ResolvedMiddlewareDefinition;
720
- globalMiddlewares: MiddlewareRoute[];
715
+ globalMiddlewares: SilgiRoute[];
721
716
  routerPrefixs: string[];
722
717
  schemas: ResolvedSchemaDefinition;
723
718
  services: ResolvedServiceDefinition;
@@ -749,20 +744,24 @@ interface BuildSilgi {
749
744
  modules?: Partial<SilgiRuntimeOptions>;
750
745
  options?: Partial<SilgiOptions>;
751
746
  }
752
- type CustomRequestInit<Schema extends SilgiSchema = SilgiSchema, Route extends keyof Schema = keyof Schema, Method extends keyof Schema[Route] = keyof Schema[Route], _Resolved extends boolean = true, _HiddenParameters extends boolean = true> = Omit<RequestInit, 'body' | 'headers' | 'method'> & {
747
+ type CustomRequestInit<Schema extends SilgiSchema = SilgiSchema, Method extends RouteEntry<Schema>['method'] = RouteEntry<Schema>['method'], Path extends Extract<RouteEntry<Schema>, {
748
+ method: Method;
749
+ }>['path'] = Extract<RouteEntry<Schema>, {
753
750
  method: Method;
754
- body?: Route extends keyof Schema ? Method extends keyof Schema[Route] ? Schema[Route][Method] extends {
751
+ }>['path'], _Resolved extends boolean = true, _HiddenParameters extends boolean = true> = Omit<RequestInit, 'body' | 'headers' | 'method'> & {
752
+ method: Method;
753
+ body?: `${Method}:${Path}` extends keyof Schema ? Schema[`${Method}:${Path}`] extends {
755
754
  input?: infer I;
756
- } ? I extends StandardSchemaV1 ? StandardSchemaV1.InferInput<I> : unknown : unknown : unknown : unknown;
757
- headers?: Route extends keyof Schema ? Method extends keyof Schema[Route] ? Schema[Route][Method] extends {
755
+ } ? I extends StandardSchemaV1 ? StandardSchemaV1.InferInput<I> : unknown : unknown : unknown;
756
+ headers?: `${Method}:${Path}` extends keyof Schema ? Schema[`${Method}:${Path}`] extends {
758
757
  headers?: infer H;
759
- } ? H extends StandardSchemaV1 ? StandardSchemaV1.InferInput<H> : unknown : unknown : unknown : unknown;
760
- } & (Route extends keyof Schema ? Method extends keyof Schema[Route] ? Schema[Route][Method] extends {
758
+ } ? H extends StandardSchemaV1 ? StandardSchemaV1.InferInput<H> : unknown : unknown : unknown;
759
+ } & (`${Method}:${Path}` extends keyof Schema ? Schema[`${Method}:${Path}`] extends {
761
760
  pathParams?: infer P;
762
761
  } ? P extends StandardSchemaV1 ? {
763
- pathParams: StandardSchemaV1.InferInput<P>;
764
- } : {
765
- pathParams?: unknown;
762
+ pathParams: {
763
+ [K in keyof StandardSchemaV1.InferInput<P>]: StandardSchemaV1.InferInput<P>[K] extends string ? string | number : StandardSchemaV1.InferInput<P>[K];
764
+ };
766
765
  } : {
767
766
  pathParams?: unknown;
768
767
  } : {
@@ -1226,4 +1225,4 @@ interface LoadConfigOptions {
1226
1225
  consola?: ConsolaInstance;
1227
1226
  }
1228
1227
 
1229
- export type { AllPaths, AllPrefixes, AppConfig, Awaitable, BuildSilgi, CaptureError, CapturedErrorContext, CommandType, Commands, CustomRequestInit, DeepPartial, DeepRequired, DefaultHooks, DefineFrameworkOptions, DotenvOptions, EnvOptions, EventHandlerResponse, ExtendContext, ExtendShared, ExtractNamespace, ExtractPathParamKeys, ExtractPathParams, ExtractPrefix, ExtractRoute, GenImport, GenerateAppOptions, HTTPMethod, HookResult, HttpMethod, LoadConfigOptions, MergeAll, MergedSilgiSchema, MetaData, MethodSchemas, MiddlewareDefinition, MiddlewareHandler, MiddlewareRoute, MiddlewareSetup, ModuleDefinition, ModuleHookContext, ModuleMeta, ModuleOptionsCustom, ModuleSetupInstallResult, ModuleSetupReturn, NamespacesForPrefix, NitroBuildInfo, RequiredServiceType, ResolvedMiddlewareDefinition, ResolvedModuleMeta, ResolvedModuleOptions, ResolvedSchema, ResolvedSchemaDefinition, ResolvedServiceDefinition, ResolvedSilgiTemplate, RouteConfig, RouteConfigService, RouteRules, RouterParams, Routers, RoutesForPrefixAndNamespace, ScanFile, Schema, ServiceHandler, ServiceHandlerInput, ServiceHandlerOutput, ServiceHandlerSource, ServiceMethods, 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 };
1228
+ 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, MiddlewareDefinition, MiddlewareHandler, MiddlewareSetup, ModuleDefinition, ModuleHookContext, ModuleMeta, ModuleOptionsCustom, ModuleSetupInstallResult, ModuleSetupReturn, NamespacesForPrefix, NitroBuildInfo, RequiredServiceType, ResolvedMiddlewareDefinition, ResolvedModuleMeta, ResolvedModuleOptions, ResolvedSchema, ResolvedSchemaDefinition, ResolvedServiceDefinition, ResolvedSilgiTemplate, RouteConfig, RouteConfigService, RouteEntry, RouteRules, 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 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.38.19",
4
+ "version": "0.39.1",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {