Skip to content
This repository has been archived by the owner on Sep 12, 2019. It is now read-only.

Commit

Permalink
intentionally use blank prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
sw-yx committed Apr 4, 2019
1 parent 11eb304 commit d1f587f
Show file tree
Hide file tree
Showing 38 changed files with 1,111 additions and 897 deletions.
6 changes: 1 addition & 5 deletions .prettierrc.json
@@ -1,5 +1 @@
{
"semi": false,
"singleQuote": true,
"printWidth": 120
}
{}
27 changes: 15 additions & 12 deletions src/commands/dev/exec.js
@@ -1,25 +1,28 @@
const execa = require('execa')
const Command = require('@netlify/cli-utils')
const execa = require("execa");
const Command = require("@netlify/cli-utils");

class ExecCommand extends Command {
async run() {
const { site } = this.netlify
const { site } = this.netlify;
if (site.id) {
const accessToken = await this.authenticate()
const { addEnvVarsFromAddons } = require('../../utils/dev-exec')
await addEnvVarsFromAddons(site, accessToken)
const accessToken = await this.authenticate();
const { addEnvVarsFromAddons } = require("../../utils/dev-exec");
await addEnvVarsFromAddons(site, accessToken);
}
execa(this.argv[0], this.argv.slice(1), { env: process.env, stdio: 'inherit' })
execa(this.argv[0], this.argv.slice(1), {
env: process.env,
stdio: "inherit"
});
}
}

ExecCommand.description = `Exec command
Runs a command within the netlify dev environment, e.g. with env variables from any installed addons
`
`;

ExecCommand.examples = ['$ netlify exec npm run bootstrap']
ExecCommand.examples = ["$ netlify exec npm run bootstrap"];

ExecCommand.strict = false
ExecCommand.parse = false
ExecCommand.strict = false;
ExecCommand.parse = false;

module.exports = ExecCommand
module.exports = ExecCommand;
242 changes: 139 additions & 103 deletions src/commands/dev/index.js
@@ -1,204 +1,240 @@
const { flags } = require('@oclif/command')
const execa = require('execa')
const http = require('http')
const httpProxy = require('http-proxy')
const waitPort = require('wait-port')
const getPort = require('get-port')
const { serveFunctions } = require('@netlify/zip-it-and-ship-it')
const { serverSettings } = require('../../detect-server')
const Command = require('@netlify/cli-utils')
const { getAddons } = require('netlify/src/addons')
const { track } = require('@netlify/cli-utils/src/utils/telemetry')
const chalk = require('chalk')
const boxen = require('boxen')
const { createTunnel, connectTunnel } = require('../../live-tunnel')
const { flags } = require("@oclif/command");
const execa = require("execa");
const http = require("http");
const httpProxy = require("http-proxy");
const waitPort = require("wait-port");
const getPort = require("get-port");
const { serveFunctions } = require("@netlify/zip-it-and-ship-it");
const { serverSettings } = require("../../detect-server");
const Command = require("@netlify/cli-utils");
const { getAddons } = require("netlify/src/addons");
const { track } = require("@netlify/cli-utils/src/utils/telemetry");
const chalk = require("chalk");
const boxen = require("boxen");
const { createTunnel, connectTunnel } = require("../../live-tunnel");

function isFunction(settings, req) {
return settings.functionsPort && req.url.match(/^\/.netlify\/functions\/.+/)
return settings.functionsPort && req.url.match(/^\/.netlify\/functions\/.+/);
}

function addonUrl(addonUrls, req) {
const m = req.url.match(/^\/.netlify\/([^\/]+)(\/.*)/)
const addonUrl = m && addonUrls[m[1]]
return addonUrl ? `${addonUrl}${m[2]}` : null
const m = req.url.match(/^\/.netlify\/([^\/]+)(\/.*)/);
const addonUrl = m && addonUrls[m[1]];
return addonUrl ? `${addonUrl}${m[2]}` : null;
}

async function startProxy(settings, addonUrls) {
const rulesProxy = require('@netlify/rules-proxy')
const rulesProxy = require("@netlify/rules-proxy");

await waitPort({ port: settings.proxyPort })
await waitPort({ port: settings.proxyPort });
if (settings.functionsPort) {
await waitPort({ port: settings.functionsPort })
await waitPort({ port: settings.functionsPort });
}
const port = await getPort({ port: settings.port })
const functionsServer = settings.functionsPort ? `http://localhost:${settings.functionsPort}` : null
const port = await getPort({ port: settings.port });
const functionsServer = settings.functionsPort
? `http://localhost:${settings.functionsPort}`
: null;

