Skip to content

Commit

Permalink
Merge pull request #81 from line/beta
Browse files Browse the repository at this point in the history
release: 3.2346.17
  • Loading branch information
h4l-yup authored Nov 16, 2023
2 parents ad655d1 + af917d1 commit ab90334
Show file tree
Hide file tree
Showing 87 changed files with 1,766 additions and 676 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test-on-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
run: |
echo "JWT_SECRET=${{ vars.TEST_JWT_SECRET }}" >> ./apps/api/.env.test
echo "OS_USE=${{ vars.TEST_OS_USE }}" >> ./apps/api/.env.test
echo "OS_NODE=http://localhost:9200" >> ./apps/api/.env.test
echo "OS_USERNAME=''" >> ./apps/api/.env.test
echo "OS_PASSWORD=''" >> ./apps/api/.env.test
- name: Run Tests
run: yarn test
16 changes: 8 additions & 8 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@nestjs/passport": "^10.0.2",
"@nestjs/platform-express": "^10.2.7",
"@nestjs/platform-fastify": "^10.2.7",
"@nestjs/swagger": "^7.1.13",
"@nestjs/swagger": "^7.1.14",
"@nestjs/terminus": "^10.1.1",
"@nestjs/typeorm": "^10.0.0",
"@opensearch-project/opensearch": "^2.4.0",
Expand All @@ -47,11 +47,12 @@
"dayjs": "^1.11.10",
"exceljs": "^4.4.0",
"fast-csv": "^4.3.6",
"joi": "^17.11.0",
"mysql2": "^3.6.2",
"nestjs-cls": "^3.6.0",
"nestjs-pino": "^3.5.0",
"nestjs-typeorm-paginate": "^4.0.4",
"nodemailer": "^6.9.6",
"nodemailer": "^6.9.7",
"passport": "^0.6.0",
"passport-custom": "^1.1.1",
"passport-jwt": "^4.0.1",
Expand All @@ -64,26 +65,25 @@
"source-map-support": "^0.5.21",
"typeorm": "^0.3.17",
"typeorm-naming-strategies": "^4.1.0",
"typeorm-transactional": "^0.4.1",
"yup": "0.32.11"
"typeorm-transactional": "^0.4.1"
},
"devDependencies": {
"@faker-js/faker": "^8.2.0",
"@nestjs/cli": "^10.1.18",
"@nestjs/cli": "^10.2.0",
"@nestjs/schematics": "^10.0.2",
"@nestjs/testing": "^10.2.7",
"@swc-node/jest": "^1.6.8",
"@swc/core": "^1.3.93",
"@swc/core": "^1.3.95",
"@types/bcrypt": "^5.0.1",
"@types/express": "^4.17.20",
"@types/jest": "^29.5.6",
"@types/node": "20.8.7",
"@types/node": "20.8.8",
"@types/nodemailer": "^6.4.13",
"@types/supertest": "^2.0.15",
"@ufb/eslint-config": "^0.1.0",
"@ufb/prettier-config": "^0.1.0",
"@ufb/tsconfig": "^0.1.0",
"eslint": "^8.51.0",
"eslint": "^8.52.0",
"jest": "^29.7.0",
"mockdate": "^3.0.5",
"supertest": "^6.3.3",
Expand Down
14 changes: 6 additions & 8 deletions apps/api/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
import { mysqlConfig, mysqlConfigSchema } from './configs/mysql.config';
import {
opensearchConfig,
opensearchSchema,
opensearchConfigSchema,
} from './configs/opensearch.config';
import { smtpConfig, smtpConfigSchema } from './configs/smtp.config';
import { AuthModule } from './domains/auth/auth.module';
Expand Down Expand Up @@ -77,13 +77,11 @@ const domainModules = [
ConfigModule.forRoot({
isGlobal: true,
load: [appConfig, opensearchConfig, smtpConfig, jwtConfig, mysqlConfig],
validate: (config) => ({
...appConfigSchema.validateSync(config),
...opensearchSchema.validateSync(config),
...smtpConfigSchema.validateSync(config),
...jwtConfigSchema.validateSync(config),
...mysqlConfigSchema.validateSync(config),
}),
validationSchema: appConfigSchema
.concat(jwtConfigSchema)
.concat(mysqlConfigSchema)
.concat(smtpConfigSchema)
.concat(opensearchConfigSchema),
validationOptions: { abortEarly: true },
}),
LoggerModule.forRoot({
Expand Down
8 changes: 4 additions & 4 deletions apps/api/src/configs/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/

import { registerAs } from '@nestjs/config';
import * as yup from 'yup';
import Joi from 'joi';

export const appConfigSchema = yup.object({
APP_PORT: yup.number().default(4000),
APP_ADDRESS: yup.string().default('0.0.0.0'),
export const appConfigSchema = Joi.object({
APP_PORT: Joi.number().default(4000),
APP_ADDRESS: Joi.string().default('0.0.0.0'),
});

export const appConfig = registerAs('app', () => ({
Expand Down
10 changes: 5 additions & 5 deletions apps/api/src/configs/jwt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* under the License.
*/
import { registerAs } from '@nestjs/config';
import * as yup from 'yup';
import Joi from 'joi';

export const jwtConfigSchema = yup.object({
JWT_SECRET: yup.string().required(),
ACCESS_TOKEN_EXPIRED_TIME: yup.string().default('10m'),
REFESH_TOKEN_EXPIRED_TIME: yup.string().default('1h'),
export const jwtConfigSchema = Joi.object({
JWT_SECRET: Joi.string().required(),
ACCESS_TOKEN_EXPIRED_TIME: Joi.string().default('10m'),
REFESH_TOKEN_EXPIRED_TIME: Joi.string().default('1h'),
});

export const jwtConfig = registerAs('jwt', () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ConfigService } from '@nestjs/config';

import type { ConfigServiceType } from '@/types/config-service.type';

@Module({
imports: [
MailerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService<ConfigServiceType>) => {
const { host, password, port, username, sender } = configService.get(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,24 @@
* under the License.
*/
import { Global, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ConfigService } from '@nestjs/config';
import { Client } from '@opensearch-project/opensearch';
import * as dotenv from 'dotenv';

import type { ConfigServiceType } from '@/types/config-service.type';

dotenv.config();

@Global()
@Module({
imports: [ConfigModule],
providers: [
{
provide: 'OPENSEARCH_CLIENT',
useFactory: (configService: ConfigService<ConfigServiceType>): Client => {
const { node, password, username } = configService.get('opensearch', {
infer: true,
});
return process.env.OS_USE === 'true'
const { use, node, password, username } = configService.get(
'opensearch',
{
infer: true,
},
);
return use
? new Client({ node, auth: { username, password } })
: undefined;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@
* under the License.
*/
import { ConfigService } from '@nestjs/config';
import * as dotenv from 'dotenv';
import type { DataSourceOptions } from 'typeorm';
import { DataSource } from 'typeorm';

import { mysqlConfig, mysqlConfigSchema } from '@/configs/mysql.config';
import { mysqlConfig } from '@/configs/mysql.config';
import { TypeOrmConfigService } from './typeorm-config.service';

dotenv.config();
process.env = mysqlConfigSchema.validateSync(process.env) as any;

const env = mysqlConfig();
console.log('env: ', env);
const configService = new ConfigService({ mysql: env });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,22 @@ import type {
TypeOrmModuleOptions,
TypeOrmOptionsFactory,
} from '@nestjs/typeorm';
import * as dotenv from 'dotenv';
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';

import type { ConfigServiceType } from '@/types/config-service.type';

dotenv.config();
@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
constructor(
private readonly configService: ConfigService<ConfigServiceType>,
) {}
createTypeOrmOptions(): TypeOrmModuleOptions {
const { main_url, sub_urls } = this.configService.get('mysql', {
infer: true,
});
const { main_url, sub_urls, auto_migration } = this.configService.get(
'mysql',
{
infer: true,
},
);

return {
type: 'mysql',
Expand All @@ -46,7 +47,7 @@ export class TypeOrmConfigService implements TypeOrmOptionsFactory {
migrations: [join(__dirname, 'migrations/*.{ts,js}')],
migrationsTableName: 'migrations',
logging: ['warn', 'error'],
migrationsRun: process.env.AUTO_MIGRATION === 'true',
migrationsRun: auto_migration,
namingStrategy: new SnakeNamingStrategy(),
timezone: '+00:00',
};
Expand Down
30 changes: 17 additions & 13 deletions apps/api/src/configs/mysql.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,26 @@
* under the License.
*/
import { registerAs } from '@nestjs/config';
import * as yup from 'yup';
import Joi from 'joi';

export const mysqlConfigSchema = yup.object({
MYSQL_PRIMARY_URL: yup.string().required(),
MYSQL_SECONDARY_URLS: yup.array().required(),
export const mysqlConfigSchema = Joi.object({
MYSQL_PRIMARY_URL: Joi.string().required(),
MYSQL_SECONDARY_URLS: Joi.string()
.custom((value, helpers) => {
const urls = JSON.parse(value);
for (const url of urls) {
if (!url.startsWith('mysql://')) {
return helpers.error('any.invalid');
}
}
return value;
}, 'custom validation')
.required(),
AUTO_MIGRATION: Joi.boolean().default(false),
});

export const mysqlConfig = registerAs('mysql', () => ({
main_url: process.env.MYSQL_PRIMARY_URL,
sub_urls: toArray(process.env.MYSQL_SECONDARY_URLS),
sub_urls: JSON.parse(process.env.MYSQL_SECONDARY_URLS),
auto_migration: process.env.AUTO_MIGRATION === 'true',
}));

const toArray = (input: string) => {
try {
return JSON.parse(input);
} catch (error) {
return [];
}
};
28 changes: 19 additions & 9 deletions apps/api/src/configs/opensearch.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,30 @@
* under the License.
*/
import { registerAs } from '@nestjs/config';
import * as dotenv from 'dotenv';
import * as yup from 'yup';
import Joi from 'joi';

export const opensearchSchema = yup.object({
OS_NODE: yup.string().default('http://localhost:9200'),
OS_USERNAME: yup.string().default(''),
OS_PASSWORD: yup.string().default(''),
export const opensearchConfigSchema = Joi.object({
OS_USE: Joi.boolean().default(false),
OS_NODE: Joi.string().when('OS_USE', {
is: true,
then: Joi.required(),
otherwise: Joi.optional(),
}),
OS_USERNAME: Joi.string().allow('').when('OS_USE', {
is: true,
then: Joi.required(),
otherwise: Joi.optional(),
}),
OS_PASSWORD: Joi.string().allow('').when('OS_USE', {
is: true,
then: Joi.required(),
otherwise: Joi.optional(),
}),
});

export const opensearchConfig = registerAs('opensearch', () => ({
use: process.env.OS_USE === 'true',
node: process.env.OS_NODE,
username: process.env.OS_USERNAME,
password: process.env.OS_PASSWORD,
}));

dotenv.config();
export const OS_USE = process.env.OS_USE === 'true';
22 changes: 10 additions & 12 deletions apps/api/src/configs/smtp.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,20 @@
* under the License.
*/
import { registerAs } from '@nestjs/config';
import * as dotenv from 'dotenv';
import * as yup from 'yup';
import Joi from 'joi';

dotenv.config();
export const SMTP_USE = process.env.SMTP_USE === 'true';

export const smtpConfigSchema = yup.object({
SMTP_HOST: yup.string().default('localhost'),
SMTP_PORT: yup.number().default(25),
SMTP_USERNAME: yup.string().default(''),
SMTP_PASSWORD: yup.string().default(''),
SMTP_SENDER: yup.string().default('[email protected]'),
SMTP_BASE_URL: yup.string().default('http://localhost:3000'),
export const smtpConfigSchema = Joi.object({
SMTP_USE: Joi.boolean().default(false),
SMTP_HOST: Joi.string().default('localhost'),
SMTP_PORT: Joi.number().default(25),
SMTP_USERNAME: Joi.string().default(''),
SMTP_PASSWORD: Joi.string().default(''),
SMTP_SENDER: Joi.string().default('[email protected]'),
SMTP_BASE_URL: Joi.string().default('http://localhost:3000'),
});

export const smtpConfig = registerAs('smtp', () => ({
use: process.env.SMTP_USE === 'true',
host: process.env.SMTP_HOST,
port: +process.env.SMTP_PORT,
password: process.env.SMTP_USERNAME,
Expand Down
3 changes: 1 addition & 2 deletions apps/api/src/domains/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';

Expand Down Expand Up @@ -48,7 +48,6 @@ import { LocalStrategy } from './strategies/local.strategy';
}),
JwtModule.registerAsync({
global: true,
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService<ConfigServiceType>) => {
const { secret } = configService.get('jwt', { infer: true });
Expand Down
6 changes: 5 additions & 1 deletion apps/api/src/domains/channel/channel/channel.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import type { Repository } from 'typeorm';

import { createFieldDto } from '@/test-utils/fixtures';
import { MockOpensearchRepository } from '@/test-utils/util-functions';
import {
MockOpensearchRepository,
TestConfig,
} from '@/test-utils/util-functions';
import { ChannelServiceProviders } from '../../../test-utils/providers/channel.service.providers';
import { ChannelEntity } from '../../channel/channel/channel.entity';
import { ProjectEntity } from '../../project/project/project.entity';
Expand Down Expand Up @@ -49,6 +52,7 @@ describe('ChannelService', () => {

beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [TestConfig],
providers: ChannelServiceProviders,
}).compile();

Expand Down
Loading

0 comments on commit ab90334

Please sign in to comment.