Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/thedevs-network/kutt.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorPouria Ezzati <ezzati.upt@gmail.com>2020-02-15 21:02:10 +0300
committerGitHub <noreply@github.com>2020-02-15 21:02:10 +0300
commit2c261ad4afd04d5c8e718decfec921027cb8e0a9 (patch)
tree82a0ccc51071426d31393b7146e8eff6aac26876 /docs
parentb5f210b68d2f3e28047fb2fecfbdb394b5bd3a47 (diff)
API doc generation! (#280)
Co-authored-by: trgwii <trgwii@hotmail.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/api/api.ts529
-rw-r--r--docs/api/generate.ts48
2 files changed, 577 insertions, 0 deletions
diff --git a/docs/api/api.ts b/docs/api/api.ts
new file mode 100644
index 0000000..bffe068
--- /dev/null
+++ b/docs/api/api.ts
@@ -0,0 +1,529 @@
+import * as p from '../../package.json';
+
+export default {
+ openapi: '3.0.0',
+ info: {
+ title: "Kutt.it",
+ description: "API referrence for [http://kutt.it](http://kutt.it).\n",
+ version: p.version
+ },
+ servers: [{
+ url: "https://kutt.it/api/v2"
+ }],
+ tags: [{
+ name: "health"
+ }, {
+ name: "links"
+ }, {
+ name: "domains"
+ }, {
+ name: "users"
+ }],
+ paths: {
+ '/health': {
+ get: {
+ tags: ["health"],
+ summary: "API health",
+ responses: {
+ 200: {
+ description: "Health",
+ content: {
+ 'text/html': {
+ example: "OK"
+ }
+ }
+ }
+ }
+ }
+ },
+ '/links': {
+ get: {
+ tags: ["links"],
+ description: "Get list of links",
+ parameters: [{
+ name: "limit",
+ in: "query",
+ description: "Limit",
+ required: false,
+ style: "form",
+ explode: true,
+ schema: {
+ type: "number",
+ example: 10
+ }
+ }, {
+ name: "skip",
+ in: "query",
+ description: "Skip",
+ required: false,
+ style: "form",
+ explode: true,
+ schema: {
+ type: "number",
+ example: 0
+ }
+ }, {
+ name: "all",
+ in: "query",
+ description: "All links (ADMIN only)",
+ required: false,
+ style: "form",
+ explode: true,
+ schema: {
+ type: "boolean",
+ example: false
+ }
+ }],
+ responses: {
+ 200: {
+ description: "List of links",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/inline_response_200"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ },
+ post: {
+ tags: ["links"],
+ description: "Create a short link",
+ requestBody: {
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/body"
+ }
+ }
+ }
+ },
+ responses: {
+ 200: {
+ description: "Craeted link",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/Link"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ }
+ },
+ '/links/{id}': {
+ delete: {
+ tags: ["links"],
+ description: "Delete a link",
+ parameters: [{
+ name: "id",
+ in: "path",
+ required: true,
+ style: "simple",
+ explode: false,
+ schema: {
+ type: "string",
+ format: "uuid"
+ }
+ }],
+ responses: {
+ 200: {
+ description: "Deleted link successfully",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/inline_response_200_1"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ }
+ },
+ '/links/{id}/stats': {
+ get: {
+ tags: ["links"],
+ description: "Get link stats",
+ parameters: [{
+ name: "id",
+ in: "path",
+ required: true,
+ style: "simple",
+ explode: false,
+ schema: {
+ type: "string",
+ format: "uuid"
+ }
+ }],
+ responses: {
+ 200: {
+ description: "Link stats",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/Stats"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ }
+ },
+ '/domains': {
+ post: {
+ tags: ["domains"],
+ description: "Create a domain",
+ requestBody: {
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/body_1"
+ }
+ }
+ }
+ },
+ responses: {
+ 200: {
+ description: "Created domain",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/Domain"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ }
+ },
+ '/domains/{id}': {
+ delete: {
+ tags: ["domains"],
+ description: "Delete a domain",
+ parameters: [{
+ name: "id",
+ in: "path",
+ required: true,
+ style: "simple",
+ explode: false,
+ schema: {
+ type: "string",
+ format: "uuid"
+ }
+ }],
+ responses: {
+ 200: {
+ description: "Deleted domain successfully",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/inline_response_200_1"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ }
+ },
+ '/users': {
+ get: {
+ tags: ["users"],
+ description: "Get user info",
+ responses: {
+ 200: {
+ description: "User info",
+ content: {
+ 'application/json': {
+ schema: {
+ $ref: "#/components/schemas/User"
+ }
+ }
+ }
+ }
+ },
+ security: [{
+ APIKeyAuth: []
+ }]
+ }
+ }
+ },
+ components: {
+ schemas: {
+ Link: {
+ type: "object",
+ properties: {
+ address: {
+ type: "string"
+ },
+ banned: {
+ type: "boolean",
+ default: false
+ },
+ created_at: {
+ type: "string",
+ format: "date-time"
+ },
+ id: {
+ type: "string",
+ format: "uuid"
+ },
+ link: {
+ type: "string"
+ },
+ password: {
+ type: "boolean",
+ default: false
+ },
+ target: {
+ type: "string"
+ },
+ updated_at: {
+ type: "string",
+ format: "date-time"
+ },
+ visit_count: {
+ type: "number"
+ }
+ }
+ },
+ Domain: {
+ type: "object",
+ properties: {
+ address: {
+ type: "string"
+ },
+ banned: {
+ type: "boolean",
+ default: false
+ },
+ created_at: {
+ type: "string",
+ format: "date-time"
+ },
+ id: {
+ type: "string",
+ format: "uuid"
+ },
+ homepage: {
+ type: "string"
+ },
+ updated_at: {
+ type: "string",
+ format: "date-time"
+ }
+ }
+ },
+ User: {
+ type: "object",
+ properties: {
+ apikey: {
+ type: "string"
+ },
+ email: {
+ type: "string"
+ },
+ domains: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/Domain"
+ }
+ }
+ }
+ },
+ StatsItem: {
+ type: "object",
+ properties: {
+ stats: {
+ $ref: "#/components/schemas/StatsItem_stats"
+ },
+ views: {
+ type: "array",
+ items: {
+ type: "number"
+ }
+ }
+ }
+ },
+ Stats: {
+ type: "object",
+ properties: {
+ allTime: {
+ $ref: "#/components/schemas/StatsItem"
+ },
+ lastDay: {
+ $ref: "#/components/schemas/StatsItem"
+ },
+ lastMonth: {
+ $ref: "#/components/schemas/StatsItem"
+ },
+ lastWeek: {
+ $ref: "#/components/schemas/StatsItem"
+ },
+ updatedAt: {
+ type: "string"
+ },
+ address: {
+ type: "string"
+ },
+ banned: {
+ type: "boolean",
+ default: false
+ },
+ created_at: {
+ type: "string",
+ format: "date-time"
+ },
+ id: {
+ type: "string",
+ format: "uuid"
+ },
+ link: {
+ type: "string"
+ },
+ password: {
+ type: "boolean",
+ default: false
+ },
+ target: {
+ type: "string"
+ },
+ updated_at: {
+ type: "string",
+ format: "date-time"
+ },
+ visit_count: {
+ type: "number"
+ }
+ }
+ },
+ inline_response_200: {
+ properties: {
+ limit: {
+ type: "number",
+ default: 10
+ },
+ skip: {
+ type: "number",
+ default: 0
+ },
+ total: {
+ type: "number",
+ default: 0
+ },
+ data: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/Link"
+ }
+ }
+ }
+ },
+ body: {
+ required: ["target"],
+ properties: {
+ target: {
+ type: "string"
+ },
+ password: {
+ type: "string"
+ },
+ customurl: {
+ type: "string"
+ },
+ reuse: {
+ type: "boolean",
+ default: false
+ },
+ domain: {
+ type: "string"
+ }
+ }
+ },
+ inline_response_200_1: {
+ properties: {
+ message: {
+ type: "string"
+ }
+ }
+ },
+ body_1: {
+ required: ["address"],
+ properties: {
+ address: {
+ type: "string"
+ },
+ homepage: {
+ type: "string"
+ }
+ }
+ },
+ StatsItem_stats_browser: {
+ type: "object",
+ properties: {
+ name: {
+ type: "string"
+ },
+ value: {
+ type: "number"
+ }
+ }
+ },
+ StatsItem_stats: {
+ type: "object",
+ properties: {
+ browser: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/StatsItem_stats_browser"
+ }
+ },
+ os: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/StatsItem_stats_browser"
+ }
+ },
+ country: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/StatsItem_stats_browser"
+ }
+ },
+ referrer: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/StatsItem_stats_browser"
+ }
+ }
+ }
+ }
+ },
+ securitySchemes: {
+ APIKeyAuth: {
+ type: "apiKey",
+ name: "X-API-KEY",
+ in: "header"
+ }
+ }
+ }
+};
diff --git a/docs/api/generate.ts b/docs/api/generate.ts
new file mode 100644
index 0000000..7c4b2f5
--- /dev/null
+++ b/docs/api/generate.ts
@@ -0,0 +1,48 @@
+import { join, dirname } from 'path';
+
+import { promises as fs } from 'fs';
+
+import api from './api';
+
+const Template = (output, { api, title, redoc }) =>
+ fs.writeFile(output,
+`<DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="X-UA-Compatible" content="ie=edge" />
+ <title>${title}</title>
+ </head>
+ <body>
+ <redoc spec-url="${api}" />
+ <script src="${redoc}"></script>
+ </body>
+</html>
+`);
+
+const Api = output =>
+ fs.writeFile(output, JSON.stringify(api));
+
+const Redoc = output =>
+ fs.copyFile(join(
+ dirname(require.resolve('redoc')),
+ 'redoc.standalone.js'),
+ output);
+
+export default (async () => {
+ const out = join(__dirname, 'static');
+ const apiFile = 'api.json';
+ const redocFile = 'redoc.js';
+ await fs.mkdir(out, { recursive: true });
+ return Promise.all([
+ Api(join(out, apiFile)),
+ Redoc(join(out, redocFile)),
+ Template(join(out, 'index.html'), {
+ api: apiFile,
+ title: api.info.title,
+ redoc: redocFile
+ }),
+
+ ]);
+})();