├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── PRIVACY.md ├── README.md ├── avrpizza.js ├── bin └── cli.js ├── lib ├── boards.js ├── packager.js └── request.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | demo.js 4 | test 5 | .vscode -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of 4 | fostering an open and welcoming community, we pledge to respect all people who 5 | contribute through reporting issues, posting feature requests, updating 6 | documentation, submitting pull requests or patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free 9 | experience for everyone, regardless of level of experience, gender, gender 10 | identity and expression, sexual orientation, disability, personal appearance, 11 | body size, race, ethnicity, age, religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic 20 | addresses, without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or 24 | reject comments, commits, code, wiki edits, issues, and other contributions 25 | that are not aligned to this Code of Conduct, or to ban temporarily or 26 | permanently any contributor for other behaviors that they deem inappropriate, 27 | threatening, offensive, or harmful. 28 | 29 | By adopting this Code of Conduct, project maintainers commit themselves to 30 | fairly and consistently applying these principles to every aspect of managing 31 | this project. Project maintainers who do not follow or enforce the Code of 32 | Conduct may be permanently removed from the project team. 33 | 34 | This code of conduct applies both within project spaces and in public spaces 35 | when an individual is representing the project or its community. 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 38 | reported by contacting the project maintainer at noopkat@gmail.com. All 39 | complaints will be reviewed and investigated and will result in a response that 40 | is deemed necessary and appropriate to the circumstances. Maintainers are 41 | obligated to maintain confidentiality with regard to the reporter of an 42 | incident. 43 | 44 | 45 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 46 | version 1.3.0, available at 47 | [http://contributor-covenant.org/version/1/3/0/][version] 48 | 49 | [homepage]: http://contributor-covenant.org 50 | [version]: http://contributor-covenant.org/version/1/3/0/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Suz Hinton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PRIVACY.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | 3 | ## General 4 | 5 | The cloud compilation feature in this software involves using a remote computer (ie. not owned by you, the user) to process the files you provide when using avr-pizza. 6 | We store the least amount of data required to deliver your pizza (compiled code). 7 | 8 | **Here is what we do store:** 9 | 10 | 1. Server logs (timestamps of individual requests, and anonymized errors/stack traces for debugging purposes) 11 | 2. Access logs (IP addresses) 12 | 13 | **What we don't store:** 14 | 15 | 1. Your uploaded files - they are deleted immediately after the compilation and return response is completed. 16 | 17 | 18 | ## Changes 19 | 20 | The author may periodically update this policy. Watching this repository will alert you to these changes when they occur. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![status not ready](https://img.shields.io/badge/status-alpha-red.svg) ![powered by Azure](https://img.shields.io/badge/powered%20by-Azure%20%E2%98%81%EF%B8%8F-blue.svg) 2 | 3 | # avr-pizza 4 | Bespoke, artisinal, **P**recompiler **I**n **ZZ**ee **A**ir 5 | 6 | :cloud: :pizza: :cloud: :pizza: :cloud: 7 | 8 | :warning: **This is very much in alpha stage at the moment, so use at your own caution. Holler in this repo's issues if you have something unexpected happen if you give this a try. Thanks** :pray: :two_hearts: 9 | 10 | ## What is this? 11 | 12 | Avr-pizza is a tool for compiling Arduino sketch files without needing to have the Arduino IDE and related toolchains installed on your machine. 13 | 14 | It makes use of :sparkles: the cloud :sparkles:. Ask, and ye shall receive a freshly baked, delicious compilation in a timely manner. 15 | 16 | ### Q: Wait, why is this happening in the cloud again? 17 | 18 | A: Glad you asked! A couple of general use cases for leaning on remote compilation: 19 | 20 | 1. Compile Arduino sketches within a web browser environment (coming soon) :zap: 21 | 22 | 2. Compile Arduino sketches on users' machines without requiring them to go through downloading and installing the Arduino IDE. This is particularly helpful for nodebots related libraries, which often produce custom sketches tailored to the unique needs of a user setting up their robot. Makes for a less confusing and more friendly 'out of the box' experience all round. 23 | 24 | ### Q: Can I override 'the cloud' with my local Arduino IDE installation to build on my own machine instead? 25 | 26 | A: Yes! See the examples section of this README for details on how to do this. 27 | 28 | ## Requirements 29 | 30 | To use this library, a stable internet connection is required. You'll also need to have [NodeJS](http://nodejs.org) installed on your computer. 31 | 32 | ## Installation 33 | 34 | First, ensure you have [installed NodeJS](http://nodejs.org). 35 | 36 | Then, run the following in your preferred terminal program: 37 | 38 | ```bash 39 | npm install avr-pizza 40 | ``` 41 | 42 | ## Examples 43 | 44 | 45 | ### Simple 46 | 47 | To compile a simple sketch with no custom library dependencies (such as blink.ino): 48 | 49 | ```js 50 | var avrpizza = require('avr-pizza'); 51 | 52 | var package = { 53 | sketch: '/path/to/blink.ino', 54 | board: 'uno' 55 | }; 56 | 57 | avrpizza.compile(package, function(error, hex) { 58 | console.log(error, hex); // hex = NodeJS Buffer containing hex file contents 59 | }); 60 | 61 | ``` 62 | 63 | **Note:** `hex` is a NodeJS Buffer. You may then go on to pass this onto your program, or even write it to disk as a `.hex` file. 64 | 65 | ### With external libraries 66 | 67 | To compile a sketch with custom library dependencies, a `libraries` option is needed containing the paths to the top level directory of each library: 68 | 69 | ```js 70 | var avrpizza = require('avr-pizza'); 71 | 72 | var package = { 73 | sketch: '/path/to/mysketch.ino', 74 | libraries: ['/path/to/customlib1', '/path/to/customlib2'], 75 | board: 'uno' 76 | }; 77 | 78 | avrpizza.compile(package, function(error, hex) { 79 | console.log(error, hex); 80 | }); 81 | 82 | ``` 83 | 84 | ### Skip the cloud and build locally on your own machine instead 85 | 86 | Currently, local builds are supported on OSX, Linux, and Windows. 87 | 88 | To compile locally, add a `builder` option to your package object. The `location` key should be set to the path where your local installation of the Arduino IDE is located. 89 | 90 | Typical installation locations (adjust accordingly - your installation path might differ slightly): 91 | 92 | + OSX: `'/Applications/Arduino.app'` 93 | + Linux: `'/usr/local/share/arduino-1.6.9'` 94 | + Windows: `'c:\\Program\ Files\\Arduino'` 95 | 96 | Example: 97 | 98 | ```js 99 | var avrpizza = require('avr-pizza'); 100 | 101 | var package = { 102 | sketch: '/path/to/mysketch.ino', 103 | libraries: ['/path/to/customlib1', '/path/to/customlib2'], 104 | board: 'uno', 105 | builder: { 106 | location: '/Applications/Arduino.app' 107 | } 108 | }; 109 | 110 | // avrpizza will now build using `/Applications/Arduino.app` 111 | avrpizza.compile(package, function(error, hex) { 112 | console.log(error, hex); 113 | }); 114 | 115 | ``` 116 | 117 | ## Package options 118 | 119 | You may include the following options in the `package` object passed to the compile method: 120 | 121 | ### Required 122 | + _String_ **sketch** - the local path to the sketch file you're looking to compile 123 | 124 | + _String_ **board** - the target Arduino board the sketch is to be compiled for. See the supported boards section in this documentation to look up the correct string to supply for your chosen board. 125 | 126 | ### Optional 127 | + _Array_ **libraries** - contains local directory paths to any library your sketch uses (optional). Standard Arduino libraries do not need to be included. See standard libraries section in this documentation for the list. 128 | 129 | + _Object_ **builder** - the location of your local installation of the Arduino IDE, only if you wish to compile locally. Contains one key - `location` which should be a path string of where the IDE is located on your hard drive. Eg: `builder: { location: '/Applications/Arduino.app' }` 130 | ## CLI 131 | 132 | Avr-pizza is also a command line tool! Run it on a sketch and a hex file will be saved to disk. 133 | 134 | Install it with: 135 | 136 | ```bash 137 | npm install -g avr-pizza 138 | ``` 139 | 140 | ### Usage 141 | 142 | ```bash 143 | avr-pizza compile -s -l -a [-o -b ] 144 | ``` 145 | You may repeat the `-l` flag as many times as necessary to supply all the library directory paths you need. 146 | 147 | `-o` is optional; if not supplied the hex file will be saved in the current directory. 148 | 149 | #### Example 150 | ```bash 151 | avr-pizza compile -s /path/to/mysketch.ino -l /path/to/cool/library/dir -a 'uno' -o ~/stuff/pizzas 152 | ``` 153 | 154 | ## Supported boards 155 | 156 | |Board Name|Option String| 157 | |:----------|:--------------| 158 | |Arduino Uno|`uno`| 159 | |Arduino Mega|`mega`| 160 | |Arduino Leonardo|`leonardo`| 161 | |Arduino Micro|`micro`| 162 | |Arduino Nano|`nano`| 163 | |Arduino Duemilanove|`diecimila`| 164 | |Arduino Yún|`yun`| 165 | |Arduino Pro|`pro`| 166 | |Arduino Mega|`ADKmegaADK`| 167 | |Arduino Esplora|`esplora`| 168 | |Arduino Mini|`mini`| 169 | |Arduino Ethernet|`ethernet`| 170 | |Arduino Fio|`fio`| 171 | |Arduino BT|`bt`| 172 | |LilyPad Arduino USB|`LilyPadUSB`| 173 | |LilyPad Arduino|`lilypad`| 174 | |Arduino NG|`atmegang`| 175 | |Arduino Robot Control|`robotControl`| 176 | |Arduino Robot Motor|`robotMotor`| 177 | |Arduino Gemma|`gemma`| 178 | 179 | 180 | ## Standard Libraries 181 | 182 | There is no need to include the standard libraries that ship with Arduino. 183 | To rejog your memory, they are: 184 | 185 | + **EEPROM** - reading and writing to "permanent" storage 186 | + **Ethernet** - for connecting to the internet using the Arduino Ethernet Shield 187 | + **Firmata** - for communicating with applications on the computer using a standard serial protocol. 188 | + **GSM** - for connecting to a GSM/GRPS network with the GSM shield. 189 | + **LiquidCrystal** - for controlling liquid crystal displays (LCDs) 190 | + **SD** - for reading and writing SD cards 191 | + **Servo** - for controlling servo motors 192 | + **SPI** - for communicating with devices using the Serial Peripheral Interface (SPI) Bus 193 | + **SoftwareSerial** - for serial communication on any digital pins. 194 | + **Stepper** - for controlling stepper motors 195 | + **TFT** - for drawing text , images, and shapes on the Arduino TFT screen 196 | + **WiFi** - for connecting to the internet using the Arduino WiFi shield 197 | + **Wire** - Two Wire Interface (TWI/I2C) for sending and receiving data over a net of devices or sensors. 198 | 199 | If the only libraries you make use of in your sketch are included in the list above, you may leave out the `libraries` key in your `avrpizza.compile` package options. 200 | 201 | ## License 202 | 203 | MIT 204 | 205 | ## Privacy 206 | 207 | You may read this software's [privacy policy](PRIVACY.md). 208 | 209 | -------------------------------------------------------------------------------- /avrpizza.js: -------------------------------------------------------------------------------- 1 | var remoteComp = require('./lib/request'); 2 | var localComp = require('avrp-local'); 3 | var packager = require('./lib/packager'); 4 | var boards = require('./lib/boards'); 5 | 6 | module.exports.compile = function compile(package, callback) { 7 | // lets get rid of this for now until the board archs are settled on 8 | // if (boards.indexOf(package.board) === -1) { 9 | // return callback(new Error('Oops! That board is not supported, sorry.')); 10 | // } 11 | 12 | var builder = package.builder || null; 13 | 14 | // look for presence of local builder preference specified 15 | if (builder && builder.location) { 16 | // do local build 17 | localComp.requestCompilation(package, callback); 18 | } else { 19 | // do remote build 20 | packager.prepare(package, function(error, pack) { 21 | if (error) return callback(error); 22 | 23 | var board = package.board || 'uno'; 24 | var version = package.version || '10609'; 25 | var manufacturer = package.manufacturer || 'arduino'; 26 | var arch = package.arch || 'avr'; 27 | 28 | // now we're ready to request compilation by throwing over the tarball to the request side 29 | remoteComp.requestCompilation( 30 | { 31 | files: pack, 32 | board: board, 33 | version: version, 34 | service: package.service, 35 | manufacturer: manufacturer, 36 | arch: arch 37 | }, 38 | function(error, data) { 39 | var result = error ? null : new Buffer(data.data.src); 40 | 41 | return callback(error, result); 42 | } 43 | ); 44 | }); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var avrpizza = require('../avrpizza'); 3 | var boards = require('../lib/boards'); 4 | var parseArgs = require('minimist'); 5 | var path = require('path'); 6 | var fs = require('fs'); 7 | 8 | var args = (process.argv.slice(2)); 9 | var argv = parseArgs(args, {}); 10 | var userAction = argv._[0]; 11 | var help = 'Usage:\n' + 12 | ' avrpizza compile -s -l -a [-o -b ]\n' + 13 | ' avrpizza help\n'; 14 | 15 | function showHelp() { 16 | console.log(help); 17 | } 18 | 19 | function compile(options) { 20 | options.sketch = path.resolve(process.cwd(), options.sketch); 21 | options.libraries.forEach(function(l, i) { 22 | options.libraries[i] = path.resolve(process.cwd(), l); 23 | }); 24 | options.output = path.resolve(process.cwd(), options.output); 25 | 26 | avrpizza.compile(options, function(error, hex) { 27 | if (error) { 28 | console.error(error); 29 | process.exit(1); 30 | } else { 31 | var hexfilename = path.basename(options.sketch); 32 | var savelocation = path.join(options.output, hexfilename + '.hex'); 33 | // create write stream for entry file 34 | var ws = fs.createWriteStream(savelocation); 35 | //write file 36 | ws.write(hex); 37 | } 38 | }); 39 | } 40 | 41 | function handleInput(action, argz) { 42 | switch (action) { 43 | case 'compile': { 44 | if (!argz.s || !argz.a) { 45 | showHelp(); 46 | process.exit(1); 47 | // lets get rid of this for now until the board archs are settled on 48 | // } else if (boards.indexOf(argz.a) === -1) { 49 | // console.error(new Error('Oops! That board is not supported, sorry.')); 50 | // process.exit(1); 51 | } else { 52 | // run compile function here if all is well 53 | var options = { 54 | libraries: argz.l || [], 55 | sketch: argz.s, 56 | board: argz.a, 57 | version: argz.c || '', 58 | output: argz.o || './', 59 | debug: argz.v || false 60 | }; 61 | 62 | if (argz.b) { 63 | options.builder = { 64 | location: argz.b 65 | } 66 | } 67 | 68 | compile(options); 69 | } 70 | 71 | break; 72 | } 73 | 74 | case 'help': { 75 | showHelp(); 76 | process.exit(); 77 | break; 78 | } 79 | 80 | default: { 81 | // Invalid or no argument specified, show help and exit with an error status 82 | showHelp(); 83 | process.exit(9); 84 | break; 85 | } 86 | } 87 | } 88 | 89 | handleInput(userAction, argv); 90 | 91 | -------------------------------------------------------------------------------- /lib/boards.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'uno': 'uno', 3 | 'mega': 'mega:cpu=atmega2560', 4 | 'leonardo': 'leonardo', 5 | 'micro': 'micro', 6 | 'nano' : 'nano:cpu=atmega328', 7 | 'diecimila': 'diecimila', 8 | 'yun': 'yun', 9 | 'pro': 'pro', 10 | 'adkmega':'ADKmegaADK', 11 | 'esplora': 'esplora', 12 | 'mini': 'mini', 13 | 'ethernet': 'ethernet', 14 | 'fio': 'fio', 15 | 'bt':'bt', 16 | 'LilyPadUSB': 'LilyPadUSB', 17 | 'lilypad': 'lilypad', 18 | 'atmegang': 'atmegang', 19 | 'robotControl': 'robotControl', 20 | 'robotMotor': 'robotMotor', 21 | 'gemma': 'gemma' 22 | }; 23 | -------------------------------------------------------------------------------- /lib/packager.js: -------------------------------------------------------------------------------- 1 | var requestComp = require('./request'); 2 | var path = require('path'); 3 | var glob = require('glob'); 4 | var fs = require('fs'); 5 | var tar = require('tar-stream'); 6 | var async = require('async'); 7 | 8 | module.exports.prepare = function prepare(package, callback) { 9 | var libpaths = package.libraries || []; 10 | var sketchfile = package.sketch; 11 | var board = package.board || 'uno'; 12 | var version = package.version || '10609'; 13 | var service = package.service || null; 14 | 15 | // if user supplies a string path, just convert it into an array without burdening them with an error 16 | if (typeof libpaths === 'string') { 17 | libpaths = [libpaths]; 18 | } 19 | 20 | // create array of paths to iterate on 21 | // end result looks something like: 22 | // [ 23 | // ['/path/to/sketch/dir', 'sketch'], 24 | // ['/path/to/lib1', 'libs'], 25 | // ['/path/to/lib2', 'libs'] 26 | // ] 27 | // push sketch dir first 28 | var globPaths = [[path.dirname(sketchfile), 'sketch']]; 29 | // if there are libraries included, push them to list 30 | libpaths.forEach(function(lib) { 31 | globPaths.push([lib, 'libs']); 32 | }); 33 | 34 | // prepare a new tarball packing 35 | var pack = tar.pack(); 36 | 37 | // we def needs these top level dirs, let's guarantee that happens 38 | pack.entry({name: 'libs', type: 'directory'}); 39 | pack.entry({name: 'dist', type: 'directory'}); 40 | pack.entry({name: 'sketch', type: 'directory'}); 41 | 42 | async.each(globPaths, findAndPackDependencies, function(error) { 43 | if (error) return callback(error); 44 | 45 | // finally, pack the sketch file itself 46 | packSketch(sketchfile, function(error) { 47 | if (error) return callback(error); 48 | 49 | // we're done with the tarball 50 | pack.finalize(); 51 | 52 | return callback(error, pack); 53 | }); 54 | }); 55 | 56 | function findDependencies(location, callback) { 57 | var searchPath = location[0]; 58 | var destPath = location[1]; 59 | 60 | // look for needed files within library dir 61 | // TODO: look into changing root in options to full path 62 | glob("**/*+(.h|.cpp|.c|.hpp)", {ignore: '**/node_modules/**/*+(.h|.cpp|.c|.hpp)', cwd: searchPath, matchBase: true}, function(error, matches) { 63 | var error = null; 64 | if (!matches.length && destPath === 'libs') error = new Error('No library files found in supplied path: ' + searchPath); 65 | return callback(error, matches); 66 | }); 67 | } 68 | 69 | function packDependencies(matches, location, callback) { 70 | if (!matches.length) return callback(null); 71 | 72 | var basepath = location[0]; 73 | var destpath = location[1]; 74 | 75 | // save each file into the tarball pack 76 | matches.forEach(function(filepath, index, arr) { 77 | 78 | var libName = destpath === 'sketch' ? '' : path.basename(basepath); 79 | 80 | fs.readFile(path.join(basepath, filepath), {encoding: 'utf8'}, function(error, filecontent) { 81 | if (error) return callback(error); 82 | 83 | // pack file into tarball 84 | pack.entry({name: path.posix.join(destpath, libName, filepath)}, filecontent); 85 | 86 | // return async if we're done 87 | if (arr.length - 1 === index) return callback(null); 88 | 89 | }); 90 | }); 91 | } 92 | 93 | function findAndPackDependencies(location, callback) { 94 | // find files that we can pack into the tarball for compilation 95 | findDependencies(location, function(error, matches) { 96 | if (error) return callback(error); 97 | 98 | // send matching files to be packed into tarball 99 | packDependencies(matches, location, function(error) { 100 | return callback(error); 101 | }); 102 | }); 103 | } 104 | 105 | function packSketch(sketchfile, callback) { 106 | // save the main sketch file to a special filename that the compiler can look for 107 | fs.readFile(sketchfile, {encoding: 'utf8'}, function(error, sketchfile) { 108 | if (error) return callback(new Error(error.message)); 109 | 110 | pack.entry({name: path.posix.join('sketch', 'sketch.ino')}, sketchfile); 111 | 112 | return callback(null); 113 | }); 114 | } 115 | }; 116 | -------------------------------------------------------------------------------- /lib/request.js: -------------------------------------------------------------------------------- 1 | var https = require('https'); 2 | var http = require('http'); 3 | var querystring = require('querystring'); 4 | var path = require('path'); 5 | var fs = require('fs'); 6 | var zlib = require('zlib'); 7 | var boards = require('./boards'); 8 | 9 | module.exports.requestCompilation = function requestCompilation(package, callback) { 10 | var host = package.service ? package.service.host : 'avr.pizza'; 11 | var port = package.service ? package.service.port : 443; 12 | var method = (port === 443) ? https : http; 13 | 14 | var options = { 15 | hostname: host, 16 | path: '/compile/v1', 17 | port: port, 18 | method : 'POST', 19 | headers: { 20 | 'User-Agent': 'avrpizza-'+host, 21 | 'Accept': 'application/json', 22 | 'Content-Type': 'application/x-tar', 23 | 'Content-Encoding': 'gzip', 24 | 'X-Version': package.version ||'16800', 25 | 'X-Board': boards[package.board] || package.board, 26 | 'X-Manufacturer': package.manufacturer || 'arduino', 27 | 'X-Arch': package.arch || 'avr' 28 | } 29 | }; 30 | 31 | var postRequest = method.request(options, function(response) { 32 | 33 | var datastring = ''; 34 | 35 | response.on('data', function(d) { 36 | datastring += d; 37 | }); 38 | 39 | response.on('end', function() { 40 | // done 41 | var response = JSON.parse(datastring); 42 | var error = response.error ? new Error(response.error) : null; 43 | var result = response.data ? response : null; 44 | return callback(error, result); 45 | }); 46 | }); 47 | 48 | postRequest.on('error', function(e) { 49 | return callback(new Error('Something went wrong with the API request: '+e)); 50 | }); 51 | 52 | var gzip = zlib.createGzip(); 53 | package.files.pipe(gzip).pipe(postRequest); 54 | }; 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avr-pizza", 3 | "version": "0.3.5", 4 | "description": "bespoke, artisinal, avr-gcc precompiler in zzee air", 5 | "main": "avrpizza.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "bin": "bin/cli.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/noopkat/avr-pizza.git" 13 | }, 14 | "keywords": [ 15 | "avr", 16 | "gcc", 17 | "compiler", 18 | "api", 19 | "arduino" 20 | ], 21 | "author": "Suz Hinton", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/noopkat/avr-pizza/issues" 25 | }, 26 | "homepage": "https://github.com/noopkat/avr-pizza#readme", 27 | "dependencies": { 28 | "async": "^2.0.0-rc.6", 29 | "avrp-local": "^1.0.5", 30 | "glob": "^7.0.3", 31 | "minimist": "^1.2.0", 32 | "mkdirp": "^0.5.1", 33 | "node-uuid": "^1.4.7", 34 | "rimraf": "^2.5.2", 35 | "tar-stream": "^1.5.2" 36 | } 37 | } 38 | --------------------------------------------------------------------------------