weifuwu 0.24.0 → 0.24.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.
- package/README.md +970 -756
- package/cli/template/app.ts +5 -1
- package/cli/template/index.ts +4 -1
- package/cli/template/locales/en.json +6 -1
- package/cli/template/locales/zh-CN.json +6 -1
- package/cli/template/locales/zh-TW.json +6 -1
- package/cli/template/locales/zh.json +6 -1
- package/cli/template/ui/app/globals.css +1 -1
- package/cli/template/ui/app/page.tsx +55 -16
- package/cli.ts +148 -104
- package/dist/agent/rest.d.ts +1 -1
- package/dist/agent/run.d.ts +2 -2
- package/dist/agent/types.d.ts +2 -1
- package/dist/ai/workflow.d.ts +1 -1
- package/dist/ai-sdk.d.ts +1 -1
- package/dist/analytics.d.ts +2 -2
- package/dist/cache.d.ts +4 -4
- package/dist/cli.js +135 -97
- package/dist/cookie.d.ts +24 -0
- package/dist/cors.d.ts +2 -2
- package/dist/deploy/types.d.ts +2 -2
- package/dist/fts.d.ts +5 -5
- package/dist/helmet.d.ts +2 -2
- package/dist/hub.d.ts +2 -1
- package/dist/iii/index.d.ts +1 -1
- package/dist/iii/register-worker.d.ts +1 -1
- package/dist/iii/types.d.ts +4 -4
- package/dist/index.d.ts +5 -5
- package/dist/index.js +905 -442
- package/dist/kb/types.d.ts +8 -0
- package/dist/live.d.ts +2 -3
- package/dist/logdb/rest.d.ts +1 -1
- package/dist/logdb/types.d.ts +2 -1
- package/dist/mailer.d.ts +3 -2
- package/dist/messager/agent.d.ts +2 -2
- package/dist/messager/rest.d.ts +3 -3
- package/dist/messager/types.d.ts +2 -1
- package/dist/messager/ws.d.ts +3 -3
- package/dist/opencode/index.d.ts +1 -1
- package/dist/opencode/permissions.d.ts +1 -1
- package/dist/opencode/run.d.ts +1 -1
- package/dist/opencode/session.d.ts +9 -9
- package/dist/opencode/tools/web.d.ts +1 -1
- package/dist/opencode/types.d.ts +2 -1
- package/dist/opencode/ws.d.ts +1 -2
- package/dist/permissions.d.ts +4 -4
- package/dist/postgres/module.d.ts +5 -4
- package/dist/postgres/schema/index.d.ts +1 -1
- package/dist/postgres/schema/table.d.ts +22 -20
- package/dist/postgres/types.d.ts +6 -6
- package/dist/queue/types.d.ts +3 -3
- package/dist/rate-limit.d.ts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +141 -96
- package/dist/redis/types.d.ts +2 -2
- package/dist/router.d.ts +10 -10
- package/dist/seo.d.ts +2 -2
- package/dist/serve.d.ts +1 -1
- package/dist/session.d.ts +8 -5
- package/dist/tailwind.d.ts +9 -0
- package/dist/tenant/graphql.d.ts +2 -2
- package/dist/tenant/index.d.ts +1 -1
- package/dist/tenant/rest.d.ts +2 -2
- package/dist/tenant/types.d.ts +3 -3
- package/dist/test-utils.d.ts +3 -3
- package/dist/types.d.ts +8 -0
- package/dist/upload.d.ts +4 -2
- package/dist/user/index.d.ts +1 -1
- package/dist/user/oauth-login.d.ts +2 -2
- package/dist/user/types.d.ts +2 -2
- package/dist/vendor.d.ts +4 -0
- package/opencode/ui/app/globals.css +1 -1
- package/opencode/ui/app/layout.tsx +2 -3
- package/opencode/ui/app/page.tsx +302 -73
- package/package.json +33 -10
- package/cli/template/.weifuwu/ssr/2e3a7e60.js +0 -112
package/dist/react.js
CHANGED
|
@@ -95,42 +95,45 @@ function useAction(url, options) {
|
|
|
95
95
|
const [error, setError] = useState2(null);
|
|
96
96
|
const [pending, setPending] = useState2(false);
|
|
97
97
|
const mountedRef = useRef2(true);
|
|
98
|
-
const submit = useCallback2(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
98
|
+
const submit = useCallback2(
|
|
99
|
+
async (body) => {
|
|
100
|
+
setPending(true);
|
|
101
|
+
setError(null);
|
|
102
|
+
try {
|
|
103
|
+
const csrfToken = getCsrfToken();
|
|
104
|
+
const hdrs = { ...headers };
|
|
105
|
+
if (csrfToken) hdrs["x-csrf-token"] = csrfToken;
|
|
106
|
+
if (body && typeof body === "object" && !(body instanceof FormData)) {
|
|
107
|
+
hdrs["content-type"] = "application/json";
|
|
108
|
+
}
|
|
109
|
+
const res = await fetch(url, {
|
|
110
|
+
method,
|
|
111
|
+
headers: hdrs,
|
|
112
|
+
body: body instanceof FormData ? body : body !== void 0 ? JSON.stringify(body) : void 0
|
|
113
|
+
});
|
|
114
|
+
if (!res.ok) {
|
|
115
|
+
const text = await res.text();
|
|
116
|
+
throw new Error(text || `HTTP ${res.status}`);
|
|
117
|
+
}
|
|
118
|
+
const result = res.status === 204 ? void 0 : await res.json();
|
|
119
|
+
if (mountedRef.current) {
|
|
120
|
+
setData(result);
|
|
121
|
+
onSuccess?.(result);
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
} catch (err) {
|
|
125
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
126
|
+
if (mountedRef.current) {
|
|
127
|
+
setError(e);
|
|
128
|
+
onError?.(e);
|
|
129
|
+
}
|
|
130
|
+
return void 0;
|
|
131
|
+
} finally {
|
|
132
|
+
if (mountedRef.current) setPending(false);
|
|
128
133
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
}, [url, method, headers, onSuccess, onError]);
|
|
134
|
+
},
|
|
135
|
+
[url, method, headers, onSuccess, onError]
|
|
136
|
+
);
|
|
134
137
|
const reset = useCallback2(() => {
|
|
135
138
|
setData(null);
|
|
136
139
|
setError(null);
|
|
@@ -155,7 +158,15 @@ async function runInterceptors(url) {
|
|
|
155
158
|
|
|
156
159
|
// tsx-context.ts
|
|
157
160
|
import { useSyncExternalStore, createContext } from "react";
|
|
158
|
-
var DEFAULT_CTX = {
|
|
161
|
+
var DEFAULT_CTX = {
|
|
162
|
+
params: {},
|
|
163
|
+
query: {},
|
|
164
|
+
parsed: {},
|
|
165
|
+
loaderData: {},
|
|
166
|
+
env: {},
|
|
167
|
+
user: {},
|
|
168
|
+
flash: {}
|
|
169
|
+
};
|
|
159
170
|
var KEY = "__WEIFUWU_CTX_STORE";
|
|
160
171
|
function getStore() {
|
|
161
172
|
if (typeof globalThis !== "undefined" && globalThis[KEY]) {
|
|
@@ -163,12 +174,22 @@ function getStore() {
|
|
|
163
174
|
}
|
|
164
175
|
const s = {
|
|
165
176
|
_ctx: DEFAULT_CTX,
|
|
166
|
-
_snapshot: {
|
|
177
|
+
_snapshot: {
|
|
178
|
+
params: DEFAULT_CTX.params,
|
|
179
|
+
query: DEFAULT_CTX.query,
|
|
180
|
+
user: DEFAULT_CTX.user,
|
|
181
|
+
parsed: DEFAULT_CTX.parsed,
|
|
182
|
+
theme: DEFAULT_CTX.theme,
|
|
183
|
+
i18n: DEFAULT_CTX.i18n,
|
|
184
|
+
loaderData: DEFAULT_CTX.loaderData,
|
|
185
|
+
env: DEFAULT_CTX.env
|
|
186
|
+
},
|
|
167
187
|
_listeners: /* @__PURE__ */ new Set(),
|
|
168
188
|
_rebuilders: [],
|
|
169
189
|
_alsGetStore: null
|
|
170
190
|
};
|
|
171
191
|
if (typeof globalThis !== "undefined") {
|
|
192
|
+
;
|
|
172
193
|
globalThis[KEY] = s;
|
|
173
194
|
}
|
|
174
195
|
return s;
|
|
@@ -192,7 +213,16 @@ function setCtx(value) {
|
|
|
192
213
|
}
|
|
193
214
|
}
|
|
194
215
|
store._ctx = { ...store._ctx, ...value };
|
|
195
|
-
store._snapshot = {
|
|
216
|
+
store._snapshot = {
|
|
217
|
+
params: store._ctx.params,
|
|
218
|
+
query: store._ctx.query,
|
|
219
|
+
user: store._ctx.user,
|
|
220
|
+
parsed: store._ctx.parsed,
|
|
221
|
+
theme: store._ctx.theme,
|
|
222
|
+
i18n: store._ctx.i18n,
|
|
223
|
+
loaderData: store._ctx.loaderData,
|
|
224
|
+
env: store._ctx.env
|
|
225
|
+
};
|
|
196
226
|
if (typeof window !== "undefined") {
|
|
197
227
|
;
|
|
198
228
|
window.__WEIFUWU_CTX = { ...window.__WEIFUWU_CTX, ...value };
|
|
@@ -290,7 +320,9 @@ function applyHead(html) {
|
|
|
290
320
|
const doc = new DOMParser().parseFromString(headHtml, "text/html");
|
|
291
321
|
const newMeta = doc.querySelectorAll("meta");
|
|
292
322
|
const existing = document.querySelectorAll("head meta");
|
|
293
|
-
const newNames = new Set(
|
|
323
|
+
const newNames = new Set(
|
|
324
|
+
Array.from(newMeta).map((m) => m.getAttribute("name") || m.getAttribute("property") || "")
|
|
325
|
+
);
|
|
294
326
|
for (const el of existing) {
|
|
295
327
|
const key = el.getAttribute("name") || el.getAttribute("property") || "";
|
|
296
328
|
if (!newNames.has(key)) el.remove();
|
|
@@ -307,7 +339,8 @@ function applyHead(html) {
|
|
|
307
339
|
}
|
|
308
340
|
}
|
|
309
341
|
if (existingEl) {
|
|
310
|
-
for (const attr of el.attributes)
|
|
342
|
+
for (const attr of el.attributes)
|
|
343
|
+
existingEl.setAttribute(attr.name, attr.value);
|
|
311
344
|
} else {
|
|
312
345
|
document.head.appendChild(el.cloneNode());
|
|
313
346
|
}
|
|
@@ -345,27 +378,37 @@ function Link({ href, children, onClick, prefetch, ...props }) {
|
|
|
345
378
|
}
|
|
346
379
|
}
|
|
347
380
|
if (!el) return;
|
|
348
|
-
const observer = new IntersectionObserver(
|
|
349
|
-
|
|
350
|
-
|
|
381
|
+
const observer = new IntersectionObserver(
|
|
382
|
+
([entry]) => {
|
|
383
|
+
if (entry.isIntersecting) prefetchPage(href);
|
|
384
|
+
},
|
|
385
|
+
{ rootMargin: "200px" }
|
|
386
|
+
);
|
|
351
387
|
observer.observe(el);
|
|
352
388
|
return () => observer.disconnect();
|
|
353
389
|
}, [href, prefetch]);
|
|
354
390
|
const handleMouseEnter = useCallback3(() => {
|
|
355
391
|
if (prefetch) prefetchPage(href);
|
|
356
392
|
}, [href, prefetch]);
|
|
357
|
-
const handleClick = useCallback3(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
href,
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
393
|
+
const handleClick = useCallback3(
|
|
394
|
+
(e) => {
|
|
395
|
+
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
396
|
+
e.preventDefault();
|
|
397
|
+
doNavigate(href);
|
|
398
|
+
onClick?.(e);
|
|
399
|
+
},
|
|
400
|
+
[href, onClick, doNavigate]
|
|
401
|
+
);
|
|
402
|
+
return createElement(
|
|
403
|
+
"a",
|
|
404
|
+
{
|
|
405
|
+
href,
|
|
406
|
+
onClick: handleClick,
|
|
407
|
+
onMouseEnter: handleMouseEnter,
|
|
408
|
+
...props
|
|
409
|
+
},
|
|
410
|
+
children
|
|
411
|
+
);
|
|
369
412
|
}
|
|
370
413
|
async function prefetchPage(href) {
|
|
371
414
|
const cached = prefetchCache.get(href);
|
|
@@ -400,10 +443,7 @@ function createStore(initial) {
|
|
|
400
443
|
listeners.delete(listener);
|
|
401
444
|
};
|
|
402
445
|
};
|
|
403
|
-
const useStore = ((selector) => useSyncExternalStore2(
|
|
404
|
-
subscribe2,
|
|
405
|
-
() => selector ? selector(state) : state
|
|
406
|
-
));
|
|
446
|
+
const useStore = ((selector) => useSyncExternalStore2(subscribe2, () => selector ? selector(state) : state));
|
|
407
447
|
useStore.getState = getState;
|
|
408
448
|
useStore.setState = setState;
|
|
409
449
|
useStore.subscribe = subscribe2;
|
|
@@ -430,19 +470,23 @@ function useFetch(url, options) {
|
|
|
430
470
|
let cancelled = false;
|
|
431
471
|
const cached = dataCache.get(u);
|
|
432
472
|
if (cached && Date.now() - cached.timestamp < ttl) {
|
|
433
|
-
if (!cancelled)
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
473
|
+
if (!cancelled)
|
|
474
|
+
setState({
|
|
475
|
+
data: cached.data,
|
|
476
|
+
error: cached.error,
|
|
477
|
+
loading: false
|
|
478
|
+
});
|
|
438
479
|
return;
|
|
439
480
|
}
|
|
440
481
|
async function doFetch() {
|
|
441
482
|
if (!inflight.has(u)) {
|
|
442
|
-
inflight.set(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
483
|
+
inflight.set(
|
|
484
|
+
u,
|
|
485
|
+
fetch(u).then((r) => {
|
|
486
|
+
if (!r.ok) throw new Error(r.statusText || `HTTP ${r.status}`);
|
|
487
|
+
return r.json();
|
|
488
|
+
})
|
|
489
|
+
);
|
|
446
490
|
}
|
|
447
491
|
const promise = inflight.get(u);
|
|
448
492
|
try {
|
|
@@ -501,18 +545,21 @@ function useQueryState(key, defaultValue = "") {
|
|
|
501
545
|
getSnapshot2,
|
|
502
546
|
() => defaultValue
|
|
503
547
|
);
|
|
504
|
-
const setValue = useCallback4(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
548
|
+
const setValue = useCallback4(
|
|
549
|
+
(val) => {
|
|
550
|
+
if (typeof window === "undefined") return;
|
|
551
|
+
const resolved = typeof val === "function" ? val(getSnapshot2()) : val;
|
|
552
|
+
const url = new URL(window.location.href);
|
|
553
|
+
if (resolved === defaultValue || resolved === "") {
|
|
554
|
+
url.searchParams.delete(key);
|
|
555
|
+
} else {
|
|
556
|
+
url.searchParams.set(key, resolved);
|
|
557
|
+
}
|
|
558
|
+
window.history.replaceState(null, "", url.toString());
|
|
559
|
+
notifyQueryListeners();
|
|
560
|
+
},
|
|
561
|
+
[key, defaultValue]
|
|
562
|
+
);
|
|
516
563
|
return [value, setValue];
|
|
517
564
|
}
|
|
518
565
|
|
|
@@ -593,7 +640,10 @@ addInterceptor(async (url) => {
|
|
|
593
640
|
headers: { accept: "application/json" }
|
|
594
641
|
});
|
|
595
642
|
const data = await res.json();
|
|
596
|
-
window.__WEIFUWU_CTX = {
|
|
643
|
+
window.__WEIFUWU_CTX = {
|
|
644
|
+
...window.__WEIFUWU_CTX,
|
|
645
|
+
theme: { value: data.theme }
|
|
646
|
+
};
|
|
597
647
|
setCtx({ theme: { value: data.theme } });
|
|
598
648
|
applyTheme(data.theme);
|
|
599
649
|
} catch {
|
|
@@ -629,43 +679,38 @@ function useFlashMessage() {
|
|
|
629
679
|
// use-agent-stream.ts
|
|
630
680
|
import { useState as useState6, useCallback as useCallback5, useRef as useRef4 } from "react";
|
|
631
681
|
function useAgentStream(opts) {
|
|
632
|
-
const { wsPath,
|
|
682
|
+
const { wsPath, onStreamEnd, onError } = opts;
|
|
633
683
|
const [streams, setStreams] = useState6({});
|
|
634
684
|
const activeRef = useRef4(/* @__PURE__ */ new Set());
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
);
|
|
639
|
-
const isAgentStreaming = useCallback5(
|
|
640
|
-
(agentId) => activeRef.current.has(agentId),
|
|
641
|
-
[]
|
|
642
|
-
);
|
|
685
|
+
const streamsRef = useRef4({});
|
|
686
|
+
const getAgentText = useCallback5((agentId) => streams[agentId] || "", [streams]);
|
|
687
|
+
const isAgentStreaming = useCallback5((agentId) => activeRef.current.has(agentId), []);
|
|
643
688
|
const streaming = activeRef.current.size > 0;
|
|
644
689
|
useWebsocket(wsPath, {
|
|
645
690
|
onMessage: (raw) => {
|
|
646
691
|
try {
|
|
647
692
|
const msg = JSON.parse(raw);
|
|
648
|
-
if (msg.type !== "agent_stream" && msg.type !== "agent_stream_end" && msg.type !== "agent_error")
|
|
693
|
+
if (msg.type !== "agent_stream" && msg.type !== "agent_stream_end" && msg.type !== "agent_error")
|
|
694
|
+
return;
|
|
649
695
|
const agentId = msg.data?.agent_id;
|
|
650
696
|
if (agentId === void 0 || agentId === null) return;
|
|
651
697
|
switch (msg.type) {
|
|
652
698
|
case "agent_stream": {
|
|
653
699
|
activeRef.current.add(agentId);
|
|
654
700
|
const token = msg.data?.token || "";
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
return { ...prev, [agentId]: current + token };
|
|
658
|
-
});
|
|
701
|
+
streamsRef.current[agentId] = (streamsRef.current[agentId] || "") + token;
|
|
702
|
+
setStreams({ ...streamsRef.current });
|
|
659
703
|
break;
|
|
660
704
|
}
|
|
661
705
|
case "agent_stream_end": {
|
|
662
706
|
activeRef.current.delete(agentId);
|
|
663
|
-
const fullText =
|
|
707
|
+
const fullText = streamsRef.current[agentId] || "";
|
|
664
708
|
onStreamEnd?.(agentId, fullText);
|
|
665
709
|
break;
|
|
666
710
|
}
|
|
667
711
|
case "agent_error": {
|
|
668
712
|
activeRef.current.delete(agentId);
|
|
713
|
+
delete streamsRef.current[agentId];
|
|
669
714
|
onError?.(agentId, msg.data?.error || "Unknown error");
|
|
670
715
|
break;
|
|
671
716
|
}
|
package/dist/redis/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Redis, RedisOptions as IORedisOptions } from '../vendor.ts';
|
|
2
|
-
import type { Context, Middleware } from '../types.ts';
|
|
2
|
+
import type { Context, Middleware, Closeable } from '../types.ts';
|
|
3
3
|
declare module '../types.ts' {
|
|
4
4
|
interface Context {
|
|
5
5
|
redis: Redis;
|
|
@@ -12,7 +12,7 @@ export type RedisOptions = IORedisOptions & {
|
|
|
12
12
|
export interface RedisInjected {
|
|
13
13
|
redis: Redis;
|
|
14
14
|
}
|
|
15
|
-
export interface RedisClient extends Middleware<Context, Context & RedisInjected
|
|
15
|
+
export interface RedisClient extends Middleware<Context, Context & RedisInjected>, Closeable {
|
|
16
16
|
redis: Redis;
|
|
17
17
|
close: () => Promise<void>;
|
|
18
18
|
}
|
package/dist/router.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { WebSocket } from './vendor.ts';
|
|
|
2
2
|
import { type IncomingMessage } from 'node:http';
|
|
3
3
|
import type { Duplex } from 'node:stream';
|
|
4
4
|
import type { Context, Handler, Middleware, ErrorHandler } from './types.ts';
|
|
5
|
-
import type
|
|
5
|
+
import { type Hub } from './hub.ts';
|
|
6
6
|
export type WebSocketHandler = {
|
|
7
7
|
open?: (ws: WebSocket, ctx: Context) => void | Promise<void>;
|
|
8
8
|
message?: (ws: WebSocket, ctx: Context, data: string | Buffer) => void | Promise<void>;
|
|
@@ -24,18 +24,18 @@ export declare class Router<T extends Context = Context> {
|
|
|
24
24
|
wsHub(hub: Hub): this;
|
|
25
25
|
use<Out extends Context>(mw: Middleware<Context, Out>): Router<T & Out>;
|
|
26
26
|
use(path: string, mw: Middleware<T, T>): Router<T>;
|
|
27
|
-
use(path: string, router: Router<
|
|
27
|
+
use(path: string, router: Router<Context>): Router<T>;
|
|
28
28
|
use(mod: Router & {
|
|
29
29
|
middleware: () => Middleware;
|
|
30
30
|
}): Router<T>;
|
|
31
|
-
get(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
32
|
-
post(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
33
|
-
put(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
34
|
-
delete(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
35
|
-
patch(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
36
|
-
head(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
37
|
-
options(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
38
|
-
all(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<
|
|
31
|
+
get(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
32
|
+
post(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
33
|
+
put(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
34
|
+
delete(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
35
|
+
patch(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
36
|
+
head(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
37
|
+
options(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
38
|
+
all(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
39
39
|
onError(handler: ErrorHandler<T>): Router<T>;
|
|
40
40
|
private _route;
|
|
41
41
|
/** Internal route registration — no type constraints (used by _mountRouter). */
|
package/dist/seo.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
1
|
+
import type { Middleware, Context } from './types.ts';
|
|
2
2
|
import { Router } from './router.ts';
|
|
3
3
|
/** A rule in `robots.txt`. */
|
|
4
4
|
export interface RobotsRule {
|
|
@@ -54,7 +54,7 @@ export interface SeoOptions {
|
|
|
54
54
|
* }))
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
|
-
export declare function seoMiddleware(options?: SeoOptions): Middleware
|
|
57
|
+
export declare function seoMiddleware(options?: SeoOptions): Middleware<Context, Context>;
|
|
58
58
|
/**
|
|
59
59
|
* SEO module — serves `robots.txt` and `sitemap.xml`.
|
|
60
60
|
*
|
package/dist/serve.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export declare function createRequest(req: IncomingMessage, body: Buffer): [Requ
|
|
|
29
29
|
export declare function sendResponse(res: ServerResponse, response: Response, opts?: {
|
|
30
30
|
traceId?: string | null;
|
|
31
31
|
}): Promise<void>;
|
|
32
|
-
export declare function createTestServer(handler: Handler): Promise<{
|
|
32
|
+
export declare function createTestServer(handler: Handler, options?: ServeOptions): Promise<{
|
|
33
33
|
server: Server;
|
|
34
34
|
url: string;
|
|
35
35
|
}>;
|
package/dist/session.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
1
|
+
import type { Context, Middleware, Closeable } from './types.ts';
|
|
2
2
|
import type { Redis } from './vendor.ts';
|
|
3
3
|
declare module './types.ts' {
|
|
4
4
|
interface Context {
|
|
@@ -27,10 +27,12 @@ export interface Session extends SessionData {
|
|
|
27
27
|
[kStore]: SessionStore;
|
|
28
28
|
[kTtl]: number;
|
|
29
29
|
}
|
|
30
|
-
export interface SessionStore {
|
|
30
|
+
export interface SessionStore extends Closeable {
|
|
31
31
|
get(sid: string): Promise<Record<string, unknown> | null>;
|
|
32
32
|
set(sid: string, data: Record<string, unknown>, ttl: number): Promise<void>;
|
|
33
33
|
destroy(sid: string): Promise<void>;
|
|
34
|
+
/** Release resources. Default no-op. */
|
|
35
|
+
close(): Promise<void>;
|
|
34
36
|
}
|
|
35
37
|
export interface SessionOptions {
|
|
36
38
|
/** Session store. 'memory' (default) or 'redis'. */
|
|
@@ -74,7 +76,7 @@ export declare class MemoryStore implements SessionStore {
|
|
|
74
76
|
set(sid: string, data: Record<string, unknown>, ttl: number): Promise<void>;
|
|
75
77
|
destroy(sid: string): Promise<void>;
|
|
76
78
|
private cleanup;
|
|
77
|
-
close(): void
|
|
79
|
+
close(): Promise<void>;
|
|
78
80
|
/** Testing only: return approximate count. */
|
|
79
81
|
get size(): number;
|
|
80
82
|
}
|
|
@@ -86,9 +88,10 @@ export declare class RedisStore implements SessionStore {
|
|
|
86
88
|
get(sid: string): Promise<Record<string, unknown> | null>;
|
|
87
89
|
set(sid: string, data: Record<string, unknown>, ttl: number): Promise<void>;
|
|
88
90
|
destroy(sid: string): Promise<void>;
|
|
91
|
+
close(): Promise<void>;
|
|
89
92
|
}
|
|
90
|
-
export declare function session(options?: SessionOptions): Middleware & {
|
|
91
|
-
close: () => void
|
|
93
|
+
export declare function session(options?: SessionOptions): Middleware<Context, Context & SessionInjected> & {
|
|
94
|
+
close: () => Promise<void>;
|
|
92
95
|
store: SessionStore;
|
|
93
96
|
};
|
|
94
97
|
export {};
|
package/dist/tailwind.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { Router } from './router.ts';
|
|
2
2
|
import type { Middleware } from './types.ts';
|
|
3
|
+
export interface TailwindInjected {
|
|
4
|
+
css: string;
|
|
5
|
+
url: string;
|
|
6
|
+
}
|
|
7
|
+
declare module './types.ts' {
|
|
8
|
+
interface Context {
|
|
9
|
+
tailwind?: TailwindInjected;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
3
12
|
export declare function addTailwindSource(dir: string): void;
|
|
4
13
|
export declare function tailwindContext(dir: string): Middleware;
|
|
5
14
|
export declare function tailwindRouter(dir: string): Router;
|
package/dist/tenant/graphql.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import { Router } from '../router.ts';
|
|
3
|
-
export declare function buildGraphQLHandler(sql:
|
|
3
|
+
export declare function buildGraphQLHandler(sql: SqlClient): Router;
|
package/dist/tenant/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { tenant } from './client.ts';
|
|
2
|
-
export type { TenantOptions, TenantModule, TenantContext, FieldDef, FieldType, RelationDef, UserTableRow } from './types.ts';
|
|
2
|
+
export type { TenantOptions, TenantModule, TenantContext, FieldDef, FieldType, RelationDef, UserTableRow, } from './types.ts';
|
package/dist/tenant/rest.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import { Router } from '../router.ts';
|
|
3
|
-
export declare function buildRouter(sql:
|
|
3
|
+
export declare function buildRouter(sql: SqlClient, usersTable: string): Router;
|
package/dist/tenant/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Context } from '../types.ts';
|
|
1
|
+
import type { Context, Handler } from '../types.ts';
|
|
2
2
|
import type { Router } from '../router.ts';
|
|
3
3
|
import type { PostgresClient } from '../postgres/types.ts';
|
|
4
4
|
declare module '../types.ts' {
|
|
@@ -42,7 +42,7 @@ export interface TenantOptions {
|
|
|
42
42
|
}
|
|
43
43
|
export interface TenantModule extends Router {
|
|
44
44
|
migrate: () => Promise<void>;
|
|
45
|
-
middleware: () => (req: Request, ctx: Context, next:
|
|
46
|
-
graphql: () =>
|
|
45
|
+
middleware: () => (req: Request, ctx: Context, next: Handler<Context>) => Promise<Response>;
|
|
46
|
+
graphql: () => Router;
|
|
47
47
|
close: () => Promise<void>;
|
|
48
48
|
}
|
package/dist/test-utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Context, Handler } from './types.ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SqlClient } from './vendor.ts';
|
|
3
3
|
export interface TestResponse {
|
|
4
4
|
readonly status: number;
|
|
5
5
|
readonly headers: Headers;
|
|
@@ -68,7 +68,7 @@ export declare function testApp(): TestApp;
|
|
|
68
68
|
*/
|
|
69
69
|
export interface TestDb {
|
|
70
70
|
/** Tagged-template SQL client connected to the test database. */
|
|
71
|
-
sql:
|
|
71
|
+
sql: SqlClient;
|
|
72
72
|
/** Connection URL of the test database. */
|
|
73
73
|
url: string;
|
|
74
74
|
/** Schema name used for this test session. */
|
|
@@ -113,4 +113,4 @@ export declare function createTestDb(options?: {
|
|
|
113
113
|
*/
|
|
114
114
|
export declare function withTestDb(optionsOrFn: string | {
|
|
115
115
|
url?: string;
|
|
116
|
-
} | ((sql:
|
|
116
|
+
} | ((sql: SqlClient) => Promise<void>), fn?: (sql: SqlClient) => Promise<void>): Promise<void>;
|
package/dist/types.d.ts
CHANGED
|
@@ -11,3 +11,11 @@ export interface Context {
|
|
|
11
11
|
export type Handler<T extends Context = Context> = (req: Request, ctx: T) => Response | Promise<Response>;
|
|
12
12
|
export type Middleware<In extends Context = Context, Out extends In = In> = (req: Request, ctx: In, next: Handler<Out>) => Response | Promise<Response>;
|
|
13
13
|
export type ErrorHandler<T extends Context = Context> = (error: Error, req: Request, ctx: T) => Response | Promise<Response>;
|
|
14
|
+
/**
|
|
15
|
+
* Interface for resources that require explicit cleanup (connections, pools, timers).
|
|
16
|
+
* All stateful modules implement this.
|
|
17
|
+
*/
|
|
18
|
+
export interface Closeable {
|
|
19
|
+
/** Release all resources. Call once when shutting down. */
|
|
20
|
+
close(): Promise<void>;
|
|
21
|
+
}
|
package/dist/upload.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
1
|
+
import type { Context, Middleware } from './types.ts';
|
|
2
2
|
declare module './types.ts' {
|
|
3
3
|
interface Context {
|
|
4
4
|
parsed: Record<string, unknown>;
|
|
@@ -46,4 +46,6 @@ export interface UploadOptions {
|
|
|
46
46
|
* })
|
|
47
47
|
* ```
|
|
48
48
|
*/
|
|
49
|
-
export declare function upload(options?: UploadOptions): Middleware
|
|
49
|
+
export declare function upload(options?: UploadOptions): Middleware<Context, Context & {
|
|
50
|
+
parsed: Record<string, unknown>;
|
|
51
|
+
}>;
|
package/dist/user/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { user } from './client.ts';
|
|
2
|
-
export type { UserOptions, UserData, UserModule, AuthResult, OAuth2Client, OAuthProviderConfig, UserInjected } from './types.ts';
|
|
2
|
+
export type { UserOptions, UserData, UserModule, AuthResult, OAuth2Client, OAuthProviderConfig, UserInjected, } from './types.ts';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SqlClient } from '../vendor.ts';
|
|
2
2
|
import type { Router } from '../router.ts';
|
|
3
3
|
import type { OAuthProviderConfig } from './types.ts';
|
|
4
4
|
interface OAuthLoginDeps {
|
|
5
|
-
sql:
|
|
5
|
+
sql: SqlClient;
|
|
6
6
|
jwtSecret: string;
|
|
7
7
|
expiresIn: string | number;
|
|
8
8
|
usersTable: string;
|
package/dist/user/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware, Context } from '../types.ts';
|
|
1
|
+
import type { Middleware, Context, Closeable } from '../types.ts';
|
|
2
2
|
import type { Router } from '../router.ts';
|
|
3
3
|
import type { PostgresClient } from '../postgres/types.ts';
|
|
4
4
|
/** A user record from the database. */
|
|
@@ -107,7 +107,7 @@ export interface UserInjected {
|
|
|
107
107
|
* app.use('/', auth) // mounts routes: /register, /login
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
|
110
|
-
export interface UserModule extends Router {
|
|
110
|
+
export interface UserModule extends Router, Closeable {
|
|
111
111
|
/**
|
|
112
112
|
* Strict auth middleware. Reads JWT from `Authorization: Bearer` header.
|
|
113
113
|
* Returns 401 if no valid token is found.
|
package/dist/vendor.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import type postgres from 'postgres';
|
|
2
|
+
/** Untyped postgres.js SQL client. Use typed `Sql<{ table: { col: type } }>` for schemas. */
|
|
3
|
+
export type SqlClient = postgres.Sql<Record<string, unknown>>;
|
|
4
|
+
/** Re-export for downstream usage. */
|
|
1
5
|
export type { Sql } from 'postgres';
|
|
2
6
|
export type { WebSocket } from 'ws';
|
|
3
7
|
export type { Redis, RedisOptions } from 'ioredis';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@import
|
|
1
|
+
@import 'tailwindcss';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
export default function RootLayout({ children }: { children: any }) {
|
|
2
3
|
return (
|
|
3
4
|
<html lang="en">
|
|
@@ -6,9 +7,7 @@ export default function RootLayout({ children }: { children: any }) {
|
|
|
6
7
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
8
|
<title>Opencode Chat</title>
|
|
8
9
|
</head>
|
|
9
|
-
<body>
|
|
10
|
-
{children}
|
|
11
|
-
</body>
|
|
10
|
+
<body>{children}</body>
|
|
12
11
|
</html>
|
|
13
12
|
)
|
|
14
13
|
}
|