UNPKG

2.75 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3'use strict';
4
5const inspectFunction = require('inspect-function');
6const pipe = require('pipe-functions');
7const { callWithObject, fnParametersFromOptions } = require('./call-with-object');
8const cli = require('commander');
9
10function getFlattenedAPI(o, path = '', methods = {}) {
11 for (let prop of Object.getOwnPropertyNames(o)) {
12 if (o[prop].constructor === Function) {
13 let methodCall = path ? `${path}-${prop}` : prop;
14 methods[methodCall] = { method: o[prop] };
15
16 let functionParams = inspectFunction(o[prop]).parameters.names;
17 if (functionParams) {
18 methods[methodCall] = {
19 params: functionParams,
20 method: o[prop]
21 };
22 }
23 }
24 if (o[prop].constructor === Object) {
25 methods = getFlattenedAPI(o[prop], path ? `${path}-${prop}` : prop, methods);
26 }
27 }
28 return methods;
29}
30
31function methodExec(fn, params, pipes = {}) {
32 let pipeline = [];
33
34 if (pipes.before) {
35 pipeline.push(pipes.before);
36 }
37
38 // MAIN
39 pipeline.push((args) => {
40 let methodReturn = callWithObject(fn, args);
41 if (methodReturn && methodReturn.then) {
42 return methodReturn.then(data => data).catch(console.error);
43 } else {
44 return methodReturn;
45 }
46 });
47
48 if(pipes.after){
49 pipeline.push(pipes.after);
50 }
51
52 pipeline.push(console.log);
53 pipe(params, ...pipeline);
54}
55
56function main(moduleRef, options = {pipes: {}}) {
57 process.env.NODE_CLI = true;
58
59 let packageJson;
60 let moduleVersion;
61 let moduleAPI;
62
63 if (moduleRef.constructor === String) {
64 packageJson = require(`${moduleRef}/package.json`);
65 moduleAPI = require(`${moduleRef}/${packageJson.main}`);
66 moduleVersion = packageJson.version;
67 } else {
68 moduleAPI = moduleRef;
69 }
70
71 // console.log('process.argv', process.argv);
72 // return;
73 if (moduleAPI.constructor === Function) {
74 // Module is a Function :: TODO : Even being a function, it still can have properties and methods
75
76 const params = inspectFunction(moduleAPI).parameters.names;
77 params.forEach(param => {
78 cli.option(`--${param} [value]`);
79 });
80
81 cli.version(moduleVersion);
82 cli.usage(`<command> [options]`);
83 cli.parse(process.argv);
84
85 methodExec(moduleAPI, cli, options.pipes);
86
87 } else {
88 // Module is a set of methods within an Object Literal
89
90 const methods = getFlattenedAPI(moduleAPI);
91 Object.keys(methods).forEach(methodKey => {
92 let cmd = cli.command(`${methodKey}`);
93 methods[methodKey].params.forEach(param => cmd.option(`--${param} [option]`));
94 cmd.action(args => {
95 methodExec(methods[methodKey].method, args, options.pipes[methodKey] || options.pipes);
96 });
97 });
98
99 cli.version(moduleVersion);
100 cli.usage(`<command> [options]`);
101 cli.parse(process.argv);
102 if (!process.argv.slice(2).length) {
103 return cli.outputHelp();
104 }
105 }
106}
107
108module.exports = main;
\No newline at end of file