@publier/openapi 0.1.18 → 0.2.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/dist/index.d.mts +4 -2
- package/dist/index.mjs +1 -1
- package/dist/parser.d.mts +19 -1
- package/dist/parser.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/package.json +7 -2
- package/src/components/api-reference.astro +1 -1
- package/src/components/code-samples.astro +2 -2
- package/src/components/props.ts +2 -0
package/dist/index.d.mts
CHANGED
|
@@ -216,7 +216,7 @@ interface AsyncApiSourceOptions {
|
|
|
216
216
|
*/
|
|
217
217
|
export declare function asyncapiSource(options: AsyncApiSourceOptions): ContentSource;
|
|
218
218
|
type SampleLang = 'curl' | 'javascript' | 'python' | 'go' | 'java' | 'csharp';
|
|
219
|
-
export declare function generateCodeSample(method: HttpMethod, path: string, operation: OpenApiOperation, lang: SampleLang, baseUrl: string): string;
|
|
219
|
+
export declare function generateCodeSample(method: HttpMethod, path: string, operation: OpenApiOperation, lang: SampleLang, baseUrl: string, spec?: OpenApiSpec): string;
|
|
220
220
|
interface APIReferenceProps {
|
|
221
221
|
method: HttpMethod;
|
|
222
222
|
path: string;
|
|
@@ -244,6 +244,8 @@ interface CodeSamplesProps {
|
|
|
244
244
|
method: HttpMethod;
|
|
245
245
|
path: string;
|
|
246
246
|
operation: OpenApiOperation;
|
|
247
|
+
/** The parsed specification; its security schemes put credentials into the samples. */
|
|
248
|
+
spec?: OpenApiSpec;
|
|
247
249
|
baseUrl?: string;
|
|
248
250
|
}
|
|
249
251
|
interface RequestExampleProps {
|
|
@@ -321,8 +323,8 @@ interface ExtractEndpointsOptions {
|
|
|
321
323
|
}
|
|
322
324
|
export declare function extractEndpoints(spec: OpenApiSpec, options?: ExtractEndpointsOptions): EndpointEntry[];
|
|
323
325
|
export declare function generateExampleFromSchema(schema: OpenApiSchema): unknown;
|
|
324
|
-
export declare function getMediaTypeExample(content: Record<string, OpenApiMediaType>, mediaType?: string): string | undefined;
|
|
325
326
|
export declare function formatJson(value: unknown): string;
|
|
327
|
+
export declare function getMediaTypeExample(content: Record<string, OpenApiMediaType>, mediaType?: string): string | undefined;
|
|
326
328
|
interface GenerateFilesOptions {
|
|
327
329
|
/** The parsed OpenAPI spec. */
|
|
328
330
|
spec: OpenApiSpec;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{asyncapiSourceBuild as e,
|
|
1
|
+
import{asyncapiSourceBuild as e,openapiExtractEndpoints as t,openapiNavigationBuild as n,openapiSourceBuild as r}from"@publier/native";import{HTTPSnippet as i}from"@readme/httpsnippet";import a from"@readme/oas-to-har";import o from"oas";import s from"openapi-sampler";function c(t){let{spec:n,baseUrl:r=``}=t,{pages:i,tree:a}=JSON.parse(e(JSON.stringify(n),r)),o=new Map(i.map(e=>[e.slug.join(`/`),e]));return{async getPage(e){return o.get(e.join(`/`))},async getPages(){return i},async getPageTree(){return a},async generateParams(){return i.map(e=>({slug:e.slug}))}}}function l(e){return s.sample(e)}function u(e,t=`application/json`){let n=e[t]??Object.values(e)[0];if(!n)return;if(n.example!==void 0)return n.example;let r=Object.values(n.examples??{}).find(e=>e.value!==void 0);return r?r.value:n.schema?l(n.schema):void 0}function d(e){return JSON.stringify(e,null,2)}function f(e,t=`application/json`){let n=u(e,t);return n===void 0?void 0:d(n)}const p={curl:[`shell`,`curl`],javascript:[`javascript`,`fetch`],python:[`python`,`requests`],go:[`go`,`native`],java:[`java`,`nethttp`],csharp:[`csharp`,`httpclient`]};function m(e,t){let n=e.getDefinition().components?.securitySchemes??{},r={};for(let e of Object.keys(t[0]??{})){let t=n[e];t?.type===`http`&&t.scheme?.toLowerCase()===`basic`?r[e]={user:`<username>`,pass:`<password>`}:t?.type===`apiKey`?r[e]=`<api-key>`:t&&(r[e]=`<token>`)}return r}function h(e,t,n,r,i){let s={openapi:`3.0.0`,info:{title:`API`,version:`1`},...i,servers:[{url:r}],paths:{...i?.paths,[t]:{...i?.paths?.[t],[e]:n}}},c=new o(s),l=c.operation(t,e),d={path:{},query:{},header:{},cookie:{}};for(let[,e]of t.matchAll(/\{([^}]+)\}/g))e&&(d.path[e]=`{${e}}`);for(let e of l.getParameters()){let t=d[e.in];t&&e.in!==`path`&&(t[e.name]=`<value>`)}if(l.hasRequestBody()){let e=l.schema.requestBody,t=l.getContentType(),n=u(e?.content??{},t);l.isFormUrlEncoded()||l.isMultipart()?d.formData=n??{}:n!==void 0&&(d.body=n)}return a(c,l,d,m(c,l.getSecurity())).log.entries[0].request}function g(e){return e.replace(/%(?:25)?(3C|3E|7B|7D)/gi,(e,t)=>String.fromCharCode(Number.parseInt(t,16)))}function _(e,t){let[n,r]=p[t],a=new i(e).convert(n,r),o=Array.isArray(a)?a.find(e=>typeof e==`string`):a;return g(typeof o==`string`?o:``)}function v(e,t,n,r,i,a){return p[r]?_(h(e,t,n,i,a),r):``}const y=[`get`,`post`,`put`,`delete`,`patch`,`head`,`options`];function b(e,n={}){let{mergePathParameters:r=!1,includeWebhooks:i=!0}=n;return JSON.parse(t(JSON.stringify(e),r,i))}function x(e,t={}){let{groupBy:r=`tag`,slugPrefix:i,excludeDeprecated:a=!1,includeWebhooks:o=!0}=t;return JSON.parse(n(JSON.stringify(e),r,i??null,a,o))}function S(e){let{spec:t,baseUrl:n=``}=e,{pages:i,tree:a}=JSON.parse(r(JSON.stringify(t),n)),o=new Map(i.map(e=>[e.slug.join(`/`),e]));return{async getPage(e){return o.get(e.join(`/`))},async getPages(){return i},async getPageTree(){return a},async generateParams(){return i.map(e=>({slug:e.slug}))}}}export{y as HTTP_METHODS,c as asyncapiSource,x as buildNavigation,b as extractEndpoints,d as formatJson,v as generateCodeSample,l as generateExampleFromSchema,f as getMediaTypeExample,S as openapiSource};
|
package/dist/parser.d.mts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI ingestion on @scalar/openapi-parser: load (file, URL or text; JSON or
|
|
3
|
+
* YAML; external `$ref`s), Swagger 2 → 3.0 upgrade, validation, dereference.
|
|
4
|
+
*
|
|
5
|
+
* The Rust renderers read a fully inlined document as JSON, so the result is
|
|
6
|
+
* made JSON-safe: a `$ref` that points back into the node being expanded is
|
|
7
|
+
* left as `{ "$ref": "#/…" }` (the shape the renderers already treat as
|
|
8
|
+
* "stop here"), instead of a cyclic object graph.
|
|
9
|
+
*
|
|
10
|
+
* 3.0 documents stay 3.0 on purpose: the 3.0 → 3.1 upgrade rewrites `nullable`
|
|
11
|
+
* into `type: [..., "null"]`, which the schema renderers cannot read.
|
|
12
|
+
*/
|
|
1
13
|
interface OpenApiSpec {
|
|
2
14
|
openapi: string;
|
|
3
15
|
info: OpenApiInfo;
|
|
@@ -129,5 +141,11 @@ interface OpenApiCodeSample {
|
|
|
129
141
|
label?: string;
|
|
130
142
|
source: string;
|
|
131
143
|
}
|
|
132
|
-
|
|
144
|
+
/**
|
|
145
|
+
* @param input File path, URL, or the JSON/YAML text of a spec, or a parsed
|
|
146
|
+
* spec object. Relative external `$ref`s resolve against a path or URL input.
|
|
147
|
+
* @throws with the parser's validation messages when the document is not a
|
|
148
|
+
* valid OpenAPI/Swagger document.
|
|
149
|
+
*/
|
|
150
|
+
export declare function parseOpenApiSpec(input: string | object): Promise<OpenApiSpec>;
|
|
133
151
|
export {};
|
package/dist/parser.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{bundle as e}from"@scalar/json-magic/bundle";import{fetchUrls as t,parseJson as n,parseYaml as r}from"@scalar/json-magic/bundle/plugins/browser";import{readFiles as i}from"@scalar/json-magic/bundle/plugins/node";import{dereference as a,validate as o}from"@scalar/openapi-parser";import{upgradeFromTwoToThree as s}from"@scalar/openapi-upgrader/2.0-to-3.0";function c(e,t,n){if(typeof e!=`object`||!e)return e;let r=t.get(e);if(r!==void 0){if(n.has(r))return{$ref:r};n.add(r)}let i=Array.isArray(e)?e.map(e=>c(e,t,n)):Object.fromEntries(Object.entries(e).map(([e,r])=>[e,c(r,t,n)]));return r!==void 0&&n.delete(r),i}async function l(l){let u=await e(l,{plugins:[i(),t(),r(),n()],treeShake:!1}),d=typeof u.swagger==`string`?s(u):u,f=await o(d);if(!f.valid){let e=f.errors.map(e=>e.message).join(`; `);throw Error(`Invalid OpenAPI spec: ${e}`)}let p=/* @__PURE__ */ new Map,{schema:m,errors:h}=a(d,{onDereference:({schema:e,ref:t})=>{p.set(e,t)}});if(h?.length)throw Error(`Invalid OpenAPI spec: ${h.map(e=>e.message).join(`; `)}`);return c(m,p,/* @__PURE__ */ new Set)}export{l as parseOpenApiSpec};
|
package/dist/server.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{openapiExtractEndpoints as e,openapiMergeSpecs as t,openapiNavigationBuild as n}from"@publier/native";import{bundle as r}from"@scalar/json-magic/bundle";import{fetchUrls as i,parseJson as a,parseYaml as o}from"@scalar/json-magic/bundle/plugins/browser";import{readFiles as s}from"@scalar/json-magic/bundle/plugins/node";import{dereference as c,validate as l}from"@scalar/openapi-parser";import{upgradeFromTwoToThree as u}from"@scalar/openapi-upgrader/2.0-to-3.0";const d=[`get`,`post`,`put`,`delete`,`patch`,`head`,`options`];function f(t,n={}){let{mergePathParameters:r=!1,includeWebhooks:i=!0}=n;return JSON.parse(e(JSON.stringify(t),r,i))}function p(e,t={}){let{groupBy:r=`tag`,slugPrefix:i,excludeDeprecated:a=!1,includeWebhooks:o=!0}=t;return JSON.parse(n(JSON.stringify(e),r,i??null,a,o))}function m(e,t,n){if(typeof e!=`object`||!e)return e;let r=t.get(e);if(r!==void 0){if(n.has(r))return{$ref:r};n.add(r)}let i=Array.isArray(e)?e.map(e=>m(e,t,n)):Object.fromEntries(Object.entries(e).map(([e,r])=>[e,m(r,t,n)]));return r!==void 0&&n.delete(r),i}async function h(e){let t=await r(e,{plugins:[s(),i(),o(),a()],treeShake:!1}),n=typeof t.swagger==`string`?u(t):t,d=await l(n);if(!d.valid){let e=d.errors.map(e=>e.message).join(`; `);throw Error(`Invalid OpenAPI spec: ${e}`)}let f=/* @__PURE__ */ new Map,{schema:p,errors:h}=c(n,{onDereference:({schema:e,ref:t})=>{f.set(e,t)}});if(h?.length)throw Error(`Invalid OpenAPI spec: ${h.map(e=>e.message).join(`; `)}`);return m(p,f,/* @__PURE__ */ new Set)}function g(e){let n=null;async function r(){if(n&&!e.disableCache)return n;let r=[];for(let t of e.input)typeof t==`string`?r.push(await h(t)):r.push(t);if(r.length===0)throw Error(`No OpenAPI specs provided`);return r.length===1?(n=r[0],n):(n=JSON.parse(t(JSON.stringify(r))),n)}return{getSpec:r,async getOperation(e){let t=await r();for(let[n,r]of Object.entries(t.paths))for(let t of d){let i=r[t];if(i?.operationId===e)return{method:t,path:n,operation:i}}},async getOperationByPath(e,t){let n=(await r()).paths[e]?.[t];return n?{method:t,path:e,operation:n}:void 0},async getOperationsByTag(e){return f(await r(),{mergePathParameters:!0}).filter(t=>t.operation.tags?.includes(e)).map(({method:e,path:t,operation:n})=>({method:e,path:t,operation:n}))},async getEndpoints(){return f(await r(),{mergePathParameters:!0})},async getNavigation(e){return p(await r(),e)}}}export{g as createOpenAPI};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@publier/openapi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -45,8 +45,13 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@publier/native": "0.
|
|
48
|
+
"@publier/native": "0.20.0",
|
|
49
49
|
"@readme/httpsnippet": "^11.4.1",
|
|
50
|
+
"@readme/oas-to-har": "^39.0.1",
|
|
51
|
+
"@scalar/json-magic": "^0.19.1",
|
|
52
|
+
"@scalar/openapi-parser": "^0.29.22",
|
|
53
|
+
"@scalar/openapi-upgrader": "^0.4.9",
|
|
54
|
+
"oas": "^39.0.1",
|
|
50
55
|
"openapi-sampler": "^1.7.10",
|
|
51
56
|
"yaml": "^2.9.1"
|
|
52
57
|
},
|
|
@@ -16,6 +16,6 @@ const L = JSON.parse(openapiRenderApiReferenceShell());
|
|
|
16
16
|
<APIPage method={method} path={path} operation={operation} />
|
|
17
17
|
<Fragment set:html={L.mainCloseAsideOpen} />
|
|
18
18
|
<RequestExample method={method} path={path} operation={operation} baseUrl={baseUrl} />
|
|
19
|
-
<CodeSamples method={method} path={path} operation={operation} baseUrl={baseUrl} />
|
|
19
|
+
<CodeSamples method={method} path={path} operation={operation} spec={spec} baseUrl={baseUrl} />
|
|
20
20
|
<ResponseExample responses={operation.responses} instanceId={instanceId} />
|
|
21
21
|
<Fragment set:html={L.close} />
|
|
@@ -4,8 +4,8 @@ import { buildCodeSamples } from '../code-sample-generators.ts';
|
|
|
4
4
|
import type { CodeSamplesProps } from './props.ts';
|
|
5
5
|
type Props = CodeSamplesProps;
|
|
6
6
|
|
|
7
|
-
const { method, path, operation, baseUrl = 'https://api.example.com' } = Astro.props;
|
|
8
|
-
const samples = buildCodeSamples(method, path, operation, baseUrl);
|
|
7
|
+
const { method, path, operation, spec, baseUrl = 'https://api.example.com' } = Astro.props;
|
|
8
|
+
const samples = buildCodeSamples(method, path, operation, baseUrl, spec);
|
|
9
9
|
const html = openapiRenderCodeSamples(method, path, JSON.stringify(samples));
|
|
10
10
|
---
|
|
11
11
|
|