@unispechq/unispec-schema 0.4.8 → 0.5.0

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 CHANGED
@@ -38,7 +38,8 @@ unispec-spec/
38
38
  │ │ └─ config/ # Valid configuration files
39
39
  │ │ ├─ simple-multi-service.json
40
40
  │ │ ├─ registry-based.json
41
- │ │ └─ complete-enterprise.json
41
+ │ │ ├─ complete-enterprise.json
42
+ │ │ └─ bearer-token.json
42
43
  │ └─ invalid/ # Schema violations for testing
43
44
  │ ├─ spec/ # Invalid specifications
44
45
  │ └─ config/ # Invalid configurations
@@ -135,6 +136,7 @@ The `examples/` directory contains comprehensive examples in JSON format:
135
136
  - `simple-multi-service.json` — Basic multi-service setup
136
137
  - `registry-based.json` — Configuration using registry references
137
138
  - `complete-enterprise.json` — Full enterprise configuration with environments
139
+ - `bearer-token.json` — HTTP spec retrieval protected by Bearer token
138
140
 
139
141
  ### Invalid Examples (`examples/invalid/`)
140
142
  - **Specifications** — Various schema violations for testing validation
@@ -25,6 +25,7 @@ This directory contains example files demonstrating the UniSpec format and confi
25
25
  - `simple-multi-service.json` - Basic multi-service configuration
26
26
  - `registry-based.json` - Configuration using registry references
27
27
  - `complete-enterprise.json` - Full enterprise configuration with environments
28
+ - `bearer-token.json` - HTTP spec retrieval protected by Bearer token
28
29
 
29
30
  ## Invalid Examples
30
31
 
@@ -54,4 +55,4 @@ These examples are intended for:
54
55
  3. **Reference** - Starting points for creating your own specifications
55
56
  4. **Documentation** - Demonstrating various features and patterns
56
57
 
57
- All examples are in JSON format for consistency and ease of validation against the JSON schemas.
58
+ All examples are in JSON format for consistency and ease of validation against the JSON schemas.
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": 1,
3
+ "services": [
4
+ {
5
+ "name": "user-service",
6
+ "baseUrl": "https://user-api.example.com",
7
+ "spec": {
8
+ "type": "http",
9
+ "url": "https://user-api.example.com/unispec.json",
10
+ "authentication": {
11
+ "bearer": {
12
+ "token": "${USER_SERVICE_SPEC_BEARER_TOKEN}"
13
+ }
14
+ }
15
+ }
16
+ }
17
+ ]
18
+ }
19
+
@@ -6,36 +6,12 @@
6
6
  "baseUrl": "https://auth.company.com",
7
7
  "spec": {
8
8
  "type": "http",
9
- "url": "/unispec.json"
10
- },
11
- "health": {
12
- "path": "/health"
13
- },
14
- "headers": [
15
- {
16
- "name": "Authorization",
17
- "description": "Bearer token",
18
- "required": true
19
- },
20
- {
21
- "name": "X-Request-ID",
22
- "description": "Request tracking ID",
23
- "required": false
9
+ "url": "/unispec.json",
10
+ "authentication": {
11
+ "bearer": {
12
+ "token": "${AUTH_SERVICE_BEARER_TOKEN}"
13
+ }
24
14
  }
25
- ],
26
- "security": [
27
- [
28
- "oauth2"
29
- ],
30
- [
31
- "apiKeyAuth"
32
- ]
33
- ],
34
- "rateLimit": {
35
- "requestsPerMinute": 2000,
36
- "requestsPerHour": 100000,
37
- "perUser": true,
38
- "burstLimit": 500
39
15
  }
40
16
  },
41
17
  {
@@ -45,16 +21,8 @@
45
21
  "type": "file",
46
22
  "path": "./specs/catalog.json"
47
23
  },
48
- "health": {
49
- "path": "/ping"
50
- },
51
24
  "discovery": {
52
25
  "dnsTemplate": "catalog-{env}.company.com"
53
- },
54
- "rateLimit": {
55
- "requestsPerMinute": 5000,
56
- "requestsPerDay": 1000000,
57
- "perApiKey": true
58
26
  }
