@donkeylabs/cli 0.1.0 → 0.4.0
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/package.json +2 -2
- package/src/client/base.ts +481 -0
- package/src/commands/generate.ts +262 -53
- package/src/index.ts +0 -0
- package/templates/starter/package.json +3 -3
- package/templates/starter/src/index.ts +19 -30
- package/templates/starter/src/routes/health/handlers/ping.ts +22 -0
- package/templates/starter/src/routes/health/index.ts +16 -2
- package/templates/sveltekit-app/bun.lock +547 -0
- package/templates/sveltekit-app/donkeylabs.config.ts +2 -0
- package/templates/sveltekit-app/package.json +10 -8
- package/templates/sveltekit-app/scripts/watch-server.ts +55 -0
- package/templates/sveltekit-app/src/lib/api.ts +195 -81
- package/templates/sveltekit-app/src/routes/+page.server.ts +3 -3
- package/templates/sveltekit-app/src/routes/+page.svelte +235 -96
- package/templates/sveltekit-app/src/server/index.ts +29 -247
- package/templates/sveltekit-app/src/server/plugins/demo/index.ts +144 -0
- package/templates/sveltekit-app/src/server/routes/cache/handlers/delete.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/cache/handlers/get.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/cache/handlers/keys.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/cache/handlers/set.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/cache/index.ts +46 -0
- package/templates/sveltekit-app/src/server/routes/counter/handlers/decrement.ts +17 -0
- package/templates/sveltekit-app/src/server/routes/counter/handlers/get.ts +17 -0
- package/templates/sveltekit-app/src/server/routes/counter/handlers/increment.ts +17 -0
- package/templates/sveltekit-app/src/server/routes/counter/handlers/reset.ts +17 -0
- package/templates/sveltekit-app/src/server/routes/counter/index.ts +39 -0
- package/templates/sveltekit-app/src/server/routes/cron/handlers/list.ts +17 -0
- package/templates/sveltekit-app/src/server/routes/cron/index.ts +24 -0
- package/templates/sveltekit-app/src/server/routes/events/handlers/emit.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/events/index.ts +19 -0
- package/templates/sveltekit-app/src/server/routes/index.ts +8 -0
- package/templates/sveltekit-app/src/server/routes/jobs/handlers/enqueue.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/jobs/handlers/stats.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/jobs/index.ts +28 -0
- package/templates/sveltekit-app/src/server/routes/ratelimit/handlers/check.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/ratelimit/handlers/reset.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/ratelimit/index.ts +29 -0
- package/templates/sveltekit-app/src/server/routes/sse/handlers/broadcast.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/sse/handlers/clients.ts +15 -0
- package/templates/sveltekit-app/src/server/routes/sse/index.ts +28 -0
- package/templates/sveltekit-app/{svelte.config.js → svelte.config.ts} +4 -5
- package/templates/sveltekit-app/tsconfig.json +4 -9
- package/templates/sveltekit-app/vite.config.ts +2 -1
- package/templates/starter/CLAUDE.md +0 -144
- package/templates/starter/src/client.test.ts +0 -7
- package/templates/starter/src/db.ts +0 -9
- package/templates/starter/src/routes/health/ping/index.ts +0 -13
- package/templates/starter/src/routes/health/ping/models/model.ts +0 -23
- package/templates/starter/src/routes/health/ping/schema.ts +0 -14
- package/templates/starter/src/routes/health/ping/tests/integ.test.ts +0 -20
- package/templates/starter/src/routes/health/ping/tests/unit.test.ts +0 -21
- package/templates/starter/src/test-ctx.ts +0 -24
|
@@ -3,6 +3,8 @@ import { defineConfig } from "@donkeylabs/server";
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
plugins: ["./src/server/plugins/**/index.ts"],
|
|
5
5
|
outDir: ".@donkeylabs/server",
|
|
6
|
+
entry: "./src/server/index.ts",
|
|
7
|
+
routes: "./src/server/routes/**/{route,index}.ts",
|
|
6
8
|
adapter: "@donkeylabs/adapter-sveltekit",
|
|
7
9
|
client: {
|
|
8
10
|
output: "./src/lib/api.ts",
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
"version": "0.0.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "bun --bun vite dev",
|
|
8
|
-
"
|
|
7
|
+
"dev": "bun run gen:types && bun run dev:watch & bun --bun vite dev",
|
|
8
|
+
"dev:watch": "bun --watch --no-clear-screen scripts/watch-server.ts",
|
|
9
|
+
"build": "bun run gen:types && vite build",
|
|
9
10
|
"preview": "bun build/server/entry.js",
|
|
10
|
-
"prepare": "svelte-kit sync || echo ''",
|
|
11
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
12
|
-
"gen:types": "donkeylabs generate"
|
|
11
|
+
"prepare": "bun --bun svelte-kit sync || echo ''",
|
|
12
|
+
"check": "bun --bun svelte-kit sync && bun --bun svelte-check --tsconfig ./tsconfig.json",
|
|
13
|
+
"gen:types": "donkeylabs generate",
|
|
14
|
+
"cli": "donkeylabs"
|
|
13
15
|
},
|
|
14
16
|
"devDependencies": {
|
|
15
|
-
"@donkeylabs/cli": "*",
|
|
16
17
|
"@sveltejs/kit": "^2.49.1",
|
|
17
18
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
18
19
|
"@tailwindcss/vite": "^4.1.18",
|
|
@@ -23,8 +24,9 @@
|
|
|
23
24
|
"vite": "^7.2.6"
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
26
|
-
"@donkeylabs/
|
|
27
|
-
"@donkeylabs/
|
|
27
|
+
"@donkeylabs/cli": "0.1.1",
|
|
28
|
+
"@donkeylabs/adapter-sveltekit": "0.1.2",
|
|
29
|
+
"@donkeylabs/server": "0.3.2",
|
|
28
30
|
"bits-ui": "^2.15.4",
|
|
29
31
|
"clsx": "^2.1.1",
|
|
30
32
|
"kysely": "^0.27.6",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Watch server files and regenerate types on changes
|
|
2
|
+
import { watch } from "node:fs";
|
|
3
|
+
import { exec } from "node:child_process";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
|
|
9
|
+
const serverDir = join(import.meta.dir, "..", "src", "server");
|
|
10
|
+
let isGenerating = false;
|
|
11
|
+
let pendingGenerate = false;
|
|
12
|
+
|
|
13
|
+
async function regenerate() {
|
|
14
|
+
if (isGenerating) {
|
|
15
|
+
pendingGenerate = true;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
isGenerating = true;
|
|
20
|
+
console.log("\x1b[36m[watch]\x1b[0m Server files changed, regenerating types...");
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
await execAsync("bun run gen:types");
|
|
24
|
+
console.log("\x1b[32m[watch]\x1b[0m Types regenerated successfully");
|
|
25
|
+
} catch (e: any) {
|
|
26
|
+
console.error("\x1b[31m[watch]\x1b[0m Error regenerating types:", e.message);
|
|
27
|
+
} finally {
|
|
28
|
+
isGenerating = false;
|
|
29
|
+
if (pendingGenerate) {
|
|
30
|
+
pendingGenerate = false;
|
|
31
|
+
await regenerate();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Debounce to avoid multiple rapid regenerations
|
|
37
|
+
let debounceTimer: Timer | null = null;
|
|
38
|
+
|
|
39
|
+
function debouncedRegenerate() {
|
|
40
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
41
|
+
debounceTimer = setTimeout(regenerate, 300);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Watch server directory recursively
|
|
45
|
+
watch(serverDir, { recursive: true }, (eventType, filename) => {
|
|
46
|
+
if (!filename) return;
|
|
47
|
+
if (!filename.endsWith(".ts")) return;
|
|
48
|
+
|
|
49
|
+
debouncedRegenerate();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
console.log("\x1b[36m[watch]\x1b[0m Watching src/server/ for changes...");
|
|
53
|
+
|
|
54
|
+
// Keep process alive
|
|
55
|
+
await new Promise(() => {});
|
|
@@ -1,134 +1,248 @@
|
|
|
1
|
+
// Auto-generated by @donkeylabs/server
|
|
2
|
+
// DO NOT EDIT MANUALLY
|
|
3
|
+
|
|
4
|
+
import { UnifiedApiClientBase, type ClientOptions } from "@donkeylabs/adapter-sveltekit/client";
|
|
5
|
+
|
|
6
|
+
// Utility type that forces TypeScript to expand types on hover
|
|
7
|
+
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
10
|
+
* Handler interface for implementing route handlers in model classes.
|
|
11
|
+
* @example
|
|
12
|
+
* class CounterModel implements Handler<Routes.Counter.get> {
|
|
13
|
+
* handle(input: Routes.Counter.get.Input): Routes.Counter.get.Output {
|
|
14
|
+
* return { count: 0 };
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
4
17
|
*/
|
|
5
|
-
|
|
18
|
+
export interface Handler<T extends { Input: any; Output: any }> {
|
|
19
|
+
handle(input: T["Input"]): T["Output"] | Promise<T["Output"]>;
|
|
20
|
+
}
|
|
6
21
|
|
|
7
|
-
//
|
|
8
|
-
export
|
|
22
|
+
// Re-export server context for model classes
|
|
23
|
+
export { type ServerContext as AppContext } from "@donkeylabs/server";
|
|
24
|
+
|
|
25
|
+
// ============================================
|
|
26
|
+
// Route Types
|
|
27
|
+
// ============================================
|
|
28
|
+
|
|
29
|
+
export namespace Routes {
|
|
30
|
+
export namespace Counter {
|
|
31
|
+
export namespace get {
|
|
32
|
+
export type Input = Expand<Record<string, never>>;
|
|
33
|
+
export type Output = Expand<{
|
|
9
34
|
count: number;
|
|
10
|
-
}
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
11
37
|
|
|
12
|
-
export
|
|
38
|
+
export namespace increment {
|
|
39
|
+
export type Input = Expand<Record<string, never>>;
|
|
40
|
+
export type Output = Expand<{
|
|
41
|
+
count: number;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export namespace decrement {
|
|
46
|
+
export type Input = Expand<Record<string, never>>;
|
|
47
|
+
export type Output = Expand<{
|
|
48
|
+
count: number;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export namespace reset {
|
|
53
|
+
export type Input = Expand<Record<string, never>>;
|
|
54
|
+
export type Output = Expand<{
|
|
55
|
+
count: number;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export namespace Cache {
|
|
61
|
+
export namespace set {
|
|
62
|
+
export type Input = Expand<{
|
|
63
|
+
key: string;
|
|
13
64
|
value: any;
|
|
65
|
+
ttl?: number;
|
|
66
|
+
}>;
|
|
67
|
+
export type Output = Expand<{
|
|
68
|
+
success: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export namespace get {
|
|
73
|
+
export type Input = Expand<{
|
|
74
|
+
key: string;
|
|
75
|
+
}>;
|
|
76
|
+
export type Output = Expand<{
|
|
77
|
+
value?: any;
|
|
14
78
|
exists: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export namespace delete {
|
|
83
|
+
export type Input = Expand<{
|
|
84
|
+
key: string;
|
|
85
|
+
}>;
|
|
86
|
+
export type Output = Expand<{
|
|
87
|
+
success: boolean;
|
|
88
|
+
}>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export namespace keys {
|
|
92
|
+
export type Input = Expand<Record<string, never>>;
|
|
93
|
+
export type Output = Expand<{
|
|
18
94
|
keys: string[];
|
|
19
|
-
|
|
20
|
-
}
|
|
95
|
+
}>;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
21
98
|
|
|
22
|
-
export
|
|
99
|
+
export namespace Jobs {
|
|
100
|
+
export namespace enqueue {
|
|
101
|
+
export type Input = Expand<{
|
|
102
|
+
name: string;
|
|
103
|
+
data: any;
|
|
104
|
+
delay?: number;
|
|
105
|
+
}>;
|
|
106
|
+
export type Output = Expand<{
|
|
23
107
|
jobId: string;
|
|
24
|
-
}
|
|
108
|
+
}>;
|
|
109
|
+
}
|
|
25
110
|
|
|
26
|
-
export
|
|
111
|
+
export namespace stats {
|
|
112
|
+
export type Input = Expand<Record<string, never>>;
|
|
113
|
+
export type Output = Expand<{
|
|
27
114
|
pending: number;
|
|
28
115
|
running: number;
|
|
29
116
|
completed: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
117
|
+
}>;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export namespace Cron {
|
|
122
|
+
export namespace list {
|
|
123
|
+
export type Input = Expand<Record<string, never>>;
|
|
124
|
+
export type Output = Expand<{
|
|
125
|
+
tasks: {
|
|
33
126
|
id: string;
|
|
34
127
|
name: string;
|
|
35
128
|
expression: string;
|
|
36
129
|
enabled: boolean;
|
|
37
130
|
lastRun?: string;
|
|
38
131
|
nextRun?: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
export
|
|
132
|
+
}[];
|
|
133
|
+
}>;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export namespace Ratelimit {
|
|
138
|
+
export namespace check {
|
|
139
|
+
export type Input = Expand<{
|
|
140
|
+
key: string;
|
|
141
|
+
limit: number;
|
|
142
|
+
window: number;
|
|
143
|
+
}>;
|
|
144
|
+
export type Output = Expand<{
|
|
46
145
|
allowed: boolean;
|
|
47
146
|
remaining: number;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export
|
|
147
|
+
resetAt: Date;
|
|
148
|
+
}>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export namespace reset {
|
|
152
|
+
export type Input = Expand<{
|
|
153
|
+
key: string;
|
|
154
|
+
}>;
|
|
155
|
+
export type Output = Expand<{
|
|
156
|
+
success: boolean;
|
|
157
|
+
}>;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export namespace Events {
|
|
162
|
+
export namespace emit {
|
|
163
|
+
export type Input = Expand<{
|
|
164
|
+
event: string;
|
|
165
|
+
data: any;
|
|
166
|
+
}>;
|
|
167
|
+
export type Output = Expand<{
|
|
168
|
+
success: boolean;
|
|
169
|
+
}>;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export namespace Sse {
|
|
174
|
+
export namespace broadcast {
|
|
175
|
+
export type Input = Expand<{
|
|
176
|
+
channel: string;
|
|
177
|
+
event: string;
|
|
178
|
+
data: any;
|
|
179
|
+
}>;
|
|
180
|
+
export type Output = Expand<{
|
|
181
|
+
success: boolean;
|
|
182
|
+
recipients: number;
|
|
183
|
+
}>;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export namespace clients {
|
|
187
|
+
export type Input = Expand<Record<string, never>>;
|
|
188
|
+
export type Output = Expand<{
|
|
54
189
|
total: number;
|
|
55
190
|
byChannel: number;
|
|
191
|
+
}>;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
56
194
|
}
|
|
57
195
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
196
|
+
// ============================================
|
|
197
|
+
// API Client
|
|
198
|
+
// ============================================
|
|
199
|
+
|
|
61
200
|
export class ApiClient extends UnifiedApiClientBase {
|
|
62
|
-
|
|
201
|
+
constructor(options?: ClientOptions) {
|
|
202
|
+
super(options);
|
|
203
|
+
}
|
|
204
|
+
|
|
63
205
|
counter = {
|
|
64
|
-
get: () => this.request
|
|
65
|
-
increment: () => this.request
|
|
66
|
-
decrement: () => this.request
|
|
67
|
-
reset: () => this.request
|
|
206
|
+
get: (input: Routes.Counter.get.Input): Promise<Routes.Counter.get.Output> => this.request("api.counter.get", input),
|
|
207
|
+
increment: (input: Routes.Counter.increment.Input): Promise<Routes.Counter.increment.Output> => this.request("api.counter.increment", input),
|
|
208
|
+
decrement: (input: Routes.Counter.decrement.Input): Promise<Routes.Counter.decrement.Output> => this.request("api.counter.decrement", input),
|
|
209
|
+
reset: (input: Routes.Counter.reset.Input): Promise<Routes.Counter.reset.Output> => this.request("api.counter.reset", input)
|
|
68
210
|
};
|
|
69
211
|
|
|
70
|
-
// Cache routes
|
|
71
212
|
cache = {
|
|
72
|
-
set: (input:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
delete: (input: { key: string }) =>
|
|
77
|
-
this.request<typeof input, { success: boolean }>("api.cache.delete", input),
|
|
78
|
-
keys: () =>
|
|
79
|
-
this.request<{}, CacheKeysResponse>("api.cache.keys", {}),
|
|
213
|
+
set: (input: Routes.Cache.set.Input): Promise<Routes.Cache.set.Output> => this.request("api.cache.set", input),
|
|
214
|
+
get: (input: Routes.Cache.get.Input): Promise<Routes.Cache.get.Output> => this.request("api.cache.get", input),
|
|
215
|
+
delete: (input: Routes.Cache.delete.Input): Promise<Routes.Cache.delete.Output> => this.request("api.cache.delete", input),
|
|
216
|
+
keys: (input: Routes.Cache.keys.Input): Promise<Routes.Cache.keys.Output> => this.request("api.cache.keys", input)
|
|
80
217
|
};
|
|
81
218
|
|
|
82
|
-
// Jobs routes
|
|
83
219
|
jobs = {
|
|
84
|
-
enqueue: (input:
|
|
85
|
-
|
|
86
|
-
stats: () =>
|
|
87
|
-
this.request<{}, JobStatsResponse>("api.jobs.stats", {}),
|
|
220
|
+
enqueue: (input: Routes.Jobs.enqueue.Input): Promise<Routes.Jobs.enqueue.Output> => this.request("api.jobs.enqueue", input),
|
|
221
|
+
stats: (input: Routes.Jobs.stats.Input): Promise<Routes.Jobs.stats.Output> => this.request("api.jobs.stats", input)
|
|
88
222
|
};
|
|
89
223
|
|
|
90
|
-
// Cron routes
|
|
91
224
|
cron = {
|
|
92
|
-
list: () =>
|
|
93
|
-
this.request<{}, CronListResponse>("api.cron.list", {}),
|
|
225
|
+
list: (input: Routes.Cron.list.Input): Promise<Routes.Cron.list.Output> => this.request("api.cron.list", input)
|
|
94
226
|
};
|
|
95
227
|
|
|
96
|
-
// Rate limiter routes
|
|
97
228
|
ratelimit = {
|
|
98
|
-
check: (input:
|
|
99
|
-
|
|
100
|
-
reset: (input: { key?: string }) =>
|
|
101
|
-
this.request<typeof input, { success: boolean }>("api.ratelimit.reset", input),
|
|
229
|
+
check: (input: Routes.Ratelimit.check.Input): Promise<Routes.Ratelimit.check.Output> => this.request("api.ratelimit.check", input),
|
|
230
|
+
reset: (input: Routes.Ratelimit.reset.Input): Promise<Routes.Ratelimit.reset.Output> => this.request("api.ratelimit.reset", input)
|
|
102
231
|
};
|
|
103
232
|
|
|
104
|
-
// Events routes
|
|
105
233
|
events = {
|
|
106
|
-
emit: (input:
|
|
107
|
-
this.request<typeof input, { success: boolean }>("api.events.emit", input),
|
|
234
|
+
emit: (input: Routes.Events.emit.Input): Promise<Routes.Events.emit.Output> => this.request("api.events.emit", input)
|
|
108
235
|
};
|
|
109
236
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.request<typeof input, { success: boolean }>("api.sse.broadcast", input),
|
|
114
|
-
clients: () =>
|
|
115
|
-
this.request<{}, SSEClientsResponse>("api.sse.clients", {}),
|
|
237
|
+
sse = {
|
|
238
|
+
broadcast: (input: Routes.Sse.broadcast.Input): Promise<Routes.Sse.broadcast.Output> => this.request("api.sse.broadcast", input),
|
|
239
|
+
clients: (input: Routes.Sse.clients.Input): Promise<Routes.Sse.clients.Output> => this.request("api.sse.clients", input)
|
|
116
240
|
};
|
|
117
241
|
}
|
|
118
242
|
|
|
119
243
|
/**
|
|
120
244
|
* Create an API client instance
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* // In +page.server.ts (SSR - direct calls)
|
|
124
|
-
* const api = createApi({ locals });
|
|
125
|
-
* const data = await api.counter.get();
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* // In +page.svelte (browser - HTTP calls)
|
|
129
|
-
* const api = createApi();
|
|
130
|
-
* const data = await api.counter.get();
|
|
131
245
|
*/
|
|
132
|
-
export function createApi(options?:
|
|
246
|
+
export function createApi(options?: ClientOptions) {
|
|
133
247
|
return new ApiClient(options);
|
|
134
248
|
}
|
|
@@ -4,13 +4,13 @@ import { createApi } from '$lib/api';
|
|
|
4
4
|
|
|
5
5
|
export const load: PageServerLoad = async ({ locals }) => {
|
|
6
6
|
// Create API client with locals for direct SSR calls (no HTTP!)
|
|
7
|
-
const
|
|
7
|
+
const client = createApi({ locals });
|
|
8
8
|
|
|
9
9
|
try {
|
|
10
10
|
// Direct service call through typed client
|
|
11
|
-
const
|
|
11
|
+
const result = await client.counter.get({});
|
|
12
12
|
return {
|
|
13
|
-
count,
|
|
13
|
+
count: result.count,
|
|
14
14
|
loadedAt: new Date().toISOString(),
|
|
15
15
|
isSSR: true,
|
|
16
16
|
};
|