Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export endpoint for ds-s #68

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.3.0",
"description": "Starter project for an ES6 RESTful Express API",
"main": "dist",
"type": "module",
"scripts": {
"dev": "env NODE_ENV=development nodemon -w src --exec \"babel-node src\"",
"build": "env NODE_ENV=production npx babel src -d dist",
Expand All @@ -26,6 +27,7 @@
"express": "^4.13.3",
"express-graphql": "^0.6.12",
"express-handlebars": "^4.0.4",
"file-system": "^2.2.2",
"googleapis": "^39.1.0",
"graphql": "^0.13.2",
"morgan": "^1.8.0",
Expand Down
15 changes: 15 additions & 0 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import copy from '../copy/en'

export default ({ config, controller }) => {
let api = Router()
const fileDest = config.EXPORT_FILE_DEST || null

api.get('/', (req, res) => {
res.json({
Expand All @@ -22,6 +23,20 @@ export default ({ config, controller }) => {
})
})

api.get('/export', (req, res) => {
controller
.retrieveAll(fileDest)
.then(msg =>
res.json({
success: msg
})
)
.catch(err =>
res.status(404)
.send({ error: err.message, err })
)
})

api.get('/update', (req, res) => {
controller
.update()
Expand Down
7 changes: 6 additions & 1 deletion src/copy/en.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export default {
errors: {
update: 'The server could not update. Check your API credentials and internet connection and try again.',
export: {
fileMissing: 'The server could not export. Check that you provided a file path to export to and try again.',
writeFailed: 'The server could not export the data to the file. There is an issue with the data format'
},
onlySheet: 'You cannot query a sheet directly. The URL needs to be in the format /:sheet/:tab/:resource.',
onlyTab: 'You cannot query a tab directly. The URL needs to be in the format /:sheet/:tab/:resource.',
noSheet: sheet => `The sheet ${sheet} is not available in this server.`,
Expand All @@ -9,6 +13,7 @@ export default {
modelLayer: prts => `Something went wrong at the model layer`
},
success: {
update: 'All sheets updated'
update: 'All sheets updated',
export: dest => `All resources exported to the file: ${dest}`
}
}
32 changes: 32 additions & 0 deletions src/lib/Controller.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import copy from '../copy/en'
import { exportToFile } from '../lib/util'

/**
* Controller
Expand Down Expand Up @@ -39,6 +40,37 @@ class Controller {
})
}

// Controller function to retrieve all blueprints and export to user defined file location
retrieveAll (fileDest) {
if (!fileDest) return Promise.reject(new Error(copy.errors.export.fileMissing))

const indexedData = {}
const urls = []

const bps = this.blueprints()
return Promise.all(
bps.map(bp => {
const resource = Object.keys(bp.resources)[0]
urls.push(bp.urls[0])
return this.retrieve(bp.sheet.name, bp.name, resource)
})
).then(async results => {
if (results.every(res => res)) {
urls.forEach((item, idx) => {
indexedData[item] = results[idx]
})
try {
const message = await exportToFile(fileDest, indexedData)
return message
} catch (e) {
return Promise.reject(e)
}
} else {
throw new Error(copy.errors.export.writeFailed)
}
})
}

retrieve (sheet, tab, resource) {
if (this._sheetExists(sheet)) {
const fetcher = this.fetchers[sheet]
Expand Down
14 changes: 14 additions & 0 deletions src/lib/util.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import R from 'ramda'
import { promises as fs } from 'file-system'
import copy from '../copy/en'

/* eslint-disable */
String.prototype.replaceAll = function (search, replacement) {
Expand All @@ -14,6 +16,18 @@ function camelize (str) {
})
}

export async function exportToFile (fileDest, data) {
const stringifiedData = JSON.stringify(data, null, 2)
const filePath = `${fileDest}/export.json`

try {
await fs.writeFile(filePath, stringifiedData)
return copy.success.export(filePath)
} catch (err) {
throw new Error(copy.errors.export.writeFailed)
}
}

export const fmtObj = R.curry(
(
columnNames,
Expand Down