@unispechq/unispec-core 0.1.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/.github/workflows/npm-publish.yml +74 -0
- package/.windsurfrules +138 -0
- package/README.md +223 -0
- package/dist/converters/index.d.ts +13 -0
- package/dist/converters/index.js +89 -0
- package/dist/diff/index.d.ts +21 -0
- package/dist/diff/index.js +195 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/loader/index.d.ts +13 -0
- package/dist/loader/index.js +19 -0
- package/dist/normalizer/index.d.ts +11 -0
- package/dist/normalizer/index.js +116 -0
- package/dist/types/index.d.ts +57 -0
- package/dist/types/index.js +1 -0
- package/dist/validator/index.d.ts +7 -0
- package/dist/validator/index.js +47 -0
- package/package.json +28 -0
- package/scripts/release.js +51 -0
- package/src/converters/index.ts +120 -0
- package/src/diff/index.ts +235 -0
- package/src/index.ts +6 -0
- package/src/loader/index.ts +25 -0
- package/src/normalizer/index.ts +156 -0
- package/src/types/index.ts +67 -0
- package/src/validator/index.ts +61 -0
- package/tests/converters.test.mjs +126 -0
- package/tests/diff.test.mjs +240 -0
- package/tests/loader-validator.test.mjs +19 -0
- package/tests/normalizer.test.mjs +115 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: CI & Publish UniSpec Core
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
tags:
|
|
8
|
+
- "unispec-core-v*"
|
|
9
|
+
pull_request:
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
ci:
|
|
15
|
+
name: CI (install & pack)
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout repo
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Use Node.js
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: 20
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
if [ -f package-lock.json ]; then
|
|
30
|
+
npm ci
|
|
31
|
+
else
|
|
32
|
+
npm install
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
- name: Run tests (if defined)
|
|
36
|
+
run: |
|
|
37
|
+
if npm run | grep -q " test"; then
|
|
38
|
+
npm test
|
|
39
|
+
else
|
|
40
|
+
echo "No test script defined, skipping tests"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
- name: Verify package can be packed
|
|
44
|
+
run: npm pack --dry-run
|
|
45
|
+
|
|
46
|
+
publish:
|
|
47
|
+
name: Publish to npm
|
|
48
|
+
needs: ci
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
if: startsWith(github.ref, 'refs/tags/unispec-core-v')
|
|
51
|
+
|
|
52
|
+
steps:
|
|
53
|
+
- name: Checkout repo
|
|
54
|
+
uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- name: Use Node.js with npm registry
|
|
57
|
+
uses: actions/setup-node@v4
|
|
58
|
+
with:
|
|
59
|
+
node-version: 20
|
|
60
|
+
registry-url: https://registry.npmjs.org
|
|
61
|
+
scope: "@unispechq"
|
|
62
|
+
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: |
|
|
65
|
+
if [ -f package-lock.json ]; then
|
|
66
|
+
npm ci
|
|
67
|
+
else
|
|
68
|
+
npm install
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
- name: Publish @unispechq/unispec-core to npm
|
|
72
|
+
env:
|
|
73
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
74
|
+
run: npm publish --access public
|
package/.windsurfrules
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# WindSurf Rules for `unispec-core`
|
|
2
|
+
# ---------------------------------
|
|
3
|
+
# This ruleset defines how AI assistants, contributors, and reviewers must
|
|
4
|
+
# interact with the UniSpec Core Engine repository.
|
|
5
|
+
# The Core Engine provides validation, parsing, normalization, diffing,
|
|
6
|
+
# and conversion logic for UniSpec specifications.
|
|
7
|
+
|
|
8
|
+
repository:
|
|
9
|
+
name: "unispec-core"
|
|
10
|
+
description: "Runtime implementation of the UniSpec Core Engine (loader, validator, normalizer, diff engine, converters, shared types). This repository contains only the Core Engine used by other UniSpec platform components (CLI, Registry, Portal, adapters, SDKs)."
|
|
11
|
+
visibility: public
|
|
12
|
+
criticality: core
|
|
13
|
+
|
|
14
|
+
goals:
|
|
15
|
+
- Implement the runtime mechanics of the UniSpec format defined in `unispec-spec`.
|
|
16
|
+
- Provide parsing, validation, normalization, and diffing for UniSpec documents.
|
|
17
|
+
- Provide reusable shared types and utilities for CLI, adapters, registry, and portal.
|
|
18
|
+
- Ensure strict alignment with the specification and JSON Schemas.
|
|
19
|
+
- Consume organization-wide context through MCP GitHub server without violating boundaries.
|
|
20
|
+
- Remain lightweight, stable, deterministic, and fully spec-compliant.
|
|
21
|
+
|
|
22
|
+
assistant_instructions:
|
|
23
|
+
allowed_actions:
|
|
24
|
+
- Read and reference content from other UniSpec repositories via MCP GitHub.
|
|
25
|
+
- Generate and update logic within this repository related to:
|
|
26
|
+
- parsing UniSpec documents,
|
|
27
|
+
- JSON Schema validation,
|
|
28
|
+
- normalization,
|
|
29
|
+
- diffing,
|
|
30
|
+
- conversions (OpenAPI, GraphQL SDL, WebSocket models),
|
|
31
|
+
- shared types and interfaces.
|
|
32
|
+
- Suggest architectural improvements to core modules.
|
|
33
|
+
- Assist in writing documentation, API descriptions, comments, and design notes.
|
|
34
|
+
- Validate behavior using actual spec files from `unispec-spec`.
|
|
35
|
+
|
|
36
|
+
forbidden_actions:
|
|
37
|
+
- Modify any files in external repositories.
|
|
38
|
+
- Introduce changes to the UniSpec language itself (belongs to `unispec-spec`).
|
|
39
|
+
- Implement features that are not grounded in the official spec.
|
|
40
|
+
- Add framework-specific or platform-specific logic (belongs to adapters).
|
|
41
|
+
- Add server code, API endpoints, frontend components, or CLI commands.
|
|
42
|
+
- Introduce non-deterministic behavior or global mutable state.
|
|
43
|
+
- Modify specification version numbers (belongs to `unispec-spec`).
|
|
44
|
+
|
|
45
|
+
escalation_policy:
|
|
46
|
+
- Any behavior that deviates from the official UniSpec spec must require maintainer confirmation.
|
|
47
|
+
- If MCP data reveals discrepancies between spec and code, assistant must warn and suggest alignment.
|
|
48
|
+
- For potentially breaking API changes, assistant must halt and request maintainer approval.
|
|
49
|
+
|
|
50
|
+
context_model:
|
|
51
|
+
mcp_github_usage:
|
|
52
|
+
allowed:
|
|
53
|
+
- Access organization repositories for context (read-only).
|
|
54
|
+
- Inspect:
|
|
55
|
+
- UniSpec format (`unispec-spec`)
|
|
56
|
+
- CLI behavior (`unispec-platform`)
|
|
57
|
+
- Adapters (`unispec-js-adapters`, `unispec-python-adapters`)
|
|
58
|
+
- Registry and Portal APIs
|
|
59
|
+
- Use cross-repo information to ensure Core Engine behavior matches platform expectations.
|
|
60
|
+
forbidden:
|
|
61
|
+
- Editing or mutating files in other repositories.
|
|
62
|
+
- Making assumptions not supported by spec.
|
|
63
|
+
- Introducing coupling that makes core depend on implementation details.
|
|
64
|
+
behaviors:
|
|
65
|
+
- Treat external repos purely as reference sources.
|
|
66
|
+
- Maintain strict alignment with the spec repo.
|
|
67
|
+
- Do not derive new behaviors not defined by the spec.
|
|
68
|
+
|
|
69
|
+
file_structure:
|
|
70
|
+
required_directories:
|
|
71
|
+
src: "Source code for the Core Engine logic"
|
|
72
|
+
src/loader: "Spec loader and YAML/JSON reading utilities"
|
|
73
|
+
src/validator: "Schema validation logic using official UniSpec JSON Schemas"
|
|
74
|
+
src/normalizer: "Canonical normalization of UniSpec documents"
|
|
75
|
+
src/diff: "Diff engine and breaking change detection"
|
|
76
|
+
src/converters: "Converters for OpenAPI, GraphQL, WebSocket, etc."
|
|
77
|
+
src/types: "Shared public-facing TypeScript types/interfaces"
|
|
78
|
+
docs: "Developer documentation and design notes"
|
|
79
|
+
|
|
80
|
+
required_files:
|
|
81
|
+
- "README.md"
|
|
82
|
+
- "package.json"
|
|
83
|
+
- "src/index.ts"
|
|
84
|
+
- "src/types/index.ts"
|
|
85
|
+
|
|
86
|
+
content_guidelines:
|
|
87
|
+
code_requirements:
|
|
88
|
+
- Must be deterministic, pure, and side-effect-free where possible.
|
|
89
|
+
- Must strictly follow the UniSpec JSON Schema definitions.
|
|
90
|
+
- Must use official schemas from `unispec-spec` (via MCP reference or local import).
|
|
91
|
+
- Should be modular, composable, and testable.
|
|
92
|
+
- Must not depend on frameworks (Express, Nest, FastAPI, etc).
|
|
93
|
+
- Must not include platform logic (Registry/Portal).
|
|
94
|
+
|
|
95
|
+
documentation:
|
|
96
|
+
- All modules must have clear API descriptions and rationale.
|
|
97
|
+
- Example inputs and outputs should reference real UniSpec examples.
|
|
98
|
+
- Must reflect the latest UniSpec specification.
|
|
99
|
+
|
|
100
|
+
testing:
|
|
101
|
+
- Core behavior must be validated using examples from `unispec-spec/examples`.
|
|
102
|
+
- All changes must include tests for validation, normalization, diffing, and conversions.
|
|
103
|
+
- Tests must cover edge cases and backward compatibility.
|
|
104
|
+
|
|
105
|
+
versioning_policy:
|
|
106
|
+
rules:
|
|
107
|
+
- Core versioning follows the platform, not the spec.
|
|
108
|
+
- Breaking API changes require:
|
|
109
|
+
- Maintainer approval
|
|
110
|
+
- Minor versions may add new converters or metadata fields if spec permits.
|
|
111
|
+
- Patch versions fix issues, improve accuracy, or correct types.
|
|
112
|
+
|
|
113
|
+
pull_request_rules:
|
|
114
|
+
- PRs must describe:
|
|
115
|
+
- intent,
|
|
116
|
+
- expected behavior,
|
|
117
|
+
- impact on users,
|
|
118
|
+
- compatibility implications.
|
|
119
|
+
- PRs affecting validation, types, or normalization must include:
|
|
120
|
+
- tests,
|
|
121
|
+
- updated docs,
|
|
122
|
+
- verification against real examples.
|
|
123
|
+
- Schema-dependent logic must be checked against `unispec-spec` via MCP.
|
|
124
|
+
|
|
125
|
+
tone_and_style:
|
|
126
|
+
- Code and docs must be clean, consistent, and professional.
|
|
127
|
+
- Naming conventions must follow spec terminology.
|
|
128
|
+
- No noisy logs, no temporary/debug code.
|
|
129
|
+
|
|
130
|
+
license:
|
|
131
|
+
- Must remain open-source.
|
|
132
|
+
- Core engine logic must be available for public use.
|
|
133
|
+
|
|
134
|
+
notes:
|
|
135
|
+
- This repository implements the *mechanics* of UniSpec, not the language definition.
|
|
136
|
+
- The UniSpec format itself lives in `unispec-spec`.
|
|
137
|
+
- Adapters, CLI, Registry, and Portal depend on core — keep APIs stable and predictable.
|
|
138
|
+
- MCP GitHub context may be used for reasoning but not for cross-repo modifications.
|
package/README.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# UniSpec Core Platform
|
|
2
|
+
**The official UniSpec Core Engine package — parser, validator, normalizer, diff engine, and converters for the UniSpec format**
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## 🚀 Overview
|
|
7
|
+
|
|
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.
|
|
10
|
+
|
|
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
|
+
|
|
13
|
+
Core Engine capabilities:
|
|
14
|
+
|
|
15
|
+
- 🧠 **Core Engine** — parser, validator, normalizer, diff engine, converters
|
|
16
|
+
- 🔄 **Format conversion** — UniSpec → OpenAPI, UniSpec → GraphQL SDL, UniSpec → WebSocket channel models
|
|
17
|
+
- 🧩 **Shared types and utilities** — types and helper functions used by the CLI, adapters, Registry, and Portal
|
|
18
|
+
|
|
19
|
+
UniSpec is designed to unify documentation for:
|
|
20
|
+
|
|
21
|
+
- REST
|
|
22
|
+
- GraphQL
|
|
23
|
+
- WebSocket
|
|
24
|
+
- 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
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🧠 Core Concepts
|
|
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 paths/methods, 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
|
+
- Treated as a general OpenAPI-like structure defined by UniSpec JSON Schemas.
|
|
81
|
+
- Normalizer orders `paths` and HTTP methods for stable diffs.
|
|
82
|
+
- Diff engine annotates path/operation additions and removals with breaking/non-breaking severity.
|
|
83
|
+
- Converter exposes REST as an OpenAPI 3.1 document while preserving the original UniSpec under `x-unispec`.
|
|
84
|
+
|
|
85
|
+
- **GraphQL**
|
|
86
|
+
- Typed protocol with `schema` (SDL) and `operations` (queries/mutations/subscriptions).
|
|
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, plus extensions.
|
|
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.
|
|
99
|
+
|
|
100
|
+
Example UniSpec CLI commands:
|
|
101
|
+
|
|
102
|
+
```pgsql
|
|
103
|
+
unispec validate
|
|
104
|
+
unispec push
|
|
105
|
+
unispec dev
|
|
106
|
+
unispec open
|
|
107
|
+
unispec diff
|
|
108
|
+
unispec convert
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
### 🗂 5. Registry API (separate service)
|
|
113
|
+
Stores UniSpec specs from multiple services and uses Core Engine for validation, normalization, and change analysis.
|
|
114
|
+
Effectively acts as the "system of record" for all APIs in the company.
|
|
115
|
+
|
|
116
|
+
### 🌐 6. Portal Web + API (separate service)
|
|
117
|
+
API documentation portal built on top of UniSpec and Core Engine:
|
|
118
|
+
|
|
119
|
+
- service catalog
|
|
120
|
+
- API endpoints
|
|
121
|
+
- schemas
|
|
122
|
+
- interactive playgrounds
|
|
123
|
+
- version comparison
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 🛒 Use Cases
|
|
128
|
+
|
|
129
|
+
### 🟦 Monolith mode (Swagger-like)
|
|
130
|
+
A backend service includes an adapter →
|
|
131
|
+
`/unispec.json` + `/docs` are served automatically.
|
|
132
|
+
|
|
133
|
+
### 🟧 Microservice mode
|
|
134
|
+
Each service pushes its UniSpec into Registry →
|
|
135
|
+
Portal Web assembles your entire company's API landscape.
|
|
136
|
+
|
|
137
|
+
### 🟩 Enterprise mode
|
|
138
|
+
Includes:
|
|
139
|
+
|
|
140
|
+
- SSO / permissions
|
|
141
|
+
- RBAC
|
|
142
|
+
- auditing
|
|
143
|
+
- topology map
|
|
144
|
+
- advanced analytics
|
|
145
|
+
|
|
146
|
+
(Handled via private repos.)
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 🏁 Getting Started
|
|
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
|
|
160
|
+
|
|
161
|
+
```pgsql
|
|
162
|
+
pnpm install
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 3. Build all packages
|
|
166
|
+
|
|
167
|
+
```pgsql
|
|
168
|
+
pnpm build
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 4. Run locally (dev mode)
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 🤝 Contributing
|
|
176
|
+
|
|
177
|
+
Contributions are welcome!
|
|
178
|
+
Before contributing, please review:
|
|
179
|
+
|
|
180
|
+
- `docs/development.md`
|
|
181
|
+
- `.windsurfrules`
|
|
182
|
+
|
|
183
|
+
All core changes must comply with:
|
|
184
|
+
|
|
185
|
+
- the UniSpec format from `unispec-spec`
|
|
186
|
+
- compatibility rules
|
|
187
|
+
- test coverage
|
|
188
|
+
- platform architecture
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Related Repositories
|
|
193
|
+
|
|
194
|
+
| Repository | Purpose |
|
|
195
|
+
|------------------------|---------|
|
|
196
|
+
| `unispec-spec` | UniSpec format definition (schemas, examples) |
|
|
197
|
+
| `unispec-core` | **This repo** — UniSpec Core Engine implementation |
|
|
198
|
+
| `unispec-docs` | Documentation site |
|
|
199
|
+
| `unispec-js-adapters` | Framework integrations (Express/Nest/Fastify) built on top of Core Engine |
|
|
200
|
+
| `unispec-infra` | Helm charts, Docker, Terraform for deploying the UniSpec platform |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
UniSpec Core Engine is open-source and free to use under the MIT License.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 🔥 Summary
|
|
211
|
+
|
|
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.
|
|
222
|
+
|
|
223
|
+
If you're building tools, adapters, or platform services that rely on UniSpec → **this is where the engine lives.**
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UniSpecDocument } from "../types";
|
|
2
|
+
export interface OpenAPIDocument {
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface GraphQLSDLOutput {
|
|
6
|
+
sdl: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WebSocketModel {
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export declare function toOpenAPI(doc: UniSpecDocument): OpenAPIDocument;
|
|
12
|
+
export declare function toGraphQLSDL(doc: UniSpecDocument): GraphQLSDLOutput;
|
|
13
|
+
export declare function toWebSocketModel(doc: UniSpecDocument): WebSocketModel;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export function toOpenAPI(doc) {
|
|
2
|
+
const service = doc.service;
|
|
3
|
+
const rest = service.protocols?.rest;
|
|
4
|
+
const info = {
|
|
5
|
+
title: service.title ?? service.name,
|
|
6
|
+
description: service.description,
|
|
7
|
+
};
|
|
8
|
+
const servers = rest?.servers ?? [];
|
|
9
|
+
const paths = rest?.paths ?? {};
|
|
10
|
+
// Transparently forward additional REST protocol fields into the OpenAPI document.
|
|
11
|
+
// This allows users to describe components, security, tags and other structures
|
|
12
|
+
// without forcing a specific REST model at the core layer.
|
|
13
|
+
const { servers: _omitServers, paths: _omitPaths, ...restExtras } = rest ?? {};
|
|
14
|
+
return {
|
|
15
|
+
openapi: "3.1.0",
|
|
16
|
+
info,
|
|
17
|
+
servers,
|
|
18
|
+
paths,
|
|
19
|
+
...restExtras,
|
|
20
|
+
"x-unispec": doc,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function toGraphQLSDL(doc) {
|
|
24
|
+
// Minimal implementation: generate a basic SDL that exposes service metadata
|
|
25
|
+
// via a Query field. This does not attempt to interpret the full GraphQL
|
|
26
|
+
// protocol structure yet, but provides a stable, deterministic SDL shape
|
|
27
|
+
// based on top-level UniSpec document fields.
|
|
28
|
+
const graphql = doc.service.protocols?.graphql;
|
|
29
|
+
const customSDL = graphql?.schema?.sdl;
|
|
30
|
+
if (typeof customSDL === "string" && customSDL.trim()) {
|
|
31
|
+
return { sdl: customSDL };
|
|
32
|
+
}
|
|
33
|
+
const service = doc.service;
|
|
34
|
+
const title = service.title ?? service.name;
|
|
35
|
+
const description = service.description ?? "";
|
|
36
|
+
const lines = [];
|
|
37
|
+
if (title || description) {
|
|
38
|
+
lines.push("\"\"");
|
|
39
|
+
if (title) {
|
|
40
|
+
lines.push(title);
|
|
41
|
+
}
|
|
42
|
+
if (description) {
|
|
43
|
+
lines.push("");
|
|
44
|
+
lines.push(description);
|
|
45
|
+
}
|
|
46
|
+
lines.push("\"\"");
|
|
47
|
+
}
|
|
48
|
+
lines.push("schema {");
|
|
49
|
+
lines.push(" query: Query");
|
|
50
|
+
lines.push("}");
|
|
51
|
+
lines.push("");
|
|
52
|
+
lines.push("type Query {");
|
|
53
|
+
lines.push(" _serviceInfo: String!\n");
|
|
54
|
+
lines.push("}");
|
|
55
|
+
const sdl = lines.join("\n");
|
|
56
|
+
return { sdl };
|
|
57
|
+
}
|
|
58
|
+
export function toWebSocketModel(doc) {
|
|
59
|
+
// Base WebSocket model intended for a modern, dashboard-oriented UI.
|
|
60
|
+
// It exposes service metadata, a normalized list of channels and the raw
|
|
61
|
+
// websocket protocol object, while also embedding the original UniSpec
|
|
62
|
+
// document under a technical key for debugging and introspection.
|
|
63
|
+
const service = doc.service;
|
|
64
|
+
const websocket = (service.protocols?.websocket ?? {});
|
|
65
|
+
const channelsRecord = (websocket && typeof websocket === "object" && websocket.channels && typeof websocket.channels === "object")
|
|
66
|
+
? websocket.channels
|
|
67
|
+
: {};
|
|
68
|
+
const channels = Object.keys(channelsRecord).sort().map((name) => {
|
|
69
|
+
const channel = channelsRecord[name] ?? {};
|
|
70
|
+
return {
|
|
71
|
+
name,
|
|
72
|
+
summary: channel.summary ?? channel.title,
|
|
73
|
+
description: channel.description,
|
|
74
|
+
direction: channel.direction,
|
|
75
|
+
messages: channel.messages,
|
|
76
|
+
raw: channel,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
service: {
|
|
81
|
+
name: service.name,
|
|
82
|
+
title: service.title,
|
|
83
|
+
description: service.description,
|
|
84
|
+
},
|
|
85
|
+
channels,
|
|
86
|
+
rawProtocol: websocket,
|
|
87
|
+
"x-unispec-ws": doc,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { UniSpecDocument } from "../types";
|
|
2
|
+
export type ChangeSeverity = "breaking" | "non-breaking" | "unknown";
|
|
3
|
+
export interface UniSpecChange {
|
|
4
|
+
path: string;
|
|
5
|
+
description: string;
|
|
6
|
+
severity: ChangeSeverity;
|
|
7
|
+
protocol?: "rest" | "graphql" | "websocket";
|
|
8
|
+
kind?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface DiffResult {
|
|
11
|
+
changes: UniSpecChange[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compute a structural diff between two UniSpec documents.
|
|
15
|
+
*
|
|
16
|
+
* Current behavior:
|
|
17
|
+
* - Tracks added, removed, and changed fields and array items.
|
|
18
|
+
* - Uses JSON Pointer-like paths rooted at "" (e.g., "/info/title").
|
|
19
|
+
* - Marks all changes with severity "unknown" for now.
|
|
20
|
+
*/
|
|
21
|
+
export declare function diffUniSpec(oldDoc: UniSpecDocument, newDoc: UniSpecDocument): DiffResult;
|