Commit 5abb3fcd authored by nanahira's avatar nanahira

rework

parent 53fc7f5f
Pipeline #6835 passed with stages
in 1 minute and 5 seconds
# compiled output
/dist
/node_modules
# Logs
logs
*.log
......@@ -6,109 +10,33 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
/build
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
/data
/output
/config.yaml
.git*
.dockerignore
Dockerfile
.gitlab-ci.yml
/config.yaml
.idea
.dockerignore
webpack.config.js
dist/*
build/*
*.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
# compiled output
/dist
/node_modules
# Logs
logs
*.log
......@@ -6,104 +10,29 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
/build
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
/data
/output
/config.yaml
.idea
stages:
- build
- combine
- deploy
variables:
GIT_DEPTH: "1"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
CONTAINER_TEST_ARM_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-arm
CONTAINER_TEST_X86_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-x86
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build-x86:
stage: build
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_X86_IMAGE
- docker build --pull -t $TARGET_IMAGE .
- docker push $TARGET_IMAGE
build-arm:
stage: build
tags:
- docker-arm
script:
- TARGET_IMAGE=$CONTAINER_TEST_ARM_IMAGE
- docker build --pull -t $TARGET_IMAGE .
- docker push $TARGET_IMAGE
combine:
stage: combine
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE
- SOURCE_IMAGE_2=$CONTAINER_TEST_ARM_IMAGE
- SOURCE_IMAGE_1=$CONTAINER_TEST_X86_IMAGE
- docker pull $SOURCE_IMAGE_1
- docker pull $SOURCE_IMAGE_2
- docker manifest create $TARGET_IMAGE --amend $SOURCE_IMAGE_1 --amend
$SOURCE_IMAGE_2
- docker manifest push $TARGET_IMAGE
deploy_latest:
stage: deploy
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_RELEASE_IMAGE
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
only:
- master
deploy_tag:
stage: deploy
tags:
- docker
script:
- TARGET_IMAGE=$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
only:
- tags
......@@ -4,40 +4,27 @@ stages:
variables:
GIT_DEPTH: "1"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
tags:
- docker
tags:
- linux
script:
- docker build --pull -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
- npm ci
- npm run build
artifacts:
paths:
- dist/
deploy_latest:
deploy_npm:
stage: deploy
tags:
- docker
dependencies:
- build
tags:
- linux
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
- apt update;apt -y install coreutils
- echo $NPMRC | base64 --decode > ~/.npmrc
- npm publish . || true
only:
- master
deploy_tag:
stage: deploy
tags:
- docker
variables:
CONTAINER_TAG_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_TAG_IMAGE
- docker push $CONTAINER_TAG_IMAGE
only:
- tags
/install-npm.sh
.git*
/data
/output
/config.yaml
.idea
.dockerignore
Dockerfile
{
"singleQuote": true,
"trailingComma": "all"
}
\ No newline at end of file
FROM node:buster-slim
FROM node:bullseye-slim
LABEL Author="Nanahira <nanahira@momobako.com>"
RUN apt update && apt -y install python3 build-essential && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /usr/src/app
COPY ./package*.json ./
RUN npm ci
RUN npm ci && npm cache clean --force
COPY . ./
RUN npm run build
......
This diff is collapsed.
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = __importDefault(require("axios"));
const config_1 = require("./src/config");
const querystring_1 = __importDefault(require("querystring"));
const underscore_1 = __importDefault(require("underscore"));
let config;
async function createTournament(oldTournamentData) {
const oldData = underscore_1.default.clone(oldTournamentData);
delete oldData.url;
oldData.name = config.targetTournamentName;
const { data } = await axios_1.default.post(" https://api.challonge.com/v1/tournaments.json", {
api_key: config.apiKey,
tournament: oldData,
}, {
validateStatus: function (status) {
return true;
},
...config_1.axiosPostConfig
});
console.log(data);
config.targetTournament = data.url;
await (0, config_1.writeConfig)(config);
return config.targetTournament;
}
async function main() {
config = await (0, config_1.loadConfig)();
try {
console.log(`Reading tournament ${config.sourceTournament}`);
const { data: { tournament } } = await axios_1.default.get(` https://api.challonge.com/v1/tournaments/${config.sourceTournament}.json`, {
responseType: "json",
paramsSerializer: querystring_1.default.stringify,
params: {
api_key: config.apiKey,
include_participants: 1
},
});
if (!config.targetTournament) {
console.log(`Target tournament does not exist. Creating one.`);
const newTournamentUrl = await createTournament(tournament);
console.log(`Tournament ${newTournamentUrl} created.`);
}
const oldParticipantDatas = tournament.participants;
const oldParticipants = oldParticipantDatas.map(oldp => oldp.participant);
console.log(`Creating participants.`);
await axios_1.default.post(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/participants/bulk_add.json`, {
api_key: config.apiKey,
participants: oldParticipants.map(p => ({ name: p.name, seed: p.seed })),
}, config_1.axiosPostConfig);
console.log(`Starting tournament.`);
await axios_1.default.post(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/start.json`, {
api_key: config.apiKey
}, config_1.axiosPostConfig);
console.log(`Finished.`);
}
catch (e) {
console.error(`Request failed: ${e.toString()}`);
}
}
main();
//# sourceMappingURL=create.js.map
\ No newline at end of file
{"version":3,"file":"create.js","sourceRoot":"","sources":["../create.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_1 = require("./src/config");
const axios_1 = __importDefault(require("axios"));
const querystring_1 = __importDefault(require("querystring"));
let config;
let oldMatches;
let oldParticipantNameMap = new Map();
let oldParticipantIdMap = new Map();
let newMatches;
let newParticipantNameMap = new Map();
let newParticipantIdMap = new Map();
async function getTournamentData(tournamentUrl) {
const { data: { tournament } } = await axios_1.default.get(` https://api.challonge.com/v1/tournaments/${tournamentUrl}.json`, {
responseType: "json",
paramsSerializer: querystring_1.default.stringify,
params: {
api_key: config.apiKey,
include_participants: 1,
include_matches: 1
},
});
const participants = tournament.participants.map(pd => pd.participant);
const matches = tournament.matches.map(pd => pd.match);
return { participants, matches };
}
async function loadOldTournamentData() {
const { participants, matches } = await getTournamentData(config.sourceTournament);
oldParticipantNameMap.clear();
oldParticipantIdMap.clear();
for (let participant of participants) {
//console.log(`Inserting old participant ${participant.id} ${participant.name}`);
oldParticipantNameMap.set(participant.name, participant);
oldParticipantIdMap.set(participant.id, participant);
}
oldMatches = matches;
}
async function loadNewTournamentData() {
const { participants, matches } = await getTournamentData(config.targetTournament);
newParticipantIdMap.clear();
newParticipantNameMap.clear();
for (let participant of participants) {
//console.log(`Inserting new participant ${participant.id} ${participant.name}`);
newParticipantNameMap.set(participant.name, participant);
newParticipantIdMap.set(participant.id, participant);
}
newMatches = matches;
}
async function checkQuit(round, oldPlayerId) {
const oldPlayer = oldParticipantIdMap.get(oldPlayerId);
if (oldPlayer.active) {
return;
}
const nextRoundMatch = oldMatches.find(m => m.round === round + 1 && (m.player1_id === oldPlayerId || m.player2_id === oldPlayerId));
if (!nextRoundMatch) {
const newPlayerId = newParticipantNameMap.get(oldPlayer.name).id;
console.log(`Player ${oldPlayer.name}: ${oldPlayerId}/${newPlayerId} quitted in round ${round}.`);
while (true) {
try {
await axios_1.default.delete(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/participants/${newPlayerId}.json?api_key=${encodeURIComponent(config.apiKey)}`, {
responseType: 'json'
});
console.log(`Successfully quitted player ${oldPlayer.name} in round ${round}.`);
break;
}
catch (e) {
console.log(`Failed quitting player ${oldPlayer.name} in round ${round}: ${e.toString()}`);
}
}
}
}
async function migrateMatch(match) {
const currentMatchPlayer1Name = newParticipantIdMap.get(match.player1_id).name;
const currentMatchPlayer2Name = newParticipantIdMap.get(match.player2_id).name;
const oldMatch = oldMatches.find(m => {
if (m.round !== match.round) {
return false;
}
const oldMatchPlayer1Name = oldParticipantIdMap.get(m.player1_id).name;
const oldMatchPlayer2Name = oldParticipantIdMap.get(m.player2_id).name;
return currentMatchPlayer1Name === oldMatchPlayer1Name && oldMatchPlayer2Name === currentMatchPlayer2Name;
});
if (!oldMatch) {
console.error(`Match for ${currentMatchPlayer1Name} vs ${currentMatchPlayer2Name} not found.`);
return;
}
let winner_id;
if (typeof (oldMatch.winner_id) === "number" && oldParticipantIdMap.has(oldMatch.winner_id)) {
const winnerName = oldParticipantIdMap.get(oldMatch.winner_id).name;
winner_id = newParticipantNameMap.get(winnerName).id;
console.log(`Migrating match ${currentMatchPlayer1Name} vs ${currentMatchPlayer2Name} with winner ${winnerName}.`);
}
else {
winner_id = oldMatch.winner_id;
if (oldMatch.scores_csv === "0-0") {
winner_id = 'tie';
}
console.log(`Migrating match ${currentMatchPlayer1Name} vs ${currentMatchPlayer2Name} with result ${winner_id}.`);
}
const oldPlayerIds = [oldMatch.player1_id, oldMatch.player2_id];
await Promise.all(oldPlayerIds.map(pid => checkQuit(match.round, pid)));
while (true) {
try {
await axios_1.default.put(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/matches/${match.id}.json`, {
api_key: config.apiKey,
match: {
scores_csv: oldMatch.scores_csv,
winner_id
}
}, config_1.axiosPostConfig);
console.log(`Successfully migrated match ${currentMatchPlayer1Name} vs ${currentMatchPlayer2Name}.`);
break;
}
catch (e) {
console.error(`Failed migrating match ${currentMatchPlayer1Name} vs ${currentMatchPlayer2Name}: ${e.toString()}`);
}
}
}
async function main() {
config = await (0, config_1.loadConfig)();
console.log(`Reading old tournament ${config.sourceTournament}.`);
await loadOldTournamentData();
for (let round = 1; round <= config.maxRounds; ++round) {
console.log(`Handling round ${round}.`);
await loadNewTournamentData();
const matches = newMatches.filter(m => m.round === round && m.state === "open");
if (!matches.length) {
console.log(`No available matches in round ${round}.`);
continue;
}
await Promise.all(matches.map(match => migrateMatch(match)));
}
console.log(`Finished.`);
}
main();
//# sourceMappingURL=migrate.js.map
\ No newline at end of file
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../migrate.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeConfig = exports.loadConfig = exports.axiosPostConfig = void 0;
const yaml_1 = __importDefault(require("yaml"));
const fs_1 = __importDefault(require("fs"));
exports.axiosPostConfig = {
responseType: "json",
headers: {
"Content-Type": "application/json;charset=utf-8"
}
};
async function loadConfig() {
return yaml_1.default.parse(await fs_1.default.promises.readFile("./config.yaml", "utf-8"));
}
exports.loadConfig = loadConfig;
async function writeConfig(config) {
await fs_1.default.promises.writeFile("./config.yaml", yaml_1.default.stringify(config));
}
exports.writeConfig = writeConfig;
//# sourceMappingURL=config.js.map
\ No newline at end of file
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,4CAAoB;AAoCP,QAAA,eAAe,GAAuB;IAC/C,YAAY,EAAE,MAAM;IACpB,OAAO,EAAE;QACL,cAAc,EAAE,gCAAgC;KACnD;CACJ,CAAC;AAEK,KAAK,UAAU,UAAU;IAC5B,OAAO,cAAI,CAAC,KAAK,CAAC,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAA;AAC3E,CAAC;AAFD,gCAEC;AAEM,KAAK,UAAU,WAAW,CAAC,MAAc;IAC5C,MAAM,YAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,cAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AACzE,CAAC;AAFD,kCAEC"}
\ No newline at end of file
import axios, {AxiosRequestConfig} from "axios";
import {Config, loadConfig, ParticipantData, writeConfig, axiosPostConfig} from "./src/config";
import qs from "querystring";
import _ from "underscore";
import axios, { AxiosRequestConfig } from 'axios';
import {
Config,
loadConfig,
ParticipantData,
writeConfig,
axiosPostConfig,
} from './src/config';
import qs from 'querystring';
import _ from 'lodash';
let config: Config;
async function createTournament(oldTournamentData: any) {
const oldData = _.clone(oldTournamentData);
delete oldData.url;
oldData.name = config.targetTournamentName;
const {data} = await axios.post(" https://api.challonge.com/v1/tournaments.json", {
api_key: config.apiKey,
tournament: oldData,
}, {
validateStatus: function (status) {
return true;
},
...axiosPostConfig
});
console.log(data);
config.targetTournament = data.url;
await writeConfig(config);
return config.targetTournament;
const oldData = _.clone(oldTournamentData);
delete oldData.url;
oldData.name = config.targetTournamentName;
const { data } = await axios.post(
' https://api.challonge.com/v1/tournaments.json',
{
api_key: config.apiKey,
tournament: oldData,
},
{
validateStatus: function (status) {
return true;
},
...axiosPostConfig,
},
);
console.log(data);
config.targetTournament = data.url;
await writeConfig(config);
return config.targetTournament;
}
async function main() {
config = await loadConfig();
config = await loadConfig();
try {
console.log(`Reading tournament ${config.sourceTournament}`);
const {data: {tournament}} = await axios.get(` https://api.challonge.com/v1/tournaments/${config.sourceTournament}.json`, {
responseType: "json",
const {
data: { tournament },
} = await axios.get(
` https://api.challonge.com/v1/tournaments/${config.sourceTournament}.json`,
{
responseType: 'json',
paramsSerializer: qs.stringify,
params: {
api_key: config.apiKey,
include_participants: 1
api_key: config.apiKey,
include_participants: 1,
},
});
if(!config.targetTournament) {
console.log(`Target tournament does not exist. Creating one.`);
const newTournamentUrl = await createTournament(tournament);
console.log(`Tournament ${newTournamentUrl} created.`);
},
);
if (!config.targetTournament) {
console.log(`Target tournament does not exist. Creating one.`);
const newTournamentUrl = await createTournament(tournament);
console.log(`Tournament ${newTournamentUrl} created.`);
}
const oldParticipantDatas = tournament.participants as ParticipantData[];
const oldParticipants = oldParticipantDatas.map(oldp => oldp.participant);
const oldParticipants = oldParticipantDatas.map((oldp) => oldp.participant);
const participants = oldParticipants.map((p) => ({
name: p.name,
seed: p.seed,
}));
console.log(`Creating participants.`);
await axios.post(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/participants/bulk_add.json`, {
for (const chunk of _.chunk(participants, config.addParticipantChunk || 10)) {
await axios.post(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/participants/bulk_add.json`, {
api_key: config.apiKey,
participants: oldParticipants.map(p => ({name: p.name, seed: p.seed})),
participants: chunk,
}, axiosPostConfig);
}
console.log(`Starting tournament.`);
await axios.post(`https://api.challonge.com/v1/tournaments/${config.targetTournament}/start.json`, {
api_key: config.apiKey
}, axiosPostConfig);
await axios.post(
`https://api.challonge.com/v1/tournaments/${config.targetTournament}/start.json`,
{
api_key: config.apiKey,
},
axiosPostConfig,
);
console.log(`Finished.`);
} catch (e) {
console.error(`Request failed: ${e.toString()}`);
}
}
main();
#!/bin/bash
npm install --save-dev \
@types/node \
typescript \
'@typescript-eslint/eslint-plugin@^4.28.2' \
'@typescript-eslint/parser@^4.28.2 '\
'eslint@^7.30.0' \
'eslint-config-prettier@^8.3.0' \
'eslint-plugin-prettier@^3.4.0' \
prettier
This diff is collapsed.
This diff is collapsed.
......@@ -5,8 +5,8 @@
"main": "build/create.ts",
"scripts": {
"build": "tsc",
"create": "node build/create.ts",
"migrate": "node build/mirate.ts"
"create": "node dist/create.js",
"migrate": "node dist/migrate.js"
},
"repository": {
"type": "git",
......@@ -15,14 +15,21 @@
"author": "Nanahira",
"license": "ISC",
"dependencies": {
"@types/node": "^14.14.10",
"@types/qs": "^6.9.5",
"@types/underscore": "^1.10.24",
"axios": "^0.21.0",
"moment": "^2.29.1",
"qs": "^6.9.4",
"typescript": "^4.1.2",
"underscore": "^1.12.0",
"yaml": "^1.10.0"
},
"devDependencies": {
"@types/node": "^16.11.7",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.1",
"lodash": "^4.17.21",
"prettier": "^2.4.1",
"typescript": "^4.4.4"
}
}
import yaml from "yaml";
import fs from "fs";
import {AxiosRequestConfig} from "axios";
import yaml from 'yaml';
import fs from 'fs';
import { AxiosRequestConfig } from 'axios';
export interface Config {
apiKey: string;
sourceTournament: string;
targetTournament: string;
targetTournamentName: string;
maxRounds: number;
apiKey: string;
sourceTournament: string;
targetTournament: string;
targetTournamentName: string;
maxRounds: number;
addParticipantChunk: number;
}
export interface Participant {
id: number;
name: string;
seed: number;
active: boolean;
id: number;
name: string;
seed: number;
active: boolean;
}
export interface ParticipantData {
participant: Participant;
participant: Participant;
}
export interface Match {
id: number;
player1_id: number;
player2_id: number;
scores_csv: string;
winner_id: string | number;
state: string;
round: number;
id: number;
player1_id: number;
player2_id: number;
scores_csv: string;
winner_id: string | number;
state: string;
round: number;
}
export interface MatchData {
match: Match;
match: Match;
}
export const axiosPostConfig: AxiosRequestConfig = {
responseType: "json",
headers: {
"Content-Type": "application/json;charset=utf-8"
}
responseType: 'json',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
};
export async function loadConfig(): Promise<Config> {
return yaml.parse(await fs.promises.readFile("./config.yaml", "utf-8"))
return yaml.parse(await fs.promises.readFile('./config.yaml', 'utf-8'));
}
export async function writeConfig(config: Config) {
await fs.promises.writeFile("./config.yaml", yaml.stringify(config));
await fs.promises.writeFile('./config.yaml', yaml.stringify(config));
}
{
"compilerOptions": {
"outDir": "build",
"outDir": "dist",
"module": "commonjs",
"target": "esnext",
"target": "es2021",
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"declaration": true,
"sourceMap": true
},
"compileOnSave": true,
"allowJs": true,
"include": [
"*.ts",
"src/*.ts"
"src/**/*.ts",
"test/**/*.ts"
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment