From 5d8db9061881cff3647b7e97629bcb3007a34405 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 6 Nov 2018 15:58:54 +0000 Subject: [PATCH] add support for single blueprinter in config --- README.md | 6 +++--- src/lib/Fetcher.js | 43 ++++++++++++++++++++++++++++++------------- src/lib/util.js | 6 ++++++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ae7c231..e0472fd 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Each Google Sheet being used as a as source requires a corresponding object in ` | ------ | ----------- | ---- | | name | Used to refer to data served from this source | string | | id | The ID of the sheet in Google. (You can find it in the address bar when the Sheet is open in a browser. It is the string that follows 'spreadsheets/d/'). | string | -| tabs | An object that maps each tab in the source to one or more Blueprinters. All of the Blueprinters in the [blueprinters folder](/lib/blueprinters) are available through a single import as at the top of [example.config.js](/src/example.config.js).
To correctly associate a Blueprinter, the object key needs to be _the tab name with all lowercase letters, and spaces replaced by a '-'_. For example, if the tab name in Google Sheets is 'Info About SHEEP', the object key should be 'info-about-sheep'.
More than one Blueprinter can be used per tab, if more than one representation is required for a single tab; in that case simply add a second Blueprinter in the array corresponding to the tab.
The value should be the Blueprinter function that you want to use for the data in that tab. See the example of a configuration object below.
TODO: no Blueprinter is used by default. | object | +| tabs | An object that maps each tab in the source to one or more Blueprinters. All of the Blueprinters in the [blueprinters folder](/lib/blueprinters) are available through a single import as at the top of [example.config.js](/src/example.config.js).
To correctly associate a Blueprinter, the object key needs to be _the tab name with all lowercase letters, and spaces replaced by a '-'_. For example, if the tab name in Google Sheets is 'Info About SHEEP', the object key should be 'info-about-sheep'.
The value should be the Blueprinter function that you want to use for the data in that tab. If you require more than one endpoint for a single tab, you can support multiple blueprinters by making the item an array. See the example of a configuration object below.
TODO: no Blueprinter is used by default. | object | ###### Example Configuration Object ```js @@ -104,8 +104,8 @@ export default { name: 'example', id: '1s-vfBR8Uy-B-TLO_C5Ozw4z-L0E3hdP8ohMV761ouRI', tabs: { - 'objects': [BP.byRow], - 'objectsB': [BP.byRow, BP.byID], + 'objects': BP.byRow, + 'fruit': [BP.byRow, BP.byID], } }, ] diff --git a/src/lib/Fetcher.js b/src/lib/Fetcher.js index 75f7d18..0f93d8c 100644 --- a/src/lib/Fetcher.js +++ b/src/lib/Fetcher.js @@ -1,6 +1,12 @@ // FetcherTwo class interfaces with Google Sheet, and saves to a specified db import {google} from "googleapis"; -import {fmtSourceTitle, fmtBlueprinterTitles, deriveFilename, bp} from "./util"; +import { + fmtSourceTitle, + fmtBlueprinterTitles, + deriveFilename, + bp, + isFunction +} from "./util"; import {byRow, byId} from "./blueprinters"; import R from "ramda"; @@ -39,6 +45,23 @@ class Fetcher { */ this.sheets = google.sheets("v4"); this.auth = null; + + /** + * saveBp is a curried function that takes in a title and + * a blueprinter. NB: it sits here in the constructor as + * I am not sure how to curry a class method with Ramda. + */ + this._saveBp = R.curry((tab, title, data, blueprinter) => { + const saturatedBp = blueprinter( + tab, + this.sourceName, + this.sourceId, + data + ); + const blueprint = bp(saturatedBp); // TODO: come up with better semantics. + this.blueprints[title] = blueprint; + return this.db.save(saturatedBp); + }); } /** returns a Promise that resolves if access is granted to the account, and rejects otherwise. */ @@ -96,19 +119,13 @@ class Fetcher { save(tab, data) { const title = fmtSourceTitle(tab); if (Object.keys(this.blueprinters).indexOf(title) > -1) { - const blueprinters = this.blueprinters[title]; + const bpConfig = this.blueprinters[title]; - return blueprinters.map(blueprinter => { - const saturatedBp = blueprinter( - tab, - this.sourceName, - this.sourceId, - data - ); - const blueprint = bp(saturatedBp); // TODO: come up with better semantics. - this.blueprints[title] = blueprint; - return this.db.save(saturatedBp); - }); + if (isFunction(bpConfig)) { + return this._saveBp(tab, title, data, bpConfig); + } else { + return bpConfig.map(this._saveBp(tab, title, data)); + } } else { // If it can't find a blueprinter for the tab title, default to byRow return this.db.save(byRow(tab, this.sourceName, this.sourceId, data)); diff --git a/src/lib/util.js b/src/lib/util.js index 3a65881..646b1b0 100755 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -85,3 +85,9 @@ export function bp(full) { }); return blueprint; } + +export function isFunction(functionToCheck) { + return ( + functionToCheck && {}.toString.call(functionToCheck) === "[object Function]" + ); +}