silgi 0.50.4 → 0.51.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { analyticsTraceMap } from "../core/trace-map.mjs";
1
2
  import { createFetchHandler, wrapHandler } from "../core/handler.mjs";
2
3
  //#region src/adapters/_fetch-adapter.ts
3
4
  /**
@@ -25,10 +26,13 @@ function rewriteRequest(request, prefix) {
25
26
  */
26
27
  function createFetchAdapter(router, options, defaultPrefix) {
27
28
  const prefix = options.prefix ?? defaultPrefix;
28
- const handler = wrapHandler(createFetchHandler(router, options.context ?? (() => ({}))), router, options);
29
- return (request) => {
30
- return handler(rewriteRequest(request, prefix));
31
- };
29
+ const inner = createFetchHandler(router, options.context ?? (() => ({})));
30
+ return wrapHandler((request) => {
31
+ const rewritten = rewriteRequest(request, prefix);
32
+ const trace = analyticsTraceMap.get(request);
33
+ if (trace) analyticsTraceMap.set(rewritten, trace);
34
+ return inner(rewritten);
35
+ }, router, options, prefix);
32
36
  }
33
37
  /**
34
38
  * Create a fetch-passthrough adapter for frameworks that pass an event object
@@ -38,15 +42,23 @@ function createFetchAdapter(router, options, defaultPrefix) {
38
42
  function createEventFetchAdapter(router, options, defaultPrefix, extractRequest) {
39
43
  const prefix = options.prefix ?? defaultPrefix;
40
44
  const requestEventMap = /* @__PURE__ */ new WeakMap();
41
- const handler = wrapHandler(createFetchHandler(router, (_req) => {
45
+ const inner = createFetchHandler(router, (_req) => {
42
46
  const eventRef = requestEventMap.get(_req);
43
47
  if (options.context && eventRef) return options.context(eventRef);
44
48
  return {};
45
- }), router, options);
49
+ });
50
+ const handler = wrapHandler((request) => {
51
+ const rewritten = rewriteRequest(request, prefix);
52
+ const eventRef = requestEventMap.get(request);
53
+ if (eventRef) requestEventMap.set(rewritten, eventRef);
54
+ const trace = analyticsTraceMap.get(request);
55
+ if (trace) analyticsTraceMap.set(rewritten, trace);
56
+ return inner(rewritten);
57
+ }, router, options, prefix);
46
58
  return (event) => {
47
- const rewritten = rewriteRequest(extractRequest(event), prefix);
48
- requestEventMap.set(rewritten, event);
49
- return handler(rewritten);
59
+ const request = extractRequest(event);
60
+ requestEventMap.set(request, event);
61
+ return handler(request);
50
62
  };
51
63
  }
52
64
  //#endregion