const proxy = httpProxy.createProxyServer({
target: {
host: 'localhost',
host: "localhost",
port: settings.proxyPort
}
})
});

const rewriter = rulesProxy({ publicFolder: settings.dist })
const rewriter = rulesProxy({ publicFolder: settings.dist });

const server = http.createServer(function(req, res) {
if (isFunction(settings, req)) {
return proxy.web(req, res, { target: functionsServer })
return proxy.web(req, res, { target: functionsServer });
}
let url = addonUrl(addonUrls, req)
let url = addonUrl(addonUrls, req);
if (url) {
return proxy.web(req, res, { target: url })
return proxy.web(req, res, { target: url });
}

rewriter(req, res, () => {
if (isFunction(settings, req)) {
return proxy.web(req, res, { target: functionsServer })
return proxy.web(req, res, { target: functionsServer });
}
url = addonUrl(addonUrls, req)
url = addonUrl(addonUrls, req);
if (url) {
return proxy.web(req, res, { target: url })
return proxy.web(req, res, { target: url });
}

proxy.web(req, res, { target: `http://localhost:${settings.proxyPort}` })
})
})
proxy.web(req, res, { target: `http://localhost:${settings.proxyPort}` });
});
});

server.on('upgrade', function(req, socket, head) {
proxy.ws(req, socket, head)
})
server.on("upgrade", function(req, socket, head) {
proxy.ws(req, socket, head);
});

server.listen(port)
return `http://localhost:${port}`
server.listen(port);
return `http://localhost:${port}`;
}

function startDevServer(settings, log, error) {
if (settings.noCmd) {
const StaticServer = require('static-server')
const StaticServer = require("static-server");
if (!settings.dist) {
log(
'Unable to determine public folder for the dev server.\nSetup a netlify.toml file with a [dev] section to specify your dev server settings.'
)
process.exit(1)
"Unable to determine public folder for the dev server.\nSetup a netlify.toml file with a [dev] section to specify your dev server settings."
);
process.exit(1);
}

const server = new StaticServer({
rootPath: settings.dist,
name: 'netlify-dev',
name: "netlify-dev",
port: settings.proxyPort,
templates: {
notFound: '404.html'
notFound: "404.html"
}
})
});

server.start(function() {
log('Server listening to', settings.proxyPort)
})
return
log("Server listening to", settings.proxyPort);
});
return;
} else {
log(`Starting netlify dev with ${settings.type}`)
const ps = execa(settings.command, settings.args, { env: settings.env, stdio: 'inherit', shell: true })
ps.on('close', code => process.exit(code))
ps.on('SIGINT', process.exit)
ps.on('SIGTERM', process.exit)
log(`Starting netlify dev with ${settings.type}`);
const ps = execa(settings.command, settings.args, {
env: settings.env,
stdio: "inherit",
shell: true
});
ps.on("close", code => process.exit(code));
ps.on("SIGINT", process.exit);
ps.on("SIGTERM", process.exit);
}
}

class DevCommand extends Command {
async run() {
const { flags, args } = this.parse(DevCommand)
const { api, site, config } = this.netlify
const { flags, args } = this.parse(DevCommand);
const { api, site, config } = this.netlify;
const functionsDir =
flags.functions || (config.dev && config.dev.functions) || (config.build && config.build.functions)
const addonUrls = {}
flags.functions ||
(config.dev && config.dev.functions) ||
(config.build && config.build.functions);
const addonUrls = {};

let accessToken = api.accessToken
let accessToken = api.accessToken;
if (site.id && !flags.offline) {
accessToken = await this.authenticate()
const addons = await getAddons(site.id, accessToken)
accessToken = await this.authenticate();
const addons = await getAddons(site.id, accessToken);
if (Array.isArray(addons)) {
addons.forEach(addon => {
addonUrls[addon.slug] = `${addon.config.site_url}/.netlify/${addon.slug}`
addonUrls[addon.slug] = `${addon.config.site_url}/.netlify/${
addon.slug
}`;
for (const key in addon.env) {
process.env[key] = process.env[key] || addon.env[key]
process.env[key] = process.env[key] || addon.env[key];
}
})
});
}
const api = this.netlify.api
const apiSite = await api.getSite({ site_id: site.id })
const api = this.netlify.api;
const apiSite = await api.getSite({ site_id: site.id });
// TODO: We should move the environment outside of build settings and possibly have a
// `/api/v1/sites/:site_id/environment` endpoint for it that we can also gate access to
// In the future and that we could make context dependend
if (apiSite.build_settings && apiSite.build_settings.env) {
for (const key in apiSite.build_settings.env) {
process.env[key] = process.env[key] || apiSite.build_settings.env[key]
process.env[key] =
process.env[key] || apiSite.build_settings.env[key];
}
}
}
process.env.NETLIFY_DEV = 'true'
process.env.NETLIFY_DEV = "true";

