Skip to content

Commit e86f11f

Browse files
committed
feat: add validation package with DTOs
1 parent e5c7567 commit e86f11f

29 files changed

Lines changed: 552 additions & 0 deletions

packages/validation/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# database
2+
3+
To install dependencies:
4+
5+
```bash
6+
bun install
7+
```
8+
9+
To run:
10+
11+
```bash
12+
bun run index.ts
13+
```
14+
15+
This project was created using `bun init` in bun v1.2.12. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.

packages/validation/jest.config.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module.exports = {
2+
moduleFileExtensions: ['js', 'json', 'ts'],
3+
rootDir: '.',
4+
testRegex: '.*\\.spec\\.ts$',
5+
transform: {
6+
'^.+\\.(t|j)s$': [
7+
'ts-jest',
8+
{
9+
tsconfig: '<rootDir>/tsconfig.json',
10+
ignoreCodes: ['TS151001'],
11+
},
12+
],
13+
},
14+
collectCoverageFrom: ['**/*.(t|j)s'],
15+
coverageDirectory: './coverage',
16+
testEnvironment: 'node',
17+
moduleNameMapper: {
18+
'^@shared/(.*)$': '<rootDir>/../shared/$1',
19+
'^@server/(.*)$': '<rootDir>/src/$1',
20+
},
21+
testPathIgnorePatterns: [
22+
'<rootDir>/node_modules/',
23+
'<rootDir>/dist/',
24+
'<rootDir>/coverage/',
25+
],
26+
coveragePathIgnorePatterns: [
27+
'<rootDir>/node_modules/',
28+
'<rootDir>/coverage/',
29+
'<rootDir>/dist/',
30+
'.eslintrc.js',
31+
'jest.config.js',
32+
],
33+
};

packages/validation/package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "@nbw/validation",
3+
"main": "dist/index.js",
4+
"module": "dist/index.js",
5+
"types": "dist/index.d.ts",
6+
"type": "module",
7+
"private": true,
8+
"exports": {
9+
".": {
10+
"import": "./dist/index.js",
11+
"types": "./dist/index.d.ts"
12+
}
13+
},
14+
"scripts": {
15+
"build": "bun run clean && bun run build:js && bun run build:types",
16+
"build:js": "tsc --project tsconfig.build.json",
17+
"build:types": "tsc --project tsconfig.types.json",
18+
"clean": "rm -rf dist",
19+
"dev": "tsc --project tsconfig.build.json --watch",
20+
"lint": "eslint \"src/**/*.ts\" --fix",
21+
"test": "bun test **/*.spec.ts"
22+
},
23+
"devDependencies": {
24+
"@types/bun": "^1.3.4",
25+
"typescript": "^5.9.3"
26+
},
27+
"dependencies": {
28+
"mongoose": "^9.0.1",
29+
"zod": "^4.1.13",
30+
"zod-validation-error": "^5.0.0",
31+
"@nbw/config": "workspace:*"
32+
},
33+
"peerDependencies": {
34+
"typescript": "^5"
35+
}
36+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { z } from 'zod';
2+
3+
export function createPageDtoSchema<T extends z.ZodTypeAny>(itemSchema: T) {
4+
return z.object({
5+
total: z.number().int().min(0),
6+
page: z.number().int().min(1),
7+
limit: z.number().int().min(1),
8+
sort: z.string().optional(),
9+
order: z.boolean(),
10+
content: z.array(itemSchema),
11+
});
12+
}
13+
14+
export type PageDto<T> = {
15+
total: number;
16+
page: number;
17+
limit: number;
18+
sort?: string;
19+
order: boolean;
20+
content: T[];
21+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { z } from 'zod';
2+
3+
import { TIMESPANS } from '@nbw/config';
4+
5+
export const pageQueryDTOSchema = z.object({
6+
page: z.number().int().min(1).optional().default(1),
7+
limit: z.number().int().min(1).max(100).optional(),
8+
sort: z.string().optional().default('createdAt'),
9+
order: z
10+
.union([z.boolean(), z.string().transform((val) => val === 'true')])
11+
.optional()
12+
.default(false),
13+
timespan: z.enum(TIMESPANS as unknown as [string, ...string[]]).optional(),
14+
});
15+
16+
export type PageQueryDTO = z.infer<typeof pageQueryDTOSchema>;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { PageQueryDTO } from './PageQuery.dto';
2+
3+
export type PageQueryDTOType = PageQueryDTO;

packages/validation/src/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export * from './common/Page.dto';
2+
export * from './common/PageQuery.dto';
3+
export * from './common/types';
4+
5+
export * from './song/CustomInstrumentData.dto';
6+
export * from './song/FeaturedSongsDto.dto';
7+
export * from './song/SongListQuery.dto';
8+
export * from './song/SongPage.dto';
9+
export * from './song/SongPreview.dto';
10+
export * from './song/SongStats';
11+
export * from './song/SongView.dto';
12+
export * from './song/ThumbnailData.dto';
13+
export * from './song/UploadSongDto.dto';
14+
export * from './song/UploadSongResponseDto.dto';
15+
export * from './song/types';
16+
17+
export * from './user/CreateUser.dto';
18+
export * from './user/GetUser.dto';
19+
export * from './user/Login.dto copy';
20+
export * from './user/LoginWithEmail.dto';
21+
export * from './user/NewEmailUser.dto';
22+
export * from './user/SingleUsePass.dto';
23+
export * from './user/UpdateUsername.dto';
24+
export * from './user/user.dto';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { z } from 'zod';
2+
3+
export const customInstrumentDataSchema = z.object({
4+
sound: z.array(z.string()).min(1),
5+
});
6+
7+
export type CustomInstrumentData = z.infer<typeof customInstrumentDataSchema>;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { z } from 'zod';
2+
3+
import { songPreviewDtoSchema } from './SongPreview.dto';
4+
5+
export const featuredSongsDtoSchema = z.object({
6+
hour: z.array(songPreviewDtoSchema),
7+
day: z.array(songPreviewDtoSchema),
8+
week: z.array(songPreviewDtoSchema),
9+
month: z.array(songPreviewDtoSchema),
10+
year: z.array(songPreviewDtoSchema),
11+
all: z.array(songPreviewDtoSchema),
12+
});
13+
14+
export type FeaturedSongsDto = z.infer<typeof featuredSongsDtoSchema>;
15+
16+
export const createFeaturedSongsDto = (): FeaturedSongsDto => {
17+
return {
18+
hour: [],
19+
day: [],
20+
week: [],
21+
month: [],
22+
year: [],
23+
all: [],
24+
};
25+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { z } from 'zod';
2+
3+
export enum SongSortType {
4+
RECENT = 'recent',
5+
RANDOM = 'random',
6+
PLAY_COUNT = 'playCount',
7+
TITLE = 'title',
8+
DURATION = 'duration',
9+
NOTE_COUNT = 'noteCount',
10+
}
11+
12+
export enum SongOrderType {
13+
ASC = 'asc',
14+
DESC = 'desc',
15+
}
16+
17+
export const songListQueryDTOSchema = z.object({
18+
q: z.string().optional(),
19+
sort: z.nativeEnum(SongSortType).optional().default(SongSortType.RECENT),
20+
order: z.nativeEnum(SongOrderType).optional().default(SongOrderType.DESC),
21+
category: z.string().optional(),
22+
uploader: z.string().optional(),
23+
page: z.number().int().min(1).optional().default(1),
24+
limit: z.number().int().min(1).max(100).optional().default(10),
25+
});
26+
27+
export type SongListQueryDTO = z.infer<typeof songListQueryDTOSchema>;

0 commit comments

Comments
 (0)