var json = typeof JSON !== undefined ? JSON : require('jsonify'); var map = require('array-map'); var filter = require('array-filter'); var reduce = require('array-reduce'); exports.quote = function (xs) { return map(xs, function (s) { if (s && typeof s === 'object') { return s.op.replace(/(.)/g, '\\$1'); } else if (/["\s]/.test(s) && !/'/.test(s)) { return "'" + s.replace(/(['\\])/g, '\\$1') + "'"; } else if (/["'\s]/.test(s)) { return '"' + s.replace(/(["\\$`!])/g, '\\$1') + '"'; } else { return String(s).replace(/([\\$`()!#&*|])/g, '\\$1'); } }).join(' '); }; var CONTROL = '(?:' + [ '\\|\\|', '\\&\\&', ';;', '\\|\\&', '[&;()|<>]' ].join('|') + ')'; var META = '|&;()<> \\t'; var BAREWORD = '(\\\\[\'"' + META + ']|[^\\s\'"' + META + '])+'; var SINGLE_QUOTE = '"((\\\\"|[^"])*?)"'; var DOUBLE_QUOTE = '\'((\\\\\'|[^\'])*?)\''; var TOKEN = ''; for (var i = 0; i < 4; i++) { TOKEN += (Math.pow(16,8)*Math.random()).toString(16); } exports.parse = function (s, env, opts) { var mapped = parse(s, env, opts); if (typeof env !== 'function') return mapped; return reduce(mapped, function (acc, s) { if (typeof s === 'object') return acc.concat(s); var xs = s.split(RegExp('(' + TOKEN + '.*?' + TOKEN + ')', 'g')); if (xs.length === 1) return acc.concat(xs[0]); return acc.concat(map(filter(xs, Boolean), function (x) { if (RegExp('^' + TOKEN).test(x)) { return json.parse(x.split(TOKEN)[1]); } else return x; })); }, []); }; function parse (s, env, opts) { var chunker = new RegExp([ '(' + CONTROL + ')', // control chars '(' + BAREWORD + '|' + SINGLE_QUOTE + '|' + DOUBLE_QUOTE + ')*' ].join('|'), 'g'); var match = filter(s.match(chunker), Boolean); if (!match) return []; if (!env) env = {}; if (!opts) opts = {}; return map(match, function (s) { if (RegExp('^' + CONTROL + '$').test(s)) { return { op: s }; } // Hand-written scanner/parser for Bash quoting rules: // // 1. inside single quotes, all characters are printed literally. // 2. inside double quotes, all characters are printed literally // except variables prefixed by '$' and backslashes followed by // either a double quote or another backslash. // 3. outside of any quotes, backslashes are treated as escape // characters and not printed (unless they are themselves escaped) // 4. quote context can switch mid-token if there is no whitespace // between the two quote contexts (e.g. all'one'"token" parses as // "allonetoken") var SQ = "'"; var DQ = '"'; var DS = '$'; var BS = opts.escape || '\\'; var quote = false; var varname = false; var esc = false; var out = ''; var isGlob = false; for (var i = 0, len = s.length; i < len; i++) { var c = s.charAt(i); isGlob = isGlob || (!quote && (c === '*' || c === '?')) if (esc) { out += c; esc = false; } else if (quote) { if (c === quote) { quote = false; } else if (quote == SQ) { out += c; } else { // Double quote if (c === BS) { i += 1; c = s.charAt(i); if (c === DQ || c === BS || c === DS) { out += c; } else { out += BS + c; } } else if (c === DS) { out += parseEnvVar(); } else { out += c } } } else if (c === DQ || c === SQ) { quote = c } else if (RegExp('^' + CONTROL + '$').test(c)) { return { op: s }; } else if (c === BS) { esc = true } else if (c === DS) { out += parseEnvVar(); } else out += c; } if (isGlob) return {op: 'glob', pattern: out}; return out function parseEnvVar() { i += 1; var varend, varname; //debugger if (s.charAt(i) === '{') { i += 1 if (s.charAt(i) === '}') { throw new Error("Bad substitution: " + s.substr(i - 2, 3)); } varend = s.indexOf('}', i); if (varend < 0) { throw new Error("Bad substitution: " + s.substr(i)); } varname = s.substr(i, varend - i); i = varend; } else if (/[*@#?$!_\-]/.test(s.charAt(i))) { varname = s.charAt(i); i += 1; } else { varend = s.substr(i).match(/[^\w\d_]/); if (!varend) { varname = s.substr(i); i = s.length; } else { varname = s.substr(i, varend.index) i += varend.index - 1; } } return getVar(null, '', varname); } }); function getVar (_, pre, key) { var r = typeof env === 'function' ? env(key) : env[key]; if (r === undefined) r = ''; if (typeof r === 'object') { return pre + TOKEN + json.stringify(r) + TOKEN; } else return pre + r; } };
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19553 | swellard | Move and rename clients | ||
//guest/perforce_software/helix-web-services/main/source/clients/2016.1.0/javascript/node_modules/shell-quote/index.js | |||||
#1 | 18810 | tjuricek |
First-pass at JavaScript client SDK. JavaScript requires Node with Gulp to "browserfy" the library. It's the easiest way I found to use the swagger-js project; bundle up a wrapping method. There is no JavaScript reference guide. The swagger-js doesn't really document what they do very well, actually. Overall I'm not particularly impressed by swagger-js, it was hard to even figure out what the right method syntax was. We may want to invest time in doing it better. This required setting CORS response headers, which are currently defaulted to a fairly insecure setting. |