let settings = serverSettings(config.dev)
let settings = serverSettings(config.dev);
if (!(settings && settings.command)) {
this.log('No dev server detected, using simple static server')
const dist = (config.dev && config.dev.publish) || (config.build && config.build.publish)
this.log("No dev server detected, using simple static server");
const dist =
(config.dev && config.dev.publish) ||
(config.build && config.build.publish);
settings = {
noCmd: true,
port: 8888,
proxyPort: 3999,
dist
}
};
}

let url;
if (flags.live) {
const liveSession = await createTunnel(site.id, accessToken, this.log)
url = liveSession.session_url
process.env.BASE_URL = url

await connectTunnel(liveSession, accessToken, settings.port, this.log, this.error)
const liveSession = await createTunnel(site.id, accessToken, this.log);
url = liveSession.session_url;
process.env.BASE_URL = url;

await connectTunnel(
liveSession,
accessToken,
settings.port,
this.log,
this.error
);
}

startDevServer(settings, this.log, this.error)
startDevServer(settings, this.log, this.error);

if (functionsDir) {
const fnSettings = await serveFunctions({ ...settings, functionsDir })
settings.functionsPort = fnSettings.port
const fnSettings = await serveFunctions({ ...settings, functionsDir });
settings.functionsPort = fnSettings.port;
}

const proxyUrl = await startProxy(settings, addonUrls)
const proxyUrl = await startProxy(settings, addonUrls);
if (!url) {
url = proxyUrl
url = proxyUrl;
}
// Todo hoist this telemetry `command` to CLI hook
track('command', {
command: 'dev',
projectType: settings.type || 'custom'
})

const banner = chalk.bold(`Netlify dev server is now ready on ${url}`)
this.log(boxen(banner, { padding: 1, margin: 1, align: 'center', borderColor: '#00c7b7' }))
track("command", {
command: "dev",
projectType: settings.type || "custom"
});

const banner = chalk.bold(`Netlify dev server is now ready on ${url}`);
this.log(
boxen(banner, {
padding: 1,
margin: 1,
align: "center",
borderColor: "#00c7b7"
})
);
}
}

DevCommand.description = `Local dev server
The dev command will run a local dev server with Netlify's proxy and redirect rules
`
`;

DevCommand.examples = ['$ netlify dev', '$ netlify dev -c "yarn start"', '$ netlify dev -c hugo']
DevCommand.examples = [
"$ netlify dev",
'$ netlify dev -c "yarn start"',
"$ netlify dev -c hugo"
];

DevCommand.strict = false
DevCommand.strict = false;

DevCommand.flags = {
cmd: flags.string({ char: 'c', description: 'command to run' }),
cmd: flags.string({ char: "c", description: "command to run" }),
devport: flags.integer({
char: 'd',
description: 'port of the dev server started by command'
char: "d",
description: "port of the dev server started by command"
}),
port: flags.integer({ char: 'p', description: 'port of netlify dev' }),
dir: flags.integer({ char: 'd', description: 'dir with static files' }),
functions: flags.string({ char: 'f', description: 'Specify a functions folder to serve' }),
offline: flags.boolean({ char: 'o', description: 'disables any features that require network access' }),
live: flags.boolean({char: 'l', description: 'Start a public live session'})
}
port: flags.integer({ char: "p", description: "port of netlify dev" }),
dir: flags.integer({ char: "d", description: "dir with static files" }),
functions: flags.string({
char: "f",
description: "Specify a functions folder to serve"
}),
offline: flags.boolean({
char: "o",
description: "disables any features that require network access"
}),
live: flags.boolean({ char: "l", description: "Start a public live session" })
};

module.exports = DevCommand
module.exports = DevCommand;

0 comments on commit d1f587f

Please sign in to comment.