Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F7066207
D1151.id3660.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
55 KB
Subscribers
None
D1151.id3660.diff
View Options
diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@
swh/web/static/js/
swh/web/static/css/
swh/web/static/fonts/
+swh/web/static/jssources/
.cache-loader/
build/
dist/
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -68,6 +68,7 @@
"robotstxt-webpack-plugin": "^5.0.0",
"sass-loader": "^7.1.0",
"showdown": "^1.9.0",
+ "spdx-expression-parse": "^3.0.0",
"style-loader": "^0.23.1",
"stylelint": "^9.10.1",
"stylelint-config-standard": "^18.2.0",
diff --git a/swh/web/assets/config/webpack-plugins/generate-weblabels-webpack-plugin/index.js b/swh/web/assets/config/webpack-plugins/generate-weblabels-webpack-plugin/index.js
new file mode 100644
--- /dev/null
+++ b/swh/web/assets/config/webpack-plugins/generate-weblabels-webpack-plugin/index.js
@@ -0,0 +1,369 @@
+/**
+ * Copyright (C) 2019 The Software Heritage developers
+ * See the AUTHORS file at the top-level directory of this distribution
+ * License: GNU Affero General Public License version 3, or any later version
+ * See top-level LICENSE file for more information
+ */
+
+// This is a first draft of a plugin for Webpack >= 4 enabling to generate a WebLabels
+// page to be used with the LibreJS Firefox plugin (https://www.gnu.org/software/librejs/).
+// The purpose of the WebLabels page is to prevent the loading of the generated
+// assets being blocked by the LibreJS Firefox plugin in client browsers.
+// To do so, the page must contain the following information. For each JavaScript asset
+// generated by webpack, all bundled source files in it need to be referenced along
+// with their licenses but also a link to their non-minified source code.
+
+// The plugin works by processing the compilation statistics available after the whole
+// webpack processing and currently does the following:
+//
+// - it copies all non-minified source files bundles into the generated JavaScript
+// assets into a directory located into the webpack output folder.
+//
+// - it generates a weblabels.json file into a directory located into the
+// webpack output folder. This JSON file should be used with an HTML template
+// engine to generate the WebLabels page and it has the following structure:
+//
+// {
+// "<js_asset_static_path>": [{
+// "id": "<bundled_source_file_identifier>",
+// "path": "<path_to_non_minified_source_file>"
+// "license": {
+// "name": "<license_name_librejs_compliant>",
+// "url": "<license_text_url_librejs_compliant>",
+// "copy_url": "<original_license_text_url>",
+// },
+// "static_url": "<link_to_non_minified_source_code>"
+// }, {
+// ...
+// }],
+// "<other_js_asset_static_path>": [
+// ...
+// ],
+// ...
+// }
+//
+// So for each JavaScript asset generated by Webpack, the JSON file references
+// all the source code files bundled in it along with the detected licenses
+// and a link to download the non-minified source codes.
+// For each referenced source file, its path corresponds to the relative
+// path from the webpack project root folder, while its identifier corresponds
+// to the path without the './' or './node_modules/' prefix.
+
+// The following options can be provided to the plugin:
+//
+// - outputDir: Specify the directory inside the webpack output folder in which
+// the weblabels JSON file and the js sources will be emitted.
+// The default value is 'jssources'.
+//
+// - exclude: An array of module name prefixes to exclude from the generated output.
+// If the prefix does not start with './', it is considered as a node module.
+//
+// - srcReplace: An object mapping source files to replace in the generated output.
+// This should be used when a node module points to its minified version
+// by default.
+//
+// - licenseOverride: An object mapping source files to their corresponding SPDX licenses.
+// This should be used when you have source files inside your webpack
+// project source tree with licenses different from the one of your
+// project. It must have the following structure:
+//
+// {
+// "<js_src_file_path>": {
+// "name": "<spdx_license_id>",
+// "path": "<path_to_license_file>"
+// },
+// ...
+// }
+//
+// - additionalScripts: An object declaring additional js scripts loaded by your web
+// application but not processed by webpack. It must have the
+// following structure:
+//
+// {
+// "<js_asset_static_path>": [{
+// "id": "<bundled_source_file_identifier>",
+// "path": "<path_to_non_minified_source_file>"
+// "license": {
+// "name": "<spdx_license_id>",
+// "path": "<path_to_license_file>"
+// }
+// }, {
+// ...
+// }],
+// ...
+// }
+
+const fs = require('fs');
+const path = require('path');
+const spdxParse = require('spdx-expression-parse');
+const spdxLicensesMapping = require('./spdx-licenses-mapping');
+
+class GenerateWebLabelsPlugin {
+
+ constructor(opts) {
+ this.options = opts || {};
+ this.weblabelsDirName = this.options['outputDir'] || 'jssources';
+ // source file extension handled by webpack and compiled to js
+ this.srcExts = ['js', 'ts', 'coffee', 'lua'];
+ this.srcExtsRegexp = new RegExp('^.*.(' + this.srcExts.join('|') + ')$');
+ this.chunkNameToJsAsset = {};
+ this.chunkJsAssetToSrcFiles = {};
+ this.packageJsonCache = {};
+ this.packageLicenseFile = {};
+ this.exclude = [];
+ this.copiedFiles = new Set();
+ // populate module prefix patterns to exclude
+ if (Array.isArray(this.options['exclude'])) {
+ this.options['exclude'].forEach(toExclude => {
+ if (!toExclude.startsWith('.')) {
+ this.exclude.push('./' + path.join('node_modules', toExclude));
+ } else {
+ this.exclude.push(toExclude);
+ }
+ });
+ }
+ }
+
+ apply(compiler) {
+ compiler.hooks.done.tap('GenerateWebLabelsPlugin', statsObj => {
+
+ // get the stats object in JSON format
+ let stats = statsObj.toJson();
+ this.stats = stats;
+
+ // set output folder
+ this.weblabelsOutputDir = path.join(stats.outputPath, this.weblabelsDirName);
+ this.recursiveMkdir(this.weblabelsOutputDir);
+
+ // map each generated webpack chunk to its js asset
+ Object.keys(stats.assetsByChunkName).forEach((chunkName, i) => {
+ if (Array.isArray(stats.assetsByChunkName[chunkName])) {
+ for (let asset of stats.assetsByChunkName[chunkName]) {
+ if (asset.endsWith('.js')) {
+ this.chunkNameToJsAsset[chunkName] = asset;
+ this.chunkNameToJsAsset[i] = asset;
+ break;
+ }
+ }
+ } else if (stats.assetsByChunkName[chunkName].endsWith('.js')) {
+ this.chunkNameToJsAsset[chunkName] = stats.assetsByChunkName[chunkName];
+ this.chunkNameToJsAsset[i] = stats.assetsByChunkName[chunkName];
+ }
+ });
+
+ // iterate on all bundled webpack modules
+ stats.modules.forEach(mod => {
+
+ let srcFilePath = mod.name;
+
+ if (!this.srcExtsRegexp.test(srcFilePath)) {
+ return;
+ }
+
+ // do not process modules unrelated to a source file
+ if (!srcFilePath.startsWith('./')) {
+ return;
+ }
+
+ // do not process modules in the exclusion list
+ for (let toExclude of this.exclude) {
+ if (srcFilePath.startsWith(toExclude)) {
+ return;
+ }
+ }
+
+ // iterate on all chunks containing the module
+ mod.chunks.forEach(chunk => {
+
+ let chunkJsAsset = stats.publicPath + this.chunkNameToJsAsset[chunk];
+
+ // init the chunk to source files mapping if needed
+ if (!this.chunkJsAssetToSrcFiles.hasOwnProperty(chunkJsAsset)) {
+ this.chunkJsAssetToSrcFiles[chunkJsAsset] = [];
+ }
+ // check if the source file needs to be replaces
+ if (this.options['srcReplace'] && this.options['srcReplace'].hasOwnProperty(srcFilePath)) {
+ srcFilePath = this.options['srcReplace'][srcFilePath];
+ }
+
+ // init source file metadata
+ let srcFileData = {'id': this.cleanupPath(srcFilePath),
+ 'path': srcFilePath};
+
+ // find and parse the corresponding package.json file
+ let packageJsonPath;
+ let nodeModule = srcFilePath.startsWith('./node_modules/');
+ if (nodeModule) {
+ packageJsonPath = this.findPackageJsonPath(srcFilePath);
+ } else {
+ packageJsonPath = './package.json';
+ }
+ let packageJson = this.parsePackageJson(packageJsonPath);
+
+ // extract license information, overriding it if needed
+ let licenseFilePath;
+ if (this.options['licenseOverride'] && this.options['licenseOverride'].hasOwnProperty(srcFilePath)) {
+ let licenseSpdxId = this.options['licenseOverride'][srcFilePath]['name'];
+ licenseFilePath = this.options['licenseOverride'][srcFilePath]['path'];
+ srcFileData['license'] = this.spdxToWebLabelsLicense(licenseSpdxId);
+ srcFileData['license']['copy_url'] = this.copyLicenseFile(licenseFilePath);
+ } else {
+ srcFileData['license'] = this.extractLicenseInformation(packageJson);
+ let licenseDir = path.join(...packageJsonPath.split('/').slice(0, -1));
+ licenseFilePath = this.findLicenseFile(licenseDir);
+ }
+
+ // copy original license file and get its static url
+ srcFileData['license']['copy_url'] = this.copyLicenseFile(licenseFilePath);
+
+ // generate static url for downloading non-minified source code
+ srcFileData['static_url'] = stats.publicPath + path.join(this.weblabelsDirName, srcFileData['id']);
+
+ // add source file metadata to the webpack chunk
+ this.chunkJsAssetToSrcFiles[chunkJsAsset].push(srcFileData);
+ // copy non-minified source to output folder
+ this.copyFileToOutputPath(srcFilePath);
+ });
+ });
+
+ // process additional scripts if needed
+ if (this.options['additionalScripts']) {
+ for (let script of Object.keys(this.options['additionalScripts'])) {
+ this.chunkJsAssetToSrcFiles[script] = [];
+ for (let scriptSrc of this.options['additionalScripts'][script]) {
+ let licenceFilePath = scriptSrc['license']['path'];
+ scriptSrc['license'] = this.spdxToWebLabelsLicense(scriptSrc['license']['name']);
+ scriptSrc['license']['copy_url'] = this.copyLicenseFile(licenceFilePath);
+ scriptSrc['static_url'] = stats.publicPath + path.join(this.weblabelsDirName, scriptSrc['id']);
+ this.chunkJsAssetToSrcFiles[script].push(scriptSrc);
+ this.copyFileToOutputPath(scriptSrc['path']);
+ }
+ }
+ }
+
+ // generate the weblabels.json file
+ let weblabelsData = JSON.stringify(this.chunkJsAssetToSrcFiles);
+ let weblabelsJsonFile = path.join(this.weblabelsOutputDir, 'weblabels.json');
+ fs.writeFileSync(weblabelsJsonFile, weblabelsData);
+ });
+ }
+
+ cleanupPath(moduleFilePath) {
+ return moduleFilePath.replace(/^[./]*node_modules\//, '').replace(/^.\//, '');
+ }
+
+ findPackageJsonPath(srcFilePath) {
+ let pathSplit = srcFilePath.split('/');
+ let packageJsonPath;
+ for (let i = 3; i < pathSplit.length; ++i) {
+ packageJsonPath = path.join(...pathSplit.slice(0, i), 'package.json');
+ if (fs.existsSync(packageJsonPath)) {
+ break;
+ }
+ }
+ return packageJsonPath;
+ }
+
+ findLicenseFile(packageJsonDir) {
+ if (!this.packageLicenseFile.hasOwnProperty(packageJsonDir)) {
+ let foundLicenseFile;
+ fs.readdirSync(packageJsonDir).forEach(file => {
+ if (foundLicenseFile) {
+ return;
+ }
+ if (file.toLowerCase().startsWith('license')) {
+ foundLicenseFile = path.join(packageJsonDir, file);
+ }
+ });
+ this.packageLicenseFile[packageJsonDir] = foundLicenseFile;
+ }
+ return this.packageLicenseFile[packageJsonDir];
+ }
+
+ copyLicenseFile(licenseFilePath) {
+ let licenseCopyPath = '';
+ if (fs.existsSync(licenseFilePath)) {
+ let ext = '';
+ // add a .txt extension in order to serve license file with text/plain
+ // content type to client browsers
+ if (licenseFilePath.toLowerCase().indexOf('license.') === -1) {
+ ext = '.txt';
+ }
+ this.copyFileToOutputPath(licenseFilePath, ext);
+ licenseFilePath = this.cleanupPath(licenseFilePath);
+ licenseCopyPath = this.stats.publicPath + path.join(this.weblabelsDirName, licenseFilePath + ext);
+ }
+ return licenseCopyPath;
+ }
+
+ parsePackageJson(packageJsonPath) {
+ if (!this.packageJsonCache.hasOwnProperty(packageJsonPath)) {
+ let packageJsonStr = fs.readFileSync(packageJsonPath).toString('utf8');
+ this.packageJsonCache[packageJsonPath] = JSON.parse(packageJsonStr);
+ }
+ return this.packageJsonCache[packageJsonPath];
+ }
+
+ spdxToWebLabelsLicense(spdxLicenceId) {
+ for (let i = 0; i < spdxLicensesMapping.length; ++i) {
+ if (spdxLicensesMapping[i]['spdx_ids'].indexOf(spdxLicenceId) !== -1) {
+ let licenseData = Object.assign({}, spdxLicensesMapping[i]);
+ delete licenseData['spdx_ids'];
+ delete licenseData['magnet_link'];
+ licenseData['copy_url'] = '';
+ return licenseData;
+ }
+ }
+ return undefined;
+ }
+
+ extractLicenseInformation(packageJson) {
+ let licenseStr;
+ if (packageJson.hasOwnProperty('license')) {
+ licenseStr = packageJson['license'];
+ } else if (packageJson.hasOwnProperty('licenses')) {
+ let licenses = packageJson['licenses'];
+ if (Array.isArray(licenses)) {
+ let l = [];
+ licenses.forEach(license => {
+ l.push(license['type']);
+ });
+ licenseStr = l.join(' OR ');
+ } else {
+ licenseStr = licenses['type'];
+ }
+ }
+ let license = spdxParse(licenseStr)['license'];
+ let licenseData = this.spdxToWebLabelsLicense(license);
+ if (licenseData) {
+ return licenseData;
+ } else {
+ return {'name': license};
+ }
+ }
+
+ copyFileToOutputPath(srcFilePath, ext = '') {
+ if (this.copiedFiles.has(srcFilePath)) {
+ return;
+ }
+ let destPath = this.cleanupPath(srcFilePath);
+ let destDir = path.join(this.weblabelsOutputDir, ...destPath.split('/').slice(0, -1));
+ this.recursiveMkdir(destDir);
+ destPath = path.join(this.weblabelsOutputDir, destPath + ext);
+ fs.copyFileSync(srcFilePath, destPath);
+ this.copiedFiles.add(srcFilePath);
+ }
+
+ recursiveMkdir(destPath) {
+ let destPathSplit = destPath.split('/');
+ for (let i = 1; i < destPathSplit.length; ++i) {
+ let currentPath = path.join('/', ...destPathSplit.slice(0, i + 1));
+ if (!fs.existsSync(currentPath)) {
+ fs.mkdirSync(currentPath);
+ }
+ }
+ }
+
+};
+
+module.exports = GenerateWebLabelsPlugin;
diff --git a/swh/web/assets/config/webpack-plugins/generate-weblabels-webpack-plugin/spdx-licenses-mapping.js b/swh/web/assets/config/webpack-plugins/generate-weblabels-webpack-plugin/spdx-licenses-mapping.js
new file mode 100644
--- /dev/null
+++ b/swh/web/assets/config/webpack-plugins/generate-weblabels-webpack-plugin/spdx-licenses-mapping.js
@@ -0,0 +1,135 @@
+/**
+ * Copyright (C) 2019 The Software Heritage developers
+ * See the AUTHORS file at the top-level directory of this distribution
+ * License: GNU Affero General Public License version 3, or any later version
+ * See top-level LICENSE file for more information
+ */
+
+module.exports = [
+ {
+ 'name': 'Apache License, Version 2.0',
+ 'url': 'http://www.apache.org/licenses/LICENSE-2.0',
+ 'magnet_link': 'magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt',
+ 'spdx_ids': ['Apache-2.0']
+ },
+ {
+ 'name': 'Artistic License 2.0',
+ 'url': 'http://www.perlfoundation.org/artistic_license_2_0',
+ 'magnet_link': 'magnet:?xt=urn:btih:54fd2283f9dbdf29466d2df1a98bf8f65cafe314&dn=artistic-2.0.txt',
+ 'spdx_ids': ['Artistic-2.0']
+ },
+ {
+ 'name': 'Boost Software License',
+ 'url': 'http://www.boost.org/LICENSE_1_0.txt',
+ 'magnet_link': 'magnet:?xt=urn:btih:89a97c535628232f2f3888c2b7b8ffd4c078cec0&dn=Boost-1.0.txt',
+ 'spdx_ids': ['BSL-1.0']
+ },
+ {
+ 'name': 'BSD 3-Clause License',
+ 'url': 'http://opensource.org/licenses/BSD-3-Clause',
+ 'magnet_link': 'magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt',
+ 'spdx_ids': ['BSD-3-Clause']
+ },
+ {
+ 'name': 'CPAL 1.0',
+ 'url': 'http://opensource.org/licenses/cpal_1.0',
+ 'magnet_link': 'magnet:?xt=urn:btih:84143bc45939fc8fa42921d619a95462c2031c5c&dn=cpal-1.0.txt',
+ 'spdx_ids': ['CPAL-1.0']
+ },
+ {
+ 'name': 'Creative Commons CC0 1.0 Universal',
+ 'url': 'http://creativecommons.org/publicdomain/zero/1.0/legalcode',
+ 'magnet_link': 'magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt',
+ 'spdx_ids': ['CC0-1.0']
+ },
+ {
+ 'name': 'Eclipse Public License 1.0',
+ 'url': 'http://www.eclipse.org/legal/epl-v10.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:4c6a2ad0018cd461e9b0fc44e1b340d2c1828b22&dn=epl-1.0.txt',
+ 'spdx_ids': ['EPL-1.0']
+ },
+ {
+ 'name': 'Expat License',
+ 'url': 'http://www.jclark.com/xml/copying.txt',
+ 'magnet_link': 'magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt',
+ 'spdx_ids': ['MIT']
+ },
+ {
+ 'name': 'FreeBSD License',
+ 'url': 'http://www.freebsd.org/copyright/freebsd-license.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:87f119ba0b429ba17a44b4bffcab33165ebdacc0&dn=freebsd.txt',
+ 'spdx_ids': ['BSD-2-Clause-FreeBSD']
+ },
+ {
+ 'name': 'GNU General Public License (GPL) version 2',
+ 'url': 'http://www.gnu.org/licenses/gpl-2.0.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt',
+ 'spdx_ids': ['GPL-2.0-only', 'GPL-2.0-or-later', 'GPL-2.0+', 'GPL-2.0']
+ },
+ {
+ 'name': 'GNU General Public License (GPL) version 3',
+ 'url': 'http://www.gnu.org/licenses/gpl-3.0.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt',
+ 'spdx_ids': ['GPL-3.0-only', 'GPL-3.0-or-later', 'GPL-3.0+', 'GPL-3.0']
+ },
+ {
+ 'name': 'GNU Lesser General Public License, version 2.1',
+ 'url': 'http://www.gnu.org/licenses/lgpl-2.1.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:5de60da917303dbfad4f93fb1b985ced5a89eac2&dn=lgpl-2.1.txt',
+ 'spdx_ids': ['LGPL-2.1-only', 'LGPL-2.1-or-later', 'LGPL-2.1+', 'LGPL-2.1']
+ },
+ {
+ 'name': 'GNU Lesser General Public License, version 3',
+ 'url': 'http://www.gnu.org/licenses/lgpl-3.0.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:0ef1b8170b3b615170ff270def6427c317705f85&dn=lgpl-3.0.txt',
+ 'spdx_ids': ['LGPL-3.0-only', 'LGPL-3.0-or-later', 'LGPL-3.0+', 'LGPL-3.0']
+ },
+ {
+ 'name': 'GNU Affero General Public License, version 3',
+ 'url': 'http://www.gnu.org/licenses/agpl-3.0.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt',
+ 'spdx_ids': ['AGPL-3.0-only', 'AGPL-3.0-or-later', 'AGPL-3.0+', 'AGPL-3.0']
+ },
+ {
+ 'name': 'The ISC License',
+ 'url': 'https://www.isc.org/downloads/software-support-policy/isc-license/',
+ 'magnet_link': 'magnet:?xt=urn:btih:b8999bbaf509c08d127678643c515b9ab0836bae&dn=ISC.txt',
+ 'spdx_ids': ['ISC']
+ },
+ {
+ 'name': 'Mozilla Public License 2.0',
+ 'url': 'http://www.mozilla.org/MPL/2.0',
+ 'magnet_link': 'magnet:?xt=urn:btih:3877d6d54b3accd4bc32f8a48bf32ebc0901502a&dn=mpl-2.0.txt',
+ 'spdx_ids': ['MPL-2.0']
+ },
+ {
+ 'name': 'Universal Permissive License',
+ 'url': 'https://oss.oracle.com/licenses/upl/',
+ 'magnet_link': 'magnet:?xt=urn:btih:478974f4d41c3fa84c4befba25f283527fad107d&dn=upl-1.0.txt',
+ 'spdx_ids': ['UPL-1.0']
+ },
+ {
+ 'name': 'WTFPL',
+ 'url': 'http://www.wtfpl.net/txt/copying/',
+ 'magnet_link': 'magnet:?xt=urn:btih:723febf9f6185544f57f0660a41489c7d6b4931b&dn=wtfpl.txt',
+ 'spdx_ids': ['WTFPL']
+ },
+ {
+ 'name': 'Unlicense',
+ 'url': 'http://unlicense.org/UNLICENSE',
+ 'magnet_link': 'magnet:?xt=urn:btih:5ac446d35272cc2e4e85e4325b146d0b7ca8f50c&dn=unlicense.txt',
+ 'spdx_ids': ['Unlicense']
+ },
+ {
+ 'name': 'X11 License',
+ 'url': 'http://www.xfree86.org/3.3.6/COPYRIGHT2.html#3',
+ 'magnet_link': 'magnet:?xt=urn:btih:5305d91886084f776adcf57509a648432709a7c7&dn=x11.txt',
+ 'spdx_ids': ['X11']
+ },
+ {
+ 'name': 'XFree86 License',
+ 'url': 'http://www.xfree86.org/current/LICENSE4.html',
+ 'magnet_link': 'magnet:?xt=urn:btih:12f2ec9e8de2a3b0002a33d518d6010cc8ab2ae9&dn=xfree86.txt',
+ 'spdx_ids': ['XFree86-1.1']
+ }
+];
diff --git a/swh/web/assets/config/webpack.config.development.js b/swh/web/assets/config/webpack.config.development.js
--- a/swh/web/assets/config/webpack.config.development.js
+++ b/swh/web/assets/config/webpack.config.development.js
@@ -17,6 +17,7 @@
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveSourceMapUrlPlugin = require('./webpack-plugins/remove-source-map-url-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
+const GenerateWebLabelsPlugin = require('./webpack-plugins/generate-weblabels-webpack-plugin');
// are we running webpack-dev-server ?
const isDevServer = process.argv.find(v => v.includes('webpack-dev-server'));
@@ -304,7 +305,8 @@
// webpack plugins
plugins: [
// cleanup previously generated assets
- new CleanWebpackPlugin(['static/css', 'static/js', 'static/fonts', 'static/*.*'], {
+ new CleanWebpackPlugin(['static/css', 'static/js', 'static/fonts',
+ 'static/jssources', 'static/*.*'], {
root: path.resolve(__dirname, '../../')
}),
// needed in order to use django_webpack_loader
@@ -349,7 +351,39 @@
new CopyWebpackPlugin([{
from: path.resolve(nodeModules, 'pdfjs-dist/build/pdf.worker.min.js'),
to: path.resolve(__dirname, '../../static/js/')
- }])
+ }]),
+ new GenerateWebLabelsPlugin({
+ exclude: ['mini-css-extract-plugin',
+ 'bootstrap-loader'],
+ srcReplace: {
+ './node_modules/pdfjs-dist/build/pdf.min.js':
+ './node_modules/pdfjs-dist/build/pdf.js',
+ './node_modules/admin-lte/dist/js/adminlte.min.js':
+ './node_modules/admin-lte/dist/js/adminlte.js'
+ },
+ licenseOverride: {
+ './swh/web/assets/src/thirdparty/highlightjs-line-numbers/highlightjs-line-numbers.js': {
+ 'name': 'MIT',
+ 'path': './swh/web/assets/src/thirdparty/highlightjs-line-numbers/LICENSE'
+ },
+ './swh/web/assets/src/thirdparty/jquery.tabSlideOut/jquery.tabSlideOut.js': {
+ 'name': 'GPL-3.0',
+ 'path': './swh/web/assets/src/thirdparty/jquery.tabSlideOut/LICENSE'
+ }
+ },
+ additionalScripts: {
+ 'js/pdf.worker.min.js': [
+ {
+ 'id': 'pdfjs-dist/build/pdf.worker.js',
+ 'path': './node_modules/pdfjs-dist/build/pdf.worker.js',
+ 'license': {
+ 'name': 'Apache-2.0',
+ 'path': './node_modules/pdfjs-dist/LICENSE'
+ }
+ }
+ ]
+ }
+ })
],
// webpack optimizations
optimization: {
diff --git a/swh/web/assets/config/webpack.config.production.js b/swh/web/assets/config/webpack.config.production.js
--- a/swh/web/assets/config/webpack.config.production.js
+++ b/swh/web/assets/config/webpack.config.production.js
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 The Software Heritage developers
+ * Copyright (C) 2018-2019 The Software Heritage developers
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU Affero General Public License version 3, or any later version
* See top-level LICENSE file for more information
@@ -38,5 +38,8 @@
})
];
+// prevent modules concatenation for generating weblabels
+webpackProdConfig.optimization.concatenateModules = false;
+
// webpack production configuration
module.exports = webpackProdConfig;
diff --git a/swh/web/common/swh_templatetags.py b/swh/web/common/swh_templatetags.py
--- a/swh/web/common/swh_templatetags.py
+++ b/swh/web/common/swh_templatetags.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2017-2018 The Software Heritage developers
+# Copyright (C) 2017-2019 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information
@@ -166,3 +166,17 @@
If the origin type is savable or not
"""
return origin_type in get_savable_origin_types()
+
+
+@register.filter
+def split(value, arg):
+ """Django template filter to split a string.
+
+ Args:
+ value (str): the string to split
+ arg (str): the split separator
+
+ Returns:
+ list: the splitted string parts
+ """
+ return value.split(arg)
diff --git a/swh/web/templates/coverage.html b/swh/web/templates/coverage.html
--- a/swh/web/templates/coverage.html
+++ b/swh/web/templates/coverage.html
@@ -1,5 +1,5 @@
{% comment %}
-Copyright (C) 2015-2018 The Software Heritage developers
+Copyright (C) 2015-2019 The Software Heritage developers
See the AUTHORS file at the top-level directory of this distribution
License: GNU Affero General Public License version 3, or any later version
See top-level LICENSE file for more information
@@ -7,6 +7,7 @@
<!DOCTYPE html>
+{% load js_reverse %}
{% load static %}
{% load render_bundle from webpack_loader %}
@@ -18,7 +19,31 @@
<title>Software Heritage archive coverage</title>
{% render_bundle 'vendors' %}
{% render_bundle 'webapp' %}
- <script src="{% url 'js_reverse' %}" type="text/javascript"></script>
+ <script>
+/*
+@licstart The following is the entire license notice for the JavaScript code in this page.
+
+Copyright (C) 2015-2019 The Software Heritage developers
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@licend The above is the entire license notice for the JavaScript code in this page.
+*/
+ </script>
+ <script type="text/javascript" charset="utf-8">
+ {% js_reverse_inline %}
+ </script>
<base target="_parent">
</head>
@@ -41,6 +66,7 @@
</div>
</div>
</div>
+ <a href="{% url 'jslicenses' %}" rel="jslicense" style="display: none;">JavaScript license information</a>
</body>
{% if count_origins %}
<script>
diff --git a/swh/web/templates/jslicenses.html b/swh/web/templates/jslicenses.html
new file mode 100644
--- /dev/null
+++ b/swh/web/templates/jslicenses.html
@@ -0,0 +1,61 @@
+{% extends "layout.html" %}
+
+{% comment %}
+Copyright (C) 2019 The Software Heritage developers
+See the AUTHORS file at the top-level directory of this distribution
+License: GNU Affero General Public License version 3, or any later version
+See top-level LICENSE file for more information
+{% endcomment %}
+
+{% load swh_templatetags %}
+
+{% block title %}JavaScript license information{% endblock %}
+
+{% block navbar-content %}
+<h4>JavaScript license information</h4>
+{% endblock %}
+
+{% block content %}
+<p>
+This page states the licenses of all the JavaScript files loaded by that web application.
+The loaded JavaScript files correspond to bundles concatenating multiple source files.
+You can find the details of the content of each bundle in the WebLabels table below.
+</p>
+<table id="jslicense-labels1" class="table swh-table swh-table-striped">
+ <thead>
+ <tr>
+ <th>Script</th>
+ <th>Licenses</th>
+ <th>Sources</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for jsasset, bundled_js_srcs in jslicenses_data %}
+ <tr>
+ <td>
+ <a href="{{ jsasset }}">{{ jsasset | split:"/" | last }}</a>
+ </td>
+ <td>
+ {% for js_src in bundled_js_srcs %}
+ <a href="{{ js_src.license.url }}">{{ js_src.license.name }}</a>
+ {% if js_src.license.copy_url %}
+ (<a href="{{ js_src.license.copy_url }}">view</a>)
+ {% endif %}
+ {% if not forloop.last %}
+ <br/>
+ {% endif %}
+ {% endfor %}
+ </td>
+ <td>
+ {% for js_src in bundled_js_srcs %}
+ <a href="{{ js_src.static_url }}">{{ js_src.id }}</a>
+ {% if not forloop.last %}
+ <br/>
+ {% endif %}
+ {% endfor %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+{% endblock %}
diff --git a/swh/web/templates/layout.html b/swh/web/templates/layout.html
--- a/swh/web/templates/layout.html
+++ b/swh/web/templates/layout.html
@@ -1,5 +1,5 @@
{% comment %}
-Copyright (C) 2015-2018 The Software Heritage developers
+Copyright (C) 2015-2019 The Software Heritage developers
See the AUTHORS file at the top-level directory of this distribution
License: GNU Affero General Public License version 3, or any later version
See top-level LICENSE file for more information
@@ -7,6 +7,7 @@
<!DOCTYPE html>
+{% load js_reverse %}
{% load static %}
{% load render_bundle from webpack_loader %}
{% load swh_templatetags %}
@@ -21,7 +22,32 @@
{% render_bundle 'vendors' %}
{% render_bundle 'webapp' %}
- <script src="{% url 'js_reverse' %}" type="text/javascript"></script>
+ <script>
+/*
+@licstart The following is the entire license notice for the JavaScript code in this page.
+
+Copyright (C) 2015-2019 The Software Heritage developers
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@licend The above is the entire license notice for the JavaScript code in this page.
+*/
+ </script>
+
+ <script type="text/javascript" charset="utf-8">
+ {% js_reverse_inline %}
+ </script>
{% block header %}{% endblock %}
@@ -30,6 +56,7 @@
<link rel="apple-touch-icon-precomposed" href="{% static 'img/icons/swh-logo-archive-180x180.png' %}" />
<link rel="search" type="application/opensearchdescription+xml" title="Software Heritage archive of public source code" href="{% static 'xml/swh-opensearch.xml' %}">
<meta name="msapplication-TileImage" content="{% static 'img/icons/swh-logo-archive-270x270.png' %}" />
+
</head>
<body class="hold-transition sidebar-mini">
@@ -172,7 +199,8 @@
<span class="link-color">Terms of use: </span>
<a href="https://www.softwareheritage.org/legal/bulk-access-terms-of-use/">Archive access</a> -
<a href="https://www.softwareheritage.org/legal/api-terms-of-use/">API</a>,
- <a href="https://www.softwareheritage.org/contact/">Contact</a>.
+ <a href="https://www.softwareheritage.org/contact/">Contact</a>,
+ <a href="{% url 'jslicenses' %}" rel="jslicense">JavaScript license information</a>
</div>
</footer>
<div id="back-to-top">
diff --git a/swh/web/urls.py b/swh/web/urls.py
--- a/swh/web/urls.py
+++ b/swh/web/urls.py
@@ -1,12 +1,15 @@
-# Copyright (C) 2017-2018 The Software Heritage developers
+# Copyright (C) 2017-2019 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information
+import json
+
from django.conf import settings
from django.conf.urls import (
url, include, handler400, handler403, handler404, handler500
)
+from django.contrib.staticfiles import finders
from django.contrib.staticfiles.views import serve
from django.shortcuts import render
from django.views.generic.base import RedirectView
@@ -30,6 +33,14 @@
return render(request, "homepage.html")
+def jslicenses(request):
+ jslicenses_data = json.load(open(finders.find('jssources/weblabels.json')))
+ jslicenses_data = sorted(jslicenses_data.items(),
+ key=lambda item: item[0].split('/')[-1])
+ return render(request, "jslicenses.html",
+ {'jslicenses_data': jslicenses_data})
+
+
urlpatterns = [
url(r'^admin/', include('swh.web.admin.urls')),
url(r'^favicon\.ico$', favicon_view),
@@ -39,7 +50,8 @@
url(r'^jsreverse/$', urls_js, name='js_reverse'),
url(r'^(?P<swh_id>swh:[0-9]+:[a-z]+:[0-9a-f]+.*)/$',
swh_id_browse, name='browse-swh-id'),
- url(r'^coverage/$', swh_coverage, name='swh-coverage')
+ url(r'^coverage/$', swh_coverage, name='swh-coverage'),
+ url(r'^jslicenses/$', jslicenses, name='jslicenses'),
]
diff --git a/yarn.lock b/yarn.lock
--- a/yarn.lock
+++ b/yarn.lock
@@ -9,27 +9,7 @@
dependencies:
"@babel/highlight" "^7.0.0"
-"@babel/core@>=7.1.0":
- version "7.2.2"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687"
- integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@babel/generator" "^7.2.2"
- "@babel/helpers" "^7.2.0"
- "@babel/parser" "^7.2.2"
- "@babel/template" "^7.2.2"
- "@babel/traverse" "^7.2.2"
- "@babel/types" "^7.2.2"
- convert-source-map "^1.1.0"
- debug "^4.1.0"
- json5 "^2.1.0"
- lodash "^4.17.10"
- resolve "^1.3.2"
- semver "^5.4.1"
- source-map "^0.5.0"
-
-"@babel/core@^7.3.3":
+"@babel/core@>=7.1.0", "@babel/core@^7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.3.tgz#d090d157b7c5060d05a05acaebc048bd2b037947"
integrity sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ==
@@ -49,18 +29,7 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/generator@^7.2.2":
- version "7.3.2"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.2.tgz#fff31a7b2f2f3dad23ef8e01be45b0d5c2fc0132"
- integrity sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==
- dependencies:
- "@babel/types" "^7.3.2"
- jsesc "^2.5.1"
- lodash "^4.17.10"
- source-map "^0.5.0"
- trim-right "^1.0.1"
-
-"@babel/generator@^7.3.3":
+"@babel/generator@^7.2.2", "@babel/generator@^7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.3.tgz#185962ade59a52e00ca2bdfcfd1d58e528d4e39e"
integrity sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A==
@@ -244,12 +213,7 @@
esutils "^2.0.2"
js-tokens "^4.0.0"
-"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3":
- version "7.3.2"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.2.tgz#95cdeddfc3992a6ca2a1315191c1679ca32c55cd"
- integrity sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==
-
-"@babel/parser@^7.3.3":
+"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3", "@babel/parser@^7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87"
integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==
@@ -363,9 +327,9 @@
lodash "^4.17.10"
"@babel/plugin-transform-classes@^7.2.0":
- version "7.2.2"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953"
- integrity sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==
+ version "7.3.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.3.tgz#a0532d6889c534d095e8f604e9257f91386c4b51"
+ integrity sha512-n0CLbsg7KOXsMF4tSTLCApNMoXk0wOPb0DYfsOO1e7SfIb9gOyfbpKI2MZ+AXfqvlfzq2qsflJ1nEns48Caf2w==
dependencies:
"@babel/helper-annotate-as-pure" "^7.0.0"
"@babel/helper-define-map" "^7.1.0"
@@ -492,9 +456,9 @@
"@babel/helper-replace-supers" "^7.1.0"
"@babel/plugin-transform-parameters@^7.2.0":
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2"
- integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==
+ version "7.3.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.3.3.tgz#3a873e07114e1a5bee17d04815662c8317f10e30"
+ integrity sha512-IrIP25VvXWu/VlBWTpsjGptpomtIkYrN/3aDp4UKm7xK6UxZY88kcJ1UwETbzHAlwN21MnNfwlar0u8y3KpiXw==
dependencies:
"@babel/helper-call-delegate" "^7.1.0"
"@babel/helper-get-function-arity" "^7.0.0"
@@ -652,16 +616,7 @@
globals "^11.1.0"
lodash "^4.17.10"
-"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.2":
- version "7.3.2"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.2.tgz#424f5be4be633fff33fb83ab8d67e4a8290f5a2f"
- integrity sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==
- dependencies:
- esutils "^2.0.2"
- lodash "^4.17.10"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.3.3":
+"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436"
integrity sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==
@@ -694,9 +649,9 @@
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@types/node@*":
- version "11.9.3"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-11.9.3.tgz#14adbb5ab8cd563f549fbae8dbe92e0b7d6e76cc"
- integrity sha512-DMiqG51GwES/c4ScBY0u5bDlH44+oY8AeYHjY1SGCWidD7h08o1dfHue/TGK7REmif2KiJzaUskO+Q0eaeZ2fQ==
+ version "11.9.4"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.9.4.tgz#ceb0048a546db453f6248f2d1d95e937a6f00a14"
+ integrity sha512-Zl8dGvAcEmadgs1tmSPcvwzO1YRsz38bVJQvH1RvRqSR9/5n61Q1ktcDL0ht3FXWR+ZpVmXVwN1LuH4Ax23NsA==
"@types/q@^1.5.1":
version "1.5.1"
@@ -704,9 +659,9 @@
integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==
"@types/unist@*", "@types/unist@^2.0.0":
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.2.tgz#5dc0a7f76809b7518c0df58689cd16a19bd751c6"
- integrity sha512-iHI60IbyfQilNubmxsq4zqSjdynlmc2Q/QvH9kjzg9+CCYVVzq1O6tc7VBzSygIwnmOt07w80IG6HDQvjv3Liw==
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
+ integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
"@types/vfile-message@*":
version "1.0.1"
@@ -1344,12 +1299,7 @@
jquery ">=1.8.2"
open-iconic ">=1.1.1"
-bootstrap@>=4.0.0, bootstrap@^4.1.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.0.tgz#2559ccb8d45426ac6c54db23eb3d1c9f4257fa22"
- integrity sha512-M0vqY0Z6UDweV2nLFl5dXcb+GIo53EBCGMMVxCGH5vJxl/jsr+HkULBMd4kn9rdpdBZwd3BduCgMOYOwJybo4Q==
-
-bootstrap@^4.3.1:
+bootstrap@>=4.0.0, bootstrap@^4.1.0, bootstrap@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac"
integrity sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==
@@ -1640,9 +1590,9 @@
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000929, caniuse-lite@^1.0.30000932:
- version "1.0.30000936"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000936.tgz#5d33b118763988bf721b9b8ad436d0400e4a116b"
- integrity sha512-orX4IdpbFhdNO7bTBhSbahp1EBpqzBc+qrvTRVUFfZgA4zta7TdM6PN5ZxkEUgDnz36m+PfWGcdX7AVfFWItJw==
+ version "1.0.30000938"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz#b64bf1427438df40183fce910fe24e34feda7a3f"
+ integrity sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw==
capture-stack-trace@^1.0.0:
version "1.0.1"
@@ -1737,9 +1687,9 @@
color-convert "^0.5.3"
chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.1.tgz#adc39ad55a2adf26548bd2afa048f611091f9184"
- integrity sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.2.tgz#9c23ea40b01638439e0513864d362aeacc5ad058"
+ integrity sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==
dependencies:
anymatch "^2.0.0"
async-each "^1.0.1"
@@ -1809,16 +1759,6 @@
dependencies:
restore-cursor "^2.0.0"
-cli-table3@^0.5.0:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"
- integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==
- dependencies:
- object-assign "^4.1.0"
- string-width "^2.1.1"
- optionalDependencies:
- colors "^1.1.2"
-
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
@@ -1939,11 +1879,6 @@
color-convert "^1.9.1"
color-string "^1.5.2"
-colors@^1.1.2:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
- integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
-
colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@@ -1984,11 +1919,11 @@
arity-n "^1.0.4"
compressible@~2.0.14:
- version "2.0.15"
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212"
- integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==
+ version "2.0.16"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.16.tgz#a49bf9858f3821b64ce1be0296afc7380466a77f"
+ integrity sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==
dependencies:
- mime-db ">= 1.36.0 < 2"
+ mime-db ">= 1.38.0 < 2"
compression@^1.5.2:
version "1.7.3"
@@ -2121,9 +2056,9 @@
serialize-javascript "^1.4.0"
core-js@^2.5.7:
- version "2.6.4"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.4.tgz#b8897c062c4d769dd30a0ac5c73976c47f92ea0d"
- integrity sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==
+ version "2.6.5"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895"
+ integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
@@ -2141,13 +2076,14 @@
require-from-string "^2.0.1"
cosmiconfig@^5.0.0:
- version "5.0.7"
- resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04"
- integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.1.0.tgz#6c5c35e97f37f985061cdf653f114784231185cf"
+ integrity sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q==
dependencies:
import-fresh "^2.0.0"
is-directory "^0.3.1"
js-yaml "^3.9.0"
+ lodash.get "^4.4.2"
parse-json "^4.0.0"
create-ecdh@^4.0.0:
@@ -2318,9 +2254,9 @@
integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=
css-what@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d"
- integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
+ integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
css@^2.0.0:
version "2.2.4"
@@ -2401,9 +2337,9 @@
integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==
cssnano@^4.1.0:
- version "4.1.9"
- resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.9.tgz#f2ac0f5a8b9396fcb11d25fb3aab1e86303fcbd2"
- integrity sha512-osEbYy4kzaNY3nkd92Uf3hy5Jqb5Aztuv+Ze3Z6DjRhyntZDlb3YljiYDdJ05k167U86CZpSR+rbuJYN7N3oBQ==
+ version "4.1.10"
+ resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2"
+ integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==
dependencies:
cosmiconfig "^5.0.0"
cssnano-preset-default "^4.0.7"
@@ -2718,14 +2654,7 @@
dependencies:
ms "2.0.0"
-debug@=3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
- dependencies:
- ms "2.0.0"
-
-debug@^3.1.0, debug@^3.2.5:
+debug@^3.1.0, debug@^3.2.5, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -2928,28 +2857,23 @@
esutils "^2.0.2"
dom-serializer@0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
- integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
+ integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
dependencies:
- domelementtype "~1.1.1"
- entities "~1.1.1"
+ domelementtype "^1.3.0"
+ entities "^1.1.1"
domain-browser@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
-domelementtype@1, domelementtype@^1.3.0:
+domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
-domelementtype@~1.1.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
- integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=
-
domhandler@^2.3.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
@@ -3049,7 +2973,7 @@
memory-fs "^0.4.0"
tapable "^1.0.0"
-entities@^1.1.1, entities@~1.1.1:
+entities@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
@@ -3692,11 +3616,11 @@
readable-stream "^2.3.6"
follow-redirects@^1.0.0:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.1.tgz#514973c44b5757368bad8bddfe52f81f015c94cb"
- integrity sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76"
+ integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==
dependencies:
- debug "=3.1.0"
+ debug "^3.2.6"
font-awesome@^4.7.0:
version "4.7.0"
@@ -4215,16 +4139,16 @@
integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=
htmlparser2@^3.10.0:
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464"
- integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
+ integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
dependencies:
- domelementtype "^1.3.0"
+ domelementtype "^1.3.1"
domhandler "^2.3.0"
domutils "^1.5.1"
entities "^1.1.1"
inherits "^2.0.1"
- readable-stream "^3.0.6"
+ readable-stream "^3.1.1"
http-deceiver@^1.2.7:
version "1.2.7"
@@ -5230,6 +5154,11 @@
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
integrity sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=
+lodash.get@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+ integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
+
lodash.max@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.max/-/lodash.max-4.0.1.tgz#8735566c618b35a9f760520b487ae79658af136a"
@@ -5506,22 +5435,17 @@
bn.js "^4.0.0"
brorand "^1.0.1"
-"mime-db@>= 1.36.0 < 2":
+"mime-db@>= 1.38.0 < 2", mime-db@~1.38.0:
version "1.38.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
-mime-db@~1.37.0:
- version "1.37.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
- integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
-
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19:
- version "2.1.21"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
- integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
+ version "2.1.22"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd"
+ integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
dependencies:
- mime-db "~1.37.0"
+ mime-db "~1.38.0"
mime@1.4.1:
version "1.4.1"
@@ -6281,9 +6205,9 @@
callsites "^3.0.0"
parse-asn1@^5.0.0:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.3.tgz#1600c6cc0727365d68b97f3aa78939e735a75204"
- integrity sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==
+ version "5.1.4"
+ resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc"
+ integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==
dependencies:
asn1.js "^4.0.0"
browserify-aes "^1.0.0"
@@ -7174,7 +7098,7 @@
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.0.6:
+readable-stream@^3.0.6, readable-stream@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06"
integrity sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==
@@ -7246,13 +7170,9 @@
integrity sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==
regexp-tree@^0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.1.tgz#27b455f9b138ca2e84c090e9aff1ffe2a04d97fa"
- integrity sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw==
- dependencies:
- cli-table3 "^0.5.0"
- colors "^1.1.2"
- yargs "^12.0.5"
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.5.tgz#7cd71fca17198d04b4176efd79713f2998009397"
+ integrity sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==
regexpp@^2.0.1:
version "2.0.1"
@@ -8238,9 +8158,9 @@
integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=
stylehacks@^4.0.0:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.2.tgz#d22eb2767598b1a704341290b42aeafb7945ce38"
- integrity sha512-AZwvn2b3aNKK1yp+VgNPOuC2jIJOvh9PAiCq2gjDBW1WkQxQUksR1RugOJRIOhMYTGHZeoMcMQKp3/qaS3evNg==
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
+ integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==
dependencies:
browserslist "^4.0.0"
postcss "^7.0.0"
@@ -9299,7 +9219,7 @@
y18n "^3.2.1"
yargs-parser "^8.1.0"
-yargs@^12.0.4, yargs@^12.0.5:
+yargs@^12.0.4:
version "12.0.5"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Nov 5 2024, 1:12 AM (19 w, 6 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3229276
Attached To
D1151: Add LibreJS compliance for swh-web
Event Timeline
Log In to Comment