Skip to content

Commit

Permalink
Add example project, fix bugs in README
Browse files Browse the repository at this point in the history
  • Loading branch information
danielcompton committed Apr 21, 2017
1 parent 37a7fa0 commit 56b0bf9
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 5 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ Chunked, pausable, recoverable uploading to Google Cloud Storage directly from t

## Example

There is a full example available at `example/example-client`.

```js
import Upload from 'gcs-browser-upload'

let input = document.getElementById('fileInput')
let pause = document.getElementbyId('pause')
let unpause = document.getElementbyId('unpause')
let pause = document.getElementById('pause')
let unpause = document.getElementById('unpause')
let upload = null

input.addEventListener('change', async () => {
Expand All @@ -39,7 +41,7 @@ input.addEventListener('change', async () => {
console.log('Upload complete!')
} catch (e) {
console.log('Upload failed!', e)
} finally () {
} finally {
upload = null
}
})
Expand All @@ -62,7 +64,7 @@ unpause.addEventListener('click', () => {

```js
{
id: null, // required - a unique ID for the upload
id: null, // required - a unique ID for the upload
url: null, // required - GCS resumable URL
file: null, // required - instance of File
chunkSize: 262144, // optional - chunk size must be a multiple of 262144
Expand Down Expand Up @@ -93,4 +95,4 @@ This project was created by the Engineering team at [Qubit](http://www.qubit.com

We’re currently looking to grow our team, so if you’re a JavaScript engineer and keen on ES2016 React+Redux applications and Node micro services, why not get in touch? Work with like minded engineers in an environment that has fantastic perks, including an annual ski trip, yoga, a competitive foosball league, and copious amounts of yogurt.

Find more details on our [Engineering site](https://eng.qubit.com). Don’t have an up to date CV? Just link us your Github profile! Better yet, send us a pull request that improves this project.
Find more details on our [Engineering site](https://eng.qubit.com). Don’t have an up to date CV? Just link us your Github profile! Better yet, send us a pull request that improves this project.
10 changes: 10 additions & 0 deletions example/example-client/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"presets": ["es2015", "stage-0"],
"plugins": [
["transform-regenerator"],
["transform-runtime", {
"polyfill": false,
"regenerator": true,
}]
]
}
60 changes: 60 additions & 0 deletions example/example-client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
lib/

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# 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/
jspm_packages/

# Typescript v1 declaration files
typings/

# 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
52 changes: 52 additions & 0 deletions example/example-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Example usage

## Setup

Before you start, you need to enable CORS on the buckets you want to upload to. You can do that with

```
gsutil cors set cors-json-file.json gs://your-bucket-name
```

`cors-json-file.json` is in this folder. You may need to tweak it depending on which HTTP methods you are wanting to call on GCS.

You also need to run

```sh
npm install
```

## Building

```sh
browserify src/main.js -o lib/bundle.js -t babelify
```

What is happening is:

1. Browserify starts
2. It runs the babelify transform
3. Babelify calls Babel which converts the ES2015 code into something readable by todays browsers. In particular it converts the `import`s into `require`s and translates async calls.
4. Browserify packages up the generated files along with all of the required code into a single `bundle.js` file.

*N.B.* Currently you need to generate an upload URL through another method and hard code it into the `url` key in the `Upload` object. For reference, here is a method in Clojure:

```clj
(defn sign-url [storage ^String bucket ^String blob content-type]
(let [storage ^Storage (:service storage)
blobinfo (.. (BlobInfo/newBuilder bucket blob)
(setContentType content-type)
(build))]
(.signUrl storage blobinfo 7 TimeUnit/DAYS (into-array Storage$SignUrlOption [(Storage$SignUrlOption/signWith
(ServiceAccountCredentials/fromStream (io/input-stream "private/repository-import-service.json")))
(Storage$SignUrlOption/withContentType)
(Storage$SignUrlOption/httpMethod HttpMethod/PUT)]))))
```

## Running

Open `index.html`. Pick a file to upload. As soon as you pick the file, the upload will begin.

# Notes

I had to make a separate `main.js` file which required babel-polyfill before requiring `app.js`, otherwise you get errors saying `regeneratorRuntime is not defined`.
8 changes: 8 additions & 0 deletions example/example-client/cors-json-file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"origin": ["http://localhost:3001"],
"responseHeader": ["Content-Type", "content-range"],
"method": ["GET", "PUT", "POST", "HEAD", "DELETE"],
"maxAgeSeconds": 3600
}
]
9 changes: 9 additions & 0 deletions example/example-client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<head>
</head>
<body>
<h2>Test Upload</h2>
<input id="fileInput" type="file"></input>
<button id="pause">Pause</button>
<button id="unpause">Unpause</button>
<script src="lib/bundle.js"></script>
</body>
28 changes: 28 additions & 0 deletions example/example-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "gcs-upload-example",
"version": "1.0.0",
"description": "gcs upload example",
"private": true,
"main": "lib/main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "babel src -d lib"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-runtime": "^6.23.0",
"gcs-browser-upload": "^1.0.0"
},
"devDependencies": {
"babel-cli": "^6.14.0",
"babel-core": "^6.7.4",
"babel-eslint": "^6.0.0",
"babel-plugin-transform-regenerator": "^6.24.1",
"babel-polyfill": "^6.7.4",
"babel-preset-env": "^1.4.0",
"babel-preset-es2015": "^6.6.0",
"babel-preset-stage-0": "^6.5.0",
"babelify": "^7.3.0"
}
}
41 changes: 41 additions & 0 deletions example/example-client/src/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Upload from 'gcs-browser-upload';

// https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/1.0.0/storage/file?method=createResumableUpload

let input = document.getElementById('fileInput')
let pause = document.getElementById('pause')
let unpause = document.getElementById('unpause')
let upload = null

input.addEventListener('change', async () => {
upload = new Upload({
id: 'foo',
// N.B. This isn't a resumable upload URL. You should generate one of them instead somehow...
url: "https://storage.googleapis.com/your-bucket/your/key.zip?GoogleAccessId=service@project-name.iam.gserviceaccount.com&Expires=1493021074&Signature=biglongsignature%%%%%EXKw8zg%2BuDNSK3Z6tb8Z%2BVgOPopN5Kizatxwg%3D%3D",
file: input.files[0],
onChunkUpload: (info) => {
console.log('Chunk uploaded', info)
}
})

try {
await upload.start()
console.log('Upload complete!')
} catch (e) {
console.log('Upload failed!', e)
} finally {
upload = null
}
})

pause.addEventListener('click', () => {
if (upload) {
upload.pause()
}
})

unpause.addEventListener('click', () => {
if (upload) {
upload.unpause()
}
})
2 changes: 2 additions & 0 deletions example/example-client/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require('babel-polyfill');
require('./app');

0 comments on commit 56b0bf9

Please sign in to comment.