@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.
Files changed (2) hide show
  1. package/package.json +67 -0
  2. 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.