From 0744c1adc8e0c01a7c781405ba5b6fefaa0bbcd1 Mon Sep 17 00:00:00 2001 From: Preston Lim Date: Thu, 17 Oct 2019 16:20:06 +0800 Subject: [PATCH] Add docs + Standardize request body and response in routes (#5) * change redirect URL to frontend instead of backend * add openapi docs + standardize request-body/response --- classes/File.js | 8 +- docs/openapi.yaml | 885 ++++++++++++++++++++++++++++++++++++++ routes/collectionPages.js | 14 +- routes/documents.js | 18 +- routes/images.js | 14 +- routes/pages.js | 14 +- 6 files changed, 921 insertions(+), 32 deletions(-) create mode 100644 docs/openapi.yaml diff --git a/classes/File.js b/classes/File.js index 87e9375b1..954f1c322 100644 --- a/classes/File.js +++ b/classes/File.js @@ -62,12 +62,14 @@ class File { "branch": "staging", } - await axios.put(endpoint, params, { + const resp = await axios.put(endpoint, params, { headers: { Authorization: `token ${this.accessToken}`, "Content-Type": "application/json" } }) + + return { sha: resp.content.sha } } catch (err) { throw err } @@ -106,12 +108,14 @@ class File { "sha": sha } - await axios.put(endpoint, params, { + const resp = await axios.put(endpoint, params, { headers: { Authorization: `token ${this.accessToken}`, "Content-Type": "application/json" } }) + + return { newSha: resp.commit.sha } } catch (err) { throw err } diff --git a/docs/openapi.yaml b/docs/openapi.yaml new file mode 100644 index 000000000..3976ead9d --- /dev/null +++ b/docs/openapi.yaml @@ -0,0 +1,885 @@ +openapi: 3.0.0 +info: + version: "0.0.1" + title: IsomerCMS API + description: | + # API documentation for IsomerCMS +servers: + - url: "https://cms-api.isomerpages.com" + description: "Production API Server" + - url: "https://staging-cms-api.isomerpages.com" + description: "Staging API Server" +tags: + - name: Authentication + - name: Collections + - name: Collection Pages + - name: Images + - name: Documents + - name: Pages + - name: Sites +components: + securitySchemes: + ApiKeyAuthentication: + type: apiKey + in: header + name: x-vault-api-key + schemas: + OAuthParams: + properties: + client_id: + type: string + state: + type: string + request_uri: + type: string + CollectionListResponse: + properties: + collections: + type: array + items: + type: string + CollectionPageListResponse: + properties: + collectionPages: + type: array + items: + type: string + PageListResponse: + properties: + pages: + type: array + items: + type: string + DocumentListResponse: + properties: + documents: + type: array + items: + type: string + ImageListResponse: + properties: + documents: + type: array + items: + type: string + CollectionNameResponse: + properties: + collectionName: + type: string + CollectionPageResponse: + properties: + collectionName: + type: string + pageName: + type: string + content: + type: string + sha: + type: string + PageResponse: + properties: + pageName: + type: string + content: + type: string + sha: + type: string + DocumentResponse: + properties: + documentName: + type: string + content: + type: string + sha: + type: string + ImageResponse: + properties: + imageName: + type: string + content: + type: string + sha: + type: string + ShaAndContent: + properties: + sha: + type: string + content: + type: string + ContentAndPageName: + properties: + pageName: + type: string + content: + type: string + ContentAndDocumentName: + properties: + documentName: + type: string + content: + type: string + ContentAndImageName: + properties: + imageName: + type: string + content: + type: string + RenameCollection: + properties: + collectionName: + type: string + newCollectionName: + type: string + RenamePage: + properties: + pageName: + type: string + newPageName: + type: string + RenameDocument: + properties: + documentName: + type: string + newDocumentName: + type: string + RenameImage: + properties: + imageName: + type: string + newDocumentName: + type: string + + +paths: + /: + get: + tags: + - Authentication + description: Obtain parameters for the GitHub OAuth link + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/OAuthParams" + /sites/{siteName}/collections: + get: + tags: + - Collections + parameters: + - name: siteName + in: path + required: true + schema: + type: string + description: List collections + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionListResponse" + post: + tags: + - Collections + description: Create new collection + parameters: + - name: siteName + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionNameResponse" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionNameResponse" + /sites/{siteName}/collections/{collectionName}: + get: + tags: + - Collection Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + description: List collection pages + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionPageListResponse" + delete: + tags: + - Collections + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + description: Delete collection + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionNameResponse" + /sites/{siteName}/collections/{collectionName}/rename/{newCollectionName}: + post: + tags: + - Collections + description: Rename collection + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + - name: newCollectionName + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RenameCollection" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/RenameCollection" + /sites/{siteName}/collections/{collectionName}/pages: + post: + tags: + - Collection Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + description: Create new collection page + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ContentAndPageName" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionListResponse" + /sites/{siteName}/collections/{collectionName}/pages/{pageName}: + get: + tags: + - Collection Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + description: Read collection page + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionPageResponse" + post: + tags: + - Collection Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + description: Update collection page + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ShaAndContent" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionPageResponse" + delete: + tags: + - Collection Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + - name: sha + in: body + required: true + schema: + type: string + description: Delete collection page + responses: + 200: + description: Success + /sites/{siteName}/collections/{collectionName}/pages/{pageName}/rename/{newPageName}: + post: + tags: + - Collection Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: collectionName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + - name: newPageName + in: path + required: true + schema: + type: string + description: Rename collection page + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ShaAndContent" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/CollectionPageResponse" + + /sites/{siteName}/pages: + get: + tags: + - Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + description: List pages + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/PageListResponse" + post: + tags: + - Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + description: Create page + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ContentAndPageName" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/PageResponse" + /sites/{siteName}/pages/{pageName}: + get: + tags: + - Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + description: Read page + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/PageResponse" + post: + tags: + - Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + description: Update page + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ShaAndContent" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/PageResponse" + delete: + tags: + - Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + - name: sha + in: body + required: true + schema: + type: string + description: Delete page + responses: + 200: + description: Success + /sites/{siteName}/pages/{pageName}/rename/{newPageName}: + post: + tags: + - Pages + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: pageName + in: path + required: true + schema: + type: string + - name: newPageName + in: path + required: true + schema: + type: string + description: Rename page + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RenamePage" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/PageResponse" + + /sites/{siteName}/documents: + get: + tags: + - Documents + parameters: + - name: siteName + in: path + required: true + schema: + type: string + description: List documents + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentListResponse" + post: + tags: + - Documents + parameters: + - name: siteName + in: path + required: true + schema: + type: string + description: Create document + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ContentAndDocumentName" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentResponse" + /sites/{siteName}/documents/{documentName}: + get: + tags: + - Documents + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: documentName + in: path + required: true + schema: + type: string + description: Read document + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentResponse" + post: + tags: + - Documents + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: documentName + in: path + required: true + schema: + type: string + description: Update document + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ShaAndContent" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentResponse" + delete: + tags: + - Documents + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: documentName + in: path + required: true + schema: + type: string + - name: sha + in: body + required: true + schema: + type: string + description: Delete document + responses: + 200: + description: Success + /sites/{siteName}/documents/{documentName}/rename/{newDocumentName}: + post: + tags: + - Documents + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: documentName + in: path + required: true + schema: + type: string + - name: newDocumentName + in: path + required: true + schema: + type: string + description: Rename document + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RenameDocument" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentResponse" + + /sites/{siteName}/images: + get: + tags: + - Images + parameters: + - name: siteName + in: path + required: true + schema: + type: string + description: List images + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/ImageListResponse" + post: + tags: + - Images + parameters: + - name: siteName + in: path + required: true + schema: + type: string + description: Create image + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ContentAndImageName" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/ImageResponse" + /sites/{siteName}/images/{imageName}: + get: + tags: + - Images + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: imageName + in: path + required: true + schema: + type: string + description: Read image + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/ImageResponse" + post: + tags: + - Images + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: imageName + in: path + required: true + schema: + type: string + description: Update image + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ShaAndContent" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/ImageResponse" + delete: + tags: + - Images + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: imageName + in: path + required: true + schema: + type: string + - name: sha + in: body + required: true + schema: + type: string + description: Delete image + responses: + 200: + description: Success + /sites/{siteName}/images/{imageName}/rename/{newImageName}: + post: + tags: + - Images + parameters: + - name: siteName + in: path + required: true + schema: + type: string + - name: imageName + in: path + required: true + schema: + type: string + - name: newImageName + in: path + required: true + schema: + type: string + description: Rename image + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RenameImage" + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/ImageResponse" +security: + - ApiKeyAuthentication: [] \ No newline at end of file diff --git a/routes/collectionPages.js b/routes/collectionPages.js index b81d307b9..0454111c5 100644 --- a/routes/collectionPages.js +++ b/routes/collectionPages.js @@ -42,9 +42,9 @@ router.post('/:siteName/collections/:collectionName/pages', async function(req, const GitHubFile = new File(access_token, siteName) const collectionPageType = new CollectionPageType(collectionName) GitHubFile.setFileType(collectionPageType) - await GitHubFile.create(pageName, content) + const { sha } = await GitHubFile.create(pageName, content) - res.status(200).json({ collectionName, pageName, content }) + res.status(200).json({ collectionName, pageName, content, sha }) } catch (err) { console.log(err) } @@ -87,9 +87,9 @@ router.post('/:siteName/collections/:collectionName/pages/:pageName', async func const GitHubFile = new File(access_token, siteName) const collectionPageType = new CollectionPageType(collectionName) GitHubFile.setFileType(collectionPageType) - await GitHubFile.update(pageName, content, sha) + const { newSha } = await GitHubFile.update(pageName, content, sha) - res.status(200).json({ pageName, content }) + res.status(200).json({ collectionName, pageName, content, sha: newSha }) } catch (err) { console.log(err) } @@ -113,7 +113,7 @@ router.delete('/:siteName/collections/:collectionName/pages/:pageName', async fu GitHubFile.setFileType(collectionPageType) await GitHubFile.delete(pageName, sha) - res.status(200).json({ collectionName, pageName, content }) + res.status(200).send('OK') } catch (err) { console.log(err) } @@ -137,10 +137,10 @@ router.post('/:siteName/collections/:collectionName/pages/:pageName/rename/:newP const GitHubFile = new File(access_token, siteName) const collectionPageType = new CollectionPageType(collectionName) GitHubFile.setFileType(collectionPageType) - await GitHubFile.create(newPageName, content) + const { sha: newSha } = await GitHubFile.create(newPageName, content) await GitHubFile.delete(pageName, sha) - res.status(200).json({ newPageName, content }) + res.status(200).json({ collectionName, pageName: newPageName, content, sha: newSha }) } catch (err) { console.log(err) } diff --git a/routes/documents.js b/routes/documents.js index 24460675c..38174ebaa 100644 --- a/routes/documents.js +++ b/routes/documents.js @@ -15,9 +15,9 @@ router.get('/:siteName/documents', async function(req, res, next) { const GitHubFile = new File(access_token, siteName) const documentType = new DocumentType() GitHubFile.setFileType(documentType) - const files = await GitHubFile.list() + const documents = await GitHubFile.list() - res.status(200).json({ files }) + res.status(200).json({ documents }) } catch (err) { console.log(err) } @@ -38,9 +38,9 @@ router.post('/:siteName/documents', async function(req, res, next) { const GitHubFile = new File(access_token, siteName) const documentType = new DocumentType() GitHubFile.setFileType(documentType) - await GitHubFile.create(documentName, content) + const { sha } = await GitHubFile.create(documentName, content) - res.status(200).json({ documentName, content }) + res.status(200).json({ documentName, content, sha }) } catch (err) { console.log(err) } @@ -83,9 +83,9 @@ router.post('/:siteName/documents/:documentName', async function(req, res, next) const GitHubFile = new File(access_token, siteName) const documentType = new DocumentType() GitHubFile.setFileType(documentType) - await GitHubFile.update(documentName, content, sha) + const { newSha } = await GitHubFile.update(documentName, content, sha) - res.status(200).json({ documentName, content }) + res.status(200).json({ documentName, content, sha: newSha }) } catch (err) { console.log(err) } @@ -105,7 +105,7 @@ router.delete('/:siteName/documents/:documentName', async function(req, res, nex GitHubFile.setFileType(documentType) await GitHubFile.delete(documentName, sha) - res.status(200).json({ documentName, content }) + res.status(200).send('OK') } catch (err) { console.log(err) } @@ -126,10 +126,10 @@ router.post('/:siteName/documents/:documentName/rename/:newDocumentName', async const GitHubFile = new File(access_token, siteName) const documentType = new DocumentType() GitHubFile.setFileType(documentType) - await GitHubFile.create(newDocumentName, content) + const { sha: newSha } = await GitHubFile.create(newDocumentName, content) await GitHubFile.delete(documentName, sha) - res.status(200).json({ newDocumentName, content }) + res.status(200).json({ documentName: newDocumentName, content, sha: newSha }) } catch (err) { console.log(err) } diff --git a/routes/images.js b/routes/images.js index 4c15ebcf5..06a2295b8 100644 --- a/routes/images.js +++ b/routes/images.js @@ -38,9 +38,9 @@ router.post('/:siteName/images', async function(req, res, next) { const GitHubFile = new File(access_token, siteName) const imageType = new ImageType() GitHubFile.setFileType(imageType) - await GitHubFile.create(imageName, content) + const { sha } = await GitHubFile.create(imageName, content) - res.status(200).json({ imageName, content }) + res.status(200).json({ imageName, content, sha }) } catch (err) { console.log(err) } @@ -83,9 +83,9 @@ router.post('/:siteName/images/:imageName', async function(req, res, next) { const GitHubFile = new File(access_token, siteName) const imageType = new ImageType() GitHubFile.setFileType(imageType) - await GitHubFile.update(imageName, content, sha) + const { newSha } = await GitHubFile.update(imageName, content, sha) - res.status(200).json({ imageName, content }) + res.status(200).json({ imageName, content, sha: newSha }) } catch (err) { console.log(err) } @@ -105,7 +105,7 @@ router.delete('/:siteName/images/:imageName', async function(req, res, next) { GitHubFile.setFileType(imageType) await GitHubFile.delete(imageName, sha) - res.status(200).json({ imageName, content }) + res.status(200).send('OK') } catch (err) { console.log(err) } @@ -128,10 +128,10 @@ router.post('/:siteName/images/:imageName/rename/:newImageName', async function( const GitHubFile = new File(access_token, siteName) const imageType = new ImageType() GitHubFile.setFileType(imageType) - await GitHubFile.create(newImageName, content) + const { sha: newSha } = await GitHubFile.create(newImageName, content) await GitHubFile.delete(imageName, sha) - res.status(200).json({ newImageName, content }) + res.status(200).json({ imageName: newImageName, content, sha: newSha }) } catch (err) { console.log(err) } diff --git a/routes/pages.js b/routes/pages.js index b3bdebd3e..f49070bab 100644 --- a/routes/pages.js +++ b/routes/pages.js @@ -39,9 +39,9 @@ router.post('/:siteName/pages', async function(req, res, next) { const GitHubFile = new File(access_token, siteName) const pageType = new PageType() GitHubFile.setFileType(pageType) - await GitHubFile.create(pageName, content) + const { sha } = await GitHubFile.create(pageName, content) - res.status(200).json({ pageName, content }) + res.status(200).json({ pageName, content, sha }) } catch (err) { console.log(err) @@ -88,9 +88,9 @@ router.post('/:siteName/pages/:pageName', async function(req, res, next) { const GitHubFile = new File(access_token, siteName) const pageType = new PageType() GitHubFile.setFileType(pageType) - await GitHubFile.update(pageName, content, sha) + const { newSha } = await GitHubFile.update(pageName, content, sha) - res.status(200).json({ pageName, content }) + res.status(200).json({ pageName, content, sha: newSha }) } catch (err) { console.log(err) res.status(400).json(err) @@ -111,7 +111,7 @@ router.delete('/:siteName/pages/:pageName', async function(req, res, next) { GitHubFile.setFileType(pageType) await GitHubFile.delete(pageName, sha) - res.status(200).json({ pageName }) + res.status(200).send('OK') } catch (err) { console.log(err) res.status(400).json(err) @@ -133,10 +133,10 @@ router.post('/:siteName/pages/:pageName/rename/:newPageName', async function(req const GitHubFile = new File(access_token, siteName) const pageType = new PageType() GitHubFile.setFileType(pageType) - await GitHubFile.create(newPageName, content) + const { sha: newSha } = await GitHubFile.create(newPageName, content) await GitHubFile.delete(pageName, sha) - res.status(200).json({ newPageName }) + res.status(200).json({ pageName: newPageName, content, sha: newSha }) } catch (err) { console.log(err)