diff --git a/.eslintrc.yml b/.eslintrc.yml index 34c77cabe4..f2914ee076 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -27,6 +27,7 @@ overrides: - test/integration/options/watch.spec.js - test/integration/helpers.js - lib/growl.js + - docs/_data/**/*.js parserOptions: ecmaVersion: 2018 env: diff --git a/docs/_data/blacklist.json b/docs/_data/blacklist.json new file mode 100644 index 0000000000..3949526a9b --- /dev/null +++ b/docs/_data/blacklist.json @@ -0,0 +1,21 @@ +[ + "cheap-writing-service", + "emailmarketingservices-io", + "device-tricks1", + "my-true-media", + "yiannakis-ttafounas-ttafounas", + "writerseperhour", + "casinotop-com", + "casino-topp", + "casinoutanreg", + "supercazino-ro", + "igor-noskov", + "blue-link-seo", + "casino-online", + "domywriting", + "writemypaper4me", + "trust-my-paper", + "seowebsitetraffic-net", + "pfannen-test", + "mochajs" +] diff --git a/docs/_data/supporters.js b/docs/_data/supporters.js new file mode 100644 index 0000000000..f4c9cdc296 --- /dev/null +++ b/docs/_data/supporters.js @@ -0,0 +1,115 @@ +#!/usr/bin/env node +'use strict'; + +const debug = require('debug')('mocha:docs:data:supporters'); +const needle = require('needle'); +const blacklist = new Set(require('./blacklist.json')); + +const API_ENDPOINT = 'https://api.opencollective.com/graphql/v2'; + +const query = `query account($limit: Int, $offset: Int, $slug: String) { + account(slug: $slug) { + orders(limit: $limit, offset: $offset) { + limit + offset + totalCount + nodes { + fromAccount { + name + slug + website + avatar: imageUrl(height:64) + type + } + totalDonations { + value + } + createdAt + } + } + } +}`; + +const graphqlPageSize = 1000; + +const nodeToSupporter = node => ({ + name: node.fromAccount.name, + slug: node.fromAccount.slug, + website: node.fromAccount.website, + avatar: node.fromAccount.avatar, + firstDonation: node.createdAt, + totalDonations: node.totalDonations.value * 100, + type: node.fromAccount.type +}); + +/** + * Retrieves donation data from OC + * + * Handles pagination + * @param {string} slug - Collective slug to get donation data from + * @returns {Promise} Array of raw donation data + */ +const getAllOrders = async (slug = 'mochajs') => { + let allOrders = []; + const variables = {limit: graphqlPageSize, offset: 0, slug}; + + // Handling pagination if necessary (2 pages for ~1400 results in May 2019) + while (true) { + const result = await needle( + 'post', + API_ENDPOINT, + {query, variables}, + {json: true} + ); + const orders = result.body.data.account.orders.nodes; + allOrders = [...allOrders, ...orders]; + variables.offset += graphqlPageSize; + if (orders.length < graphqlPageSize) { + debug('retrieved %d orders', allOrders.length); + return allOrders; + } else { + debug( + 'loading page %d of orders...', + Math.floor(variables.offset / graphqlPageSize) + ); + } + } +}; + +module.exports = async () => { + const orders = await getAllOrders(); + // Deduplicating supporters with multiple orders + const uniqueSupporters = new Map(); + + const supporters = orders + .map(nodeToSupporter) + .filter(supporter => !blacklist.has(supporter.slug)) + .reduce((supporters, supporter) => { + if (uniqueSupporters.has(supporter.slug)) { + // aggregate donation totals + uniqueSupporters.get(supporter.slug).totalDonations += + supporter.totalDonations; + return supporters; + } + uniqueSupporters.set(supporter.slug, supporter); + return [...supporters, supporter]; + }, []) + .sort((a, b) => b.totalDonations - a.totalDonations) + .reduce( + (supporters, supporter) => { + supporters[ + supporter.type === 'INDIVIDUAL' ? 'backers' : 'sponsors' + ].push(supporter); + return supporters; + }, + {sponsors: [], backers: []} + ); + + debug( + 'found %d valid backers and %d valid sponsors (%d total)', + supporters.backers.length, + supporters.sponsors.length, + supporters.backers.length + supporters.sponsors.length + ); + return supporters; +}; diff --git a/docs/_includes/backers.md b/docs/_includes/backers.md index 4481202591..de36ba9964 100644 --- a/docs/_includes/backers.md +++ b/docs/_includes/backers.md @@ -1,7 +1,11 @@ ## Backers -Find Mocha helpful? Become a [backer](https://opencollective.com/mochajs#support) and support Mocha with a monthly donation. +Find Mocha helpful? Become a [backer](https://opencollective.com/mochajs#support) and support Mocha with a monthly donation. - -{% for i in (0..29) %}[![](https://opencollective.com/mochajs/backer/{{ i }}/avatar.jpg)](https://opencollective.com/mochajs/backer/{{ i }}/website){: target="_blank" rel="noopener"}{% endfor %} -{: .image-list id="_backers" } +{% comment %} +Do not remove whitespace below! +{% endcomment %} + + diff --git a/docs/_includes/default.liquid b/docs/_includes/default.liquid new file mode 100644 index 0000000000..a8be8a0d56 --- /dev/null +++ b/docs/_includes/default.liquid @@ -0,0 +1,176 @@ + + + + + + {{ title }} + + + + + + + + + + +
+

+ + + +

+

simple, flexible, fun

+
+ +
{{ content }}
+ + + + + + + + diff --git a/docs/_includes/sponsors.md b/docs/_includes/sponsors.md index 257f9524b1..d95cf21eb8 100644 --- a/docs/_includes/sponsors.md +++ b/docs/_includes/sponsors.md @@ -2,9 +2,10 @@ Use Mocha at Work? Ask your manager or marketing team if they'd help [support](https://opencollective.com/mochajs#support) our project. Your company's logo will also be displayed on [npmjs.com](http://npmjs.com/package/mocha) and our [GitHub repository](https://github.com/mochajs/mocha#sponsors). - +{% comment %} +Do not remove whitespace below! +{% endcomment %} -{% for i in (0..15) %}[![](https://opencollective.com/mochajs/sponsor/{{ i }}/avatar.png)](https://opencollective.com/mochajs/sponsor/{{ i }}/website){: target="\_blank"} {% endfor %} -{: .image-list .faded-images} - - + diff --git a/docs/css/style.css b/docs/css/style.css index 39fefea91e..4861dc6b56 100644 --- a/docs/css/style.css +++ b/docs/css/style.css @@ -74,21 +74,30 @@ nav.badges a + a { margin-left: 3px; } -.image-list { +ul.image-list { overflow: hidden; text-align: center; + list-style: none; + column-count: 1; } -.image-list a { +ul.image-list li { + border-bottom: none; display: inline-block; - margin: 6px; + margin: 2px; + padding: 0; } -.image-list a img { +ul.image-list li a img { display: block; height: 64px; } +ul#backers.image-list li a img { + width: 64px; + clip-path: inset(0, 0, 64px, 64px); +} + .faded-images { background-color: #ddd; border: 1px solid; diff --git a/package.json b/package.json index 777d26bd28..323a50d393 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "markdown-magic-package-json": "^2.0.1", "markdown-toc": "^1.2.0", "markdownlint-cli": "^0.22.0", + "needle": "^2.4.1", "nps": "^5.9.12", "nyc": "^15.0.0", "prettier": "^1.19.1",