mirror of
https://github.com/LukeHagar/OpenAPI.gg.git
synced 2025-12-09 12:37:48 +00:00
add new types and info page
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<script lang="ts">
|
||||
<!-- <script lang="ts">
|
||||
import { openApiStore } from '$lib';
|
||||
import {
|
||||
apiKeyAuthTemplate,
|
||||
@@ -80,4 +80,4 @@
|
||||
Add Security Schema
|
||||
</button>
|
||||
</span>
|
||||
</form>
|
||||
</form> -->
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { popup, type PopupSettings } from '@skeletonlabs/skeleton';
|
||||
import Info from '../icons/Info.svelte';
|
||||
import { openApiStore } from '$lib';
|
||||
|
||||
const descriptionTooltip: PopupSettings = {
|
||||
event: 'click',
|
||||
target: 'descriptionTooltip',
|
||||
placement: 'top'
|
||||
};
|
||||
</script>
|
||||
|
||||
<form class="container mx-auto card px-6 py-4 space-y-4">
|
||||
@@ -18,20 +11,17 @@
|
||||
name="title"
|
||||
placeholder="Sample API"
|
||||
type="text"
|
||||
bind:value={$openApiStore.title}
|
||||
bind:value={$openApiStore.info.title}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label class="text-xl space-y-2">
|
||||
<span>
|
||||
Description (optional) <button type="button" use:popup={descriptionTooltip}>
|
||||
<Info />
|
||||
</button>
|
||||
</span>
|
||||
<span> Description (optional) </span>
|
||||
<textarea
|
||||
class="textarea"
|
||||
name="description"
|
||||
placeholder="Sample API description"
|
||||
bind:value={$openApiStore.description}
|
||||
placeholder="Optional multiline or single-line description. Supports Markdown."
|
||||
bind:value={$openApiStore.info.description}
|
||||
/>
|
||||
</label>
|
||||
<label class="text-xl space-y-2">
|
||||
@@ -41,13 +31,51 @@
|
||||
name="version"
|
||||
placeholder="0.1.0"
|
||||
type="text"
|
||||
bind:value={$openApiStore.version}
|
||||
bind:value={$openApiStore.info.version}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label class="text-xl space-y-2">
|
||||
<span>Terms of Service (optional)</span>
|
||||
<input
|
||||
class="input"
|
||||
name="termsOfService"
|
||||
placeholder="https://example.com/terms"
|
||||
type="url"
|
||||
bind:value={$openApiStore.info.termsOfService}
|
||||
/>
|
||||
</label>
|
||||
<div class="border-token rounded-container-token space-y-4 p-4">
|
||||
<h4 class="h4">Contact Information</h4>
|
||||
<label class="text-xl space-y-2">
|
||||
<span>Name (optional)</span>
|
||||
<input
|
||||
class="input"
|
||||
name="contactName"
|
||||
placeholder="John Doe"
|
||||
type="text"
|
||||
bind:value={$openApiStore.info.contact.name}
|
||||
/>
|
||||
</label>
|
||||
<label class="text-xl space-y-2">
|
||||
<span>Email (optional)</span>
|
||||
<input
|
||||
class="input"
|
||||
name="contactEmail"
|
||||
placeholder="email@example.com"
|
||||
type="email"
|
||||
bind:value={$openApiStore.info.contact.email}
|
||||
/>
|
||||
</label>
|
||||
<label class="text-xl space-y-2">
|
||||
<span>URL (optional)</span>
|
||||
<input
|
||||
class="input"
|
||||
name="contactUrl"
|
||||
placeholder="https://example.com"
|
||||
type="url"
|
||||
bind:value={$openApiStore.info.contact.url}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Description Tooltip -->
|
||||
<div class="card px-4 py-2 variant-filled-primary" data-popup="descriptionTooltip">
|
||||
<p>Optional multiline or single-line description. Supports Markdown.</p>
|
||||
<div class="arrow variant-filled-primary" />
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<script lang="ts">
|
||||
<!-- <script lang="ts">
|
||||
import { openApiStore } from '$lib';
|
||||
import ServerInput from '../atoms/ServerInput.svelte';
|
||||
|
||||
@@ -35,10 +35,9 @@
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
<!-- Add another Server Button -->
|
||||
<span class="flex justify-center" class:!mt-0={$openApiStore.servers.length === 0}>
|
||||
<button type="button" class="btn variant-filled-primary" on:click={addServer}>
|
||||
Add Server
|
||||
</button>
|
||||
</span>
|
||||
</form>
|
||||
</form> -->
|
||||
|
||||
@@ -1,12 +1,40 @@
|
||||
import type { OpenAPI } from './types';
|
||||
import { persisted } from 'svelte-persisted-store';
|
||||
import type { OpenAPIV3 } from './openAPITypes';
|
||||
|
||||
export const localStoragePrefix = 'openapigen-';
|
||||
|
||||
export const openApiStore = persisted<OpenAPI>(`${localStoragePrefix}openApi`, {
|
||||
title: '',
|
||||
version: '',
|
||||
description: '',
|
||||
export const openApiStore = persisted<OpenAPIV3.Document>(`${localStoragePrefix}openApi`, {
|
||||
openapi: '3.0.0', // OpenAPI version
|
||||
info: {
|
||||
/** Title of the API (required) */
|
||||
title: '',
|
||||
/** Description of the API (optional) */
|
||||
description: '',
|
||||
/** Terms of service link (optional) */
|
||||
termsOfService: '',
|
||||
/** API Version (required) */
|
||||
version: '',
|
||||
/** Contact Information */
|
||||
contact: {
|
||||
/** Name of the contact person/organization. */
|
||||
name: '', // optional
|
||||
/** URL pointing to the contact information. MUST be in the format of a URL. */
|
||||
url: '', // optional
|
||||
/** Email address of the contact person/organization. MUST be in the format of an email address. */
|
||||
email: '' // optional
|
||||
},
|
||||
license: {
|
||||
name: '', // required if license is included
|
||||
url: '' // optional
|
||||
}
|
||||
},
|
||||
servers: [],
|
||||
securitySchemas: []
|
||||
paths: {},
|
||||
components: {},
|
||||
security: [],
|
||||
tags: [],
|
||||
externalDocs: {
|
||||
description: '',
|
||||
url: ''
|
||||
}
|
||||
});
|
||||
|
||||
330
src/lib/openAPITypes.d.ts
vendored
Normal file
330
src/lib/openAPITypes.d.ts
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export namespace OpenAPIV3 {
|
||||
interface Document<T extends {} = {}> {
|
||||
openapi: string;
|
||||
info: InfoObject;
|
||||
servers?: ServerObject[];
|
||||
paths: PathsObject<T>;
|
||||
components?: ComponentsObject;
|
||||
security?: SecurityRequirementObject[];
|
||||
tags?: TagObject[];
|
||||
externalDocs?: ExternalDocumentationObject;
|
||||
'x-express-openapi-additional-middleware'?: (
|
||||
| ((request: any, response: any, next: any) => Promise<void>)
|
||||
| ((request: any, response: any, next: any) => void)
|
||||
)[];
|
||||
'x-express-openapi-validation-strict'?: boolean;
|
||||
}
|
||||
interface InfoObject {
|
||||
title: string;
|
||||
description: string;
|
||||
termsOfService: string;
|
||||
contact: ContactObject;
|
||||
license: LicenseObject;
|
||||
version: string;
|
||||
}
|
||||
interface ContactObject {
|
||||
name?: string;
|
||||
url?: string;
|
||||
email?: string;
|
||||
}
|
||||
interface LicenseObject {
|
||||
name: string;
|
||||
url?: string;
|
||||
}
|
||||
interface ServerObject {
|
||||
url: string;
|
||||
description?: string;
|
||||
variables?: {
|
||||
[variable: string]: ServerVariableObject;
|
||||
};
|
||||
}
|
||||
interface ServerVariableObject {
|
||||
enum?: string[];
|
||||
default: string;
|
||||
description?: string;
|
||||
}
|
||||
interface PathsObject<T extends {} = {}, P extends {} = {}> {
|
||||
[pattern: string]: (PathItemObject<T> & P) | undefined;
|
||||
}
|
||||
enum HttpMethods {
|
||||
GET = 'get',
|
||||
PUT = 'put',
|
||||
POST = 'post',
|
||||
DELETE = 'delete',
|
||||
OPTIONS = 'options',
|
||||
HEAD = 'head',
|
||||
PATCH = 'patch',
|
||||
TRACE = 'trace'
|
||||
}
|
||||
type PathItemObject<T extends {} = {}> = {
|
||||
$ref?: string;
|
||||
summary?: string;
|
||||
description?: string;
|
||||
servers?: ServerObject[];
|
||||
parameters?: (ReferenceObject | ParameterObject)[];
|
||||
} & {
|
||||
[method in HttpMethods]?: OperationObject<T>;
|
||||
};
|
||||
type OperationObject<T extends {} = {}> = {
|
||||
tags?: string[];
|
||||
summary?: string;
|
||||
description?: string;
|
||||
externalDocs?: ExternalDocumentationObject;
|
||||
operationId?: string;
|
||||
parameters?: (ReferenceObject | ParameterObject)[];
|
||||
requestBody?: ReferenceObject | RequestBodyObject;
|
||||
responses: ResponsesObject;
|
||||
callbacks?: {
|
||||
[callback: string]: ReferenceObject | CallbackObject;
|
||||
};
|
||||
deprecated?: boolean;
|
||||
security?: SecurityRequirementObject[];
|
||||
servers?: ServerObject[];
|
||||
} & T;
|
||||
interface ExternalDocumentationObject {
|
||||
description?: string;
|
||||
url: string;
|
||||
}
|
||||
interface ParameterObject extends ParameterBaseObject {
|
||||
name: string;
|
||||
in: string;
|
||||
}
|
||||
interface HeaderObject extends ParameterBaseObject {}
|
||||
interface ParameterBaseObject {
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
deprecated?: boolean;
|
||||
allowEmptyValue?: boolean;
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
schema?: ReferenceObject | SchemaObject;
|
||||
example?: any;
|
||||
examples?: {
|
||||
[media: string]: ReferenceObject | ExampleObject;
|
||||
};
|
||||
content?: {
|
||||
[media: string]: MediaTypeObject;
|
||||
};
|
||||
}
|
||||
type NonArraySchemaObjectType = 'boolean' | 'object' | 'number' | 'string' | 'integer';
|
||||
type ArraySchemaObjectType = 'array';
|
||||
type SchemaObject = ArraySchemaObject | NonArraySchemaObject;
|
||||
interface ArraySchemaObject extends BaseSchemaObject {
|
||||
type: ArraySchemaObjectType;
|
||||
items: ReferenceObject | SchemaObject;
|
||||
}
|
||||
interface NonArraySchemaObject extends BaseSchemaObject {
|
||||
type?: NonArraySchemaObjectType;
|
||||
}
|
||||
interface BaseSchemaObject {
|
||||
title?: string;
|
||||
description?: string;
|
||||
format?: string;
|
||||
default?: any;
|
||||
multipleOf?: number;
|
||||
maximum?: number;
|
||||
exclusiveMaximum?: boolean;
|
||||
minimum?: number;
|
||||
exclusiveMinimum?: boolean;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
pattern?: string;
|
||||
additionalProperties?: boolean | ReferenceObject | SchemaObject;
|
||||
maxItems?: number;
|
||||
minItems?: number;
|
||||
uniqueItems?: boolean;
|
||||
maxProperties?: number;
|
||||
minProperties?: number;
|
||||
required?: string[];
|
||||
enum?: any[];
|
||||
properties?: {
|
||||
[name: string]: ReferenceObject | SchemaObject;
|
||||
};
|
||||
allOf?: (ReferenceObject | SchemaObject)[];
|
||||
oneOf?: (ReferenceObject | SchemaObject)[];
|
||||
anyOf?: (ReferenceObject | SchemaObject)[];
|
||||
not?: ReferenceObject | SchemaObject;
|
||||
nullable?: boolean;
|
||||
discriminator?: DiscriminatorObject;
|
||||
readOnly?: boolean;
|
||||
writeOnly?: boolean;
|
||||
xml?: XMLObject;
|
||||
externalDocs?: ExternalDocumentationObject;
|
||||
example?: any;
|
||||
deprecated?: boolean;
|
||||
}
|
||||
interface DiscriminatorObject {
|
||||
propertyName: string;
|
||||
mapping?: {
|
||||
[value: string]: string;
|
||||
};
|
||||
}
|
||||
interface XMLObject {
|
||||
name?: string;
|
||||
namespace?: string;
|
||||
prefix?: string;
|
||||
attribute?: boolean;
|
||||
wrapped?: boolean;
|
||||
}
|
||||
interface ReferenceObject {
|
||||
$ref: string;
|
||||
}
|
||||
interface ExampleObject {
|
||||
summary?: string;
|
||||
description?: string;
|
||||
value?: any;
|
||||
externalValue?: string;
|
||||
}
|
||||
interface MediaTypeObject {
|
||||
schema?: ReferenceObject | SchemaObject;
|
||||
example?: any;
|
||||
examples?: {
|
||||
[media: string]: ReferenceObject | ExampleObject;
|
||||
};
|
||||
encoding?: {
|
||||
[media: string]: EncodingObject;
|
||||
};
|
||||
}
|
||||
interface EncodingObject {
|
||||
contentType?: string;
|
||||
headers?: {
|
||||
[header: string]: ReferenceObject | HeaderObject;
|
||||
};
|
||||
style?: string;
|
||||
explode?: boolean;
|
||||
allowReserved?: boolean;
|
||||
}
|
||||
interface RequestBodyObject {
|
||||
description?: string;
|
||||
content: {
|
||||
[media: string]: MediaTypeObject;
|
||||
};
|
||||
required?: boolean;
|
||||
}
|
||||
interface ResponsesObject {
|
||||
[code: string]: ReferenceObject | ResponseObject;
|
||||
}
|
||||
interface ResponseObject {
|
||||
description: string;
|
||||
headers?: {
|
||||
[header: string]: ReferenceObject | HeaderObject;
|
||||
};
|
||||
content?: {
|
||||
[media: string]: MediaTypeObject;
|
||||
};
|
||||
links?: {
|
||||
[link: string]: ReferenceObject | LinkObject;
|
||||
};
|
||||
}
|
||||
interface LinkObject {
|
||||
operationRef?: string;
|
||||
operationId?: string;
|
||||
parameters?: {
|
||||
[parameter: string]: any;
|
||||
};
|
||||
requestBody?: any;
|
||||
description?: string;
|
||||
server?: ServerObject;
|
||||
}
|
||||
interface CallbackObject {
|
||||
[url: string]: PathItemObject;
|
||||
}
|
||||
interface SecurityRequirementObject {
|
||||
[name: string]: string[];
|
||||
}
|
||||
interface ComponentsObject {
|
||||
schemas?: {
|
||||
[key: string]: ReferenceObject | SchemaObject;
|
||||
};
|
||||
responses?: {
|
||||
[key: string]: ReferenceObject | ResponseObject;
|
||||
};
|
||||
parameters?: {
|
||||
[key: string]: ReferenceObject | ParameterObject;
|
||||
};
|
||||
examples?: {
|
||||
[key: string]: ReferenceObject | ExampleObject;
|
||||
};
|
||||
requestBodies?: {
|
||||
[key: string]: ReferenceObject | RequestBodyObject;
|
||||
};
|
||||
headers?: {
|
||||
[key: string]: ReferenceObject | HeaderObject;
|
||||
};
|
||||
securitySchemes?: {
|
||||
[key: string]: ReferenceObject | SecuritySchemeObject;
|
||||
};
|
||||
links?: {
|
||||
[key: string]: ReferenceObject | LinkObject;
|
||||
};
|
||||
callbacks?: {
|
||||
[key: string]: ReferenceObject | CallbackObject;
|
||||
};
|
||||
}
|
||||
type SecuritySchemeObject =
|
||||
| HttpSecurityScheme
|
||||
| ApiKeySecurityScheme
|
||||
| OAuth2SecurityScheme
|
||||
| OpenIdSecurityScheme;
|
||||
interface HttpSecurityScheme {
|
||||
type: 'http';
|
||||
description?: string;
|
||||
scheme: string;
|
||||
bearerFormat?: string;
|
||||
}
|
||||
interface ApiKeySecurityScheme {
|
||||
type: 'apiKey';
|
||||
description?: string;
|
||||
name: string;
|
||||
in: string;
|
||||
}
|
||||
interface OAuth2SecurityScheme {
|
||||
type: 'oauth2';
|
||||
description?: string;
|
||||
flows: {
|
||||
implicit?: {
|
||||
authorizationUrl: string;
|
||||
refreshUrl?: string;
|
||||
scopes: {
|
||||
[scope: string]: string;
|
||||
};
|
||||
};
|
||||
password?: {
|
||||
tokenUrl: string;
|
||||
refreshUrl?: string;
|
||||
scopes: {
|
||||
[scope: string]: string;
|
||||
};
|
||||
};
|
||||
clientCredentials?: {
|
||||
tokenUrl: string;
|
||||
refreshUrl?: string;
|
||||
scopes: {
|
||||
[scope: string]: string;
|
||||
};
|
||||
};
|
||||
authorizationCode?: {
|
||||
authorizationUrl: string;
|
||||
tokenUrl: string;
|
||||
refreshUrl?: string;
|
||||
scopes: {
|
||||
[scope: string]: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
interface OpenIdSecurityScheme {
|
||||
type: 'openIdConnect';
|
||||
description?: string;
|
||||
openIdConnectUrl: string;
|
||||
}
|
||||
interface TagObject {
|
||||
name: string;
|
||||
description?: string;
|
||||
externalDocs?: ExternalDocumentationObject;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
// Basic Auth
|
||||
export interface BasicAuth extends Auth {
|
||||
type: 'http';
|
||||
scheme: 'basic';
|
||||
}
|
||||
|
||||
// Bearer Token
|
||||
export interface BearerAuth extends Auth {
|
||||
type: 'http';
|
||||
scheme: 'bearer';
|
||||
bearerFormat?: string; // arbitrary value for documentation purposes
|
||||
}
|
||||
|
||||
// API Key
|
||||
export interface ApiKeyAuth extends Auth {
|
||||
type: 'apiKey';
|
||||
in: 'header' | 'query' | 'cookie';
|
||||
name: string;
|
||||
}
|
||||
|
||||
// OAuth2
|
||||
export interface OAuth2Auth extends Auth {
|
||||
type: 'oauth2';
|
||||
description: string;
|
||||
flows: Flows[];
|
||||
}
|
||||
|
||||
type Scope = [
|
||||
{
|
||||
scope: string;
|
||||
description?: string;
|
||||
}
|
||||
];
|
||||
|
||||
export type Flows =
|
||||
| OAuth2AuchorizationCodeFlow
|
||||
| OAuth2ImplicitFlow
|
||||
| OAuth2PasswordFlow
|
||||
| OAuth2ClientCredentialsFlow;
|
||||
|
||||
interface OAuth2AuchorizationCodeFlow {
|
||||
name: 'authorizationCode';
|
||||
authorizationUrl: string;
|
||||
tokenUrl: string;
|
||||
scopes: Scope[];
|
||||
}
|
||||
|
||||
interface OAuth2ImplicitFlow {
|
||||
name: 'implicit';
|
||||
authorizationUrl: string;
|
||||
scopes: Scope[];
|
||||
}
|
||||
|
||||
interface OAuth2PasswordFlow {
|
||||
name: 'password';
|
||||
tokenUrl: string;
|
||||
scopes: Scope[];
|
||||
}
|
||||
|
||||
interface OAuth2ClientCredentialsFlow {
|
||||
name: 'clientCredentials';
|
||||
tokenUrl: string;
|
||||
scopes: Scope[];
|
||||
}
|
||||
|
||||
// OpenID Connect
|
||||
export interface OpenIdConnectAuth extends Auth {
|
||||
type: 'openIdConnect';
|
||||
openIdConnectUrl: string;
|
||||
}
|
||||
|
||||
// Cookie Auth
|
||||
export interface CookieAuth extends Auth {
|
||||
type: 'apiKey';
|
||||
in: 'cookie';
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Auth {
|
||||
identifier: string; // a unique name for the auth-configuration
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import type {
|
||||
ApiKeyAuth,
|
||||
BasicAuth,
|
||||
BearerAuth,
|
||||
CookieAuth,
|
||||
OAuth2Auth,
|
||||
OpenIdConnectAuth
|
||||
} from './auth';
|
||||
|
||||
export interface OpenAPI extends Info {
|
||||
servers: Server[];
|
||||
securitySchemas: SecuritySchema[];
|
||||
}
|
||||
|
||||
export interface Info {
|
||||
title: string;
|
||||
version: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface Server {
|
||||
url: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type SecuritySchema =
|
||||
| BasicAuth
|
||||
| BearerAuth
|
||||
| ApiKeyAuth
|
||||
| OAuth2Auth
|
||||
| OpenIdConnectAuth
|
||||
| CookieAuth;
|
||||
@@ -27,11 +27,11 @@
|
||||
</Tab>
|
||||
<svelte:fragment slot="panel">
|
||||
{#if $tabSet === 0}
|
||||
<Info></Info>
|
||||
<Info />
|
||||
{:else if $tabSet === 1}
|
||||
<Authentication />
|
||||
<!-- <Authentication /> -->
|
||||
{:else if $tabSet === 2}
|
||||
<Servers />
|
||||
<!-- <Servers /> -->
|
||||
{:else if $tabSet === 3}
|
||||
<p>Paths</p>
|
||||
{:else if $tabSet === 4}
|
||||
|
||||
Reference in New Issue
Block a user