archive
/
givemoneyto.me
Archived
1
Fork 0
This repository has been archived on 2023-03-26. You can view files and clone it, but cannot push or open issues or pull requests.
givemoneyto.me/index.ts

154 lines
3.9 KiB
TypeScript
Raw Permalink Normal View History

2019-06-29 16:23:38 +01:00
import { readFileSync, writeFileSync } from 'fs';
2019-06-29 18:11:10 +01:00
import glob from 'glob';
2019-06-29 16:23:38 +01:00
import Handlebars from 'handlebars';
2019-06-29 18:22:14 +01:00
import jsyaml from 'js-yaml';
2019-06-29 16:23:38 +01:00
import mkdirp from 'mkdirp';
2019-06-29 17:56:02 +01:00
import Bundler from 'parcel-bundler';
import { dirname, join } from 'path';
2019-06-29 17:21:43 +01:00
import ProgressBar from 'progress';
2019-06-29 17:56:02 +01:00
import rimraf from 'rimraf';
import { mapObject, range } from 'underscore';
2019-06-29 13:26:43 +01:00
2019-06-29 18:22:14 +01:00
interface Account {
image: string;
link: string;
}
interface Redirect {
src: string;
dest: string;
}
2019-06-29 13:26:43 +01:00
const BUILD_DIR = join(__dirname, 'build');
const SRC_DIR = join(__dirname, 'src');
2019-06-29 17:43:03 +01:00
const PROGRESS_BAR_FORMAT = '[:bar] :rate/ps :percent :current/:total';
2019-06-29 17:56:02 +01:00
const MAX_VALUE = process.env.MAX_VALUE
? parseInt(process.env.MAX_VALUE, 10)
: 2;
2019-06-29 13:26:43 +01:00
const BUNDLER_OPTIONS = {
outDir: BUILD_DIR,
watch: false,
minify: true,
};
2019-07-01 15:46:34 +01:00
const NEW_LINES_RE = /(\r\n|\n|\r)/gm;
2019-06-29 13:26:43 +01:00
function readAccounts(): ReadonlyArray<Account> {
2019-06-29 21:17:01 +01:00
const rawAccounts: object = jsyaml.safeLoad(
2019-06-29 21:13:47 +01:00
readFileSync(join(__dirname, 'accounts.yml')).toString()
);
return Object.values(
mapObject(rawAccounts, (val, key) => {
return {
...val,
name: key,
};
})
);
}
2019-06-29 17:21:43 +01:00
function statusOutput(message: string) {
2019-06-29 17:43:03 +01:00
console.log('> ' + message + '...');
2019-06-29 17:21:43 +01:00
}
function isPrecision(value: number, precision: number) {
return value.toFixed(precision) === value.toString();
}
function writeTemplate(
template: HandlebarsTemplateDelegate,
value: string,
context: any
) {
2019-06-29 16:23:38 +01:00
const outputFile = join(BUILD_DIR, value, 'index.html');
mkdirp.sync(dirname(outputFile));
2019-10-27 23:18:35 +00:00
writeFileSync(
outputFile,
template({
...context,
outputUrl: encodeURIComponent(`https://givemoneyto.me/${value}/`),
}).replace(NEW_LINES_RE, '')
);
2019-06-29 16:23:38 +01:00
}
function writeRedirects(redirects: ReadonlyArray<Redirect>) {
const template = Handlebars.compile(
readFileSync(join(SRC_DIR, 'redirects.txt')).toString()
);
writeFileSync(join(BUILD_DIR, '_redirects'), template({ redirects }));
}
2019-06-29 21:41:41 +01:00
function humanize(value: number) {
if (isPrecision(value, 0)) {
return value.toString();
}
return value.toFixed(2);
}
2019-06-29 13:26:43 +01:00
(async function() {
rimraf.sync(BUILD_DIR);
2019-06-29 21:13:47 +01:00
statusOutput('Reading accounts');
const accounts = readAccounts();
2019-06-29 18:22:14 +01:00
2019-06-29 17:43:03 +01:00
statusOutput('Creating template');
2019-06-29 13:26:43 +01:00
const bundler = new Bundler(join(SRC_DIR, 'template.html'), BUNDLER_OPTIONS);
await bundler.bundle();
2019-06-29 16:23:38 +01:00
2019-06-29 17:43:03 +01:00
statusOutput('Compiling HTML template');
2019-06-29 21:13:47 +01:00
Handlebars.registerPartial(
'accounts',
readFileSync(join(SRC_DIR, 'accounts.html')).toString()
);
2019-06-29 17:43:03 +01:00
const template = Handlebars.compile(
readFileSync(join(BUILD_DIR, 'template.html')).toString()
);
2019-06-29 16:23:38 +01:00
const possibleValues = range(0, MAX_VALUE, 0.01);
2019-06-29 17:21:43 +01:00
const bar = new ProgressBar(PROGRESS_BAR_FORMAT, {
total: possibleValues.length,
2019-06-29 17:43:03 +01:00
width: 40,
2019-06-29 17:21:43 +01:00
});
2019-06-29 18:22:14 +01:00
const baseContext = {
2019-06-29 21:13:47 +01:00
accounts,
2019-06-29 18:22:14 +01:00
};
const redirects: Redirect[] = [];
2019-06-29 17:43:03 +01:00
statusOutput('Generating pages');
possibleValues.forEach(i => {
if (i) {
const value = parseFloat(i.toFixed(2));
const context = {
2019-06-29 18:22:14 +01:00
...baseContext,
2019-06-29 21:43:14 +01:00
displayValue: '£' + humanize(value),
value: humanize(value),
};
writeTemplate(template, value.toString(), context);
if (isPrecision(value, 1)) {
redirects.push({
src: value.toString() + '0',
dest: value.toString(),
});
// writeTemplate(template, value.toString() + '0', context);
}
if (isPrecision(value, 0)) {
redirects.push({
src: value.toString() + '.00',
dest: value.toString(),
});
redirects.push({
src: value.toString() + '.0',
dest: value.toString(),
});
// writeTemplate(template, value.toString() + '.00', context);
}
}
2019-06-29 17:21:43 +01:00
bar.tick();
2019-06-29 16:35:41 +01:00
});
2019-06-29 21:41:41 +01:00
writeTemplate(template, '', { ...baseContext, displayValue: 'money' });
2019-06-29 21:13:47 +01:00
const filesOutput = glob.sync(join(BUILD_DIR, '**/index.html')).length;
2019-06-29 18:11:10 +01:00
console.log(`Generated ${filesOutput} files.`);
writeRedirects(redirects);
2019-06-29 13:26:43 +01:00
})();