Updated the Survey.
This commit is contained in:
parent
f59686eae0
commit
6d3ba1a714
1203 changed files with 140782 additions and 5 deletions
43
node_modules/nodemon/lib/config/command.js
generated
vendored
Normal file
43
node_modules/nodemon/lib/config/command.js
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
module.exports = command;
|
||||
|
||||
/**
|
||||
* command constructs the executable command to run in a shell including the
|
||||
* user script, the command arguments.
|
||||
*
|
||||
* @param {Object} settings Object as:
|
||||
* { execOptions: {
|
||||
* exec: String,
|
||||
* [script: String],
|
||||
* [scriptPosition: Number],
|
||||
* [execArgs: Array<string>]
|
||||
* }
|
||||
* }
|
||||
* @return {Object} an object with the node executable and the
|
||||
* arguments to the command
|
||||
*/
|
||||
function command(settings) {
|
||||
var options = settings.execOptions;
|
||||
var executable = options.exec;
|
||||
var args = [];
|
||||
|
||||
// after "executable" go the exec args (like --debug, etc)
|
||||
if (options.execArgs) {
|
||||
[].push.apply(args, options.execArgs);
|
||||
}
|
||||
|
||||
// then goes the user's script arguments
|
||||
if (options.args) {
|
||||
[].push.apply(args, options.args);
|
||||
}
|
||||
|
||||
// after the "executable" goes the user's script
|
||||
if (options.script) {
|
||||
args.splice((options.scriptPosition || 0) +
|
||||
options.execArgs.length, 0, options.script);
|
||||
}
|
||||
|
||||
return {
|
||||
executable: executable,
|
||||
args: args,
|
||||
};
|
||||
}
|
28
node_modules/nodemon/lib/config/defaults.js
generated
vendored
Normal file
28
node_modules/nodemon/lib/config/defaults.js
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
var ignoreRoot = require('ignore-by-default').directories();
|
||||
|
||||
// default options for config.options
|
||||
module.exports = {
|
||||
restartable: 'rs',
|
||||
colours: true,
|
||||
execMap: {
|
||||
py: 'python',
|
||||
rb: 'ruby',
|
||||
ts: 'ts-node',
|
||||
// more can be added here such as ls: lsc - but please ensure it's cross
|
||||
// compatible with linux, mac and windows, or make the default.js
|
||||
// dynamically append the `.cmd` for node based utilities
|
||||
},
|
||||
ignoreRoot: ignoreRoot.map(_ => `**/${_}/**`),
|
||||
watch: ['*.*'],
|
||||
stdin: true,
|
||||
runOnChangeOnly: false,
|
||||
verbose: false,
|
||||
signal: 'SIGUSR2',
|
||||
// 'stdout' refers to the default behaviour of a required nodemon's child,
|
||||
// but also includes stderr. If this is false, data is still dispatched via
|
||||
// nodemon.on('stdout/stderr')
|
||||
stdout: true,
|
||||
watchOptions: {
|
||||
|
||||
},
|
||||
};
|
225
node_modules/nodemon/lib/config/exec.js
generated
vendored
Normal file
225
node_modules/nodemon/lib/config/exec.js
generated
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const existsSync = fs.existsSync;
|
||||
const utils = require('../utils');
|
||||
|
||||
module.exports = exec;
|
||||
module.exports.expandScript = expandScript;
|
||||
|
||||
/**
|
||||
* Reads the cwd/package.json file and looks to see if it can load a script
|
||||
* and possibly an exec first from package.main, then package.start.
|
||||
*
|
||||
* @return {Object} exec & script if found
|
||||
*/
|
||||
function execFromPackage() {
|
||||
// doing a try/catch because we can't use the path.exist callback pattern
|
||||
// or we could, but the code would get messy, so this will do exactly
|
||||
// what we're after - if the file doesn't exist, it'll throw.
|
||||
try {
|
||||
// note: this isn't nodemon's package, it's the user's cwd package
|
||||
var pkg = require(path.join(process.cwd(), 'package.json'));
|
||||
if (pkg.main !== undefined) {
|
||||
// no app found to run - so give them a tip and get the feck out
|
||||
return { exec: null, script: pkg.main };
|
||||
}
|
||||
|
||||
if (pkg.scripts && pkg.scripts.start) {
|
||||
return { exec: pkg.scripts.start };
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(map, str) {
|
||||
var re = new RegExp('{{(' + Object.keys(map).join('|') + ')}}', 'g');
|
||||
return str.replace(re, function (all, m) {
|
||||
return map[m] || all || '';
|
||||
});
|
||||
}
|
||||
|
||||
function expandScript(script, ext) {
|
||||
if (!ext) {
|
||||
ext = '.js';
|
||||
}
|
||||
if (script.indexOf(ext) !== -1) {
|
||||
return script;
|
||||
}
|
||||
|
||||
if (existsSync(path.resolve(script))) {
|
||||
return script;
|
||||
}
|
||||
|
||||
if (existsSync(path.resolve(script + ext))) {
|
||||
return script + ext;
|
||||
}
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discovers all the options required to run the script
|
||||
* and if a custom exec has been passed in, then it will
|
||||
* also try to work out what extensions to monitor and
|
||||
* whether there's a special way of running that script.
|
||||
*
|
||||
* @param {Object} nodemonOptions
|
||||
* @param {Object} execMap
|
||||
* @return {Object} new and updated version of nodemonOptions
|
||||
*/
|
||||
function exec(nodemonOptions, execMap) {
|
||||
if (!execMap) {
|
||||
execMap = {};
|
||||
}
|
||||
|
||||
var options = utils.clone(nodemonOptions || {});
|
||||
var script;
|
||||
|
||||
// if there's no script passed, try to get it from the first argument
|
||||
if (!options.script && (options.args || []).length) {
|
||||
script = expandScript(options.args[0],
|
||||
options.ext && ('.' + (options.ext || 'js').split(',')[0]));
|
||||
|
||||
// if the script was found, shift it off our args
|
||||
if (script !== options.args[0]) {
|
||||
options.script = script;
|
||||
options.args.shift();
|
||||
}
|
||||
}
|
||||
|
||||
// if there's no exec found yet, then try to read it from the local
|
||||
// package.json this logic used to sit in the cli/parse, but actually the cli
|
||||
// should be parsed first, then the user options (via nodemon.json) then
|
||||
// finally default down to pot shots at the directory via package.json
|
||||
if (!options.exec && !options.script) {
|
||||
var found = execFromPackage();
|
||||
if (found !== null) {
|
||||
if (found.exec) {
|
||||
options.exec = found.exec;
|
||||
}
|
||||
if (!options.script) {
|
||||
options.script = found.script;
|
||||
}
|
||||
if (Array.isArray(options.args) &&
|
||||
options.scriptPosition === null) {
|
||||
options.scriptPosition = options.args.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// var options = utils.clone(nodemonOptions || {});
|
||||
script = path.basename(options.script || '');
|
||||
|
||||
var scriptExt = path.extname(script).slice(1);
|
||||
|
||||
var extension = options.ext;
|
||||
if (extension === undefined) {
|
||||
var isJS = scriptExt === 'js' || scriptExt === 'mjs';
|
||||
extension = (isJS || !scriptExt) ? 'js,mjs' : scriptExt;
|
||||
extension += ',json'; // Always watch JSON files
|
||||
}
|
||||
|
||||
var execDefined = !!options.exec;
|
||||
|
||||
// allows the user to simplify cli usage:
|
||||
// https://github.com/remy/nodemon/issues/195
|
||||
// but always give preference to the user defined argument
|
||||
if (!options.exec && execMap[scriptExt] !== undefined) {
|
||||
options.exec = execMap[scriptExt];
|
||||
execDefined = true;
|
||||
}
|
||||
|
||||
options.execArgs = nodemonOptions.execArgs || [];
|
||||
|
||||
if (Array.isArray(options.exec)) {
|
||||
options.execArgs = options.exec;
|
||||
options.exec = options.execArgs.shift();
|
||||
}
|
||||
|
||||
if (options.exec === undefined) {
|
||||
options.exec = 'node';
|
||||
} else {
|
||||
// allow variable substitution for {{filename}} and {{pwd}}
|
||||
var substitution = replace.bind(null, {
|
||||
filename: options.script,
|
||||
pwd: process.cwd(),
|
||||
});
|
||||
|
||||
var newExec = substitution(options.exec);
|
||||
if (newExec !== options.exec &&
|
||||
options.exec.indexOf('{{filename}}') !== -1) {
|
||||
options.script = null;
|
||||
}
|
||||
options.exec = newExec;
|
||||
|
||||
var newExecArgs = options.execArgs.map(substitution);
|
||||
if (newExecArgs.join('') !== options.execArgs.join('')) {
|
||||
options.execArgs = newExecArgs;
|
||||
delete options.script;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (options.exec === 'node' && options.nodeArgs && options.nodeArgs.length) {
|
||||
options.execArgs = options.execArgs.concat(options.nodeArgs);
|
||||
}
|
||||
|
||||
// note: indexOf('coffee') handles both .coffee and .litcoffee
|
||||
if (!execDefined && options.exec === 'node' &&
|
||||
scriptExt.indexOf('coffee') !== -1) {
|
||||
options.exec = 'coffee';
|
||||
|
||||
// we need to get execArgs set before the script
|
||||
// for example, in `nodemon --debug my-script.coffee --my-flag`, debug is an
|
||||
// execArg, while my-flag is a script arg
|
||||
var leadingArgs = (options.args || []).splice(0, options.scriptPosition);
|
||||
options.execArgs = options.execArgs.concat(leadingArgs);
|
||||
options.scriptPosition = 0;
|
||||
|
||||
if (options.execArgs.length > 0) {
|
||||
// because this is the coffee executable, we need to combine the exec args
|
||||
// into a single argument after the nodejs flag
|
||||
options.execArgs = ['--nodejs', options.execArgs.join(' ')];
|
||||
}
|
||||
}
|
||||
|
||||
if (options.exec === 'coffee') {
|
||||
// don't override user specified extension tracking
|
||||
if (options.ext === undefined) {
|
||||
if (extension) { extension += ','; }
|
||||
extension += 'coffee,litcoffee';
|
||||
}
|
||||
|
||||
// because windows can't find 'coffee', it needs the real file 'coffee.cmd'
|
||||
if (utils.isWindows) {
|
||||
options.exec += '.cmd';
|
||||
}
|
||||
}
|
||||
|
||||
// allow users to make a mistake on the extension to monitor
|
||||
// converts .js, pug => js,pug
|
||||
// BIG NOTE: user can't do this: nodemon -e *.js
|
||||
// because the terminal will automatically expand the glob against
|
||||
// the file system :(
|
||||
extension = (extension.match(/[^,*\s]+/g) || [])
|
||||
.map(ext => ext.replace(/^\./, ''))
|
||||
.join(',');
|
||||
|
||||
options.ext = extension;
|
||||
|
||||
if (options.script) {
|
||||
options.script = expandScript(options.script,
|
||||
extension && ('.' + extension.split(',')[0]));
|
||||
}
|
||||
|
||||
options.env = {};
|
||||
// make sure it's an object (and since we don't have )
|
||||
if (({}).toString.apply(nodemonOptions.env) === '[object Object]') {
|
||||
options.env = utils.clone(nodemonOptions.env);
|
||||
} else if (nodemonOptions.env !== undefined) {
|
||||
throw new Error('nodemon env values must be an object: { PORT: 8000 }');
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
93
node_modules/nodemon/lib/config/index.js
generated
vendored
Normal file
93
node_modules/nodemon/lib/config/index.js
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* Manages the internal config of nodemon, checking for the state of support
|
||||
* with fs.watch, how nodemon can watch files (using find or fs methods).
|
||||
*
|
||||
* This is *not* the user's config.
|
||||
*/
|
||||
var debug = require('debug')('nodemon');
|
||||
var load = require('./load');
|
||||
var rules = require('../rules');
|
||||
var utils = require('../utils');
|
||||
var pinVersion = require('../version').pin;
|
||||
var command = require('./command');
|
||||
var rulesToMonitor = require('../monitor/match').rulesToMonitor;
|
||||
var bus = utils.bus;
|
||||
|
||||
function reset() {
|
||||
rules.reset();
|
||||
|
||||
config.dirs = [];
|
||||
config.options = { ignore: [], watch: [], monitor: [] };
|
||||
config.lastStarted = 0;
|
||||
config.loaded = [];
|
||||
}
|
||||
|
||||
var config = {
|
||||
run: false,
|
||||
system: {
|
||||
cwd: process.cwd(),
|
||||
},
|
||||
required: false,
|
||||
dirs: [],
|
||||
timeout: 1000,
|
||||
options: {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Take user defined settings, then detect the local machine capability, then
|
||||
* look for local and global nodemon.json files and merge together the final
|
||||
* settings with the config for nodemon.
|
||||
*
|
||||
* @param {Object} settings user defined settings for nodemon (typically on
|
||||
* the cli)
|
||||
* @param {Function} ready callback fired once the config is loaded
|
||||
*/
|
||||
config.load = function (settings, ready) {
|
||||
reset();
|
||||
var config = this;
|
||||
load(settings, config.options, config, function (options) {
|
||||
config.options = options;
|
||||
|
||||
if (options.watch.length === 0) {
|
||||
// this is to catch when the watch is left blank
|
||||
options.watch.push('*.*');
|
||||
}
|
||||
|
||||
if (options['watch_interval']) { // jshint ignore:line
|
||||
options.watchInterval = options['watch_interval']; // jshint ignore:line
|
||||
}
|
||||
|
||||
config.watchInterval = options.watchInterval || null;
|
||||
if (options.signal) {
|
||||
config.signal = options.signal;
|
||||
}
|
||||
|
||||
var cmd = command(config.options);
|
||||
config.command = {
|
||||
raw: cmd,
|
||||
string: utils.stringify(cmd.executable, cmd.args),
|
||||
};
|
||||
|
||||
// now run automatic checks on system adding to the config object
|
||||
options.monitor = rulesToMonitor(options.watch, options.ignore, config);
|
||||
|
||||
var cwd = process.cwd();
|
||||
debug('config: dirs', config.dirs);
|
||||
if (config.dirs.length === 0) {
|
||||
config.dirs.unshift(cwd);
|
||||
}
|
||||
|
||||
bus.emit('config:update', config);
|
||||
pinVersion().then(function () {
|
||||
ready(config);
|
||||
}).catch(e => {
|
||||
// this doesn't help testing, but does give exposure on syntax errors
|
||||
console.error(e.stack);
|
||||
setTimeout(() => { throw e; }, 0);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
config.reset = reset;
|
||||
|
||||
module.exports = config;
|
256
node_modules/nodemon/lib/config/load.js
generated
vendored
Normal file
256
node_modules/nodemon/lib/config/load.js
generated
vendored
Normal file
|
@ -0,0 +1,256 @@
|
|||
var debug = require('debug')('nodemon');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var exists = fs.exists || path.exists;
|
||||
var utils = require('../utils');
|
||||
var rules = require('../rules');
|
||||
var parse = require('../rules/parse');
|
||||
var exec = require('./exec');
|
||||
var defaults = require('./defaults');
|
||||
|
||||
module.exports = load;
|
||||
module.exports.mutateExecOptions = mutateExecOptions;
|
||||
|
||||
var existsSync = fs.existsSync || path.existsSync;
|
||||
|
||||
function findAppScript() {
|
||||
// nodemon has been run alone, so try to read the package file
|
||||
// or try to read the index.js file
|
||||
if (existsSync('./index.js')) {
|
||||
return 'index.js';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the nodemon config, first reading the global root/nodemon.json, then
|
||||
* the local nodemon.json to the exec and then overwriting using any user
|
||||
* specified settings (i.e. from the cli)
|
||||
*
|
||||
* @param {Object} settings user defined settings
|
||||
* @param {Function} ready callback that receives complete config
|
||||
*/
|
||||
function load(settings, options, config, callback) {
|
||||
config.loaded = [];
|
||||
// first load the root nodemon.json
|
||||
loadFile(options, config, utils.home, function (options) {
|
||||
// then load the user's local configuration file
|
||||
if (settings.configFile) {
|
||||
options.configFile = path.resolve(settings.configFile);
|
||||
}
|
||||
loadFile(options, config, process.cwd(), function (options) {
|
||||
// Then merge over with the user settings (parsed from the cli).
|
||||
// Note that merge protects and favours existing values over new values,
|
||||
// and thus command line arguments get priority
|
||||
options = utils.merge(settings, options);
|
||||
|
||||
// legacy support
|
||||
if (!Array.isArray(options.ignore)) {
|
||||
options.ignore = [options.ignore];
|
||||
}
|
||||
|
||||
if (!options.ignoreRoot) {
|
||||
options.ignoreRoot = defaults.ignoreRoot;
|
||||
}
|
||||
|
||||
// blend the user ignore and the default ignore together
|
||||
if (options.ignoreRoot && options.ignore) {
|
||||
if (!Array.isArray(options.ignoreRoot)) {
|
||||
options.ignoreRoot = [options.ignoreRoot];
|
||||
}
|
||||
options.ignore = options.ignoreRoot.concat(options.ignore);
|
||||
} else {
|
||||
options.ignore = defaults.ignore.concat(options.ignore);
|
||||
}
|
||||
|
||||
|
||||
// add in any missing defaults
|
||||
options = utils.merge(options, defaults);
|
||||
|
||||
if (!options.script && !options.exec) {
|
||||
var found = findAppScript();
|
||||
if (found) {
|
||||
if (!options.args) {
|
||||
options.args = [];
|
||||
}
|
||||
// if the script is found as a result of not being on the command
|
||||
// line, then we move any of the pre double-dash args in execArgs
|
||||
const n = options.scriptPosition === null ?
|
||||
options.args.length : options.scriptPosition;
|
||||
|
||||
options.execArgs = (options.execArgs || [])
|
||||
.concat(options.args.splice(0, n));
|
||||
options.scriptPosition = null;
|
||||
|
||||
options.script = found;
|
||||
}
|
||||
}
|
||||
|
||||
mutateExecOptions(options);
|
||||
|
||||
if (options.quiet) {
|
||||
utils.quiet();
|
||||
}
|
||||
|
||||
if (options.verbose) {
|
||||
utils.debug = true;
|
||||
}
|
||||
|
||||
// simplify the ready callback to be called after the rules are normalised
|
||||
// from strings to regexp through the rules lib. Note that this gets
|
||||
// created *after* options is overwritten twice in the lines above.
|
||||
var ready = function (options) {
|
||||
normaliseRules(options, callback);
|
||||
};
|
||||
|
||||
// if we didn't pick up a nodemon.json file & there's no cli ignores
|
||||
// then try loading an old style .nodemonignore file
|
||||
if (config.loaded.length === 0) {
|
||||
var legacy = loadLegacyIgnore.bind(null, options, config, ready);
|
||||
|
||||
// first try .nodemonignore, if that doesn't exist, try nodemon-ignore
|
||||
return legacy('.nodemonignore', function () {
|
||||
legacy('nodemon-ignore', function (options) {
|
||||
ready(options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ready(options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the old style nodemonignore files which is a list of patterns
|
||||
* in a file to ignore
|
||||
*
|
||||
* @param {Object} options nodemon user options
|
||||
* @param {Function} success
|
||||
* @param {String} filename ignore file (.nodemonignore or nodemon-ignore)
|
||||
* @param {Function} fail (optional) failure callback
|
||||
*/
|
||||
function loadLegacyIgnore(options, config, success, filename, fail) {
|
||||
var ignoreFile = path.join(process.cwd(), filename);
|
||||
|
||||
exists(ignoreFile, function (exists) {
|
||||
if (exists) {
|
||||
config.loaded.push(ignoreFile);
|
||||
return parse(ignoreFile, function (error, rules) {
|
||||
options.ignore = rules.raw;
|
||||
success(options);
|
||||
});
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
fail(options);
|
||||
} else {
|
||||
success(options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function normaliseRules(options, ready) {
|
||||
// convert ignore and watch options to rules/regexp
|
||||
rules.watch.add(options.watch);
|
||||
rules.ignore.add(options.ignore);
|
||||
|
||||
// normalise the watch and ignore arrays
|
||||
options.watch = options.watch === false ? false : rules.rules.watch;
|
||||
options.ignore = rules.rules.ignore;
|
||||
|
||||
ready(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a config in the current working directory, and a config in the
|
||||
* user's home directory, merging the two together, giving priority to local
|
||||
* config. This can then be overwritten later by command line arguments
|
||||
*
|
||||
* @param {Function} ready callback to pass loaded settings to
|
||||
*/
|
||||
function loadFile(options, config, dir, ready) {
|
||||
if (!ready) {
|
||||
ready = function () { };
|
||||
}
|
||||
|
||||
var callback = function (settings) {
|
||||
// prefer the local nodemon.json and fill in missing items using
|
||||
// the global options
|
||||
ready(utils.merge(settings, options));
|
||||
};
|
||||
|
||||
if (!dir) {
|
||||
return callback({});
|
||||
}
|
||||
|
||||
var filename = options.configFile || path.join(dir, 'nodemon.json');
|
||||
|
||||
if (config.loaded.indexOf(filename) !== -1) {
|
||||
// don't bother re-parsing the same config file
|
||||
return callback({});
|
||||
}
|
||||
|
||||
fs.readFile(filename, 'utf8', function (err, data) {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
if (!options.configFile && dir !== utils.home) {
|
||||
// if no specified local config file and local nodemon.json
|
||||
// doesn't exist, try the package.json
|
||||
return loadPackageJSON(config, callback);
|
||||
}
|
||||
}
|
||||
return callback({});
|
||||
}
|
||||
|
||||
var settings = {};
|
||||
|
||||
try {
|
||||
settings = JSON.parse(data.toString('utf8').replace(/^\uFEFF/, ''));
|
||||
if (!filename.endsWith('package.json') || settings.nodemonConfig) {
|
||||
config.loaded.push(filename);
|
||||
}
|
||||
} catch (e) {
|
||||
utils.log.fail('Failed to parse config ' + filename);
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// options values will overwrite settings
|
||||
callback(settings);
|
||||
});
|
||||
}
|
||||
|
||||
function loadPackageJSON(config, ready) {
|
||||
if (!ready) {
|
||||
ready = () => { };
|
||||
}
|
||||
|
||||
const dir = process.cwd();
|
||||
const filename = path.join(dir, 'package.json');
|
||||
const packageLoadOptions = { configFile: filename };
|
||||
return loadFile(packageLoadOptions, config, dir, settings => {
|
||||
ready(settings.nodemonConfig || {});
|
||||
});
|
||||
}
|
||||
|
||||
function mutateExecOptions(options) {
|
||||
// work out the execOptions based on the final config we have
|
||||
options.execOptions = exec({
|
||||
script: options.script,
|
||||
exec: options.exec,
|
||||
args: options.args,
|
||||
scriptPosition: options.scriptPosition,
|
||||
nodeArgs: options.nodeArgs,
|
||||
execArgs: options.execArgs,
|
||||
ext: options.ext,
|
||||
env: options.env,
|
||||
}, options.execMap);
|
||||
|
||||
// clean up values that we don't need at the top level
|
||||
delete options.scriptPosition;
|
||||
delete options.script;
|
||||
delete options.args;
|
||||
delete options.ext;
|
||||
|
||||
return options;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue