json-rest-api 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/.claude/settings.local.json +16 -0
- package/LICENSE +674 -0
- package/README.md +655 -309
- package/RELATIONSHIPS.md +1013 -0
- package/TODO_rest-api-plugin-extras.js +142 -0
- package/connectors_ideas/express-plugin.js +120 -0
- package/connectors_ideas/fastify.js +219 -0
- package/connectors_ideas/http-plugin.js +138 -0
- package/connectors_ideas/koa-plugin.js +113 -0
- package/docs/fileUploads.md +722 -0
- package/docs/mini-guides/file-uploads-complete.md +159 -0
- package/examples/.gitkeep +0 -0
- package/examples/express-example.js +262 -0
- package/examples/express-plugin.js +366 -0
- package/examples/file-upload-example.js +205 -0
- package/examples/filename-strategies.js +140 -0
- package/examples/knex-basic.js +66 -0
- package/index.js +31 -56
- package/lib/payload-validators.js +685 -0
- package/lib/rest-api-errors.js +58 -0
- package/package.json +41 -14
- package/payloadValdators.js +686 -0
- package/plugins/core/connectors/express-plugin.js +449 -0
- package/plugins/core/connectors/http-plugin.js +450 -0
- package/plugins/core/file-handling-plugin.js +338 -0
- package/plugins/core/lib/busboy-detector.js +167 -0
- package/plugins/core/lib/formidable-detector.js +130 -0
- package/plugins/core/rest-api-knex-plugin.js +200 -0
- package/plugins/core/rest-api-plugin.js +1419 -0
- package/plugins/storage/local-storage.js +218 -0
- package/plugins/storage/s3-storage.js +125 -0
- package/test-examples/package-lock.json +906 -0
- package/test-examples/package.json +15 -0
- package/test-examples/test-basic-api.js +11 -0
- package/test-examples/test-books-resource.js +116 -0
- package/test-examples/test-complete-file-upload.js +140 -0
- package/test-examples/test-debug.js +28 -0
- package/test-examples/test-express-plugin.js +177 -0
- package/test-examples/test-express-simple.js +28 -0
- package/test-examples/test-express-with-import.js +71 -0
- package/test-examples/test-file-upload.js +132 -0
- package/test-examples/test-http-plugin.js +159 -0
- package/test-examples/test-programmatic-api.js +188 -0
- package/test-examples/test-rest-api-plugin.js +13 -0
- package/TODO.todo +0 -113
- package/api.js +0 -628
- package/docs/API.md +0 -1306
- package/docs/FIXES_APPLIED.md +0 -59
- package/docs/GUIDES.md +0 -1792
- package/docs/RESOURCES_IN_EXPRESS.md +0 -456
- package/docs/example-versioning.js +0 -168
- package/docs/example.js +0 -195
- package/plugins/API guide.md +0 -364
- package/plugins/api-registry.js +0 -142
- package/plugins/api-versioning.md +0 -135
- package/plugins/http.js +0 -273
- package/plugins/logging.js +0 -255
- package/plugins/memory.js +0 -182
- package/plugins/mysql.js +0 -753
- package/plugins/openapi.js +0 -401
- package/plugins/positioning.js +0 -220
- package/plugins/security.js +0 -261
- package/plugins/validation.js +0 -173
- package/plugins/versioning.js +0 -288
- package/resource-helper.js +0 -79
- package/schema.js +0 -481
- package/test-basic.js +0 -107
package/docs/API.md
DELETED
|
@@ -1,1306 +0,0 @@
|
|
|
1
|
-
# JSON REST API - Complete API Reference
|
|
2
|
-
|
|
3
|
-
This document provides a complete reference for every class, method, and option in the JSON REST API library.
|
|
4
|
-
|
|
5
|
-
## Key Concepts: API Instance Management
|
|
6
|
-
|
|
7
|
-
### When to Create New vs Share Instances
|
|
8
|
-
|
|
9
|
-
**Create NEW instance (with `createApi()` or `new Api()`):**
|
|
10
|
-
- Simple APIs where everything is in one file
|
|
11
|
-
- Standalone services that don't interact
|
|
12
|
-
- Different API versions (each version gets its own instance)
|
|
13
|
-
|
|
14
|
-
**Share EXISTING instance (with `Api.get()` or `defineResource()`):**
|
|
15
|
-
- Resources split across multiple files
|
|
16
|
-
- Resources that need to interact (e.g., users querying products)
|
|
17
|
-
- Resources sharing the same database connection
|
|
18
|
-
- Resources in the same API version
|
|
19
|
-
|
|
20
|
-
### Example Patterns
|
|
21
|
-
|
|
22
|
-
```javascript
|
|
23
|
-
// Simple API (one file) - CREATE new instance
|
|
24
|
-
const api = createApi({ storage: 'memory' });
|
|
25
|
-
api.addResource('users', userSchema);
|
|
26
|
-
api.addResource('products', productSchema);
|
|
27
|
-
|
|
28
|
-
// Modular API (multiple files) - SHARE instance
|
|
29
|
-
// api/1.0.0/users.js
|
|
30
|
-
const api = Api.get('myapp', '1.0.0') || new Api({ name: 'myapp', version: '1.0.0' });
|
|
31
|
-
api.addResource('users', userSchema);
|
|
32
|
-
export default api;
|
|
33
|
-
|
|
34
|
-
// api/1.0.0/products.js
|
|
35
|
-
const api = Api.get('myapp', '1.0.0'); // Gets SAME instance!
|
|
36
|
-
api.addResource('products', productSchema);
|
|
37
|
-
export default api;
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Table of Contents
|
|
41
|
-
|
|
42
|
-
1. [Core Classes](#core-classes)
|
|
43
|
-
- [Api Class](#api-class)
|
|
44
|
-
- [Schema Class](#schema-class)
|
|
45
|
-
2. [Plugin Reference](#plugin-reference)
|
|
46
|
-
- [ValidationPlugin](#validationplugin)
|
|
47
|
-
- [MemoryPlugin](#memoryplugin)
|
|
48
|
-
- [MySQLPlugin](#mysqlplugin)
|
|
49
|
-
- [HTTPPlugin](#httpplugin)
|
|
50
|
-
- [PositioningPlugin](#positioningplugin)
|
|
51
|
-
- [VersioningPlugin](#versioningplugin)
|
|
52
|
-
- [SecurityPlugin](#securityplugin)
|
|
53
|
-
- [LoggingPlugin](#loggingplugin)
|
|
54
|
-
- [OpenAPIPlugin](#openapiplugin)
|
|
55
|
-
3. [Helper Functions](#helper-functions)
|
|
56
|
-
4. [Type Definitions](#type-definitions)
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
# Core Classes
|
|
61
|
-
|
|
62
|
-
## Api Class
|
|
63
|
-
|
|
64
|
-
The main class for creating and managing JSON REST APIs.
|
|
65
|
-
|
|
66
|
-
### Constructor
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
new Api(options)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Options:**
|
|
73
|
-
| Option | Type | Default | Description |
|
|
74
|
-
|--------|------|---------|-------------|
|
|
75
|
-
| `idProperty` | string | `'id'` | The field name used as the primary identifier |
|
|
76
|
-
| `name` | string | `null` | API name for versioning registry |
|
|
77
|
-
| `version` | string | `null` | API version (e.g., '1.0.0') |
|
|
78
|
-
|
|
79
|
-
**Example:**
|
|
80
|
-
```javascript
|
|
81
|
-
const api = new Api({
|
|
82
|
-
idProperty: 'id',
|
|
83
|
-
name: 'myapp',
|
|
84
|
-
version: '1.0.0'
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Methods
|
|
89
|
-
|
|
90
|
-
#### `use(plugin, options)`
|
|
91
|
-
Add a plugin to the API.
|
|
92
|
-
|
|
93
|
-
**Parameters:**
|
|
94
|
-
- `plugin` (Object): Plugin object with `install` method
|
|
95
|
-
- `options` (Object): Plugin-specific options
|
|
96
|
-
|
|
97
|
-
**Returns:** `this` (for chaining)
|
|
98
|
-
|
|
99
|
-
**Example:**
|
|
100
|
-
```javascript
|
|
101
|
-
api.use(MySQLPlugin, { connection: dbConfig })
|
|
102
|
-
.use(HTTPPlugin, { basePath: '/api' });
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
#### `hook(name, handler, priority)`
|
|
106
|
-
Register a hook handler.
|
|
107
|
-
|
|
108
|
-
**Parameters:**
|
|
109
|
-
- `name` (string): Hook name
|
|
110
|
-
- `handler` (async function): Hook handler function
|
|
111
|
-
- `priority` (number): Execution priority (lower = earlier, default: 50)
|
|
112
|
-
|
|
113
|
-
**Available Hooks:**
|
|
114
|
-
- `beforeValidate`: Before data validation
|
|
115
|
-
- `afterValidate`: After validation, before operation
|
|
116
|
-
- `beforeGet`: Before fetching single resource
|
|
117
|
-
- `afterGet`: After fetching single resource
|
|
118
|
-
- `beforeQuery`: Before querying resources
|
|
119
|
-
- `afterQuery`: After querying resources
|
|
120
|
-
- `beforeInsert`: Before inserting resource
|
|
121
|
-
- `afterInsert`: After inserting resource
|
|
122
|
-
- `beforeUpdate`: Before updating resource
|
|
123
|
-
- `afterUpdate`: After updating resource
|
|
124
|
-
- `beforeDelete`: Before deleting resource
|
|
125
|
-
- `afterDelete`: After deleting resource
|
|
126
|
-
- `beforeSend`: Before sending response (HTTP)
|
|
127
|
-
- `transformResult`: Transform results before returning
|
|
128
|
-
|
|
129
|
-
**Hook Context Object:**
|
|
130
|
-
```javascript
|
|
131
|
-
{
|
|
132
|
-
method: 'insert', // Current operation
|
|
133
|
-
id: '123', // Resource ID (for get/update/delete)
|
|
134
|
-
data: {...}, // Request data
|
|
135
|
-
params: {...}, // Query parameters
|
|
136
|
-
options: {...}, // Operation options
|
|
137
|
-
result: {...}, // Operation result
|
|
138
|
-
results: [...], // Query results
|
|
139
|
-
errors: [...], // Validation errors
|
|
140
|
-
meta: {...} // Metadata
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**Example:**
|
|
145
|
-
```javascript
|
|
146
|
-
api.hook('beforeInsert', async (context) => {
|
|
147
|
-
context.data.createdAt = Date.now();
|
|
148
|
-
});
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### `get(id, options)`
|
|
152
|
-
Fetch a single resource by ID.
|
|
153
|
-
|
|
154
|
-
**Parameters:**
|
|
155
|
-
- `id` (string|number): Resource identifier
|
|
156
|
-
- `options` (Object): Operation options
|
|
157
|
-
|
|
158
|
-
**Options:**
|
|
159
|
-
| Option | Type | Description |
|
|
160
|
-
|--------|------|-------------|
|
|
161
|
-
| `type` | string | Resource type (required) |
|
|
162
|
-
| `table` | string | Database table (MySQL) |
|
|
163
|
-
| `connection` | string | Database connection name |
|
|
164
|
-
| `fields` | string[] | Fields to return |
|
|
165
|
-
| `userId` | any | User ID for audit |
|
|
166
|
-
| `request` | Object | HTTP request object |
|
|
167
|
-
|
|
168
|
-
**Returns:** Promise<{ data: Resource }>
|
|
169
|
-
|
|
170
|
-
**Example:**
|
|
171
|
-
```javascript
|
|
172
|
-
const result = await api.get('123', { type: 'users' });
|
|
173
|
-
// { data: { id: '123', type: 'users', attributes: {...} } }
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
#### `query(params, options)`
|
|
177
|
-
Query multiple resources.
|
|
178
|
-
|
|
179
|
-
**Parameters:**
|
|
180
|
-
- `params` (Object): Query parameters
|
|
181
|
-
- `options` (Object): Operation options
|
|
182
|
-
|
|
183
|
-
**Query Parameters:**
|
|
184
|
-
| Parameter | Type | Description |
|
|
185
|
-
|-----------|------|-------------|
|
|
186
|
-
| `filter` | Object | Field filters |
|
|
187
|
-
| `sort` | string | Sort order (e.g., '-createdAt,name') |
|
|
188
|
-
| `page.size` | number | Page size |
|
|
189
|
-
| `page.number` | number | Page number |
|
|
190
|
-
| `search` | string | Search term |
|
|
191
|
-
| `include` | string | Related resources to include |
|
|
192
|
-
|
|
193
|
-
**Returns:** Promise<{ data: Resource[], meta: Object, links: Object }>
|
|
194
|
-
|
|
195
|
-
**Example:**
|
|
196
|
-
```javascript
|
|
197
|
-
const result = await api.query({
|
|
198
|
-
filter: { active: true },
|
|
199
|
-
sort: '-createdAt',
|
|
200
|
-
page: { size: 10, number: 1 }
|
|
201
|
-
}, { type: 'users' });
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
#### `insert(data, options)`
|
|
205
|
-
Create a new resource.
|
|
206
|
-
|
|
207
|
-
**Parameters:**
|
|
208
|
-
- `data` (Object): Resource data
|
|
209
|
-
- `options` (Object): Operation options
|
|
210
|
-
|
|
211
|
-
**Additional Options:**
|
|
212
|
-
| Option | Type | Description |
|
|
213
|
-
|--------|------|-------------|
|
|
214
|
-
| `positioning` | Object | Positioning options |
|
|
215
|
-
| `skipValidation` | boolean | Skip validation |
|
|
216
|
-
| `fullRecord` | boolean | Validate all fields |
|
|
217
|
-
|
|
218
|
-
**Returns:** Promise<{ data: Resource }>
|
|
219
|
-
|
|
220
|
-
**Example:**
|
|
221
|
-
```javascript
|
|
222
|
-
const result = await api.insert({
|
|
223
|
-
name: 'John Doe',
|
|
224
|
-
email: 'john@example.com'
|
|
225
|
-
}, { type: 'users' });
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
#### `update(id, data, options)`
|
|
229
|
-
Update an existing resource.
|
|
230
|
-
|
|
231
|
-
**Parameters:**
|
|
232
|
-
- `id` (string|number): Resource identifier
|
|
233
|
-
- `data` (Object): Update data
|
|
234
|
-
- `options` (Object): Operation options
|
|
235
|
-
|
|
236
|
-
**Returns:** Promise<{ data: Resource }>
|
|
237
|
-
|
|
238
|
-
**Example:**
|
|
239
|
-
```javascript
|
|
240
|
-
const result = await api.update('123', {
|
|
241
|
-
name: 'Jane Doe'
|
|
242
|
-
}, { type: 'users' });
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
#### `delete(id, options)`
|
|
246
|
-
Delete a resource.
|
|
247
|
-
|
|
248
|
-
**Parameters:**
|
|
249
|
-
- `id` (string|number): Resource identifier
|
|
250
|
-
- `options` (Object): Operation options
|
|
251
|
-
|
|
252
|
-
**Returns:** Promise<{ data: null }>
|
|
253
|
-
|
|
254
|
-
**Example:**
|
|
255
|
-
```javascript
|
|
256
|
-
await api.delete('123', { type: 'users' });
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
#### `addResource(type, schema, hooks?)`
|
|
260
|
-
Register a resource type with its schema and optional hooks.
|
|
261
|
-
|
|
262
|
-
**Parameters:**
|
|
263
|
-
- `type` (string): Resource type name
|
|
264
|
-
- `schema` (Schema): Schema instance
|
|
265
|
-
- `hooks` (object, optional): Hook functions for this resource
|
|
266
|
-
|
|
267
|
-
**Example:**
|
|
268
|
-
```javascript
|
|
269
|
-
const userHooks = {
|
|
270
|
-
async afterValidate(context) {
|
|
271
|
-
// Custom validation
|
|
272
|
-
},
|
|
273
|
-
async transformResult(context) {
|
|
274
|
-
// Transform output
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
api.addResource('users', userSchema, userHooks);
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
**Available hooks:**
|
|
282
|
-
- `beforeValidate` - Before schema validation
|
|
283
|
-
- `afterValidate` - After schema validation
|
|
284
|
-
- `beforeGet` - Before fetching single record
|
|
285
|
-
- `afterGet` - After fetching single record
|
|
286
|
-
- `beforeQuery` - Before querying records
|
|
287
|
-
- `afterQuery` - After querying records
|
|
288
|
-
- `beforeInsert` - Before inserting
|
|
289
|
-
- `afterInsert` - After inserting
|
|
290
|
-
- `beforeUpdate` - Before updating
|
|
291
|
-
- `afterUpdate` - After updating
|
|
292
|
-
- `beforeDelete` - Before deleting
|
|
293
|
-
- `afterDelete` - After deleting
|
|
294
|
-
- `transformResult` - Transform results before sending
|
|
295
|
-
|
|
296
|
-
#### `resource(type)`
|
|
297
|
-
Alternative method to access a resource.
|
|
298
|
-
|
|
299
|
-
**Parameters:**
|
|
300
|
-
- `type` (string): Resource type name
|
|
301
|
-
|
|
302
|
-
**Returns:** Resource proxy object
|
|
303
|
-
|
|
304
|
-
**Example:**
|
|
305
|
-
```javascript
|
|
306
|
-
// Useful when resource name is dynamic
|
|
307
|
-
const resourceName = getUserResourceName();
|
|
308
|
-
const data = await api.resource(resourceName).get(123);
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Resource Proxy Methods
|
|
312
|
-
|
|
313
|
-
Each resource accessible via `api.resources.{name}` has the following methods:
|
|
314
|
-
|
|
315
|
-
#### Resource CRUD Methods
|
|
316
|
-
|
|
317
|
-
##### `get(id, options)`
|
|
318
|
-
Fetch a single resource.
|
|
319
|
-
|
|
320
|
-
```javascript
|
|
321
|
-
const user = await api.resources.users.get(123);
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
##### `query(params, options)`
|
|
325
|
-
Query multiple resources.
|
|
326
|
-
|
|
327
|
-
```javascript
|
|
328
|
-
const users = await api.resources.users.query({
|
|
329
|
-
filter: { active: true },
|
|
330
|
-
sort: '-createdAt'
|
|
331
|
-
});
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
##### `create(data, options)` / `post(data, options)`
|
|
335
|
-
Create a new resource.
|
|
336
|
-
|
|
337
|
-
```javascript
|
|
338
|
-
const user = await api.resources.users.create({
|
|
339
|
-
name: 'John Doe',
|
|
340
|
-
email: 'john@example.com'
|
|
341
|
-
});
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
##### `update(id, data, options)` / `put(id, data, options)`
|
|
345
|
-
Update an existing resource.
|
|
346
|
-
|
|
347
|
-
```javascript
|
|
348
|
-
const updated = await api.resources.users.update(123, {
|
|
349
|
-
email: 'newemail@example.com'
|
|
350
|
-
});
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
##### `delete(id, options)` / `remove(id, options)`
|
|
354
|
-
Delete a resource.
|
|
355
|
-
|
|
356
|
-
```javascript
|
|
357
|
-
await api.resources.users.delete(123);
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
#### Resource Versioning
|
|
361
|
-
|
|
362
|
-
##### `version(versionSpec)`
|
|
363
|
-
Access a specific version of the resource.
|
|
364
|
-
|
|
365
|
-
```javascript
|
|
366
|
-
// Access version 1.0.0 of users
|
|
367
|
-
const userV1 = await api.resources.users.version('1.0.0').get(123);
|
|
368
|
-
|
|
369
|
-
// Access latest 2.x version
|
|
370
|
-
const userV2 = await api.resources.users.version('^2.0.0').get(123);
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
#### Batch Operations
|
|
374
|
-
|
|
375
|
-
##### `batch.create(items, options)`
|
|
376
|
-
Create multiple resources.
|
|
377
|
-
|
|
378
|
-
```javascript
|
|
379
|
-
const users = await api.resources.users.batch.create([
|
|
380
|
-
{ name: 'User 1' },
|
|
381
|
-
{ name: 'User 2' }
|
|
382
|
-
]);
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
##### `batch.update(updates, options)`
|
|
386
|
-
Update multiple resources.
|
|
387
|
-
|
|
388
|
-
```javascript
|
|
389
|
-
await api.resources.users.batch.update([
|
|
390
|
-
{ id: 1, data: { active: false } },
|
|
391
|
-
{ id: 2, data: { active: false } }
|
|
392
|
-
]);
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
##### `batch.delete(ids, options)`
|
|
396
|
-
Delete multiple resources.
|
|
397
|
-
|
|
398
|
-
```javascript
|
|
399
|
-
await api.resources.users.batch.delete([1, 2, 3]);
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
#### Resource Properties
|
|
403
|
-
|
|
404
|
-
##### `schema`
|
|
405
|
-
Access the resource's schema.
|
|
406
|
-
|
|
407
|
-
```javascript
|
|
408
|
-
const userSchema = api.resources.users.schema;
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
##### `hooks`
|
|
412
|
-
Access the resource's hooks.
|
|
413
|
-
|
|
414
|
-
```javascript
|
|
415
|
-
const userHooks = api.resources.users.hooks;
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
#### `getSchema(type)`
|
|
419
|
-
Get the schema for a resource type.
|
|
420
|
-
|
|
421
|
-
**Parameters:**
|
|
422
|
-
- `type` (string): Resource type name
|
|
423
|
-
|
|
424
|
-
**Returns:** Schema instance or undefined
|
|
425
|
-
|
|
426
|
-
#### `mount(app, basePath)`
|
|
427
|
-
Mount HTTP routes on Express app (requires HTTPPlugin).
|
|
428
|
-
|
|
429
|
-
**Parameters:**
|
|
430
|
-
- `app` (Express app): Express application
|
|
431
|
-
- `basePath` (string): Base path for routes (default: '/api')
|
|
432
|
-
|
|
433
|
-
**Example:**
|
|
434
|
-
```javascript
|
|
435
|
-
api.mount(app, '/api/v1');
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
### Static Methods
|
|
439
|
-
|
|
440
|
-
#### `Api.get(name, version)`
|
|
441
|
-
Get a registered API by name and version.
|
|
442
|
-
|
|
443
|
-
**Parameters:**
|
|
444
|
-
- `name` (string): API name
|
|
445
|
-
- `version` (string): Version specifier ('latest', '1.0.0', '>=1.0.0', etc.)
|
|
446
|
-
|
|
447
|
-
**Returns:** Api instance or null
|
|
448
|
-
|
|
449
|
-
**Example:**
|
|
450
|
-
```javascript
|
|
451
|
-
const api = Api.get('myapp', 'latest');
|
|
452
|
-
const apiV1 = Api.get('myapp', '1.0.0');
|
|
453
|
-
const apiV2Plus = Api.get('myapp', '>=2.0.0');
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
#### `Api.getRegistry()`
|
|
457
|
-
Get all registered APIs.
|
|
458
|
-
|
|
459
|
-
**Returns:** Object with API names and versions
|
|
460
|
-
|
|
461
|
-
**Example:**
|
|
462
|
-
```javascript
|
|
463
|
-
const registry = Api.getRegistry();
|
|
464
|
-
// { myapp: ['2.1.0', '2.0.0', '1.0.0'], otherapp: ['1.0.0'] }
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
### Properties
|
|
468
|
-
|
|
469
|
-
#### `apis`
|
|
470
|
-
Proxy object for accessing other registered APIs.
|
|
471
|
-
|
|
472
|
-
**Example:**
|
|
473
|
-
```javascript
|
|
474
|
-
const usersApi = api.apis.users; // Gets compatible users API
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
---
|
|
478
|
-
|
|
479
|
-
## Schema Class
|
|
480
|
-
|
|
481
|
-
Defines data structure and validation rules.
|
|
482
|
-
|
|
483
|
-
### Constructor
|
|
484
|
-
|
|
485
|
-
```javascript
|
|
486
|
-
new Schema(structure, options)
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
**Parameters:**
|
|
490
|
-
- `structure` (Object): Field definitions
|
|
491
|
-
- `options` (Object): Schema options
|
|
492
|
-
|
|
493
|
-
**Options:**
|
|
494
|
-
| Option | Type | Default | Description |
|
|
495
|
-
|--------|------|---------|-------------|
|
|
496
|
-
| `emptyAsNull` | boolean | false | Convert empty strings to null |
|
|
497
|
-
| `canBeNull` | boolean | false | Allow null values by default |
|
|
498
|
-
|
|
499
|
-
### Field Definition
|
|
500
|
-
|
|
501
|
-
```javascript
|
|
502
|
-
{
|
|
503
|
-
type: 'string', // Required: field type
|
|
504
|
-
required: false, // Field is required
|
|
505
|
-
default: null, // Default value or function
|
|
506
|
-
canBeNull: false, // Can be null
|
|
507
|
-
emptyAsNull: false, // Empty string becomes null
|
|
508
|
-
|
|
509
|
-
// Type-specific options
|
|
510
|
-
min: 0, // Minimum value/length
|
|
511
|
-
max: 100, // Maximum value/length
|
|
512
|
-
pattern: /regex/, // Regex pattern (strings)
|
|
513
|
-
enum: ['a', 'b'], // Allowed values
|
|
514
|
-
|
|
515
|
-
// String options
|
|
516
|
-
lowercase: false, // Convert to lowercase
|
|
517
|
-
uppercase: false, // Convert to uppercase
|
|
518
|
-
trim: 50, // Trim to length
|
|
519
|
-
noTrim: false, // Don't trim whitespace
|
|
520
|
-
|
|
521
|
-
// Validation
|
|
522
|
-
validator: fn, // Custom validator function
|
|
523
|
-
notEmpty: false, // Can't be empty string
|
|
524
|
-
|
|
525
|
-
// Documentation
|
|
526
|
-
description: '', // Field description
|
|
527
|
-
example: '', // Example value
|
|
528
|
-
|
|
529
|
-
// Special
|
|
530
|
-
silent: false, // Hide from responses
|
|
531
|
-
searchable: false, // Include in search
|
|
532
|
-
unique: false // Must be unique (custom)
|
|
533
|
-
}
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
### Methods
|
|
537
|
-
|
|
538
|
-
#### `use(plugin, options)`
|
|
539
|
-
Add a plugin to the schema.
|
|
540
|
-
|
|
541
|
-
**Parameters:**
|
|
542
|
-
- `plugin` (Object): Plugin with `install` method
|
|
543
|
-
- `options` (Object): Plugin options
|
|
544
|
-
|
|
545
|
-
**Returns:** `this`
|
|
546
|
-
|
|
547
|
-
#### `registerType(name, handler)`
|
|
548
|
-
Register a custom type handler.
|
|
549
|
-
|
|
550
|
-
**Parameters:**
|
|
551
|
-
- `name` (string): Type name
|
|
552
|
-
- `handler` (Function): Type handler function
|
|
553
|
-
|
|
554
|
-
**Handler Parameters:**
|
|
555
|
-
```javascript
|
|
556
|
-
{
|
|
557
|
-
definition: {}, // Field definition
|
|
558
|
-
value: any, // Current value
|
|
559
|
-
fieldName: string, // Field name
|
|
560
|
-
object: {}, // Full object
|
|
561
|
-
options: {}, // Validation options
|
|
562
|
-
computedOptions: {} // Computed options
|
|
563
|
-
}
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
**Example:**
|
|
567
|
-
```javascript
|
|
568
|
-
schema.registerType('phone', ({ value }) => {
|
|
569
|
-
const cleaned = value.replace(/\D/g, '');
|
|
570
|
-
if (cleaned.length !== 10) throw new Error('Invalid phone');
|
|
571
|
-
return cleaned;
|
|
572
|
-
});
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
#### `registerParam(name, handler)`
|
|
576
|
-
Register a custom parameter handler.
|
|
577
|
-
|
|
578
|
-
**Parameters:**
|
|
579
|
-
- `name` (string): Parameter name
|
|
580
|
-
- `handler` (Function): Parameter handler function
|
|
581
|
-
|
|
582
|
-
**Example:**
|
|
583
|
-
```javascript
|
|
584
|
-
schema.registerParam('unique', async ({ value, fieldName }) => {
|
|
585
|
-
const exists = await checkUnique(fieldName, value);
|
|
586
|
-
if (exists) throw new Error(`${fieldName} must be unique`);
|
|
587
|
-
});
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
#### `validate(object, options)`
|
|
591
|
-
Validate an object against the schema.
|
|
592
|
-
|
|
593
|
-
**Parameters:**
|
|
594
|
-
- `object` (Object): Object to validate
|
|
595
|
-
- `options` (Object): Validation options
|
|
596
|
-
|
|
597
|
-
**Validation Options:**
|
|
598
|
-
| Option | Type | Description |
|
|
599
|
-
|--------|------|-------------|
|
|
600
|
-
| `onlyObjectValues` | boolean | Only validate provided fields |
|
|
601
|
-
| `skipFields` | string[] | Fields to skip |
|
|
602
|
-
| `skipParams` | Object | Parameters to skip by field |
|
|
603
|
-
| `emptyAsNull` | boolean | Convert empty to null |
|
|
604
|
-
| `canBeNull` | boolean | Allow null values |
|
|
605
|
-
|
|
606
|
-
**Returns:** Promise<{ validatedObject: Object, errors: Array }>
|
|
607
|
-
|
|
608
|
-
**Example:**
|
|
609
|
-
```javascript
|
|
610
|
-
const { validatedObject, errors } = await schema.validate({
|
|
611
|
-
name: 'John',
|
|
612
|
-
email: 'john@example.com'
|
|
613
|
-
});
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
#### `cleanup(object, parameterName)`
|
|
617
|
-
Get object with only fields having specific parameter.
|
|
618
|
-
|
|
619
|
-
**Parameters:**
|
|
620
|
-
- `object` (Object): Source object
|
|
621
|
-
- `parameterName` (string): Parameter to filter by
|
|
622
|
-
|
|
623
|
-
**Returns:** Filtered object
|
|
624
|
-
|
|
625
|
-
### Built-in Types
|
|
626
|
-
|
|
627
|
-
| Type | Description | Casts From | Default |
|
|
628
|
-
|------|-------------|------------|---------|
|
|
629
|
-
| `none` | No casting | - | - |
|
|
630
|
-
| `string` | String value | Any with toString() | `''` |
|
|
631
|
-
| `number` | Numeric value | Numeric strings | `0` |
|
|
632
|
-
| `boolean` | Boolean value | Strings, numbers | `false` |
|
|
633
|
-
| `id` | Integer ID | Numeric strings | - |
|
|
634
|
-
| `timestamp` | Unix timestamp | Date strings, numbers | - |
|
|
635
|
-
| `date` | Date (YYYY-MM-DD) | Date objects, strings | - |
|
|
636
|
-
| `dateTime` | DateTime | Date objects, strings | - |
|
|
637
|
-
| `array` | Array | Single values | `[]` |
|
|
638
|
-
| `object` | Object | Objects | `{}` |
|
|
639
|
-
| `serialize` | Circular JSON | Any | - |
|
|
640
|
-
| `blob` | Binary data | - | - |
|
|
641
|
-
|
|
642
|
-
---
|
|
643
|
-
|
|
644
|
-
# Plugin Reference
|
|
645
|
-
|
|
646
|
-
## ValidationPlugin
|
|
647
|
-
|
|
648
|
-
Automatically included. Provides schema validation for all operations.
|
|
649
|
-
|
|
650
|
-
### Installation
|
|
651
|
-
```javascript
|
|
652
|
-
api.use(ValidationPlugin); // Usually automatic
|
|
653
|
-
```
|
|
654
|
-
|
|
655
|
-
### Features
|
|
656
|
-
- Validates data against registered schemas
|
|
657
|
-
- Supports custom validation hooks
|
|
658
|
-
- Provides detailed error messages
|
|
659
|
-
- Handles cross-field validation
|
|
660
|
-
|
|
661
|
-
### Hooks Added
|
|
662
|
-
- `beforeValidate`: Prepare data for validation
|
|
663
|
-
- `afterValidate`: Additional validation logic
|
|
664
|
-
|
|
665
|
-
### Methods Added
|
|
666
|
-
- `api.addResource(type, schema, hooks?)`: Register resource with schema and hooks
|
|
667
|
-
- `api.getSchema(type)`: Get schema
|
|
668
|
-
- `api.createSearchSchema(schema, fields)`: Create search schema
|
|
669
|
-
|
|
670
|
-
---
|
|
671
|
-
|
|
672
|
-
## MemoryPlugin
|
|
673
|
-
|
|
674
|
-
In-memory storage backend.
|
|
675
|
-
|
|
676
|
-
### Installation
|
|
677
|
-
```javascript
|
|
678
|
-
api.use(MemoryPlugin, {
|
|
679
|
-
initialData: [], // Initial data array
|
|
680
|
-
initialIdCounter: 1 // Starting ID value
|
|
681
|
-
});
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
### Features
|
|
685
|
-
- Fast in-memory storage
|
|
686
|
-
- Full CRUD operations
|
|
687
|
-
- Filtering and sorting
|
|
688
|
-
- Pagination support
|
|
689
|
-
- Search functionality
|
|
690
|
-
|
|
691
|
-
### Storage Access
|
|
692
|
-
```javascript
|
|
693
|
-
api.memoryData // Direct access to data array
|
|
694
|
-
api.memoryIdCounter // Current ID counter
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
---
|
|
698
|
-
|
|
699
|
-
## MySQLPlugin
|
|
700
|
-
|
|
701
|
-
MySQL database storage backend.
|
|
702
|
-
|
|
703
|
-
### Installation
|
|
704
|
-
```javascript
|
|
705
|
-
api.use(MySQLPlugin, {
|
|
706
|
-
connection: {
|
|
707
|
-
host: 'localhost',
|
|
708
|
-
user: 'root',
|
|
709
|
-
password: 'password',
|
|
710
|
-
database: 'myapp',
|
|
711
|
-
waitForConnections: true,
|
|
712
|
-
connectionLimit: 10,
|
|
713
|
-
queueLimit: 0
|
|
714
|
-
}
|
|
715
|
-
});
|
|
716
|
-
|
|
717
|
-
// Or multiple connections
|
|
718
|
-
api.use(MySQLPlugin, {
|
|
719
|
-
connections: [
|
|
720
|
-
{
|
|
721
|
-
name: 'primary',
|
|
722
|
-
config: { host: 'primary.db', ... }
|
|
723
|
-
},
|
|
724
|
-
{
|
|
725
|
-
name: 'replica',
|
|
726
|
-
config: { host: 'replica.db', ... }
|
|
727
|
-
}
|
|
728
|
-
]
|
|
729
|
-
});
|
|
730
|
-
```
|
|
731
|
-
|
|
732
|
-
### Methods Added
|
|
733
|
-
|
|
734
|
-
#### `api.syncSchema(schema, table, options)`
|
|
735
|
-
Synchronize database table with schema.
|
|
736
|
-
|
|
737
|
-
**Parameters:**
|
|
738
|
-
- `schema` (Schema): Schema to sync
|
|
739
|
-
- `table` (string): Table name
|
|
740
|
-
- `options` (Object): Sync options
|
|
741
|
-
|
|
742
|
-
**Options:**
|
|
743
|
-
| Option | Type | Description |
|
|
744
|
-
|--------|------|-------------|
|
|
745
|
-
| `connection` | string | Connection name |
|
|
746
|
-
| `idProperty` | string | ID field name |
|
|
747
|
-
|
|
748
|
-
**Example:**
|
|
749
|
-
```javascript
|
|
750
|
-
await api.syncSchema(userSchema, 'users');
|
|
751
|
-
```
|
|
752
|
-
|
|
753
|
-
#### `api.getConnection(name)`
|
|
754
|
-
Get connection pool by name.
|
|
755
|
-
|
|
756
|
-
**Parameters:**
|
|
757
|
-
- `name` (string): Connection name (default: 'default')
|
|
758
|
-
|
|
759
|
-
**Returns:** { pool: MySQLPool, options: Object }
|
|
760
|
-
|
|
761
|
-
### Schema Sync Features
|
|
762
|
-
- Creates tables if not exists
|
|
763
|
-
- Adds new columns
|
|
764
|
-
- Updates column types
|
|
765
|
-
- Creates indexes for searchable fields
|
|
766
|
-
- Handles foreign key constraints
|
|
767
|
-
|
|
768
|
-
### Field Type Mapping
|
|
769
|
-
|
|
770
|
-
| Schema Type | MySQL Type | Notes |
|
|
771
|
-
|-------------|------------|-------|
|
|
772
|
-
| `id` | `INT AUTO_INCREMENT` | Primary key |
|
|
773
|
-
| `number` | `INT` | Or FLOAT, DECIMAL |
|
|
774
|
-
| `string` | `VARCHAR(n)` | Or TEXT |
|
|
775
|
-
| `boolean` | `BOOLEAN` | |
|
|
776
|
-
| `timestamp` | `BIGINT` | Unix timestamp |
|
|
777
|
-
| `date` | `DATE` | |
|
|
778
|
-
| `dateTime` | `DATETIME` | |
|
|
779
|
-
| `array` | `JSON` | |
|
|
780
|
-
| `object` | `JSON` | |
|
|
781
|
-
| `serialize` | `JSON` | |
|
|
782
|
-
| `blob` | `BLOB` | |
|
|
783
|
-
|
|
784
|
-
---
|
|
785
|
-
|
|
786
|
-
## HTTPPlugin
|
|
787
|
-
|
|
788
|
-
Provides RESTful HTTP endpoints.
|
|
789
|
-
|
|
790
|
-
### Installation
|
|
791
|
-
```javascript
|
|
792
|
-
api.use(HTTPPlugin, {
|
|
793
|
-
basePath: '/api', // Base URL path
|
|
794
|
-
app: expressApp, // Express app (optional)
|
|
795
|
-
typeOptions: { // Per-type options
|
|
796
|
-
users: {
|
|
797
|
-
searchFields: ['name', 'email']
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
### Routes Created
|
|
804
|
-
|
|
805
|
-
| Method | Path | Description |
|
|
806
|
-
|--------|------|-------------|
|
|
807
|
-
| GET | `/{type}` | List resources |
|
|
808
|
-
| GET | `/{type}/{id}` | Get single resource |
|
|
809
|
-
| POST | `/{type}` | Create resource |
|
|
810
|
-
| PATCH | `/{type}/{id}` | Update resource |
|
|
811
|
-
| DELETE | `/{type}/{id}` | Delete resource |
|
|
812
|
-
| OPTIONS | `*` | CORS preflight |
|
|
813
|
-
|
|
814
|
-
### Query Parameters
|
|
815
|
-
|
|
816
|
-
| Parameter | Example | Description |
|
|
817
|
-
|-----------|---------|-------------|
|
|
818
|
-
| `filter[field]` | `filter[active]=true` | Filter by field |
|
|
819
|
-
| `sort` | `sort=-createdAt,name` | Sort order |
|
|
820
|
-
| `page[size]` | `page[size]=20` | Page size |
|
|
821
|
-
| `page[number]` | `page[number]=2` | Page number |
|
|
822
|
-
| `fields[type]` | `fields[users]=id,name` | Sparse fields |
|
|
823
|
-
| `include` | `include=posts,comments` | Include relations |
|
|
824
|
-
|
|
825
|
-
### Request/Response Format
|
|
826
|
-
|
|
827
|
-
**Request Body (POST/PATCH):**
|
|
828
|
-
```json
|
|
829
|
-
{
|
|
830
|
-
"data": {
|
|
831
|
-
"type": "users",
|
|
832
|
-
"attributes": {
|
|
833
|
-
"name": "John Doe",
|
|
834
|
-
"email": "john@example.com"
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
```
|
|
839
|
-
|
|
840
|
-
**Response Format:**
|
|
841
|
-
```json
|
|
842
|
-
{
|
|
843
|
-
"data": {
|
|
844
|
-
"id": "123",
|
|
845
|
-
"type": "users",
|
|
846
|
-
"attributes": {
|
|
847
|
-
"name": "John Doe",
|
|
848
|
-
"email": "john@example.com"
|
|
849
|
-
}
|
|
850
|
-
},
|
|
851
|
-
"meta": {
|
|
852
|
-
"total": 100
|
|
853
|
-
},
|
|
854
|
-
"links": {
|
|
855
|
-
"self": "/api/users/123"
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
```
|
|
859
|
-
|
|
860
|
-
### Methods Added
|
|
861
|
-
|
|
862
|
-
#### `api.mount(app, basePath)`
|
|
863
|
-
Mount routes on Express app.
|
|
864
|
-
|
|
865
|
-
#### `api.useMiddleware(middleware)`
|
|
866
|
-
Add middleware to all routes.
|
|
867
|
-
|
|
868
|
-
#### `api.useRouteMiddleware(method, path, middleware)`
|
|
869
|
-
Add middleware to specific route.
|
|
870
|
-
|
|
871
|
-
---
|
|
872
|
-
|
|
873
|
-
## PositioningPlugin
|
|
874
|
-
|
|
875
|
-
Manage record ordering for drag-and-drop interfaces.
|
|
876
|
-
|
|
877
|
-
### Installation
|
|
878
|
-
```javascript
|
|
879
|
-
api.use(PositioningPlugin, {
|
|
880
|
-
positionField: 'position', // Position field name
|
|
881
|
-
beforeIdField: 'beforeId', // Virtual field for positioning
|
|
882
|
-
positionFilters: ['projectId'] // Group by these fields
|
|
883
|
-
});
|
|
884
|
-
```
|
|
885
|
-
|
|
886
|
-
### Features
|
|
887
|
-
- Automatic position management
|
|
888
|
-
- Drag-and-drop support
|
|
889
|
-
- Position groups/scopes
|
|
890
|
-
- Gap-free positioning
|
|
891
|
-
|
|
892
|
-
### Usage
|
|
893
|
-
|
|
894
|
-
**Insert with position:**
|
|
895
|
-
```javascript
|
|
896
|
-
await api.insert({
|
|
897
|
-
title: 'Task',
|
|
898
|
-
beforeId: '123' // Insert before this ID
|
|
899
|
-
}, {
|
|
900
|
-
type: 'tasks',
|
|
901
|
-
positioning: { enabled: true }
|
|
902
|
-
});
|
|
903
|
-
|
|
904
|
-
// beforeId values:
|
|
905
|
-
// - null: Insert at end
|
|
906
|
-
// - undefined: Keep current position (update) or end (insert)
|
|
907
|
-
// - ID: Insert before specified record
|
|
908
|
-
```
|
|
909
|
-
|
|
910
|
-
### Methods Added
|
|
911
|
-
|
|
912
|
-
#### `api.reposition(type, recordId, beforeId, options)`
|
|
913
|
-
Reposition existing record.
|
|
914
|
-
|
|
915
|
-
**Parameters:**
|
|
916
|
-
- `type` (string): Resource type
|
|
917
|
-
- `recordId` (string): Record to move
|
|
918
|
-
- `beforeId` (string|null): Position before this ID
|
|
919
|
-
- `options` (Object): Positioning options
|
|
920
|
-
|
|
921
|
-
#### `api.getNextPosition(type, filters, options)`
|
|
922
|
-
Get next available position.
|
|
923
|
-
|
|
924
|
-
**Returns:** Promise<number>
|
|
925
|
-
|
|
926
|
-
#### `api.normalizePositions(type, filters, options)`
|
|
927
|
-
Remove gaps in position numbers.
|
|
928
|
-
|
|
929
|
-
---
|
|
930
|
-
|
|
931
|
-
## VersioningPlugin
|
|
932
|
-
|
|
933
|
-
API versioning and resource version tracking.
|
|
934
|
-
|
|
935
|
-
### Installation
|
|
936
|
-
```javascript
|
|
937
|
-
api.use(VersioningPlugin, {
|
|
938
|
-
// API versioning
|
|
939
|
-
apiVersion: '2.0.0',
|
|
940
|
-
versionHeader: 'api-version',
|
|
941
|
-
versionParam: 'v',
|
|
942
|
-
|
|
943
|
-
// Resource versioning
|
|
944
|
-
versionField: 'version',
|
|
945
|
-
lastModifiedField: 'lastModified',
|
|
946
|
-
modifiedByField: 'modifiedBy',
|
|
947
|
-
trackHistory: true,
|
|
948
|
-
historyTable: 'posts_history',
|
|
949
|
-
optimisticLocking: true
|
|
950
|
-
});
|
|
951
|
-
```
|
|
952
|
-
|
|
953
|
-
### Features
|
|
954
|
-
- Automatic API version negotiation
|
|
955
|
-
- Resource version tracking
|
|
956
|
-
- Version history
|
|
957
|
-
- Optimistic locking
|
|
958
|
-
- Version comparison
|
|
959
|
-
|
|
960
|
-
### Methods Added
|
|
961
|
-
|
|
962
|
-
#### `api.getVersionHistory(type, id, options)`
|
|
963
|
-
Get version history for a resource.
|
|
964
|
-
|
|
965
|
-
**Returns:** Promise<{ data: VersionHistory[] }>
|
|
966
|
-
|
|
967
|
-
#### `api.restoreVersion(type, id, version, options)`
|
|
968
|
-
Restore a specific version.
|
|
969
|
-
|
|
970
|
-
**Returns:** Promise<{ data: Resource }>
|
|
971
|
-
|
|
972
|
-
#### `api.diffVersions(type, id, version1, version2, options)`
|
|
973
|
-
Compare two versions.
|
|
974
|
-
|
|
975
|
-
**Returns:** Promise<VersionDiff>
|
|
976
|
-
|
|
977
|
-
```javascript
|
|
978
|
-
{
|
|
979
|
-
version1: 1,
|
|
980
|
-
version2: 2,
|
|
981
|
-
changes: [
|
|
982
|
-
{ field: 'title', oldValue: 'Old', newValue: 'New' }
|
|
983
|
-
]
|
|
984
|
-
}
|
|
985
|
-
```
|
|
986
|
-
|
|
987
|
-
### Version Headers
|
|
988
|
-
- Request: `API-Version: 2.0.0`
|
|
989
|
-
- Response: `API-Version: 2.0.0`
|
|
990
|
-
|
|
991
|
-
---
|
|
992
|
-
|
|
993
|
-
## SecurityPlugin
|
|
994
|
-
|
|
995
|
-
Comprehensive security features.
|
|
996
|
-
|
|
997
|
-
### Installation
|
|
998
|
-
```javascript
|
|
999
|
-
api.use(SecurityPlugin, {
|
|
1000
|
-
// Rate limiting
|
|
1001
|
-
rateLimit: {
|
|
1002
|
-
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
1003
|
-
max: 100, // Max requests
|
|
1004
|
-
message: 'Too many requests'
|
|
1005
|
-
},
|
|
1006
|
-
|
|
1007
|
-
// CORS
|
|
1008
|
-
cors: {
|
|
1009
|
-
origin: '*',
|
|
1010
|
-
credentials: true,
|
|
1011
|
-
methods: ['GET', 'POST', 'PATCH', 'DELETE'],
|
|
1012
|
-
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
1013
|
-
exposedHeaders: ['X-Total-Count']
|
|
1014
|
-
},
|
|
1015
|
-
|
|
1016
|
-
// Authentication
|
|
1017
|
-
authentication: {
|
|
1018
|
-
type: 'bearer', // 'bearer', 'basic', 'apikey'
|
|
1019
|
-
header: 'Authorization',
|
|
1020
|
-
queryParam: 'api_key',
|
|
1021
|
-
required: true
|
|
1022
|
-
},
|
|
1023
|
-
|
|
1024
|
-
// Token verification
|
|
1025
|
-
verifyToken: async (token, context) => {
|
|
1026
|
-
// Return user object or throw
|
|
1027
|
-
return { id: '123', roles: ['admin'] };
|
|
1028
|
-
},
|
|
1029
|
-
|
|
1030
|
-
// Options
|
|
1031
|
-
publicRead: false, // Allow GET without auth
|
|
1032
|
-
allowUnknownFilters: false
|
|
1033
|
-
});
|
|
1034
|
-
```
|
|
1035
|
-
|
|
1036
|
-
### Security Headers Added
|
|
1037
|
-
- `X-Content-Type-Options: nosniff`
|
|
1038
|
-
- `X-Frame-Options: DENY`
|
|
1039
|
-
- `X-XSS-Protection: 1; mode=block`
|
|
1040
|
-
- `Strict-Transport-Security`
|
|
1041
|
-
- `Content-Security-Policy`
|
|
1042
|
-
- `X-Request-ID`
|
|
1043
|
-
|
|
1044
|
-
### Rate Limit Headers
|
|
1045
|
-
- `X-RateLimit-Limit`
|
|
1046
|
-
- `X-RateLimit-Remaining`
|
|
1047
|
-
- `X-RateLimit-Reset`
|
|
1048
|
-
|
|
1049
|
-
### Methods Added
|
|
1050
|
-
|
|
1051
|
-
#### `api.generateToken(payload, expiresIn)`
|
|
1052
|
-
Generate authentication token.
|
|
1053
|
-
|
|
1054
|
-
#### `api.verifyToken(token)`
|
|
1055
|
-
Verify authentication token.
|
|
1056
|
-
|
|
1057
|
-
---
|
|
1058
|
-
|
|
1059
|
-
## LoggingPlugin
|
|
1060
|
-
|
|
1061
|
-
Structured logging with sensitive data protection.
|
|
1062
|
-
|
|
1063
|
-
### Installation
|
|
1064
|
-
```javascript
|
|
1065
|
-
api.use(LoggingPlugin, {
|
|
1066
|
-
level: 'info', // error, warn, info, debug
|
|
1067
|
-
format: 'json', // json or pretty
|
|
1068
|
-
includeRequest: true,
|
|
1069
|
-
includeResponse: true,
|
|
1070
|
-
includeTiming: true,
|
|
1071
|
-
sensitiveFields: ['password', 'token'],
|
|
1072
|
-
logger: console, // Or Winston, Bunyan, etc.
|
|
1073
|
-
auditLog: false // Enable audit logging
|
|
1074
|
-
});
|
|
1075
|
-
```
|
|
1076
|
-
|
|
1077
|
-
### Log Levels
|
|
1078
|
-
- `error`: Errors only
|
|
1079
|
-
- `warn`: Warnings and above
|
|
1080
|
-
- `info`: Info and above
|
|
1081
|
-
- `debug`: Everything
|
|
1082
|
-
|
|
1083
|
-
### Methods Added
|
|
1084
|
-
|
|
1085
|
-
#### `api.log`
|
|
1086
|
-
Structured logger with methods:
|
|
1087
|
-
- `api.log.error(message, meta)`
|
|
1088
|
-
- `api.log.warn(message, meta)`
|
|
1089
|
-
- `api.log.info(message, meta)`
|
|
1090
|
-
- `api.log.debug(message, meta)`
|
|
1091
|
-
|
|
1092
|
-
**Example:**
|
|
1093
|
-
```javascript
|
|
1094
|
-
api.log.info('User created', {
|
|
1095
|
-
userId: '123',
|
|
1096
|
-
email: 'user@example.com',
|
|
1097
|
-
ip: req.ip
|
|
1098
|
-
});
|
|
1099
|
-
```
|
|
1100
|
-
|
|
1101
|
-
### Automatic Logging
|
|
1102
|
-
- All API operations
|
|
1103
|
-
- HTTP requests/responses
|
|
1104
|
-
- SQL queries (with MySQL)
|
|
1105
|
-
- Validation errors
|
|
1106
|
-
- Performance metrics
|
|
1107
|
-
|
|
1108
|
-
---
|
|
1109
|
-
|
|
1110
|
-
## OpenAPIPlugin
|
|
1111
|
-
|
|
1112
|
-
Auto-generate OpenAPI documentation.
|
|
1113
|
-
|
|
1114
|
-
### Installation
|
|
1115
|
-
```javascript
|
|
1116
|
-
api.use(OpenAPIPlugin, {
|
|
1117
|
-
title: 'My API',
|
|
1118
|
-
version: '1.0.0',
|
|
1119
|
-
description: 'API description',
|
|
1120
|
-
servers: [
|
|
1121
|
-
{ url: 'https://api.example.com', description: 'Production' },
|
|
1122
|
-
{ url: 'http://localhost:3000', description: 'Development' }
|
|
1123
|
-
],
|
|
1124
|
-
contact: {
|
|
1125
|
-
name: 'API Support',
|
|
1126
|
-
email: 'support@example.com',
|
|
1127
|
-
url: 'https://example.com/support'
|
|
1128
|
-
},
|
|
1129
|
-
license: {
|
|
1130
|
-
name: 'MIT',
|
|
1131
|
-
url: 'https://opensource.org/licenses/MIT'
|
|
1132
|
-
}
|
|
1133
|
-
});
|
|
1134
|
-
```
|
|
1135
|
-
|
|
1136
|
-
### Endpoints Added
|
|
1137
|
-
- `GET /openapi.json` - OpenAPI specification
|
|
1138
|
-
- `GET /docs` - Swagger UI
|
|
1139
|
-
|
|
1140
|
-
### Methods Added
|
|
1141
|
-
|
|
1142
|
-
#### `api.generateOpenAPISpec()`
|
|
1143
|
-
Generate OpenAPI 3.0 specification.
|
|
1144
|
-
|
|
1145
|
-
**Returns:** OpenAPI specification object
|
|
1146
|
-
|
|
1147
|
-
### Schema Documentation
|
|
1148
|
-
```javascript
|
|
1149
|
-
const schema = new Schema({
|
|
1150
|
-
email: {
|
|
1151
|
-
type: 'string',
|
|
1152
|
-
required: true,
|
|
1153
|
-
description: 'User email address',
|
|
1154
|
-
example: 'user@example.com',
|
|
1155
|
-
pattern: '^[^@]+@[^@]+$'
|
|
1156
|
-
}
|
|
1157
|
-
});
|
|
1158
|
-
```
|
|
1159
|
-
|
|
1160
|
-
---
|
|
1161
|
-
|
|
1162
|
-
# Helper Functions
|
|
1163
|
-
|
|
1164
|
-
## `createApi(options)`
|
|
1165
|
-
|
|
1166
|
-
Convenience function to create a fully configured API.
|
|
1167
|
-
|
|
1168
|
-
**Parameters:**
|
|
1169
|
-
- `options` (Object): Combined options for Api and plugins
|
|
1170
|
-
|
|
1171
|
-
**Options:**
|
|
1172
|
-
```javascript
|
|
1173
|
-
{
|
|
1174
|
-
// Api options
|
|
1175
|
-
name: 'myapp',
|
|
1176
|
-
version: '1.0.0',
|
|
1177
|
-
idProperty: 'id',
|
|
1178
|
-
|
|
1179
|
-
// Storage
|
|
1180
|
-
storage: 'memory' | 'mysql',
|
|
1181
|
-
|
|
1182
|
-
// Plugin options
|
|
1183
|
-
memory: { /* MemoryPlugin options */ },
|
|
1184
|
-
mysql: { /* MySQLPlugin options */ },
|
|
1185
|
-
http: { /* HTTPPlugin options */ },
|
|
1186
|
-
validation: { /* ValidationPlugin options */ },
|
|
1187
|
-
positioning: { /* PositioningPlugin options */ },
|
|
1188
|
-
versioning: { /* VersioningPlugin options */ },
|
|
1189
|
-
security: { /* SecurityPlugin options */ },
|
|
1190
|
-
logging: { /* LoggingPlugin options */ }
|
|
1191
|
-
}
|
|
1192
|
-
```
|
|
1193
|
-
|
|
1194
|
-
**Example:**
|
|
1195
|
-
```javascript
|
|
1196
|
-
const api = createApi({
|
|
1197
|
-
name: 'myapp',
|
|
1198
|
-
version: '1.0.0',
|
|
1199
|
-
storage: 'mysql',
|
|
1200
|
-
mysql: {
|
|
1201
|
-
connection: dbConfig
|
|
1202
|
-
},
|
|
1203
|
-
http: {
|
|
1204
|
-
basePath: '/api'
|
|
1205
|
-
},
|
|
1206
|
-
security: {
|
|
1207
|
-
authentication: { type: 'bearer' }
|
|
1208
|
-
}
|
|
1209
|
-
});
|
|
1210
|
-
```
|
|
1211
|
-
|
|
1212
|
-
---
|
|
1213
|
-
|
|
1214
|
-
# Type Definitions
|
|
1215
|
-
|
|
1216
|
-
## Resource Format
|
|
1217
|
-
|
|
1218
|
-
JSON:API resource format:
|
|
1219
|
-
|
|
1220
|
-
```typescript
|
|
1221
|
-
interface Resource {
|
|
1222
|
-
id: string;
|
|
1223
|
-
type: string;
|
|
1224
|
-
attributes: {
|
|
1225
|
-
[key: string]: any;
|
|
1226
|
-
};
|
|
1227
|
-
relationships?: {
|
|
1228
|
-
[key: string]: {
|
|
1229
|
-
data: ResourceIdentifier | ResourceIdentifier[];
|
|
1230
|
-
};
|
|
1231
|
-
};
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
interface ResourceIdentifier {
|
|
1235
|
-
id: string;
|
|
1236
|
-
type: string;
|
|
1237
|
-
}
|
|
1238
|
-
```
|
|
1239
|
-
|
|
1240
|
-
## Error Format
|
|
1241
|
-
|
|
1242
|
-
JSON:API error format:
|
|
1243
|
-
|
|
1244
|
-
```typescript
|
|
1245
|
-
interface Error {
|
|
1246
|
-
status: string; // HTTP status code
|
|
1247
|
-
code?: string; // Application error code
|
|
1248
|
-
title: string; // Error title
|
|
1249
|
-
detail?: string; // Error details
|
|
1250
|
-
source?: {
|
|
1251
|
-
pointer?: string; // JSON pointer to error field
|
|
1252
|
-
parameter?: string; // Query parameter that caused error
|
|
1253
|
-
};
|
|
1254
|
-
meta?: any; // Additional metadata
|
|
1255
|
-
}
|
|
1256
|
-
```
|
|
1257
|
-
|
|
1258
|
-
## Query Response Format
|
|
1259
|
-
|
|
1260
|
-
```typescript
|
|
1261
|
-
interface QueryResponse {
|
|
1262
|
-
data: Resource[];
|
|
1263
|
-
meta?: {
|
|
1264
|
-
total: number;
|
|
1265
|
-
pageSize: number;
|
|
1266
|
-
pageNumber: number;
|
|
1267
|
-
totalPages: number;
|
|
1268
|
-
[key: string]: any;
|
|
1269
|
-
};
|
|
1270
|
-
links?: {
|
|
1271
|
-
self: string;
|
|
1272
|
-
first?: string;
|
|
1273
|
-
last?: string;
|
|
1274
|
-
prev?: string;
|
|
1275
|
-
next?: string;
|
|
1276
|
-
};
|
|
1277
|
-
included?: Resource[];
|
|
1278
|
-
}
|
|
1279
|
-
```
|
|
1280
|
-
|
|
1281
|
-
---
|
|
1282
|
-
|
|
1283
|
-
# Constants
|
|
1284
|
-
|
|
1285
|
-
## VERSION
|
|
1286
|
-
Current library version.
|
|
1287
|
-
```javascript
|
|
1288
|
-
import { VERSION } from 'jsonrestapi';
|
|
1289
|
-
console.log(VERSION); // '1.0.0'
|
|
1290
|
-
```
|
|
1291
|
-
|
|
1292
|
-
## Default Values
|
|
1293
|
-
|
|
1294
|
-
| Constant | Default | Description |
|
|
1295
|
-
|----------|---------|-------------|
|
|
1296
|
-
| ID Property | `'id'` | Default ID field name |
|
|
1297
|
-
| Page Size | `10` | Default query page size |
|
|
1298
|
-
| Max Page Size | `1000` | Maximum allowed page size |
|
|
1299
|
-
| Position Field | `'position'` | Default position field |
|
|
1300
|
-
| Version Field | `'version'` | Default version field |
|
|
1301
|
-
| Rate Limit Window | `900000` | 15 minutes in ms |
|
|
1302
|
-
| Rate Limit Max | `100` | Max requests per window |
|
|
1303
|
-
|
|
1304
|
-
---
|
|
1305
|
-
|
|
1306
|
-
This completes the comprehensive API reference for the JSON REST API library. Every public method, option, and feature is documented with examples and type information.
|