@questpie/elysia 0.0.1 → 1.0.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.
- package/README.md +54 -54
- package/dist/client.mjs +2 -2
- package/package.json +9 -2
- package/.turbo/turbo-build.log +0 -16
- package/.turbo/turbo-check-types.log +0 -1
- package/CHANGELOG.md +0 -9
- package/src/client.ts +0 -86
- package/src/server.ts +0 -93
- package/tsconfig.json +0 -5
- package/tsconfig.tsbuildinfo +0 -1
- package/tsdown.config.ts +0 -10
package/README.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# @questpie/elysia
|
|
2
2
|
|
|
3
|
-
Elysia adapter for QUESTPIE
|
|
3
|
+
Elysia adapter for QUESTPIE with full end-to-end type safety using Eden Treaty.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
7
|
+
- **Full Type Safety**: End-to-end type safety using Elysia's Eden Treaty
|
|
8
|
+
- **High Performance**: Built on Elysia's blazing-fast framework
|
|
9
|
+
- **Auto-complete**: IntelliSense for all CMS routes and methods
|
|
10
|
+
- **Zero Config**: Works out of the box with minimal setup
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @questpie/elysia
|
|
15
|
+
bun add @questpie/elysia questpie elysia
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Quick Start
|
|
@@ -24,11 +24,11 @@ import { Elysia } from "elysia";
|
|
|
24
24
|
import { questpieElysia } from "@questpie/elysia";
|
|
25
25
|
import { cms } from "./cms";
|
|
26
26
|
|
|
27
|
-
const app = new Elysia()
|
|
28
|
-
.use(questpieElysia(cms))
|
|
29
|
-
.listen(3000);
|
|
27
|
+
const app = new Elysia().use(questpieElysia(cms)).listen(3000);
|
|
30
28
|
|
|
31
|
-
console.log(
|
|
29
|
+
console.log(
|
|
30
|
+
`Server running at http://${app.server?.hostname}:${app.server?.port}`,
|
|
31
|
+
);
|
|
32
32
|
|
|
33
33
|
// Export type for Eden Treaty client
|
|
34
34
|
export type App = typeof app;
|
|
@@ -43,13 +43,13 @@ import type { App } from "./server";
|
|
|
43
43
|
|
|
44
44
|
// IMPORTANT: Use `typeof cms` directly (not a type alias) for proper type inference
|
|
45
45
|
const client = createClientFromEden<App, typeof cms>({
|
|
46
|
-
|
|
46
|
+
server: "localhost:3000",
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// Use CMS CRUD operations (fully typed!)
|
|
50
50
|
const posts = await client.collections.posts.find({ limit: 10 });
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// Use Eden Treaty for custom routes (fully type-safe!)
|
|
53
53
|
const result = await client.api.custom.route.get();
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -63,13 +63,13 @@ import { questpieElysia } from "@questpie/elysia";
|
|
|
63
63
|
import { cms } from "./cms";
|
|
64
64
|
|
|
65
65
|
const app = new Elysia().use(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
questpieElysia(cms, {
|
|
67
|
+
basePath: "/cms-api", // Default: '/cms'
|
|
68
|
+
cors: {
|
|
69
|
+
origin: "https://example.com",
|
|
70
|
+
credentials: true,
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
73
|
);
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -77,9 +77,9 @@ const app = new Elysia().use(
|
|
|
77
77
|
|
|
78
78
|
```typescript
|
|
79
79
|
const app = new Elysia().use(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
questpieElysia(cms, {
|
|
81
|
+
cors: false, // Disable CORS middleware
|
|
82
|
+
}),
|
|
83
83
|
);
|
|
84
84
|
```
|
|
85
85
|
|
|
@@ -120,23 +120,23 @@ import type { App } from "./server";
|
|
|
120
120
|
|
|
121
121
|
// IMPORTANT: Use `typeof cms` directly for proper type inference
|
|
122
122
|
const client = createClientFromEden<App, typeof cms>({
|
|
123
|
-
|
|
123
|
+
server: "localhost:3000",
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
// CMS CRUD operations (fully typed with autocomplete!)
|
|
127
127
|
const posts = await client.collections.posts.find({
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
where: { published: true },
|
|
129
|
+
limit: 10,
|
|
130
|
+
orderBy: { createdAt: "desc" },
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
const newPost = await client.collections.posts.create({
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
title: "New Post",
|
|
135
|
+
content: "Content here",
|
|
136
136
|
});
|
|
137
137
|
|
|
138
138
|
const updated = await client.collections.posts.update("123", {
|
|
139
|
-
|
|
139
|
+
title: "Updated Title",
|
|
140
140
|
});
|
|
141
141
|
|
|
142
142
|
await client.collections.posts.delete("123");
|
|
@@ -146,11 +146,11 @@ await client.collections.posts.delete("123");
|
|
|
146
146
|
|
|
147
147
|
```typescript
|
|
148
148
|
const post = await client.collections.posts.findOne({
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
where: { id: "123" },
|
|
150
|
+
with: {
|
|
151
|
+
author: true,
|
|
152
|
+
comments: true,
|
|
153
|
+
},
|
|
154
154
|
});
|
|
155
155
|
```
|
|
156
156
|
|
|
@@ -159,14 +159,14 @@ const post = await client.collections.posts.findOne({
|
|
|
159
159
|
```typescript
|
|
160
160
|
// Custom business logic routes are fully type-safe!
|
|
161
161
|
const availability = await client.api.barbers[":id"].availability.get({
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
params: { id: "barber-123" },
|
|
163
|
+
query: { date: "2025-01-15" },
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
const booking = await client.api.appointments.book.post({
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
barberId: "123",
|
|
168
|
+
serviceId: "456",
|
|
169
|
+
scheduledAt: "2025-01-15T10:00:00Z",
|
|
170
170
|
});
|
|
171
171
|
```
|
|
172
172
|
|
|
@@ -181,15 +181,15 @@ const asset = await client.api.storage.upload.post(formData);
|
|
|
181
181
|
|
|
182
182
|
## Generic HTTP Client
|
|
183
183
|
|
|
184
|
-
If you prefer a generic HTTP client (not Eden Treaty), use the shared client from
|
|
184
|
+
If you prefer a generic HTTP client (not Eden Treaty), use the shared client from `questpie`:
|
|
185
185
|
|
|
186
186
|
```typescript
|
|
187
|
-
import {
|
|
187
|
+
import { createClient } from "questpie/client";
|
|
188
188
|
import type { cms } from "./server";
|
|
189
189
|
|
|
190
|
-
const client =
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
const client = createClient<typeof cms>({
|
|
191
|
+
baseURL: "http://localhost:3000",
|
|
192
|
+
basePath: "/cms",
|
|
193
193
|
});
|
|
194
194
|
|
|
195
195
|
// Still type-safe but uses fetch under the hood
|
|
@@ -207,13 +207,13 @@ import type { App } from "./server";
|
|
|
207
207
|
|
|
208
208
|
// Use `typeof cms` directly (not type alias!)
|
|
209
209
|
const client = createClientFromEden<App, typeof cms>({
|
|
210
|
-
|
|
210
|
+
server: "localhost:3000",
|
|
211
211
|
});
|
|
212
212
|
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
//
|
|
213
|
+
// Fully type-safe end-to-end
|
|
214
|
+
// Auto-complete for all routes and collections
|
|
215
|
+
// Runtime type checking
|
|
216
|
+
// CMS CRUD + custom routes in one client
|
|
217
217
|
const posts = await client.collections.posts.find();
|
|
218
218
|
const custom = await client.api.custom.route.get();
|
|
219
219
|
```
|
|
@@ -226,12 +226,12 @@ import type { AppType } from "./server";
|
|
|
226
226
|
import type { cms } from "./cms";
|
|
227
227
|
|
|
228
228
|
const client = createClientFromHono<AppType, typeof cms>({
|
|
229
|
-
|
|
229
|
+
baseURL: "http://localhost:3000",
|
|
230
230
|
});
|
|
231
231
|
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
232
|
+
// Limited type safety for custom routes
|
|
233
|
+
// Good CMS CRUD type safety
|
|
234
|
+
// Single unified client
|
|
235
235
|
const posts = await client.collections.posts.find();
|
|
236
236
|
const custom = await client.api.custom.route.$get();
|
|
237
237
|
```
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { treaty } from "@elysiajs/eden";
|
|
2
|
-
import {
|
|
2
|
+
import { createClient } from "questpie/client";
|
|
3
3
|
|
|
4
4
|
//#region src/client.ts
|
|
5
5
|
/**
|
|
@@ -24,7 +24,7 @@ import { createQuestpieClient } from "questpie/client";
|
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
26
|
function createClientFromEden(config) {
|
|
27
|
-
const cmsClient =
|
|
27
|
+
const cmsClient = createClient({
|
|
28
28
|
baseURL: config.server.startsWith("http") ? config.server : `http://${config.server}`,
|
|
29
29
|
fetch: config.fetch,
|
|
30
30
|
basePath: config.basePath,
|
package/package.json
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@questpie/elysia",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/questpie/questpie-cms.git",
|
|
8
|
+
"directory": "packages/elysia"
|
|
9
|
+
},
|
|
5
10
|
"scripts": {
|
|
6
11
|
"build": "tsdown",
|
|
7
12
|
"check-types": "tsc --noEmit"
|
|
8
13
|
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
9
17
|
"dependencies": {
|
|
10
18
|
"@elysiajs/cors": "^1.2.1",
|
|
11
19
|
"@elysiajs/eden": "^1.2.6",
|
|
@@ -14,7 +22,6 @@
|
|
|
14
22
|
"qs": "^6.13.1"
|
|
15
23
|
},
|
|
16
24
|
"devDependencies": {
|
|
17
|
-
"@questpie/typescript-config": "workspace:*",
|
|
18
25
|
"@types/qs": "^6.9.17",
|
|
19
26
|
"bun-types": "latest",
|
|
20
27
|
"tsdown": "^0.18.3"
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
[0m[2m[35m$[0m [2m[1mtsdown[0m
|
|
3
|
-
[34mℹ[39m tsdown [2mv0.18.4[22m powered by rolldown [2mv1.0.0-beta.57[22m
|
|
4
|
-
[34mℹ[39m config file: [4m/Users/drepkovsky/questpie/repos/questpie-cms/packages/elysia/tsdown.config.ts[24m
|
|
5
|
-
(node:61186) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
|
|
6
|
-
(Use `node --trace-warnings ...` to show where the warning was created)
|
|
7
|
-
[34mℹ[39m entry: [34msrc/server.ts, src/client.ts[39m
|
|
8
|
-
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
9
|
-
[34mℹ[39m Build start
|
|
10
|
-
[34mℹ[39m Cleaning 4 files
|
|
11
|
-
[34mℹ[39m [2mdist/[22m[1mserver.mjs[22m [2m1.53 kB[22m [2m│ gzip: 0.73 kB[22m
|
|
12
|
-
[34mℹ[39m [2mdist/[22m[1mclient.mjs[22m [2m1.20 kB[22m [2m│ gzip: 0.56 kB[22m
|
|
13
|
-
[34mℹ[39m [2mdist/[22m[32m[1mserver.d.mts[22m[39m [2m2.54 kB[22m [2m│ gzip: 0.96 kB[22m
|
|
14
|
-
[34mℹ[39m [2mdist/[22m[32m[1mclient.d.mts[22m[39m [2m1.60 kB[22m [2m│ gzip: 0.71 kB[22m
|
|
15
|
-
[34mℹ[39m 4 files, total: 6.86 kB
|
|
16
|
-
[32m✔[39m Build complete in [32m5676ms[39m
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
$ tsc --noEmit
|
package/CHANGELOG.md
DELETED
package/src/client.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { treaty } from "@elysiajs/eden";
|
|
2
|
-
import type { Treaty } from "@elysiajs/eden";
|
|
3
|
-
import { createQuestpieClient, type QuestpieClient } from "questpie/client";
|
|
4
|
-
import type { Questpie } from "questpie";
|
|
5
|
-
import type Elysia from "elysia";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Elysia client configuration
|
|
9
|
-
*/
|
|
10
|
-
export type ElysiaClientConfig = {
|
|
11
|
-
/**
|
|
12
|
-
* Server URL (domain with optional port, no protocol needed for Eden)
|
|
13
|
-
* @example 'localhost:3000'
|
|
14
|
-
* @example 'api.example.com'
|
|
15
|
-
*/
|
|
16
|
-
server: string;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Custom fetch implementation
|
|
20
|
-
* @default globalThis.fetch
|
|
21
|
-
*/
|
|
22
|
-
fetch?: typeof fetch;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Base path for CMS routes
|
|
26
|
-
* @default '/cms'
|
|
27
|
-
*/
|
|
28
|
-
basePath?: string;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Default headers to include in all requests
|
|
32
|
-
*/
|
|
33
|
-
headers?: Record<string, string>;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Create a unified client that combines QUESTPIE CMS CRUD operations
|
|
38
|
-
* with Elysia's native Eden Treaty client for custom routes
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```ts
|
|
42
|
-
* import { createClientFromEden } from '@questpie/elysia/client'
|
|
43
|
-
* import type { App } from './server'
|
|
44
|
-
* import type { AppCMS } from './cms'
|
|
45
|
-
*
|
|
46
|
-
* const client = createClientFromEden<App, AppCMS>({
|
|
47
|
-
* server: 'localhost:3000'
|
|
48
|
-
* })
|
|
49
|
-
*
|
|
50
|
-
* // Use CMS CRUD operations
|
|
51
|
-
* const posts = await client.collections.posts.find({ limit: 10 })
|
|
52
|
-
*
|
|
53
|
-
* // Use Eden Treaty for custom routes (fully type-safe!)
|
|
54
|
-
* const result = await client.api.custom.route.get()
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
export function createClientFromEden<
|
|
58
|
-
TApp extends Elysia<any, any, any, any, any, any, any> = any,
|
|
59
|
-
TCMS extends Questpie<any> = any,
|
|
60
|
-
>(config: ElysiaClientConfig): QuestpieClient<TCMS> & Treaty.Create<TApp> {
|
|
61
|
-
// Determine baseURL with protocol for CMS client
|
|
62
|
-
const baseURL = config.server.startsWith("http")
|
|
63
|
-
? config.server
|
|
64
|
-
: `http://${config.server}`;
|
|
65
|
-
|
|
66
|
-
// Create CMS client for CRUD operations
|
|
67
|
-
const cmsClient = createQuestpieClient<TCMS>({
|
|
68
|
-
baseURL,
|
|
69
|
-
fetch: config.fetch,
|
|
70
|
-
basePath: config.basePath,
|
|
71
|
-
headers: config.headers,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// Create Eden Treaty client for custom routes
|
|
75
|
-
const edenClient = treaty<TApp>(config.server, {
|
|
76
|
-
fetcher: config.fetch,
|
|
77
|
-
headers: config.headers,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Merge both clients
|
|
81
|
-
return {
|
|
82
|
-
...edenClient,
|
|
83
|
-
collections: cmsClient.collections,
|
|
84
|
-
globals: cmsClient.globals,
|
|
85
|
-
} as QuestpieClient<TCMS> & Treaty.Create<TApp>;
|
|
86
|
-
}
|
package/src/server.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { Elysia } from "elysia";
|
|
2
|
-
import { createFetchHandler, type Questpie } from "questpie";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Context stored in Elysia decorator
|
|
6
|
-
*/
|
|
7
|
-
export type QuestpieContext = {
|
|
8
|
-
cms: Questpie<any>;
|
|
9
|
-
cmsContext: Awaited<ReturnType<Questpie<any>["createContext"]>>;
|
|
10
|
-
user: any;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Elysia adapter configuration
|
|
15
|
-
*/
|
|
16
|
-
export type ElysiaAdapterConfig = {
|
|
17
|
-
/**
|
|
18
|
-
* Base path for CMS routes
|
|
19
|
-
* Use '/cms' for server-only apps or '/api/cms' for fullstack apps.
|
|
20
|
-
* @default '/cms'
|
|
21
|
-
*/
|
|
22
|
-
basePath?: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Create Elysia app with QUESTPIE CMS integration
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```ts
|
|
30
|
-
* import { Elysia } from 'elysia'
|
|
31
|
-
* import { questpieElysia } from '@questpie/elysia'
|
|
32
|
-
* import { cms } from './cms'
|
|
33
|
-
*
|
|
34
|
-
* const app = new Elysia()
|
|
35
|
-
* .use(questpieElysia(cms))
|
|
36
|
-
*
|
|
37
|
-
* export default app
|
|
38
|
-
* export type App = typeof app
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* // With custom config
|
|
44
|
-
* const app = new Elysia()
|
|
45
|
-
* .use(questpieElysia(cms, {
|
|
46
|
-
* basePath: '/cms-api',
|
|
47
|
-
* cors: {
|
|
48
|
-
* origin: 'https://example.com',
|
|
49
|
-
* credentials: true
|
|
50
|
-
* }
|
|
51
|
-
* }))
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```ts
|
|
56
|
-
* // Client usage with Eden Treaty
|
|
57
|
-
* import { treaty } from '@elysiajs/eden'
|
|
58
|
-
* import type { App } from './server'
|
|
59
|
-
*
|
|
60
|
-
* const client = treaty<App>('localhost:3000')
|
|
61
|
-
*
|
|
62
|
-
* // Fully type-safe!
|
|
63
|
-
* const posts = await client.cms.posts.get()
|
|
64
|
-
* const post = await client.cms.posts({ id: '123' }).get()
|
|
65
|
-
* const newPost = await client.cms.posts.post({ title: 'Hello' })
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export function questpieElysia(
|
|
69
|
-
cms: Questpie<any>,
|
|
70
|
-
config: ElysiaAdapterConfig = {},
|
|
71
|
-
) {
|
|
72
|
-
const basePath = config.basePath || "/cms";
|
|
73
|
-
const handler = createFetchHandler(cms, {
|
|
74
|
-
basePath,
|
|
75
|
-
accessMode: "user",
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const app = new Elysia({ prefix: basePath, name: "questpie-cms" }).all(
|
|
79
|
-
"/*",
|
|
80
|
-
async ({ request }) => {
|
|
81
|
-
const response = await handler(request);
|
|
82
|
-
return (
|
|
83
|
-
response ??
|
|
84
|
-
new Response(JSON.stringify({ error: "Not found" }), {
|
|
85
|
-
status: 404,
|
|
86
|
-
headers: { "Content-Type": "application/json" },
|
|
87
|
-
})
|
|
88
|
-
);
|
|
89
|
-
},
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
return app;
|
|
93
|
-
}
|