Comparing version 1.0.7 to 1.0.8
@@ -9,2 +9,3 @@ 'use strict'; | ||
const inquirer = require('inquirer'); | ||
const f = require('f'); | ||
@@ -15,2 +16,17 @@ const fs = require('fs'); | ||
const spawnSync = require('child_process').spawnSync; | ||
function deepAssign(o1, o2) { | ||
Object.keys(o2).forEach(k => { | ||
if ( | ||
o1[k] && o2[k] && | ||
typeof o1[k] === 'object' && typeof o2[k] === 'object' | ||
) { | ||
deepAssign(o1[k], o2[k]); | ||
} else { | ||
o1[k] = o2[k]; | ||
} | ||
}); | ||
} | ||
class CreateCommand extends Command { | ||
@@ -32,10 +48,10 @@ | ||
flags: { | ||
x: 'The default function name', | ||
n: 'No login - don\'t require an internet connection', | ||
w: 'Write over - overwrite the current directory contents' | ||
w: 'Write over - overwrite the current directory contents', | ||
t: 'Template - a stdlib service template to use' | ||
}, | ||
vflags: { | ||
'function': 'The default function name', | ||
'no-login': 'No login - don\'t require an internet connection', | ||
'write-over': 'Write over - overwrite the current directory contents' | ||
'write-over': 'Write over - overwrite the current directory contents', | ||
'template': 'Template - a stdlib service template to use' | ||
} | ||
@@ -50,5 +66,2 @@ }; | ||
let functionName = params.flags.x || params.vflags.function || []; | ||
functionName = functionName[0]; | ||
let host = params.flags.h ? params.flags.h[0] : 'https://api.polybit.com'; | ||
@@ -62,2 +75,5 @@ let port = params.flags.p && params.flags.p[0]; | ||
let extPkgName = (params.flags.t || params.vflags.template || [])[0]; | ||
let extPkg = null; | ||
if (!force && !Credentials.location(1)) { | ||
@@ -76,2 +92,7 @@ console.log(); | ||
console.log(); | ||
console.log(`Awesome! Let's create a ${chalk.bold.green('stdlib')} service!`); | ||
extPkgName && console.log(`We'll use the template ${chalk.bold.green(extPkgName)} to proceed.`); | ||
console.log(); | ||
let questions = []; | ||
@@ -86,9 +107,2 @@ | ||
functionName || questions.push({ | ||
name: 'functionName', | ||
type: 'input', | ||
default: '', | ||
message: 'Default Function Name' | ||
}); | ||
let login = []; | ||
@@ -115,3 +129,3 @@ !nologin && login.push((cb) => { | ||
name = name || promptResult.name; | ||
functionName = functionName || promptResult.functionName || 'main'; | ||
let functionName = 'main'; // set default function name | ||
let username; | ||
@@ -136,109 +150,180 @@ | ||
!fs.existsSync(username) && fs.mkdirSync(username); | ||
let servicePath = path.join(process.cwd(), username, name); | ||
let fPath = path.join(servicePath, 'f'); | ||
let functionPath; | ||
// Do template fetching... | ||
let extPkgCalls = []; | ||
if (fs.existsSync(servicePath)) { | ||
if (extPkgName) { | ||
if (!write) { | ||
console.log(`Fetching template ${chalk.bold.green(extPkgName)}...`); | ||
console.log(); | ||
console.log(); | ||
console.log(chalk.bold.red('Oops!')); | ||
console.log(); | ||
console.log(`The directory you're creating a stdlib project in already exists:`); | ||
console.log(` ${chalk.bold(servicePath)}`); | ||
console.log(); | ||
console.log(`Try removing the existing directory first.`); | ||
console.log(); | ||
console.log(`Use ${chalk.bold('lib create --write-over')} to override.`); | ||
console.log(); | ||
return callback(null); | ||
extPkgCalls = [ | ||
cb => { | ||
f(`stdlib/templates/package?name=${extPkgName}`)((err, result) => { | ||
cb(err, result); | ||
}); | ||
}, | ||
cb => { | ||
f(`stdlib/templates/files?name=${extPkgName}`)((err, result) => { | ||
cb(err, result); | ||
}); | ||
} | ||
]; | ||
} | ||
async.series(extPkgCalls, (err, results) => { | ||
if (err) { | ||
return callback(new Error(`Error retrieving template: ${extPkgName}`)); | ||
} | ||
} else { | ||
if (results.length === 2) { | ||
extPkg = { | ||
pkg: results[0], | ||
files: results[1] | ||
}; | ||
} | ||
fs.mkdirSync(servicePath); | ||
fs.mkdirSync(fPath); | ||
!fs.existsSync(username) && fs.mkdirSync(username); | ||
let servicePath = path.join(process.cwd(), username, name); | ||
let fPath = path.join(servicePath, 'f'); | ||
let functionPath; | ||
} | ||
if (fs.existsSync(servicePath)) { | ||
let directories = functionName.split('/'); | ||
for (let i = 0; i < directories.length; i++) { | ||
let relpath = path.join.apply(path, [fPath].concat(directories.slice(0, i + 1))); | ||
!fs.existsSync(relpath) && fs.mkdirSync(relpath); | ||
functionPath = relpath; | ||
} | ||
if (!write) { | ||
let json = { | ||
pkg: require(path.join(__dirname, '../templates/package.json')), | ||
func: require(path.join(__dirname, '../templates/f/function.json')) | ||
}; | ||
console.log(); | ||
console.log(chalk.bold.red('Oops!')); | ||
console.log(); | ||
console.log(`The directory you're creating a stdlib project in already exists:`); | ||
console.log(` ${chalk.bold(servicePath)}`); | ||
console.log(); | ||
console.log(`Try removing the existing directory first.`); | ||
console.log(); | ||
console.log(`Use ${chalk.bold('lib create --write-over')} to override.`); | ||
console.log(); | ||
return callback(null); | ||
json.pkg.name = name; | ||
json.pkg.author = user.username + (user.email ? ` <${user.email}>` : ''); | ||
json.pkg.main = ['f', functionName, 'index.js'].join('/'); | ||
json.pkg.stdlib.name = [username, name].join('/'); | ||
json.pkg.stdlib.defaultFunction = functionName; | ||
} | ||
fs.writeFileSync( | ||
path.join(servicePath, 'package.json'), | ||
JSON.stringify(json.pkg, null, 2) | ||
); | ||
} else { | ||
json.func.name = functionName; | ||
fs.mkdirSync(servicePath); | ||
fs.mkdirSync(fPath); | ||
fs.writeFileSync( | ||
path.join(functionPath, 'function.json'), | ||
JSON.stringify(json.func, null, 2) | ||
); | ||
} | ||
let files = { | ||
base: { | ||
copy: { | ||
'.gitignore': fs.readFileSync(path.join(__dirname, '../templates/gitignore')), | ||
'env.json': fs.readFileSync(path.join(__dirname, '../templates/env.json')) | ||
let directories = functionName.split('/'); | ||
for (let i = 0; i < directories.length; i++) { | ||
let relpath = path.join.apply(path, [fPath].concat(directories.slice(0, i + 1))); | ||
!fs.existsSync(relpath) && fs.mkdirSync(relpath); | ||
functionPath = relpath; | ||
} | ||
let json = { | ||
pkg: require(path.join(__dirname, '../templates/package.json')), | ||
func: require(path.join(__dirname, '../templates/f/function.json')) | ||
}; | ||
json.pkg.name = name; | ||
json.pkg.author = user.username + (user.email ? ` <${user.email}>` : ''); | ||
json.pkg.main = ['f', functionName, 'index.js'].join('/'); | ||
json.pkg.stdlib.name = [username, name].join('/'); | ||
json.pkg.stdlib.defaultFunction = functionName; | ||
// EXTERNAL: Assign package details | ||
if (extPkg && extPkg.pkg) { | ||
deepAssign(json.pkg, extPkg.pkg); | ||
} | ||
fs.writeFileSync( | ||
path.join(servicePath, 'package.json'), | ||
JSON.stringify(json.pkg, null, 2) | ||
); | ||
json.func.name = functionName; | ||
fs.writeFileSync( | ||
path.join(functionPath, 'function.json'), | ||
JSON.stringify(json.func, null, 2) | ||
); | ||
let files = { | ||
base: { | ||
copy: { | ||
'.gitignore': fs.readFileSync(path.join(__dirname, '../templates/gitignore')), | ||
'env.json': fs.readFileSync(path.join(__dirname, '../templates/env.json')) | ||
}, | ||
template: { | ||
'README.md': fs.readFileSync(path.join(__dirname, '../templates/README.md')).toString() | ||
} | ||
}, | ||
template: { | ||
'README.md': fs.readFileSync(path.join(__dirname, '../templates/README.md')).toString() | ||
func: { | ||
copy: { | ||
'index.js': fs.readFileSync(path.join(__dirname, '../templates/f/index.js')), | ||
} | ||
} | ||
}, | ||
func: { | ||
copy: { | ||
'index.js': fs.readFileSync(path.join(__dirname, '../templates/f/index.js')), | ||
}; | ||
let templateData = { | ||
username: username, | ||
service: name, | ||
func: functionName | ||
}; | ||
Object.keys(files.base.copy).forEach(filename => { | ||
fs.writeFileSync(path.join(servicePath, filename), files.base.copy[filename]) | ||
}); | ||
Object.keys(files.base.template).forEach(filename => { | ||
let template = files.base.template[filename]; | ||
Object.keys(templateData).forEach(k => { | ||
template = template.replace(new RegExp(`\{\{${k}\}\}`, 'gi'), templateData[k]); | ||
}); | ||
fs.writeFileSync(path.join(servicePath, filename), template); | ||
}); | ||
Object.keys(files.func.copy).forEach(filename => { | ||
fs.writeFileSync(path.join(functionPath, filename), files.func.copy[filename]) | ||
}); | ||
// EXTERNAL: Unzip tar | ||
if (extPkg && extPkg.files && extPkg.files.length) { | ||
let tmpPath = `/tmp/stdlib-addon.tgz`; | ||
fs.existsSync(tmpPath) && fs.unlinkSync(tmpPath); | ||
fs.writeFileSync(tmpPath, extPkg.files); | ||
let command = spawnSync('tar', `-xzf ${tmpPath} -C ${servicePath}`.split(' '), {stdio: [0, 1, 2]}); | ||
if (command.status !== 0) { | ||
console.log(chalk.bold.yellow('Warn: ') + 'Error extracting addon package files'); | ||
} | ||
fs.unlinkSync(tmpPath); | ||
} | ||
}; | ||
let templateData = { | ||
username: username, | ||
service: name, | ||
func: functionName | ||
}; | ||
if ( | ||
(json.pkg.depenencies && Object.keys(json.pkg.dependencies).length) || | ||
(json.pkg.devDependencies && Object.keys(json.pkg.devDependencies).length) | ||
) { | ||
console.log(`Installing npm packages...`); | ||
console.log(); | ||
let command = spawnSync('npm', ['install'], {stdio: [0, 1, 2], cwd: servicePath}); | ||
if (command.status !== 0) { | ||
console.log(chalk.bold.yellow('Warn: ') + 'Error with npm install'); | ||
} | ||
} | ||
Object.keys(files.base.copy).forEach(filename => { | ||
fs.writeFileSync(path.join(servicePath, filename), files.base.copy[filename]) | ||
}); | ||
console.log(chalk.bold.green('Success!')); | ||
console.log(); | ||
console.log(`Service ${chalk.bold([username, name].join('/'))} created at:`); | ||
console.log(` ${chalk.bold(servicePath)}`); | ||
console.log(); | ||
console.log(`Use the following to enter your service directory:`); | ||
console.log(` ${chalk.bold('cd ' + [username, name].join('/'))}`); | ||
console.log(); | ||
console.log(`Type ${chalk.bold('lib help')} for more commands.`); | ||
console.log(); | ||
return callback(null); | ||
Object.keys(files.base.template).forEach(filename => { | ||
let template = files.base.template[filename]; | ||
Object.keys(templateData).forEach(k => { | ||
template = template.replace(new RegExp(`\{\{${k}\}\}`, 'gi'), templateData[k]); | ||
}); | ||
fs.writeFileSync(path.join(servicePath, filename), template); | ||
}); | ||
Object.keys(files.func.copy).forEach(filename => { | ||
fs.writeFileSync(path.join(functionPath, filename), files.func.copy[filename]) | ||
}); | ||
console.log(); | ||
console.log(chalk.bold.green('Success!')); | ||
console.log(); | ||
console.log(`Service ${chalk.bold([username, name].join('/'))} created at:`); | ||
console.log(` ${chalk.bold(servicePath)}`); | ||
console.log(); | ||
return callback(null); | ||
}); | ||
@@ -245,0 +330,0 @@ |
@@ -7,2 +7,3 @@ 'use strict'; | ||
const parser = require('../parser.js'); | ||
const scripts = require('../scripts.js'); | ||
@@ -40,2 +41,4 @@ class HTTPCommand extends Command { | ||
scripts.run(pkg, '+http'); | ||
if (!offline) { | ||
@@ -42,0 +45,0 @@ parser.check(err => parser.createServer(pkg, port, !!err)); |
@@ -6,9 +6,12 @@ 'use strict'; | ||
const Credentials = require('../credentials.js'); | ||
const scripts = require('../scripts.js'); | ||
const fs = require('fs'); | ||
const async = require('async'); | ||
const tar = require('tar-stream'); | ||
const zlib = require('zlib'); | ||
const path = require('path'); | ||
const async = require('async'); | ||
const tar = require('tar-stream'); | ||
function readFiles(base, properties, dir, data) { | ||
@@ -122,53 +125,45 @@ | ||
let resource = new APIResource(host, port); | ||
resource.authorize(Credentials.read('ACCESS_TOKEN')); | ||
scripts.run(pkg, 'preup', err => { | ||
!fs.existsSync('/tmp') && fs.mkdirSync('/tmp'); | ||
!fs.existsSync('/tmp/stdlib') && fs.mkdirSync('/tmp/stdlib'); | ||
let tmpPath = `/tmp/stdlib/${pkg.stdlib.name.replace(/\//g, '.')}.${new Date().valueOf()}.tar.gz`; | ||
if (err) { | ||
return callback(err); | ||
} | ||
let start = new Date().valueOf(); | ||
let resource = new APIResource(host, port); | ||
resource.authorize(Credentials.read('ACCESS_TOKEN')); | ||
let tarball = fs.createWriteStream(tmpPath); | ||
!fs.existsSync('/tmp') && fs.mkdirSync('/tmp'); | ||
!fs.existsSync('/tmp/stdlib') && fs.mkdirSync('/tmp/stdlib'); | ||
let tmpPath = `/tmp/stdlib/${pkg.stdlib.name.replace(/\//g, '.')}.${new Date().valueOf()}.tar.gz`; | ||
let pack = tar.pack(); | ||
let start = new Date().valueOf(); | ||
let data = readFiles( | ||
process.cwd(), | ||
{ | ||
ignore: [ | ||
'/node_modules', | ||
'/.stdlib', | ||
'/.git', | ||
'.DS_Store', | ||
] | ||
} | ||
); | ||
let tarball = fs.createWriteStream(tmpPath); | ||
// pipe the pack stream to your file | ||
pack.pipe(tarball); | ||
let pack = tar.pack(); | ||
// Run everything in parallel... | ||
async.parallel(data.map((file) => { | ||
return (callback) => { | ||
pack.entry({name: file.filename}, file.buffer, callback); | ||
}; | ||
}), (err) => { | ||
if (err) { | ||
return callback(err); | ||
let defignore = ['/node_modules', '/.stdlib', '/.git', '.DS_Store']; | ||
let libignore = fs.existsSync('.libignore') ? fs.readFileSync('.libignore').toString() : ''; | ||
libignore = libignore.split('\n').map(v => v.replace(/^\s(.*)\s$/, '$1')).filter(v => v); | ||
while (defignore.length) { | ||
let ignore = defignore.pop(); | ||
(libignore.indexOf(ignore) === -1) && libignore.push(ignore); | ||
} | ||
pack.finalize(); | ||
let data = readFiles( | ||
process.cwd(), | ||
{ignore: libignore} | ||
); | ||
}); | ||
// pipe the pack stream to your file | ||
pack.pipe(tarball); | ||
tarball.on('close', () => { | ||
// Run everything in parallel... | ||
let buffer = fs.readFileSync(tmpPath); | ||
fs.unlinkSync(tmpPath); | ||
async.parallel(data.map((file) => { | ||
return (callback) => { | ||
pack.entry({name: file.filename}, file.buffer, callback); | ||
}; | ||
}), (err) => { | ||
zlib.gzip(buffer, (err, result) => { | ||
if (err) { | ||
@@ -178,31 +173,48 @@ return callback(err); | ||
let t = new Date().valueOf() - start; | ||
// console.log(`Service "${pkg.stdlib.name}" compressed in ${t}ms.`); | ||
// console.log(`File size: ${result.length} bytes`); | ||
pack.finalize(); | ||
let endpoint = environment ? | ||
`${pkg.stdlib.name}@${environment}` : | ||
`${pkg.stdlib.name}@${pkg.version}`; | ||
}); | ||
return resource.request(endpoint).stream( | ||
'POST', | ||
result, | ||
(data) => { | ||
data.length > 1 && process.stdout.write(data.toString()); | ||
}, | ||
(err, response) => { | ||
tarball.on('close', () => { | ||
if (err) { | ||
return callback(err); | ||
} | ||
let buffer = fs.readFileSync(tmpPath); | ||
fs.unlinkSync(tmpPath); | ||
if (response[response.length - 1] === 1) { | ||
return callback(new Error('There was an error processing your request')); | ||
} else { | ||
return callback(null); | ||
} | ||
zlib.gzip(buffer, (err, result) => { | ||
if (err) { | ||
return callback(err); | ||
} | ||
); | ||
let t = new Date().valueOf() - start; | ||
// console.log(`Service "${pkg.stdlib.name}" compressed in ${t}ms.`); | ||
// console.log(`File size: ${result.length} bytes`); | ||
let endpoint = environment ? | ||
`${pkg.stdlib.name}@${environment}` : | ||
`${pkg.stdlib.name}@${pkg.version}`; | ||
return resource.request(endpoint).stream( | ||
'POST', | ||
result, | ||
(data) => { | ||
data.length > 1 && process.stdout.write(data.toString()); | ||
}, | ||
(err, response) => { | ||
if (err) { | ||
return callback(err); | ||
} | ||
if (response[response.length - 1] === 1) { | ||
return callback(new Error('There was an error processing your request')); | ||
} else { | ||
return callback(null); | ||
} | ||
} | ||
); | ||
}); | ||
}); | ||
@@ -209,0 +221,0 @@ |
@@ -83,3 +83,11 @@ #!/usr/bin/env node | ||
} | ||
console.log(response); | ||
if (response === null) { | ||
console.log(response); | ||
} else if (response instanceof Buffer) { | ||
console.log(response.toString()); | ||
} else if (typeof response === 'object') { | ||
console.log(JSON.stringify(response, null, 2)); | ||
} else { | ||
console.log(response); | ||
} | ||
}); |
// Uses stdlib reflect service to parse args, kwargs | ||
const https = require('https'); | ||
const http = require('http'); | ||
const path = require('path'); | ||
const url = require('url'); | ||
const fs = require('fs'); | ||
const f = require('f'); | ||
f.config.cache = false; | ||
// set env | ||
let env = {}; | ||
if (fs.existsSync(path.join(process.cwd(), 'env.json'))) { | ||
env = require(path.join(process.cwd(), 'env.json')).dev || {}; | ||
} | ||
// Disable caching of functions for hot reloading | ||
f.config.local.cache = false; | ||
const chalk = require('chalk'); | ||
@@ -36,6 +46,6 @@ | ||
console.log(`Request to .${pathname}`); | ||
let response = (err, params) => { | ||
console.log(`[function: ${pathname}] ${JSON.stringify({args: params.args, kwargs: params.kwargs})}`); | ||
if (err) { | ||
@@ -47,4 +57,12 @@ res.writeHead(400, {'Content-Type': 'text/plain'}); | ||
let fn = f(`.${pathname}`); | ||
fn.apply(null, params.args.concat(params.kwargs, (err, result) => { | ||
// FIXME: Async will not have fun with this. Run in new context. | ||
let oldenv = process.env; | ||
process.env = env; | ||
fn.apply(null, params.args.concat(params.kwargs, (err, result, headers) => { | ||
// FIXME: Reset process.env | ||
process.env = oldenv; | ||
if (err) { | ||
@@ -54,3 +72,3 @@ res.writeHead(400, {'Content-Type': 'text/plain'}); | ||
} else { | ||
res.writeHead(200, {'Content-Type': 'text/plain'}); | ||
res.writeHead(200, headers); | ||
if (result instanceof Buffer || typeof result !== 'object') { | ||
@@ -81,3 +99,5 @@ res.end(result); | ||
server.listen(port); | ||
console.log(`HTTP development server listening for service ${chalk.bold(serviceName)} on port ${chalk.bold(port)}`); | ||
console.log(); | ||
console.log(`HTTP development server listening for service ${chalk.bold.green(serviceName)} on port ${chalk.bold(port)}`); | ||
console.log(); | ||
@@ -84,0 +104,0 @@ }, |
{ | ||
"name": "lib", | ||
"version": "1.0.7", | ||
"version": "1.0.8", | ||
"description": "Standard Library for Microservices", | ||
@@ -37,4 +37,4 @@ "main": "index.js", | ||
"tar-stream": "^1.5.2", | ||
"f": "1.1.0" | ||
"f": "1.2.2" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
84510
35
1903
32
6