From bdb4c21e882eb38950f50b8bad1997cc8342a97d Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Thu, 18 Jun 2020 15:01:51 -0700 Subject: [PATCH 1/9] Added test for CRLF newlines --- test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test.js b/test.js index 63c70f5..f417fac 100644 --- a/test.js +++ b/test.js @@ -1958,6 +1958,10 @@ describe('CSV', function() { assert.equal(get_cell(sheet, "C1").t, 's'); assert.equal(get_cell(sheet, "C1").v, '100'); }); + it('should interpret CRLF newlines', function() { + var wb = X.read(new Buffer("sep=&\r\n1&2&3\r\n4&5&6"), {type: "buffer"}); + assert.equal(wb.Sheets.Sheet1["!ref"], "A1:C2"); + }); if(!browser || typeof cptable !== 'undefined') it('should honor codepage for binary strings', function() { var data = "abc,def\nghi,j\xD3l"; [[1251, 'У'],[1252, 'Ó'], [1253, 'Σ'], [1254, 'Ó'], [1255, '׃'], [1256, 'س'], [10000, '”']].forEach(function(m) { -- 2.34.1 From 5c0d0e21b9f9e421bd9b2786940f6651be8443ec Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Fri, 19 Jun 2020 14:57:04 -0700 Subject: [PATCH 2/9] Initialized firebase functions app --- demos/function/Firebase/.firebaserc | 1 + demos/function/Firebase/.gitignore | 65 +++++++++++++++++++ demos/function/Firebase/firebase.json | 1 + demos/function/Firebase/functions/.gitignore | 1 + demos/function/Firebase/functions/index.js | 8 +++ .../function/Firebase/functions/package.json | 22 +++++++ 6 files changed, 98 insertions(+) create mode 100644 demos/function/Firebase/.firebaserc 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/Firebase/.firebaserc b/demos/function/Firebase/.firebaserc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/demos/function/Firebase/.firebaserc @@ -0,0 +1 @@ +{} diff --git a/demos/function/Firebase/.gitignore b/demos/function/Firebase/.gitignore new file mode 100644 index 0000000..f626852 --- /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..bd698a2 --- /dev/null +++ b/demos/function/Firebase/functions/index.js @@ -0,0 +1,8 @@ +const functions = require('firebase-functions'); + +// // 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!"); +// }); diff --git a/demos/function/Firebase/functions/package.json b/demos/function/Firebase/functions/package.json new file mode 100644 index 0000000..89652b8 --- /dev/null +++ b/demos/function/Firebase/functions/package.json @@ -0,0 +1,22 @@ +{ + "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": { + "firebase-admin": "^8.6.0", + "firebase-functions": "^3.3.0" + }, + "devDependencies": { + "firebase-functions-test": "^0.1.6" + }, + "private": true +} -- 2.34.1 From b796774e4b063d6526d2a17fa90b5dd6b6a3faa6 Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Fri, 19 Jun 2020 18:14:59 -0700 Subject: [PATCH 3/9] Updated gitignore --- demos/function/Firebase/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/function/Firebase/.gitignore b/demos/function/Firebase/.gitignore index f626852..f9ed3da 100644 --- a/demos/function/Firebase/.gitignore +++ b/demos/function/Firebase/.gitignore @@ -14,7 +14,7 @@ firebase-debug.log* # 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 +.firebaserc # Runtime data pids -- 2.34.1 From 6c40a7f3ffa3eb2407ef884312030e589a6e6e0d Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Fri, 19 Jun 2020 18:16:52 -0700 Subject: [PATCH 4/9] Implemented csv file conversion --- demos/function/Firebase/.firebaserc | 1 - demos/function/Firebase/functions/index.js | 38 +++++++++++++++++-- .../function/Firebase/functions/package.json | 4 +- 3 files changed, 38 insertions(+), 5 deletions(-) delete mode 100644 demos/function/Firebase/.firebaserc diff --git a/demos/function/Firebase/.firebaserc b/demos/function/Firebase/.firebaserc deleted file mode 100644 index 0967ef4..0000000 --- a/demos/function/Firebase/.firebaserc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/demos/function/Firebase/functions/index.js b/demos/function/Firebase/functions/index.js index bd698a2..b8a8b42 100644 --- a/demos/function/Firebase/functions/index.js +++ b/demos/function/Firebase/functions/index.js @@ -1,8 +1,40 @@ 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.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" }); + // Conver to CSV + XLSX.write(wb, {type: "string", bookType: "csv"}); + res.send(wb); + }); + bb.end(req.body) +}); diff --git a/demos/function/Firebase/functions/package.json b/demos/function/Firebase/functions/package.json index 89652b8..53238b4 100644 --- a/demos/function/Firebase/functions/package.json +++ b/demos/function/Firebase/functions/package.json @@ -12,8 +12,10 @@ "node": "8" }, "dependencies": { + "busboy": "^0.3.1", "firebase-admin": "^8.6.0", - "firebase-functions": "^3.3.0" + "firebase-functions": "^3.3.0", + "xlsx": "^0.16.2" }, "devDependencies": { "firebase-functions-test": "^0.1.6" -- 2.34.1 From 925a26cf02e40332a3295e18aeb180d570519e9a Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Mon, 22 Jun 2020 13:30:58 -0700 Subject: [PATCH 5/9] [ci skip] CSV conversion --- demos/function/Firebase/functions/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/demos/function/Firebase/functions/index.js b/demos/function/Firebase/functions/index.js index b8a8b42..d14b499 100644 --- a/demos/function/Firebase/functions/index.js +++ b/demos/function/Firebase/functions/index.js @@ -32,9 +32,8 @@ exports.main = functions.https.onRequest((req, res) => { bb.on('finish', () => { let f = files[Object.keys(files)[0]]; const wb = XLSX.read(f[0], { type: "buffer" }); - // Conver to CSV - XLSX.write(wb, {type: "string", bookType: "csv"}); - res.send(wb); + // Convert to CSV + res.send(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])); }); bb.end(req.body) }); -- 2.34.1 From f32ce495d0d34dbb9bc52a604d1d15206ac1cc1d Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Mon, 22 Jun 2020 14:09:51 -0700 Subject: [PATCH 6/9] [ci skip] Modified README to include firebase --- demos/function/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/demos/function/README.md b/demos/function/README.md index 70099ee..018d8c2 100644 --- a/demos/function/README.md +++ b/demos/function/README.md @@ -121,3 +121,13 @@ 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 run `firebase +emulators:start` to start the local server. -- 2.34.1 From f3fb4c21ac48f6a203a3ed40468508aab86d0fd1 Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Tue, 23 Jun 2020 18:24:49 -0700 Subject: [PATCH 7/9] Added init-azure script to makefile --- demos/function/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 -- 2.34.1 From c69e61baa7d683333042bed110079cabfdc5aa8e Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Tue, 23 Jun 2020 18:29:18 -0700 Subject: [PATCH 8/9] [ci skip] Updated Azure demo --- demos/function/AzureHTTPTrigger/index.js | 5 ++--- demos/function/host.json | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) 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/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 -- 2.34.1 From d872e777d9c7f7c43a51d1151d2c1cd077b8929a Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Thu, 25 Jun 2020 12:27:17 -0700 Subject: [PATCH 9/9] [ci skip] Updated README --- demos/function/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/demos/function/README.md b/demos/function/README.md index 018d8c2..d4138ec 100644 --- a/demos/function/README.md +++ b/demos/function/README.md @@ -129,5 +129,6 @@ 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 run `firebase -emulators:start` to start the local server. +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. -- 2.34.1