@unispechq/unispec-schema 0.4.0 → 0.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 (44) hide show
  1. package/README.md +170 -162
  2. package/examples/README.md +128 -0
  3. package/examples/invalid/config/additional-properties.json +26 -0
  4. package/examples/invalid/config/missing-service-name.json +22 -0
  5. package/examples/invalid/config/missing-version.json +6 -0
  6. package/examples/invalid/graphql-additional-properties.json +22 -0
  7. package/examples/invalid/graphql-missing-arg-type.json +26 -0
  8. package/examples/invalid/graphql-missing-name.json +19 -0
  9. package/examples/invalid/graphql-missing-schema.json +19 -0
  10. package/examples/invalid/mixed-invalid-protocol.json +26 -0
  11. package/examples/invalid/mixed-missing-graphql-schema.json +33 -0
  12. package/examples/invalid/mixed-multiple-errors.json +41 -0
  13. package/examples/invalid/rest-additional-properties.json +25 -0
  14. package/examples/invalid/rest-invalid-identifiers.json +29 -0
  15. package/examples/invalid/rest-invalid-method.json +23 -0
  16. package/examples/invalid/rest-missing-required.json +21 -0
  17. package/examples/invalid/websocket-additional-properties.json +27 -0
  18. package/examples/invalid/websocket-invalid-direction.json +27 -0
  19. package/examples/invalid/websocket-missing-channel-name.json +25 -0
  20. package/examples/invalid/websocket-missing-message-name.json +25 -0
  21. package/examples/valid/config/complete.json +61 -0
  22. package/examples/valid/config/minimal.json +8 -0
  23. package/examples/valid/graphql-complete.json +348 -0
  24. package/examples/valid/graphql-simple.json +34 -0
  25. package/examples/valid/mixed-complete.json +799 -0
  26. package/examples/valid/mixed-simple.json +56 -0
  27. package/examples/valid/rest-complete.json +539 -0
  28. package/examples/valid/rest-simple.json +279 -0
  29. package/examples/valid/websocket-complete.json +471 -0
  30. package/examples/valid/websocket-simple.json +116 -0
  31. package/index.cjs +7 -7
  32. package/index.d.ts +9 -9
  33. package/index.mjs +9 -9
  34. package/package.json +15 -6
  35. package/schema/index.json +19 -19
  36. package/schema/types/common.schema.json +195 -195
  37. package/schema/types/graphql.schema.json +172 -172
  38. package/schema/types/rest.schema.json +221 -226
  39. package/schema/types/schemas.schema.json +84 -84
  40. package/schema/types/service.schema.json +158 -158
  41. package/schema/types/websocket.schema.json +185 -190
  42. package/schema/unispec-config.schema.json +509 -509
  43. package/schema/unispec-tests.schema.json +368 -378
  44. package/schema/unispec.schema.json +18 -23
