@@ -0,0 +1,25 @@ | |||
module.exports = { | |||
parser: '@typescript-eslint/parser', | |||
parserOptions: { | |||
project: 'tsconfig.json', | |||
sourceType: 'module', | |||
}, | |||
plugins: ['@typescript-eslint/eslint-plugin'], | |||
extends: [ | |||
'plugin:@typescript-eslint/eslint-recommended', | |||
'plugin:@typescript-eslint/recommended', | |||
'prettier', | |||
'prettier/@typescript-eslint', | |||
], | |||
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', | |||
}, | |||
}; |
@@ -0,0 +1,34 @@ | |||
# 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 |
@@ -0,0 +1,4 @@ | |||
{ | |||
"singleQuote": true, | |||
"trailingComma": "all" | |||
} |
@@ -0,0 +1 @@ | |||
start db `docker run --name geekfights-db -e MONGO_INITDB_DATABASE=geekfights -d -p 27017:27017 -v ~/data:/data/db mongo` |
@@ -0,0 +1,4 @@ | |||
{ | |||
"collection": "@nestjs/schematics", | |||
"sourceRoot": "src" | |||
} |
@@ -0,0 +1,72 @@ | |||
{ | |||
"name": "geekfights-service", | |||
"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.0.0", | |||
"@nestjs/core": "^7.0.0", | |||
"@nestjs/mongoose": "^7.0.2", | |||
"@nestjs/platform-express": "^7.0.0", | |||
"@types/podcast": "^1.3.0", | |||
"mongoose": "^5.10.9", | |||
"podcast": "^1.3.0", | |||
"reflect-metadata": "^0.1.13", | |||
"rimraf": "^3.0.2", | |||
"rxjs": "^6.5.4" | |||
}, | |||
"devDependencies": { | |||
"@nestjs/cli": "^7.0.0", | |||
"@nestjs/schematics": "^7.0.0", | |||
"@nestjs/testing": "^7.0.0", | |||
"@types/express": "^4.17.3", | |||
"@types/jest": "26.0.10", | |||
"@types/mongoose": "^5.7.36", | |||
"@types/node": "^13.9.1", | |||
"@types/supertest": "^2.0.8", | |||
"@typescript-eslint/eslint-plugin": "3.9.1", | |||
"@typescript-eslint/parser": "3.9.1", | |||
"eslint": "7.7.0", | |||
"eslint-config-prettier": "^6.10.0", | |||
"eslint-plugin-import": "^2.20.1", | |||
"jest": "26.4.2", | |||
"prettier": "^1.19.1", | |||
"supertest": "^4.0.2", | |||
"ts-jest": "26.2.0", | |||
"ts-loader": "^6.2.1", | |||
"ts-node": "9.0.0", | |||
"tsconfig-paths": "^3.9.0", | |||
"typescript": "^3.7.4" | |||
}, | |||
"jest": { | |||
"moduleFileExtensions": [ | |||
"js", | |||
"json", | |||
"ts" | |||
], | |||
"rootDir": "src", | |||
"testRegex": ".spec.ts$", | |||
"transform": { | |||
"^.+\\.(t|j)s$": "ts-jest" | |||
}, | |||
"coverageDirectory": "../coverage", | |||
"testEnvironment": "node" | |||
} | |||
} |
@@ -0,0 +1,5 @@ | |||
import { Episode } from "schemas/entity/episode.entity"; | |||
export class CreateEpisodeDto extends Episode { | |||
} |
@@ -0,0 +1,21 @@ | |||
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; | |||
import Podcast from 'podcast'; | |||
import { Document } from 'mongoose'; | |||
export type EpisodeEnclosureDocument = EpisodeEnclosure & Document; | |||
@Schema() | |||
export class EpisodeEnclosure implements Podcast.ItemEnclosure { | |||
@Prop() | |||
url: string; | |||
@Prop() | |||
file?: string; | |||
@Prop() | |||
size?: number; | |||
@Prop() | |||
type?: string; | |||
} | |||
export const EpisodeEnclosureSchema = SchemaFactory.createForClass( | |||
EpisodeEnclosure, | |||
); |
@@ -0,0 +1,55 @@ | |||
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; | |||
import Podcast from 'podcast'; | |||
import { ItunesEpisodeTypeEnum } from 'schemas/enum/itunes-episode-type.enum'; | |||
import { EpisodeEnclosure } from './episode-enclosure'; | |||
import { Document } from 'mongoose'; | |||
export type EpisodeDocument = Episode & Document; | |||
@Schema() | |||
export class Episode implements Podcast.Item { | |||
@Prop() | |||
title?: string; | |||
@Prop() | |||
description?: string; | |||
@Prop() | |||
url: string; | |||
@Prop() | |||
guid?: string; | |||
@Prop([String]) | |||
categories?: string[]; | |||
@Prop() | |||
author?: string; | |||
@Prop() | |||
date: Date; | |||
@Prop() | |||
lat?: number; | |||
@Prop() | |||
long?: number; | |||
@Prop(EpisodeEnclosure) | |||
enclosure?: EpisodeEnclosure; | |||
@Prop() | |||
content?: string; | |||
@Prop() | |||
itunesAuthor?: string; | |||
@Prop() | |||
itunesExplicit?: boolean; | |||
@Prop() | |||
itunesSubtitle?: string; | |||
@Prop() | |||
itunesSummary?: string; | |||
@Prop() | |||
itunesDuration?: number; | |||
@Prop() | |||
itunesImage?: string; | |||
@Prop() | |||
itunesSeason?: number; | |||
@Prop() | |||
itunesEpisode?: number; | |||
@Prop() | |||
itunesTitle?: string; | |||
@Prop(ItunesEpisodeTypeEnum) | |||
itunesEpisodeType?: ItunesEpisodeTypeEnum; | |||
} | |||
export const EpisodeSchema = SchemaFactory.createForClass(Episode); |
@@ -0,0 +1,5 @@ | |||
export enum ItunesEpisodeTypeEnum { | |||
FULL = "full", | |||
TRAILER = "trailer", | |||
BONUS = "bonus", | |||
} |
@@ -0,0 +1,22 @@ | |||
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!'); | |||
}); | |||
}); | |||
}); |
@@ -0,0 +1,14 @@ | |||
import { Module } from '@nestjs/common'; | |||
import { MongooseModule } from '@nestjs/mongoose'; | |||
import { Episode, EpisodeSchema } from 'schemas/entity/episode.entity'; | |||
import { AppService } from './app.service'; | |||
import { EpisodeService } from './episode/episode.service'; | |||
@Module({ | |||
imports: [ | |||
MongooseModule.forFeature([{ name: Episode.name, schema: EpisodeSchema }]), | |||
MongooseModule.forRoot('mongodb://localhost:27017/test') | |||
], | |||
providers: [AppService, EpisodeService], | |||
}) | |||
export class AppModule {} |
@@ -0,0 +1,8 @@ | |||
import { Injectable } from '@nestjs/common'; | |||
@Injectable() | |||
export class AppService { | |||
getHello(): string { | |||
return 'Hello World!'; | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
import { Test, TestingModule } from '@nestjs/testing'; | |||
import { EpisodeService } from './episode.service'; | |||
describe('EpisodeService', () => { | |||
let service: EpisodeService; | |||
beforeEach(async () => { | |||
const module: TestingModule = await Test.createTestingModule({ | |||
providers: [EpisodeService], | |||
}).compile(); | |||
service = module.get<EpisodeService>(EpisodeService); | |||
}); | |||
it('should be defined', () => { | |||
expect(service).toBeDefined(); | |||
}); | |||
}); |
@@ -0,0 +1,20 @@ | |||
import { Injectable } from '@nestjs/common'; | |||
import { InjectModel } from '@nestjs/mongoose'; | |||
import { Model } from 'mongoose'; | |||
import { CreateEpisodeDto } from 'schemas/dto/create-episode.dto'; | |||
import { Episode, EpisodeDocument } from 'schemas/entity/episode.entity'; | |||
@Injectable() | |||
export class EpisodeService { | |||
constructor( | |||
@InjectModel(Episode.name) private episodeModel: Model<EpisodeDocument>, | |||
) {} | |||
async create(createEpisodeDto: CreateEpisodeDto): Promise<Episode> { | |||
const createdEpisode = new this.episodeModel(createEpisodeDto); | |||
return createdEpisode.save(); | |||
} | |||
async findAll(): Promise<Episode[]> { | |||
return this.episodeModel.find().exec(); | |||
} | |||
} |
@@ -0,0 +1,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(); |
@@ -0,0 +1,24 @@ | |||
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!'); | |||
}); | |||
}); |
@@ -0,0 +1,9 @@ | |||
{ | |||
"moduleFileExtensions": ["js", "json", "ts"], | |||
"rootDir": ".", | |||
"testEnvironment": "node", | |||
"testRegex": ".e2e-spec.ts$", | |||
"transform": { | |||
"^.+\\.(t|j)s$": "ts-jest" | |||
} | |||
} |
@@ -0,0 +1,4 @@ | |||
{ | |||
"extends": "./tsconfig.json", | |||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"] | |||
} |
@@ -0,0 +1,15 @@ | |||
{ | |||
"compilerOptions": { | |||
"module": "commonjs", | |||
"declaration": true, | |||
"removeComments": true, | |||
"emitDecoratorMetadata": true, | |||
"experimentalDecorators": true, | |||
"allowSyntheticDefaultImports": true, | |||
"target": "es2017", | |||
"sourceMap": true, | |||
"outDir": "./dist", | |||
"baseUrl": "./", | |||
"incremental": true | |||
} | |||
} |