Commit e092fe7e authored by nanahira's avatar nanahira

koishijs

parent f50fecde
Pipeline #3088 passed with stages
in 1 minute and 35 seconds
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppLogger } from './app.logger';
import { TypeOrmModule } from '@nestjs/typeorm';
import { typeormConfig } from './config';
import { BotService } from './bot/bot.service';
import { BotLogger } from './bot/bot.logger';
import { BotController } from './bot/bot.controller';
@Module({
imports: [TypeOrmModule.forRoot(typeormConfig())],
controllers: [AppController, BotController],
providers: [AppService, AppLogger, BotService, BotLogger],
})
export class AppModule {}
#!/bin/bash
npm install --save \
lodash \
typeorm \
@nestjs/typeorm \
mysql \
reflect-metadata \
koishi \
koishi-adapter-onebot \
koishi-plugin-common
npm install --save-dev \
@types/lodash
import { Test, TestingModule } from '@nestjs/testing';
import { BotController } from './bot.controller';
describe('BotController', () => {
let controller: BotController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [BotController],
}).compile();
controller = module.get<BotController>(BotController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
import { Controller } from '@nestjs/common';
import { AppService } from '../app.service';
import { BotService } from './bot.service';
import { App } from 'koishi';
import * as koishiCommonPlugin from 'koishi-plugin-common';
import * as adapter from 'koishi-adapter-onebot';
const __ = typeof adapter; // just for import
@Controller('_bot')
export class BotController {
bot: App;
constructor(
private readonly appService: AppService,
private readonly botService: BotService,
) {
this.initializeBot();
}
async initializeBot() {
this.bot = new App({
type: 'onebot:ws',
selfId: process.env.CQ_ID,
server: process.env.CQ_SERVER,
token: process.env.CQ_TOKEN,
prefix: process.env.CQ_PREFIX || '.',
});
this.bot.plugin(koishiCommonPlugin);
this.loadBotRouters();
await this.bot.start();
this.botService.log.log(`Bot started.`);
}
loadBotRouters() {
// all middlewares should be here.
}
}
import { Injectable, Scope, Logger } from '@nestjs/common';
@Injectable()
export class BotLogger extends Logger {}
import { Test, TestingModule } from '@nestjs/testing';
import { BotService } from './bot.service';
describe('BotService', () => {
let service: BotService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [BotService],
}).compile();
service = module.get<BotService>(BotService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/typeorm';
import { Connection } from 'typeorm';
import { BotLogger } from './bot.logger';
import { User } from '../entities/User';
import { Group } from '../entities/Group';
@Injectable()
export class BotService {
constructor(
@InjectConnection('app')
private db: Connection,
public log: BotLogger,
) {
this.log.setContext('bot');
}
async findOrCreateUser(id: string, name?: string) {
const repo = this.db.getRepository(User);
let ent = await repo.findOne({ where: { id } });
if (ent) {
return ent;
}
ent = new User();
ent.id = id;
ent.name = name;
try {
ent = await repo.save(ent);
} catch (e) {
this.log.error(`Failed to save user ${id}: ${e.toString()}`);
return null;
}
return ent;
}
async findOrCreateGroup(id: string, name?: string) {
const repo = this.db.getRepository(Group);
let ent = await repo.findOne({ where: { id } });
if (ent) {
return ent;
}
ent = new Group();
ent.id = id;
ent.name = name;
try {
ent = await repo.save(ent);
} catch (e) {
this.log.error(`Failed to save group ${id}: ${e.toString()}`);
return null;
}
return ent;
}
}
import { QQIDBase } from './QQIDBase';
import { Entity } from 'typeorm';
@Entity()
export class Group extends QQIDBase {}
import { TimeBase } from './TimeBase';
import { Column, Index, PrimaryColumn } from 'typeorm';
export class QQIDBase extends TimeBase {
@PrimaryColumn('varchar', { length: 12 })
id: string;
@Index()
@Column('varchar', { length: 32, nullable: true })
name: string;
}
import { QQIDBase } from './QQIDBase';
import { Entity } from 'typeorm';
@Entity()
export class User extends QQIDBase {}
#!/bin/bash
npm install --save \
lodash \
typeorm \
@nestjs/typeorm \
mysql \
reflect-metadata
npm install --save-dev \
@types/lodash
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppLogger } from './app.logger';
import { TypeOrmModule } from '@nestjs/typeorm';
import { typeormConfig } from './config';
@Module({
imports: [TypeOrmModule.forRoot(typeormConfig())],
controllers: [AppController],
providers: [AppService, AppLogger],
})
export class AppModule {}
import { Injectable } from '@nestjs/common';
import { AppLogger } from './app.logger';
import { Connection } from 'typeorm';
import { InjectConnection } from '@nestjs/typeorm';
@Injectable()
export class AppService {
constructor(
@InjectConnection('app')
private db: Connection,
private log: AppLogger,
) {
this.log.setContext('app');
}
getHello(): string {
return 'Hello World!';
}
}
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { User } from './entities/User';
export function dbConfig() {
return {
host: process.env.DB_HOST,
port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
};
}
export function typeormConfig(): TypeOrmModuleOptions {
return {
name: 'app',
type: 'mysql',
entities: [User], // entities here
synchronize: true,
...dbConfig(),
};
}
import { CreateDateColumn, UpdateDateColumn } from 'typeorm';
export class TimeBase {
@CreateDateColumn({ select: false })
createTime: Date;
@UpdateDateColumn({ select: false })
updateTime: Date;
toObject() {
return JSON.parse(JSON.stringify(this));
}
}
# 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
# 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
FROM node:buster-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
COPY . ./
RUN npm run build
CMD ["npm", "run", "start:prod"]
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 { 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 { Injectable, Scope, Logger } from '@nestjs/common';
@Injectable()
export class AppLogger extends Logger {}
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
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"
}
}
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"esModuleInterop": true
},
"compileOnSave": true,
"allowJs": true
}
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:
- docker build --pull -t $CONTAINER_TEST_X86_IMAGE .
- docker push $CONTAINER_TEST_X86_IMAGE
build-arm:
stage: build
tags:
- docker-arm
script:
- docker build --pull -t $CONTAINER_TEST_ARM_IMAGE .
- docker push $CONTAINER_TEST_ARM_IMAGE
combine:
stage: combine
tags:
- docker
script:
- docker pull $CONTAINER_TEST_X86_IMAGE
- docker pull $CONTAINER_TEST_ARM_IMAGE
- docker manifest create $CONTAINER_TEST_IMAGE --amend $CONTAINER_TEST_X86_IMAGE --amend $CONTAINER_TEST_ARM_IMAGE
- docker manifest 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
This diff is collapsed.
#!/bin/bash
npm install --save \
lodash
npm install --save-dev \
@types/node \
@types/lodash \
typescript
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