From 726fd8d55f9732e02bc0c27922443660bc37aa1c Mon Sep 17 00:00:00 2001 From: Agent of User Date: Thu, 4 Apr 2019 09:00:47 -0400 Subject: [PATCH] feat: Add --help and parameterize CLI and library ipfs-deploy [options] path Pin path locally, upload to pinning service, and update DNS Positionals: path The path to deploy [string] [default: "./public/"] Options: --version Show version number [boolean] --help Show help [boolean] -D DON'T update Cloudflare DNS' TXT dnslink [boolean] [default: false] -o Open URL after deploying [boolean] [default: false] -p, --pinner Pinning services to which path will be uploaded [choices: "pinata", "infura"] [default: ["pinata","infura"]] -P DON'T pin remotely, only to local daemon (overrides -p) [boolean] [default: false] Examples: ipfs-deploy _site # Deploys path "_site" to pinata and infura, and updates cloudflare DNS ipfs-deploy -p infura -p pinata # Deploys path "./public/" to pinata and infura, and updates cloudflare DNS ipfs-deploy -p pinata static # Deploys path "static" ONLY to pinata and updates cloudflare DNS ipfs-deploy -D docs # Deploys path "docs" to pinata and infura, and DON'T update DNS --- bin/ipfs-deploy.js | 87 +++++++++++++++++++++++++++++++++++++++++++++- index.js | 66 ++++++++++++++++++++++++++--------- package-lock.json | 11 ++++-- package.json | 5 ++- 4 files changed, 149 insertions(+), 20 deletions(-) diff --git a/bin/ipfs-deploy.js b/bin/ipfs-deploy.js index 717d718..1a89eaa 100755 --- a/bin/ipfs-deploy.js +++ b/bin/ipfs-deploy.js @@ -1,5 +1,90 @@ #!/usr/bin/env node +const chalk = require('chalk') const deploy = require('../index') -deploy() +const argv = require('yargs') + .scriptName('ipfs-deploy') + .usage( + '$0 [options] path', + 'Pin path locally, upload to pinning service, and update DNS', + yargs => { + yargs + .positional('path', { + type: 'string', + default: './public/', + describe: 'The path to deploy', + }) + .options({ + D: { + type: 'boolean', + default: false, + describe: "DON'T update Cloudflare DNS' TXT dnslink", + }, + o: { + type: 'boolean', + default: false, + describe: 'Open URL after deploying', + }, + p: { + alias: 'pinner', + choices: ['pinata', 'infura'], + default: ['pinata', 'infura'], + describe: `Pinning services to which ${chalk.whiteBright( + 'path' + )} will be uploaded`, + }, + P: { + type: 'boolean', + default: false, + describe: + "DON'T pin remotely, only to local daemon (overrides -p)", + }, + }) + .example( + '$0 _site', + `# Deploys path "${chalk.whiteBright( + '_site' + )}" to ${chalk.whiteBright('pinata')} and ${chalk.whiteBright( + 'infura' + )}, and updates ${chalk.whiteBright('cloudflare')} DNS` + ) + .example( + '$0 -p infura -p pinata', + `# Deploys path "${chalk.whiteBright( + './public/' + )}" to ${chalk.whiteBright('pinata')} and ${chalk.whiteBright( + 'infura' + )}, and updates ${chalk.whiteBright('cloudflare')} DNS` + ) + .example( + '$0 -p pinata static', + `# Deploys path "${chalk.whiteBright( + 'static' + )}" ONLY to ${chalk.whiteBright( + 'pinata' + )} and updates ${chalk.whiteBright('cloudflare')} DNS` + ) + .example( + '$0 -D docs', + `# Deploys path "${chalk.whiteBright( + 'docs' + )}" to ${chalk.whiteBright('pinata')} and ${chalk.whiteBright( + 'infura' + )}, and ${chalk.whiteBright("DON'T")} update DNS` + ) + } + ) + .help().argv + +function main() { + deploy({ + updateDns: !argv.D, + open: argv.o, + // pinners: argv.p, TODO + // pinRemotely: !argv.P, TODO + publicDirPath: argv.path, + }) +} + +main() diff --git a/index.js b/index.js index e8bd0bb..f67cc47 100644 --- a/index.js +++ b/index.js @@ -5,10 +5,12 @@ const pinataSDK = require('@pinata/sdk') const got = require('got') const updateCloudflareDnslink = require('dnslink-cloudflare') const ora = require('ora') +const chalk = require('chalk') +const openUrl = require('open') require('dotenv').config() -async function updateDns(hash) { +async function doUpdateDns(hash) { const key = process.env.CF_API_KEY const email = process.env.CF_API_EMAIL const domain = process.env.SITE_DOMAIN @@ -16,7 +18,7 @@ async function updateDns(hash) { const spinner = ora() if (!key || !email || !domain || !hash) { - throw new Error('Missing information for updateDns()') + throw new Error('Missing information for doUpdateDns()') } const api = { @@ -31,17 +33,29 @@ async function updateDns(hash) { } try { - spinner.info('📡 Beaming new hash to DNS provider...') + spinner.info( + `📡 Beaming new hash to DNS provider ${chalk.whiteBright( + 'Cloudflare' + )}...` + ) const content = await updateCloudflareDnslink(api, opts) - spinner.succeed(`🙌 SUCCESS! Updated TXT ${opts.record} to ${content}.`) - spinner.succeed('🌐 Your website is deployed now :)') + spinner.succeed('🙌 SUCCESS!') + spinner.info(`Updated TXT ${chalk.whiteBright(opts.record)} to:`) + spinner.info(`${chalk.whiteBright(content)}.`) + spinner.succeed('🌐 Your website is deployed now.') } catch (err) { console.log(err) process.exit(1) } } -async function main() { +async function deploy({ + updateDns = true, + open = false, + // pinners = ['pinata', 'infura'], TODO + // pinRemotely = true, TODO + publicDirPath = 'public', +} = {}) { const ipfsBinAbsPath = which.sync('ipfs', { nothrow: true }) || which.sync('jsipfs', { nothrow: true }) @@ -57,17 +71,25 @@ async function main() { ipfsd.start([], (err2, ipfsClient) => { if (err2) throw err2 - spinner.succeed('📶 Connected.') + // spinner.succeed('📶 Connected.') + + spinner.info( + `💾 Adding and pinning ${chalk.blue(publicDirPath)} locally...` + ) - spinner.info('💾 Adding and pinning ./public/ locally...') ipfsClient.addFromFs( - 'public', + publicDirPath, { recursive: true }, (err3, localPinResult) => { - if (err3) throw err3 + if (err3) { + spinner.fail( + "☠ Couldn't connect to local ipfs daemon. Is it running?" + ) + throw err3 + } const { hash } = localPinResult[localPinResult.length - 1] - spinner.succeed(`🔗 Added locally as ${hash}.`) + spinner.succeed(`🔗 Added locally as ${chalk.green(hash)}.`) ipfsClient.id((err4, { addresses }) => { if (err4) throw err4 @@ -94,14 +116,22 @@ async function main() { process.env.PINATA_SECRET_API_KEY ) - spinner.info('📠 Requesting remote pin to pinata.cloud...') + spinner.info( + `📠 Requesting remote pin to ${chalk.whiteBright( + 'pinata.cloud' + )}...` + ) pinata .pinHashToIPFS(hash, pinataOptions) .then(async _pinataPinResult => { spinner.succeed("📌 It's pinned to Pinata now.") try { - spinner.info('📠 Requesting remote pin to infura.io...') + spinner.info( + `📠 Requesting remote pin to ${chalk.whiteBright( + 'infura.io' + )}.` + ) const infuraResponse = await got( `https://ipfs.infura.io:5001/api/v0/pin/add?arg=${hash}` + '&recursive=true' @@ -117,9 +147,13 @@ async function main() { } clipboardy.writeSync(hash) - spinner.succeed(`📋 Hash ${hash} copied to clipboard.`) + spinner.succeed( + `📋 Hash ${chalk.green(hash)} copied to clipboard.` + ) + + if (updateDns) doUpdateDns(hash) - updateDns(hash) + if (open) openUrl(`https://${process.env.SITE_DOMAIN}`) }) .catch(err5 => { throw err5 @@ -131,4 +165,4 @@ async function main() { }) } -module.exports = main +module.exports = deploy diff --git a/package-lock.json b/package-lock.json index 28b521f..cff6958 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12467,8 +12467,7 @@ "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" }, "isarray": { "version": "1.0.0", @@ -18328,6 +18327,14 @@ } } }, + "open": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.0.0.tgz", + "integrity": "sha512-/yb5mVZBz7mHLySMiSj2DcLtMBbFPJk5JBKEkHVZFxZAPzeg3L026O0T+lbdz1B2nyDnkClRSwRQJdeVUIF7zw==", + "requires": { + "is-wsl": "^1.1.0" + } + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", diff --git a/package.json b/package.json index 1545a8c..af98a3a 100644 --- a/package.json +++ b/package.json @@ -30,14 +30,17 @@ }, "dependencies": { "@pinata/sdk": "^1.0.16", + "chalk": "^2.4.2", "clipboardy": "^1.2.3", "dnslink-cloudflare": "^2.0.1", "dotenv": "^7.0.0", "got": "^9.6.0", "ipfs": "^0.35.0-rc.4", "ipfsd-ctl": "^0.42.1", + "open": "^6.0.0", "ora": "^3.4.0", - "which": "^1.3.1" + "which": "^1.3.1", + "yargs": "^13.2.2" }, "devDependencies": { "@semantic-release/changelog": "^3.0.2",