@publier/openapi 0.1.19 → 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/dist/index.d.mts CHANGED
@@ -216,7 +216,17 @@ 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
+ /**
221
+ * Build the full `(lang, label, code)` triple list the Rust renderer
222
+ * expects, in the canonical LANGUAGES order. Honors x-codeSamples
223
+ * overrides first, then falls back to auto-generation.
224
+ */
225
+ export declare function buildCodeSamples(method: HttpMethod, path: string, operation: OpenApiOperation, baseUrl: string, spec?: OpenApiSpec): {
226
+ lang: SampleLang;
227
+ label: string;
228
+ code: string;
229
+ }[];
220
230
  interface APIReferenceProps {
221
231
  method: HttpMethod;
222
232
  path: string;
@@ -244,6 +254,8 @@ interface CodeSamplesProps {
244
254
  method: HttpMethod;
245
255
  path: string;
246
256
  operation: OpenApiOperation;
257
+ /** The parsed specification; its security schemes put credentials into the samples. */
258
+ spec?: OpenApiSpec;
247
259
  baseUrl?: string;
248
260
  }
249
261
  interface RequestExampleProps {
@@ -321,8 +333,8 @@ interface ExtractEndpointsOptions {
321
333
  }
322
334
  export declare function extractEndpoints(spec: OpenApiSpec, options?: ExtractEndpointsOptions): EndpointEntry[];
323
335
  export declare function generateExampleFromSchema(schema: OpenApiSchema): unknown;
324
- export declare function getMediaTypeExample(content: Record<string, OpenApiMediaType>, mediaType?: string): string | undefined;
325
336
  export declare function formatJson(value: unknown): string;
337
+ export declare function getMediaTypeExample(content: Record<string, OpenApiMediaType>, mediaType?: string): string | undefined;
326
338
  interface GenerateFilesOptions {
327
339
  /** The parsed OpenAPI spec. */
328
340
  spec: OpenApiSpec;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{asyncapiSourceBuild as e,openapiDecodePlaceholders as t,openapiExtractEndpoints as n,openapiGetMediaTypeExample as r,openapiGetSnippetClient as i,openapiHarFromOperation as a,openapiNavigationBuild as o,openapiSourceBuild as s}from"@publier/native";import{HTTPSnippet as c}from"@readme/httpsnippet";import l from"openapi-sampler";function u(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 d(e,n,r,o,s){let l=i(o);if(!l)return``;let[u,d]=l,f=JSON.parse(a(e,n,JSON.stringify(r),s)),p=new c(f).convert(u,d),m=``;if(Array.isArray(p)){let e=p.find(e=>typeof e==`string`);typeof e==`string`&&(m=e)}else typeof p==`string`&&(m=p);return t(m)}const f=[`get`,`post`,`put`,`delete`,`patch`,`head`,`options`];function p(e,t={}){let{mergePathParameters:r=!1,includeWebhooks:i=!0}=t;return JSON.parse(n(JSON.stringify(e),r,i))}function m(e){return l.sample(e)}function h(e,t=`application/json`){let n=r(JSON.stringify(e),t);if(n===`__schema__`){let n=Object.keys(e)[0],r=e[t]??(n?e[n]:void 0);return r?.schema?g(m(r.schema)):void 0}return n??void 0}function g(e){return JSON.stringify(e,null,2)}function _(e,t={}){let{groupBy:n=`tag`,slugPrefix:r,excludeDeprecated:i=!1,includeWebhooks:a=!0}=t;return JSON.parse(o(JSON.stringify(e),n,r??null,i,a))}function v(e){let{spec:t,baseUrl:n=``}=e,{pages:r,tree:i}=JSON.parse(s(JSON.stringify(t),n)),a=new Map(r.map(e=>[e.slug.join(`/`),e]));return{async getPage(e){return a.get(e.join(`/`))},async getPages(){return r},async getPageTree(){return i},async generateParams(){return r.map(e=>({slug:e.slug}))}}}export{f as HTTP_METHODS,u as asyncapiSource,_ as buildNavigation,p as extractEndpoints,g as formatJson,d as generateCodeSample,m as generateExampleFromSchema,h as getMediaTypeExample,v as openapiSource};
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*as 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}))}}}const l=s.sample??s.default.sample;function u(e){return l(e)}function d(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?u(n.schema):void 0}function f(e){return JSON.stringify(e,null,2)}function p(e,t=`application/json`){let n=d(e,t);return n===void 0?void 0:f(n)}const m=[`curl`,`javascript`,`python`,`go`,`java`,`csharp`],h={curl:`cURL`,javascript:`JavaScript`,python:`Python`,go:`Go`,java:`Java`,csharp:`C#`},g={curl:[`shell`,`curl`],javascript:[`javascript`,`fetch`],python:[`python`,`requests`],go:[`go`,`native`],java:[`java`,`nethttp`],csharp:[`csharp`,`httpclient`]},_={curl:`curl`,javascript:`javascript`,js:`javascript`,python:`python`,py:`python`,go:`go`,golang:`go`,java:`java`,csharp:`csharp`,"c#":`csharp`,cs:`csharp`};function v(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 y(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),u={path:{},query:{},header:{},cookie:{}};for(let[,e]of t.matchAll(/\{([^}]+)\}/g))e&&(u.path[e]=`{${e}}`);for(let e of l.getParameters()){let t=u[e.in];t&&e.in!==`path`&&(t[e.name]=`<value>`)}if(l.hasRequestBody()){let e=l.schema.requestBody,t=l.getContentType(),n=d(e?.content??{},t);l.isFormUrlEncoded()||l.isMultipart()?u.formData=n??{}:n!==void 0&&(u.body=n)}return a(c,l,u,v(c,l.getSecurity())).log.entries[0].request}function b(e){return e.replace(/%(?:25)?(3C|3E|7B|7D)/gi,(e,t)=>String.fromCharCode(Number.parseInt(t,16)))}function x(e,t){let[n,r]=g[t],a=new i(e).convert(n,r),o=Array.isArray(a)?a.find(e=>typeof e==`string`):a;return b(typeof o==`string`?o:``)}function S(e,t,n,r,i,a){return g[r]?x(y(e,t,n,i,a),r):``}function C(e){let t=/* @__PURE__ */ new Map;for(let{lang:n,source:r}of e){let e=_[n.trim().toLowerCase()];e&&t.set(e,r)}return t}function w(e,t,n,r,i){let a=C(n[`x-codeSamples`]??[]),o=m.some(e=>!a.has(e))?y(e,t,n,r,i):void 0;return m.map(e=>({lang:e,label:h[e],code:a.get(e)??(o?x(o,e):``)}))}const T=[`get`,`post`,`put`,`delete`,`patch`,`head`,`options`];function E(e,n={}){let{mergePathParameters:r=!1,includeWebhooks:i=!0}=n;return JSON.parse(t(JSON.stringify(e),r,i))}function D(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 O(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{T as HTTP_METHODS,c as asyncapiSource,w as buildCodeSamples,D as buildNavigation,E as extractEndpoints,f as formatJson,S as generateCodeSample,u as generateExampleFromSchema,p as getMediaTypeExample,O 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,15 @@ interface OpenApiCodeSample {
129
141
  label?: string;
130
142
  source: string;
131
143
  }
132
- export declare function parseOpenApiSpec(input: string): OpenApiSpec;
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
+ * @param options.onRead Called with each local file the parser reads (the spec
148
+ * and the files it `$ref`s), so a dev server can watch them.
149
+ * @throws with the parser's validation messages when the document is not a
150
+ * valid OpenAPI/Swagger document.
151
+ */
152
+ export declare function parseOpenApiSpec(input: string | object, options?: {
153
+ onRead?: (file: string) => void;
154
+ }): Promise<OpenApiSpec>;
133
155
  export {};
package/dist/parser.mjs CHANGED
@@ -1 +1 @@
1
- import{openapiParseOpenapiSpec as e}from"@publier/native";import{parse as t}from"yaml";function n(n){let r;try{JSON.parse(n),r=n}catch{r=JSON.stringify(t(n))}return JSON.parse(e(r))}export{n as parseOpenApiSpec};
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,u={}){let d=i(),f={...d,exec:e=>(u.onRead?.(e),d.exec(e))},p=await e(l,{plugins:[f,t(),r(),n()],treeShake:!1}),m=typeof p.swagger==`string`?s(p):p,h=await o(m);if(!h.valid){let e=h.errors.map(e=>e.message).join(`; `);throw Error(`Invalid OpenAPI spec: ${e}`)}let g=/* @__PURE__ */ new Map,{schema:_,errors:v}=a(m,{onDereference:({schema:e,ref:t})=>{g.set(e,t)}});if(v?.length)throw Error(`Invalid OpenAPI spec: ${v.map(e=>e.message).join(`; `)}`);return c(_,g,/* @__PURE__ */ new Set)}export{l as parseOpenApiSpec};
package/dist/server.mjs CHANGED
@@ -1 +1 @@
1
- import{readFileSync as e}from"node:fs";import{openapiExtractEndpoints as t,openapiMergeSpecs as n,openapiNavigationBuild as r,openapiParseOpenapiSpec as i}from"@publier/native";import{parse as a}from"yaml";const o=[`get`,`post`,`put`,`delete`,`patch`,`head`,`options`];function s(e,n={}){let{mergePathParameters:r=!1,includeWebhooks:i=!0}=n;return JSON.parse(t(JSON.stringify(e),r,i))}function c(e,t={}){let{groupBy:n=`tag`,slugPrefix:i,excludeDeprecated:a=!1,includeWebhooks:o=!0}=t;return JSON.parse(r(JSON.stringify(e),n,i??null,a,o))}function l(e){let t;try{JSON.parse(e),t=e}catch{t=JSON.stringify(a(e))}return JSON.parse(i(t))}function u(t){let r=null;async function i(){if(r&&!t.disableCache)return r;let i=[];for(let n of t.input)if(typeof n==`string`){let t;if(n.startsWith(`http:`)||n.startsWith(`https:`)){let e=await fetch(n);if(!e.ok)throw Error(`Failed to fetch OpenAPI spec from "${n}": ${e.status} ${e.statusText}`);t=await e.text()}else t=e(n,`utf-8`);i.push(l(t))}else i.push(n);if(i.length===0)throw Error(`No OpenAPI specs provided`);return i.length===1?(r=i[0],r):(r=JSON.parse(n(JSON.stringify(i))),r)}return{getSpec:i,async getOperation(e){let t=await i();for(let[n,r]of Object.entries(t.paths))for(let t of o){let i=r[t];if(i?.operationId===e)return{method:t,path:n,operation:i}}},async getOperationByPath(e,t){let n=(await i()).paths[e]?.[t];return n?{method:t,path:e,operation:n}:void 0},async getOperationsByTag(e){return s(await i(),{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 s(await i(),{mergePathParameters:!0})},async getNavigation(e){return c(await i(),e)}}}export{u as createOpenAPI};
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,t={}){let n=s(),d={...n,exec:e=>(t.onRead?.(e),n.exec(e))},f=await r(e,{plugins:[d,i(),o(),a()],treeShake:!1}),p=typeof f.swagger==`string`?u(f):f,h=await l(p);if(!h.valid){let e=h.errors.map(e=>e.message).join(`; `);throw Error(`Invalid OpenAPI spec: ${e}`)}let g=/* @__PURE__ */ new Map,{schema:_,errors:v}=c(p,{onDereference:({schema:e,ref:t})=>{g.set(e,t)}});if(v?.length)throw Error(`Invalid OpenAPI spec: ${v.map(e=>e.message).join(`; `)}`);return m(_,g,/* @__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.1.19",
3
+ "version": "0.3.0",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "files": [
@@ -8,6 +8,8 @@
8
8
  "src/components/**/*.astro",
9
9
  "src/components/**/*.ts",
10
10
  "src/components/props.ts",
11
+ "src/types.ts",
12
+ "src/async-types.ts",
11
13
  "!src/**/__tests__/**",
12
14
  "!src/**/*.test.ts"
13
15
  ],
@@ -45,8 +47,13 @@
45
47
  "access": "public"
46
48
  },
47
49
  "dependencies": {
48
- "@publier/native": "0.19.0",
50
+ "@publier/native": "0.21.0",
49
51
  "@readme/httpsnippet": "^11.4.1",
52
+ "@readme/oas-to-har": "^39.0.1",
53
+ "@scalar/json-magic": "^0.19.1",
54
+ "@scalar/openapi-parser": "^0.29.22",
55
+ "@scalar/openapi-upgrader": "^0.4.9",
56
+ "oas": "^39.0.1",
50
57
  "openapi-sampler": "^1.7.10",
51
58
  "yaml": "^2.9.1"
52
59
  },
@@ -0,0 +1,59 @@
1
+ import type { OpenApiSchema } from './types.ts';
2
+
3
+ export interface AsyncApiSpec {
4
+ asyncapi: string;
5
+ info: { title: string; description?: string; version: string };
6
+ servers?: Record<string, AsyncApiServer>;
7
+ channels?: Record<string, AsyncApiChannel>;
8
+ operations?: Record<string, AsyncApiOperation>;
9
+ components?: AsyncApiComponents;
10
+ }
11
+
12
+ export interface AsyncApiServer {
13
+ host: string;
14
+ protocol: string;
15
+ pathname?: string;
16
+ description?: string;
17
+ tags?: { name: string; description?: string }[];
18
+ }
19
+
20
+ export interface AsyncApiChannel {
21
+ address?: string;
22
+ description?: string;
23
+ messages?: Record<string, AsyncApiMessage | { $ref: string }>;
24
+ parameters?: Record<string, AsyncApiParameter>;
25
+ tags?: { name: string; description?: string }[];
26
+ }
27
+
28
+ export interface AsyncApiOperation {
29
+ action: 'send' | 'receive';
30
+ channel: { $ref: string };
31
+ summary?: string;
32
+ description?: string;
33
+ messages?: ({ $ref: string } | AsyncApiMessage)[];
34
+ tags?: { name: string; description?: string }[];
35
+ }
36
+
37
+ export interface AsyncApiMessage {
38
+ name?: string;
39
+ title?: string;
40
+ summary?: string;
41
+ description?: string;
42
+ contentType?: string;
43
+ payload?: OpenApiSchema;
44
+ headers?: OpenApiSchema;
45
+ tags?: { name: string; description?: string }[];
46
+ }
47
+
48
+ export interface AsyncApiParameter {
49
+ description?: string;
50
+ default?: string;
51
+ enum?: string[];
52
+ }
53
+
54
+ export interface AsyncApiComponents {
55
+ schemas?: Record<string, OpenApiSchema>;
56
+ messages?: Record<string, AsyncApiMessage>;
57
+ channels?: Record<string, AsyncApiChannel>;
58
+ operations?: Record<string, AsyncApiOperation>;
59
+ }
@@ -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} />
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  import { openapiRenderCodeSamples } from '@publier/native';
3
- import { buildCodeSamples } from '../code-sample-generators.ts';
3
+ import { buildCodeSamples } from '@publier/openapi';
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
 
@@ -43,6 +43,8 @@ export interface CodeSamplesProps {
43
43
  method: HttpMethod;
44
44
  path: string;
45
45
  operation: OpenApiOperation;
46
+
47
+ spec?: OpenApiSpec;
46
48
  baseUrl?: string;
47
49
  }
48
50
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import { openapiRenderRequestExample } from '@publier/native';
3
- import { getMediaTypeExample } from '../example-utils.ts';
3
+ import { getMediaTypeExample } from '@publier/openapi';
4
4
  import type { RequestExampleProps } from './props.ts';
5
5
  type Props = RequestExampleProps;
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import { openapiRenderResponseExample } from '@publier/native';
3
- import { getMediaTypeExample } from '../example-utils.ts';
3
+ import { getMediaTypeExample } from '@publier/openapi';
4
4
  import type { ResponseExampleProps } from './props.ts';
5
5
  type Props = ResponseExampleProps;
6
6
 
package/src/types.ts ADDED
@@ -0,0 +1,140 @@
1
+ export interface OpenApiSpec {
2
+ openapi: string;
3
+ info: OpenApiInfo;
4
+ servers?: OpenApiServer[];
5
+ paths: Record<string, OpenApiPathItem>;
6
+ /**
7
+ * OpenAPI 3.1 webhooks — server-to-client push endpoints, keyed by name.
8
+ * Shape-identical to path items but not part of the HTTP routing table.
9
+ */
10
+ webhooks?: Record<string, OpenApiPathItem>;
11
+ components?: OpenApiComponents;
12
+ security?: Record<string, string[]>[];
13
+ tags?: OpenApiTag[];
14
+ }
15
+
16
+ export interface OpenApiInfo {
17
+ title: string;
18
+ description?: string;
19
+ version: string;
20
+ }
21
+
22
+ export interface OpenApiServer {
23
+ url: string;
24
+ description?: string;
25
+ }
26
+
27
+ export interface OpenApiPathItem {
28
+ get?: OpenApiOperation;
29
+ post?: OpenApiOperation;
30
+ put?: OpenApiOperation;
31
+ delete?: OpenApiOperation;
32
+ patch?: OpenApiOperation;
33
+ head?: OpenApiOperation;
34
+ options?: OpenApiOperation;
35
+ summary?: string;
36
+ description?: string;
37
+ parameters?: OpenApiParameter[];
38
+ }
39
+
40
+ export interface OpenApiOperation {
41
+ operationId?: string;
42
+ summary?: string;
43
+ description?: string;
44
+ tags?: string[];
45
+ parameters?: OpenApiParameter[];
46
+ requestBody?: OpenApiRequestBody;
47
+ responses: Record<string, OpenApiResponse>;
48
+ /**
49
+ * OpenAPI 3.0+ callbacks — out-of-band requests the service will make in
50
+ * response to this operation.
51
+ */
52
+ callbacks?: Record<string, Record<string, OpenApiPathItem>>;
53
+ security?: Record<string, string[]>[];
54
+ deprecated?: boolean;
55
+ 'x-codeSamples'?: OpenApiCodeSample[];
56
+ }
57
+
58
+ export interface OpenApiParameter {
59
+ name: string;
60
+ in: 'path' | 'query' | 'header' | 'cookie';
61
+ description?: string;
62
+ required?: boolean;
63
+ schema?: OpenApiSchema;
64
+ deprecated?: boolean;
65
+ }
66
+
67
+ export interface OpenApiRequestBody {
68
+ description?: string;
69
+ required?: boolean;
70
+ content: Record<string, OpenApiMediaType>;
71
+ }
72
+
73
+ export interface OpenApiResponse {
74
+ description: string;
75
+ content?: Record<string, OpenApiMediaType>;
76
+ headers?: Record<string, { description?: string; schema?: OpenApiSchema }>;
77
+ }
78
+
79
+ export interface OpenApiMediaType {
80
+ schema?: OpenApiSchema;
81
+ example?: unknown;
82
+ examples?: Record<string, { value: unknown; summary?: string }>;
83
+ }
84
+
85
+ export interface OpenApiSchema {
86
+ type?: string;
87
+ format?: string;
88
+ description?: string;
89
+ properties?: Record<string, OpenApiSchema>;
90
+ items?: OpenApiSchema;
91
+ required?: string[];
92
+ enum?: unknown[];
93
+ default?: unknown;
94
+ oneOf?: OpenApiSchema[];
95
+ anyOf?: OpenApiSchema[];
96
+ allOf?: OpenApiSchema[];
97
+ $ref?: string;
98
+ nullable?: boolean;
99
+ readOnly?: boolean;
100
+ writeOnly?: boolean;
101
+ deprecated?: boolean;
102
+ example?: unknown;
103
+ title?: string;
104
+ minimum?: number;
105
+ maximum?: number;
106
+ pattern?: string;
107
+ minLength?: number;
108
+ maxLength?: number;
109
+ additionalProperties?: boolean | OpenApiSchema;
110
+ }
111
+
112
+ export interface OpenApiComponents {
113
+ schemas?: Record<string, OpenApiSchema>;
114
+ parameters?: Record<string, OpenApiParameter>;
115
+ responses?: Record<string, OpenApiResponse>;
116
+ requestBodies?: Record<string, OpenApiRequestBody>;
117
+ securitySchemes?: Record<string, OpenApiSecurityScheme>;
118
+ }
119
+
120
+ export interface OpenApiSecurityScheme {
121
+ type: 'apiKey' | 'http' | 'oauth2' | 'openIdConnect';
122
+ description?: string;
123
+ name?: string;
124
+ in?: 'query' | 'header' | 'cookie';
125
+ scheme?: string;
126
+ bearerFormat?: string;
127
+ }
128
+
129
+ export interface OpenApiTag {
130
+ name: string;
131
+ description?: string;
132
+ }
133
+
134
+ export interface OpenApiCodeSample {
135
+ lang: string;
136
+ label?: string;
137
+ source: string;
138
+ }
139
+
140
+ export type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'options';