From 0c7e809e9c16ffaa9459031d032f22c69da436d9 Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Thu, 25 Jun 2020 12:30:56 -0700 Subject: [PATCH] [ci skip] Fixed functions demos (#2025) * Added test for CRLF newlines * Initialized firebase functions app * Updated gitignore * Implemented csv file conversion * CSV conversion * Modified README to include firebase * Added init-azure script to makefile * Updated Azure demo * Updated README --- demos/function/AzureHTTPTrigger/index.js | 5 +- demos/function/Firebase/.gitignore | 65 +++++++++++++++++++ demos/function/Firebase/firebase.json | 1 + demos/function/Firebase/functions/.gitignore | 1 + demos/function/Firebase/functions/index.js | 39 +++++++++++ .../function/Firebase/functions/package.json | 24 +++++++ demos/function/Makefile | 6 +- demos/function/README.md | 11 ++++ demos/function/host.json | 4 +- 9 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 demos/function/Firebase/.gitignore create mode 100644 demos/function/Firebase/firebase.json create mode 100644 demos/function/Firebase/functions/.gitignore create mode 100644 demos/function/Firebase/functions/index.js create mode 100644 demos/function/Firebase/functions/package.json diff --git a/demos/function/AzureHTTPTrigger/index.js b/demos/function/AzureHTTPTrigger/index.js index a576f5c..c39d77c 100644 --- a/demos/function/AzureHTTPTrigger/index.js +++ b/demos/function/AzureHTTPTrigger/index.js @@ -26,9 +26,8 @@ module.exports = (context, req) => { if(!f) { context.res = { status: 400, body: "Must submit a file for processing!" }; } else { - /* since the file is Base64-encoded, read the file and parse as "base64" */ - const b64 = fs.readFileSync(f.path).toString(); - const wb = XLSX.read(b64, {type:"base64"}); + /* file is stored in a temp directory, so we can point to that and read it */ + const wb = XLSX.read(f.path, {type:"file"}); /* convert to specified output type -- default CSV */ const ext = (fields.bookType || "csv").toLowerCase(); diff --git a/demos/function/Firebase/.gitignore b/demos/function/Firebase/.gitignore new file mode 100644 index 0000000..f9ed3da --- /dev/null +++ b/demos/function/Firebase/.gitignore @@ -0,0 +1,65 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +firebase-debug.log* + +# Firebase cache +.firebase/ + +# Firebase config + +# Uncomment this if you'd like others to create their own Firebase project. +# For a team working on the same Firebase project(s), it is recommended to leave +# it commented so all members can deploy to the same project(s) in .firebaserc. +.firebaserc + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/demos/function/Firebase/firebase.json b/demos/function/Firebase/firebase.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/demos/function/Firebase/firebase.json @@ -0,0 +1 @@ +{} diff --git a/demos/function/Firebase/functions/.gitignore b/demos/function/Firebase/functions/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/demos/function/Firebase/functions/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/demos/function/Firebase/functions/index.js b/demos/function/Firebase/functions/index.js new file mode 100644 index 0000000..d14b499 --- /dev/null +++ b/demos/function/Firebase/functions/index.js @@ -0,0 +1,39 @@ +const functions = require('firebase-functions'); +const Busboy = require('busboy'); +const XLSX = require('xlsx'); + +// // Create and Deploy Your First Cloud Functions +// // https://firebase.google.com/docs/functions/write-firebase-functions +// +exports.helloWorld = functions.https.onRequest((request, response) => { + response.send("Hello from Firebase!"); +}); + +exports.main = functions.https.onRequest((req, res) => { + var bb = new Busboy({ + headers: { + 'content-type': req.headers['content-type'] + } + }); + let fields = {}; + let files = {}; + bb.on('field', (fieldname, val) => { + fields[fieldname] = val; + }); + bb.on('file', (fieldname, file, filename) => { + var buffers = []; + file.on('data', (data) => { + buffers.push(data); + }); + file.on('end', () => { + files[fieldname] = [Buffer.concat(buffers), filename]; + }); + }); + bb.on('finish', () => { + let f = files[Object.keys(files)[0]]; + const wb = XLSX.read(f[0], { type: "buffer" }); + // Convert to CSV + res.send(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])); + }); + bb.end(req.body) +}); diff --git a/demos/function/Firebase/functions/package.json b/demos/function/Firebase/functions/package.json new file mode 100644 index 0000000..53238b4 --- /dev/null +++ b/demos/function/Firebase/functions/package.json @@ -0,0 +1,24 @@ +{ + "name": "functions", + "description": "Cloud Functions for Firebase", + "scripts": { + "serve": "firebase emulators:start --only functions", + "shell": "firebase functions:shell", + "start": "npm run shell", + "deploy": "firebase deploy --only functions", + "logs": "firebase functions:log" + }, + "engines": { + "node": "8" + }, + "dependencies": { + "busboy": "^0.3.1", + "firebase-admin": "^8.6.0", + "firebase-functions": "^3.3.0", + "xlsx": "^0.16.2" + }, + "devDependencies": { + "firebase-functions-test": "^0.1.6" + }, + "private": true +} diff --git a/demos/function/Makefile b/demos/function/Makefile index 242d892..e76c097 100644 --- a/demos/function/Makefile +++ b/demos/function/Makefile @@ -9,8 +9,12 @@ aws: lambda-proxy lambda-proxy: cd LambdaProxy; mkdir -p node_modules; npm install xlsx busboy; sam local start-api; cd - +.PHONY: init-azure +init-azure: + cd AzureHTTPTrigger; mkdir -p node_modules; npm install xlsx formidable fs + .PHONY: azure -azure: +azure: init-azure func start .PHONY: azure-server diff --git a/demos/function/README.md b/demos/function/README.md index 70099ee..d4138ec 100644 --- a/demos/function/README.md +++ b/demos/function/README.md @@ -121,3 +121,14 @@ HTTP trigger that converts the submitted file to CSV. When deploying on Azure, be sure to install the module from the remote console, as described in the "Azure Functions JavaScript developer guide". + +#### Firebase Functions + +Firebase functions can be triggered via HTTP requests, similar to a REST API. +In the `Firebase` directory, the example function reads files sent through +HTTP and converts it to a CSV and sends the response in the form of a string. + +To run this demo locally, run `npm i -g firebase-tools` to install the +Firebase CLI and `npm i` to install the dependencies, then `firebase use --add` +to connect to an existing Firebase project. Run `firebase emulators:start` to +start the local server. diff --git a/demos/function/host.json b/demos/function/host.json index ffcd441..81e35b7 100644 --- a/demos/function/host.json +++ b/demos/function/host.json @@ -1 +1,3 @@ -{ } +{ + "version": "2.0" +} \ No newline at end of file