@@ -72,7 +72,7 @@ function makeResponse(output, route, format, ctx) {
72
72
  * Returns a new handler that applies wrappers on first request (async import).
73
73
  * If no wrappers are needed, returns the original handler as-is.
74
74
  */
75
- function wrapHandler(handler, router, options) {
75
+ function wrapHandler(handler, router, options, prefix) {
76
76
  if (!options?.scalar && !options?.analytics) return handler;
77
77
  let wrapped;
78
78
  let initPromise;
@@ -81,7 +81,7 @@ function wrapHandler(handler, router, options) {
81
81
  if (options.scalar) {
82
82
  const { wrapWithScalar } = await import("../scalar.mjs");
83
83
  const scalarOpts = typeof options.scalar === "object" ? options.scalar : {};
84
- h = wrapWithScalar(h, router, scalarOpts);
84
+ h = wrapWithScalar(h, router, scalarOpts, prefix);
85
85
  }
86
86
  if (options.analytics) {
87
87
  const { wrapWithAnalytics } = await import("../plugins/analytics.mjs");
@@ -65,7 +65,7 @@ var AlertEngine = class {
65
65
  case "no_requests": return samples.length;
66
66
  case "latency_avg": return samples.reduce((sum, s) => sum + s.durationMs, 0) / samples.length;
67
67
  case "latency_p95": {
68
- const sorted = samples.map((s) => s.durationMs).sort((a, b) => a - b);
68
+ const sorted = samples.map((s) => s.durationMs).toSorted((a, b) => a - b);
69
69
  const idx = Math.ceil(sorted.length * .95) - 1;
70
70
  return sorted[Math.max(0, idx)];
71
71
  }
@@ -69,7 +69,7 @@ document.getElementById('f').onsubmit=function(e){
69
69
  e.preventDefault();
70
70
  var t=document.getElementById('t').value.trim();
71
71
  if(!t)return;
72
- var base=location.pathname.replace(/\/$/,'');
72
+ var base=location.pathname;if(base.slice(-1)==='/')base=base.slice(0,-1);
73
73
  document.cookie='silgi-auth='+encodeURIComponent(t)+';path='+base+';samesite=strict';
74
74
  fetch(base+'/stats',{headers:{'cookie':'silgi-auth='+encodeURIComponent(t)}}).then(function(){
75
75
  location.reload();
package/dist/scalar.d.mts CHANGED
@@ -43,7 +43,7 @@ interface ScalarOptions {
43
43
  */
44
44
  cdn?: 'cdn' | 'unpkg' | 'local' | (string & {});
45
45
  }
46
- declare function generateOpenAPI(router: RouterDef, options?: ScalarOptions): Record<string, unknown>;
46
+ declare function generateOpenAPI(router: RouterDef, options?: ScalarOptions, basePath?: string): Record<string, unknown>;
47
47
  declare function scalarHTML(specUrl: string, options?: ScalarOptions): string;
48
48
  //#endregion
49
49
  export { ScalarOptions, generateOpenAPI, scalarHTML };
package/dist/scalar.mjs CHANGED
@@ -24,12 +24,13 @@ function toOpenAPIPath(raw) {
24
24
  pathParams
25
25
  };
26
26
  }
27
- function generateOpenAPI(router, options = {}) {
27
+ function generateOpenAPI(router, options = {}, basePath = "") {
28
28
  const paths = {};
29
29
  const tags = /* @__PURE__ */ new Map();
30
30
  collectProcedures(router, [], (path, proc) => {
31
31
  const route = proc.route;
32
- const { httpPath, pathParams } = toOpenAPIPath(route?.path ?? "/" + path.join("/"));
32
+ const { httpPath: routePath, pathParams } = toOpenAPIPath(route?.path ?? "/" + path.join("/"));
33
+ const httpPath = basePath ? basePath.replace(/\/$/, "") + routePath : routePath;
33
34
  const rawMethod = route?.method?.toLowerCase() ?? "post";
34
35
  const methods = rawMethod === "*" ? [
35
36
  "get",
@@ -293,17 +294,20 @@ function objectSchemaToParams(schema) {
293
294
  * Wrap a fetch handler to serve Scalar API Reference at /api/reference and /api/openapi.json.
294
295
  * Scalar routes are intercepted before the handler — zero overhead for normal requests.
295
296
  */
296
- function wrapWithScalar(handler, routerDef, options = {}) {
297
- const specJson = JSON.stringify(generateOpenAPI(routerDef, options));
298
- const specHtml = scalarHTML("/api/openapi.json", options);
297
+ function wrapWithScalar(handler, routerDef, options = {}, prefix = "/api") {
298
+ const normPrefix = (prefix.startsWith("/") ? prefix : "/" + prefix).replace(/\/+$/, "");
299
+ const specJson = JSON.stringify(generateOpenAPI(routerDef, options, normPrefix));
300
+ const specHtml = scalarHTML(`${normPrefix}/openapi.json`, options);
301
+ const openapiMatch = `${normPrefix.slice(1)}/openapi.json`;
302
+ const referenceMatch = `${normPrefix.slice(1)}/reference`;
299
303
  return (request) => {
300
304
  const url = request.url;
301
305
  const pathStart = url.indexOf("/", url.indexOf("//") + 2);
302
306
  const qMark = url.indexOf("?", pathStart);
303
307
  const fullPath = qMark === -1 ? url.slice(pathStart) : url.slice(pathStart, qMark);
304
308
  const pathname = fullPath.length > 1 ? fullPath.slice(1) : "";
305
- if (pathname === "api/openapi.json") return new Response(specJson, { headers: { "content-type": "application/json" } });
306
- if (pathname === "api/reference") return new Response(specHtml, { headers: { "content-type": "text/html" } });
309
+ if (pathname === openapiMatch) return new Response(specJson, { headers: { "content-type": "application/json" } });
310
+ if (pathname === referenceMatch) return new Response(specHtml, { headers: { "content-type": "text/html" } });
307
311
  return handler(request);
308
312
  };
309
313
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "silgi",
3
- "version": "0.50.4",
3
+ "version": "0.51.2",
4
4
  "private": false,
5
5
  "description": "The fastest end-to-end type-safe RPC framework for TypeScript — compiled pipelines, single package, every runtime",
6
6
  "keywords": [
@@ -268,6 +268,7 @@
268
268
  "ocache": "^0.1.4",
269
269
  "ofetch": "2.0.0-alpha.3",
270
270
  "ohash": "^2.0.11",
271
+ "rou3": "^0.8.1",
271
272
  "srvx": "^0.11.13",
272
273
  "unstorage": "^2.0.0-alpha.7"
273
274
  },
@@ -313,6 +314,8 @@
313
314
  "peerDependencies": {
314
315
  "@pinia/colada": ">=0.16.0",
315
316
  "@scalar/api-reference": ">=1.0.0",
317
+ "ai": ">=5.0.0",
318
+ "oxc-parser": ">=0.50.0",
316
319
  "vue": ">=3.3.0"
317
320
  },
318
321
  "peerDependenciesMeta": {
@@ -322,6 +325,12 @@
322
325
  "@pinia/colada": {
323
326
  "optional": true
324
327
  },
328
+ "ai": {
329
+ "optional": true
330
+ },
331
+ "oxc-parser": {
332
+ "optional": true
333
+ },
325
334
  "vue": {
326
335
  "optional": true
327
336
  }