@adhd/apigen-plugin-openapi 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/index.d.ts +3 -0
- package/index.js +1 -0
- package/index.mjs +128 -0
- package/lib/plugin.d.ts +23 -0
- package/package.json +14 -0
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function m(e){return e.words.join("-")}function g(e){return e.words.map(P).join("")}function b(e){return e.words.join("_")}function v(e,t={}){var d,h;const n=[e.namespace,...e.path],s=e.safe?"GET":"POST",r=((h=(d=t.http)==null?void 0:d.verb)==null?void 0:h[e.id])??s,o="/"+n.map(i=>m(i)).join("/"),l=n.map(i=>b(i)).join("_"),p=n.map(i=>b(i)).slice(0,-1).join("."),u=g(n[n.length-2]??n[0]),c=g(n[n.length-1]),a=n.map(i=>m(i));return{http:{verb:r,route:o},mcp:{name:l},grpc:{package:p,service:u,method:c},cli:{path:a}}}function P(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function O(e,t={}){const n=t.title??"API",s=t.version??"0.0.0",r={};for(const o of e){const l=v(o),{verb:f,route:p}=l.http,u=f.toLowerCase(),c={operationId:o.id,summary:o.id,responses:{200:S(o.output)}};if(o.safe)c.parameters=q(o.input);else{const a=o.input;typeof a=="object"&&a!==null&&Object.keys(a).length>0&&(c.requestBody={required:!0,content:{"application/json":{schema:a}}})}r[p]===void 0&&(r[p]={}),r[p][u]=c}return{openapi:"3.1.0",info:{title:n,version:s},paths:r}}function S(e){return typeof e=="object"&&e!==null&&Object.keys(e).length>0?{description:"Success",content:{"application/json":{schema:e}}}:{description:"Success"}}function q(e){if(typeof e!="object"||e===null||typeof e.properties!="object"||e.properties===null)return[];const t=Array.isArray(e.required)?e.required:[],n=e.properties;return Object.entries(n).map(([s,r])=>({name:s,in:"query",required:t.includes(s),schema:r}))}function y(e){return{raw:e,words:e.split(/(?=[A-Z])|[-_]/).map(t=>t.toLowerCase()).filter(Boolean)}}function A(e,t={}){return[{id:"_meta/openapi",host:e.host,namespace:y("meta"),path:[y("openapi")],kind:"query",async:!1,streaming:!1,safe:!0,input:{},output:{type:"object"},envelope:{},typeText:null,transports:["http"],handler:n=>O(e.operations,{title:t.title,version:t.version})}]}const j={id:"openapi",description:"Mount plugin: serves the OpenAPI 3.1 doc at GET /meta/openapi",optionsSchema:{type:"object",properties:{title:{type:"string",description:"OpenAPI info.title"},version:{type:"string",description:"OpenAPI info.version"}},additionalProperties:!1},capabilities:{mount:{operations(e,t){return A(e,t)}}}};exports.default=j;exports.openapiPlugin=j;
|
package/index.mjs
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
function m(e) {
|
|
2
|
+
return e.words.join("-");
|
|
3
|
+
}
|
|
4
|
+
function y(e) {
|
|
5
|
+
return e.words.map(v).join("");
|
|
6
|
+
}
|
|
7
|
+
function b(e) {
|
|
8
|
+
return e.words.join("_");
|
|
9
|
+
}
|
|
10
|
+
function j(e, t = {}) {
|
|
11
|
+
var f, h;
|
|
12
|
+
const n = [e.namespace, ...e.path], s = e.safe ? "GET" : "POST", r = ((h = (f = t.http) == null ? void 0 : f.verb) == null ? void 0 : h[e.id]) ?? s, o = "/" + n.map((i) => m(i)).join("/"), l = n.map((i) => b(i)).join("_"), a = n.map((i) => b(i)).slice(0, -1).join("."), u = y(n[n.length - 2] ?? n[0]), c = y(n[n.length - 1]), p = n.map((i) => m(i));
|
|
13
|
+
return {
|
|
14
|
+
http: { verb: r, route: o },
|
|
15
|
+
mcp: { name: l },
|
|
16
|
+
grpc: { package: a, service: u, method: c },
|
|
17
|
+
cli: { path: p }
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function v(e) {
|
|
21
|
+
return e.length === 0 ? e : e[0].toUpperCase() + e.slice(1);
|
|
22
|
+
}
|
|
23
|
+
function P(e, t = {}) {
|
|
24
|
+
const n = t.title ?? "API", s = t.version ?? "0.0.0", r = {};
|
|
25
|
+
for (const o of e) {
|
|
26
|
+
const l = j(o), { verb: d, route: a } = l.http, u = d.toLowerCase(), c = {
|
|
27
|
+
operationId: o.id,
|
|
28
|
+
summary: o.id,
|
|
29
|
+
responses: {
|
|
30
|
+
200: O(o.output)
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
if (o.safe)
|
|
34
|
+
c.parameters = q(o.input);
|
|
35
|
+
else {
|
|
36
|
+
const p = o.input;
|
|
37
|
+
typeof p == "object" && p !== null && Object.keys(p).length > 0 && (c.requestBody = {
|
|
38
|
+
required: !0,
|
|
39
|
+
content: {
|
|
40
|
+
"application/json": {
|
|
41
|
+
schema: p
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
r[a] === void 0 && (r[a] = {}), r[a][u] = c;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
openapi: "3.1.0",
|
|
50
|
+
info: { title: n, version: s },
|
|
51
|
+
paths: r
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function O(e) {
|
|
55
|
+
return typeof e == "object" && e !== null && Object.keys(e).length > 0 ? {
|
|
56
|
+
description: "Success",
|
|
57
|
+
content: {
|
|
58
|
+
"application/json": { schema: e }
|
|
59
|
+
}
|
|
60
|
+
} : { description: "Success" };
|
|
61
|
+
}
|
|
62
|
+
function q(e) {
|
|
63
|
+
if (typeof e != "object" || e === null || typeof e.properties != "object" || e.properties === null)
|
|
64
|
+
return [];
|
|
65
|
+
const t = Array.isArray(e.required) ? e.required : [], n = e.properties;
|
|
66
|
+
return Object.entries(n).map(([s, r]) => ({
|
|
67
|
+
name: s,
|
|
68
|
+
in: "query",
|
|
69
|
+
required: t.includes(s),
|
|
70
|
+
schema: r
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
function g(e) {
|
|
74
|
+
return { raw: e, words: e.split(/(?=[A-Z])|[-_]/).map((t) => t.toLowerCase()).filter(Boolean) };
|
|
75
|
+
}
|
|
76
|
+
function A(e, t = {}) {
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
// Canonical id — the `_meta` prefix is a convention for meta-endpoints.
|
|
80
|
+
id: "_meta/openapi",
|
|
81
|
+
host: e.host,
|
|
82
|
+
namespace: g("meta"),
|
|
83
|
+
path: [g("openapi")],
|
|
84
|
+
// query + safe → GET /meta/openapi (SPEC §5)
|
|
85
|
+
kind: "query",
|
|
86
|
+
async: !1,
|
|
87
|
+
streaming: !1,
|
|
88
|
+
safe: !0,
|
|
89
|
+
// Input: no domain params — this is a zero-arg metadata endpoint.
|
|
90
|
+
input: {},
|
|
91
|
+
// Output: an object (the full OpenAPI doc shape; not narrowed further
|
|
92
|
+
// here because the exact schema varies with the descriptor content).
|
|
93
|
+
output: { type: "object" },
|
|
94
|
+
envelope: {},
|
|
95
|
+
typeText: null,
|
|
96
|
+
// Expose only on HTTP — the doc is a tooling artefact (SPEC §7.2b).
|
|
97
|
+
transports: ["http"],
|
|
98
|
+
// Handler: derive the doc from the descriptor at request time.
|
|
99
|
+
handler: (n) => P(e.operations, {
|
|
100
|
+
title: t.title,
|
|
101
|
+
version: t.version
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
const S = {
|
|
107
|
+
id: "openapi",
|
|
108
|
+
description: "Mount plugin: serves the OpenAPI 3.1 doc at GET /meta/openapi",
|
|
109
|
+
optionsSchema: {
|
|
110
|
+
type: "object",
|
|
111
|
+
properties: {
|
|
112
|
+
title: { type: "string", description: "OpenAPI info.title" },
|
|
113
|
+
version: { type: "string", description: "OpenAPI info.version" }
|
|
114
|
+
},
|
|
115
|
+
additionalProperties: !1
|
|
116
|
+
},
|
|
117
|
+
capabilities: {
|
|
118
|
+
mount: {
|
|
119
|
+
operations(e, t) {
|
|
120
|
+
return A(e, t);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
export {
|
|
126
|
+
S as default,
|
|
127
|
+
S as openapiPlugin
|
|
128
|
+
};
|
package/lib/plugin.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Plugin } from '@adhd/apigen-core';
|
|
2
|
+
|
|
3
|
+
/** Options accepted by the openapi mount plugin. */
|
|
4
|
+
export interface OpenapiOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The API title placed in the generated OpenAPI doc's `info.title`.
|
|
7
|
+
* @default 'API'
|
|
8
|
+
*/
|
|
9
|
+
title?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The API version placed in the generated OpenAPI doc's `info.version`.
|
|
12
|
+
* @default '0.0.0'
|
|
13
|
+
*/
|
|
14
|
+
version?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* v2 openapi mount plugin (SPEC §7.1 / §7.2b).
|
|
18
|
+
*
|
|
19
|
+
* Contributes `GET /meta/openapi` → the OpenAPI 3.1 document derived from
|
|
20
|
+
* the canonical descriptor at request time.
|
|
21
|
+
*/
|
|
22
|
+
export declare const openapiPlugin: Plugin<OpenapiOptions>;
|
|
23
|
+
export default openapiPlugin;
|
package/package.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adhd/apigen-plugin-openapi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "./index.js",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@adhd/apigen-core": "^0.1.0",
|
|
7
|
+
"@adhd/apigen-codegen-openapi": "^0.1.0"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"module": "./index.mjs",
|
|
13
|
+
"types": "./index.d.ts"
|
|
14
|
+
}
|