59
27
  },
60
28
  {
@@ -63,11 +31,6 @@
63
31
  "spec": {
64
32
  "type": "registry",
65
33
  "ref": "notification-service@v2.1.0"
66
- },
67
- "rateLimit": {
68
- "requestsPerMinute": 10000,
69
- "perUser": true,
70
- "customKey": "tenantId"
71
34
  }
72
35
  }
73
36
  ],
@@ -77,29 +40,12 @@
77
40
  "overrides": {
78
41
  "services": {
79
42
  "auth-service": {
80
- "baseUrl": "http://localhost:8000",
81
- "rateLimit": {
82
- "inherit": true,
83
- "requestsPerMinute": 5000
84
- }
43
+ "baseUrl": "http://localhost:8000"
85
44
  },
86
45
  "catalog-service": {
87
- "baseUrl": "http://localhost:8001",
88
- "rateLimit": {
89
- "inherit": true,
90
- "requestsPerMinute": 10000
91
- }
46
+ "baseUrl": "http://localhost:8001"
92
47
  }
93
48
  }
94
- },
95
- "observability": {
96
- "logging": {
97
- "level": "debug"
98
- },
99
- "tracing": {
100
- "enabled": true,
101
- "samplingRate": 1
102
- }
103
49
  }
104
50
  },
105
51
  {
@@ -107,25 +53,10 @@
107
53
  "overrides": {
108
54
  "services": {
109
55
  "auth-service": {
110
- "baseUrl": "https://staging-auth.company.com",
111
- "rateLimit": {
112
- "inherit": true,
113
- "burstLimit": 200
114
- }
56
+ "baseUrl": "https://staging-auth.company.com"
115
57
  }
116
58
  }
117
59
  },
118
- "observability": {
119
- "logging": {
120
- "level": "info"
121
- },
122
- "metrics": {
123
- "enabled": true,
124
- "endpoints": [
125
- "/metrics"
126
- ]
127
- }
128
- },
129
60
  "deployment": {
130
61
  "replicas": 2,
131
62
  "kubernetes": {
@@ -135,35 +66,12 @@
135
66
  },
136
67
  {
137
68
  "name": "production",
138
- "observability": {
139
- "logging": {
140
- "level": "warn",
141
- "format": "json"
142
- },
143
- "metrics": {
144
- "enabled": true
145
- },
146
- "tracing": {
147
- "enabled": true,
148
- "samplingRate": 0.01
149
- }
150
- },
151
69
  "deployment": {
152
70
  "replicas": 5,
153
71
  "kubernetes": {
154
72
  "namespace": "production",
155
73
  "serviceType": "LoadBalancer"
156
74
  }
157
- },
158
- "dataResidency": "EU-West",
159
- "audit": {
160
- "enabled": true,
161
- "retention": "1 year",
162
- "fields": [
163
- "userId",
164
- "action",
165
- "timestamp"
166
- ]
167
75
  }
168
76
  }
169
77
  ]
@@ -7,24 +7,6 @@
7
7
  "spec": {
8
8
  "type": "registry",
9
9
  "ref": "payment-service@v1.2.3"
10
- },
11
- "headers": [
12
- {
13
- "name": "X-API-Key",
14
- "description": "API key for payment service",
15
- "required": true
16
- }
17
- ],
18
- "security": [
19
- [
20
- "apiKeyAuth"
21
- ]
22
- ],
23
- "rateLimit": {
24
- "requestsPerMinute": 500,
25
- "requestsPerHour": 30000,
26
- "perApiKey": true,
27
- "customKey": "organizationId"
28
10
  }
29
11
  }
30
12
  ],
@@ -37,11 +19,7 @@
37
19
  "overrides": {
38
20
  "services": {
39
21
  "payment-service": {
40
- "baseUrl": "https://staging-payments.example.com",
41
- "rateLimit": {
42
- "inherit": true,
43
- "requestsPerMinute": 100
44
- }
22
+ "baseUrl": "https://staging-payments.example.com"
45
23
  }
46
24
  }
47
25
  }
