@mix-space-lts/api-client 2.4.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/package.json +67 -0
- package/readme.md +281 -0
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mix-space-lts/api-client",
|
|
3
|
+
"version": "2.4.2",
|
|
4
|
+
"description": "A api client for mx-space server@next",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Innei",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"main": "dist/index.cjs",
|
|
15
|
+
"module": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.mts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.mts",
|
|
20
|
+
"require": "./dist/index.cjs",
|
|
21
|
+
"import": "./dist/index.mjs"
|
|
22
|
+
},
|
|
23
|
+
"./dist/*": {
|
|
24
|
+
"require": "./dist/*.cjs",
|
|
25
|
+
"import": "./dist/*.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./dist/adaptors/*": {
|
|
28
|
+
"require": "./dist/adaptors/*.cjs",
|
|
29
|
+
"import": "./dist/adaptors/*.mjs"
|
|
30
|
+
},
|
|
31
|
+
"./package.json": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
"bump": {
|
|
34
|
+
"before": [
|
|
35
|
+
"git pull --rebase",
|
|
36
|
+
"pnpm i",
|
|
37
|
+
"npm run package"
|
|
38
|
+
],
|
|
39
|
+
"after": [
|
|
40
|
+
"npm publish --access=public"
|
|
41
|
+
],
|
|
42
|
+
"tag": false,
|
|
43
|
+
"commit_message": "chore(release): bump @mix-space-lts/api-client to v${NEW_VERSION}"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"package": "rm -rf dist && tsdown",
|
|
47
|
+
"build": "npm run package",
|
|
48
|
+
"prepackage": "rm -rf dist",
|
|
49
|
+
"test": "vitest",
|
|
50
|
+
"dev": "vitest"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/cors": "2.8.19",
|
|
54
|
+
"@types/express": "5.0.6",
|
|
55
|
+
"abort-controller": "3.0.0",
|
|
56
|
+
"axios": "^1.13.3",
|
|
57
|
+
"camelcase-keys": "^10.0.2",
|
|
58
|
+
"cors": "2.8.6",
|
|
59
|
+
"es-toolkit": "1.45.0",
|
|
60
|
+
"express": "4.21.2",
|
|
61
|
+
"form-data": "4.0.5",
|
|
62
|
+
"tsdown": "0.21.0-beta.2",
|
|
63
|
+
"umi-request": "1.4.0",
|
|
64
|
+
"vite": "^7.3.1",
|
|
65
|
+
"vitest": "4.0.18"
|
|
66
|
+
}
|
|
67
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# @mx-space/api-client
|
|
2
|
+
|
|
3
|
+
A framework-agnostic TypeScript/JavaScript SDK for the MX Space server (MServer v3). It wraps common API endpoints with typed request methods and response types for fast frontend and server-side integration.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Requirements](#requirements)
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Quick Start](#quick-start)
|
|
12
|
+
- [Architecture](#architecture)
|
|
13
|
+
- [Adapters](#adapters)
|
|
14
|
+
- [Controllers](#controllers)
|
|
15
|
+
- [Client Options](#client-options)
|
|
16
|
+
- [Proxy API](#proxy-api)
|
|
17
|
+
- [Version Compatibility & Migration](#version-compatibility--migration)
|
|
18
|
+
- [Development](#development)
|
|
19
|
+
- [License](#license)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
- **Node.js** ≥ 22 (see `engines` in `package.json`)
|
|
26
|
+
- **MX Space server** v10+ for api-client v2.x (Better Auth); v9 or below use api-client v1.x
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
From the monorepo root (recommended):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @mx-space/api-client
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or with npm:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @mx-space/api-client
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The package is **framework-agnostic** and does not bundle a specific HTTP client. You must provide an adapter (e.g. Axios or fetch). Install the HTTP library you use:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm add axios
|
|
48
|
+
# or use the built-in fetch adapter (no extra install)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
1. **Create a client** with an endpoint and an adapter.
|
|
56
|
+
2. **Inject controllers** you need (tree-shakeable).
|
|
57
|
+
3. **Call methods** on the client (e.g. `client.post`, `client.note`).
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import {
|
|
61
|
+
createClient,
|
|
62
|
+
PostController,
|
|
63
|
+
NoteController,
|
|
64
|
+
AggregateController,
|
|
65
|
+
CategoryController,
|
|
66
|
+
} from '@mx-space/api-client'
|
|
67
|
+
import { axiosAdaptor } from '@mx-space/api-client/adaptors/axios'
|
|
68
|
+
|
|
69
|
+
const endpoint = 'https://api.example.com/v2'
|
|
70
|
+
const client = createClient(axiosAdaptor)(endpoint)
|
|
71
|
+
|
|
72
|
+
client.injectControllers([
|
|
73
|
+
PostController,
|
|
74
|
+
NoteController,
|
|
75
|
+
AggregateController,
|
|
76
|
+
CategoryController,
|
|
77
|
+
])
|
|
78
|
+
|
|
79
|
+
// Typed API calls
|
|
80
|
+
const posts = await client.post.post.getList(1, 10, { year: 2024 })
|
|
81
|
+
const aggregate = await client.aggregate.getAggregateData()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Optional: set token and interceptors** (example with Axios):
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const $axios = axiosAdaptor.default
|
|
88
|
+
$axios.defaults.timeout = 10000
|
|
89
|
+
$axios.interceptors.request.use((config) => {
|
|
90
|
+
const token = getToken()
|
|
91
|
+
if (token) config.headers!.Authorization = `bearer ${token}`
|
|
92
|
+
return config
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Architecture
|
|
99
|
+
|
|
100
|
+
- **Core**: `HTTPClient` in `core/client.ts` — builds a route proxy and delegates HTTP calls to an adapter.
|
|
101
|
+
- **Adapters**: Implement `IRequestAdapter` (get/post/put/patch/delete + optional `default` client). Responses are normalized to `{ data }`; optional `transformResponse` (e.g. camelCase) runs on `data`.
|
|
102
|
+
- **Controllers**: Classes that receive the client and attach methods under a name (e.g. `post`, `note`). Controllers are **injected at runtime** so you only bundle what you use.
|
|
103
|
+
- **Proxy**: `client.proxy` allows arbitrary path chains and HTTP methods for endpoints not modeled by a controller (e.g. `client.note.proxy.something.other('123').info.get()`).
|
|
104
|
+
|
|
105
|
+
**Response shape**: The adapter is expected to return a value with a `data` property. By default, `getDataFromResponse` uses `(res) => res.data`, and `transformResponse` converts keys to camelCase. Each returned object gets attached `$raw` (adapter response), `$request` (url, method, options), and `$serialized` (transformed data).
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Adapters
|
|
110
|
+
|
|
111
|
+
Official adapters live under `@mx-space/api-client/adaptors/`:
|
|
112
|
+
|
|
113
|
+
| Adapter | Import path | Notes |
|
|
114
|
+
|----------------|------------------------------------------|--------------------------|
|
|
115
|
+
| **Axios** | `@mx-space/api-client/adaptors/axios` | Exposes `axiosAdaptor.default` (AxiosInstance). |
|
|
116
|
+
| **umi-request**| `@mx-space/api-client/adaptors/umi-request` | For umi-request users. |
|
|
117
|
+
| **Fetch** | `@mx-space/api-client/adaptors/fetch` | Uses global `fetch`; no extra dependency. |
|
|
118
|
+
|
|
119
|
+
**Custom adapter**: Implement `IRequestAdapter` from `@mx-space/api-client` (methods: `get`, `post`, `put`, `patch`, `delete`; optional `default`). See `src/adaptors/axios.ts` and `src/adaptors/umi-request.ts` for reference.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Controllers
|
|
124
|
+
|
|
125
|
+
Inject one or more controllers so the client exposes them (e.g. `client.post`, `client.note`). Use `allControllers` to inject everything, or list only what you need for smaller bundles.
|
|
126
|
+
|
|
127
|
+
| Controller | Client name | Purpose (high level) |
|
|
128
|
+
|-------------|---------------|-----------------------------|
|
|
129
|
+
| PostController | `post` | Blog posts |
|
|
130
|
+
| NoteController | `note` | Notes / private posts |
|
|
131
|
+
| PageController | `page` | Pages |
|
|
132
|
+
| CategoryController | `category` | Categories |
|
|
133
|
+
| AggregateController | `aggregate` | Site aggregate data |
|
|
134
|
+
| CommentController | `comment` | Comments |
|
|
135
|
+
| UserController (owner) | `owner` | Auth, session, login, OAuth |
|
|
136
|
+
| SayController | `say` | Says / short notes |
|
|
137
|
+
| LinkController | `link` | Links |
|
|
138
|
+
| SnippetController| `snippet` | Snippets |
|
|
139
|
+
| ProjectController | `project` | Projects |
|
|
140
|
+
| TopicController | `topic` | Topics |
|
|
141
|
+
| RecentlyController | `recently` | Recently items |
|
|
142
|
+
| SearchController | `search` | Search |
|
|
143
|
+
| ActivityController| `activity`| Activity |
|
|
144
|
+
| AIController | `ai` | AI-related endpoints |
|
|
145
|
+
| SubscribeController | `subscribe` | Subscriptions |
|
|
146
|
+
| ServerlessController | `serverless` | Serverless functions |
|
|
147
|
+
| AckController | `ack` | Ack |
|
|
148
|
+
|
|
149
|
+
**Example — inject all controllers:**
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { createClient, allControllers } from '@mx-space/api-client'
|
|
153
|
+
import { axiosAdaptor } from '@mx-space/api-client/adaptors/axios'
|
|
154
|
+
|
|
155
|
+
const client = createClient(axiosAdaptor)('https://api.example.com/v2')
|
|
156
|
+
client.injectControllers(allControllers)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Why inject manually?** To keep bundle size small (tree-shaking) and to avoid pulling in a specific HTTP library by default.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Client Options
|
|
164
|
+
|
|
165
|
+
`createClient(adapter)(endpoint, options)` accepts optional second argument:
|
|
166
|
+
|
|
167
|
+
| Option | Description |
|
|
168
|
+
|----------------------------|-------------|
|
|
169
|
+
| `controllers` | Array of controller classes to inject immediately. |
|
|
170
|
+
| `transformResponse` | `(data) => transformed`. Default: camelCase keys. |
|
|
171
|
+
| `getDataFromResponse` | `(response) => data`. Default: `(res) => res.data`. |
|
|
172
|
+
| `getCodeMessageFromException` | `(error) => { message?, code? }` for custom error parsing. |
|
|
173
|
+
| `customThrowResponseError` | `(error) => Error` to throw a custom error type. |
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Proxy API
|
|
178
|
+
|
|
179
|
+
For paths not covered by a controller, use the **proxy** to build URLs and perform requests:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
// GET /notes/something/other/123456/info
|
|
183
|
+
const data = await client.note.proxy.something.other('123456').info.get()
|
|
184
|
+
|
|
185
|
+
// Get path only (no request)
|
|
186
|
+
client.note.proxy.something.other('123456').info.toString()
|
|
187
|
+
// => '/notes/something/other/123456/info'
|
|
188
|
+
|
|
189
|
+
// Full URL (with base endpoint)
|
|
190
|
+
client.note.proxy.something.other('123456').info.toString(true)
|
|
191
|
+
// => 'https://api.example.com/v2/notes/something/other/123456/info'
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Version Compatibility & Migration
|
|
197
|
+
|
|
198
|
+
### Compatibility
|
|
199
|
+
|
|
200
|
+
| api-client version | Server version | Notes |
|
|
201
|
+
|--------------------|----------------|-------|
|
|
202
|
+
| v2.x | ≥ 10 | Better Auth; owner API; new auth endpoints. |
|
|
203
|
+
| v1.x | ≤ 9 | Legacy auth. |
|
|
204
|
+
|
|
205
|
+
v2 introduces breaking changes; see migration below.
|
|
206
|
+
|
|
207
|
+
### Migrating to v2
|
|
208
|
+
|
|
209
|
+
**1. Controller renames**
|
|
210
|
+
|
|
211
|
+
- `user` / `master` → `owner`. Use `client.owner` for auth and owner info.
|
|
212
|
+
|
|
213
|
+
```diff
|
|
214
|
+
- client.user.getMasterInfo()
|
|
215
|
+
- client.master.getMasterInfo()
|
|
216
|
+
+ client.owner.getOwnerInfo()
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**2. Login**
|
|
220
|
+
|
|
221
|
+
- Endpoint: `POST /master/login` → `POST /auth/sign-in`.
|
|
222
|
+
- v2 `login` returns `{ token, user }`.
|
|
223
|
+
|
|
224
|
+
```diff
|
|
225
|
+
- client.user.login(username, password)
|
|
226
|
+
+ client.owner.login(username, password, { rememberMe: boolean })
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**3. New auth-related APIs (v2)**
|
|
230
|
+
|
|
231
|
+
- `client.owner.getSession()`
|
|
232
|
+
- `client.owner.getAuthSession()`
|
|
233
|
+
- `client.owner.logout()`
|
|
234
|
+
- `client.owner.getAllowLoginMethods()`
|
|
235
|
+
- `client.owner.getProviders()`
|
|
236
|
+
- `client.owner.listSessions()`
|
|
237
|
+
- `client.owner.revokeSession(token)` / `revokeSessions()` / `revokeOtherSessions()`
|
|
238
|
+
|
|
239
|
+
### Migrating from v2 to v1 (downgrade)
|
|
240
|
+
|
|
241
|
+
- No re-export of `camelcase-keys`. Use the built-in helper or install yourself:
|
|
242
|
+
|
|
243
|
+
```diff
|
|
244
|
+
- import { camelcaseKeysDeep, camelcaseKeys } from '@mx-space/api-client'
|
|
245
|
+
+ import { simpleCamelcaseKeys as camelcaseKeysDeep } from '@mx-space/api-client'
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Development
|
|
251
|
+
|
|
252
|
+
**From repo root:**
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pnpm i
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**From `packages/api-client`:**
|
|
259
|
+
|
|
260
|
+
- **Build**: `pnpm run package` or `pnpm run build` (cleans `dist`, runs `tsdown`).
|
|
261
|
+
- **Test**: `pnpm test` (Vitest).
|
|
262
|
+
- **Dev (watch tests)**: `pnpm run dev`.
|
|
263
|
+
|
|
264
|
+
**Project layout (high level):**
|
|
265
|
+
|
|
266
|
+
- `core/` — client, request attachment, error type.
|
|
267
|
+
- `controllers/` — one class per API area; names listed in `controllers/index.ts`.
|
|
268
|
+
- `adaptors/` — axios, umi-request, fetch.
|
|
269
|
+
- `models/`, `dtos/`, `interfaces/` — types and DTOs for requests/responses.
|
|
270
|
+
- `utils/` — path resolution, camelCase, auto-bind.
|
|
271
|
+
|
|
272
|
+
**Exports:**
|
|
273
|
+
|
|
274
|
+
- Main: `createClient`, `RequestError`, controllers, models, DTOs, `simpleCamelcaseKeys`, `HTTPClient` type, `IRequestAdapter` type.
|
|
275
|
+
- Adapters: `@mx-space/api-client/adaptors/axios`, `/adaptors/umi-request`, `/adaptors/fetch`.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT.
|