@unispechq/unispec-core 0.2.13 → 0.3.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 +85 -160
- package/dist/cache/cache-factory.d.ts +31 -0
- package/dist/cache/cache-factory.js +65 -0
- package/dist/cache/cache-manager.d.ts +62 -0
- package/dist/cache/cache-manager.js +122 -0
- package/dist/cache/constants.d.ts +21 -0
- package/dist/cache/constants.js +22 -0
- package/dist/cache/hash-utils.d.ts +21 -0
- package/dist/cache/hash-utils.js +35 -0
- package/dist/cache/hashing.d.ts +19 -0
- package/dist/cache/hashing.js +197 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.js +10 -0
- package/dist/cache/lru-cache.d.ts +56 -0
- package/dist/cache/lru-cache.js +161 -0
- package/dist/cache/types.d.ts +24 -0
- package/dist/cache/types.js +4 -0
- package/dist/cjs/cache/cache-factory.js +72 -0
- package/dist/cjs/cache/cache-manager.js +126 -0
- package/dist/cjs/cache/constants.js +25 -0
- package/dist/cjs/cache/hash-utils.js +41 -0
- package/dist/cjs/cache/hashing.js +236 -0
- package/dist/cjs/cache/index.js +26 -0
- package/dist/cjs/cache/lru-cache.js +165 -0
- package/dist/cjs/cache/types.js +5 -0
- package/dist/cjs/diff/annotators.js +132 -0
- package/dist/cjs/diff/change-reports.js +369 -0
- package/dist/cjs/diff/core.js +158 -0
- package/dist/cjs/diff/enhanced-diff.js +79 -0
- package/dist/cjs/diff/impact-strategies-refactored.js +230 -0
- package/dist/cjs/diff/impact-strategies.js +219 -0
- package/dist/cjs/diff/index.js +25 -247
- package/dist/cjs/diff/metrics-calculator.js +69 -0
- package/dist/cjs/diff/risk-calculator.js +58 -0
- package/dist/cjs/diff/suggestion-generator.js +78 -0
- package/dist/cjs/diff/types.js +11 -0
- package/dist/cjs/errors/base-error.js +33 -0
- package/dist/cjs/errors/config-error.js +11 -0
- package/dist/cjs/errors/error-factory.js +48 -0
- package/dist/cjs/errors/index.js +19 -0
- package/dist/cjs/errors/loader-error.js +11 -0
- package/dist/cjs/errors/reference-error.js +11 -0
- package/dist/cjs/errors/schema-error.js +11 -0
- package/dist/cjs/errors/security-error.js +11 -0
- package/dist/cjs/errors/semantic-error.js +11 -0
- package/dist/cjs/generated-schemas.js +2100 -0
- package/dist/cjs/index.js +41 -5
- package/dist/cjs/loader/index.js +11 -75
- package/dist/cjs/loader/security-validator.js +53 -0
- package/dist/cjs/loader/types.js +11 -0
- package/dist/cjs/loader/unispec-loader.js +84 -0
- package/dist/cjs/loader/yaml-loader.js +76 -0
- package/dist/cjs/normalizer/core.js +32 -0
- package/dist/cjs/normalizer/graphql-normalizer.js +67 -0
- package/dist/cjs/normalizer/index.js +5 -119
- package/dist/cjs/normalizer/rest-normalizer.js +51 -0
- package/dist/cjs/normalizer/types.js +2 -0
- package/dist/cjs/normalizer/utils.js +33 -0
- package/dist/cjs/normalizer/websocket-normalizer.js +81 -0
- package/dist/cjs/optimizer/core.js +115 -0
- package/dist/cjs/optimizer/index.js +17 -0
- package/dist/cjs/optimizer/optimization-functions.js +185 -0
- package/dist/cjs/optimizer/types.js +2 -0
- package/dist/cjs/optimizer/utils.js +32 -0
- package/dist/cjs/schemas/dedupe.js +100 -0
- package/dist/cjs/schemas/index.js +12 -132
- package/dist/cjs/schemas/resolver.js +41 -0
- package/dist/cjs/schemas/utils.js +53 -0
- package/dist/cjs/types/index.js +0 -1
- package/dist/cjs/validator/ajv-validator.js +82 -0
- package/dist/cjs/validator/config-validator-main.js +34 -0
- package/dist/cjs/validator/config-validator.js +17 -0
- package/dist/cjs/validator/index.js +21 -108
- package/dist/cjs/validator/object-traversal.js +112 -0
- package/dist/cjs/validator/reference-validator.js +233 -0
- package/dist/cjs/validator/schema-references.js +116 -0
- package/dist/cjs/validator/semantic-validator.js +328 -0
- package/dist/cjs/validator/tests-validator.js +16 -0
- package/dist/cjs/validator/types.js +2 -0
- package/dist/cjs/validator/unispec-validator.js +84 -0
- package/dist/cjs/validator/validator-factory.js +77 -0
- package/dist/cjs/versions.js +147 -0
- package/dist/diff/annotators.d.ts +4 -0
- package/dist/diff/annotators.js +127 -0
- package/dist/diff/change-reports.d.ts +37 -0
- package/dist/diff/change-reports.js +366 -0
- package/dist/diff/core.d.ts +26 -0
- package/dist/diff/core.js +155 -0
- package/dist/diff/enhanced-diff.d.ts +51 -0
- package/dist/diff/enhanced-diff.js +76 -0
- package/dist/diff/impact-strategies-refactored.d.ts +69 -0
- package/dist/diff/impact-strategies-refactored.js +223 -0
- package/dist/diff/impact-strategies.d.ts +41 -0
- package/dist/diff/impact-strategies.js +212 -0
- package/dist/diff/index.d.ts +8 -34
- package/dist/diff/index.js +11 -246
- package/dist/diff/metrics-calculator.d.ts +23 -0
- package/dist/diff/metrics-calculator.js +65 -0
- package/dist/diff/risk-calculator.d.ts +23 -0
- package/dist/diff/risk-calculator.js +55 -0
- package/dist/diff/suggestion-generator.d.ts +18 -0
- package/dist/diff/suggestion-generator.js +74 -0
- package/dist/diff/types.d.ts +24 -0
- package/dist/diff/types.js +8 -0
- package/dist/errors/base-error.d.ts +20 -0
- package/dist/errors/base-error.js +29 -0
- package/dist/errors/config-error.d.ts +4 -0
- package/dist/errors/config-error.js +7 -0
- package/dist/errors/error-factory.d.ts +22 -0
- package/dist/errors/error-factory.js +45 -0
- package/dist/errors/index.d.ts +8 -0
- package/dist/errors/index.js +8 -0
- package/dist/errors/loader-error.d.ts +4 -0
- package/dist/errors/loader-error.js +7 -0
- package/dist/errors/reference-error.d.ts +4 -0
- package/dist/errors/reference-error.js +7 -0
- package/dist/errors/schema-error.d.ts +4 -0
- package/dist/errors/schema-error.js +7 -0
- package/dist/errors/security-error.d.ts +4 -0
- package/dist/errors/security-error.js +7 -0
- package/dist/errors/semantic-error.d.ts +4 -0
- package/dist/errors/semantic-error.js +7 -0
- package/dist/generated-schemas.d.ts +2073 -0
- package/dist/generated-schemas.js +2097 -0
- package/dist/index.cjs +41 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.js +41 -5
- package/dist/loader/index.d.ts +5 -12
- package/dist/loader/index.js +5 -41
- package/dist/loader/security-validator.d.ts +5 -0
- package/dist/loader/security-validator.js +50 -0
- package/dist/loader/types.d.ts +30 -0
- package/dist/loader/types.js +8 -0
- package/dist/loader/unispec-loader.d.ts +10 -0
- package/dist/loader/unispec-loader.js +81 -0
- package/dist/loader/yaml-loader.d.ts +10 -0
- package/dist/loader/yaml-loader.js +39 -0
- package/dist/normalizer/core.d.ts +24 -0
- package/dist/normalizer/core.js +29 -0
- package/dist/normalizer/graphql-normalizer.d.ts +8 -0
- package/dist/normalizer/graphql-normalizer.js +64 -0
- package/dist/normalizer/index.d.ts +2 -25
- package/dist/normalizer/index.js +3 -118
- package/dist/normalizer/rest-normalizer.d.ts +8 -0
- package/dist/normalizer/rest-normalizer.js +48 -0
- package/dist/normalizer/types.d.ts +7 -0
- package/dist/normalizer/types.js +1 -0
- package/dist/normalizer/utils.d.ts +14 -0
- package/dist/normalizer/utils.js +29 -0
- package/dist/normalizer/websocket-normalizer.d.ts +8 -0
- package/dist/normalizer/websocket-normalizer.js +78 -0
- package/dist/optimizer/core.d.ts +17 -0
- package/dist/optimizer/core.js +111 -0
- package/dist/optimizer/index.d.ts +4 -0
- package/dist/optimizer/index.js +7 -0
- package/dist/optimizer/optimization-functions.d.ts +32 -0
- package/dist/optimizer/optimization-functions.js +179 -0
- package/dist/optimizer/types.d.ts +28 -0
- package/dist/optimizer/types.js +1 -0
- package/dist/optimizer/utils.d.ts +7 -0
- package/dist/optimizer/utils.js +29 -0
- package/dist/schemas/dedupe.d.ts +9 -0
- package/dist/schemas/dedupe.js +97 -0
- package/dist/schemas/index.d.ts +3 -4
- package/dist/schemas/index.js +6 -129
- package/dist/schemas/resolver.d.ts +19 -0
- package/dist/schemas/resolver.js +37 -0
- package/dist/schemas/utils.d.ts +20 -0
- package/dist/schemas/utils.js +49 -0
- package/dist/types/index.d.ts +279 -41
- package/dist/types/index.js +0 -1
- package/dist/validator/ajv-validator.d.ts +15 -0
- package/dist/validator/ajv-validator.js +75 -0
- package/dist/validator/config-validator-main.d.ts +10 -0
- package/dist/validator/config-validator-main.js +31 -0
- package/dist/validator/config-validator.d.ts +5 -0
- package/dist/validator/config-validator.js +14 -0
- package/dist/validator/index.d.ts +10 -23
- package/dist/validator/index.js +11 -103
- package/dist/validator/object-traversal.d.ts +52 -0
- package/dist/validator/object-traversal.js +104 -0
- package/dist/validator/reference-validator.d.ts +31 -0
- package/dist/validator/reference-validator.js +230 -0
- package/dist/validator/schema-references.d.ts +23 -0
- package/dist/validator/schema-references.js +111 -0
- package/dist/validator/semantic-validator.d.ts +26 -0
- package/dist/validator/semantic-validator.js +325 -0
- package/dist/validator/tests-validator.d.ts +9 -0
- package/dist/validator/tests-validator.js +13 -0
- package/dist/validator/types.d.ts +29 -0
- package/dist/validator/types.js +1 -0
- package/dist/validator/unispec-validator.d.ts +15 -0
- package/dist/validator/unispec-validator.js +81 -0
- package/dist/validator/validator-factory.d.ts +10 -0
- package/dist/validator/validator-factory.js +73 -0
- package/dist/versions.d.ts +10 -0
- package/dist/versions.js +143 -0
- package/package.json +11 -9
- package/dist/cjs/converters/index.js +0 -204
- package/dist/cjs/validator/generated-schemas.js +0 -827
- package/dist/converters/index.d.ts +0 -14
- package/dist/converters/index.js +0 -199
- package/dist/validator/generated-schemas.d.ts +0 -842
- package/dist/validator/generated-schemas.js +0 -824
package/README.md
CHANGED
|
@@ -1,187 +1,119 @@
|
|
|
1
|
-
# UniSpec Core
|
|
2
|
-
|
|
1
|
+
# UniSpec Core Engine
|
|
2
|
+
|
|
3
|
+
**The official UniSpec Core Engine package — parser, validator, normalizer, diff engine for the UniSpec format**
|
|
3
4
|
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
## 🚀 Overview
|
|
7
|
+
## 🚀 Quick Overview
|
|
7
8
|
|
|
8
|
-
**UniSpec Core Engine** is the central runtime package of the UniSpec ecosystem.
|
|
9
|
-
It implements the mechanics of the **UniSpec Format**: loading, JSON Schema validation, normalization, diffing, and conversion to other formats.
|
|
9
|
+
**UniSpec Core Engine** is the central runtime package of the UniSpec ecosystem. It implements the mechanics of the **UniSpec Format**: loading, JSON Schema validation, normalization, and diffing.
|
|
10
10
|
|
|
11
11
|
This repository contains **only the Core Engine**, which is consumed by other UniSpec platform components (CLI, Registry, Portal, adapters, SDKs) that live in separate repositories.
|
|
12
12
|
|
|
13
|
-
Core
|
|
13
|
+
### Core Capabilities
|
|
14
14
|
|
|
15
|
-
- 🧠 **Core Engine** — parser, validator, normalizer, diff engine
|
|
16
|
-
-
|
|
17
|
-
- 🧩 **Shared types and utilities** — types and helper functions used
|
|
15
|
+
- 🧠 **Core Engine** — parser, validator, normalizer, diff engine
|
|
16
|
+
- 📋 **UniSpec Config** — configuration file support for multi-service setups
|
|
17
|
+
- 🧩 **Shared types and utilities** — types and helper functions used across the UniSpec ecosystem
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
### Protocol Support
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
21
|
+
UniSpec unifies documentation for:
|
|
22
|
+
- REST APIs
|
|
23
|
+
- GraphQL APIs
|
|
24
|
+
- WebSocket APIs
|
|
24
25
|
- Event-driven APIs (future)
|
|
25
|
-
- Multi-service architectures
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## 📦 Repository Structure
|
|
30
|
-
|
|
31
|
-
```pgsql
|
|
32
|
-
unispec-core/
|
|
33
|
-
├─ src/
|
|
34
|
-
│ ├─ loader/ # File loading (YAML/JSON → JS object)
|
|
35
|
-
│ ├─ validator/ # JSON Schema validation
|
|
36
|
-
│ ├─ normalizer/ # UniSpec structure normalization
|
|
37
|
-
│ ├─ diff/ # Comparison of two UniSpec documents
|
|
38
|
-
│ ├─ converters/ # OpenAPI, GraphQL SDL, WS, etc.
|
|
39
|
-
│ ├─ types/ # UniSpec types/interfaces
|
|
40
|
-
│ ├─ utils/ # Small helpers
|
|
41
|
-
│ └─ index.ts # Public API
|
|
42
|
-
├─ tests/ # Unit tests
|
|
43
|
-
├─ package.json
|
|
44
|
-
└─ README.md
|
|
45
|
-
```
|
|
26
|
+
- Multi-service architectures
|
|
46
27
|
|
|
47
28
|
---
|
|
48
29
|
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
### 📐 1. UniSpec Format
|
|
52
|
-
Defined in a separate repository: **`unispec-spec`**.
|
|
53
|
-
UniSpec Core Engine *implements* this format but does **not** define it.
|
|
54
|
-
|
|
55
|
-
### 🧱 2. Core Engine
|
|
56
|
-
Located in this repository, under the `src/` directory.
|
|
57
|
-
|
|
58
|
-
Core Engine provides:
|
|
59
|
-
|
|
60
|
-
- YAML/JSON loader
|
|
61
|
-
- JSON Schema validator
|
|
62
|
-
– Normalizer → canonical UniSpec output (REST routes, GraphQL operations, WebSocket channels/messages)
|
|
63
|
-
– Diff engine (with basic breaking / non-breaking classification for REST, GraphQL and WebSocket)
|
|
64
|
-
– Converters:
|
|
65
|
-
- UniSpec → OpenAPI (REST-centric)
|
|
66
|
-
- UniSpec → GraphQL SDL
|
|
67
|
-
- UniSpec → WebSocket channel models for dashboards
|
|
68
|
-
|
|
69
|
-
This is the foundation used by:
|
|
70
|
-
|
|
71
|
-
- the CLI (in a separate repository/package)
|
|
72
|
-
- framework adapters
|
|
73
|
-
- Registry and Portal (as separate UniSpec platform services)
|
|
74
|
-
|
|
75
|
-
### 🌉 3. Protocol Coverage in Core
|
|
76
|
-
|
|
77
|
-
At the level of the Core Engine, protocol support is intentionally minimal but deterministic:
|
|
78
|
-
|
|
79
|
-
- **REST**
|
|
80
|
-
- Typed REST surface defined by `service.protocols.rest.routes[]` and reusable `service.schemas`.
|
|
81
|
-
- Normalizer orders routes by `name` (or `path + method`) for stable diffs.
|
|
82
|
-
- Diff engine annotates route additions and removals with breaking/non-breaking severity.
|
|
83
|
-
- Converter exposes REST as an OpenAPI 3.1 document built from routes, schemas and environments, while preserving the original UniSpec under `x-unispec`.
|
|
84
|
-
|
|
85
|
-
- **GraphQL**
|
|
86
|
-
- Typed protocol with `schema` (SDL string) and `queries`/`mutations`/`subscriptions` as operation lists.
|
|
87
|
-
- Normalizer orders operation names within each bucket.
|
|
88
|
-
- Diff engine annotates operation additions/removals as non-breaking/breaking.
|
|
89
|
-
- Converter either passes through user-provided SDL or generates a minimal, deterministic SDL shell.
|
|
90
|
-
|
|
91
|
-
- **WebSocket**
|
|
92
|
-
- Typed protocol with channels and messages backed by reusable schemas and security schemes.
|
|
93
|
-
- Normalizer orders channels by name and messages by `name` within each channel.
|
|
94
|
-
- Diff engine annotates channel/message additions/removals as non-breaking/breaking changes.
|
|
95
|
-
- Converter produces a dashboard-friendly model with service metadata, a normalized channel list and the raw protocol.
|
|
96
|
-
|
|
97
|
-
### 💻 4. CLI (separate platform component)
|
|
98
|
-
The CLI uses UniSpec Core Engine for validation, conversion, and working with UniSpec specifications.
|
|
30
|
+
## 🏁 Getting Started
|
|
99
31
|
|
|
100
|
-
|
|
32
|
+
### Installation
|
|
101
33
|
|
|
102
|
-
```
|
|
103
|
-
unispec
|
|
104
|
-
unispec push
|
|
105
|
-
unispec dev
|
|
106
|
-
unispec open
|
|
107
|
-
unispec diff
|
|
108
|
-
unispec convert
|
|
34
|
+
```bash
|
|
35
|
+
npm install @unispechq/unispec-core
|
|
109
36
|
```
|
|
110
37
|
|
|
38
|
+
### Basic Usage
|
|
111
39
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Effectively acts as the "system of record" for all APIs in the company.
|
|
40
|
+
```javascript
|
|
41
|
+
import { validateUniSpec, loadUniSpec } from '@unispechq/unispec-core';
|
|
115
42
|
|
|
116
|
-
|
|
117
|
-
|
|
43
|
+
// Load and validate a UniSpec document
|
|
44
|
+
const spec = await loadUniSpec('./unispec.yaml');
|
|
45
|
+
const result = await validateUniSpec(spec);
|
|
118
46
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
47
|
+
if (result.valid) {
|
|
48
|
+
console.log('✅ Valid UniSpec document');
|
|
49
|
+
} else {
|
|
50
|
+
console.log('❌ Validation errors:', result.errors);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
124
53
|
|
|
125
54
|
---
|
|
126
55
|
|
|
127
|
-
##
|
|
128
|
-
|
|
129
|
-
###
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
56
|
+
## 📚 Documentation
|
|
57
|
+
|
|
58
|
+
### 📖 [Core Concepts](docs/core-concepts.md)
|
|
59
|
+
- UniSpec format overview
|
|
60
|
+
- Core Engine architecture
|
|
61
|
+
- Protocol coverage details
|
|
62
|
+
- Platform components explanation
|
|
63
|
+
- Use cases and deployment patterns
|
|
64
|
+
|
|
65
|
+
### 💡 [Usage Examples](docs/usage-examples.md)
|
|
66
|
+
- Document validation
|
|
67
|
+
- Configuration support
|
|
68
|
+
- Schema reference resolution
|
|
69
|
+
- Enhanced diff analysis
|
|
70
|
+
- Performance optimization
|
|
71
|
+
- Error handling patterns
|
|
72
|
+
|
|
73
|
+
### 🔧 [API Reference](docs/api.md)
|
|
74
|
+
- Complete function documentation
|
|
75
|
+
- Type definitions and interfaces
|
|
76
|
+
- Configuration options
|
|
77
|
+
- Error types and codes
|
|
78
|
+
- Performance considerations
|
|
79
|
+
|
|
80
|
+
### 🛠️ [Development Guide](docs/development.md)
|
|
81
|
+
- Repository structure
|
|
82
|
+
- Development setup
|
|
83
|
+
- Testing guidelines
|
|
84
|
+
- Build process
|
|
85
|
+
- Contributing guidelines
|
|
86
|
+
- Plugin development
|
|
147
87
|
|
|
148
88
|
---
|
|
149
89
|
|
|
150
|
-
##
|
|
151
|
-
|
|
152
|
-
### 1. Clone the repo
|
|
153
|
-
|
|
154
|
-
```pgsql
|
|
155
|
-
git clone https://github.com/unispec/unispec-core.git
|
|
156
|
-
cd unispec-core
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### 2. Install dependencies
|
|
90
|
+
## 📦 Repository Structure
|
|
160
91
|
|
|
161
|
-
```pgsql
|
|
162
|
-
pnpm install
|
|
163
92
|
```
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
93
|
+
unispec-core/
|
|
94
|
+
├─ src/
|
|
95
|
+
│ ├─ loader/ # File loading with security
|
|
96
|
+
│ ├─ validator/ # JSON Schema validation
|
|
97
|
+
│ ├─ normalizer/ # Structure normalization
|
|
98
|
+
│ ├─ diff/ # Enhanced comparison
|
|
99
|
+
│ ├─ cache/ # LRU caching
|
|
100
|
+
│ ├─ types/ # TypeScript interfaces
|
|
101
|
+
│ └─ index.ts # Public API
|
|
102
|
+
├─ tests/ # Unit and integration tests
|
|
103
|
+
├─ docs/ # Detailed documentation
|
|
104
|
+
└─ scripts/ # Build and release scripts
|
|
169
105
|
```
|
|
170
106
|
|
|
171
|
-
### 4. Run locally (dev mode)
|
|
172
|
-
|
|
173
107
|
---
|
|
174
108
|
|
|
175
109
|
## 🤝 Contributing
|
|
176
110
|
|
|
177
|
-
Contributions are welcome!
|
|
178
|
-
Before contributing, please review:
|
|
111
|
+
Contributions are welcome! Before contributing, please review:
|
|
179
112
|
|
|
180
|
-
-
|
|
181
|
-
- `.windsurfrules`
|
|
113
|
+
- [Development Guide](docs/development.md)
|
|
114
|
+
- [`.windsurfrules`](.windsurfrules)
|
|
182
115
|
|
|
183
116
|
All core changes must comply with:
|
|
184
|
-
|
|
185
117
|
- the UniSpec format from `unispec-spec`
|
|
186
118
|
- compatibility rules
|
|
187
119
|
- test coverage
|
|
@@ -189,19 +121,19 @@ All core changes must comply with:
|
|
|
189
121
|
|
|
190
122
|
---
|
|
191
123
|
|
|
192
|
-
## Related Repositories
|
|
124
|
+
## 📊 Related Repositories
|
|
193
125
|
|
|
194
126
|
| Repository | Purpose |
|
|
195
127
|
|------------------------|---------|
|
|
196
128
|
| `unispec-spec` | UniSpec format definition (schemas, examples) |
|
|
197
129
|
| `unispec-core` | **This repo** — UniSpec Core Engine implementation |
|
|
198
130
|
| `unispec-docs` | Documentation site |
|
|
199
|
-
| `unispec-js-adapters` | Framework integrations (Express/Nest/Fastify)
|
|
200
|
-
| `unispec-infra` | Helm charts, Docker, Terraform for
|
|
131
|
+
| `unispec-js-adapters` | Framework integrations (Express/Nest/Fastify) |
|
|
132
|
+
| `unispec-infra` | Helm charts, Docker, Terraform for deployment |
|
|
201
133
|
|
|
202
134
|
---
|
|
203
135
|
|
|
204
|
-
## License
|
|
136
|
+
## 📄 License
|
|
205
137
|
|
|
206
138
|
UniSpec Core Engine is open-source and free to use under the MIT License.
|
|
207
139
|
|
|
@@ -209,15 +141,8 @@ UniSpec Core Engine is open-source and free to use under the MIT License.
|
|
|
209
141
|
|
|
210
142
|
## 🔥 Summary
|
|
211
143
|
|
|
212
|
-
`unispec-core` is the **heart of the UniSpec ecosystem** at the code level.
|
|
213
|
-
It provides the Core Engine used to:
|
|
214
|
-
|
|
215
|
-
- validate
|
|
216
|
-
- normalize
|
|
217
|
-
- diff
|
|
218
|
-
- convert
|
|
219
|
-
- and integrate
|
|
220
|
-
|
|
221
|
-
API specifications in the UniSpec format.
|
|
144
|
+
`unispec-core` is the **heart of the UniSpec ecosystem** at the code level. It provides the Core Engine used to validate, normalize, diff, and integrate API specifications in the UniSpec format.
|
|
222
145
|
|
|
223
146
|
If you're building tools, adapters, or platform services that rely on UniSpec → **this is where the engine lives.**
|
|
147
|
+
|
|
148
|
+
For detailed information, explore the [documentation](docs/) folder.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { UniSpecCacheManager } from "./cache-manager.js";
|
|
2
|
+
import type { CacheOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Create a new isolated cache manager instance.
|
|
5
|
+
* @param options - Cache configuration options
|
|
6
|
+
* @returns New cache manager instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCacheManager(options?: CacheOptions): UniSpecCacheManager;
|
|
9
|
+
/**
|
|
10
|
+
* Create a named cache manager instance with simple registry.
|
|
11
|
+
* @param name - Instance name for identification
|
|
12
|
+
* @param options - Cache configuration options
|
|
13
|
+
* @returns Cache manager instance
|
|
14
|
+
*/
|
|
15
|
+
export declare function createNamedCacheManager(name?: string, options?: CacheOptions): UniSpecCacheManager;
|
|
16
|
+
/**
|
|
17
|
+
* Get cache manager statistics for multiple instances.
|
|
18
|
+
* @param managers - Array of cache manager instances
|
|
19
|
+
* @returns Statistics for all provided managers
|
|
20
|
+
*/
|
|
21
|
+
export declare function getManagersStats(managers: UniSpecCacheManager[]): Record<string, ReturnType<UniSpecCacheManager["getStats"]>>;
|
|
22
|
+
/**
|
|
23
|
+
* Destroy multiple cache manager instances.
|
|
24
|
+
* @param managers - Array of cache manager instances to destroy
|
|
25
|
+
*/
|
|
26
|
+
export declare function destroyManagers(managers: UniSpecCacheManager[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Clear test registry (for testing only).
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearTestRegistry(): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { UniSpecCacheManager } from "./cache-manager.js";
|
|
2
|
+
/**
|
|
3
|
+
* Simple registry for test cleanup (minimal, not persistent global state)
|
|
4
|
+
*/
|
|
5
|
+
const testRegistry = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Create a new isolated cache manager instance.
|
|
8
|
+
* @param options - Cache configuration options
|
|
9
|
+
* @returns New cache manager instance
|
|
10
|
+
*/
|
|
11
|
+
export function createCacheManager(options) {
|
|
12
|
+
return new UniSpecCacheManager(options);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a named cache manager instance with simple registry.
|
|
16
|
+
* @param name - Instance name for identification
|
|
17
|
+
* @param options - Cache configuration options
|
|
18
|
+
* @returns Cache manager instance
|
|
19
|
+
*/
|
|
20
|
+
export function createNamedCacheManager(name = "default", options) {
|
|
21
|
+
// For testing, keep simple registry to enable cleanup
|
|
22
|
+
if (testRegistry.has(name)) {
|
|
23
|
+
const existing = testRegistry.get(name);
|
|
24
|
+
if (existing) {
|
|
25
|
+
existing.destroy(); // Cleanup existing instance
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const manager = new UniSpecCacheManager(options);
|
|
29
|
+
manager._name = name; // Store name for debugging
|
|
30
|
+
testRegistry.set(name, manager); // Add to registry for cleanup
|
|
31
|
+
return manager;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get cache manager statistics for multiple instances.
|
|
35
|
+
* @param managers - Array of cache manager instances
|
|
36
|
+
* @returns Statistics for all provided managers
|
|
37
|
+
*/
|
|
38
|
+
export function getManagersStats(managers) {
|
|
39
|
+
const stats = {};
|
|
40
|
+
for (const [index, manager] of managers.entries()) {
|
|
41
|
+
const name = manager._name ||
|
|
42
|
+
`manager_${index}`;
|
|
43
|
+
stats[name] = manager.getStats();
|
|
44
|
+
}
|
|
45
|
+
return stats;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Destroy multiple cache manager instances.
|
|
49
|
+
* @param managers - Array of cache manager instances to destroy
|
|
50
|
+
*/
|
|
51
|
+
export function destroyManagers(managers) {
|
|
52
|
+
for (const manager of managers) {
|
|
53
|
+
manager.destroy();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Clear test registry (for testing only).
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export function clearTestRegistry() {
|
|
61
|
+
for (const manager of testRegistry.values()) {
|
|
62
|
+
manager.destroy();
|
|
63
|
+
}
|
|
64
|
+
testRegistry.clear();
|
|
65
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ValidationResult } from "../types/index.js";
|
|
2
|
+
import type { CacheOptions, CacheStats } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Cache manager for UniSpec operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare class UniSpecCacheManager {
|
|
7
|
+
private validationCache;
|
|
8
|
+
private normalizationCache;
|
|
9
|
+
private diffCache;
|
|
10
|
+
private cleanupInterval;
|
|
11
|
+
constructor(options?: CacheOptions);
|
|
12
|
+
/**
|
|
13
|
+
* Get cached validation result asynchronously.
|
|
14
|
+
*/
|
|
15
|
+
getValidationResult(documentHash: string): Promise<ValidationResult | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* Cache validation result asynchronously.
|
|
18
|
+
*/
|
|
19
|
+
setValidationResult(documentHash: string, result: ValidationResult): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Get cached normalization result asynchronously.
|
|
22
|
+
*/
|
|
23
|
+
getNormalizationResult(documentHash: string): Promise<unknown>;
|
|
24
|
+
/**
|
|
25
|
+
* Cache normalization result asynchronously.
|
|
26
|
+
*/
|
|
27
|
+
setNormalizationResult(documentHash: string, result: unknown): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Get cached diff result asynchronously.
|
|
30
|
+
*/
|
|
31
|
+
getDiffResult(docsHash: string): Promise<unknown>;
|
|
32
|
+
/**
|
|
33
|
+
* Cache diff result asynchronously.
|
|
34
|
+
*/
|
|
35
|
+
setDiffResult(docsHash: string, result: unknown): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Get comprehensive cache statistics.
|
|
38
|
+
*/
|
|
39
|
+
getStats(): {
|
|
40
|
+
validation: CacheStats;
|
|
41
|
+
normalization: CacheStats;
|
|
42
|
+
diff: CacheStats;
|
|
43
|
+
total: {
|
|
44
|
+
size: number;
|
|
45
|
+
hits: number;
|
|
46
|
+
misses: number;
|
|
47
|
+
hitRate: number;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Clear all caches.
|
|
52
|
+
*/
|
|
53
|
+
clearAll(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Start automatic cleanup interval.
|
|
56
|
+
*/
|
|
57
|
+
private startCleanup;
|
|
58
|
+
/**
|
|
59
|
+
* Stop automatic cleanup.
|
|
60
|
+
*/
|
|
61
|
+
destroy(): void;
|
|
62
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { CACHE_CONSTANTS, CACHE_MESSAGES } from "./constants.js";
|
|
2
|
+
import { LRUCache } from "./lru-cache.js";
|
|
3
|
+
/**
|
|
4
|
+
* Cache manager for UniSpec operations.
|
|
5
|
+
*/
|
|
6
|
+
export class UniSpecCacheManager {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.cleanupInterval = null;
|
|
9
|
+
this.validationCache = new LRUCache({
|
|
10
|
+
...options,
|
|
11
|
+
maxSize: CACHE_CONSTANTS.VALIDATION_MAX_SIZE,
|
|
12
|
+
});
|
|
13
|
+
this.normalizationCache = new LRUCache({
|
|
14
|
+
...options,
|
|
15
|
+
maxSize: CACHE_CONSTANTS.NORMALIZATION_MAX_SIZE,
|
|
16
|
+
});
|
|
17
|
+
this.diffCache = new LRUCache({
|
|
18
|
+
...options,
|
|
19
|
+
maxSize: CACHE_CONSTANTS.DIFF_MAX_SIZE,
|
|
20
|
+
});
|
|
21
|
+
// Start cleanup interval
|
|
22
|
+
this.startCleanup();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get cached validation result asynchronously.
|
|
26
|
+
*/
|
|
27
|
+
async getValidationResult(documentHash) {
|
|
28
|
+
return await this.validationCache.get(documentHash);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Cache validation result asynchronously.
|
|
32
|
+
*/
|
|
33
|
+
async setValidationResult(documentHash, result) {
|
|
34
|
+
await this.validationCache.set(documentHash, result);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get cached normalization result asynchronously.
|
|
38
|
+
*/
|
|
39
|
+
async getNormalizationResult(documentHash) {
|
|
40
|
+
return await this.normalizationCache.get(documentHash);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Cache normalization result asynchronously.
|
|
44
|
+
*/
|
|
45
|
+
async setNormalizationResult(documentHash, result) {
|
|
46
|
+
await this.normalizationCache.set(documentHash, result);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get cached diff result asynchronously.
|
|
50
|
+
*/
|
|
51
|
+
async getDiffResult(docsHash) {
|
|
52
|
+
return await this.diffCache.get(docsHash);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Cache diff result asynchronously.
|
|
56
|
+
*/
|
|
57
|
+
async setDiffResult(docsHash, result) {
|
|
58
|
+
await this.diffCache.set(docsHash, result);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get comprehensive cache statistics.
|
|
62
|
+
*/
|
|
63
|
+
getStats() {
|
|
64
|
+
const validationStats = this.validationCache.getStats();
|
|
65
|
+
const normalizationStats = this.normalizationCache.getStats();
|
|
66
|
+
const diffStats = this.diffCache.getStats();
|
|
67
|
+
const total = {
|
|
68
|
+
size: validationStats.size + normalizationStats.size + diffStats.size,
|
|
69
|
+
hits: validationStats.hits + normalizationStats.hits + diffStats.hits,
|
|
70
|
+
misses: validationStats.misses + normalizationStats.misses + diffStats.misses,
|
|
71
|
+
hitRate: 0,
|
|
72
|
+
};
|
|
73
|
+
const totalRequests = total.hits + total.misses;
|
|
74
|
+
total.hitRate = totalRequests > 0 ? total.hits / totalRequests : 0;
|
|
75
|
+
return {
|
|
76
|
+
validation: validationStats,
|
|
77
|
+
normalization: normalizationStats,
|
|
78
|
+
diff: diffStats,
|
|
79
|
+
total,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Clear all caches.
|
|
84
|
+
*/
|
|
85
|
+
clearAll() {
|
|
86
|
+
this.validationCache.clear();
|
|
87
|
+
this.normalizationCache.clear();
|
|
88
|
+
this.diffCache.clear();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Start automatic cleanup interval.
|
|
92
|
+
*/
|
|
93
|
+
startCleanup() {
|
|
94
|
+
try {
|
|
95
|
+
this.cleanupInterval = setInterval(() => {
|
|
96
|
+
try {
|
|
97
|
+
this.validationCache.cleanup();
|
|
98
|
+
this.normalizationCache.cleanup();
|
|
99
|
+
this.diffCache.cleanup();
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error(CACHE_MESSAGES.CLEANUP_ERROR, error);
|
|
103
|
+
// Continue running cleanup even if one cache fails
|
|
104
|
+
}
|
|
105
|
+
}, CACHE_CONSTANTS.CLEANUP_INTERVAL);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error(CACHE_MESSAGES.CLEANUP_START_ERROR, error);
|
|
109
|
+
// Cache will still work without automatic cleanup
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Stop automatic cleanup.
|
|
114
|
+
*/
|
|
115
|
+
destroy() {
|
|
116
|
+
if (this.cleanupInterval) {
|
|
117
|
+
clearInterval(this.cleanupInterval);
|
|
118
|
+
this.cleanupInterval = null;
|
|
119
|
+
}
|
|
120
|
+
this.clearAll();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache configuration constants.
|
|
3
|
+
*/
|
|
4
|
+
export declare const CACHE_CONSTANTS: {
|
|
5
|
+
readonly DEFAULT_MAX_SIZE: 100;
|
|
6
|
+
readonly VALIDATION_MAX_SIZE: 50;
|
|
7
|
+
readonly NORMALIZATION_MAX_SIZE: 30;
|
|
8
|
+
readonly DIFF_MAX_SIZE: 20;
|
|
9
|
+
readonly DEFAULT_TTL: number;
|
|
10
|
+
readonly CLEANUP_INTERVAL: 60000;
|
|
11
|
+
readonly HASH_GOLDEN_RATIO: 2654435761;
|
|
12
|
+
readonly HASH_BASE: 31;
|
|
13
|
+
readonly HASH_MASK: 4294967295;
|
|
14
|
+
};
|
|
15
|
+
export declare const CACHE_MESSAGES: {
|
|
16
|
+
readonly CLEANUP_ERROR: "Cache cleanup error";
|
|
17
|
+
readonly CLEANUP_START_ERROR: "Failed to start cleanup interval";
|
|
18
|
+
readonly CACHE_WILL_CONTINUE: "Cache will still work without automatic cleanup";
|
|
19
|
+
};
|
|
20
|
+
export type CacheSize = typeof CACHE_CONSTANTS.DEFAULT_MAX_SIZE | typeof CACHE_CONSTANTS.VALIDATION_MAX_SIZE | typeof CACHE_CONSTANTS.NORMALIZATION_MAX_SIZE | typeof CACHE_CONSTANTS.DIFF_MAX_SIZE;
|
|
21
|
+
export type TTL = typeof CACHE_CONSTANTS.DEFAULT_TTL | typeof CACHE_CONSTANTS.CLEANUP_INTERVAL;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache configuration constants.
|
|
3
|
+
*/
|
|
4
|
+
export const CACHE_CONSTANTS = {
|
|
5
|
+
// Default cache sizes
|
|
6
|
+
DEFAULT_MAX_SIZE: 100,
|
|
7
|
+
VALIDATION_MAX_SIZE: 50,
|
|
8
|
+
NORMALIZATION_MAX_SIZE: 30,
|
|
9
|
+
DIFF_MAX_SIZE: 20,
|
|
10
|
+
// TTL values (in milliseconds)
|
|
11
|
+
DEFAULT_TTL: 5 * 60 * 1000, // 5 minutes
|
|
12
|
+
CLEANUP_INTERVAL: 60000, // 1 minute
|
|
13
|
+
// Hash configuration
|
|
14
|
+
HASH_GOLDEN_RATIO: 2654435761,
|
|
15
|
+
HASH_BASE: 31,
|
|
16
|
+
HASH_MASK: 0xffffffff,
|
|
17
|
+
};
|
|
18
|
+
export const CACHE_MESSAGES = {
|
|
19
|
+
CLEANUP_ERROR: "Cache cleanup error",
|
|
20
|
+
CLEANUP_START_ERROR: "Failed to start cleanup interval",
|
|
21
|
+
CACHE_WILL_CONTINUE: "Cache will still work without automatic cleanup",
|
|
22
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { UniSpecDocument } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a hash for a UniSpec document for caching purposes.
|
|
4
|
+
* Uses optimized hashing for better performance and collision resistance.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateDocumentHash(document: UniSpecDocument): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Synchronous version for backward compatibility (deprecated).
|
|
9
|
+
* @deprecated Use async version for better security
|
|
10
|
+
*/
|
|
11
|
+
export declare function generateDocumentHashSync(document: UniSpecDocument): string;
|
|
12
|
+
/**
|
|
13
|
+
* Generate a hash for two documents (for diff caching).
|
|
14
|
+
* Uses optimized diff hashing with better collision resistance.
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateDiffHash(oldDoc: UniSpecDocument, newDoc: UniSpecDocument): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Synchronous version for backward compatibility (deprecated).
|
|
19
|
+
* @deprecated Use async version for better security
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateDiffHashSync(oldDoc: UniSpecDocument, newDoc: UniSpecDocument): string;
|