Jofthomas's picture
Jofthomas HF staff
Upload 4781 files
5c2ed06 verified
/**
* Imports and generates the '@smogon/sets' package.
* Pokemon Showdown - http://pokemonshowdown.com/
*
* Run with `node tools/set-import [version]`. If version is not specified,
* the 'patch' version of the existing package will be bumped. If version is
* 'minor' or 'monthly', the minor version will be bumped. In general, every
* month after usage stats are processed this script should be run to update
* the sets package and bump the minor version. If this script is run in
* between usage stats updates, the patch version should be bumped. If a
* breaking change occurs to the output format, the major version must be
* bumped (with 'major' or 'breaking' as the version argument). The exact
* version string (eg. '1.2.3') can also be provided. After creating the set
* import, provided there are no serious errors, the package can be released
* by running `npm publish` in the `sets/` directory.
*
* @license MIT
*/
'use strict';
const child_process = require('child_process');
const path = require('path');
const fs = require('fs');
const shell = cmd => child_process.execSync(cmd, { stdio: 'inherit', cwd: path.resolve(__dirname, '../..') });
shell('node build');
function missing(dep) {
try {
require.resolve(dep);
return false;
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') throw err;
return true;
}
}
// We depend on smogon as a devDependency in order to get the typing information
if (missing('smogon')) shell(`npm install --no-save smogon`);
// Rather obnoxiously, the TeamValidator used by the importer refers to
// rulesets which rely on Chat.plural to be set up, so we do so here.
global.Chat = {};
Chat.plural = function (num, plural = 's', singular = '') {
if (num && typeof num.length === 'number') {
num = num.length;
} else if (num && typeof num.size === 'number') {
num = num.size;
} else {
num = Number(num);
}
return (num !== 1 ? plural : singular);
};
const importer = require('../../dist/tools/set-import/importer.js');
const SETS = path.resolve(__dirname, 'sets');
(async () => {
// Clean up old artifacts
for (const file of fs.readdirSync(SETS)) {
if (file.startsWith('gen') && file.endsWith('json')) {
fs.unlinkSync(path.join(SETS, file));
}
}
const imports = [];
for (const [i, generationData] of (await importer.importAll()).entries()) {
fs.writeFileSync(path.resolve(SETS, `gen${i + 1}.json`), JSON.stringify(generationData));
imports.push(`gen${i + 1}`);
for (const format in generationData) {
fs.writeFileSync(path.resolve(SETS, `${format}.json`), JSON.stringify(generationData[format]));
imports.push(format);
}
}
let version = process.argv[2];
if (!version || version.match(/^[^\d]/)) {
try {
const current = require('./sets/package.json').version;
const [major, minor, patch] = current.split('.');
if (version === 'major' || version === 'breaking') {
version = `${Number(major) + 1}.0.0`;
} else if (version === 'minor' || version === 'monthly') {
version = `${major}.${Number(minor) + 1}.0`;
} else {
version = `${major}.${minor}.${Number(patch) + 1}`;
}
} catch {
console.error("Version required to create '@smogon/sets' package");
process.exit(1);
}
}
const packagejson = {
"name": "@smogon/sets",
version,
"description": "Set data imported from Smogon.com and used on Pokémon Showdown",
"main": "index.js",
"unpkg": "index.js",
"types": "index.d.ts",
"repository": "github:smogon/sets",
"publishConfig": {
"access": "public",
},
"license": "UNLICENSED", // The code/typings are MIT, but not all sources of data fall under MIT
};
fs.writeFileSync(path.resolve(SETS, 'package.json'), JSON.stringify(packagejson, null, 2));
const indexjs = [
'"use strict";',
'var JSON;',
// This hack allows us to require this package in Node and in the browser
// and have the Node code which uses `require` get stripped on web.
'if (typeof window === "undefined") {',
' JSON = {',
imports.map(n => ` "${n}": load("./${n}.json")`).join(',\n'),
' };',
'} else {',
' JSON = {',
imports.map(n => ` "${n}": import("./${n}.json")`).join(',\n'),
' };',
'}',
'function load(path) {',
' return Promise.resolve(require(path));',
'}',
'function forGen(gen) {',
// eslint-disable-next-line no-template-curly-in-string
' return JSON[`gen${typeof gen === "number" ? gen : gen.num}`];',
'}',
'exports.forGen = forGen;',
'function forFormat(format) {',
' return JSON[format];',
'}',
'exports.forFormat = forFormat;',
].join('\n');
fs.writeFileSync(path.resolve(SETS, 'index.js'), indexjs);
})().catch(err => console.error(err));