UNPKG

5.51 kBJavaScriptView Raw
1var Parameter, Signature, _, appearedMoreThanOnce, async, isLastOne, parse, settings, utils;
2
3_ = require('lodash');
4
5_.str = require('underscore.string');
6
7async = require('async');
8
9Parameter = require('./parameter');
10
11settings = require('./settings');
12
13parse = require('./parse');
14
15utils = require('./utils');
16
17isLastOne = function(parameters, predicate) {
18 var lastParameter;
19 lastParameter = _.last(parameters);
20 return predicate(lastParameter);
21};
22
23appearedMoreThanOnce = function(parameters, predicate) {
24 var filteredParameters;
25 filteredParameters = _.filter(parameters, predicate);
26 return filteredParameters.length > 1;
27};
28
29module.exports = Signature = (function() {
30 function Signature(signature) {
31 var isStdin, isVariadic;
32 if ((signature == null) || !_.isString(signature)) {
33 throw new Error('Missing or invalid signature');
34 }
35 this.parameters = [];
36 _.each(parse.split(signature), this._addParameter, this);
37 if (this.allowsStdin()) {
38 isStdin = function(parameter) {
39 return parameter.allowsStdin();
40 };
41 if (appearedMoreThanOnce(this.parameters, isStdin)) {
42 throw new Error('Signature can only contain one stdin parameter');
43 }
44 if (!isLastOne(this.parameters, isStdin)) {
45 throw new Error('The stdin parameter should be the last one');
46 }
47 }
48 if (this.hasVariadicParameters()) {
49 isVariadic = function(parameter) {
50 return parameter.isVariadic();
51 };
52 if (appearedMoreThanOnce(this.parameters, isVariadic)) {
53 throw new Error('Signature can only contain one variadic parameter');
54 }
55 if (!isLastOne(this.parameters, isVariadic)) {
56 throw new Error('The variadic parameter should be the last one');
57 }
58 }
59 }
60
61 Signature.prototype._addParameter = function(word) {
62 var parameter;
63 parameter = new Parameter(word);
64 return this.parameters.push(parameter);
65 };
66
67 Signature.prototype.hasParameters = function() {
68 return _.any(this.parameters, function(parameter) {
69 return !parameter.isWord();
70 });
71 };
72
73 Signature.prototype.hasVariadicParameters = function() {
74 return _.any(this.parameters, function(parameter) {
75 return parameter.isVariadic();
76 });
77 };
78
79 Signature.prototype.allowsStdin = function() {
80 return _.any(this.parameters, function(parameter) {
81 return parameter.allowsStdin();
82 });
83 };
84
85 Signature.prototype.toString = function() {
86 var i, len, parameter, ref, result;
87 result = [];
88 ref = this.parameters;
89 for (i = 0, len = ref.length; i < len; i++) {
90 parameter = ref[i];
91 result.push(parameter.toString());
92 }
93 return result.join(' ');
94 };
95
96 Signature.prototype.isWildcard = function() {
97 return _.all([this.parameters.length === 1, this.parameters[0].toString() === settings.signatures.wildcard]);
98 };
99
100 Signature.prototype.matches = function(command, callback) {
101 return this.compileParameters(command, function(error) {
102 if (error == null) {
103 return callback(true);
104 }
105 if (_.str.startsWith(error.message, 'Missing')) {
106 return callback(true);
107 }
108 return callback(false);
109 }, false);
110 };
111
112 Signature.prototype.compileParameters = function(command, callback, performStdin) {
113 var commandWords, comparison, result;
114 if (performStdin == null) {
115 performStdin = true;
116 }
117 commandWords = parse.split(command);
118 comparison = _.zip(this.parameters, commandWords);
119 result = {};
120 if (this.isWildcard()) {
121 return callback(null, result);
122 }
123 return async.eachSeries(comparison, (function(_this) {
124 return function(item, done) {
125 var parameter, parameterIndex, parameterValue, value, word;
126 parameter = item[0];
127 word = item[1];
128 if (parameter == null) {
129 return callback(new Error('Signature dismatch'));
130 }
131 parameterValue = parameter.getValue();
132 if (parameter.allowsStdin() && (word == null)) {
133 if (!performStdin) {
134 return callback(null, result);
135 }
136 return utils.getStdin(function(stdin) {
137 if (parameter.isRequired() && (stdin == null)) {
138 return callback(new Error("Missing " + parameterValue));
139 }
140 if (stdin != null) {
141 result[parameterValue] = stdin;
142 }
143 return callback(null, result);
144 });
145 }
146 if (!parameter.matches(word)) {
147 if (parameter.isRequired()) {
148 return callback(new Error("Missing " + parameterValue));
149 }
150 return callback(new Error(parameterValue + " does not match " + word));
151 }
152 if (parameter.isVariadic()) {
153 parameterIndex = _.indexOf(_this.parameters, parameter);
154 value = _.rest(commandWords, parameterIndex).join(' ');
155 if (parameter.isOptional() && _.isEmpty(value)) {
156 return callback(null, result);
157 }
158 result[parameterValue] = value;
159 return callback(null, result);
160 }
161 if (!parameter.isWord() && (word != null)) {
162 if (/^\d+$/.test(word)) {
163 result[parameterValue] = _.parseInt(word);
164 } else {
165 result[parameterValue] = word;
166 }
167 }
168 return done();
169 };
170 })(this), function(error) {
171 if (error != null) {
172 return callback(error);
173 }
174 return callback(null, result);
175 });
176 };
177
178 return Signature;
179
180})();