Skip to content

Commit 8454448

Browse files
initial commit
0 parents  commit 8454448

File tree

17 files changed

+2109
-0
lines changed

17 files changed

+2109
-0
lines changed

.editorconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
end_of_line = lf
9+
insert_final_newline = true
10+
trim_trailing_whitespace = true
11+
12+
[*.md]
13+
insert_final_newline = false
14+
trim_trailing_whitespace = false

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# tmp
2+
.idea
3+
.DS_Store
4+
5+
# lib
6+
node_modules
7+
8+
# build
9+
**/*.js
10+
**/*.js.map
11+
**/*.d.ts

index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './lib/server';

lib/app.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import * as express from 'express';
2+
import * as bodyParser from 'body-parser';
3+
import * as errorhandler from 'strong-error-handler';
4+
import {movies} from './routes/movies';
5+
import {actors} from './routes/actors';
6+
7+
export const app = express();
8+
9+
// middleware for parsing application/x-www-form-urlencoded
10+
app.use(bodyParser.urlencoded({extended: true}));
11+
12+
// middleware for json body parsing
13+
app.use(bodyParser.json({limit: '5mb'}));
14+
15+
// enable corse for all origins
16+
app.use((req, res, next) => {
17+
res.header("Access-Control-Allow-Origin", "*");
18+
res.header("Access-Control-Expose-Headers", "x-total-count");
19+
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH");
20+
res.header("Access-Control-Allow-Headers", "Content-Type,authorization");
21+
22+
next();
23+
});
24+
25+
app.use('/movies', movies);
26+
app.use('/actors', actors);
27+
28+
app.use(errorhandler({
29+
debug: process.env.ENV !== 'prod',
30+
log: true,
31+
}));

lib/models/Actor.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {Model, Column, Table, BelongsToMany, Scopes, CreatedAt, UpdatedAt} from "sequelize-typescript";
2+
import {Movie} from "./Movie";
3+
import {MovieActor} from "./MovieActor";
4+
5+
@Scopes({
6+
movies: {
7+
include: [
8+
{
9+
model: () => Movie,
10+
through: {attributes: []},
11+
},
12+
],
13+
},
14+
})
15+
@Table
16+
export class Actor extends Model<Actor> {
17+
18+
@Column
19+
firstName: string;
20+
21+
@Column
22+
lastName: string;
23+
24+
@Column
25+
birthday: Date;
26+
27+
@BelongsToMany(() => Movie, () => MovieActor)
28+
movies?: Movie[];
29+
30+
@CreatedAt
31+
@Column
32+
createdAt: Date;
33+
34+
@UpdatedAt
35+
@Column
36+
updatedAt: Date;
37+
38+
static scope(name: string = 'defaultScope'): typeof Actor {
39+
return super.scope.call(this, name);
40+
}
41+
}

lib/models/Genre.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {Model, Column, Table, BelongsToMany, Scopes, PrimaryKey, CreatedAt, UpdatedAt} from "sequelize-typescript";
2+
import {Movie} from "./Movie";
3+
import {MovieGenre} from "./MovieGenre";
4+
5+
@Scopes({
6+
movies: {
7+
include: [
8+
{
9+
model: () => Movie,
10+
through: {attributes: []},
11+
},
12+
],
13+
},
14+
})
15+
@Table
16+
export class Genre extends Model<Genre> {
17+
18+
@PrimaryKey
19+
@Column
20+
name: string;
21+
22+
@BelongsToMany(() => Movie, () => MovieGenre)
23+
movies?: Movie[];
24+
25+
@CreatedAt
26+
@Column
27+
createdAt: Date;
28+
29+
@UpdatedAt
30+
@Column
31+
updatedAt: Date;
32+
}

lib/models/Movie.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {Model, Column, Table, BelongsToMany, Scopes, CreatedAt, UpdatedAt} from "sequelize-typescript";
2+
import * as Promise from "bluebird";
3+
import {MovieActor} from "./MovieActor";
4+
import {Actor} from "./Actor";
5+
import {ICreateOptions} from "sequelize-typescript/lib/interfaces/ICreateOptions";
6+
import {Genre} from "./Genre";
7+
import {MovieGenre} from "./MovieGenre";
8+
9+
@Scopes({
10+
cast: {
11+
include: [{
12+
model: () => Actor,
13+
through: {attributes: []},
14+
}],
15+
},
16+
genre: {
17+
include: [{
18+
model: () => Genre,
19+
through: {attributes: []},
20+
}]
21+
},
22+
full: {
23+
include: [{
24+
model: () => Actor,
25+
through: {attributes: []},
26+
}, {
27+
model: () => Genre,
28+
through: {attributes: []},
29+
}]
30+
}
31+
})
32+
@Table
33+
export class Movie extends Model<Movie> {
34+
35+
@Column
36+
title: string;
37+
38+
@Column
39+
year: number;
40+
41+
@BelongsToMany(() => Actor, () => MovieActor)
42+
cast?: Actor[];
43+
44+
@BelongsToMany(() => Genre, () => MovieGenre)
45+
genres?: Genre[];
46+
47+
@CreatedAt
48+
@Column
49+
createdAt: Date;
50+
51+
@UpdatedAt
52+
@Column
53+
updatedAt: Date;
54+
55+
static create(values?: any, options?: ICreateOptions): Promise<Movie> {
56+
const include: any = [];
57+
if (values) {
58+
if (values.cast) include.push(Actor);
59+
if (values.genres) include.push(Genre);
60+
}
61+
if (!options) options = {};
62+
options.include = options.include ? options.include.concat(include) : include;
63+
64+
return super.create.call(this, values, options);
65+
}
66+
67+
static scope(name: string = 'defaultScope'): typeof Movie {
68+
return super.scope.call(this, name);
69+
}
70+
}

lib/models/MovieActor.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {Model, Column, Table, ForeignKey} from "sequelize-typescript";
2+
import {Movie} from "./Movie";
3+
import {Actor} from "./Actor";
4+
5+
@Table
6+
export class MovieActor extends Model<MovieActor> {
7+
8+
@ForeignKey(() => Movie)
9+
@Column
10+
movieId: number;
11+
12+
@ForeignKey(() => Actor)
13+
@Column
14+
actorId: number;
15+
}

lib/models/MovieGenre.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {Model, Column, Table, ForeignKey} from "sequelize-typescript";
2+
import {Movie} from "./Movie";
3+
import {Genre} from "./Genre";
4+
5+
@Table
6+
export class MovieGenre extends Model<MovieGenre> {
7+
8+
@ForeignKey(() => Movie)
9+
@Column
10+
movieId: number;
11+
12+
@ForeignKey(() => Genre)
13+
@Column
14+
genre: string;
15+
}

lib/routes/actors.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {Router} from 'express';
2+
import {Actor} from '../models/Actor';
3+
import {MovieActor} from '../models/MovieActor';
4+
5+
export const actors = Router();
6+
7+
actors.post('/', (req, res, next) => {
8+
Actor
9+
.create(req.body)
10+
.then(() => res.sendStatus(201))
11+
.catch(next);
12+
});
13+
14+
actors.post('/:id/movies/:movieId', (req, res, next) => {
15+
MovieActor
16+
.create({
17+
actorId: req.params['id'], movieId: req.params['movieId']
18+
})
19+
.then(() => res.sendStatus(200))
20+
.catch(next);
21+
});
22+
23+
actors.get('', (req, res, next) => {
24+
Actor
25+
.scope(req.query['scope'])
26+
.findAll()
27+
.then(_actors => res.json(_actors))
28+
.catch(next);
29+
});
30+
31+
actors.get('/:id', (req, res, next) => {
32+
Actor
33+
.scope(req.query['scope'])
34+
.findById(req.params['id'])
35+
.then(actor => res.json(actor))
36+
.catch(next);
37+
});
38+
39+
actors.put('/:id', (req, res, next) => {
40+
Actor
41+
.update(req.body, {where: {id: req.params['id']}})
42+
.then(() => res.sendStatus(200))
43+
.catch(next);
44+
});

0 commit comments

Comments
 (0)