@@ -7,13 +7,6 @@
7
7
  "spec": {
8
8
  "type": "http",
9
9
  "url": "https://user-api.example.com/unispec.json"
10
- },
11
- "health": {
12
- "path": "/health"
13
- },
14
- "rateLimit": {
15
- "requestsPerMinute": 1000,
16
- "perUser": true
17
10
  }
18
11
  },
19
12
  {
@@ -22,14 +15,6 @@
22
15
  "spec": {
23
16
  "type": "file",
24
17
  "path": "./order-service-spec.json"
25
- },
26
- "health": {
27
- "path": "/ping"
28
- },
29
- "rateLimit": {
30
- "requestsPerHour": 50000,
31
- "perApiKey": true,
32
- "burstLimit": 1000
33
18
  }
34
19
  }
35
20
  ],
@@ -39,34 +24,13 @@
39
24
  "overrides": {
40
25
  "services": {
41
26
  "user-service": {
42
- "baseUrl": "http://localhost:3001",
43
- "rateLimit": {
44
- "inherit": true,
45
- "requestsPerMinute": 100,
46
- "perUser": false
47
- }
27
+ "baseUrl": "http://localhost:3001"
48
28
  },
49
29
  "order-service": {
50
30
  "baseUrl": "http://localhost:3002"
51
31
  }
52
32
  }
53
33
  }
54
- },
55
- {
56
- "name": "production",
57
- "observability": {
58
- "logging": {
59
- "level": "info",
60
- "format": "json"
61
- },
62
- "metrics": {
63
- "enabled": true
64
- },
65
- "tracing": {
66
- "enabled": true,
67
- "samplingRate": 0.1
68
- }
69
- }
70
34
  }
71
35
  ]
72
36
  }
@@ -4,6 +4,9 @@
4
4
  "name": "blog-service",
5
5
  "description": "A blog service with GraphQL API",
6
6
  "version": "1.0.0",
