Commit 93322b8d authored by nanahira's avatar nanahira

first

parents
Pipeline #1805 passed with stages
in 7 minutes and 31 seconds
# compiled output
/dist
/node_modules
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# 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*
Dockerfile
.dockerignore
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
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
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# 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
stages:
- build
- deploy
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
script:
- docker build --pull -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
deploy_latest:
stage: deploy
tags:
- docker
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
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
{
"singleQuote": true,
"trailingComma": "all"
}
\ No newline at end of file
FROM node:buster-slim
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
COPY . ./
RUN npm run build
CMD ["npm", "run", "start:prod"]
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
/* it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
}); */
});
});
checkPort: 7911
checkTimeout: 5000
checkInterval: 30000
enters:
- name: tiramisu-sha-1
address: tiramisu-sha-1.mycard.moe
location: sha
weight: 1
\ No newline at end of file
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}
This diff is collapsed.
{
"name": "ygopro-enter-checker",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^7.5.1",
"@nestjs/config": "^0.6.1",
"@nestjs/core": "^7.5.1",
"@nestjs/platform-express": "^7.5.1",
"@types/q": "^1.5.4",
"@types/underscore": "^1.10.24",
"q": "^1.5.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.6.3",
"underscore": "^1.12.0",
"yaml": "^1.10.0"
},
"devDependencies": {
"@nestjs/cli": "^7.5.1",
"@nestjs/schematics": "^7.1.3",
"@nestjs/testing": "^7.5.1",
"@types/express": "^4.17.8",
"@types/jest": "^26.0.15",
"@types/node": "^14.14.6",
"@types/supertest": "^2.0.10",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.6.3",
"prettier": "^2.1.2",
"supertest": "^6.0.0",
"ts-jest": "^26.4.3",
"ts-loader": "^8.0.8",
"ts-node": "^9.0.0",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.0.5"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
import { CheckConfig, EnterData } from './config';
import * as net from 'net';
import { AppLogger } from './app.logger';
import { promises as dns } from 'dns';
function check(host: string, port: number, timeout: number) {
return new Promise<number>((resolve, reject) => {
const hrstart = process.hrtime();
const socket = new net.Socket();
socket.connect(port, host);
socket.setTimeout(timeout || 1000);
socket.on('connect', () => {
socket.destroy();
resolve(milliseconds());
});
socket.on('error', (error) => {
socket.destroy();
reject(error);
});
socket.on('timeout', (error) => {
socket.destroy();
reject(error || 'socket TIMEOUT');
});
function milliseconds() {
const hrend = process.hrtime(hrstart);
const ms = hrend[0] * 1e3 + hrend[1] / 1e6;
return Math.floor(ms);
}
});
}
export class Enter implements EnterData {
name: string;
address: string;
ip: string;
location: string;
weight: number;
good: boolean;
delay: number;
constructor(data: EnterData) {
for (const propertyName of ['name', 'address', 'location', 'weight']) {
this[propertyName] = data[propertyName];
}
this.ip = null;
this.good = false;
this.delay = null;
}
async check(checkConfig: CheckConfig) {
try {
this.ip = (await dns.resolve4(this.address))[0];
this.delay = await check(
this.address,
checkConfig.checkPort,
checkConfig.checkTimeout,
);
this.good = true;
return null;
} catch (e) {
this.good = false;
return e.toString();
}
}
}
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
/* it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
}); */
});
});
import { Controller, Get, Query } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('one')
getOneEnter(
@Query('includeBad') includeBad: string,
@Query('location') location: string,
): any {
const enter = this.appService.getOneEnter(!!includeBad, location);
return { enter };
}
@Get('all')
getAllEnters(
@Query('includeBad') includeBad: string,
@Query('location') location: string,
): any {
const enters = this.appService.getAllEnters(!!includeBad, location);
return { enters };
}
}
import { Injectable, Scope, Logger } from '@nestjs/common';
@Injectable()
export class AppLogger extends Logger {}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppLogger } from './app.logger';
import { ConfigModule } from '@nestjs/config';
import config from './config';
@Module({
imports: [
ConfigModule.forRoot({
load: [config],
isGlobal: true,
}),
],
controllers: [AppController],
providers: [AppService, AppLogger],
})
export class AppModule {}
import { Injectable } from '@nestjs/common';
import { AppLogger } from './app.logger';
import { ConfigService } from '@nestjs/config';
import { CheckConfig } from './config';
import { Enter } from './Enter';
import { delay } from 'q';
@Injectable()
export class AppService {
private checkConfig: CheckConfig;
private enters: Enter[];
constructor(private log: AppLogger, private configService: ConfigService) {
this.log.setContext('Enter Checker');
this.checkConfig = {
checkInterval: configService.get('checkInterval'),
checkPort: configService.get('checkPort'),
checkTimeout: configService.get('checkTimeout'),
};
const enterDatas = configService.get('enters');
this.enters = enterDatas.map((enterData) => new Enter(enterData));
this.mainCheckLoop();
}
private async mainCheckLoop() {
while (true) {
await this.checkAllEnters();
await delay(
this.checkConfig.checkInterval - this.checkConfig.checkTimeout,
);
}
}
private async checkAllEnters() {
this.log.log(`Start checking ${this.enters.length} enters.`);
return await Promise.all(
this.enters.map((enter) => this.checkEnter(enter)),
);
}
private async checkEnter(enter: Enter) {
const checkErrorMessage = await enter.check(this.checkConfig);
if (checkErrorMessage) {
this.log.error(`Enter ${enter.name} is bad: ${checkErrorMessage}`);
} else {
this.log.log(`Enter ${enter.name} is good.`);
}
}
getAllEnters(includeBad: boolean, location: string) {
let enters = this.enters;
if (!includeBad) {
enters = enters.filter((enter) => enter.good);
}
if (location) {
enters = enters.filter((enter) => enter.location === location);
}
return enters;
}
getOneEnter(includeBad: boolean, location: string) {
const enters = this.getAllEnters(includeBad, location);
if (!enters.length) {
return null;
}
const enterRandomList: Enter[] = [];
for (const enter of enters) {
for (let i = 0; i < enter.weight; ++i) {
enterRandomList.push(enter);
}
}
return enterRandomList[Math.floor(Math.random() * enterRandomList.length)];
}
}
import * as yaml from 'yaml';
import * as fs from 'fs';
export interface EnterData {
name: string;
address: string;
location: string;
weight: number;
}
export interface CheckConfig {
checkPort: number;
checkTimeout: number;
checkInterval: number;
}
export interface Config extends CheckConfig {
enters: EnterData[];
}
export default function config(): Config {
return yaml.parse(fs.readFileSync('./config.yaml', 'utf-8'));
}
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
/* it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
}); */
});
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
},
"compileOnSave": true,
"allowJs": true
}
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