/*! * async * https://github.com/caolan/async * * Copyright 2010-2014 Caolan McMahon * Released under the MIT license */ (function () { var async = {}; function noop() {} function identity(v) { return v; } function toBool(v) { return !!v; } function notId(v) { return !v; } // global on the server, window in the browser var previous_async; // Establish the root object, `window` (`self`) in the browser, `global` // on the server, or `this` in some virtual machines. We use `self` // instead of `window` for `WebWorker` support. var root = typeof self === 'object' && self.self === self && self || typeof global === 'object' && global.global === global && global || this; if (root != null) { previous_async = root.async; } async.noConflict = function () { root.async = previous_async; return async; }; function only_once(fn) { return function() { if (fn === null) throw new Error("Callback was already called."); fn.apply(this, arguments); fn = null; }; } function _once(fn) { return function() { if (fn === null) return; fn.apply(this, arguments); fn = null; }; } //// cross-browser compatiblity functions //// var _toString = Object.prototype.toString; var _isArray = Array.isArray || function (obj) { return _toString.call(obj) === '[object Array]'; }; // Ported from underscore.js isObject var _isObject = function(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; }; function _isArrayLike(arr) { return _isArray(arr) || ( // has a positive integer length property typeof arr.length === "number" && arr.length >= 0 && arr.length % 1 === 0 ); } function _arrayEach(arr, iterator) { var index = -1, length = arr.length; while (++index < length) { iterator(arr[index], index, arr); } } function _map(arr, iterator) { var index = -1, length = arr.length, result = Array(length); while (++index < length) { result[index] = iterator(arr[index], index, arr); } return result; } function _range(count) { return _map(Array(count), function (v, i) { return i; }); } function _reduce(arr, iterator, memo) { _arrayEach(arr, function (x, i, a) { memo = iterator(memo, x, i, a); }); return memo; } function _forEachOf(object, iterator) { _arrayEach(_keys(object), function (key) { iterator(object[key], key); }); } function _indexOf(arr, item) { for (var i = 0; i < arr.length; i++) { if (arr[i] === item) return i; } return -1; } var _keys = Object.keys || function (obj) { var keys = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { keys.push(k); } } return keys; }; function _keyIterator(coll) { var i = -1; var len; var keys; if (_isArrayLike(coll)) { len = coll.length; return function next() { i++; return i < len ? i : null; }; } else { keys = _keys(coll); len = keys.length; return function next() { i++; return i < len ? keys[i] : null; }; } } // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) // This accumulates the arguments passed into an array, after a given index. // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). function _restParam(func, startIndex) { startIndex = startIndex == null ? func.length - 1 : +startIndex; return function() { var length = Math.max(arguments.length - startIndex, 0); var rest = Array(length); for (var index = 0; index < length; index++) { rest[index] = arguments[index + startIndex]; } switch (startIndex) { case 0: return func.call(this, rest); case 1: return func.call(this, arguments[0], rest); } // Currently unused but handle cases outside of the switch statement: // var args = Array(startIndex + 1); // for (index = 0; index < startIndex; index++) { // args[index] = arguments[index]; // } // args[startIndex] = rest; // return func.apply(this, args); }; } function _withoutIndex(iterator) { return function (value, index, callback) { return iterator(value, callback); }; } //// exported async module functions //// //// nextTick implementation with browser-compatible fallback //// // capture the global reference to guard against fakeTimer mocks var _setImmediate = typeof setImmediate === 'function' && setImmediate; var _delay = _setImmediate ? function(fn) { // not a direct alias for IE10 compatibility _setImmediate(fn); } : function(fn) { setTimeout(fn, 0); }; if (typeof process === 'object' && typeof process.nextTick === 'function') { async.nextTick = process.nextTick; } else { async.nextTick = _delay; } async.setImmediate = _setImmediate ? _delay : async.nextTick; async.forEach = async.each = function (arr, iterator, callback) { return async.eachOf(arr, _withoutIndex(iterator), callback); }; async.forEachSeries = async.eachSeries = function (arr, iterator, callback) { return async.eachOfSeries(arr, _withoutIndex(iterator), callback); }; async.forEachLimit = async.eachLimit = function (arr, limit, iterator, callback) { return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); }; async.forEachOf = async.eachOf = function (object, iterator, callback) { callback = _once(callback || noop); object = object || []; var iter = _keyIterator(object); var key, completed = 0; while ((key = iter()) != null) { completed += 1; iterator(object[key], key, only_once(done)); } if (completed === 0) callback(null); function done(err) { completed--; if (err) { callback(err); } // Check key is null in case iterator isn't exhausted // and done resolved synchronously. else if (key === null && completed <= 0) { callback(null); } } }; async.forEachOfSeries = async.eachOfSeries = function (obj, iterator, callback) { callback = _once(callback || noop); obj = obj || []; var nextKey = _keyIterator(obj); var key = nextKey(); function iterate() { var sync = true; if (key === null) { return callback(null); } iterator(obj[key], key, only_once(function (err) { if (err) { callback(err); } else { key = nextKey(); if (key === null) { return callback(null); } else { if (sync) { async.setImmediate(iterate); } else { iterate(); } } } })); sync = false; } iterate(); }; async.forEachOfLimit = async.eachOfLimit = function (obj, limit, iterator, callback) { _eachOfLimit(limit)(obj, iterator, callback); }; function _eachOfLimit(limit) { return function (obj, iterator, callback) { callback = _once(callback || noop); obj = obj || []; var nextKey = _keyIterator(obj); if (limit <= 0) { return callback(null); } var done = false; var running = 0; var errored = false; (function replenish () { if (done && running <= 0) { return callback(null); } while (running < limit && !errored) { var key = nextKey(); if (key === null) { done = true; if (running <= 0) { callback(null); } return; } running += 1; iterator(obj[key], key, only_once(function (err) { running -= 1; if (err) { callback(err); errored = true; } else { replenish(); } })); } })(); }; } function doParallel(fn) { return function (obj, iterator, callback) { return fn(async.eachOf, obj, iterator, callback); }; } function doParallelLimit(fn) { return function (obj, limit, iterator, callback) { return fn(_eachOfLimit(limit), obj, iterator, callback); }; } function doSeries(fn) { return function (obj, iterator, callback) { return fn(async.eachOfSeries, obj, iterator, callback); }; } function _asyncMap(eachfn, arr, iterator, callback) { callback = _once(callback || noop); arr = arr || []; var results = _isArrayLike(arr) ? [] : {}; eachfn(arr, function (value, index, callback) { iterator(value, function (err, v) { results[index] = v; callback(err); }); }, function (err) { callback(err, results); }); } async.map = doParallel(_asyncMap); async.mapSeries = doSeries(_asyncMap); async.mapLimit = doParallelLimit(_asyncMap); // reduce only has a series version, as doing reduce in parallel won't // work in many situations. async.inject = async.foldl = async.reduce = function (arr, memo, iterator, callback) { async.eachOfSeries(arr, function (x, i, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }; async.foldr = async.reduceRight = function (arr, memo, iterator, callback) { var reversed = _map(arr, identity).reverse(); async.reduce(reversed, memo, iterator, callback); }; async.transform = function (arr, memo, iterator, callback) { if (arguments.length === 3) { callback = iterator; iterator = memo; memo = _isArray(arr) ? [] : {}; } async.eachOf(arr, function(v, k, cb) { iterator(memo, v, k, cb); }, function(err) { callback(err, memo); }); }; function _filter(eachfn, arr, iterator, callback) { var results = []; eachfn(arr, function (x, index, callback) { iterator(x, function (v) { if (v) { results.push({index: index, value: x}); } callback(); }); }, function () { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); } async.select = async.filter = doParallel(_filter); async.selectLimit = async.filterLimit = doParallelLimit(_filter); async.selectSeries = async.filterSeries = doSeries(_filter); function _reject(eachfn, arr, iterator, callback) { _filter(eachfn, arr, function(value, cb) { iterator(value, function(v) { cb(!v); }); }, callback); } async.reject = doParallel(_reject); async.rejectLimit = doParallelLimit(_reject); async.rejectSeries = doSeries(_reject); function _createTester(eachfn, check, getResult) { return function(arr, limit, iterator, cb) { function done() { if (cb) cb(getResult(false, void 0)); } function iteratee(x, _, callback) { if (!cb) return callback(); iterator(x, function (v) { if (cb && check(v)) { cb(getResult(true, x)); cb = iterator = false; } callback(); }); } if (arguments.length > 3) { eachfn(arr, limit, iteratee, done); } else { cb = iterator; iterator = limit; eachfn(arr, iteratee, done); } }; } async.any = async.some = _createTester(async.eachOf, toBool, identity); async.someLimit = _createTester(async.eachOfLimit, toBool, identity); async.all = async.every = _createTester(async.eachOf, notId, notId); async.everyLimit = _createTester(async.eachOfLimit, notId, notId); function _findGetResult(v, x) { return x; } async.detect = _createTester(async.eachOf, identity, _findGetResult); async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult); async.sortBy = function (arr, iterator, callback) { async.map(arr, function (x, callback) { iterator(x, function (err, criteria) { if (err) { callback(err); } else { callback(null, {value: x, criteria: criteria}); } }); }, function (err, results) { if (err) { return callback(err); } else { callback(null, _map(results.sort(comparator), function (x) { return x.value; })); } }); function comparator(left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; } }; async.auto = function (tasks, concurrency, callback) { if (typeof arguments[1] === 'function') { // concurrency is optional, shift the args. callback = concurrency; concurrency = null; } callback = _once(callback || noop); var keys = _keys(tasks); var remainingTasks = keys.length; if (!remainingTasks) { return callback(null); } if (!concurrency) { concurrency = remainingTasks; } var results = {}; var runningTasks = 0; var hasError = false; var listeners = []; function addListener(fn) { listeners.unshift(fn); } function removeListener(fn) { var idx = _indexOf(listeners, fn); if (idx >= 0) listeners.splice(idx, 1); } function taskComplete() { remainingTasks--; _arrayEach(listeners.slice(0), function (fn) { fn(); }); } addListener(function () { if (!remainingTasks) { callback(null, results); } }); _arrayEach(keys, function (k) { if (hasError) return; var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; var taskCallback = _restParam(function(err, args) { runningTasks--; if (args.length <= 1) { args = args[0]; } if (err) { var safeResults = {}; _forEachOf(results, function(val, rkey) { safeResults[rkey] = val; }); safeResults[k] = args; hasError = true; callback(err, safeResults); } else { results[k] = args; async.setImmediate(taskComplete); } }); var requires = task.slice(0, task.length - 1); // prevent dead-locks var len = requires.length; var dep; while (len--) { if (!(dep = tasks[requires[len]])) { throw new Error('Has nonexistent dependency in ' + requires.join(', ')); } if (_isArray(dep) && _indexOf(dep, k) >= 0) { throw new Error('Has cyclic dependencies'); } } function ready() { return runningTasks < concurrency && _reduce(requires, function (a, x) { return (a && results.hasOwnProperty(x)); }, true) && !results.hasOwnProperty(k); } if (ready()) { runningTasks++; task[task.length - 1](taskCallback, results); } else { addListener(listener); } function listener() { if (ready()) { runningTasks++; removeListener(listener); task[task.length - 1](taskCallback, results); } } }); }; async.retry = function(times, task, callback) { var DEFAULT_TIMES = 5; var DEFAULT_INTERVAL = 0; var attempts = []; var opts = { times: DEFAULT_TIMES, interval: DEFAULT_INTERVAL }; function parseTimes(acc, t){ if(typeof t === 'number'){ acc.times = parseInt(t, 10) || DEFAULT_TIMES; } else if(typeof t === 'object'){ acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; } else { throw new Error('Unsupported argument type for \'times\': ' + typeof t); } } var length = arguments.length; if (length < 1 || length > 3) { throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); } else if (length <= 2 && typeof times === 'function') { callback = task; task = times; } if (typeof times !== 'function') { parseTimes(opts, times); } opts.callback = callback; opts.task = task; function wrappedTask(wrappedCallback, wrappedResults) { function retryAttempt(task, finalAttempt) { return function(seriesCallback) { task(function(err, result){ seriesCallback(!err || finalAttempt, {err: err, result: result}); }, wrappedResults); }; } function retryInterval(interval){ return function(seriesCallback){ setTimeout(function(){ seriesCallback(null); }, interval); }; } while (opts.times) { var finalAttempt = !(opts.times-=1); attempts.push(retryAttempt(opts.task, finalAttempt)); if(!finalAttempt && opts.interval > 0){ attempts.push(retryInterval(opts.interval)); } } async.series(attempts, function(done, data){ data = data[data.length - 1]; (wrappedCallback || opts.callback)(data.err, data.result); }); } // If a callback is passed, run this as a controll flow return opts.callback ? wrappedTask() : wrappedTask; }; async.waterfall = function (tasks, callback) { callback = _once(callback || noop); if (!_isArray(tasks)) { var err = new Error('First argument to waterfall must be an array of functions'); return callback(err); } if (!tasks.length) { return callback(); } function wrapIterator(iterator) { return _restParam(function (err, args) { if (err) { callback.apply(null, [err].concat(args)); } else { var next = iterator.next(); if (next) { args.push(wrapIterator(next)); } else { args.push(callback); } ensureAsync(iterator).apply(null, args); } }); } wrapIterator(async.iterator(tasks))(); }; function _parallel(eachfn, tasks, callback) { callback = callback || noop; var results = _isArrayLike(tasks) ? [] : {}; eachfn(tasks, function (task, key, callback) { task(_restParam(function (err, args) { if (args.length <= 1) { args = args[0]; } results[key] = args; callback(err); })); }, function (err) { callback(err, results); }); } async.parallel = function (tasks, callback) { _parallel(async.eachOf, tasks, callback); }; async.parallelLimit = function(tasks, limit, callback) { _parallel(_eachOfLimit(limit), tasks, callback); }; async.series = function(tasks, callback) { _parallel(async.eachOfSeries, tasks, callback); }; async.iterator = function (tasks) { function makeCallback(index) { function fn() { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); } fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; } return makeCallback(0); }; async.apply = _restParam(function (fn, args) { return _restParam(function (callArgs) { return fn.apply( null, args.concat(callArgs) ); }); }); function _concat(eachfn, arr, fn, callback) { var result = []; eachfn(arr, function (x, index, cb) { fn(x, function (err, y) { result = result.concat(y || []); cb(err); }); }, function (err) { callback(err, result); }); } async.concat = doParallel(_concat); async.concatSeries = doSeries(_concat); async.whilst = function (test, iterator, callback) { callback = callback || noop; if (test()) { var next = _restParam(function(err, args) { if (err) { callback(err); } else if (test.apply(this, args)) { iterator(next); } else { callback.apply(null, [null].concat(args)); } }); iterator(next); } else { callback(null); } }; async.doWhilst = function (iterator, test, callback) { var calls = 0; return async.whilst(function() { return ++calls <= 1 || test.apply(this, arguments); }, iterator, callback); }; async.until = function (test, iterator, callback) { return async.whilst(function() { return !test.apply(this, arguments); }, iterator, callback); }; async.doUntil = function (iterator, test, callback) { return async.doWhilst(iterator, function() { return !test.apply(this, arguments); }, callback); }; async.during = function (test, iterator, callback) { callback = callback || noop; var next = _restParam(function(err, args) { if (err) { callback(err); } else { args.push(check); test.apply(this, args); } }); var check = function(err, truth) { if (err) { callback(err); } else if (truth) { iterator(next); } else { callback(null); } }; test(check); }; async.doDuring = function (iterator, test, callback) { var calls = 0; async.during(function(next) { if (calls++ < 1) { next(null, true); } else { test.apply(this, arguments); } }, iterator, callback); }; function _queue(worker, concurrency, payload) { if (concurrency == null) { concurrency = 1; } else if(concurrency === 0) { throw new Error('Concurrency must not be zero'); } function _insert(q, data, pos, callback) { if (callback != null && typeof callback !== "function") { throw new Error("task callback must be a function"); } q.started = true; if (!_isArray(data)) { data = [data]; } if(data.length === 0 && q.idle()) { // call drain immediately if there are no tasks return async.setImmediate(function() { q.drain(); }); } _arrayEach(data, function(task) { var item = { data: task, callback: callback || noop }; if (pos) { q.tasks.unshift(item); } else { q.tasks.push(item); } if (q.tasks.length === q.concurrency) { q.saturated(); } }); async.setImmediate(q.process); } function _next(q, tasks) { return function(){ workers -= 1; var removed = false; var args = arguments; _arrayEach(tasks, function (task) { _arrayEach(workersList, function (worker, index) { if (worker === task && !removed) { workersList.splice(index, 1); removed = true; } }); task.callback.apply(task, args); }); if (q.tasks.length + workers === 0) { q.drain(); } q.process(); }; } var workers = 0; var workersList = []; var q = { tasks: [], concurrency: concurrency, payload: payload, saturated: noop, empty: noop, drain: noop, started: false, paused: false, push: function (data, callback) { _insert(q, data, false, callback); }, kill: function () { q.drain = noop; q.tasks = []; }, unshift: function (data, callback) { _insert(q, data, true, callback); }, process: function () { while(!q.paused && workers < q.concurrency && q.tasks.length){ var tasks = q.payload ? q.tasks.splice(0, q.payload) : q.tasks.splice(0, q.tasks.length); var data = _map(tasks, function (task) { return task.data; }); if (q.tasks.length === 0) { q.empty(); } workers += 1; workersList.push(tasks[0]); var cb = only_once(_next(q, tasks)); worker(data, cb); } }, length: function () { return q.tasks.length; }, running: function () { return workers; }, workersList: function () { return workersList; }, idle: function() { return q.tasks.length + workers === 0; }, pause: function () { q.paused = true; }, resume: function () { if (q.paused === false) { return; } q.paused = false; var resumeCount = Math.min(q.concurrency, q.tasks.length); // Need to call q.process once per concurrent // worker to preserve full concurrency after pause for (var w = 1; w <= resumeCount; w++) { async.setImmediate(q.process); } } }; return q; } async.queue = function (worker, concurrency) { var q = _queue(function (items, cb) { worker(items[0], cb); }, concurrency, 1); return q; }; async.priorityQueue = function (worker, concurrency) { function _compareTasks(a, b){ return a.priority - b.priority; } function _binarySearch(sequence, item, compare) { var beg = -1, end = sequence.length - 1; while (beg < end) { var mid = beg + ((end - beg + 1) >>> 1); if (compare(item, sequence[mid]) >= 0) { beg = mid; } else { end = mid - 1; } } return beg; } function _insert(q, data, priority, callback) { if (callback != null && typeof callback !== "function") { throw new Error("task callback must be a function"); } q.started = true; if (!_isArray(data)) { data = [data]; } if(data.length === 0) { // call drain immediately if there are no tasks return async.setImmediate(function() { q.drain(); }); } _arrayEach(data, function(task) { var item = { data: task, priority: priority, callback: typeof callback === 'function' ? callback : noop }; q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); if (q.tasks.length === q.concurrency) { q.saturated(); } async.setImmediate(q.process); }); } // Start with a normal queue var q = async.queue(worker, concurrency); // Override push to accept second parameter representing priority q.push = function (data, priority, callback) { _insert(q, data, priority, callback); }; // Remove unshift function delete q.unshift; return q; }; async.cargo = function (worker, payload) { return _queue(worker, 1, payload); }; function _console_fn(name) { return _restParam(function (fn, args) { fn.apply(null, args.concat([_restParam(function (err, args) { if (typeof console === 'object') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { _arrayEach(args, function (x) { console[name](x); }); } } })])); }); } async.log = _console_fn('log'); async.dir = _console_fn('dir'); /*async.info = _console_fn('info'); async.warn = _console_fn('warn'); async.error = _console_fn('error');*/ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; var has = Object.prototype.hasOwnProperty; hasher = hasher || identity; var memoized = _restParam(function memoized(args) { var callback = args.pop(); var key = hasher.apply(null, args); if (has.call(memo, key)) { async.setImmediate(function () { callback.apply(null, memo[key]); }); } else if (has.call(queues, key)) { queues[key].push(callback); } else { queues[key] = [callback]; fn.apply(null, args.concat([_restParam(function (args) { memo[key] = args; var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { q[i].apply(null, args); } })])); } }); memoized.memo = memo; memoized.unmemoized = fn; return memoized; }; async.unmemoize = function (fn) { return function () { return (fn.unmemoized || fn).apply(null, arguments); }; }; function _times(mapper) { return function (count, iterator, callback) { mapper(_range(count), iterator, callback); }; } async.times = _times(async.map); async.timesSeries = _times(async.mapSeries); async.timesLimit = function (count, limit, iterator, callback) { return async.mapLimit(_range(count), limit, iterator, callback); }; async.seq = function (/* functions... */) { var fns = arguments; return _restParam(function (args) { var that = this; var callback = args[args.length - 1]; if (typeof callback == 'function') { args.pop(); } else { callback = noop; } async.reduce(fns, args, function (newargs, fn, cb) { fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { cb(err, nextargs); })])); }, function (err, results) { callback.apply(that, [err].concat(results)); }); }); }; async.compose = function (/* functions... */) { return async.seq.apply(null, Array.prototype.reverse.call(arguments)); }; function _applyEach(eachfn) { return _restParam(function(fns, args) { var go = _restParam(function(args) { var that = this; var callback = args.pop(); return eachfn(fns, function (fn, _, cb) { fn.apply(that, args.concat([cb])); }, callback); }); if (args.length) { return go.apply(this, args); } else { return go; } }); } async.applyEach = _applyEach(async.eachOf); async.applyEachSeries = _applyEach(async.eachOfSeries); async.forever = function (fn, callback) { var done = only_once(callback || noop); var task = ensureAsync(fn); function next(err) { if (err) { return done(err); } task(next); } next(); }; function ensureAsync(fn) { return _restParam(function (args) { var callback = args.pop(); args.push(function () { var innerArgs = arguments; if (sync) { async.setImmediate(function () { callback.apply(null, innerArgs); }); } else { callback.apply(null, innerArgs); } }); var sync = true; fn.apply(this, args); sync = false; }); } async.ensureAsync = ensureAsync; async.constant = _restParam(function(values) { var args = [null].concat(values); return function (callback) { return callback.apply(this, args); }; }); async.wrapSync = async.asyncify = function asyncify(func) { return _restParam(function (args) { var callback = args.pop(); var result; try { result = func.apply(this, args); } catch (e) { return callback(e); } // if result is Promise object if (_isObject(result) && typeof result.then === "function") { result.then(function(value) { callback(null, value); })["catch"](function(err) { callback(err.message ? err : new Error(err)); }); } else { callback(null, result); } }); }; // Node.js if (typeof module === 'object' && module.exports) { module.exports = async; } // AMD / RequireJS else if (typeof define === 'function' && define.amd) { define([], function () { return async; }); } // included directly via <script> tag else { root.async = async; } }());
# | 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/async/dist/async.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. |