@molecule/app-http 1.0.0 → 1.0.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 +536 -0
- package/package.json +11 -10
package/README.md
ADDED
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
3
|
+
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
|
+
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
|
+
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
+
Generated: 2026-08-04T01:50:58.464Z
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# @molecule/app-http
|
|
10
|
+
|
|
11
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
+
|
|
15
|
+
Client HTTP interface for molecule.dev.
|
|
16
|
+
|
|
17
|
+
Provides a unified HTTP client API that works across different
|
|
18
|
+
HTTP libraries (fetch, axios, ky, etc.).
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// In a React component, get the configured client from context and call it.
|
|
24
|
+
// The hook is exported by the framework binding (@molecule/app-react), not
|
|
25
|
+
// this core package — never construct your own fetch/axios client.
|
|
26
|
+
import { useHttpClient } from '@molecule/app-react'
|
|
27
|
+
|
|
28
|
+
function Plants() {
|
|
29
|
+
const http = useHttpClient()
|
|
30
|
+
const load = async () => {
|
|
31
|
+
const res = await http.get<Plant[]>('/plants') // baseURL ('/api') is prepended
|
|
32
|
+
setPlants(res.data)
|
|
33
|
+
}
|
|
34
|
+
// http.post(url, body), http.put, http.delete are also available.
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Type
|
|
39
|
+
|
|
40
|
+
`core`
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install @molecule/app-http @molecule/app-bond @molecule/app-i18n @molecule/app-logger
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
### Interfaces
|
|
51
|
+
|
|
52
|
+
#### `FullRequestConfig`
|
|
53
|
+
|
|
54
|
+
Full request configuration including method and URL.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
interface FullRequestConfig extends RequestConfig {
|
|
58
|
+
/**
|
|
59
|
+
* HTTP method.
|
|
60
|
+
*/
|
|
61
|
+
method: HttpMethod
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Request URL (can be relative or absolute).
|
|
65
|
+
*/
|
|
66
|
+
url: string
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Request body data.
|
|
70
|
+
*/
|
|
71
|
+
data?: unknown
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### `HttpClient`
|
|
76
|
+
|
|
77
|
+
HTTP client interface.
|
|
78
|
+
|
|
79
|
+
All HTTP providers must implement this interface.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
interface HttpClient {
|
|
83
|
+
/**
|
|
84
|
+
* Base URL for all requests.
|
|
85
|
+
*/
|
|
86
|
+
baseURL: string
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Default headers for all requests.
|
|
90
|
+
*/
|
|
91
|
+
defaultHeaders: Record<string, string>
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Makes a generic HTTP request.
|
|
95
|
+
*/
|
|
96
|
+
request<T = unknown>(config: FullRequestConfig): Promise<HttpResponse<T>>
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Makes a GET request.
|
|
100
|
+
*/
|
|
101
|
+
get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Makes a POST request.
|
|
105
|
+
*/
|
|
106
|
+
post<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Makes a PUT request.
|
|
110
|
+
*/
|
|
111
|
+
put<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Makes a PATCH request.
|
|
115
|
+
*/
|
|
116
|
+
patch<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Makes a DELETE request.
|
|
120
|
+
*/
|
|
121
|
+
delete<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Adds a request interceptor.
|
|
125
|
+
* Returns a function to remove the interceptor.
|
|
126
|
+
*/
|
|
127
|
+
addRequestInterceptor(interceptor: RequestInterceptor): () => void
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Adds a response interceptor.
|
|
131
|
+
* Returns a function to remove the interceptor.
|
|
132
|
+
*/
|
|
133
|
+
addResponseInterceptor(interceptor: ResponseInterceptor): () => void
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Adds an error interceptor.
|
|
137
|
+
* Returns a function to remove the interceptor.
|
|
138
|
+
*/
|
|
139
|
+
addErrorInterceptor(interceptor: ErrorInterceptor): () => void
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Sets the authorization token.
|
|
143
|
+
*/
|
|
144
|
+
setAuthToken(token: string | null): void
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Returns the current authorization token, or `null` if not set.
|
|
148
|
+
*/
|
|
149
|
+
getAuthToken(): string | null
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Registers a handler for authentication errors (401).
|
|
153
|
+
*
|
|
154
|
+
* @returns An unsubscribe function.
|
|
155
|
+
*/
|
|
156
|
+
onAuthError(handler: () => void): () => void
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### `HttpClientConfig`
|
|
161
|
+
|
|
162
|
+
HTTP client configuration.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface HttpClientConfig {
|
|
166
|
+
/**
|
|
167
|
+
* Base URL for all requests.
|
|
168
|
+
*/
|
|
169
|
+
baseURL?: string
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Default headers for all requests.
|
|
173
|
+
*/
|
|
174
|
+
defaultHeaders?: Record<string, string>
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Default timeout in milliseconds.
|
|
178
|
+
*/
|
|
179
|
+
timeout?: number
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Whether to include credentials by default.
|
|
183
|
+
*/
|
|
184
|
+
withCredentials?: boolean
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### `HttpResponse`
|
|
189
|
+
|
|
190
|
+
Parsed HTTP response with status code, headers, and typed body data.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface HttpResponse<T = unknown> {
|
|
194
|
+
/**
|
|
195
|
+
* Response data.
|
|
196
|
+
*/
|
|
197
|
+
data: T
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* HTTP status code.
|
|
201
|
+
*/
|
|
202
|
+
status: number
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* HTTP status text.
|
|
206
|
+
*/
|
|
207
|
+
statusText: string
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Response headers.
|
|
211
|
+
*/
|
|
212
|
+
headers: Record<string, string>
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Original request config.
|
|
216
|
+
*/
|
|
217
|
+
config: FullRequestConfig
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### `RequestConfig`
|
|
222
|
+
|
|
223
|
+
HTTP request options (headers, query params, timeout, credentials, response type, abort signal).
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
interface RequestConfig {
|
|
227
|
+
/**
|
|
228
|
+
* Request headers.
|
|
229
|
+
*/
|
|
230
|
+
headers?: Record<string, string>
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Query parameters.
|
|
234
|
+
*/
|
|
235
|
+
params?: Record<string, string | number | boolean | undefined>
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Request timeout in milliseconds.
|
|
239
|
+
*/
|
|
240
|
+
timeout?: number
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Whether to include credentials (cookies).
|
|
244
|
+
*/
|
|
245
|
+
withCredentials?: boolean
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Response type.
|
|
249
|
+
*/
|
|
250
|
+
responseType?: 'json' | 'text' | 'blob' | 'arraybuffer'
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Abort signal for cancellation.
|
|
254
|
+
*/
|
|
255
|
+
signal?: AbortSignal
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Request body data.
|
|
259
|
+
*/
|
|
260
|
+
data?: unknown
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Custom request options (implementation-specific).
|
|
264
|
+
*/
|
|
265
|
+
options?: Record<string, unknown>
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Types
|
|
270
|
+
|
|
271
|
+
#### `ErrorInterceptor`
|
|
272
|
+
|
|
273
|
+
Intercepts HTTP errors to transform, retry, or rethrow them.
|
|
274
|
+
Throwing from this interceptor propagates the error to the caller.
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
type ErrorInterceptor = (error: HttpError) => HttpError | Promise<HttpError> | never
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### `HttpMethod`
|
|
281
|
+
|
|
282
|
+
HTTP request method.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### `RequestInterceptor`
|
|
289
|
+
|
|
290
|
+
Intercepts outgoing requests to modify headers, URL, or body
|
|
291
|
+
before the request is sent.
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
type RequestInterceptor = (
|
|
295
|
+
config: FullRequestConfig,
|
|
296
|
+
) => FullRequestConfig | Promise<FullRequestConfig>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### `ResponseInterceptor`
|
|
300
|
+
|
|
301
|
+
Intercepts incoming responses to transform data, check status,
|
|
302
|
+
or perform side effects before the response reaches the caller.
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
type ResponseInterceptor<T = unknown> = (
|
|
306
|
+
response: HttpResponse<T>,
|
|
307
|
+
) => HttpResponse<T> | Promise<HttpResponse<T>>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Classes
|
|
311
|
+
|
|
312
|
+
#### `HttpError`
|
|
313
|
+
|
|
314
|
+
HTTP error with response details.
|
|
315
|
+
|
|
316
|
+
### Functions
|
|
317
|
+
|
|
318
|
+
#### `createFetchClient(config)`
|
|
319
|
+
|
|
320
|
+
Creates a fetch-based HTTP client using the native Fetch API.
|
|
321
|
+
|
|
322
|
+
Supports request/response/error interceptors, automatic JSON
|
|
323
|
+
serialization, auth token injection, timeout via AbortController,
|
|
324
|
+
and 401 error handler hooks.
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
function createFetchClient(config?: HttpClientConfig): HttpClient
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
- `config` — Client configuration including baseURL, default headers, timeout, and credentials.
|
|
331
|
+
|
|
332
|
+
**Returns:** A fully configured `HttpClient` instance.
|
|
333
|
+
|
|
334
|
+
#### `del(url, config)`
|
|
335
|
+
|
|
336
|
+
Makes a DELETE request using the bonded HTTP client.
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
function del(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
- `url` — The request URL.
|
|
343
|
+
- `config` — Optional request configuration.
|
|
344
|
+
|
|
345
|
+
**Returns:** The HTTP response with typed data.
|
|
346
|
+
|
|
347
|
+
#### `get(url, config)`
|
|
348
|
+
|
|
349
|
+
Makes a GET request using the bonded HTTP client.
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
function get(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
- `url` — The request URL (relative to baseURL if configured).
|
|
356
|
+
- `config` — Optional request configuration (headers, params, timeout).
|
|
357
|
+
|
|
358
|
+
**Returns:** The HTTP response with typed data.
|
|
359
|
+
|
|
360
|
+
#### `getClient()`
|
|
361
|
+
|
|
362
|
+
Retrieves the bonded HTTP client. If none is bonded, automatically
|
|
363
|
+
creates a default fetch-based client.
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
function getClient(): HttpClient
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Returns:** The active HTTP client instance.
|
|
370
|
+
|
|
371
|
+
#### `patch(url, data, config)`
|
|
372
|
+
|
|
373
|
+
Makes a PATCH request using the bonded HTTP client.
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
function patch(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
- `url` — The request URL.
|
|
380
|
+
- `data` — The request body (partial update).
|
|
381
|
+
- `config` — Optional request configuration.
|
|
382
|
+
|
|
383
|
+
**Returns:** The HTTP response with typed data.
|
|
384
|
+
|
|
385
|
+
#### `post(url, data, config)`
|
|
386
|
+
|
|
387
|
+
Makes a POST request using the bonded HTTP client.
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
function post(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
- `url` — The request URL.
|
|
394
|
+
- `data` — The request body.
|
|
395
|
+
- `config` — Optional request configuration.
|
|
396
|
+
|
|
397
|
+
**Returns:** The HTTP response with typed data.
|
|
398
|
+
|
|
399
|
+
#### `put(url, data, config)`
|
|
400
|
+
|
|
401
|
+
Makes a PUT request using the bonded HTTP client.
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
function put(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
- `url` — The request URL.
|
|
408
|
+
- `data` — The request body.
|
|
409
|
+
- `config` — Optional request configuration.
|
|
410
|
+
|
|
411
|
+
**Returns:** The HTTP response with typed data.
|
|
412
|
+
|
|
413
|
+
#### `setClient(client)`
|
|
414
|
+
|
|
415
|
+
Registers an HTTP client as the active singleton.
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
function setClient(client: HttpClient): void
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
- `client` — The HTTP client implementation to bond.
|
|
422
|
+
|
|
423
|
+
#### `unwrapList(res)`
|
|
424
|
+
|
|
425
|
+
Normalize an unknown response body into a typed array.
|
|
426
|
+
|
|
427
|
+
Accepts:
|
|
428
|
+
|
|
429
|
+
- a bare array → returned as-is (cast)
|
|
430
|
+
- `{ data: T[] }` envelope → the inner array
|
|
431
|
+
- `HttpResponse<T[]>` (i.e. `{ data: T[], status, ... }`) → the inner array
|
|
432
|
+
- `HttpResponse<{ data: T[] }>` (the response of an envelope-returning
|
|
433
|
+
endpoint as it arrives from `@molecule/app-http`'s `HttpClient`) → the
|
|
434
|
+
doubly-nested inner array
|
|
435
|
+
- `HttpResponse<{ data: T[], total, limit, offset }>` (a RICH pagination
|
|
436
|
+
envelope from a pre-built `@molecule/api-resource-*` list endpoint) → the
|
|
437
|
+
inner `data` array (the numeric `total`/`limit`/`offset` make the shape
|
|
438
|
+
unambiguous, so callers can pass the whole HttpResponse and still get the rows)
|
|
439
|
+
- anything else → `[]`
|
|
440
|
+
|
|
441
|
+
Callers commonly pass either the raw JSON body (e.g. from `fetch().then(r =>
|
|
442
|
+
r.json())`) or the `HttpResponse` returned by `useHttpClient().get(...)`.
|
|
443
|
+
Both shapes are handled here so pages don't have to remember to call
|
|
444
|
+
`unwrapList(res.data)` vs `unwrapList(res)`.
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
function unwrapList(res: unknown): T[]
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
- `res` — Raw response body OR an `HttpResponse` envelope from `@molecule/app-http`.
|
|
451
|
+
|
|
452
|
+
**Returns:** A typed array `T[]`; never `null`/`undefined`.
|
|
453
|
+
|
|
454
|
+
#### `unwrapSingle(res)`
|
|
455
|
+
|
|
456
|
+
Normalize an unknown response body into a single typed resource.
|
|
457
|
+
|
|
458
|
+
Accepts:
|
|
459
|
+
|
|
460
|
+
- a non-empty plain object → returned as-is (cast)
|
|
461
|
+
- `{ data: T }` envelope → the inner value
|
|
462
|
+
- `{ data: null }`, `{ data: undefined }`, `{ data: [] }`, or
|
|
463
|
+
`{ data: {} }` (mock-server's no-match shape) → `null`
|
|
464
|
+
- an empty object `{}` → `null`
|
|
465
|
+
- arrays, primitives, `null`, `undefined` → `null`
|
|
466
|
+
|
|
467
|
+
The "envelope contains an array → null" branch handles the case
|
|
468
|
+
where the mock server returns `[]` for unmatched endpoints but the
|
|
469
|
+
caller expects a single resource.
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
function unwrapSingle(res: unknown): T | null
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
- `res` — Raw response body (e.g. `HttpResponse.data` from `@molecule/app-http`).
|
|
476
|
+
|
|
477
|
+
**Returns:** The typed resource `T`, or `null` when the response shape indicates "no resource" (including the various empty envelopes above).
|
|
478
|
+
|
|
479
|
+
### Constants
|
|
480
|
+
|
|
481
|
+
#### `fetchClient`
|
|
482
|
+
|
|
483
|
+
Pre-created fetch client for environments where `fetch` is available.
|
|
484
|
+
`null` in environments without a global `fetch`.
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
const fetchClient: HttpClient | null
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## Available Providers
|
|
491
|
+
|
|
492
|
+
| Provider | Package |
|
|
493
|
+
| -------- | -------------------------- |
|
|
494
|
+
| Axios | `@molecule/app-http-axios` |
|
|
495
|
+
|
|
496
|
+
## Injection Notes
|
|
497
|
+
|
|
498
|
+
### Requirements
|
|
499
|
+
|
|
500
|
+
Peer dependencies:
|
|
501
|
+
|
|
502
|
+
- `@molecule/app-bond` ^1.0.1
|
|
503
|
+
- `@molecule/app-i18n` ^1.0.1
|
|
504
|
+
- `@molecule/app-logger` ^1.0.1
|
|
505
|
+
|
|
506
|
+
### Runtime Dependencies
|
|
507
|
+
|
|
508
|
+
- `@molecule/app-bond`
|
|
509
|
+
- `@molecule/app-i18n`
|
|
510
|
+
- `@molecule/app-logger`
|
|
511
|
+
|
|
512
|
+
Make ALL API calls through this client (via the framework hook `useHttpClient()` in
|
|
513
|
+
React / the Vue composable) — it carries the configured `baseURL`, auth headers, and
|
|
514
|
+
interceptors. Do NOT call `fetch()` / `axios` directly in components — that bypasses auth
|
|
515
|
+
|
|
516
|
+
- base-URL config and breaks when the transport is swapped.
|
|
517
|
+
|
|
518
|
+
Two mistakes that break in preview/production (seen in real imported apps):
|
|
519
|
+
|
|
520
|
+
- **Pass RELATIVE paths; never a hardcoded host.** Use `'/plants'` (the `baseURL` `'/api'`
|
|
521
|
+
is prepended), NOT `'/api/plants'`, and NEVER an absolute dev URL like
|
|
522
|
+
`'http://localhost:4000/api/…'`. A hardcoded `localhost`/host works on the author's
|
|
523
|
+
machine, then fails cross-origin (CORS) in the preview and points at the wrong server in
|
|
524
|
+
production. The base URL is configured ONCE (via `setClient`), not per call.
|
|
525
|
+
- **The client is PUBLIC — never put a secret in it.** Anything the browser sends (an API
|
|
526
|
+
key, a service-role / `sk_…` key, a signing secret) is visible to every user. Secrets
|
|
527
|
+
stay in YOUR API; the browser calls your API and the API uses the secret server-side.
|
|
528
|
+
Only a publishable/public key may ever be client-side.
|
|
529
|
+
|
|
530
|
+
Auth (the bearer token / session cookie) is attached by the client's interceptors — do not
|
|
531
|
+
read a token from `localStorage` or hand-attach it (the token is memory-only; see the user
|
|
532
|
+
resource).
|
|
533
|
+
|
|
534
|
+
## Translations
|
|
535
|
+
|
|
536
|
+
Translation strings are provided by `@molecule/app-locales-http`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-http",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Client HTTP interface for molecule.dev",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
21
22
|
],
|
|
22
23
|
"keywords": [
|
|
23
24
|
"molecule",
|
|
@@ -27,24 +28,24 @@
|
|
|
27
28
|
],
|
|
28
29
|
"license": "Apache-2.0",
|
|
29
30
|
"peerDependencies": {
|
|
30
|
-
"@molecule/app-bond": "^1.0.
|
|
31
|
-
"@molecule/app-i18n": "^1.0.
|
|
32
|
-
"@molecule/app-logger": "^1.0.
|
|
31
|
+
"@molecule/app-bond": "^1.0.1",
|
|
32
|
+
"@molecule/app-i18n": "^1.0.1",
|
|
33
|
+
"@molecule/app-logger": "^1.0.1"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
|
-
"@molecule/app-bond": "1.0.
|
|
36
|
-
"@molecule/app-i18n": "1.0.
|
|
37
|
-
"@molecule/app-logger": "1.0.
|
|
36
|
+
"@molecule/app-bond": "1.0.2",
|
|
37
|
+
"@molecule/app-i18n": "1.0.2",
|
|
38
|
+
"@molecule/app-logger": "1.0.2",
|
|
38
39
|
"@types/node": "26.1.2",
|
|
39
40
|
"typescript": "6.0.3",
|
|
40
|
-
"vitest": "4.1.
|
|
41
|
+
"vitest": "4.1.11"
|
|
41
42
|
},
|
|
42
43
|
"repository": {
|
|
43
44
|
"type": "git",
|
|
44
45
|
"url": "https://github.com/molecule-dev/molecule.git",
|
|
45
46
|
"directory": "packages/app/core/http"
|
|
46
47
|
},
|
|
47
|
-
"homepage": "https://
|
|
48
|
+
"homepage": "https://www.molecule.dev/packages/app-http",
|
|
48
49
|
"bugs": "https://github.com/molecule-dev/molecule/issues",
|
|
49
50
|
"publishConfig": {
|
|
50
51
|
"access": "public"
|