@@ -0,0 +1,56 @@
1
+ {
2
+ "unispecVersion": "0.1.0",
3
+ "service": {
4
+ "name": "mixed-simple-api",
5
+ "description": "Simple API combining REST and GraphQL protocols",
6
+ "version": "1.0.0",
7
+ "baseUrl": "https://api.example.com",
8
+ "protocols": {
9
+ "rest": {
10
+ "routes": [
11
+ {
12
+ "name": "getStatus",
13
+ "summary": "Get API status",
14
+ "path": "/status",
15
+ "method": "GET",
16
+ "responses": {
17
+ "200": {
18
+ "description": "Status response",
19
+ "content": {
20
+ "application/json": {
21
+ "schemaRef": "StatusResponse"
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ]
28
+ },
29
+ "graphql": {
30
+ "url": "/graphql",
31
+ "schema": "type Status {\n status: String!\n timestamp: String!\n}\n\ntype Query {\n status: Status!\n}\n",
32
+ "queries": [
33
+ {
34
+ "name": "status",
35
+ "description": "Get system status",
36
+ "returnType": "Status!"
37
+ }
38
+ ]
39
+ }
40
+ },
41
+ "schemas": {
42
+ "StatusResponse": {
43
+ "type": "object",
44
+ "properties": {
45
+ "status": {
46
+ "type": "string"
47
+ },
48
+ "timestamp": {
49
+ "type": "string",
50
+ "format": "date-time"
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,539 @@
1
+ {
2
+ "unispecVersion": "0.1.0",
3
+ "service": {
4
+ "name": "user-management-api",
5
+ "description": "Complete user management REST API with authentication",
6
+ "version": "1.0.0",
7
+ "baseUrl": "https://api.example.com/v1",
8
+ "contact": {
9
+ "name": "API Support",
10
+ "email": "support@example.com",
11
+ "url": "https://example.com/support"
12
+ },
13
+ "license": {
14
+ "name": "MIT",
15
+ "url": "https://opensource.org/licenses/MIT"
16
+ },
17
+ "tags": ["users", "authentication", "management"],
18
+ "servers": [
19
+ {
20
+ "url": "https://api.example.com/v1",
21
+ "description": "Production server"
22
+ },
23
+ {
24
+ "url": "https://staging-api.example.com/v1",
25
+ "description": "Staging server"
26
+ }
27
+ ],
28
+ "securitySchemes": {
29
+ "bearerAuth": {
30
+ "type": "http",
31
+ "scheme": "bearer",
32
+ "bearerFormat": "JWT",
33
+ "description": "JWT authentication token"
34
+ },
35
+ "apiKeyAuth": {
36
+ "type": "apiKey",
37
+ "name": "X-API-Key",
38
+ "in": "header",
39
+ "description": "API key for authentication"
40
+ }
41
+ },
42
+ "rateLimit": {
43
+ "requestsPerMinute": 1000,
44
+ "requestsPerHour": 50000,
45
+ "perUser": true
46
+ },
47
+ "compliance": ["GDPR", "SOC2"],
48
+ "dataClassification": "confidential",
49
+ "protocols": {
50
+ "rest": {
51
+ "headers": [
52
+ {
53
+ "name": "Content-Type",
54
+ "description": "Request content type",
55
+ "required": true
56
+ },
57
+ {
58
+ "name": "Accept",
59
+ "description": "Response content type",
60
+ "required": true
61
+ }
62
+ ],
63
+ "routes": [
64
+ {
65
+ "name": "getUsers",
66
+ "summary": "List all users",
67
+ "tags": ["users"],
68
+ "description": "Retrieve a paginated list of users",
69
+ "path": "/users",
70
+ "method": "GET",
71
+ "queryParams": [
72
+ {
73
+ "name": "page",
74
+ "description": "Page number for pagination",
75
+ "required": false,
76
+ "schemaRef": "PageNumber"
77
+ },
78
+ {
79
+ "name": "limit",
80
+ "description": "Number of items per page",
81
+ "required": false,
82
+ "schemaRef": "PageSize"
83
+ },
84
+ {
85
+ "name": "search",
86
+ "description": "Search term for filtering users",
87
+ "required": false,
88
+ "schemaRef": "SearchTerm"
89
+ }
90
+ ],
91
+ "responses": {
92
+ "200": {
93
+ "description": "List of users retrieved successfully",
94
+ "content": {
95
+ "application/json": {
96
+ "schemaRef": "UserListResponse"
97
+ }
98
+ }
99
+ },
100
+ "400": {
101
+ "description": "Bad request - invalid parameters",
102
+ "content": {
103
+ "application/json": {
104
+ "schemaRef": "ErrorResponse"
105
+ }
106
+ }
107
+ },
108
+ "401": {
109
+ "description": "Unauthorized - authentication required",
110
+ "content": {
111
+ "application/json": {
112
+ "schemaRef": "ErrorResponse"
113
+ }
114
+ }
115
+ }
116
+ },
117
+ "security": [
118
+ {
119
+ "bearerAuth": []
120
+ },
121
+ {
122
+ "apiKeyAuth": []
123
+ }
124
+ ]
125
+ },
126
+ {
127
+ "name": "createUser",
128
+ "summary": "Create a new user",
129
+ "tags": ["users"],
130
+ "description": "Create a new user account",
131
+ "path": "/users",
132
+ "method": "POST",
133
+ "requestBody": {
134
+ "description": "User data for creation",
135
+ "required": true,
136
+ "content": {
137
+ "application/json": {
138
+ "schemaRef": "CreateUserRequest"
139
+ }
140
+ }
141
+ },
142
+ "responses": {
143
+ "201": {
144
+ "description": "User created successfully",
145
+ "content": {
146
+ "application/json": {
147
+ "schemaRef": "UserResponse"
148
+ }
149
+ }
150
+ },
151
+ "400": {
152
+ "description": "Bad request - invalid user data",
153
+ "content": {
154
+ "application/json": {
155
+ "schemaRef": "ErrorResponse"
156
+ }
157
+ }
158
+ },
159
+ "409": {
160
+ "description": "Conflict - user already exists",
161
+ "content": {
162
+ "application/json": {
163
+ "schemaRef": "ErrorResponse"
164
+ }
165
+ }
166
+ }
167
+ },
168
+ "security": [
169
+ {
170
+ "bearerAuth": []
171
+ }
172
+ ]
173
+ },
174
+ {
175
+ "name": "getUserById",
176
+ "summary": "Get user by ID",
177
+ "tags": ["users"],
178
+ "description": "Retrieve a specific user by their ID",
179
+ "path": "/users/{id}",
180
+ "method": "GET",
181
+ "pathParams": [
182
+ {
183
+ "name": "id",
184
+ "description": "User ID",
185
+ "required": true,
186
+ "schemaRef": "UserId"
187
+ }
188
+ ],
189
+ "responses": {
190
+ "200": {
191
+ "description": "User retrieved successfully",
192
+ "content": {
193
+ "application/json": {
194
+ "schemaRef": "UserResponse"
195
+ }
196
+ }
197
+ },
198
+ "404": {
199
+ "description": "User not found",
200
+ "content": {
201
+ "application/json": {
202
+ "schemaRef": "ErrorResponse"
203
+ }
204
+ }
205
+ }
206
+ },
207
+ "security": [
208
+ {
209
+ "bearerAuth": []
210
+ },
211
+ {
212
+ "apiKeyAuth": []
213
+ }
214
+ ]
215
+ },
216
+ {
217
+ "name": "updateUser",
218
+ "summary": "Update user",
219
+ "tags": ["users"],
220
+ "description": "Update an existing user's information",
221
+ "path": "/users/{id}",
222
+ "method": "PUT",
223
+ "pathParams": [
224
+ {
225
+ "name": "id",
226
+ "description": "User ID",
227
+ "required": true,
228
+ "schemaRef": "UserId"
229
+ }
230
+ ],
231
+ "requestBody": {
232
+ "description": "Updated user data",
233
+ "required": true,
234
+ "content": {
235
+ "application/json": {
236
+ "schemaRef": "UpdateUserRequest"
237
+ }
238
+ }
239
+ },
240
+ "responses": {
241
+ "200": {
242
+ "description": "User updated successfully",
243
+ "content": {
244
+ "application/json": {
245
+ "schemaRef": "UserResponse"
246
+ }
247
+ }
248
+ },
249
+ "400": {
250
+ "description": "Bad request - invalid user data",
251
+ "content": {
252
+ "application/json": {
253
+ "schemaRef": "ErrorResponse"
254
+ }
255
+ }
256
+ },
257
+ "404": {
258
+ "description": "User not found",
259
+ "content": {
260
+ "application/json": {
261
+ "schemaRef": "ErrorResponse"
262
+ }
263
+ }
264
+ }
265
+ },
266
+ "security": [
267
+ {
268
+ "bearerAuth": []
269
+ }
270
+ ]
271
+ },
272
+ {
273
+ "name": "deleteUser",
274
+ "summary": "Delete user",
275
+ "tags": ["users"],
276
+ "description": "Delete a user account",
277
+ "path": "/users/{id}",
278
+ "method": "DELETE",
279
+ "pathParams": [
280
+ {
281
+ "name": "id",
282
+ "description": "User ID",
283
+ "required": true,
284
+ "schemaRef": "UserId"
285
+ }
286
+ ],
287
+ "responses": {
288
+ "204": {
289
+ "description": "User deleted successfully"
290
+ },
291
+ "404": {
292
+ "description": "User not found",
293
+ "content": {
294
+ "application/json": {
295
+ "schemaRef": "ErrorResponse"
296
+ }
297
+ }
298
+ }
299
+ },
300
+ "security": [
301
+ {
302
+ "bearerAuth": []
303
+ }
304
+ ]
305
+ },
306
+ {
307
+ "name": "authenticateUser",
308
+ "summary": "User authentication",
309
+ "tags": ["authentication"],
310
+ "description": "Authenticate user and return JWT token",
311
+ "path": "/auth/login",
312
+ "method": "POST",
313
+ "requestBody": {
314
+ "description": "User credentials",
315
+ "required": true,
316
+ "content": {
317
+ "application/json": {
318
+ "schemaRef": "LoginRequest"
319
+ }
320
+ }
321
+ },
322
+ "responses": {
323
+ "200": {
324
+ "description": "Authentication successful",
325
+ "content": {
326
+ "application/json": {
327
+ "schemaRef": "AuthResponse"
328
+ }
329
+ }
330
+ },
331
+ "401": {
332
+ "description": "Invalid credentials",
333
+ "content": {
334
+ "application/json": {
335
+ "schemaRef": "ErrorResponse"
336
+ }
337
+ }
338
+ }
339
+ },
340
+ "security": []
341
+ }
342
+ ]
343
+ }
344
+ },
345
+ "schemas": {
346
+ "UserId": {
347
+ "type": "string",
348
+ "pattern": "^[0-9a-fA-F]{24}$",
349
+ "description": "MongoDB ObjectId string"
350
+ },
351
+ "PageNumber": {
352
+ "type": "integer",
353
+ "minimum": 1,
354
+ "default": 1,
355
+ "description": "Page number for pagination"
356
+ },
357
+ "PageSize": {
358
+ "type": "integer",
359
+ "minimum": 1,
360
+ "maximum": 100,
361
+ "default": 20,
362
+ "description": "Number of items per page"
363
+ },
364
+ "SearchTerm": {
365
+ "type": "string",
366
+ "minLength": 1,
367
+ "maxLength": 100,
368
+ "description": "Search term for filtering"
369
+ },
370
+ "CreateUserRequest": {
371
+ "type": "object",
372
+ "required": ["email", "password", "firstName", "lastName"],
373
+ "properties": {
374
+ "email": {
375
+ "type": "string",
376
+ "format": "email",
377
+ "description": "User email address"
378
+ },
379
+ "password": {
380
+ "type": "string",
381
+ "minLength": 8,
382
+ "description": "User password (min 8 characters)"
383
+ },
384
+ "firstName": {
385
+ "type": "string",
386
+ "minLength": 1,
387
+ "maxLength": 50,
388
+ "description": "User first name"
389
+ },
390
+ "lastName": {
391
+ "type": "string",
392
+ "minLength": 1,
393
+ "maxLength": 50,
394
+ "description": "User last name"
395
+ },
396
+ "phone": {
397
+ "type": "string",
398
+ "description": "Optional phone number"
399
+ }
400
+ }
401
+ },
402
+ "UpdateUserRequest": {
403
+ "type": "object",
404
+ "properties": {
405
+ "firstName": {
406
+ "type": "string",
407
+ "minLength": 1,
408
+ "maxLength": 50,
409
+ "description": "User first name"
410
+ },
411
+ "lastName": {
412
+ "type": "string",
413
+ "minLength": 1,
414
+ "maxLength": 50,
415
+ "description": "User last name"
416
+ },
417
+ "phone": {
418
+ "type": "string",
419
+ "description": "Optional phone number"
420
+ },
421
+ "email": {
422
+ "type": "string",
423
+ "format": "email",
424
+ "description": "User email address"
425
+ }
426
+ }
427
+ },
428
+ "LoginRequest": {
429
+ "type": "object",
430
+ "required": ["email", "password"],
431
+ "properties": {
432
+ "email": {
433
+ "type": "string",
434
+ "format": "email",
435
+ "description": "User email address"
436
+ },
437
+ "password": {
438
+ "type": "string",
439
+ "description": "User password"
440
+ }
441
+ }
442
+ },
443
+ "UserResponse": {
444
+ "type": "object",
445
+ "properties": {
446
+ "id": {
447
+ "$ref": "#/service/schemas/UserId"
448
+ },
449
+ "email": {
450
+ "type": "string",
451
+ "format": "email"
452
+ },
453
+ "firstName": {
454
+ "type": "string"
455
+ },
456
+ "lastName": {
457
+ "type": "string"
458
+ },
459
+ "phone": {
460
+ "type": "string"
461
+ },
462
+ "createdAt": {
463
+ "type": "string",
464
+ "format": "date-time"
465
+ },
466
+ "updatedAt": {
467
+ "type": "string",
468
+ "format": "date-time"
469
+ }
470
+ }
471
+ },
472
+ "UserListResponse": {
473
+ "type": "object",
474
+ "properties": {
475
+ "users": {
476
+ "type": "array",
477
+ "items": {
478
+ "$ref": "#/service/schemas/UserResponse"
479
+ }
480
+ },
481
+ "pagination": {
482
+ "type": "object",
483
+ "properties": {
484
+ "page": {
485
+ "$ref": "#/service/schemas/PageNumber"
486
+ },
487
+ "limit": {
488
+ "$ref": "#/service/schemas/PageSize"
489
+ },
490
+ "total": {
491
+ "type": "integer",
492
+ "minimum": 0,
493
+ "description": "Total number of users"
494
+ },
495
+ "totalPages": {
496
+ "type": "integer",
497
+ "minimum": 0,
498
+ "description": "Total number of pages"
499
+ }
500
+ }
501
+ }
502
+ }
503
+ },
504
+ "AuthResponse": {
505
+ "type": "object",
506
+ "properties": {
507
+ "token": {
508
+ "type": "string",
509
+ "description": "JWT authentication token"
510
+ },
511
+ "expiresIn": {
512
+ "type": "integer",
513
+ "description": "Token expiration time in seconds"
514
+ },
515
+ "user": {
516
+ "$ref": "#/service/schemas/UserResponse"
517
+ }
518
+ }
519
+ },
520
+ "ErrorResponse": {
521
+ "type": "object",
522
+ "properties": {
523
+ "error": {
524
+ "type": "string",
525
+ "description": "Error code"
526
+ },
527
+ "message": {
528
+ "type": "string",
529
+ "description": "Human-readable error message"
530
+ },
531
+ "details": {
532
+ "type": "object",
533
+ "description": "Additional error details"
534
+ }
535
+ }
536
+ }
537
+ }
538
+ }
539
+ }