7
+ "health": {
8
+ "path": "/health"
9
+ },
7
10
  "protocols": {
8
11
  "graphql": {
9
12
  "url": "/graphql",
@@ -4,6 +4,9 @@
4
4
  "name": "ecommerce-service",
5
5
  "description": "A complete e-commerce service with multiple protocols",
6
6
  "version": "2.1.0",
7
+ "health": {
8
+ "path": "/health"
9
+ },
7
10
  "contact": {
8
11
  "name": "API Team",
9
12
  "email": "api@ecommerce.com"
@@ -4,6 +4,50 @@
4
4
  "name": "user-service",
5
5
  "description": "A simple user management service with REST API",
6
6
  "version": "1.2.3",
7
+ "health": {
8
+ "path": "/health"
9
+ },
10
+ "schemas": {
11
+ "UserList": {
12
+ "description": "List of users response",
13
+ "jsonSchema": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "properties": {
18
+ "id": {"type": "string"},
19
+ "name": {"type": "string"},
20
+ "email": {"type": "string"}
21
+ },
22
+ "required": ["id", "name", "email"]
23
+ }
24
+ }
25
+ },
26
+ "CreateUserRequest": {
27
+ "description": "Request to create a new user",
28
+ "jsonSchema": {
29
+ "type": "object",
30
+ "properties": {
31
+ "name": {"type": "string"},
32
+ "email": {"type": "string"}
33
+ },
34
+ "required": ["name", "email"]
35
+ }
36
+ },
37
+ "UserResponse": {
38
+ "description": "User creation response",
39
+ "jsonSchema": {
40
+ "type": "object",
41
+ "properties": {
42
+ "id": {"type": "string"},
43
+ "name": {"type": "string"},
44
+ "email": {"type": "string"},
45
+ "createdAt": {"type": "string", "format": "date-time"}
46
+ },
47
+ "required": ["id", "name", "email", "createdAt"]
48
+ }
49
+ }
50
+ },
7
51
  "protocols": {
8
52
  "rest": {
9
53
  "routes": [
@@ -14,7 +58,12 @@
14
58
  "method": "GET",
15
59
  "responses": {
16
60
  "200": {
17
- "description": "List of users retrieved successfully"
61
+ "description": "List of users retrieved successfully",
62
+ "content": {
63
+ "application/json": {
64
+ "schemaRef": "UserList"
65
+ }
66
+ }
18
67
  }
19
68
  }
20
69
  },
@@ -33,7 +82,12 @@
33
82
  },
34
83
  "responses": {
35
84
  "201": {
36
- "description": "User created successfully"
85
+ "description": "User created successfully",
86
+ "content": {
87
+ "application/json": {
88
+ "schemaRef": "UserResponse"
89
+ }
90
+ }
37
91
  }
38
92
  }
39
93
  }
@@ -4,6 +4,9 @@
4
4
  "name": "chat-service",
5
5
  "description": "A chat service with WebSocket API",
6
6
  "version": "1.0.0",
7
+ "health": {
8
+ "path": "/health"
9
+ },
7
10
  "protocols": {
8
11
  "websocket": {
9
12
  "url": "/ws",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unispechq/unispec-schema",
3
- "version": "0.4.8",
3
+ "version": "0.5.0",
4
4
  "description": "Official UniSpec JSON Schemas",
5
5
  "type": "module",
6
6
  "main": "index.cjs",
@@ -15,7 +15,7 @@
15
15
  "type": "string",
16
16
  "description": "Short, human-readable summary of the route."
17
17
  },
18
- "deprecated": {
18
+ "deprecated": {
19
19
  "type": "boolean",
20
20
  "description": "Marks the route as deprecated.",
21
21
  "default": false
@@ -14,6 +14,17 @@
14
14
  "version": {
15
15
  "$ref": "./common.schema.json#/$defs/Version"
16
16
  },
17
+ "health": {
18
+ "type": "object",
19
+ "description": "Service health check endpoint definition.",
20
+ "properties": {
21
+ "path": {
22
+ "type": "string",
23
+ "description": "HTTP path for a health check endpoint (for example, /health or /ping)."
24
+ }
25
+ },
26
+ "additionalProperties": false
27
+ },
17
28
  "contact": {
18
29
  "type": "object",
19
30
  "description": "Contact information for the service.",
@@ -45,28 +45,8 @@
45
45
  "spec": {
46
46
  "$ref": "#/$defs/SpecReference"
47
47
  },
48
- "health": {
49
- "$ref": "#/$defs/Health"
50
- },
51
48
  "discovery": {
52
49
  "$ref": "#/$defs/Discovery"
53
- },
54
- "headers": {
55
- "type": "array",
56
- "description": "HTTP headers commonly used for accessing this service's UniSpec document.",
57
- "items": {
58
- "$ref": "#/$defs/Header"
59
- }
60
- },
61
- "security": {
62
- "type": "array",
63
- "description": "Security requirements for accessing this service's UniSpec document. Each item represents an alternative set of named security schemes.",
64
- "items": {
65
- "$ref": "#/$defs/SecurityRequirement"
66
- }
67
- },
68
- "rateLimit": {
69
- "$ref": "#/$defs/RateLimit"
70
50
  }
71
51
  },
72
52
  "additionalProperties": false
@@ -103,6 +83,10 @@
103
83
  "path": {
104
84
  "type": "string",
105
85
  "description": "Backward-compatible alias for url (for example, /unispec.yaml)."
86
+ },
87
+ "authentication": {
88
+ "$ref": "#/$defs/Authentication",
89
+ "description": "Authentication configuration for accessing the UniSpec document."
106
90
  }
107
91
  },
108
92
  "oneOf": [{ "required": ["url"] }, { "required": ["path"] }],
@@ -136,17 +120,6 @@
136
120
  },
137
121
  "additionalProperties": false
138
122
  },
139
- "Health": {
140
- "type": "object",
141
- "required": ["path"],
142
- "properties": {
143
- "path": {
144
- "type": "string",
145
- "description": "HTTP path for a health check endpoint (for example, /ping)."
146
- }
147
- },
148
- "additionalProperties": false
149
- },
150
123
  "Discovery": {
151
124
  "type": "object",
152
125
  "properties": {
@@ -168,18 +141,8 @@
168
141
  "overrides": {
169
142
  "$ref": "#/$defs/EnvironmentOverrides"
170
143
  },
171
- "observability": {
172
- "$ref": "#/$defs/Observability"
173
- },
174
144
  "deployment": {
175
145
  "$ref": "#/$defs/Deployment"
176
- },
177
- "dataResidency": {
178
- "type": "string",
179
- "description": "Geographic region where data is stored for compliance."
180
- },
181
- "audit": {
182
- "$ref": "#/$defs/Audit"
183
146
  }
184
147
  },
185
148
  "additionalProperties": false
@@ -207,164 +170,12 @@
207
170
  "spec": {
208
171
  "$ref": "#/$defs/SpecReference"
209
172
  },
210
- "health": {
211
- "$ref": "#/$defs/Health"
212
- },
213
173
  "discovery": {
214
174
  "$ref": "#/$defs/Discovery"
215
- },
216
- "headers": {
217
- "type": "array",
218
- "description": "HTTP headers overrides for accessing this service's UniSpec document in this environment.",
219
- "items": {
220
- "$ref": "#/$defs/Header"
221
- }
222
- },
223
- "security": {
224
- "type": "array",
225
- "description": "Security requirements overrides for accessing this service's UniSpec document in this environment.",
226
- "items": {
227
- "$ref": "#/$defs/SecurityRequirement"
228
- }
229
- },
230
- "rateLimit": {
231
- "$ref": "#/$defs/RateLimit"
232
- }
233
- },
234
- "additionalProperties": false
235
- },
236
- "Header": {
237
- "type": "object",
238
- "required": ["name"],
239
- "properties": {
240
- "name": {
241
- "type": "string",
242
- "description": "Header name (case-insensitive)."
243
- },
244
- "description": {
245
- "type": "string",
246
- "description": "Human-readable description of the header."
247
- },
248
- "required": {
249
- "type": "boolean",
250
- "description": "Whether this header is required.",
251
- "default": false
252
- },
253
- "defaultValue": {
254
- "type": "string",
255
- "description": "Default value for the header."
256
- }
257
- },
258
- "additionalProperties": false
259
- },
260
- "SecurityRequirement": {
261
- "type": "array",
262
- "description": "Alternative set of named security schemes applied to a service or operation.",
263
- "items": {
264
- "$ref": "./types/common.schema.json#/$defs/Identifier"
265
- }
266
- },
267
- "Observability": {
268
- "type": "object",
269
- "description": "Observability configuration for the environment.",
270
- "properties": {
271
- "logging": {
272
- "type": "object",
273
- "properties": {
274
- "level": {
275
- "type": "string",
276
- "enum": ["debug", "info", "warn", "error"],
277
- "description": "Logging level."
278
- },
279
- "format": {
280
- "type": "string",
281
- "enum": ["json", "text"],
282
- "description": "Log format."
283
- },
284
- "fields": {
285
- "type": "array",
286
- "items": {
287
- "type": "string"
288
- },
289
- "description": "Additional fields to include in logs."
290
- }
291
- },
292
- "additionalProperties": false
293
- },
294
- "metrics": {
295
- "type": "object",
296
- "properties": {
297
- "enabled": {
298
- "type": "boolean",
299
- "description": "Whether metrics collection is enabled."
300
- },
301
- "endpoints": {
302
- "type": "array",
303
- "items": {
304
- "type": "string"
305
- },
306
- "description": "Metrics endpoints."
307
- },
308
- "customMetrics": {
309
- "type": "array",
310
- "items": {
311
- "$ref": "#/$defs/CustomMetric"
312
- },
313
- "description": "Custom metrics definitions."
314
- }
315
- },
316
- "additionalProperties": false
317
- },
318
- "tracing": {
319
- "type": "object",
320
- "properties": {
321
- "enabled": {
322
- "type": "boolean",
323
- "description": "Whether distributed tracing is enabled."
324
- },
325
- "samplingRate": {
326
- "type": "number",
327
- "minimum": 0,
328
- "maximum": 1,
329
- "description": "Sampling rate for traces (0.0 to 1.0)."
330
- },
331
- "exporter": {
332
- "type": "string",
333
- "description": "Tracing exporter (e.g., jaeger, zipkin)."
334
- }
335
- },
336
- "additionalProperties": false
337
175
  }
338
176
  },
339
177
  "additionalProperties": false
340
178
  },
