Prettier all files, update dependencies

This commit is contained in:
Vjacheslav Trushkin 2020-07-22 20:48:17 +03:00
parent 6adfc9d131
commit d28f8f095f
23 changed files with 2737 additions and 2323 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
[{*.json,*.yml}]
indent_style = space
indent_size = 2

7
.prettierrc Normal file
View File

@ -0,0 +1,7 @@
{
"trailingComma": "es5",
"singleQuote": true,
"useTabs": true,
"semi": true,
"quoteProps": "consistent"
}

102
app.js
View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
// Load required modules
const fs = require('fs'),
@ -21,13 +21,15 @@ process.on('uncaughtException', function (err) {
// Create application
let app = {
root: __dirname
root: __dirname,
};
/**
* Load config.json and config-default.json
*/
app.config = JSON.parse(fs.readFileSync(__dirname + '/config-default.json', 'utf8'));
app.config = JSON.parse(
fs.readFileSync(__dirname + '/config-default.json', 'utf8')
);
try {
let customConfig = fs.readFileSync(__dirname + '/config.json', 'utf8');
@ -76,7 +78,10 @@ if (app.config['env-port'] && process.env.PORT) {
if (!app.config['env-region'] && process.env.region) {
app.config.region = process.env.region;
}
if (app.config.region.length > 10 || !app.config.region.match(/^[a-z0-9_-]+$/i)) {
if (
app.config.region.length > 10 ||
!app.config.region.match(/^[a-z0-9_-]+$/i)
) {
app.config.region = '';
app.error('Invalid value for region config variable.');
}
@ -84,7 +89,9 @@ if (app.config.region.length > 10 || !app.config.region.match(/^[a-z0-9_-]+$/i))
// Reload secret key
if (app.config['reload-secret'] === '') {
// Add reload-secret to config.json to be able to run /reload?key=your-secret-key that will reload collections without restarting server
console.log('reload-secret configuration is empty. You will not be able to update all collections without restarting server.');
console.log(
'reload-secret configuration is empty. You will not be able to update all collections without restarting server.'
);
}
/**
@ -92,7 +99,9 @@ if (app.config['reload-secret'] === '') {
*/
// Get version
app.version = JSON.parse(fs.readFileSync(__dirname + '/package.json', 'utf8')).version;
app.version = JSON.parse(
fs.readFileSync(__dirname + '/package.json', 'utf8')
).version;
// Files helper
app.fs = require('./src/files')(app);
@ -103,7 +112,9 @@ app.loadJSON = require('./src/json').bind(this, app);
// Add directories storage
app.dirs = require('./src/dirs')(app);
if (!app.dirs.getRepos().length) {
console.error('No repositories found. Make sure either Iconify or custom repository is set in configuration.');
console.error(
'No repositories found. Make sure either Iconify or custom repository is set in configuration.'
);
return;
}
@ -120,8 +131,8 @@ app.iconsRequest = require('./src/request-icons').bind(this, app);
app.miscRequest = require('./src/request').bind(this, app);
// Start application
require('./src/startup')(app).then(() => {
require('./src/startup')(app)
.then(() => {
// Create HTTP server
app.server = express();
@ -131,20 +142,38 @@ require('./src/startup')(app).then(() => {
// CORS
app.server.options('/*', (req, res) => {
if (app.config.cors) {
res.header('Access-Control-Allow-Origin', app.config.cors.origins);
res.header('Access-Control-Allow-Methods', app.config.cors.methods);
res.header('Access-Control-Allow-Headers', app.config.cors.headers);
res.header(
'Access-Control-Allow-Origin',
app.config.cors.origins
);
res.header(
'Access-Control-Allow-Methods',
app.config.cors.methods
);
res.header(
'Access-Control-Allow-Headers',
app.config.cors.headers
);
res.header('Access-Control-Max-Age', app.config.cors.timeout);
}
res.send(200);
});
// GET 3 part request
app.server.get(/^\/([a-z0-9-]+)\/([a-z0-9-]+)\.(js|json|svg)$/, (req, res) => {
app.server.get(
/^\/([a-z0-9-]+)\/([a-z0-9-]+)\.(js|json|svg)$/,
(req, res) => {
// prefix/icon.svg
// prefix/icons.json
app.iconsRequest(req, res, req.params[0], req.params[1], req.params[2]);
});
app.iconsRequest(
req,
res,
req.params[0],
req.params[1],
req.params[2]
);
}
);
// GET 2 part JS/JSON request
app.server.get(/^\/([a-z0-9-]+)\.(js|json)$/, (req, res) => {
@ -166,7 +195,13 @@ require('./src/startup')(app).then(() => {
parts = parts[0].split('-');
if (parts.length > 1) {
// prefix-icon.svg
app.iconsRequest(req, res, parts.shift(), parts.join('-'), 'svg');
app.iconsRequest(
req,
res,
parts.shift(),
parts.join('-'),
'svg'
);
return;
}
}
@ -175,19 +210,33 @@ require('./src/startup')(app).then(() => {
});
// Send robots.txt that disallows everything
app.server.get('/robots.txt', (req, res) => app.miscRequest(req, res, 'robots'));
app.server.post('/robots.txt', (req, res) => app.miscRequest(req, res, 'robots'));
app.server.get('/robots.txt', (req, res) =>
app.miscRequest(req, res, 'robots')
);
app.server.post('/robots.txt', (req, res) =>
app.miscRequest(req, res, 'robots')
);
// API version information
app.server.get('/version', (req, res) => app.miscRequest(req, res, 'version'));
app.server.get('/version', (req, res) =>
app.miscRequest(req, res, 'version')
);
// Reload collections without restarting app
app.server.get('/reload', (req, res) => app.miscRequest(req, res, 'reload'));
app.server.post('/reload', (req, res) => app.miscRequest(req, res, 'reload'));
app.server.get('/reload', (req, res) =>
app.miscRequest(req, res, 'reload')
);
app.server.post('/reload', (req, res) =>
app.miscRequest(req, res, 'reload')
);
// Get latest collection from Git repository
app.server.get('/sync', (req, res) => app.miscRequest(req, res, 'sync'));
app.server.post('/sync', (req, res) => app.miscRequest(req, res, 'sync'));
app.server.get('/sync', (req, res) =>
app.miscRequest(req, res, 'sync')
);
app.server.post('/sync', (req, res) =>
app.miscRequest(req, res, 'sync')
);
// Redirect home page
app.server.get('/', (req, res) => {
@ -198,10 +247,7 @@ require('./src/startup')(app).then(() => {
app.server.listen(app.config.port, () => {
app.log('Listening on port ' + app.config.port);
});
}).catch(err => {
})
.catch(err => {
console.error(err);
});

36
package-lock.json generated
View File

@ -10,9 +10,9 @@
"optional": true
},
"@iconify/json-tools": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@iconify/json-tools/-/json-tools-1.0.6.tgz",
"integrity": "sha512-mBM+Zk1rodeQ+RdpHj4RWFBMErC0YTca5npOlNqJr/6TFjHN5qnY7GYWe4rf/poB6L9BYrJ73irz1hyeLE1CDA=="
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@iconify/json-tools/-/json-tools-1.0.9.tgz",
"integrity": "sha512-l/c2siIH6shOSrGXgjiO5bax8uZgEZPoBARPezVg10SmSg/FIlD4tkqclqnbz09/Ya2baOjlF0YrHUFo9yk3Jg=="
},
"accepts": {
"version": "1.3.7",
@ -333,13 +333,13 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"media-typer": {
"version": "0.3.0",
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
@ -358,16 +358,16 @@
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"requires": {
"mime-db": "1.40.0"
"mime-db": "1.44.0"
}
},
"minimatch": {
@ -480,12 +480,12 @@
"dev": true
},
"proxy-addr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
"integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.0"
"ipaddr.js": "1.9.1"
}
},
"qs": {

View File

@ -13,7 +13,7 @@
"homepage": "https://github.com/iconify/api.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/iconify/api.js.git"
"url": "https://github.com/iconify/api.js.git"
},
"dependencies": {
"@iconify/json-tools": "^1.0.6",

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const fs = require('fs');
@ -32,7 +32,7 @@ module.exports = app => {
* @param {string} repo
* @returns {string}
*/
functions.rootDir = repo => dirs[repo] === void 0 ? '' : dirs[repo];
functions.rootDir = repo => (dirs[repo] === void 0 ? '' : dirs[repo]);
/**
* Get storage directory
@ -101,7 +101,11 @@ module.exports = app => {
custom[repo] = time;
functions.setRootDir(repo, dir);
if (save === true) {
fs.writeFileSync(versionsFile, JSON.stringify(custom, null, 4), 'utf8');
fs.writeFileSync(
versionsFile,
JSON.stringify(custom, null, 4),
'utf8'
);
}
};
@ -154,8 +158,7 @@ module.exports = app => {
if (storageDir !== null) {
try {
fs.mkdirSync(storageDir);
} catch (err) {
}
} catch (err) {}
}
// Set default directories
@ -171,7 +174,9 @@ module.exports = app => {
repos.push(key);
dirs[key] = icons.rootDir();
} catch (err) {
app.error('Cannot load Iconify icons because @iconify/json package is not installed');
app.error(
'Cannot load Iconify icons because @iconify/json package is not installed'
);
}
}
}
@ -182,7 +187,10 @@ module.exports = app => {
if (cached[key]) {
functions.setSynchronizedRepoDir(key, cached[key], false);
} else {
dirs[key] = app.config['custom-icons-dir'].replace('{dir}', app.root);
dirs[key] = app.config['custom-icons-dir'].replace(
'{dir}',
app.root
);
}
}

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const fs = require('fs');
const util = require('util');
@ -23,15 +23,24 @@ let functions = {
* @param options
* @return {Promise<any>}
*/
unlink: (file, options) => new Promise((fulfill, reject) => {
unlink: (file, options) =>
new Promise((fulfill, reject) => {
fs.unlink(file, err => {
if (err) {
_app.error('Error deleting file ' + file, Object.assign({
key: 'unlink-' + file
}, typeof options === 'object' ? options : Object.create(null)));
_app.error(
'Error deleting file ' + file,
Object.assign(
{
key: 'unlink-' + file,
},
typeof options === 'object'
? options
: Object.create(null)
)
);
}
fulfill();
})
});
}),
/**
@ -41,15 +50,23 @@ let functions = {
* @param options
* @return {Promise<any>}
*/
rmdir: (dir, options) => new Promise((fulfill, reject) => {
options = typeof options === 'object' ? options : Object.create(null);
rmdir: (dir, options) =>
new Promise((fulfill, reject) => {
options =
typeof options === 'object' ? options : Object.create(null);
function done() {
fs.rmdir(dir, err => {
if (err) {
_app.error('Error deleting directory ' + dir, Object.assign({
key: 'rmdir-' + dir
}, options));
_app.error(
'Error deleting directory ' + dir,
Object.assign(
{
key: 'rmdir-' + dir,
},
options
)
);
}
fulfill();
});
@ -84,16 +101,27 @@ let functions = {
} else {
return functions.unlink(file, options);
}
}).then(() => {
done();
}).catch(err => {
_app.error('Error recursively removing directory ' + dir + '\n' + util.format(err), Object.assign({
key: 'rmdir-' + dir
}, options));
done();
});
});
})
.then(() => {
done();
})
.catch(err => {
_app.error(
'Error recursively removing directory ' +
dir +
'\n' +
util.format(err),
Object.assign(
{
key: 'rmdir-' + dir,
},
options
)
);
done();
});
});
}),
};
module.exports = app => {

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const fs = require('fs');
const util = require('util');
@ -23,7 +23,8 @@ let imported = Object.create(null);
* @param {*} [hash] Hash of previously loaded file. If hashes match, load will be aborted
* @returns {Promise}
*/
module.exports = (app, file, hash) => new Promise((fulfill, reject) => {
module.exports = (app, file, hash) =>
new Promise((fulfill, reject) => {
let newHash = null,
result;
@ -44,9 +45,11 @@ module.exports = (app, file, hash) => new Promise((fulfill, reject) => {
result.data = data;
fulfill(result);
});
stream.pipe(JSONStream.parse(true)).pipe(es.mapSync(res => {
stream.pipe(JSONStream.parse(true)).pipe(
es.mapSync(res => {
data = res;
}));
})
);
}
/**
@ -90,14 +93,14 @@ module.exports = (app, file, hash) => new Promise((fulfill, reject) => {
if (newHash && newHash === hash) {
fulfill({
changed: false,
hash: newHash
hash: newHash,
});
return;
}
result = {
changed: true,
hash: newHash
hash: newHash,
};
// Figure out which parser to use
@ -106,9 +109,9 @@ module.exports = (app, file, hash) => new Promise((fulfill, reject) => {
// 'stream' is
let parser = 'parse';
try {
parser = typeof app === 'string' ? app : app.config['json-loader'];
} catch(err) {
}
parser =
typeof app === 'string' ? app : app.config['json-loader'];
} catch (err) {}
switch (parser) {
case 'stream':
@ -118,7 +121,9 @@ module.exports = (app, file, hash) => new Promise((fulfill, reject) => {
imported.JSONStream = require('JSONStream');
imported.eventStream = require('event-stream');
} catch (err) {
console.error('Cannot use stream JSON parser because JSONStream or event-stream module is not available. Switching to default parser.');
console.error(
'Cannot use stream JSON parser because JSONStream or event-stream module is not available. Switching to default parser.'
);
imported.JSONStream = null;
}
}

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const util = require('util');
@ -22,7 +22,7 @@ const defaultOptions = {
key: null,
// Console object
console: console
console: console,
};
// List of notices that are sent only once per session
@ -54,9 +54,17 @@ const sendQueue = app => {
* @param {object|boolean} [options]
*/
module.exports = (app, error, message, options) => {
options = Object.assign(Object.create(null), defaultOptions, options === void 0 ? Object.create(null) : (typeof options === 'boolean' ? {
log: options
}: options));
options = Object.assign(
Object.create(null),
defaultOptions,
options === void 0
? Object.create(null)
: typeof options === 'boolean'
? {
log: options,
}
: options
);
// Convert to test
if (typeof message !== 'string') {
@ -65,7 +73,14 @@ module.exports = (app, error, message, options) => {
// Get time stamp
let time = new Date();
time = (time.getUTCHours() > 9 ? '[' : '[0') + time.getUTCHours() + (time.getUTCMinutes() > 9 ? ':' : ':0') + time.getUTCMinutes() + (time.getUTCSeconds() > 9 ? ':' : ':0') + time.getUTCSeconds() + '] ';
time =
(time.getUTCHours() > 9 ? '[' : '[0') +
time.getUTCHours() +
(time.getUTCMinutes() > 9 ? ':' : ':0') +
time.getUTCMinutes() +
(time.getUTCSeconds() > 9 ? ':' : ':0') +
time.getUTCSeconds() +
'] ';
// Copy message to console
if (options.log || !app.mail) {
@ -118,7 +133,7 @@ module.exports = (app, error, message, options) => {
} catch (err) {
delay = 60;
}
setTimeout(sendQueue.bind(null, app), delay * 1000)
setTimeout(sendQueue.bind(null, app), delay * 1000);
}
throttled.push(message);
};

View File

@ -7,20 +7,24 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
class Logger {
constructor(app, subject, delay) {
this.app = app;
this.subject = subject;
this.messages = [];
this.delay = typeof delay === 'number' ? Math.min(Math.max(delay, 15), 300) : 60;
this.delay =
typeof delay === 'number' ? Math.min(Math.max(delay, 15), 300) : 60;
this.throttled = false;
}
send() {
if (this.messages.length) {
this.app.mail((this.subject ? this.subject + '\n\n' : '') + this.messages.join('\n'));
this.app.mail(
(this.subject ? this.subject + '\n\n' : '') +
this.messages.join('\n')
);
this.messages = [];
}
}

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
let nodemailer;
@ -38,7 +38,7 @@ module.exports = (app, message) => {
from: config.from,
to: config.to,
subject: config.subject,
text: message
text: message,
};
// Send email

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
/**
* Alternative to Promise.all() that runs each promise after another, not simultaneously
@ -16,7 +16,8 @@
* @param callback
* @returns {Promise<any>}
*/
module.exports = (list, callback) => new Promise((fulfill, reject) => {
module.exports = (list, callback) =>
new Promise((fulfill, reject) => {
let results = [],
index = -1,
total = list.length;
@ -34,12 +35,14 @@ module.exports = (list, callback) => new Promise((fulfill, reject) => {
next();
return;
}
promise.then(result => {
promise
.then(result => {
results.push(result);
next();
}).catch(err => {
reject(err);
})
.catch(err => {
reject(err);
});
}
next();

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const fs = require('fs');
const util = require('util');
@ -16,7 +16,7 @@ const Collection = require('@iconify/json-tools').Collection;
const defaultOptions = {
// Logger instance
logger: null
logger: null,
};
let repoItems = Object.create(null),
@ -42,7 +42,9 @@ class Loader {
* @private
*/
_prettyFile(filename) {
return filename.slice(0, this.app.root.length) === this.app.root ? filename.slice(this.app.root.length + 1) : filename;
return filename.slice(0, this.app.root.length) === this.app.root
? filename.slice(this.app.root.length + 1)
: filename;
}
/**
@ -52,11 +54,18 @@ class Loader {
*/
findCollections() {
return new Promise((fulfill, reject) => {
promiseEach(this.repos, repo => new Promise((fulfill, reject) => {
promiseEach(
this.repos,
repo =>
new Promise((fulfill, reject) => {
// Get directory
let dir = this.app.dirs.iconsDir(repo);
if (dir === '') {
reject('Missing directory for repository "' + repo + '"');
reject(
'Missing directory for repository "' +
repo +
'"'
);
return;
}
@ -64,7 +73,12 @@ class Loader {
fs.readdir(dir, (err, files) => {
let items = [];
if (err) {
reject('Error reading directory: ' + this._prettyFile(dir) + '\n' + util.format(err));
reject(
'Error reading directory: ' +
this._prettyFile(dir) +
'\n' +
util.format(err)
);
return;
}
files.forEach(file => {
@ -75,12 +89,14 @@ class Loader {
repo: repo,
file: file,
filename: dir + '/' + file,
prefix: file.slice(0, file.length - 5)
prefix: file.slice(0, file.length - 5),
});
});
fulfill(items);
});
})).then(results => {
})
)
.then(results => {
let items = [];
results.forEach(result => {
@ -98,19 +114,34 @@ class Loader {
if (collectionRepos[item.prefix] !== item.repo) {
// Conflict: same prefix in multiple repositories
this.app.error('Collection "' + item.prefix + '" is found in multiple repositories. Ignoring json file from ' + item.repo + ', using file from ' + collectionRepos[item.prefix], Object.assign({
key: 'json-duplicate/' + item.repo + '/' + item.prefix
}, this.options));
this.app.error(
'Collection "' +
item.prefix +
'" is found in multiple repositories. Ignoring json file from ' +
item.repo +
', using file from ' +
collectionRepos[item.prefix],
Object.assign(
{
key:
'json-duplicate/' +
item.repo +
'/' +
item.prefix,
},
this.options
)
);
return;
}
// Everything is fine
items.push(item);
});
});
fulfill(items);
}).catch(err => {
})
.catch(err => {
reject(err);
});
});
@ -127,11 +158,21 @@ class Loader {
let total;
// Load all files
promiseEach(items, item => new Promise((fulfill, reject) => {
promiseEach(
items,
item =>
new Promise((fulfill, reject) => {
let collection;
// Load JSON file
this.app.loadJSON(item.filename, hashes[item.prefix] === void 0 ? null : hashes[item.prefix]).then(result => {
this.app
.loadJSON(
item.filename,
hashes[item.prefix] === void 0
? null
: hashes[item.prefix]
)
.then(result => {
if (!result.changed) {
// Nothing to do
fulfill(true);
@ -139,20 +180,32 @@ class Loader {
}
return this.loadCollection(item, result);
}).then(result => {
})
.then(result => {
collection = result;
// Run post-load function if there is one
if (this.app.postLoadCollection) {
return this.app.postLoadCollection(collection, this.options);
return this.app.postLoadCollection(
collection,
this.options
);
}
}).then(() => {
})
.then(() => {
fulfill(collection);
}).catch(err => {
reject('Error loading json file: ' + this._prettyFile(item.filename) + '\n' + util.format(err));
})
.catch(err => {
reject(
'Error loading json file: ' +
this._prettyFile(item.filename) +
'\n' +
util.format(err)
);
});
})).then(collections => {
})
)
.then(collections => {
let loaded = 0,
skipped = 0;
@ -167,19 +220,46 @@ class Loader {
let count = Object.keys(collection.items.icons).length,
prefix = collection.prefix();
this.app.log('Loaded collection ' + prefix + ' from ' + collection.filename + ' (' + count + ' icons)', this.options);
this.app.log(
'Loaded collection ' +
prefix +
' from ' +
collection.filename +
' (' +
count +
' icons)',
this.options
);
total += count;
this.app.collections[prefix] = collection;
});
this.app.log('Loaded ' + total + ' icons from ' + loaded + (loaded > 1 ? ' collections ' : ' collection ') + (skipped ? '(no changes in ' + skipped + (skipped > 1 ? ' collections) ' : ' collection) ') : '') + 'in ' + (Date.now() - this.start) / 1000 + ' seconds.', this.options);
this.app.log(
'Loaded ' +
total +
' icons from ' +
loaded +
(loaded > 1 ? ' collections ' : ' collection ') +
(skipped
? '(no changes in ' +
skipped +
(skipped > 1
? ' collections) '
: ' collection) ')
: '') +
'in ' +
(Date.now() - this.start) / 1000 +
' seconds.',
this.options
);
if (this.reloadInfo) {
return this.getCollectionsJSON();
}
}).then(() => {
})
.then(() => {
fulfill(total);
}).catch(err => {
})
.catch(err => {
reject(err);
});
});
@ -192,17 +272,26 @@ class Loader {
*/
getCollectionsJSON() {
return new Promise((fulfill, reject) => {
let filename = this.app.dirs.rootDir('iconify') + '/collections.json';
let filename =
this.app.dirs.rootDir('iconify') + '/collections.json';
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
reject('Error locating collections.json for Iconify default icons.\n' + util.format(err));
reject(
'Error locating collections.json for Iconify default icons.\n' +
util.format(err)
);
return;
}
try {
data = JSON.parse(data);
} catch (err) {
reject('Error reading contents of' + filename + '\n' + util.format(err));
reject(
'Error reading contents of' +
filename +
'\n' +
util.format(err)
);
return;
}
@ -224,7 +313,13 @@ class Loader {
let collection = new Collection();
if (!collection.loadJSON(data.data, item.prefix)) {
delete data.data;
reject('Error loading collection "' + item.prefix + '" from repository "' + item.repo + '": error parsing JSON');
reject(
'Error loading collection "' +
item.prefix +
'" from repository "' +
item.repo +
'": error parsing JSON'
);
return;
}
delete data.data;
@ -232,7 +327,14 @@ class Loader {
let prefix = collection.prefix();
if (prefix !== item.prefix) {
delete collection.items;
reject('Error loading collection "' + item.prefix + '" from repository "' + item.repo + '": invalid prefix in JSON file: ' + prefix);
reject(
'Error loading collection "' +
item.prefix +
'" from repository "' +
item.repo +
'": invalid prefix in JSON file: ' +
prefix
);
return;
}
@ -256,9 +358,14 @@ class Loader {
* @param {Array|string|boolean} [repos] Repositories to reload
* @param {object} [options]
*/
module.exports = (app, repos, options) => new Promise((fulfill, reject) => {
module.exports = (app, repos, options) =>
new Promise((fulfill, reject) => {
// Options
options = Object.assign(Object.create(null), defaultOptions, typeof options === 'object' ? options : Object.create(null));
options = Object.assign(
Object.create(null),
defaultOptions,
typeof options === 'object' ? options : Object.create(null)
);
// Get list of repositories to reload
let availableRepos = app.dirs.getRepos();
@ -318,26 +425,31 @@ module.exports = (app, repos, options) => new Promise((fulfill, reject) => {
count;
app.reloading = true;
loader.findCollections().then(items => {
loader
.findCollections()
.then(items => {
return loader.loadCollections(items);
}).then(total => {
})
.then(total => {
count = total;
// Run post-load function if there is one
if (app.postReload) {
return app.postReload(loader.updated, options);
}
}).then(() => {
})
.then(() => {
// Do not allow /reload for 30 seconds
nextReload = Date.now() + 30000;
// Done
fulfill({
icons: count,
updated: loader.updated
updated: loader.updated,
});
app.reloading = false;
}).catch(err => {
})
.catch(err => {
reject(err);
app.reloading = false;
});

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const SVG = require('@iconify/json-tools').SVG;
@ -62,7 +62,7 @@ module.exports = (app, req, res, prefix, query, ext) => {
return {
filename: query + '.svg',
type: 'image/svg+xml; charset=utf-8',
body: generateSVG(icon, params)
body: generateSVG(icon, params),
};
case 'js':
@ -76,14 +76,17 @@ module.exports = (app, req, res, prefix, query, ext) => {
if (result === null || !Object.keys(result.icons).length) {
return 404;
}
if (result.aliases !== void 0 && !Object.keys(result.aliases).length) {
if (
result.aliases !== void 0 &&
!Object.keys(result.aliases).length
) {
delete result.aliases;
}
return {
js: ext === 'js',
defaultCallback: 'SimpleSVG._loaderCallback',
data: result
data: result,
};
default:

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
/**
* Parse request
@ -29,14 +29,14 @@ module.exports = (app, req, res, query) => {
body += ')';
app.response(req, res, {
type: 'text/plain',
body: body
body: body,
});
return;
case 'robots':
app.response(req, res, {
type: 'text/plain',
body: 'User-agent: *\nDisallow: /'
body: 'User-agent: *\nDisallow: /',
});
return;
@ -45,11 +45,21 @@ module.exports = (app, req, res, query) => {
app.response(req, res, 200);
// Do stuff
if (app.config['reload-secret'].length && req.query && typeof req.query.key === 'string' && req.query.key === app.config['reload-secret'] && !app.reloading) {
if (
app.config['reload-secret'].length &&
req.query &&
typeof req.query.key === 'string' &&
req.query.key === app.config['reload-secret'] &&
!app.reloading
) {
process.nextTick(() => {
app.reload(false).then(() => {
}).catch(err => {
app.error('Error reloading collections:\n' + util.format(err));
app.reload(false)
.then(() => {})
.catch(err => {
app.error(
'Error reloading collections:\n' +
util.format(err)
);
});
});
}
@ -60,7 +70,13 @@ module.exports = (app, req, res, query) => {
app.response(req, res, 200);
let repo = req.query.repo;
if (typeof repo !== 'string' || !app.config.canSync || !app.config.sync[repo] || !app.config.sync.git || !app.config.sync.secret) {
if (
typeof repo !== 'string' ||
!app.config.canSync ||
!app.config.sync[repo] ||
!app.config.sync.git ||
!app.config.sync.secret
) {
return;
}
@ -70,8 +86,9 @@ module.exports = (app, req, res, query) => {
}
process.nextTick(() => {
app.sync(repo).then(() => {
}).catch(err => {
app.sync(repo)
.then(() => {})
.catch(err => {
app.error(err);
});
});

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
/**
* Regexp for checking callback attribute
@ -35,7 +35,10 @@ module.exports = (app, req, res, result) => {
// Convert JSON(P) response
if (result.body === void 0 && result.data !== void 0) {
if (typeof result.data === 'object') {
result.body = (req.query.pretty === '1' || req.query.pretty === 'true') ? JSON.stringify(result.data, null, 4) : JSON.stringify(result.data);
result.body =
req.query.pretty === '1' || req.query.pretty === 'true'
? JSON.stringify(result.data, null, 4)
: JSON.stringify(result.data);
}
if (result.js === void 0) {
@ -52,7 +55,10 @@ module.exports = (app, req, res, result) => {
return;
}
} else {
callback = result.callback === void 0 ? result.defaultCallback : result.callback;
callback =
result.callback === void 0
? result.defaultCallback
: result.callback;
if (callback === void 0) {
res.sendStatus(400);
return;
@ -67,19 +73,35 @@ module.exports = (app, req, res, result) => {
// Send cache header
if (
app.config.cache && app.config.cache.timeout &&
(req.get('Pragma') === void 0 || req.get('Pragma').indexOf('no-cache') === -1) &&
(req.get('Cache-Control') === void 0 || req.get('Cache-Control').indexOf('no-cache') === -1)
app.config.cache &&
app.config.cache.timeout &&
(req.get('Pragma') === void 0 ||
req.get('Pragma').indexOf('no-cache') === -1) &&
(req.get('Cache-Control') === void 0 ||
req.get('Cache-Control').indexOf('no-cache') === -1)
) {
res.set('Cache-Control', (app.config.cache.private ? 'private' : 'public') + ', max-age=' + app.config.cache.timeout + ', min-refresh=' + app.config.cache['min-refresh']);
res.set(
'Cache-Control',
(app.config.cache.private ? 'private' : 'public') +
', max-age=' +
app.config.cache.timeout +
', min-refresh=' +
app.config.cache['min-refresh']
);
if (!app.config.cache.private) {
res.set('Pragma', 'cache');
}
}
// Check for download
if (result.filename !== void 0 && (req.query.download === '1' || req.query.download === 'true')) {
res.set('Content-Disposition', 'attachment; filename="' + result.filename + '"');
if (
result.filename !== void 0 &&
(req.query.download === '1' || req.query.download === 'true')
) {
res.set(
'Content-Disposition',
'attachment; filename="' + result.filename + '"'
);
}
// Send data

View File

@ -7,12 +7,13 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const util = require('util');
const promiseEach = require('./promise');
module.exports = app => new Promise((fulfill, reject) => {
module.exports = app =>
new Promise((fulfill, reject) => {
let actions = [],
logger = app.logger('Starting API...', 60),
start = Date.now();
@ -23,12 +24,14 @@ module.exports = app => new Promise((fulfill, reject) => {
case 'always':
case 'missing':
app.dirs.getRepos().forEach(repo => {
if (app.sync[repo] && (
app.config['sync-on-startup'] === 'always' || !app.dirs.synchronized(repo)
)) {
if (
app.sync[repo] &&
(app.config['sync-on-startup'] === 'always' ||
!app.dirs.synchronized(repo))
) {
actions.push({
action: 'sync',
repo: repo
repo: repo,
});
}
});
@ -38,24 +41,32 @@ module.exports = app => new Promise((fulfill, reject) => {
// Load icons
actions.push({
action: 'load'
action: 'load',
});
// Parse each promise
promiseEach(actions, action => new Promise((fulfill, reject) => {
promiseEach(
actions,
action =>
new Promise((fulfill, reject) => {
switch (action.action) {
case 'load':
// Load icons
app.reload(null, {
logger: logger
}).then(() => {
logger: logger,
})
.then(() => {
if (!Object.keys(app.collections).length) {
reject('No collections were found.');
} else {
fulfill();
}
}).catch(err => {
reject('Error loading collections: ' + util.format(err));
})
.catch(err => {
reject(
'Error loading collections: ' +
util.format(err)
);
});
return;
@ -64,19 +75,35 @@ module.exports = app => new Promise((fulfill, reject) => {
app.sync(action.repo, {
noDelay: true,
reload: false,
logger: logger
}).then(res => {
logger: logger,
})
.then(res => {
fulfill();
}).catch(err => {
reject('Error synchronizing repository "' + repo + '": ' + util.format(err));
})
.catch(err => {
reject(
'Error synchronizing repository "' +
repo +
'": ' +
util.format(err)
);
});
return;
}
})).then(() => {
logger.log('\nStart up process completed in ' + (Date.now() - start) / 1000 + ' seconds.');
})
)
.then(() => {
logger.log(
'\nStart up process completed in ' +
(Date.now() - start) / 1000 +
' seconds.'
);
fulfill();
}).catch(err => {
logger.error('\nStart up process failed!\n\n' + util.format(err));
})
.catch(err => {
logger.error(
'\nStart up process failed!\n\n' + util.format(err)
);
reject(err);
});
});

View File

@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
"use strict";
'use strict';
const fs = require('fs');
const util = require('util');
@ -16,7 +16,7 @@ const child_process = require('child_process');
const defaultOptions = {
logger: null,
noDelay: false,
reload: true
reload: true,
};
let active = Object.create(null),
@ -31,19 +31,27 @@ class Sync {
sync() {
return new Promise((fulfill, reject) => {
this.app.log('Synchronizing repository "' + this.repo + '"...', this.options);
this.app.log(
'Synchronizing repository "' + this.repo + '"...',
this.options
);
let time = Date.now(),
root = this.app.dirs.storageDir(),
targetDir = root + '/' + this.repo + '.' + time,
repoURL = this.app.config.sync[this.repo],
cmd = this.app.config.sync.git.replace('{target}', '"' + targetDir + '"').replace('{repo}', '"' + repoURL + '"');
cmd = this.app.config.sync.git
.replace('{target}', '"' + targetDir + '"')
.replace('{repo}', '"' + repoURL + '"');
child_process.exec(cmd, {
child_process.exec(
cmd,
{
cwd: root,
env: process.env,
uid: process.getuid()
}, (error, stdout, stderr) => {
uid: process.getuid(),
},
(error, stdout, stderr) => {
if (error) {
reject('Error executing git:' + util.format(error));
return;
@ -53,7 +61,8 @@ class Sync {
this.app.dirs.setSynchronizedRepoDir(this.repo, time, true);
fulfill(true);
});
}
);
});
}
@ -71,7 +80,8 @@ class Sync {
queued[repo] = false;
let sync = new Sync(app, repo, options);
sync.sync(fulfill, reject).then(() => {
sync.sync(fulfill, reject)
.then(() => {
active[repo] = false;
if (queued[repo]) {
// Retry
@ -81,7 +91,14 @@ class Sync {
} catch (err) {
retryDelay = 60;
}
app.log('Repository "' + repo + '" has finished synchronizing, but there is another sync request queued. Will do another sync in ' + retryDelay + ' seconds.', options);
app.log(
'Repository "' +
repo +
'" has finished synchronizing, but there is another sync request queued. Will do another sync in ' +
retryDelay +
' seconds.',
options
);
setTimeout(() => {
Sync.sync(app, repo, options, fulfill, reject);
@ -90,35 +107,55 @@ class Sync {
}
// Done
app.log('Completed synchronization of repository "' + repo + '".', options);
app.log(
'Completed synchronization of repository "' + repo + '".',
options
);
if (options.reload && !queued[repo]) {
app.reload(repo, options).then(() => {
app.reload(repo, options)
.then(() => {
fulfill(true);
}).catch(err => {
})
.catch(err => {
reject(err);
});
} else {
fulfill(true);
}
}).catch(err => {
reject(err);
})
.catch(err => {
reject(err);
});
}
}
module.exports = (app, repo, options) => new Promise((fulfill, reject) => {
module.exports = (app, repo, options) =>
new Promise((fulfill, reject) => {
// Options
options = Object.assign(Object.create(null), defaultOptions, typeof options !== 'object' ? options : Object.create(null));
options = Object.assign(
Object.create(null),
defaultOptions,
typeof options !== 'object' ? options : Object.create(null)
);
// Check if synchronization is disabled
if (!app.config.canSync || !app.config.sync[repo] || !app.config.sync.git) {
if (
!app.config.canSync ||
!app.config.sync[repo] ||
!app.config.sync.git
) {
reject('Synchronization is disabled.');
return;
}
// Check if repository sync is already in queue
if (queued[repo]) {
app.log('Repository "' + repo + '" is already in synchronization queue.', options);
app.log(
'Repository "' +
repo +
'" is already in synchronization queue.',
options
);
fulfill(false);
return;
}
@ -140,24 +177,40 @@ module.exports = (app, repo, options) => new Promise((fulfill, reject) => {
// Check if repository is already being synchronized
if (active[repo]) {
app.log('Repository "' + repo + '" is already being synchronized. Will do another sync ' + retryDelay + ' seconds after previous sync completes.', options);
app.log(
'Repository "' +
repo +
'" is already being synchronized. Will do another sync ' +
retryDelay +
' seconds after previous sync completes.',
options
);
fulfill(false);
return;
}
// Create logger if its missing
if (!options.logger) {
options.logger = app.logger('Synchronizing repository: ' + repo, delay + 15);
options.logger = app.logger(
'Synchronizing repository: ' + repo,
delay + 15
);
}
// Start time
if (!delay) {
Sync.sync(app, repo, options, fulfill, reject);
} else {
app.log('Repository "' + repo + '" will start synchronizing in ' + delay + ' seconds.', options);
app.log(
'Repository "' +
repo +
'" will start synchronizing in ' +
delay +
' seconds.',
options
);
setTimeout(() => {
Sync.sync(app, repo, options, fulfill, reject);
}, delay * 1000);
}
});

View File

@ -1,4 +1,4 @@
"use strict";
'use strict';
(() => {
const loadJSON = require('../src/json');
@ -31,20 +31,24 @@
}
// Load file
loadJSON(method, filename).then(result => {
loadJSON(method, filename)
.then(result => {
expect(result.changed).to.be.equal(true);
expect(result.data).to.be.eql(expectedResult);
// Load file with same hash
loadJSON(method, filename, result.hash).then(result2 => {
loadJSON(method, filename, result.hash)
.then(result2 => {
expect(result2.changed).to.be.equal(false);
expect(result2.hash).to.be.equal(result.hash);
done();
}).catch(err => {
})
.catch(err => {
done(err);
});
}).catch(err => {
})
.catch(err => {
done(err);
});
});

View File

@ -1,4 +1,4 @@
"use strict";
'use strict';
(() => {
const log = require('../src/log');
@ -11,11 +11,13 @@
it('logging error to console and mail', done => {
let logged = {
log: false,
mail: false
mail: false,
};
let fakeApp = {
mail: message => {
expect(message.indexOf(expectedMessage) !== false).to.be.equal(true);
expect(
message.indexOf(expectedMessage) !== false
).to.be.equal(true);
logged.mail = true;
},
logger: () => {
@ -23,28 +25,30 @@
},
config: {
mail: {
throttle: 0.2
}
}
throttle: 0.2,
},
},
};
let expectedMessage = 'This is a test';
log(fakeApp, true, expectedMessage, {
console: {
error: message => {
expect(message.indexOf(expectedMessage) !== false).to.be.equal(true);
expect(
message.indexOf(expectedMessage) !== false
).to.be.equal(true);
logged.log = true;
},
log: message => {
done('console.log should not have been called');
}
}
},
},
});
setTimeout(() => {
expect(logged).to.be.eql({
log: true,
mail: true
mail: true,
});
done();
}, 500);
@ -52,7 +56,7 @@
it('logging message to console', done => {
let logged = {
log: false
log: false,
};
let fakeApp = {
mail: message => {
@ -63,27 +67,29 @@
},
config: {
mail: {
throttle: 0.2
}
}
throttle: 0.2,
},
},
};
let expectedMessage = 'This is a test';
log(fakeApp, false, expectedMessage, {
console: {
log: message => {
expect(message.indexOf(expectedMessage) !== false).to.be.equal(true);
expect(
message.indexOf(expectedMessage) !== false
).to.be.equal(true);
logged.log = true;
},
error: message => {
done('console.log should not have been called');
}
}
},
},
});
setTimeout(() => {
expect(logged).to.be.eql({
log: true
log: true,
});
done();
}, 500);
@ -92,14 +98,16 @@
it('logging same error only once', done => {
let logged = {
log: false,
mail: false
mail: false,
};
let fakeApp = {
mail: message => {
if (logged.mail) {
done('mail() was called twice');
}
expect(message.indexOf(expectedMessage) !== false).to.be.equal(true);
expect(
message.indexOf(expectedMessage) !== false
).to.be.equal(true);
logged.mail = true;
},
logger: () => {
@ -107,35 +115,37 @@
},
config: {
mail: {
throttle: 0.2
}
}
throttle: 0.2,
},
},
};
let expectedMessage = 'This is a test',
fakeConsole = {
error: message => {
expect(message.indexOf(expectedMessage) !== false).to.be.equal(true);
expect(
message.indexOf(expectedMessage) !== false
).to.be.equal(true);
logged.log = true;
},
log: message => {
done('console.log should not have been called');
}
},
};
log(fakeApp, true, expectedMessage, {
console: fakeConsole,
key: 'test'
key: 'test',
});
log(fakeApp, true, expectedMessage, {
console: fakeConsole,
key: 'test'
key: 'test',
});
setTimeout(() => {
expect(logged).to.be.eql({
log: true,
mail: true
mail: true,
});
done();
}, 500);

View File

@ -1,4 +1,4 @@
"use strict";
'use strict';
(() => {
const chai = require('chai'),
@ -25,11 +25,19 @@
// SVG
expect(test('/foo/bar.svg')).to.be.eql(['foo', 'bar', 'svg']);
expect(test('/fa-pro/test-icon.svg')).to.be.eql(['fa-pro', 'test-icon', 'svg']);
expect(test('/fa-pro/test-icon.svg')).to.be.eql([
'fa-pro',
'test-icon',
'svg',
]);
// icons
expect(test('/foo/icons.js')).to.be.eql(['foo', 'icons', 'js']);
expect(test('/long-prefixed-v1/icons.json')).to.be.eql(['long-prefixed-v1', 'icons', 'json']);
expect(test('/long-prefixed-v1/icons.json')).to.be.eql([
'long-prefixed-v1',
'icons',
'json',
]);
// Too long
expect(test('/fa-pro/test/icon.svg')).to.be.equal(null);
@ -60,7 +68,10 @@
// icons
expect(test('/foo.js')).to.be.eql(['foo', 'js']);
expect(test('/long-prefixed-v1.json')).to.be.eql(['long-prefixed-v1', 'json']);
expect(test('/long-prefixed-v1.json')).to.be.eql([
'long-prefixed-v1',
'json',
]);
// Too long
expect(test('/fa-pro/icons.js')).to.be.equal(null);
@ -91,8 +102,12 @@
// icons
expect(test('/foo.svg')).to.be.eql(['foo']);
expect(test('/long-prefixed-v1.svg')).to.be.eql(['long-prefixed-v1']);
expect(test('/long-prefixed:icon-v1.svg')).to.be.eql(['long-prefixed:icon-v1']);
expect(test('/long-prefixed-v1.svg')).to.be.eql([
'long-prefixed-v1',
]);
expect(test('/long-prefixed:icon-v1.svg')).to.be.eql([
'long-prefixed:icon-v1',
]);
// Too long
expect(test('/fa-pro/icons.svg')).to.be.equal(null);

View File

@ -1,4 +1,4 @@
"use strict";
'use strict';
(() => {
const chai = require('chai'),
@ -13,19 +13,26 @@
const parseQuery = (prefix, query, ext, params) => {
let result = null;
request({
request(
{
// fake app
response: (req, res, data) => {
result = data;
},
collections: {
test1: collection1,
test2: collection2
}
}, {
test2: collection2,
},
},
{
// fake request
query: params
}, {}, prefix, query, ext);
query: params,
},
{},
prefix,
query,
ext
);
return result;
};
@ -36,43 +43,44 @@
icons: {
icon1: {
body: '<icon1 fill="currentColor" />',
width: 30
width: 30,
},
icon2: {
body: '<icon2 />'
}
body: '<icon2 />',
},
},
aliases: {
alias1: {
parent: 'icon2',
hFlip: true
}
hFlip: true,
},
},
width: 24,
height: 24
height: 24,
});
collection2.loadJSON({
icons: {
'test2-icon1': {
body: '<icon1 fill="currentColor" />',
width: 30
width: 30,
},
'test2-icon2': {
body: '<icon2 />'
body: '<icon2 />',
},
'test2-icon3': {
body: '<defs><foo id="bar" /></defs><bar use="url(#bar)" fill="currentColor" stroke="currentColor" />'
}
body:
'<defs><foo id="bar" /></defs><bar use="url(#bar)" fill="currentColor" stroke="currentColor" />',
},
},
aliases: {
'test2-alias1': {
parent: 'test2-icon2',
hFlip: true
}
hFlip: true,
},
},
width: 24,
height: 24
height: 24,
});
expect(collection1.items).to.not.be.equal(null);
@ -81,87 +89,101 @@
it('icons list', () => {
// Simple query with prefix
expect(parseQuery('test1', 'icons', 'js', {
icons: 'alias1'
})).to.be.eql({
expect(
parseQuery('test1', 'icons', 'js', {
icons: 'alias1',
})
).to.be.eql({
js: true,
defaultCallback: 'SimpleSVG._loaderCallback',
data: {
prefix: 'test',
icons: {
icon2: { body: '<icon2 />' }
icon2: { body: '<icon2 />' },
},
aliases: {
alias1: { parent: 'icon2', hFlip: true }
alias1: { parent: 'icon2', hFlip: true },
},
width: 24,
height: 24
}
height: 24,
},
});
// Query collection without prefix, json
expect(parseQuery('test2', 'icons', 'json', {
icons: 'alias1'
})).to.be.eql({
expect(
parseQuery('test2', 'icons', 'json', {
icons: 'alias1',
})
).to.be.eql({
js: false,
defaultCallback: 'SimpleSVG._loaderCallback',
data: {
prefix: 'test2',
icons: {
icon2: { body: '<icon2 />' }
icon2: { body: '<icon2 />' },
},
aliases: {
alias1: { parent: 'icon2', hFlip: true }
alias1: { parent: 'icon2', hFlip: true },
},
width: 24,
height: 24
}
height: 24,
},
});
// Custom callback
expect(parseQuery('test1', 'icons', 'js', {
expect(
parseQuery('test1', 'icons', 'js', {
icons: 'icon1,icon2',
callback: 'console.log'
})).to.be.eql({
callback: 'console.log',
})
).to.be.eql({
js: true,
defaultCallback: 'SimpleSVG._loaderCallback',
data: {
prefix: 'test',
icons: {
icon1: { body: '<icon1 fill="currentColor" />', width: 30 },
icon2: { body: '<icon2 />' }
icon1: {
body: '<icon1 fill="currentColor" />',
width: 30,
},
icon2: { body: '<icon2 />' },
},
width: 24,
height: 24
}
height: 24,
},
});
});
it('svg', () => {
// Simple icon
expect(parseQuery('test1', 'icon1', 'svg', {
})).to.be.eql({
expect(parseQuery('test1', 'icon1', 'svg', {})).to.be.eql({
filename: 'icon1.svg',
type: 'image/svg+xml; charset=utf-8',
body: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1.25em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><icon1 fill="currentColor" /></svg>'
body:
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1.25em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><icon1 fill="currentColor" /></svg>',
});
// Icon with custom attributes
expect(parseQuery('test2', 'alias1', 'svg', {
color: 'red'
})).to.be.eql({
expect(
parseQuery('test2', 'alias1', 'svg', {
color: 'red',
})
).to.be.eql({
filename: 'alias1.svg',
type: 'image/svg+xml; charset=utf-8',
body: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g transform="translate(24 0) scale(-1 1)"><icon2 /></g></svg>'
body:
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g transform="translate(24 0) scale(-1 1)"><icon2 /></g></svg>',
});
// Icon with id replacement
let result = parseQuery('test2', 'icon3', 'svg', {
color: 'red',
rotate: '90deg'
rotate: '90deg',
}).body.replace(/IconifyId-[0-9a-f]+-[0-9a-f]+-[0-9]+/g, 'some-id');
expect(result).to.be.equal('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g transform="rotate(90 12 12)"><defs><foo id="some-id" /></defs><bar use="url(#some-id)" fill="red" stroke="red" /></g></svg>');
expect(result).to.be.equal(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><g transform="rotate(90 12 12)"><defs><foo id="some-id" /></defs><bar use="url(#some-id)" fill="red" stroke="red" /></g></svg>'
);
});
});
})();