Compare commits
5 Commits
bcaecf8cb7
...
f1edf363cc
Author | SHA1 | Date |
---|---|---|
Bauke | f1edf363cc | |
Bauke | d360e80158 | |
Bauke | d83aec1707 | |
Bauke | 35f9319012 | |
Bauke | 19cd2a2f0c |
|
@ -0,0 +1,129 @@
|
||||||
|
# Development Guide
|
||||||
|
|
||||||
|
Welcome to the Tildes Issue Log development guide, this will be very concise.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Clone the repository.
|
||||||
|
1. Create a `config.json` file from the sample `config.sample.json` file. The `gitlabToken` should be [a Personal Access Token](https://gitlab.com/profile/personal_access_tokens) with the `api` scope available.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
The Tildes Issue Log is set up with 7 scripts, 6 of which can be run on their own.
|
||||||
|
|
||||||
|
If you want to run any of these on their own, use `yarn ts-node 'source/scripts/<script>.ts'`.
|
||||||
|
|
||||||
|
These 7 are the following:
|
||||||
|
|
||||||
|
### `assets.ts`
|
||||||
|
|
||||||
|
Extracts the fonts and favicons `.tar` files located in `source/pages/assets/` and outputs them in `public/`.
|
||||||
|
|
||||||
|
### `download.ts`
|
||||||
|
|
||||||
|
Downloads all the commit, issue and merge request data with the GitLab API and saves it to `temp/data/`. If any of these already exist for today (meaning you have downloaded them previously) it won't try to redownload them and will use the existing ones instead.
|
||||||
|
|
||||||
|
### `feeds.ts`
|
||||||
|
|
||||||
|
*This is the script that can't be run on its own.*
|
||||||
|
|
||||||
|
Generates the Atom, JSON and RSS feeds from the post list that is created by `html.ts`. The feeds are output to `public/feed.{atom,json,rss}`.
|
||||||
|
|
||||||
|
### `html.ts`
|
||||||
|
|
||||||
|
Takes in all the generated data by `download.ts`, `official-topics.ts` and `statistics.ts`, and the Markdown posts in `source/pages/posts/` and generates all the HTML for the site.
|
||||||
|
|
||||||
|
The HTML is generated using Nunjucks templates, all of which can be found in `source/pages/templates/`.
|
||||||
|
|
||||||
|
The HTML generation also linkifies Tildes-style `@user` mentions and ~group mentions.
|
||||||
|
|
||||||
|
This script also writes a Markdown file to `temp/email.md` to be used for [the mailing list](https://lists.sr.ht/~bauke/tildes-issue-log). If you plan on sending the email, don't forget to change the header so instead of it being something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
<h2 id="may-2020">
|
||||||
|
May 2020
|
||||||
|
<span id="authors">by @Bauke</span>
|
||||||
|
</h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
It looks something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Tildes Issue Log
|
||||||
|
|
||||||
|
## May 2020 by @Bauke
|
||||||
|
```
|
||||||
|
|
||||||
|
### `official-topics.ts`
|
||||||
|
|
||||||
|
Scrapes [~tildes.official](https://tildes.net/~tildes.official) and extracts all the official topics that were posted after the latest one we have saved in `source/pages/data/official-topics.json`.
|
||||||
|
|
||||||
|
### `redirects.ts`
|
||||||
|
|
||||||
|
Creates HTML files for the posts [before the 2.0.0 redesign](https://gitlab.com/Bauke/tildes-issue-log/-/commit/959c68125e8ac810d79f9a8cc8d2d7072300b320) that contain a `<meta http-equiv="refresh">` tag that redirects to the new wanted location after 5 seconds.
|
||||||
|
|
||||||
|
The old URL scheme was `https://til.bauke.xyz/posts/<month>-<year>.html`.
|
||||||
|
|
||||||
|
The current URL scheme is `https://til.bauke.xyz/<year>/<month>.html`.
|
||||||
|
|
||||||
|
An example: https://til.bauke.xyz/posts/january-2020.html
|
||||||
|
|
||||||
|
### `statistics.ts`
|
||||||
|
|
||||||
|
Generates various statistics from the downloaded data `download.ts` creates.
|
||||||
|
|
||||||
|
## Writing Posts
|
||||||
|
|
||||||
|
To start writing a new post, create the Markdown file as `source/pages/posts/<year>/<month>.md`. Every post should contain the same header similar to this one:
|
||||||
|
|
||||||
|
```
|
||||||
|
<h2 id="may-2020">
|
||||||
|
May 2020
|
||||||
|
<span id="authors">by @Bauke</span>
|
||||||
|
</h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `@user` mentions are automatically linkified, so it's simple to add multiple authors.
|
||||||
|
|
||||||
|
After that it's all up to you. As mentioned in the `html.ts` section, `@user` mentions and ~group mentions are automatically linkified.
|
||||||
|
|
||||||
|
If you write and intend to publish a completely new post, don't forget to update the latest post link in the ReadMe.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
To test and build the entire site, you can run this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn test && yarn download && yarn statistics && yarn official-topics && yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
This will run all the scripts in the desired sequence. It's not necessary to run it like this, once you have successfully ran `yarn download && yarn statistics && yarn official-topics` once you can run `yarn build` by itself after, but this way everything is generated and ready for the post.
|
||||||
|
|
||||||
|
`yarn build` runs all the `build:...` commands inside `package.json`. Some of these commands are do not run scripts, so if you want to build the entire site use `yarn build` to include everything.
|
||||||
|
|
||||||
|
## Testing/Linting
|
||||||
|
|
||||||
|
The JavaScript and TypeScript is linted by XO. If XO ever complains, you can usually fix it quickly with `xo --fix`. If not it will usually tell you what exactly to fix.
|
||||||
|
|
||||||
|
The SCSS is linted by Stylelint with an XO-like config.
|
||||||
|
|
||||||
|
If you only want to lint JS/TS, use `yarn xo`.
|
||||||
|
|
||||||
|
If you only want to lint SCSS, use `yarn stylelint 'source/pages/scss/**'`. Stylelint might try to lint the compiled CSS in `public/` without the specified path and blow up with errors, so don't forget to include it.
|
||||||
|
|
||||||
|
You can run both of these linters at the same time with `yarn test`.
|
||||||
|
|
||||||
|
## Committing
|
||||||
|
|
||||||
|
If you have written a new post, there's a few things you should do before you commit.
|
||||||
|
|
||||||
|
* Proofread the new post.
|
||||||
|
* Build the site, copy the entire contents of the post from the site. (`CTRL+A` and then `CTRL+C`). Then paste this into LibreOffice Writer or equivalent program and do a spellcheck. Ignore any false positives it might mark like `@user` mentions or unknown but correct words.
|
||||||
|
* Make sure there are new statistics for this month in `source/pages/data/statistics.json`. Even if they are all 0, they should be included.
|
||||||
|
* If any official topics were posted, make they are added correctly in `source/pages/data/official-topics.json`.
|
||||||
|
|
||||||
|
## Deploying
|
||||||
|
|
||||||
|
Deployment is completely and automatically handled via the GitLab CI/CD and hosted with GitLab Pages.
|
||||||
|
|
||||||
|
The CI/CD will first run `yarn test` to make sure everything is good. And then it will run `yarn build`. If successful it will save the generated `public/` directory as artifacts and upload it to be used on the live site. If either of these steps failed nothing will be uploaded.
|
|
@ -1,9 +1,13 @@
|
||||||
# Tildes Issue Log
|
# Tildes Issue Log
|
||||||
|
|
||||||
[Latest Post: **February 2020**](https://til.bauke.xyz/2020/february.html).
|
[Latest Post: **June 2020**](https://til.bauke.xyz/2020/june.html).
|
||||||
|
|
||||||
[Click here to view all posts](https://til.bauke.xyz/posts.html).
|
[Click here to view all posts](https://til.bauke.xyz/posts.html).
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
If you're interested in developing the site or writing a new post, see [the Development document](Development.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under [AGPL-3.0-or-later](License).
|
Licensed under [AGPL-3.0-or-later](License).
|
||||||
|
|
32
package.json
32
package.json
|
@ -5,6 +5,7 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"serve": "serve 'public/'",
|
||||||
"build": "mkdir 'public/images/' 'public/fonts/' -p && yarn build:assets && yarn build:html && yarn build:images && yarn build:js && yarn build:redirects && yarn build:sass",
|
"build": "mkdir 'public/images/' 'public/fonts/' -p && yarn build:assets && yarn build:html && yarn build:images && yarn build:js && yarn build:redirects && yarn build:sass",
|
||||||
"build:assets": "TZ=UTC ts-node 'source/scripts/assets.ts'",
|
"build:assets": "TZ=UTC ts-node 'source/scripts/assets.ts'",
|
||||||
"build:html": "TZ=UTC ts-node 'source/scripts/html.ts'",
|
"build:html": "TZ=UTC ts-node 'source/scripts/html.ts'",
|
||||||
|
@ -21,30 +22,31 @@
|
||||||
"modern-normalize": "^0.6.0"
|
"modern-normalize": "^0.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cheerio": "^0.22.16",
|
"@types/cheerio": "^0.22.18",
|
||||||
"@types/got": "^9.6.9",
|
"@types/got": "^9.6.11",
|
||||||
"@types/marked": "^0.7.2",
|
"@types/marked": "^1.1.0",
|
||||||
"@types/nunjucks": "^3.1.3",
|
"@types/nunjucks": "^3.1.3",
|
||||||
"@types/tar": "^4.0.3",
|
"@types/tar": "^4.0.3",
|
||||||
"@types/wordwrap": "^1.0.0",
|
"@types/wordwrap": "^1.0.0",
|
||||||
"cheerio": "^1.0.0-rc.3",
|
"cheerio": "^1.0.0-rc.3",
|
||||||
"cpy-cli": "^3.1.0",
|
"cpy-cli": "^3.1.1",
|
||||||
"fecha": "^4.1.0",
|
"fecha": "^4.2.0",
|
||||||
"feed": "^4.1.0",
|
"feed": "^4.2.0",
|
||||||
"gitlab": "^14.2.2",
|
"gitlab": "^14.2.2",
|
||||||
"got": "^10.6.0",
|
"got": "^11.3.0",
|
||||||
"htmlclean": "^3.0.8",
|
"htmlclean": "^3.0.8",
|
||||||
"marked": "^0.8.0",
|
"marked": "^1.1.0",
|
||||||
"nunjucks": "^3.2.0",
|
"nunjucks": "^3.2.1",
|
||||||
"sass": "^1.26.1",
|
"sass": "^1.26.9",
|
||||||
"stylelint": "^13.2.0",
|
"serve": "^11.3.2",
|
||||||
|
"stylelint": "^13.6.1",
|
||||||
"stylelint-config-xo-scss": "^0.12.0",
|
"stylelint-config-xo-scss": "^0.12.0",
|
||||||
"stylelint-config-xo-space": "^0.14.0",
|
"stylelint-config-xo-space": "^0.14.0",
|
||||||
"tar": "^6.0.1",
|
"tar": "^6.0.2",
|
||||||
"ts-node": "^8.6.2",
|
"ts-node": "^8.10.2",
|
||||||
"typescript": "^3.8.2",
|
"typescript": "^3.9.5",
|
||||||
"wordwrap": "^1.0.0",
|
"wordwrap": "^1.0.0",
|
||||||
"xo": "^0.27.2"
|
"xo": "^0.32.0"
|
||||||
},
|
},
|
||||||
"stylelint": {
|
"stylelint": {
|
||||||
"extends": [
|
"extends": [
|
||||||
|
|
|
@ -405,7 +405,7 @@
|
||||||
"commits": 30
|
"commits": 30
|
||||||
},
|
},
|
||||||
"issues": {
|
"issues": {
|
||||||
"closed": 9,
|
"closed": 8,
|
||||||
"opened": 9
|
"opened": 9
|
||||||
},
|
},
|
||||||
"lines": {
|
"lines": {
|
||||||
|
@ -498,5 +498,45 @@
|
||||||
},
|
},
|
||||||
"month": 4,
|
"month": 4,
|
||||||
"year": 2020
|
"year": 2020
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"contributions": {
|
||||||
|
"authors": 2,
|
||||||
|
"commits": 11
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"closed": 4,
|
||||||
|
"opened": 13
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"added": 243,
|
||||||
|
"removed": 41
|
||||||
|
},
|
||||||
|
"mergeRequests": {
|
||||||
|
"closed": 1,
|
||||||
|
"opened": 1
|
||||||
|
},
|
||||||
|
"month": 5,
|
||||||
|
"year": 2020
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"contributions": {
|
||||||
|
"authors": 1,
|
||||||
|
"commits": 7
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"closed": 1,
|
||||||
|
"opened": 10
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"added": 197,
|
||||||
|
"removed": 283
|
||||||
|
},
|
||||||
|
"mergeRequests": {
|
||||||
|
"closed": 0,
|
||||||
|
"opened": 0
|
||||||
|
},
|
||||||
|
"month": 6,
|
||||||
|
"year": 2020
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -8,7 +8,7 @@ window.addEventListener('load', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the theme button is clicked, switch the theme to the other one.
|
// When the theme button is clicked, switch the theme to the other one.
|
||||||
themeToggleButton.addEventListener('click', event => {
|
themeToggleButton.addEventListener('click', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (document.body.getAttribute('id') === 'dark-theme') {
|
if (document.body.getAttribute('id') === 'dark-theme') {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<h2 id="june-2020">
|
||||||
|
June 2020
|
||||||
|
<span id="authors">by @Bauke</span>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
### Another Very Short One
|
||||||
|
|
||||||
|
Just like last month, this month's also a shorter one. Nonetheless, some things still happened:
|
||||||
|
|
||||||
|
* Comments that are removed by a site admin and then deleted by the comment author will now show that it was removed. Previously it would show as deleted but the reason it was deleted is often because it was removed.
|
||||||
|
* The specialized coronavirus views that were introduced [in March](https://til.bauke.xyz/2020/march.html#covid-19) and were visible at the top of the home page have been removed.
|
||||||
|
* A [new feature was introduced](https://tildes.net/~tildes/pt7/you_cant_reply_to_this_user_yet_please_wait_29_minutes#comment-57nh) that added a hard delay when 2 people were replying to each other too quickly. It was removed a few days after the delay was being triggered more than @Deimos liked, but it will likely come back in the future in an improved form.
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2 id="may-2020">
|
||||||
|
May 2020
|
||||||
|
<span id="authors">by @Bauke</span>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
### A Very Short One
|
||||||
|
|
||||||
|
* A bug with tag autocompletion has been fixed, [thanks ASZH](https://gitlab.com/tildes/tildes/-/merge_requests/104)!
|
||||||
|
* When logging in, if you enter the wrong username or password, Tildes will now specifically tell you which one was wrong.
|
||||||
|
* A bug was fixed that caused an internal server error when voting on ignored topics.
|
|
@ -17,5 +17,5 @@ async function entry(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
entry();
|
void entry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ async function setupGitLabAPI(): Promise<GitLab> {
|
||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setupTempDirectory(): Promise<string> {
|
async function setupTemporaryDirectory(): Promise<string> {
|
||||||
const tempDirectory: string = join(__dirname, '../../temp/');
|
const temporaryDirectory: string = join(__dirname, '../../temp/');
|
||||||
await fsp.mkdir(tempDirectory + 'data/', {recursive: true});
|
await fsp.mkdir(temporaryDirectory + 'data/', {recursive: true});
|
||||||
return tempDirectory;
|
return temporaryDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getConfig(): Promise<Config> {
|
async function getConfig(): Promise<Config> {
|
||||||
|
@ -33,13 +33,13 @@ async function getConfig(): Promise<Config> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCommits(): Promise<any[]> {
|
export async function getCommits(): Promise<any[]> {
|
||||||
const tempDirectory: string = await setupTempDirectory();
|
const temporaryDirectory: string = await setupTemporaryDirectory();
|
||||||
const api: GitLab = await setupGitLabAPI();
|
const api: GitLab = await setupGitLabAPI();
|
||||||
const project: gitlab.ProjectSchema = await api.Projects.show(
|
const project: gitlab.ProjectSchema = await api.Projects.show(
|
||||||
'tildes/tildes'
|
'tildes/tildes'
|
||||||
);
|
);
|
||||||
const commitsPath: string = join(
|
const commitsPath: string = join(
|
||||||
tempDirectory,
|
temporaryDirectory,
|
||||||
`data/commits (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
|
`data/commits (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
|
||||||
);
|
);
|
||||||
let commits: any[];
|
let commits: any[];
|
||||||
|
@ -59,13 +59,13 @@ export async function getCommits(): Promise<any[]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getIssues(): Promise<any[]> {
|
export async function getIssues(): Promise<any[]> {
|
||||||
const tempDirectory: string = await setupTempDirectory();
|
const temporaryDirectory: string = await setupTemporaryDirectory();
|
||||||
const api: GitLab = await setupGitLabAPI();
|
const api: GitLab = await setupGitLabAPI();
|
||||||
const project: gitlab.ProjectSchema = await api.Projects.show(
|
const project: gitlab.ProjectSchema = await api.Projects.show(
|
||||||
'tildes/tildes'
|
'tildes/tildes'
|
||||||
);
|
);
|
||||||
const issuesPath: string = join(
|
const issuesPath: string = join(
|
||||||
tempDirectory,
|
temporaryDirectory,
|
||||||
`data/issues (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
|
`data/issues (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
|
||||||
);
|
);
|
||||||
let issues: any[];
|
let issues: any[];
|
||||||
|
@ -83,13 +83,13 @@ export async function getIssues(): Promise<any[]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMergeRequests(): Promise<any[]> {
|
export async function getMergeRequests(): Promise<any[]> {
|
||||||
const tempDirectory: string = await setupTempDirectory();
|
const temporaryDirectory: string = await setupTemporaryDirectory();
|
||||||
const api: GitLab = await setupGitLabAPI();
|
const api: GitLab = await setupGitLabAPI();
|
||||||
const project: gitlab.ProjectSchema = await api.Projects.show(
|
const project: gitlab.ProjectSchema = await api.Projects.show(
|
||||||
'tildes/tildes'
|
'tildes/tildes'
|
||||||
);
|
);
|
||||||
const mergeRequestsPath: string = join(
|
const mergeRequestsPath: string = join(
|
||||||
tempDirectory,
|
temporaryDirectory,
|
||||||
`data/merge requests (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
|
`data/merge requests (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
|
||||||
);
|
);
|
||||||
let mergeRequests: any[];
|
let mergeRequests: any[];
|
||||||
|
@ -114,5 +114,5 @@ export async function getMergeRequests(): Promise<any[]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
entry();
|
void entry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {promises as fsp} from 'fs';
|
import {promises as fsp} from 'fs';
|
||||||
import {basename, join} from 'path';
|
import {basename, join} from 'path';
|
||||||
import fecha from 'fecha';
|
import fecha from 'fecha';
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
import htmlclean from 'htmlclean';
|
import htmlclean from 'htmlclean';
|
||||||
import marked from 'marked';
|
import marked from 'marked';
|
||||||
import nunjucks from 'nunjucks';
|
import nunjucks from 'nunjucks';
|
||||||
|
@ -99,7 +99,7 @@ async function entry(): Promise<void> {
|
||||||
|
|
||||||
// Get the statistics for that month.
|
// Get the statistics for that month.
|
||||||
const statistic: Statistics = statistics.find(
|
const statistic: Statistics = statistics.find(
|
||||||
val => val.year === Number(year) && val.month === monthNumber
|
(value) => value.year === Number(year) && value.month === monthNumber
|
||||||
)!;
|
)!;
|
||||||
|
|
||||||
const topics: OfficialTopic[] = await getTopicsFromMonth(
|
const topics: OfficialTopic[] = await getTopicsFromMonth(
|
||||||
|
@ -184,7 +184,7 @@ async function entry(): Promise<void> {
|
||||||
export async function renderTemplate(
|
export async function renderTemplate(
|
||||||
template: string,
|
template: string,
|
||||||
location: string,
|
location: string,
|
||||||
context: object = {}
|
context: Record<string, unknown> = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const html: string = htmlclean(nunjucks.render(template, context));
|
const html: string = htmlclean(nunjucks.render(template, context));
|
||||||
await fsp.writeFile(location, html);
|
await fsp.writeFile(location, html);
|
||||||
|
@ -211,5 +211,5 @@ export function pluralize(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
entry();
|
void entry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ async function entry(): Promise<void> {
|
||||||
|
|
||||||
// If all pagination buttons are "previous" buttons, stop the loop.
|
// If all pagination buttons are "previous" buttons, stop the loop.
|
||||||
if (
|
if (
|
||||||
paginationButtons.every(val =>
|
paginationButtons.every((value) =>
|
||||||
val.firstChild.data?.toLowerCase().includes('prev')
|
value.firstChild.data?.toLowerCase().includes('prev')
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
hasNextButton = false;
|
hasNextButton = false;
|
||||||
|
@ -76,7 +76,7 @@ async function entry(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function wait(timeout: number): Promise<void> {
|
export async function wait(timeout: number): Promise<void> {
|
||||||
return new Promise(resolve => setTimeout(resolve, timeout));
|
return new Promise((resolve) => setTimeout(resolve, timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTopicsFromMonth(
|
export async function getTopicsFromMonth(
|
||||||
|
@ -100,5 +100,5 @@ export async function getTopicsFromMonth(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
entry();
|
void entry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,5 +33,5 @@ async function entry(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
entry();
|
void entry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,7 @@ export async function findData<T extends Result>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the monthly that applies to this datapoint.
|
// Find the monthly that applies to this datapoint.
|
||||||
const monthly: T | undefined = monthlies.find(result =>
|
const monthly: T | undefined = monthlies.find((result) =>
|
||||||
findFn(result, point)
|
findFn(result, point)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -311,11 +311,11 @@ async function getResultCount(
|
||||||
month: number
|
month: number
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
const result: MonthlyResult | undefined = results.find(
|
const result: MonthlyResult | undefined = results.find(
|
||||||
val => val.year === year && val.month === month
|
(value) => value.year === year && value.month === month
|
||||||
);
|
);
|
||||||
return result === undefined ? 0 : result.count;
|
return result === undefined ? 0 : result.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
entry();
|
void entry();
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue