Skip to content

Commit

Permalink
feat: introduce code generation for file upload
Browse files Browse the repository at this point in the history
  • Loading branch information
dsinghvi committed Jan 10, 2025
1 parent 65ae054 commit e81dddf
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 20 deletions.
14 changes: 14 additions & 0 deletions fern/definition/imdb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ service:
errors:
- MovieDoesNotExistError

uploadMovie:
method: POST
path: /{movieId}/upload
path-parameters:
movieId: MovieId
request:
name: UploadMovieRequest
body:
properties:
length: double
video: file
errors:
- MovieDoesNotExistError

errors:
MovieDoesNotExistError:
status-code: 404
2 changes: 1 addition & 1 deletion fern/fern.config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"organization": "fern",
"version": "0.40.4"
"version": "0.47.1"
}
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@
},
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2"
"express": "^4.18.2",
"multer": "^1.4.5-lts.1"
},
"devDependencies": {
"@types/cors": "^2.8.13",
"@types/express": "^4.17.16",
"@types/express": "4.17.13",
"@types/multer": "1.4.7",
"@types/node": "^22.5.0",
"@typescript-eslint/eslint-plugin": "latest",
"@typescript-eslint/parser": "latest",
"prettier": "^3.1.0",
"nodemon": "^3.0.2",
"eslint": "^8.55.0",
"nodemon": "^3.0.2",
"prettier": "^3.1.0",
"ts-node": "^10.9.2",
"typescript": "4.6.4"
}
}
}
99 changes: 97 additions & 2 deletions src/api/generated/api/resources/imdb/service/ImdbService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
* This file was auto-generated by Fern from our API Definition.
*/

import * as FernApi from "../../../index";
import express from "express";
import * as serializers from "../../../../serialization/index";
import multer from "multer";
import path from "path";
import * as errors from "../../../../errors/index";
import * as serializers from "../../../../serialization/index";
import * as FernApi from "../../../index";

export interface ImdbServiceMethods {
createMovie(
Expand Down Expand Up @@ -33,12 +35,50 @@ export interface ImdbServiceMethods {
},
next: express.NextFunction
): void | Promise<void>;
uploadMovie(
req: express.Request<
{
movieId: serializers.MovieId.Raw;
},
never,
{
length: number;
video: Express.Multer.File;
},
never
>,
res: {
send: (responseBody: void) => Promise<void>;
cookie: (cookie: string, value: string, options?: express.CookieOptions) => void;
locals: any;
},
next: express.NextFunction
): void | Promise<void>;
}

export class ImdbService {
private router;
private upload;

constructor(private readonly methods: ImdbServiceMethods, middleware: express.RequestHandler[] = []) {
// Configure multer storage
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`);
}
});

// Initialize multer with storage config
this.upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 100 // 100MB file size limit for videos
}
});

this.router = express.Router({ mergeParams: true }).use(
express.json({
strict: false,
Expand Down Expand Up @@ -127,6 +167,61 @@ export class ImdbService {
next(error);
}
});
this.router.post("/:movieId/upload", this.upload.single('video') as any, async (req, res, next) => {
try {
if (!req.file) {
res.status(400).json({
error: "Missing required video file"
});
return;
}

const length = parseFloat(req.body.length);
if (!length) {
res.status(400).json({
error: "Missing required length parameter"
});
return;
}

await this.methods.uploadMovie(
req as any,
{
send: async (responseBody) => {
res.json(responseBody);
},
cookie: res.cookie.bind(res),
locals: res.locals,
},
next
);
next();
} catch (error) {
if (error instanceof multer.MulterError) {
if (error.code === 'LIMIT_FILE_SIZE') {
res.status(400).json({
error: 'File size is too large. Max size is 100MB'
});
} else {
res.status(400).json({
error: error.message
});
}
return;
}
if (error instanceof errors.FernApiError) {
console.warn(
`Endpoint 'uploadMovie' unexpectedly threw ${error.constructor.name}.` +
` If this was intentional, please add ${error.constructor.name} to` +
" the endpoint's errors list in your Fern Definition."
);
await error.send(res);
} else {
res.status(500).json("Internal Server Error");
}
next(error);
}
});
return this.router;
}
}
9 changes: 9 additions & 0 deletions src/services/imdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,13 @@ export default new ImdbService({
throw new FernApi.MovieDoesNotExistError();
}
},
uploadMovie: async (req, res) => {
console.log('Request:', {
file: req.file,
body: req.body,
params: req.params
});
// Handle the uploaded movie
await res.send();
},
});
Loading

0 comments on commit e81dddf

Please sign in to comment.