commit e1ef6f1f62de02e8b2d0f4beebf6a842779c3be8 Author: cyberalien Date: Fri May 5 18:29:10 2017 +0300 First public commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51941da --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea +.elasticbeanstalk +node_modules +*.log +ssl/ssl.* \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..3b6c027 --- /dev/null +++ b/.npmignore @@ -0,0 +1,5 @@ +.idea +.git +node_modules +npm-debug.log +tests diff --git a/app.js b/app.js new file mode 100644 index 0000000..440fcfe --- /dev/null +++ b/app.js @@ -0,0 +1,151 @@ +/** + * Main file to run in Node.js + * + * Run ssl.js instead of you want SSL support. + */ +"use strict"; + +/* + * Configuration + */ +// True if server should include default icons set +const serveDefaultIcons = true; + +// Directory with json files for custom icon sets +// Use simple-svg-tools package to create json collections +const customIconsDirectory = 'json'; + +// HTTP port +// Run ssl.js for SSL support +const port = process.env.PORT || 3000; + + +/* + * Main stuff + */ +const fs = require('fs'), + // Express stuff + express = require('express'), + compression = require('compression'), + app = express(), + + // Debug stuff + version = JSON.parse(fs.readFileSync('package.json', 'utf8')).version, + + // CDN stuff + cdn = require('simple-svg-cdn'); + +// Cache time +const cache = 3600; // cache time in seconds +const cacheMin = cache; // minimum cache refresh time in seconds + +// Load default collections +if (serveDefaultIcons) { + const icons = require('simple-svg-icons'); + Object.keys(icons.collections()).forEach(prefix => { + let filename = icons.locate(prefix), + data; + try { + data = fs.readFileSync(filename, 'utf8'); + data = JSON.parse(data); + cdn.deOptimize(data); + } catch (err) { + console.log(err); + return; + } + console.log('Added premade collection: ' + prefix); + cdn.addCollection(prefix, data); + }); +} + +// Add collections from "json" directory +let files; +try { + files = fs.readdirSync(customIconsDirectory); +} catch (err) { + files = []; +} +files.forEach(file => { + let list = file.split('.'); + if (list.length !== 2 || list[1] !== 'json') { + return; + } + try { + let data = fs.readFileSync(customIconsDirectory + '/' + file, 'utf8'); + data = JSON.parse(data); + cdn.deOptimize(data); + console.log('Added custom collection: ' + list[0]); + cdn.addCollection(list[0], data); + } catch (err) { + + } +}); + +// Sort collections +cdn.sortPrefixes(); + +// Disable X-Powered-By header and enable compression +app.disable('x-powered-by'); +app.use(compression({ + filter: (req, res) => true +})); + +// CORS +app.options('/*', (req, res) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET, OPTIONS'); + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding'); + res.header('Access-Control-Max-Age', 86400); + res.send(200); +}); + +// GET request +app.get(/\/([a-z0-9\-]+)\/([a-z0-9\-,]+\.(js|json|svg))?$/, (req, res) => { + let collection = cdn.findCollection(req.params[0]), + result; + + if (collection === null) { + result = 404; + } else { + result = cdn.parser(collection, req.params[1], req.query); + } + + if (typeof result === 'number') { + res.sendStatus(result); + return; + } + + // Send cache header + if ( + cache && + (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', 'public, max-age=' + cache + ', min-refresh=' + cacheMin); + } + + // Send data + res.type(result.type).send(result.body); +}); + +// Debug information and AWS health check +app.get('/version', (req, res) => { + let body = 'SimpleSVG CDN version ' + version + ' (Node'; + if (process.env.region) { + body += ', ' + process.env.region; + } + body += ')'; + res.send(body); +}); + +// Redirect home page +app.get('/', (req, res) => { + res.redirect(301, 'https://simplesvg.com/'); +}); + +// Create server +app.listen(port, () => { + console.log('Listening on port ' + port); +}); + +module.exports = app; \ No newline at end of file diff --git a/app.yaml b/app.yaml new file mode 100644 index 0000000..739fd51 --- /dev/null +++ b/app.yaml @@ -0,0 +1,4 @@ +# [START runtime] +runtime: nodejs +env: flex +# [END runtime] diff --git a/json/arty.json b/json/arty.json new file mode 100644 index 0000000..923d5ed --- /dev/null +++ b/json/arty.json @@ -0,0 +1,259 @@ +{ + "icons": { + "arty-stroke-16-arrow-left": { + "body": "" + }, + "arty-stroke-16-arrows-from-2-corners": { + "body": "" + }, + "arty-stroke-16-arrows-from-corners": { + "body": "" + }, + "arty-stroke-16-arrows-horizontal": { + "body": "" + }, + "arty-stroke-16-arrows-to-2-corners": { + "body": "" + }, + "arty-stroke-16-arrows-to-corners": { + "body": "" + }, + "arty-stroke-16-caret-up-outline": { + "body": "" + }, + "arty-stroke-16-caret-up": { + "body": "" + }, + "arty-stroke-16-carets-vertical-outline": { + "body": "" + }, + "arty-stroke-16-carets-vertical": { + "body": "" + }, + "arty-stroke-16-chevron-left": { + "body": "" + }, + "arty-stroke-16-close": { + "body": "" + }, + "arty-stroke-16-confirm": { + "body": "" + }, + "arty-stroke-16-double-arrow-horizontal": { + "body": "" + }, + "arty-stroke-16-drop-outline": { + "body": "" + }, + "arty-stroke-16-drop": { + "body": "" + }, + "arty-stroke-16-filters": { + "body": "" + }, + "arty-stroke-16-grid-3-outline": { + "body": "" + }, + "arty-stroke-16-grid-3": { + "body": "" + }, + "arty-stroke-16-list-3-outline": { + "body": "" + }, + "arty-stroke-16-list-3": { + "body": "" + }, + "arty-stroke-16-panel-left": { + "body": "" + }, + "arty-stroke-16-search": { + "body": "" + }, + "arty-stroke-20-search": { + "body": "", + "width": 160, + "height": 160 + }, + "arty-stroke-24-close": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-confirm": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-drop-outline": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-drop": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-filters": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-grid-3-outline": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-grid-3": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-list-3-outline": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-list-3": { + "body": "", + "width": 192, + "height": 192 + }, + "arty-stroke-24-search": { + "body": "", + "width": 192, + "height": 192 + } + }, + "aliases": { + "arty-stroke-16-arrow-right": { + "parent": "arty-stroke-16-arrow-left", + "hFlip": true + }, + "arty-stroke-16-arrow-up": { + "parent": "arty-stroke-16-arrow-left", + "rotate": 1, + "vFlip": true + }, + "arty-stroke-16-arrow-down": { + "parent": "arty-stroke-16-arrow-left", + "rotate": 3 + }, + "arty-stroke-16-arrows-from-2-corners-rotated": { + "parent": "arty-stroke-16-arrows-from-2-corners", + "hFlip": true + }, + "arty-stroke-16-arrows-vertical": { + "parent": "arty-stroke-16-arrows-horizontal", + "rotate": 1 + }, + "arty-stroke-16-arrows-to-2-corners-rotated": { + "parent": "arty-stroke-16-arrows-to-2-corners", + "hFlip": true + }, + "arty-stroke-16-caret-down-outline": { + "parent": "arty-stroke-16-caret-up-outline", + "vFlip": true + }, + "arty-stroke-16-caret-left-outline": { + "parent": "arty-stroke-16-caret-up-outline", + "rotate": 1, + "vFlip": true + }, + "arty-stroke-16-caret-right-outline": { + "parent": "arty-stroke-16-caret-up-outline", + "rotate": 1 + }, + "arty-stroke-16-caret-down": { + "parent": "arty-stroke-16-caret-up", + "vFlip": true + }, + "arty-stroke-16-caret-left": { + "parent": "arty-stroke-16-caret-up", + "rotate": 1, + "vFlip": true + }, + "arty-stroke-16-caret-right": { + "parent": "arty-stroke-16-caret-up", + "rotate": 1 + }, + "arty-stroke-16-carets-horizontal-outline": { + "parent": "arty-stroke-16-carets-vertical-outline", + "rotate": 3 + }, + "arty-stroke-16-carets-horizontal": { + "parent": "arty-stroke-16-carets-vertical", + "rotate": 3 + }, + "arty-stroke-16-chevron-right": { + "parent": "arty-stroke-16-chevron-left", + "hFlip": true + }, + "arty-stroke-16-chevron-up": { + "parent": "arty-stroke-16-chevron-left", + "rotate": 1, + "vFlip": true + }, + "arty-stroke-16-chevron-down": { + "parent": "arty-stroke-16-chevron-left", + "rotate": 3 + }, + "arty-stroke-16-double-arrow-vertical": { + "parent": "arty-stroke-16-double-arrow-horizontal", + "rotate": 1 + }, + "arty-stroke-16-filters-horizontal": { + "parent": "arty-stroke-16-filters", + "rotate": 3, + "hFlip": true + }, + "arty-stroke-16-list-3-outline-rtl": { + "parent": "arty-stroke-16-list-3-outline", + "hFlip": true + }, + "arty-stroke-16-list-3-rtl": { + "parent": "arty-stroke-16-list-3", + "hFlip": true + }, + "arty-stroke-16-panel-right": { + "parent": "arty-stroke-16-panel-left", + "hFlip": true + }, + "arty-stroke-16-panel-up": { + "parent": "arty-stroke-16-panel-left", + "rotate": 1, + "vFlip": true + }, + "arty-stroke-16-panel-down": { + "parent": "arty-stroke-16-panel-left", + "rotate": 3 + }, + "arty-stroke-16-search-rotated": { + "parent": "arty-stroke-16-search", + "rotate": 3 + }, + "arty-stroke-20-search-rotated": { + "parent": "arty-stroke-20-search", + "rotate": 3 + }, + "arty-stroke-24-filters-horizontal": { + "parent": "arty-stroke-24-filters", + "rotate": 3, + "hFlip": true + }, + "arty-stroke-24-list-3-outline-rtl": { + "parent": "arty-stroke-24-list-3-outline", + "hFlip": true + }, + "arty-stroke-24-list-3-rtl": { + "parent": "arty-stroke-24-list-3", + "hFlip": true + }, + "arty-stroke-24-search-rotated": { + "parent": "arty-stroke-24-search", + "rotate": 3 + } + }, + "width": 128, + "height": 128 +} \ No newline at end of file diff --git a/license.txt b/license.txt new file mode 100755 index 0000000..08a0802 --- /dev/null +++ b/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Vjacheslav Trushkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..ac9d63e --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "simple-svg-website-icons", + "version": "0.0.2", + "description": "Node.js version of icons.simplesvg.com", + "main": "app.js", + "scripts": { + "start": "node app.js" + }, + "author": "Vjacheslav Trushkin", + "license": "MIT", + "dependencies": { + "compression": "^1.6.2", + "express": "^4.15.2", + "simple-svg-cdn": "*", + "simple-svg-icons": "git+https://github.com/simplesvg/icons.git" + } +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6565e19 --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# SimpleSVG icons website + +This code runs on icons.simplesvg.com that is used to serve collections and SVG images. \ No newline at end of file diff --git a/ssl.js b/ssl.js new file mode 100644 index 0000000..67075c3 --- /dev/null +++ b/ssl.js @@ -0,0 +1,26 @@ +/** + * Run this file instead of app.js if you want to enable SSL support + */ +"use strict"; + +const https = require('https'), + fs = require('fs'); + +let app = require('./app'); + +try { + let ssl = { + secureProtocol: 'SSLv23_method', + secureOptions: require('constants').SSL_OP_NO_SSLv3, + key: fs.readFileSync('ssl/ssl.key'), + cert: fs.readFileSync('ssl/ssl.crt'), + ca: fs.readFileSync('ssl/ssl.ca-bundle'), + }; + let port = process.env.SSLPORT || 443; + https.createServer(ssl, app).listen(port); + console.log('Listening on port ' + port); +} catch (err) { + console.log('SSL certificates are missing'); +} + +module.exports = app; diff --git a/ssl/readme.md b/ssl/readme.md new file mode 100644 index 0000000..414513a --- /dev/null +++ b/ssl/readme.md @@ -0,0 +1,7 @@ +Put your SSL certificate here to enable SSL support. +Change file names to "ssl". + +Files: +* ssl.key +* ssl.crt +* ssl.ca-bundle