From dba4db9a668e620e5d525cf585f1a12279eb6c3f Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Tue, 30 Jun 2015 18:41:10 +0100 Subject: [PATCH 1/8] programatic login --- .gitignore | 1 + lib/api.js | 5 +++++ lib/methods/login.js | 22 ++++++++++++++++++++++ lib/methods/logout.js | 4 ++++ 4 files changed, 32 insertions(+) create mode 100644 lib/api.js create mode 100644 lib/methods/login.js create mode 100644 lib/methods/logout.js diff --git a/.gitignore b/.gitignore index e9e966b..151dfd1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules *.swp +test.js diff --git a/lib/api.js b/lib/api.js new file mode 100644 index 0000000..a1dca11 --- /dev/null +++ b/lib/api.js @@ -0,0 +1,5 @@ + +module.exports = { + login: require('./methods/login.js'), + logout: require('./methods/logout.js') +} diff --git a/lib/methods/login.js b/lib/methods/login.js new file mode 100644 index 0000000..7fcf265 --- /dev/null +++ b/lib/methods/login.js @@ -0,0 +1,22 @@ +var helpers = require('../middleware/util/helpers.js') +var localCreds = require('../middleware/util/creds.js') + +module.exports = function (email, password, cb) { + var creds = new Promise(function (resolve, reject) { + helpers.fetchToken('https://surge.sh')(email, password, function(err, obj){ + if (err) reject(err); + else resolve(localCreds('https://surge.sh').set(obj.email, obj.token)) + }) + }) + + if (typeof cb === 'function') { + creds.then(function (c) { + cb(null, c) + }) + .catch(function (e) { + cb(e, null) + }) + } + + return creds +} diff --git a/lib/methods/logout.js b/lib/methods/logout.js new file mode 100644 index 0000000..2fe2f0a --- /dev/null +++ b/lib/methods/logout.js @@ -0,0 +1,4 @@ + +module.exports = function () { + +} From 0417c71f08fc350e0c8423d7c4619f4ce8da5eb2 Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Tue, 30 Jun 2015 19:51:40 +0100 Subject: [PATCH 2/8] logout, whoami, ready for deploy --- lib/api.js | 7 ++++++- lib/methods/deploy.js | 4 ++++ lib/methods/login.js | 5 +++-- lib/methods/logout.js | 3 ++- lib/methods/whoami.js | 5 +++++ 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 lib/methods/deploy.js create mode 100644 lib/methods/whoami.js diff --git a/lib/api.js b/lib/api.js index a1dca11..f83a4d3 100644 --- a/lib/api.js +++ b/lib/api.js @@ -1,5 +1,10 @@ module.exports = { + defaults: { + endpoint: 'https://surge.sh' + }, login: require('./methods/login.js'), - logout: require('./methods/logout.js') + logout: require('./methods/logout.js'), + whoami: require('./methods/whoami.js'), + deploy: require('./methods/deploy.js'), } diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js new file mode 100644 index 0000000..2fe2f0a --- /dev/null +++ b/lib/methods/deploy.js @@ -0,0 +1,4 @@ + +module.exports = function () { + +} diff --git a/lib/methods/login.js b/lib/methods/login.js index 7fcf265..de8b17a 100644 --- a/lib/methods/login.js +++ b/lib/methods/login.js @@ -2,10 +2,11 @@ var helpers = require('../middleware/util/helpers.js') var localCreds = require('../middleware/util/creds.js') module.exports = function (email, password, cb) { + var defaults = this.defaults; var creds = new Promise(function (resolve, reject) { - helpers.fetchToken('https://surge.sh')(email, password, function(err, obj){ + helpers.fetchToken(defaults.endpoint)(email, password, function(err, obj){ if (err) reject(err); - else resolve(localCreds('https://surge.sh').set(obj.email, obj.token)) + else resolve(localCreds(defaults.endpoint).set(obj.email, obj.token)) }) }) diff --git a/lib/methods/logout.js b/lib/methods/logout.js index 2fe2f0a..ff2a478 100644 --- a/lib/methods/logout.js +++ b/lib/methods/logout.js @@ -1,4 +1,5 @@ +var localCreds = require('../middleware/util/creds.js') module.exports = function () { - + localCreds(this.defaults.endpoint).set(null) } diff --git a/lib/methods/whoami.js b/lib/methods/whoami.js new file mode 100644 index 0000000..5f51316 --- /dev/null +++ b/lib/methods/whoami.js @@ -0,0 +1,5 @@ +var localCreds = require('../middleware/util/creds.js') + +module.exports = function () { + return localCreds(this.defaults.endpoint).get() +} From 526a8cd7d933eedcfad09df0961ff4392d231cf8 Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Tue, 30 Jun 2015 21:34:43 +0100 Subject: [PATCH 3/8] doesnt work yet --- lib/methods/deploy.js | 38 ++++++++++++++++++++++++++++++++- lib/methods/util/domainInfo.js | 18 ++++++++++++++++ lib/methods/util/projectInfo.js | 26 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 lib/methods/util/domainInfo.js create mode 100644 lib/methods/util/projectInfo.js diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js index 2fe2f0a..954ce03 100644 --- a/lib/methods/deploy.js +++ b/lib/methods/deploy.js @@ -1,4 +1,40 @@ +var projectInfo = require('./util/projectInfo.js') +var domainInfo = require('./util/domainInfo.js') +var surgePkg = require(__dirname + "/../../package.json").version -module.exports = function () { +module.exports = function (options, cb) { + + var opts = { + project: options.project || false, + token: options.token || false, + domain: options.domain || false, + add: options.add || false, + rem: options.rem || false, + build: options.build || false + } + + var cbIsFunction = (typeof cb === 'function') + + if (!opts.project && !opts.token) { + if (cbIsFunction) cb('You must pass in both a project dir and an auth token', null) + return false + } + + Promise.all([projectInfo(opts.project), domainInfo(opts.domain)]) + .then(function (values) { + + console.log(values) + + var headers = { + "version" : surgePkg.version, + "file-count": projInfo.fileCount, + "project-size": projInfo.projectSize + } + if (opts.add) headers['add'] = opts.add; + if (opts.rem) headers['rem'] = opts.rem; + if (opts.build) headers['build'] = opts.build; + if (false) headers['ssl'] = false; + + }) } diff --git a/lib/methods/util/domainInfo.js b/lib/methods/util/domainInfo.js new file mode 100644 index 0000000..7995591 --- /dev/null +++ b/lib/methods/util/domainInfo.js @@ -0,0 +1,18 @@ +var url = require('url') + +module.exports = function (domain) { + + var u = url.parse(domain) + var domainInfo = { + ssl: false, + domain: false + } + + if (u.protocol !== null) { + if (u.protocol == 'https:') domainInfo.ssl = true + if (u.protocol == 'http:') domainInfo.ssl = false + domainInfo.domain = u.hostname + } + + return domainInfo +} diff --git a/lib/methods/util/projectInfo.js b/lib/methods/util/projectInfo.js new file mode 100644 index 0000000..7f369fe --- /dev/null +++ b/lib/methods/util/projectInfo.js @@ -0,0 +1,26 @@ +var ignore = require("surge-ignore") +var fsReader = require('fstream-ignore') +var fs = require("fs") + +module.exports = function (project) { + return new Promise(function (resolve, reject) { + var projectSize = 0; + var fileCount = 0 + var project = fsReader({ 'path': project, ignoreFiles: [".surgeignore"] }) + project.addIgnoreRules(ignore) + + project.on("child", function (c) { + fs.lstat(c.path, function(err, stats) { + projectSize += stats.size + if (!stats.isDirectory()) fileCount++ + }) + }).on("close", function() { + resolve({ + projectSize: projectSize, + fileCount: fileCount + }) + }).on("error", function(e) { + reject(e) + }) + }) +} From 721c5fba76dbb4ba88568e21efb765fb448c6bad Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Tue, 30 Jun 2015 23:56:04 +0100 Subject: [PATCH 4/8] =?UTF-8?q?deploy=20works=20=F0=9F=91=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/methods/deploy.js | 64 ++++++++++++++++++++++++++++++--- lib/methods/util/domainInfo.js | 5 ++- lib/methods/util/projectInfo.js | 8 ++--- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js index 954ce03..cf2aa9e 100644 --- a/lib/methods/deploy.js +++ b/lib/methods/deploy.js @@ -1,9 +1,18 @@ var projectInfo = require('./util/projectInfo.js') var domainInfo = require('./util/domainInfo.js') -var surgePkg = require(__dirname + "/../../package.json").version +var surgePkg = require(__dirname + "/../../package.json") + +var url = require("url") +var request = require("request") +var fsReader = require('fstream-ignore') +var tar = require('tar') +var zlib = require('zlib') +var ignore = require("surge-ignore") +var split = require("split") module.exports = function (options, cb) { + var defaults = this.defaults var opts = { project: options.project || false, token: options.token || false, @@ -20,10 +29,10 @@ module.exports = function (options, cb) { return false } - Promise.all([projectInfo(opts.project), domainInfo(opts.domain)]) - .then(function (values) { + projectInfo(opts.project) + .then(function (projInfo) { - console.log(values) + var urlInfo = domainInfo(opts.domain); var headers = { "version" : surgePkg.version, @@ -33,7 +42,52 @@ module.exports = function (options, cb) { if (opts.add) headers['add'] = opts.add; if (opts.rem) headers['rem'] = opts.rem; if (opts.build) headers['build'] = opts.build; - if (false) headers['ssl'] = false; + if (urlInfo.ssl) headers['ssl'] = urlInfo.ssl; + + console.log(opts.domain, urlInfo) + + // create upload + var uri = url.resolve(defaults.endpoint, urlInfo.domain) + var handshake = request.put(uri, { headers: headers }) + + + // apply basic auth + handshake.auth("token", opts.token, true) + + // catch errors + handshake.on('error', console.log) + + // split replies on new line + handshake.pipe(split()) + + // output result + handshake.on("data", function (d) { + console.log(d) + }) + + // done + handshake.on("end", function () { + console.log('COMPLETE') + }) + + handshake.on("response", function(rsp){ + if (rsp.statusCode == 403) { + console.log(403) + } + }) + + // Read Project + var project = fsReader({ 'path': opts.project, ignoreFiles: [".surgeignore"] }) + + // we always ignore .git directory + project.addIgnoreRules(ignore) + + // chain all this together... + project + .pipe(tar.Pack()) + .pipe(zlib.Gzip()) + .pipe(handshake) + }) diff --git a/lib/methods/util/domainInfo.js b/lib/methods/util/domainInfo.js index 7995591..c2ff79b 100644 --- a/lib/methods/util/domainInfo.js +++ b/lib/methods/util/domainInfo.js @@ -1,11 +1,12 @@ var url = require('url') +var helpers = require('../../middleware/util/helpers.js') module.exports = function (domain) { var u = url.parse(domain) var domainInfo = { ssl: false, - domain: false + domain: domain } if (u.protocol !== null) { @@ -14,5 +15,7 @@ module.exports = function (domain) { domainInfo.domain = u.hostname } + if (!helpers.validDomain(domainInfo.domain)) domainInfo.domain = false + return domainInfo } diff --git a/lib/methods/util/projectInfo.js b/lib/methods/util/projectInfo.js index 7f369fe..1dddabc 100644 --- a/lib/methods/util/projectInfo.js +++ b/lib/methods/util/projectInfo.js @@ -2,11 +2,11 @@ var ignore = require("surge-ignore") var fsReader = require('fstream-ignore') var fs = require("fs") -module.exports = function (project) { +module.exports = function (path) { return new Promise(function (resolve, reject) { var projectSize = 0; var fileCount = 0 - var project = fsReader({ 'path': project, ignoreFiles: [".surgeignore"] }) + var project = fsReader({ 'path': path, ignoreFiles: [".surgeignore"] }) project.addIgnoreRules(ignore) project.on("child", function (c) { @@ -19,8 +19,8 @@ module.exports = function (project) { projectSize: projectSize, fileCount: fileCount }) - }).on("error", function(e) { - reject(e) + }).on("error", function (err) { + reject(err) }) }) } From b1f2727a234e33f4ccbcfb61bf6e221ce000c36e Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Tue, 7 Jul 2015 23:09:12 +0100 Subject: [PATCH 5/8] add event emitter, almost working --- lib/methods/deploy.js | 55 ++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js index cf2aa9e..8ed8397 100644 --- a/lib/methods/deploy.js +++ b/lib/methods/deploy.js @@ -1,6 +1,7 @@ var projectInfo = require('./util/projectInfo.js') var domainInfo = require('./util/domainInfo.js') var surgePkg = require(__dirname + "/../../package.json") +var EventEmitter = require('events').EventEmitter var url = require("url") var request = require("request") @@ -10,7 +11,7 @@ var zlib = require('zlib') var ignore = require("surge-ignore") var split = require("split") -module.exports = function (options, cb) { +module.exports = function (options) { var defaults = this.defaults var opts = { @@ -22,13 +23,40 @@ module.exports = function (options, cb) { build: options.build || false } - var cbIsFunction = (typeof cb === 'function') + var emitter = new EventEmitter(); - if (!opts.project && !opts.token) { - if (cbIsFunction) cb('You must pass in both a project dir and an auth token', null) - return false + var tick = function tick (d) { + + var payload; + + try { + payload = JSON.parse(tick.toString()) + } catch(e) { + return; + } + + if (payload.hasOwnProperty("type") && payload.type === "error") { + emitter.emit('error', payload.error) + } + + if (payload.hasOwnProperty("type") && payload.type === "users") { + // helpers.log("users:".grey, payload.users.join(", ")) + } + + if (payload.hasOwnProperty("type") && payload.type === "collect") { + emitter.emit('error', "Project requires the " + payload.plan.name + " plan. " + ("$" + (payload.plan.amount / 100) + "/mo") + " (cancel anytime).") + } + + emitter.emit('progress', { + file: payload.file, + percent: payload.written / payload.total, + written: payload.written, + total: payload.total, + payload: payload + }) } + projectInfo(opts.project) .then(function (projInfo) { @@ -44,35 +72,32 @@ module.exports = function (options, cb) { if (opts.build) headers['build'] = opts.build; if (urlInfo.ssl) headers['ssl'] = urlInfo.ssl; - console.log(opts.domain, urlInfo) - // create upload var uri = url.resolve(defaults.endpoint, urlInfo.domain) var handshake = request.put(uri, { headers: headers }) - // apply basic auth handshake.auth("token", opts.token, true) // catch errors - handshake.on('error', console.log) + handshake.on('error', function (e) { + emitter.emit('error', e) + }) // split replies on new line handshake.pipe(split()) // output result - handshake.on("data", function (d) { - console.log(d) - }) + handshake.on("data", tick) // done handshake.on("end", function () { - console.log('COMPLETE') + emitter.emit('end') }) handshake.on("response", function(rsp){ if (rsp.statusCode == 403) { - console.log(403) + emitter.emit('error', 'Aborted - you must be granted access to publish to, ' + urlInfo.domain) } }) @@ -91,4 +116,6 @@ module.exports = function (options, cb) { }) + return emitter + } From 594a67961d8e5ac4cc0910a2d6cb4ea413d39077 Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Thu, 9 Jul 2015 22:48:00 +0100 Subject: [PATCH 6/8] lol now progress is emitted --- lib/methods/deploy.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js index 8ed8397..cbfaec6 100644 --- a/lib/methods/deploy.js +++ b/lib/methods/deploy.js @@ -30,7 +30,7 @@ module.exports = function (options) { var payload; try { - payload = JSON.parse(tick.toString()) + payload = JSON.parse(d.toString()) } catch(e) { return; } @@ -44,16 +44,23 @@ module.exports = function (options) { } if (payload.hasOwnProperty("type") && payload.type === "collect") { - emitter.emit('error', "Project requires the " + payload.plan.name + " plan. " + ("$" + (payload.plan.amount / 100) + "/mo") + " (cancel anytime).") + emitter.emit('error', + "Project requires the " + + payload.plan.name + " plan. " + + ("$" + (payload.plan.amount / 100) + "/mo") + " (cancel anytime)." + ) } - emitter.emit('progress', { - file: payload.file, - percent: payload.written / payload.total, - written: payload.written, - total: payload.total, - payload: payload - }) + if (payload.hasOwnProperty("type") && payload.type === "progress") { + emitter.emit('progress', { + file: payload.file, + percent: payload.written / payload.total, + written: payload.written, + total: payload.total, + type: payload.id, + payload: payload + }) + } } From c01aad8aff3dc4c76e1425215bccf5367abdb0f1 Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Thu, 9 Jul 2015 22:54:00 +0100 Subject: [PATCH 7/8] stub for subscription output --- lib/methods/deploy.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js index cbfaec6..91c7e82 100644 --- a/lib/methods/deploy.js +++ b/lib/methods/deploy.js @@ -43,6 +43,10 @@ module.exports = function (options) { // helpers.log("users:".grey, payload.users.join(", ")) } + if (payload.hasOwnProperty("type") && payload.type === "subscription") { + // console.log(payload) + } + if (payload.hasOwnProperty("type") && payload.type === "collect") { emitter.emit('error', "Project requires the " + From d7e55e8398e245b5de481ad02a041257d6549f95 Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Thu, 9 Jul 2015 22:57:32 +0100 Subject: [PATCH 8/8] lol percent is out of one hundred --- lib/methods/deploy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/methods/deploy.js b/lib/methods/deploy.js index 91c7e82..0069c7c 100644 --- a/lib/methods/deploy.js +++ b/lib/methods/deploy.js @@ -58,7 +58,7 @@ module.exports = function (options) { if (payload.hasOwnProperty("type") && payload.type === "progress") { emitter.emit('progress', { file: payload.file, - percent: payload.written / payload.total, + percent: (payload.written / payload.total) * 100, written: payload.written, total: payload.total, type: payload.id,