341
- "CustomMetric": {
342
- "type": "object",
343
- "properties": {
344
- "name": {
345
- "type": "string",
346
- "description": "Metric name."
347
- },
348
- "type": {
349
- "type": "string",
350
- "enum": ["counter", "gauge", "histogram", "summary"],
351
- "description": "Metric type."
352
- },
353
- "description": {
354
- "type": "string",
355
- "description": "Metric description."
356
- },
357
- "labels": {
358
- "type": "array",
359
- "items": {
360
- "type": "string"
361
- },
362
- "description": "Metric labels."
363
- }
364
- },
365
- "required": ["name", "type"],
366
- "additionalProperties": false
367
- },
368
179
  "Deployment": {
369
180
  "type": "object",
370
181
  "description": "Deployment configuration for the environment.",
@@ -473,85 +284,31 @@
473
284
  },
474
285
  "additionalProperties": false
475
286
  },
476
- "RateLimit": {
287
+ "Authentication": {
477
288
  "type": "object",
478
- "description": "Rate limiting configuration for the service.",
289
+ "description": "Authentication configuration for accessing UniSpec documents.",
290
+ "required": ["bearer"],
479
291
  "properties": {
480
- "inherit": {
481
- "type": "boolean",
482
- "description": "Whether to inherit from parent rate limit configuration. When true, only specified fields override parent values.",
483
- "default": false
484
- },
485
- "requestsPerMinute": {
486
- "type": "integer",
487
- "minimum": 0,
488
- "description": "Maximum requests per minute."
489
- },
490
- "requestsPerHour": {
491
- "type": "integer",
492
- "minimum": 0,
493
- "description": "Maximum requests per hour."
494
- },
495
- "requestsPerDay": {
496
- "type": "integer",
497
- "minimum": 0,
498
- "description": "Maximum requests per day."
499
- },
500
- "burstLimit": {
501
- "type": "integer",
502
- "minimum": 0,
503
- "description": "Maximum burst requests allowed."
504
- },
505
- "perUser": {
506
- "type": "boolean",
507
- "description": "Whether rate limiting is applied per user.",
508
- "default": false
509
- },
510
- "perApiKey": {
511
- "type": "boolean",
512
- "description": "Whether rate limiting is applied per API key.",
513
- "default": false
514
- },
515
- "customKey": {
516
- "type": "string",
517
- "description": "Custom key for rate limiting (e.g., IP address, organization ID)."
292
+ "bearer": {
293
+ "$ref": "#/$defs/BearerAuth",
294
+ "description": "Bearer token authentication."
518
295
  }
519
296
  },
520
297
  "additionalProperties": false
521
298
  },
522
- "Audit": {
299
+ "BearerAuth": {
523
300
  "type": "object",
524
- "description": "Audit configuration for compliance.",
301
+ "description": "Bearer token authentication configuration.",
302
+ "required": ["token"],
525
303
  "properties": {
526
- "enabled": {
527
- "type": "boolean",
528
- "description": "Whether audit logging is enabled."
529
- },
530
- "retention": {
304
+ "token": {
531
305
  "type": "string",
532
- "description": "Audit log retention period."
533
- },
534
- "fields": {
535
- "type": "array",
536
- "items": {
537
- "type": "string"
538
- },
539
- "description": "Fields to include in audit logs."
306
+ "description": "Bearer token value. Can be a literal token or a reference to environment variable using ${ENV_VAR} syntax."
540
307
  },
541
- "export": {
542
- "type": "object",
543
- "properties": {
544
- "format": {
545
- "type": "string",
546
- "enum": ["json", "csv"],
547
- "description": "Export format."
548
- },
549
- "destination": {
550
- "type": "string",
551
- "description": "Export destination."
552
- }
553
- },
554
- "additionalProperties": false
308
+ "scheme": {
309
+ "type": "string",
310
+ "description": "Token scheme (defaults to 'Bearer').",
311
+ "default": "Bearer"
555
312
  }
556
313
  },
557
314
  "additionalProperties": false