mirror of
https://github.com/LukeHagar/openapi-definition-generator.git
synced 2025-12-06 04:20:23 +00:00
Initial Commit
This commit is contained in:
13
.eslintignore
Normal file
13
.eslintignore
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
20
.eslintrc.cjs
Normal file
20
.eslintrc.cjs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
||||||
|
plugins: ['svelte3', '@typescript-eslint'],
|
||||||
|
ignorePatterns: ['*.cjs'],
|
||||||
|
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
|
||||||
|
settings: {
|
||||||
|
'svelte3/typescript': () => require('typescript')
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2020
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2017: true,
|
||||||
|
node: true
|
||||||
|
}
|
||||||
|
};
|
||||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
vite.config.js.timestamp-*
|
||||||
|
vite.config.ts.timestamp-*
|
||||||
13
.prettierignore
Normal file
13
.prettierignore
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
9
.prettierrc
Normal file
9
.prettierrc
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"useTabs": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"printWidth": 100,
|
||||||
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
|
"pluginSearchDirs": ["."],
|
||||||
|
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||||
|
}
|
||||||
99
.vscode/settings.json
vendored
Normal file
99
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"prettier.documentSelectors": [
|
||||||
|
"**/*.svelte"
|
||||||
|
],
|
||||||
|
"tailwindCSS.classAttributes": [
|
||||||
|
"class",
|
||||||
|
"accent",
|
||||||
|
"active",
|
||||||
|
"background",
|
||||||
|
"badge",
|
||||||
|
"bgBackdrop",
|
||||||
|
"bgDark",
|
||||||
|
"bgDrawer",
|
||||||
|
"bgLight",
|
||||||
|
"blur",
|
||||||
|
"border",
|
||||||
|
"button",
|
||||||
|
"buttonAction",
|
||||||
|
"buttonBack",
|
||||||
|
"buttonClasses",
|
||||||
|
"buttonComplete",
|
||||||
|
"buttonDismiss",
|
||||||
|
"buttonNeutral",
|
||||||
|
"buttonNext",
|
||||||
|
"buttonPositive",
|
||||||
|
"buttonTextCancel",
|
||||||
|
"buttonTextConfirm",
|
||||||
|
"buttonTextNext",
|
||||||
|
"buttonTextPrevious",
|
||||||
|
"buttonTextSubmit",
|
||||||
|
"caretClosed",
|
||||||
|
"caretOpen",
|
||||||
|
"chips",
|
||||||
|
"color",
|
||||||
|
"cursor",
|
||||||
|
"display",
|
||||||
|
"element",
|
||||||
|
"fill",
|
||||||
|
"fillDark",
|
||||||
|
"fillLight",
|
||||||
|
"flex",
|
||||||
|
"gap",
|
||||||
|
"gridColumns",
|
||||||
|
"height",
|
||||||
|
"hover",
|
||||||
|
"invalid",
|
||||||
|
"justify",
|
||||||
|
"meter",
|
||||||
|
"padding",
|
||||||
|
"position",
|
||||||
|
"regionBackdrop",
|
||||||
|
"regionBody",
|
||||||
|
"regionCaption",
|
||||||
|
"regionCaret",
|
||||||
|
"regionCell",
|
||||||
|
"regionCone",
|
||||||
|
"regionContent",
|
||||||
|
"regionControl",
|
||||||
|
"regionDefault",
|
||||||
|
"regionDrawer",
|
||||||
|
"regionFoot",
|
||||||
|
"regionFooter",
|
||||||
|
"regionHead",
|
||||||
|
"regionHeader",
|
||||||
|
"regionIcon",
|
||||||
|
"regionInterface",
|
||||||
|
"regionInterfaceText",
|
||||||
|
"regionLabel",
|
||||||
|
"regionLead",
|
||||||
|
"regionLegend",
|
||||||
|
"regionList",
|
||||||
|
"regionNavigation",
|
||||||
|
"regionPage",
|
||||||
|
"regionPanel",
|
||||||
|
"regionRowHeadline",
|
||||||
|
"regionRowMain",
|
||||||
|
"regionTrail",
|
||||||
|
"ring",
|
||||||
|
"rounded",
|
||||||
|
"select",
|
||||||
|
"shadow",
|
||||||
|
"slotDefault",
|
||||||
|
"slotFooter",
|
||||||
|
"slotHeader",
|
||||||
|
"slotLead",
|
||||||
|
"slotMessage",
|
||||||
|
"slotMeta",
|
||||||
|
"slotPageContent",
|
||||||
|
"slotPageFooter",
|
||||||
|
"slotPageHeader",
|
||||||
|
"slotSidebarLeft",
|
||||||
|
"slotSidebarRight",
|
||||||
|
"slotTrail",
|
||||||
|
"spacing",
|
||||||
|
"text",
|
||||||
|
"track",
|
||||||
|
"width"
|
||||||
|
]
|
||||||
|
}
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Luke Hagar
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
2
README.md
Normal file
2
README.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# openapi-definition-generator
|
||||||
|
JSON to OpenAPI Definition generator
|
||||||
39
package.json
Normal file
39
package.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"name": "swagger-definition-generator",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite dev",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||||
|
"format": "prettier --plugin-search-dir . --write ."
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@skeletonlabs/skeleton": "^1.2.5",
|
||||||
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
|
"@sveltejs/kit": "^1.5.0",
|
||||||
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
|
"autoprefixer": "^10.4.14",
|
||||||
|
"eslint": "^8.28.0",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-plugin-svelte3": "^4.0.0",
|
||||||
|
"json-to-pretty-yaml": "^1.2.2",
|
||||||
|
"postcss": "^8.4.23",
|
||||||
|
"prettier": "^2.8.0",
|
||||||
|
"prettier-plugin-svelte": "^2.8.1",
|
||||||
|
"svelte": "^3.54.0",
|
||||||
|
"svelte-check": "^3.0.1",
|
||||||
|
"tailwindcss": "^3.3.2",
|
||||||
|
"tslib": "^2.4.1",
|
||||||
|
"typescript": "^5.0.0",
|
||||||
|
"vite": "^4.2.0",
|
||||||
|
"yaml": "^2.2.2"
|
||||||
|
},
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
6
postcss.config.cjs
Normal file
6
postcss.config.cjs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
9
src/app.d.ts
vendored
Normal file
9
src/app.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
|
// for information about these interfaces
|
||||||
|
// and what to do when importing types
|
||||||
|
declare namespace App {
|
||||||
|
// interface Locals {}
|
||||||
|
// interface PageData {}
|
||||||
|
// interface Error {}
|
||||||
|
// interface Platform {}
|
||||||
|
}
|
||||||
12
src/app.html
Normal file
12
src/app.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="dark">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
<body data-sveltekit-preload-data="hover" data-theme="skeleton">
|
||||||
|
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
src/app.postcss
Normal file
2
src/app.postcss
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/*place global styles here */
|
||||||
|
html, body { @apply h-full overflow-hidden; }
|
||||||
49
src/routes/+layout.svelte
Normal file
49
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// The ordering of these imports is critical to your app working properly
|
||||||
|
import '@skeletonlabs/skeleton/themes/theme-skeleton.css';
|
||||||
|
// If you have source.organizeImports set to true in VSCode, then it will auto change this ordering
|
||||||
|
import '@skeletonlabs/skeleton/styles/all.css';
|
||||||
|
// Most of your app wide CSS should be put in this file
|
||||||
|
import '../app.postcss';
|
||||||
|
import { AppShell, AppBar } from '@skeletonlabs/skeleton';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- App Shell -->
|
||||||
|
<AppShell>
|
||||||
|
<svelte:fragment slot="header">
|
||||||
|
<!-- App Bar -->
|
||||||
|
<AppBar>
|
||||||
|
<svelte:fragment slot="lead">
|
||||||
|
<strong class="text-xl">Swagger Definition Objects Generator</strong>
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="trail">
|
||||||
|
<a
|
||||||
|
class="btn btn-sm variant-ghost-surface"
|
||||||
|
href="https://discord.gg/EXqV7W8MtY"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Discord
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="btn btn-sm variant-ghost-surface"
|
||||||
|
href="https://twitter.com/SkeletonUI"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Twitter
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="btn btn-sm variant-ghost-surface"
|
||||||
|
href="https://github.com/skeletonlabs/skeleton"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</svelte:fragment>
|
||||||
|
</AppBar>
|
||||||
|
</svelte:fragment>
|
||||||
|
<!-- Page Route Content -->
|
||||||
|
<slot />
|
||||||
|
</AppShell>
|
||||||
356
src/routes/+page.svelte
Normal file
356
src/routes/+page.svelte
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
import { stringify } from 'yaml';
|
||||||
|
let inJSON: any;
|
||||||
|
let inputJSON = '';
|
||||||
|
let outSwagger = '';
|
||||||
|
|
||||||
|
let requestExamples: boolean;
|
||||||
|
let noInt: boolean;
|
||||||
|
let yamlOut: boolean;
|
||||||
|
let tabCount: number;
|
||||||
|
let indentator: string;
|
||||||
|
let nullType: string;
|
||||||
|
let parseErr: Error | null;
|
||||||
|
let timeOut: any;
|
||||||
|
|
||||||
|
const trigger = (evt: Event) => {
|
||||||
|
clearTimeout(timeOut);
|
||||||
|
timeOut = setTimeout(() => convert(), 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
const convert = () => {
|
||||||
|
localStorage.setItem('inputJSON', inputJSON);
|
||||||
|
try {
|
||||||
|
inJSON = JSON.parse(inputJSON);
|
||||||
|
parseErr = null;
|
||||||
|
} catch (e: any) {
|
||||||
|
parseErr = e;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//For recursive functions to keep track of the tab spacing
|
||||||
|
tabCount = 0;
|
||||||
|
indentator = '\n';
|
||||||
|
// ---- Begin definitions ----
|
||||||
|
outSwagger = '{';
|
||||||
|
changeIndentation(1);
|
||||||
|
//For each object inside the JSON
|
||||||
|
for (let obj in inJSON) {
|
||||||
|
// ---- Begin schema scope ----
|
||||||
|
outSwagger += indentator + '"' + obj + '": {';
|
||||||
|
conversorSelection(inJSON[obj]);
|
||||||
|
outSwagger += indentator + '},';
|
||||||
|
// ---- End schema scope ----
|
||||||
|
}
|
||||||
|
//Remove last comma
|
||||||
|
outSwagger = outSwagger.substring(0, outSwagger.length - 1);
|
||||||
|
// ---- End definitions ----
|
||||||
|
changeIndentation(tabCount - 1);
|
||||||
|
outSwagger += indentator + '}';
|
||||||
|
|
||||||
|
outSwagger = format(outSwagger);
|
||||||
|
};
|
||||||
|
|
||||||
|
function changeIndentation(count: number) {
|
||||||
|
/*
|
||||||
|
Assign 'indentator' a string beginning with newline and followed by 'count' tabs
|
||||||
|
Updates variable 'tabCount' with the number of tabs used
|
||||||
|
Global variables updated:
|
||||||
|
-indentator
|
||||||
|
-tabCount
|
||||||
|
*/
|
||||||
|
|
||||||
|
let i;
|
||||||
|
if (count >= tabCount) {
|
||||||
|
i = tabCount;
|
||||||
|
} else {
|
||||||
|
i = 0;
|
||||||
|
indentator = '\n';
|
||||||
|
}
|
||||||
|
for (; i < count; i++) {
|
||||||
|
indentator += '\t';
|
||||||
|
}
|
||||||
|
//Update tabCount
|
||||||
|
tabCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function conversorSelection(obj: any) {
|
||||||
|
/*
|
||||||
|
Selects which conversion method to call based on given obj
|
||||||
|
Global variables updated:
|
||||||
|
-outSwagger
|
||||||
|
*/
|
||||||
|
|
||||||
|
changeIndentation(tabCount + 1);
|
||||||
|
if (typeof obj === 'number') {
|
||||||
|
//attribute is a number
|
||||||
|
convertNumber(obj);
|
||||||
|
} else if (Object.prototype.toString.call(obj) === '[object Array]') {
|
||||||
|
//attribute is an array
|
||||||
|
convertArray(obj);
|
||||||
|
} else if (typeof obj === 'object') {
|
||||||
|
//attribute is an object
|
||||||
|
convertObject(obj);
|
||||||
|
} else if (typeof obj === 'string') {
|
||||||
|
//attribute is a string
|
||||||
|
convertString(obj);
|
||||||
|
} else if (typeof obj === 'boolean') {
|
||||||
|
// attribute is a boolean
|
||||||
|
outSwagger += indentator + '"type": "boolean"';
|
||||||
|
} else {
|
||||||
|
// not a valid Swagger type
|
||||||
|
alert('Property type "' + typeof obj + '" not valid for Swagger definitions');
|
||||||
|
}
|
||||||
|
changeIndentation(tabCount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertNumber(num: number) {
|
||||||
|
/*
|
||||||
|
Append to 'outSwagger' string with Swagger schema attributes relative to given number
|
||||||
|
Global variables updated:
|
||||||
|
-outSwagger
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (num % 1 === 0 && !noInt) {
|
||||||
|
outSwagger += indentator + '"type": "integer",';
|
||||||
|
if (num < 2147483647 && num > -2147483647) {
|
||||||
|
outSwagger += indentator + '"format": "int32"';
|
||||||
|
} else if (Number.isSafeInteger(num)) {
|
||||||
|
outSwagger += indentator + '"format": "int64"';
|
||||||
|
} else {
|
||||||
|
outSwagger += indentator + '"format": "unsafe"';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
outSwagger += indentator + '"type": "number"';
|
||||||
|
}
|
||||||
|
if (requestExamples) {
|
||||||
|
//Log example if checkbox is checked
|
||||||
|
outSwagger += ',' + indentator + '"example": "' + num + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//date is ISO8601 format - https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14
|
||||||
|
function convertString(str: string) {
|
||||||
|
/*
|
||||||
|
Append to 'outSwagger' string with Swagger schema attributes relative to given string
|
||||||
|
Global variables updated:
|
||||||
|
-outSwagger
|
||||||
|
*/
|
||||||
|
|
||||||
|
let regxDate = /^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/,
|
||||||
|
regxDateTime =
|
||||||
|
/^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]).([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]{1,3})?(Z|(\+|\-)([0-1][0-9]|2[0-3]):[0-5][0-9])$/;
|
||||||
|
|
||||||
|
outSwagger += indentator + '"type": "string"';
|
||||||
|
if (regxDateTime.test(str)) {
|
||||||
|
outSwagger += ',';
|
||||||
|
outSwagger += indentator + '"format": "date-time"';
|
||||||
|
} else if (regxDate.test(str)) {
|
||||||
|
outSwagger += ',';
|
||||||
|
outSwagger += indentator + '"format": "date"';
|
||||||
|
}
|
||||||
|
if (requestExamples) {
|
||||||
|
//Log example if checkbox is checked
|
||||||
|
outSwagger += ',' + indentator + '"example": "' + str + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertArray(obj: any[]) {
|
||||||
|
/*
|
||||||
|
Append to 'outSwagger' string with Swagger schema attributes relative to given array
|
||||||
|
Global variables updated:
|
||||||
|
-outSwagger
|
||||||
|
*/
|
||||||
|
let schema: any = {};
|
||||||
|
let examples = new Set();
|
||||||
|
for (const entry of obj) {
|
||||||
|
for (const key of Object.keys(entry)) {
|
||||||
|
if (!Object.keys(schema).includes(key)) {
|
||||||
|
examples.add(entry);
|
||||||
|
schema[key] = entry[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outSwagger += indentator + '"type": "array",';
|
||||||
|
// ---- Begin items scope ----
|
||||||
|
outSwagger += indentator + '"items": {';
|
||||||
|
conversorSelection(schema);
|
||||||
|
outSwagger += indentator + '}';
|
||||||
|
// ---- End items scope ----
|
||||||
|
// ---- Begin example scope ----
|
||||||
|
if (requestExamples) {
|
||||||
|
outSwagger += ',' + indentator + '"example": ' + JSON.stringify([...examples], null, '\t');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertObject(obj: any) {
|
||||||
|
/*
|
||||||
|
Append to 'outSwagger' string with Swagger schema attributes relative to given object
|
||||||
|
Global variables updated:
|
||||||
|
-outSwagger
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Convert null attributes to given type
|
||||||
|
if (obj === null) {
|
||||||
|
outSwagger += indentator + '"type": "' + nullType + '",';
|
||||||
|
outSwagger += indentator + '"format": "nullable"';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ---- Begin properties scope ----
|
||||||
|
outSwagger += indentator + '"type": "object",';
|
||||||
|
outSwagger += indentator + '"properties": {';
|
||||||
|
changeIndentation(tabCount + 1);
|
||||||
|
//For each attribute inside that object
|
||||||
|
for (var prop in obj) {
|
||||||
|
// ---- Begin property type scope ----
|
||||||
|
outSwagger += indentator + '"' + prop + '": {';
|
||||||
|
conversorSelection(obj[prop]);
|
||||||
|
outSwagger += indentator + '},';
|
||||||
|
// ---- End property type scope ----
|
||||||
|
}
|
||||||
|
|
||||||
|
changeIndentation(tabCount - 1);
|
||||||
|
if (Object.keys(obj).length > 0) {
|
||||||
|
//At least 1 property inserted
|
||||||
|
outSwagger = outSwagger.substring(0, outSwagger.length - 1); //Remove last comma
|
||||||
|
outSwagger += indentator + '}';
|
||||||
|
} else {
|
||||||
|
// No property inserted
|
||||||
|
outSwagger += ' }';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function format(value: string) {
|
||||||
|
/*
|
||||||
|
Convert JSON to YAML if yaml checkbox is checked
|
||||||
|
Global variables updated:
|
||||||
|
NONE
|
||||||
|
*/
|
||||||
|
|
||||||
|
value = JSON.stringify(JSON.parse(value), null, '\t');
|
||||||
|
|
||||||
|
if (yamlOut) {
|
||||||
|
return stringify(JSON.parse(value));
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
let tempJSON = localStorage.getItem('inputJSON');
|
||||||
|
if (tempJSON !== null && tempJSON !== '') {
|
||||||
|
inputJSON = tempJSON;
|
||||||
|
} else {
|
||||||
|
inputJSON = `{
|
||||||
|
"numbersMock": {
|
||||||
|
"smallInt": -20,
|
||||||
|
"bigInt": 2147483647,
|
||||||
|
"unsafeInt": 9999999999999999,
|
||||||
|
"notInt": 12.2
|
||||||
|
},
|
||||||
|
"stringsMock": {
|
||||||
|
"stringTest": "Hello World",
|
||||||
|
"isoDate": "1999-12-31",
|
||||||
|
"isoDateTime": "1999-12-31T23:59:59Z"
|
||||||
|
},
|
||||||
|
"objectsMock": {
|
||||||
|
"child": {"child": true},
|
||||||
|
"childList": [{"child": true}],
|
||||||
|
"childMatrix": [[{"child": true}]],
|
||||||
|
"nullable": null
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
convert();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Swagger Generator</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<p class="text-center p-8 relative">
|
||||||
|
Add your JSON mock to generate Swagger definitions.
|
||||||
|
{#if parseErr && inputJSON != ''}
|
||||||
|
<aside class="alert variant-filled-warning absolute m-4 center inset-0">
|
||||||
|
<h3>Error in JSON</h3>
|
||||||
|
<p>{parseErr}</p>
|
||||||
|
</aside>
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-row justify-between p-2 gap-2">
|
||||||
|
<textarea
|
||||||
|
id="JSON"
|
||||||
|
rows="35"
|
||||||
|
cols="85"
|
||||||
|
class="grow textarea"
|
||||||
|
placeholder="Type your JSON"
|
||||||
|
contenteditable
|
||||||
|
on:input={trigger}
|
||||||
|
on:paste
|
||||||
|
bind:value={inputJSON}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
readonly
|
||||||
|
id="Swagger"
|
||||||
|
rows="35"
|
||||||
|
cols="85"
|
||||||
|
class="grow textarea"
|
||||||
|
placeholder="Here is your Swagger"
|
||||||
|
bind:value={outSwagger}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row justify-center px-4 gap-24">
|
||||||
|
<label class="label">
|
||||||
|
Convert null values to:
|
||||||
|
<select bind:value={nullType} on:change={() => convert()} class="select" id="nullType">
|
||||||
|
<option value="string" selected>String</option>
|
||||||
|
<option value="number">Number</option>
|
||||||
|
<option value="integer">Integer</option>
|
||||||
|
<option value="boolean">Boolean</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Add values as examples:
|
||||||
|
<input
|
||||||
|
bind:checked={requestExamples}
|
||||||
|
on:change={() => convert()}
|
||||||
|
class="checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
id="requestExamples"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Convert integer values to number:
|
||||||
|
<input
|
||||||
|
bind:checked={noInt}
|
||||||
|
on:change={() => convert()}
|
||||||
|
class="checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
id="noInt"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Output as YAML:
|
||||||
|
<input
|
||||||
|
bind:checked={yamlOut}
|
||||||
|
on:change={() => convert()}
|
||||||
|
class="checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
id="yamlOut"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-center pt-4">
|
||||||
|
Feel like collaborating? Clone the repository at <a
|
||||||
|
target="_blank"
|
||||||
|
href="https://github.com/Roger13/SwaggerGenerator">GitHub</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
BIN
static/favicon.png
Normal file
BIN
static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
18
svelte.config.js
Normal file
18
svelte.config.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import adapter from '@sveltejs/adapter-auto';
|
||||||
|
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
|
const config = {
|
||||||
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
|
// for more information about preprocessors
|
||||||
|
preprocess: vitePreprocess(),
|
||||||
|
|
||||||
|
kit: {
|
||||||
|
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||||
|
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||||
|
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||||
|
adapter: adapter()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
16
tailwind.config.cjs
Normal file
16
tailwind.config.cjs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
darkMode: 'class',
|
||||||
|
content: [
|
||||||
|
'./src/**/*.{html,js,svelte,ts}',
|
||||||
|
require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
require('@tailwindcss/forms'),
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
|
...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
|
||||||
|
]
|
||||||
|
};
|
||||||
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "./.svelte-kit/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||||
|
//
|
||||||
|
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||||
|
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||||
|
}
|
||||||
6
vite.config.ts
Normal file
6
vite.config.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [sveltekit()]
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user