@unispechq/unispec-core 0.1.0 → 0.1.1
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 -74
- package/.windsurfrules +138 -138
- package/README.md +223 -223
- package/package.json +28 -28
- package/scripts/release.js +51 -51
- package/src/converters/index.ts +120 -120
- package/src/diff/index.ts +235 -235
- package/src/index.ts +6 -6
- package/src/loader/index.ts +25 -25
- package/src/normalizer/index.ts +156 -156
- package/src/types/index.ts +67 -67
- package/src/validator/index.ts +61 -61
- package/tests/converters.test.mjs +126 -126
- package/tests/diff.test.mjs +240 -240
- package/tests/loader-validator.test.mjs +19 -19
- package/tests/normalizer.test.mjs +115 -115
- package/tsconfig.json +15 -15
- package/dist/converters/index.d.ts +0 -13
- package/dist/converters/index.js +0 -89
- package/dist/diff/index.d.ts +0 -21
- package/dist/diff/index.js +0 -195
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -6
- package/dist/loader/index.d.ts +0 -13
- package/dist/loader/index.js +0 -19
- package/dist/normalizer/index.d.ts +0 -11
- package/dist/normalizer/index.js +0 -116
- package/dist/types/index.d.ts +0 -57
- package/dist/types/index.js +0 -1
- package/dist/validator/index.d.ts +0 -7
- package/dist/validator/index.js +0 -47
package/src/converters/index.ts
CHANGED
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
import { UniSpecDocument, UniSpecWebSocketProtocol, UniSpecWebSocketChannel } from "../types";
|
|
2
|
-
|
|
3
|
-
export interface OpenAPIDocument {
|
|
4
|
-
[key: string]: unknown;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface GraphQLSDLOutput {
|
|
8
|
-
sdl: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface WebSocketModel {
|
|
12
|
-
[key: string]: unknown;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function toOpenAPI(doc: UniSpecDocument): OpenAPIDocument {
|
|
16
|
-
const service = doc.service;
|
|
17
|
-
const rest = service.protocols?.rest as any | undefined;
|
|
18
|
-
|
|
19
|
-
const info = {
|
|
20
|
-
title: service.title ?? service.name,
|
|
21
|
-
description: service.description,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const servers = rest?.servers ?? [];
|
|
25
|
-
const paths = rest?.paths ?? {};
|
|
26
|
-
|
|
27
|
-
// Transparently forward additional REST protocol fields into the OpenAPI document.
|
|
28
|
-
// This allows users to describe components, security, tags and other structures
|
|
29
|
-
// without forcing a specific REST model at the core layer.
|
|
30
|
-
const { servers: _omitServers, paths: _omitPaths, ...restExtras } = rest ?? {};
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
openapi: "3.1.0",
|
|
34
|
-
info,
|
|
35
|
-
servers,
|
|
36
|
-
paths,
|
|
37
|
-
...restExtras,
|
|
38
|
-
"x-unispec": doc,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function toGraphQLSDL(doc: UniSpecDocument): GraphQLSDLOutput {
|
|
43
|
-
// Minimal implementation: generate a basic SDL that exposes service metadata
|
|
44
|
-
// via a Query field. This does not attempt to interpret the full GraphQL
|
|
45
|
-
// protocol structure yet, but provides a stable, deterministic SDL shape
|
|
46
|
-
// based on top-level UniSpec document fields.
|
|
47
|
-
|
|
48
|
-
const graphql = doc.service.protocols?.graphql;
|
|
49
|
-
const customSDL = graphql?.schema?.sdl;
|
|
50
|
-
|
|
51
|
-
if (typeof customSDL === "string" && customSDL.trim()) {
|
|
52
|
-
return { sdl: customSDL };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const service = doc.service;
|
|
56
|
-
const title = service.title ?? service.name;
|
|
57
|
-
const description = service.description ?? "";
|
|
58
|
-
|
|
59
|
-
const lines: string[] = [];
|
|
60
|
-
|
|
61
|
-
if (title || description) {
|
|
62
|
-
lines.push("\"\"");
|
|
63
|
-
if (title) {
|
|
64
|
-
lines.push(title);
|
|
65
|
-
}
|
|
66
|
-
if (description) {
|
|
67
|
-
lines.push("");
|
|
68
|
-
lines.push(description);
|
|
69
|
-
}
|
|
70
|
-
lines.push("\"\"");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
lines.push("schema {");
|
|
74
|
-
lines.push(" query: Query");
|
|
75
|
-
lines.push("}");
|
|
76
|
-
lines.push("");
|
|
77
|
-
lines.push("type Query {");
|
|
78
|
-
lines.push(" _serviceInfo: String!\n");
|
|
79
|
-
lines.push("}");
|
|
80
|
-
|
|
81
|
-
const sdl = lines.join("\n");
|
|
82
|
-
return { sdl };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function toWebSocketModel(doc: UniSpecDocument): WebSocketModel {
|
|
86
|
-
// Base WebSocket model intended for a modern, dashboard-oriented UI.
|
|
87
|
-
// It exposes service metadata, a normalized list of channels and the raw
|
|
88
|
-
// websocket protocol object, while also embedding the original UniSpec
|
|
89
|
-
// document under a technical key for debugging and introspection.
|
|
90
|
-
|
|
91
|
-
const service = doc.service;
|
|
92
|
-
const websocket = (service.protocols?.websocket ?? {}) as UniSpecWebSocketProtocol;
|
|
93
|
-
|
|
94
|
-
const channelsRecord = (websocket && typeof websocket === "object" && websocket.channels && typeof websocket.channels === "object")
|
|
95
|
-
? (websocket.channels as Record<string, UniSpecWebSocketChannel>)
|
|
96
|
-
: {};
|
|
97
|
-
|
|
98
|
-
const channels = Object.keys(channelsRecord).sort().map((name) => {
|
|
99
|
-
const channel = channelsRecord[name] ?? {};
|
|
100
|
-
return {
|
|
101
|
-
name,
|
|
102
|
-
summary: channel.summary ?? channel.title,
|
|
103
|
-
description: channel.description,
|
|
104
|
-
direction: channel.direction,
|
|
105
|
-
messages: channel.messages,
|
|
106
|
-
raw: channel,
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
service: {
|
|
112
|
-
name: service.name,
|
|
113
|
-
title: service.title,
|
|
114
|
-
description: service.description,
|
|
115
|
-
},
|
|
116
|
-
channels,
|
|
117
|
-
rawProtocol: websocket,
|
|
118
|
-
"x-unispec-ws": doc,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
1
|
+
import { UniSpecDocument, UniSpecWebSocketProtocol, UniSpecWebSocketChannel } from "../types";
|
|
2
|
+
|
|
3
|
+
export interface OpenAPIDocument {
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface GraphQLSDLOutput {
|
|
8
|
+
sdl: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface WebSocketModel {
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function toOpenAPI(doc: UniSpecDocument): OpenAPIDocument {
|
|
16
|
+
const service = doc.service;
|
|
17
|
+
const rest = service.protocols?.rest as any | undefined;
|
|
18
|
+
|
|
19
|
+
const info = {
|
|
20
|
+
title: service.title ?? service.name,
|
|
21
|
+
description: service.description,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const servers = rest?.servers ?? [];
|
|
25
|
+
const paths = rest?.paths ?? {};
|
|
26
|
+
|
|
27
|
+
// Transparently forward additional REST protocol fields into the OpenAPI document.
|
|
28
|
+
// This allows users to describe components, security, tags and other structures
|
|
29
|
+
// without forcing a specific REST model at the core layer.
|
|
30
|
+
const { servers: _omitServers, paths: _omitPaths, ...restExtras } = rest ?? {};
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
openapi: "3.1.0",
|
|
34
|
+
info,
|
|
35
|
+
servers,
|
|
36
|
+
paths,
|
|
37
|
+
...restExtras,
|
|
38
|
+
"x-unispec": doc,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function toGraphQLSDL(doc: UniSpecDocument): GraphQLSDLOutput {
|
|
43
|
+
// Minimal implementation: generate a basic SDL that exposes service metadata
|
|
44
|
+
// via a Query field. This does not attempt to interpret the full GraphQL
|
|
45
|
+
// protocol structure yet, but provides a stable, deterministic SDL shape
|
|
46
|
+
// based on top-level UniSpec document fields.
|
|
47
|
+
|
|
48
|
+
const graphql = doc.service.protocols?.graphql;
|
|
49
|
+
const customSDL = graphql?.schema?.sdl;
|
|
50
|
+
|
|
51
|
+
if (typeof customSDL === "string" && customSDL.trim()) {
|
|
52
|
+
return { sdl: customSDL };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const service = doc.service;
|
|
56
|
+
const title = service.title ?? service.name;
|
|
57
|
+
const description = service.description ?? "";
|
|
58
|
+
|
|
59
|
+
const lines: string[] = [];
|
|
60
|
+
|
|
61
|
+
if (title || description) {
|
|
62
|
+
lines.push("\"\"");
|
|
63
|
+
if (title) {
|
|
64
|
+
lines.push(title);
|
|
65
|
+
}
|
|
66
|
+
if (description) {
|
|
67
|
+
lines.push("");
|
|
68
|
+
lines.push(description);
|
|
69
|
+
}
|
|
70
|
+
lines.push("\"\"");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
lines.push("schema {");
|
|
74
|
+
lines.push(" query: Query");
|
|
75
|
+
lines.push("}");
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("type Query {");
|
|
78
|
+
lines.push(" _serviceInfo: String!\n");
|
|
79
|
+
lines.push("}");
|
|
80
|
+
|
|
81
|
+
const sdl = lines.join("\n");
|
|
82
|
+
return { sdl };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function toWebSocketModel(doc: UniSpecDocument): WebSocketModel {
|
|
86
|
+
// Base WebSocket model intended for a modern, dashboard-oriented UI.
|
|
87
|
+
// It exposes service metadata, a normalized list of channels and the raw
|
|
88
|
+
// websocket protocol object, while also embedding the original UniSpec
|
|
89
|
+
// document under a technical key for debugging and introspection.
|
|
90
|
+
|
|
91
|
+
const service = doc.service;
|
|
92
|
+
const websocket = (service.protocols?.websocket ?? {}) as UniSpecWebSocketProtocol;
|
|
93
|
+
|
|
94
|
+
const channelsRecord = (websocket && typeof websocket === "object" && websocket.channels && typeof websocket.channels === "object")
|
|
95
|
+
? (websocket.channels as Record<string, UniSpecWebSocketChannel>)
|
|
96
|
+
: {};
|
|
97
|
+
|
|
98
|
+
const channels = Object.keys(channelsRecord).sort().map((name) => {
|
|
99
|
+
const channel = channelsRecord[name] ?? {};
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
summary: channel.summary ?? channel.title,
|
|
103
|
+
description: channel.description,
|
|
104
|
+
direction: channel.direction,
|
|
105
|
+
messages: channel.messages,
|
|
106
|
+
raw: channel,
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
service: {
|
|
112
|
+
name: service.name,
|
|
113
|
+
title: service.title,
|
|
114
|
+
description: service.description,
|
|
115
|
+
},
|
|
116
|
+
channels,
|
|
117
|
+
rawProtocol: websocket,
|
|
118
|
+
"x-unispec-ws": doc,
|
|
119
|
+
};
|
|
120
|
+
}
|