From 2f7e3222140aba2a0e13e307f18b42f6b39f084d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Sat, 20 Aug 2022 12:35:49 +0900 Subject: [PATCH] fix(es): Improve sourcemap (#5569) --- .../tests/fixture/sourcemap/011/input/.swcrc | 16 +++ .../sourcemap/011/input/CommentControlller.ts | 36 +++++ .../011/output/CommentControlller.map | 39 +++++ .../011/output/CommentControlller.ts | 55 +++++++ .../tests/fixture/sourcemap/012/input/.swcrc | 16 +++ .../sourcemap/012/input/CommentService.ts | 134 ++++++++++++++++++ .../sourcemap/012/output/CommentService.map | 61 ++++++++ .../sourcemap/012/output/CommentService.ts | 111 +++++++++++++++ .../tests/fixture/sourcemap/013/input/.swcrc | 16 +++ .../sourcemap/013/input/PistController.ts | 80 +++++++++++ .../sourcemap/013/output/PistController.map | 58 ++++++++ .../sourcemap/013/output/PistController.ts | 110 ++++++++++++++ .../tests/fixture/sourcemap/014/input/.swcrc | 16 +++ .../sourcemap/014/input/UserController.ts | 48 +++++++ .../sourcemap/014/output/UserController.map | 41 ++++++ .../sourcemap/014/output/UserController.ts | 55 +++++++ crates/swc_ecma_ast/src/ident.rs | 9 +- crates/swc_ecma_codegen/src/lib.rs | 3 +- .../src/decorators/legacy/metadata.rs | 2 +- .../src/decorators/legacy/mod.rs | 7 + .../src/strip.rs | 5 +- 21 files changed, 913 insertions(+), 5 deletions(-) create mode 100644 crates/swc/tests/fixture/sourcemap/011/input/.swcrc create mode 100644 crates/swc/tests/fixture/sourcemap/011/input/CommentControlller.ts create mode 100644 crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.map create mode 100644 crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.ts create mode 100644 crates/swc/tests/fixture/sourcemap/012/input/.swcrc create mode 100644 crates/swc/tests/fixture/sourcemap/012/input/CommentService.ts create mode 100644 crates/swc/tests/fixture/sourcemap/012/output/CommentService.map create mode 100644 crates/swc/tests/fixture/sourcemap/012/output/CommentService.ts create mode 100644 crates/swc/tests/fixture/sourcemap/013/input/.swcrc create mode 100644 crates/swc/tests/fixture/sourcemap/013/input/PistController.ts create mode 100644 crates/swc/tests/fixture/sourcemap/013/output/PistController.map create mode 100644 crates/swc/tests/fixture/sourcemap/013/output/PistController.ts create mode 100644 crates/swc/tests/fixture/sourcemap/014/input/.swcrc create mode 100644 crates/swc/tests/fixture/sourcemap/014/input/UserController.ts create mode 100644 crates/swc/tests/fixture/sourcemap/014/output/UserController.map create mode 100644 crates/swc/tests/fixture/sourcemap/014/output/UserController.ts diff --git a/crates/swc/tests/fixture/sourcemap/011/input/.swcrc b/crates/swc/tests/fixture/sourcemap/011/input/.swcrc new file mode 100644 index 00000000000..44899292f8e --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/011/input/.swcrc @@ -0,0 +1,16 @@ +{ + "sourceMaps": true, + "jsc": { + "target": "es2022", + "parser": { + "syntax": "typescript", + "tsx": true, + "decorators": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "keepClassNames": true + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/sourcemap/011/input/CommentControlller.ts b/crates/swc/tests/fixture/sourcemap/011/input/CommentControlller.ts new file mode 100644 index 00000000000..acce7815a2c --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/011/input/CommentControlller.ts @@ -0,0 +1,36 @@ +import { Body, Controller, Delete, Param, Put, UseGuards, UseInterceptors } from '@nestjs/common'; + +import { + COMMENT_CONTROLLER_ROUTE, + COMMENT_DELETE_ENDPOINT, + COMMENT_UPDATE_ENDPOINT, +} from '@server/constants/controllers'; +import { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor'; +import { Comment } from '@server/comment/schemas/CommentSchema'; +import { CommentService } from '@server/comment/CommentService'; +import { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard'; +import { User } from '@server/decorators/UserDecorator'; +import { User as UserType } from '@server/user/schemas/UserSchema'; +import { UpdateCommentDto } from '@server/comment/dto/UpdateCommentDto'; + +@Controller(COMMENT_CONTROLLER_ROUTE) +@UseInterceptors(MongooseClassSerializerInterceptor(Comment)) +export class CommentController { + constructor(private commentService: CommentService) { } + + @UseGuards(JwtAuthGuard) + @Put(COMMENT_UPDATE_ENDPOINT) + public updateComment( + @Param('id') id: string, + @Body() updateCommentDto: UpdateCommentDto, + @User() user: UserType, + ) { + return this.commentService.update(id, updateCommentDto, user.id); + } + + @UseGuards(JwtAuthGuard) + @Delete(COMMENT_DELETE_ENDPOINT) + public deleteComment(@Param('id') id: string, @User() user: UserType) { + return this.commentService.delete(id, user.id); + } +} diff --git a/crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.map b/crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.map new file mode 100644 index 00000000000..6e68e1b20b2 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.map @@ -0,0 +1,39 @@ +{ + "mappings": "AAAA;;;AAAA,SAASA,IAAI,EAAEC,UAAU,EAAEC,MAAM,EAAEC,KAAK,EAAEC,GAAG,EAAEC,SAAS,EAAEC,eAAe,QAAQ,gBAAgB,CAAC;AAElG,SACIC,wBAAwB,EACxBC,uBAAuB,EACvBC,uBAAuB,QACpB,+BAA+B,CAAC;AACvC,SAASC,kCAAkC,QAAQ,yDAAyD,CAAC;AAC7G,SAASC,OAAO,QAAQ,uCAAuC,CAAC;AAChE,SAASC,cAAc,QAAQ,gCAAgC,CAAC;AAChE,SAASC,YAAY,QAAQ,kCAAkC,CAAC;AAChE,SAASC,IAAI,QAAQ,kCAAkC,CAAC;AACxD,SAASA,IAAI,IAAIC,QAAQ,QAAQ,iCAAiC,CAAC;AACnE,SAASC,gBAAgB,QAAQ,sCAAsC,CAAC;AAIxE,WAAaC,iBAAiB,GAAvB;IACHC,YAAoBC,cAA8B,CAAE;QAAhCA,sBAAAA,cAA8B,CAAA;KAAK;IAIhDC,aAAa,CAChB,AAAaC,EAAU,EACvB,AAAQC,gBAAkC,EAC1C,AAAQC,IAAc,EACxB;QACE,OAAO,IAAI,CAACJ,cAAc,CAACK,MAAM,CAACH,EAAE,EAAEC,gBAAgB,EAAEC,IAAI,CAACF,EAAE,CAAC,CAAC;KACpE;IAIMI,aAAa,CAAC,AAAaJ,EAAU,EAAE,AAAQE,IAAc,EAAE;QAClE,OAAO,IAAI,CAACJ,cAAc,CAACO,MAAM,CAACL,EAAE,EAAEE,IAAI,CAACF,EAAE,CAAC,CAAC;KAClD;CACJ,CAAA;;IAfIhB,SAAS,CAACQ,YAAY,CAAC;IACvBT,GAAG,CAACK,uBAAuB,CAAC;IAExBN,aAAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IACXH,aAAAA,IAAI,EAAE,CAAA;IACNc,aAAAA,IAAI,EAAE,CAAA;;;;eADmB,gBAAgB,4BAAhB,gBAAgB;eAC5B,QAAQ,4BAAR,QAAQ;;GARjBG,iBAAiB;;IAazBZ,SAAS,CAACQ,YAAY,CAAC;IACvBX,MAAM,CAACM,uBAAuB,CAAC;IACVL,aAAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IAAcW,aAAAA,IAAI,EAAE,CAAA;;;;eAAO,QAAQ,4BAAR,QAAQ;;GAf3DG,iBAAiB;AAAjBA,iBAAiB;IAF7BhB,UAAU,CAACM,wBAAwB,CAAC;IACpCD,eAAe,CAACI,kCAAkC,CAACC,OAAO,CAAC,CAAC;;;eAErB,cAAc,4BAAd,cAAc;;GADzCM,iBAAiB", + "names": [ + "Body", + "Controller", + "Delete", + "Param", + "Put", + "UseGuards", + "UseInterceptors", + "COMMENT_CONTROLLER_ROUTE", + "COMMENT_DELETE_ENDPOINT", + "COMMENT_UPDATE_ENDPOINT", + "MongooseClassSerializerInterceptor", + "Comment", + "CommentService", + "JwtAuthGuard", + "User", + "UserType", + "UpdateCommentDto", + "CommentController", + "constructor", + "commentService", + "updateComment", + "id", + "updateCommentDto", + "user", + "update", + "deleteComment", + "delete" + ], + "sources": [ + "../../input/CommentControlller.ts" + ], + "sourcesContent": [ + "import { Body, Controller, Delete, Param, Put, UseGuards, UseInterceptors } from '@nestjs/common';\n\nimport {\n COMMENT_CONTROLLER_ROUTE,\n COMMENT_DELETE_ENDPOINT,\n COMMENT_UPDATE_ENDPOINT,\n} from '@server/constants/controllers';\nimport { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor';\nimport { Comment } from '@server/comment/schemas/CommentSchema';\nimport { CommentService } from '@server/comment/CommentService';\nimport { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard';\nimport { User } from '@server/decorators/UserDecorator';\nimport { User as UserType } from '@server/user/schemas/UserSchema';\nimport { UpdateCommentDto } from '@server/comment/dto/UpdateCommentDto';\n\n@Controller(COMMENT_CONTROLLER_ROUTE)\n@UseInterceptors(MongooseClassSerializerInterceptor(Comment))\nexport class CommentController {\n constructor(private commentService: CommentService) { }\n\n @UseGuards(JwtAuthGuard)\n @Put(COMMENT_UPDATE_ENDPOINT)\n public updateComment(\n @Param('id') id: string,\n @Body() updateCommentDto: UpdateCommentDto,\n @User() user: UserType,\n ) {\n return this.commentService.update(id, updateCommentDto, user.id);\n }\n\n @UseGuards(JwtAuthGuard)\n @Delete(COMMENT_DELETE_ENDPOINT)\n public deleteComment(@Param('id') id: string, @User() user: UserType) {\n return this.commentService.delete(id, user.id);\n }\n}\n" + ], + "version": 3 +} diff --git a/crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.ts b/crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.ts new file mode 100644 index 00000000000..20dab4032c9 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/011/output/CommentControlller.ts @@ -0,0 +1,55 @@ +import _ts_decorate from "@swc/helpers/src/_ts_decorate.mjs"; +import _ts_metadata from "@swc/helpers/src/_ts_metadata.mjs"; +import _ts_param from "@swc/helpers/src/_ts_param.mjs"; +import { Body, Controller, Delete, Param, Put, UseGuards, UseInterceptors } from '@nestjs/common'; +import { COMMENT_CONTROLLER_ROUTE, COMMENT_DELETE_ENDPOINT, COMMENT_UPDATE_ENDPOINT } from '@server/constants/controllers'; +import { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor'; +import { Comment } from '@server/comment/schemas/CommentSchema'; +import { CommentService } from '@server/comment/CommentService'; +import { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard'; +import { User } from '@server/decorators/UserDecorator'; +import { User as UserType } from '@server/user/schemas/UserSchema'; +import { UpdateCommentDto } from '@server/comment/dto/UpdateCommentDto'; +export let CommentController = class CommentController { + constructor(commentService){ + this.commentService = commentService; + } + updateComment(id, updateCommentDto, user) { + return this.commentService.update(id, updateCommentDto, user.id); + } + deleteComment(id, user) { + return this.commentService.delete(id, user.id); + } +}; +_ts_decorate([ + UseGuards(JwtAuthGuard), + Put(COMMENT_UPDATE_ENDPOINT), + _ts_param(0, Param('id')), + _ts_param(1, Body()), + _ts_param(2, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String, + typeof UpdateCommentDto === "undefined" ? Object : UpdateCommentDto, + typeof UserType === "undefined" ? Object : UserType + ]) +], CommentController.prototype, "updateComment", null); +_ts_decorate([ + UseGuards(JwtAuthGuard), + Delete(COMMENT_DELETE_ENDPOINT), + _ts_param(0, Param('id')), + _ts_param(1, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String, + typeof UserType === "undefined" ? Object : UserType + ]) +], CommentController.prototype, "deleteComment", null); +CommentController = _ts_decorate([ + Controller(COMMENT_CONTROLLER_ROUTE), + UseInterceptors(MongooseClassSerializerInterceptor(Comment)), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + typeof CommentService === "undefined" ? Object : CommentService + ]) +], CommentController); diff --git a/crates/swc/tests/fixture/sourcemap/012/input/.swcrc b/crates/swc/tests/fixture/sourcemap/012/input/.swcrc new file mode 100644 index 00000000000..44899292f8e --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/012/input/.swcrc @@ -0,0 +1,16 @@ +{ + "sourceMaps": true, + "jsc": { + "target": "es2022", + "parser": { + "syntax": "typescript", + "tsx": true, + "decorators": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "keepClassNames": true + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/sourcemap/012/input/CommentService.ts b/crates/swc/tests/fixture/sourcemap/012/input/CommentService.ts new file mode 100644 index 00000000000..b9d007f051d --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/012/input/CommentService.ts @@ -0,0 +1,134 @@ +import { Model, Connection as MongooseConnection } from 'mongoose'; +import { + ForbiddenException, + Injectable, + InternalServerErrorException, + NotFoundException, +} from '@nestjs/common'; +import { InjectModel, InjectConnection } from '@nestjs/mongoose'; + +import { Comment, CommentDocument } from '@server/comment/schemas/CommentSchema'; +import { CreateCommentDto } from '@server/comment/dto/CreateCommentDto'; +import { UpdateCommentDto } from '@server/comment/dto/UpdateCommentDto'; +import { Post, PostDocument } from '@server/post/schemas/PostSchema'; + +@Injectable() +export class CommentService { + constructor( + @InjectModel(Comment.name) private commentModel: Model, + @InjectModel(Post.name) private postModel: Model, + @InjectConnection() private readonly connection: MongooseConnection, + ) {} + + async getById(commentId: string): Promise { + const comment = await this.commentModel.findById(commentId); + + if (!comment) { + throw new NotFoundException(); + } + + return comment.populate('author'); + } + + async create( + comment: CreateCommentDto, + postId: string, + userId: string, + ): Promise { + const session = await this.connection.startSession(); + + session.startTransaction(); + + try { + const createdComment = await this.commentModel.create({ + ...comment, + author: userId, + postId, + }); + + if (!createdComment) { + throw new InternalServerErrorException('Comment was not created'); + } + + const { modifiedCount } = await this.postModel.updateOne( + { _id: createdComment.postId }, + { + $push: { comments: createdComment.id }, + }, + { useFindAndModify: false }, + ); + + if (modifiedCount === 0) { + throw new InternalServerErrorException('Comment was not created'); + } + + await session.commitTransaction(); + + return createdComment.populate('author'); + } catch (error) { + await session.abortTransaction(); + + throw error; + } finally { + session.endSession(); + } + } + + async update( + commentId: string, + comment: UpdateCommentDto, + userId: string, + ): Promise { + const { author } = await this.getById(commentId); + + if (author.id !== userId) { + throw new ForbiddenException(); + } + + const updatedComment = await this.commentModel.findByIdAndUpdate(commentId, comment, { + new: true, + }); + + if (!updatedComment) { + throw new InternalServerErrorException('Comment was not updated'); + } + + return updatedComment.populate('author'); + } + + async delete(commentId: string, userId: string): Promise { + const session = await this.connection.startSession(); + + session.startTransaction(); + + try { + const { author, postId } = await this.getById(commentId); + + if (author.id !== userId) { + throw new ForbiddenException(); + } + + const { deletedCount } = await this.commentModel.deleteOne({ _id: commentId }); + + const { modifiedCount } = await this.postModel.updateOne( + { _id: postId }, + { + $pull: { comments: commentId }, + }, + { useFindAndModify: false }, + ); + + if (deletedCount === 0 || modifiedCount === 0) { + throw new InternalServerErrorException('Comment was not deleted'); + } + + await session.commitTransaction(); + } catch (error) { + await session.abortTransaction(); + + throw error; + } finally { + session.endSession(); + } + } +} diff --git a/crates/swc/tests/fixture/sourcemap/012/output/CommentService.map b/crates/swc/tests/fixture/sourcemap/012/output/CommentService.map new file mode 100644 index 00000000000..46108fb0ef1 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/012/output/CommentService.map @@ -0,0 +1,61 @@ +{ + "mappings": "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", + "names": [ + "Model", + "Connection", + "MongooseConnection", + "ForbiddenException", + "Injectable", + "InternalServerErrorException", + "NotFoundException", + "InjectModel", + "InjectConnection", + "Comment", + "Post", + "CommentService", + "constructor", + "commentModel", + "postModel", + "connection", + "getById", + "commentId", + "comment", + "findById", + "populate", + "create", + "postId", + "userId", + "session", + "startSession", + "startTransaction", + "createdComment", + "author", + "modifiedCount", + "updateOne", + "_id", + "$push", + "comments", + "id", + "useFindAndModify", + "commitTransaction", + "error", + "abortTransaction", + "endSession", + "update", + "updatedComment", + "findByIdAndUpdate", + "new", + "delete", + "deletedCount", + "deleteOne", + "$pull", + "name" + ], + "sources": [ + "../../input/CommentService.ts" + ], + "sourcesContent": [ + "import { Model, Connection as MongooseConnection } from 'mongoose';\nimport {\n ForbiddenException,\n Injectable,\n InternalServerErrorException,\n NotFoundException,\n} from '@nestjs/common';\nimport { InjectModel, InjectConnection } from '@nestjs/mongoose';\n\nimport { Comment, CommentDocument } from '@server/comment/schemas/CommentSchema';\nimport { CreateCommentDto } from '@server/comment/dto/CreateCommentDto';\nimport { UpdateCommentDto } from '@server/comment/dto/UpdateCommentDto';\nimport { Post, PostDocument } from '@server/post/schemas/PostSchema';\n\n@Injectable()\nexport class CommentService {\n constructor(\n @InjectModel(Comment.name) private commentModel: Model,\n @InjectModel(Post.name) private postModel: Model,\n @InjectConnection() private readonly connection: MongooseConnection,\n ) {}\n\n async getById(commentId: string): Promise {\n const comment = await this.commentModel.findById(commentId);\n\n if (!comment) {\n throw new NotFoundException();\n }\n\n return comment.populate('author');\n }\n\n async create(\n comment: CreateCommentDto,\n postId: string,\n userId: string,\n ): Promise {\n const session = await this.connection.startSession();\n\n session.startTransaction();\n\n try {\n const createdComment = await this.commentModel.create({\n ...comment,\n author: userId,\n postId,\n });\n\n if (!createdComment) {\n throw new InternalServerErrorException('Comment was not created');\n }\n\n const { modifiedCount } = await this.postModel.updateOne(\n { _id: createdComment.postId },\n {\n $push: { comments: createdComment.id },\n },\n { useFindAndModify: false },\n );\n\n if (modifiedCount === 0) {\n throw new InternalServerErrorException('Comment was not created');\n }\n\n await session.commitTransaction();\n\n return createdComment.populate('author');\n } catch (error) {\n await session.abortTransaction();\n\n throw error;\n } finally {\n session.endSession();\n }\n }\n\n async update(\n commentId: string,\n comment: UpdateCommentDto,\n userId: string,\n ): Promise {\n const { author } = await this.getById(commentId);\n\n if (author.id !== userId) {\n throw new ForbiddenException();\n }\n\n const updatedComment = await this.commentModel.findByIdAndUpdate(commentId, comment, {\n new: true,\n });\n\n if (!updatedComment) {\n throw new InternalServerErrorException('Comment was not updated');\n }\n\n return updatedComment.populate('author');\n }\n\n async delete(commentId: string, userId: string): Promise {\n const session = await this.connection.startSession();\n\n session.startTransaction();\n\n try {\n const { author, postId } = await this.getById(commentId);\n\n if (author.id !== userId) {\n throw new ForbiddenException();\n }\n\n const { deletedCount } = await this.commentModel.deleteOne({ _id: commentId });\n\n const { modifiedCount } = await this.postModel.updateOne(\n { _id: postId },\n {\n $pull: { comments: commentId },\n },\n { useFindAndModify: false },\n );\n\n if (deletedCount === 0 || modifiedCount === 0) {\n throw new InternalServerErrorException('Comment was not deleted');\n }\n\n await session.commitTransaction();\n } catch (error) {\n await session.abortTransaction();\n\n throw error;\n } finally {\n session.endSession();\n }\n }\n}\n" + ], + "version": 3 +} diff --git a/crates/swc/tests/fixture/sourcemap/012/output/CommentService.ts b/crates/swc/tests/fixture/sourcemap/012/output/CommentService.ts new file mode 100644 index 00000000000..4e2b2ae8343 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/012/output/CommentService.ts @@ -0,0 +1,111 @@ +import _ts_decorate from "@swc/helpers/src/_ts_decorate.mjs"; +import _ts_metadata from "@swc/helpers/src/_ts_metadata.mjs"; +import _ts_param from "@swc/helpers/src/_ts_param.mjs"; +import { Model, Connection as MongooseConnection } from 'mongoose'; +import { ForbiddenException, Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; +import { InjectModel, InjectConnection } from '@nestjs/mongoose'; +import { Comment } from '@server/comment/schemas/CommentSchema'; +import { Post } from '@server/post/schemas/PostSchema'; +export let CommentService = class CommentService { + constructor(commentModel, postModel, connection){ + this.commentModel = commentModel; + this.postModel = postModel; + this.connection = connection; + } + async getById(commentId) { + const comment = await this.commentModel.findById(commentId); + if (!comment) { + throw new NotFoundException(); + } + return comment.populate('author'); + } + async create(comment, postId, userId) { + const session = await this.connection.startSession(); + session.startTransaction(); + try { + const createdComment = await this.commentModel.create({ + ...comment, + author: userId, + postId + }); + if (!createdComment) { + throw new InternalServerErrorException('Comment was not created'); + } + const { modifiedCount } = await this.postModel.updateOne({ + _id: createdComment.postId + }, { + $push: { + comments: createdComment.id + } + }, { + useFindAndModify: false + }); + if (modifiedCount === 0) { + throw new InternalServerErrorException('Comment was not created'); + } + await session.commitTransaction(); + return createdComment.populate('author'); + } catch (error) { + await session.abortTransaction(); + throw error; + } finally{ + session.endSession(); + } + } + async update(commentId, comment, userId) { + const { author } = await this.getById(commentId); + if (author.id !== userId) { + throw new ForbiddenException(); + } + const updatedComment = await this.commentModel.findByIdAndUpdate(commentId, comment, { + new: true + }); + if (!updatedComment) { + throw new InternalServerErrorException('Comment was not updated'); + } + return updatedComment.populate('author'); + } + async delete(commentId, userId) { + const session = await this.connection.startSession(); + session.startTransaction(); + try { + const { author , postId } = await this.getById(commentId); + if (author.id !== userId) { + throw new ForbiddenException(); + } + const { deletedCount } = await this.commentModel.deleteOne({ + _id: commentId + }); + const { modifiedCount } = await this.postModel.updateOne({ + _id: postId + }, { + $pull: { + comments: commentId + } + }, { + useFindAndModify: false + }); + if (deletedCount === 0 || modifiedCount === 0) { + throw new InternalServerErrorException('Comment was not deleted'); + } + await session.commitTransaction(); + } catch (error) { + await session.abortTransaction(); + throw error; + } finally{ + session.endSession(); + } + } +}; +CommentService = _ts_decorate([ + Injectable(), + _ts_param(0, InjectModel(Comment.name)), + _ts_param(1, InjectModel(Post.name)), + _ts_param(2, InjectConnection()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + typeof Model === "undefined" ? Object : Model, + typeof Model === "undefined" ? Object : Model, + typeof MongooseConnection === "undefined" ? Object : MongooseConnection + ]) +], CommentService); diff --git a/crates/swc/tests/fixture/sourcemap/013/input/.swcrc b/crates/swc/tests/fixture/sourcemap/013/input/.swcrc new file mode 100644 index 00000000000..44899292f8e --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/013/input/.swcrc @@ -0,0 +1,16 @@ +{ + "sourceMaps": true, + "jsc": { + "target": "es2022", + "parser": { + "syntax": "typescript", + "tsx": true, + "decorators": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "keepClassNames": true + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/sourcemap/013/input/PistController.ts b/crates/swc/tests/fixture/sourcemap/013/input/PistController.ts new file mode 100644 index 00000000000..96fe85cd558 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/013/input/PistController.ts @@ -0,0 +1,80 @@ +import { + Body, + Controller, + Delete, + Get, + Param, + Post, + Put, + UseGuards, + UseInterceptors, +} from '@nestjs/common'; + +import { + POST_CONTROLLER_ROUTE, + POST_DELETE_ENDPOINT, + POST_GET_ALL_ENDPOINT, + POST_GET_ENDPOINT, + POST_CREATE_COMMENT_ENDPOINT, + POST_CREATE_ENDPOINT, + POST_UPDATE_ENDPOINT, +} from '@server/constants/controllers'; +import { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor'; +import { Post as PostType } from '@server/post/schemas/PostSchema'; +import { PostService } from '@server/post/PostService'; +import { CreatePostDto } from '@server/post/dto/CreatePostDto'; +import { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard'; +import { User } from '@server/decorators/UserDecorator'; +import { User as UserType } from '@server/user/schemas/UserSchema'; +import { CreateCommentDto } from '@server/comment/dto/CreateCommentDto'; +import { CommentService } from '@server/comment/CommentService'; +import { Comment } from '@server/comment/schemas/CommentSchema'; + +@Controller(POST_CONTROLLER_ROUTE) +@UseInterceptors(MongooseClassSerializerInterceptor(PostType)) +export class PostController { + constructor(private postService: PostService, private commentService: CommentService) { } + + @Get(POST_GET_ALL_ENDPOINT) + public getPosts() { + return this.postService.getAll(); + } + + @Get(POST_GET_ENDPOINT) + public getPost(@Param('id') id: string) { + return this.postService.getById(id); + } + + @UseGuards(JwtAuthGuard) + @Post(POST_CREATE_ENDPOINT) + public createPost(@Body() createPostDto: CreatePostDto, @User() user: UserType) { + return this.postService.create(createPostDto, user.id); + } + + @UseGuards(JwtAuthGuard) + @Put(POST_UPDATE_ENDPOINT) + public updatePost( + @Param('id') id: string, + @Body() updatePostDto: CreatePostDto, + @User() user: UserType, + ) { + return this.postService.update(id, updatePostDto, user.id); + } + + @UseGuards(JwtAuthGuard) + @Delete(POST_DELETE_ENDPOINT) + public deletePost(@Param('id') id: string, @User() user: UserType) { + return this.postService.delete(id, user.id); + } + + @UseInterceptors(MongooseClassSerializerInterceptor(Comment)) + @UseGuards(JwtAuthGuard) + @Post(POST_CREATE_COMMENT_ENDPOINT) + public createPostComment( + @Param('id') id: string, + @Body() createCommentDto: CreateCommentDto, + @User() user: UserType, + ) { + return this.commentService.create(createCommentDto, id, user.id); + } +} diff --git a/crates/swc/tests/fixture/sourcemap/013/output/PistController.map b/crates/swc/tests/fixture/sourcemap/013/output/PistController.map new file mode 100644 index 00000000000..89729fa06c1 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/013/output/PistController.map @@ -0,0 +1,58 @@ +{ + "mappings": "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", + "names": [ + "Body", + "Controller", + "Delete", + "Get", + "Param", + "Post", + "Put", + "UseGuards", + "UseInterceptors", + "POST_CONTROLLER_ROUTE", + "POST_DELETE_ENDPOINT", + "POST_GET_ALL_ENDPOINT", + "POST_GET_ENDPOINT", + "POST_CREATE_COMMENT_ENDPOINT", + "POST_CREATE_ENDPOINT", + "POST_UPDATE_ENDPOINT", + "MongooseClassSerializerInterceptor", + "PostType", + "PostService", + "CreatePostDto", + "JwtAuthGuard", + "User", + "UserType", + "CreateCommentDto", + "CommentService", + "Comment", + "PostController", + "constructor", + "postService", + "commentService", + "getPosts", + "getAll", + "getPost", + "id", + "getById", + "createPost", + "createPostDto", + "user", + "create", + "updatePost", + "updatePostDto", + "update", + "deletePost", + "delete", + "createPostComment", + "createCommentDto" + ], + "sources": [ + "../../input/PistController.ts" + ], + "sourcesContent": [ + "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Put,\n UseGuards,\n UseInterceptors,\n} from '@nestjs/common';\n\nimport {\n POST_CONTROLLER_ROUTE,\n POST_DELETE_ENDPOINT,\n POST_GET_ALL_ENDPOINT,\n POST_GET_ENDPOINT,\n POST_CREATE_COMMENT_ENDPOINT,\n POST_CREATE_ENDPOINT,\n POST_UPDATE_ENDPOINT,\n} from '@server/constants/controllers';\nimport { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor';\nimport { Post as PostType } from '@server/post/schemas/PostSchema';\nimport { PostService } from '@server/post/PostService';\nimport { CreatePostDto } from '@server/post/dto/CreatePostDto';\nimport { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard';\nimport { User } from '@server/decorators/UserDecorator';\nimport { User as UserType } from '@server/user/schemas/UserSchema';\nimport { CreateCommentDto } from '@server/comment/dto/CreateCommentDto';\nimport { CommentService } from '@server/comment/CommentService';\nimport { Comment } from '@server/comment/schemas/CommentSchema';\n\n@Controller(POST_CONTROLLER_ROUTE)\n@UseInterceptors(MongooseClassSerializerInterceptor(PostType))\nexport class PostController {\n constructor(private postService: PostService, private commentService: CommentService) { }\n\n @Get(POST_GET_ALL_ENDPOINT)\n public getPosts() {\n return this.postService.getAll();\n }\n\n @Get(POST_GET_ENDPOINT)\n public getPost(@Param('id') id: string) {\n return this.postService.getById(id);\n }\n\n @UseGuards(JwtAuthGuard)\n @Post(POST_CREATE_ENDPOINT)\n public createPost(@Body() createPostDto: CreatePostDto, @User() user: UserType) {\n return this.postService.create(createPostDto, user.id);\n }\n\n @UseGuards(JwtAuthGuard)\n @Put(POST_UPDATE_ENDPOINT)\n public updatePost(\n @Param('id') id: string,\n @Body() updatePostDto: CreatePostDto,\n @User() user: UserType,\n ) {\n return this.postService.update(id, updatePostDto, user.id);\n }\n\n @UseGuards(JwtAuthGuard)\n @Delete(POST_DELETE_ENDPOINT)\n public deletePost(@Param('id') id: string, @User() user: UserType) {\n return this.postService.delete(id, user.id);\n }\n\n @UseInterceptors(MongooseClassSerializerInterceptor(Comment))\n @UseGuards(JwtAuthGuard)\n @Post(POST_CREATE_COMMENT_ENDPOINT)\n public createPostComment(\n @Param('id') id: string,\n @Body() createCommentDto: CreateCommentDto,\n @User() user: UserType,\n ) {\n return this.commentService.create(createCommentDto, id, user.id);\n }\n}\n" + ], + "version": 3 +} diff --git a/crates/swc/tests/fixture/sourcemap/013/output/PistController.ts b/crates/swc/tests/fixture/sourcemap/013/output/PistController.ts new file mode 100644 index 00000000000..20a4485865a --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/013/output/PistController.ts @@ -0,0 +1,110 @@ +import _ts_decorate from "@swc/helpers/src/_ts_decorate.mjs"; +import _ts_metadata from "@swc/helpers/src/_ts_metadata.mjs"; +import _ts_param from "@swc/helpers/src/_ts_param.mjs"; +import { Body, Controller, Delete, Get, Param, Post, Put, UseGuards, UseInterceptors } from '@nestjs/common'; +import { POST_CONTROLLER_ROUTE, POST_DELETE_ENDPOINT, POST_GET_ALL_ENDPOINT, POST_GET_ENDPOINT, POST_CREATE_COMMENT_ENDPOINT, POST_CREATE_ENDPOINT, POST_UPDATE_ENDPOINT } from '@server/constants/controllers'; +import { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor'; +import { Post as PostType } from '@server/post/schemas/PostSchema'; +import { PostService } from '@server/post/PostService'; +import { CreatePostDto } from '@server/post/dto/CreatePostDto'; +import { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard'; +import { User } from '@server/decorators/UserDecorator'; +import { User as UserType } from '@server/user/schemas/UserSchema'; +import { CreateCommentDto } from '@server/comment/dto/CreateCommentDto'; +import { CommentService } from '@server/comment/CommentService'; +import { Comment } from '@server/comment/schemas/CommentSchema'; +export let PostController = class PostController { + constructor(postService, commentService){ + this.postService = postService; + this.commentService = commentService; + } + getPosts() { + return this.postService.getAll(); + } + getPost(id) { + return this.postService.getById(id); + } + createPost(createPostDto, user) { + return this.postService.create(createPostDto, user.id); + } + updatePost(id, updatePostDto, user) { + return this.postService.update(id, updatePostDto, user.id); + } + deletePost(id, user) { + return this.postService.delete(id, user.id); + } + createPostComment(id, createCommentDto, user) { + return this.commentService.create(createCommentDto, id, user.id); + } +}; +_ts_decorate([ + Get(POST_GET_ALL_ENDPOINT), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", []) +], PostController.prototype, "getPosts", null); +_ts_decorate([ + Get(POST_GET_ENDPOINT), + _ts_param(0, Param('id')), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String + ]) +], PostController.prototype, "getPost", null); +_ts_decorate([ + UseGuards(JwtAuthGuard), + Post(POST_CREATE_ENDPOINT), + _ts_param(0, Body()), + _ts_param(1, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + typeof CreatePostDto === "undefined" ? Object : CreatePostDto, + typeof UserType === "undefined" ? Object : UserType + ]) +], PostController.prototype, "createPost", null); +_ts_decorate([ + UseGuards(JwtAuthGuard), + Put(POST_UPDATE_ENDPOINT), + _ts_param(0, Param('id')), + _ts_param(1, Body()), + _ts_param(2, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String, + typeof CreatePostDto === "undefined" ? Object : CreatePostDto, + typeof UserType === "undefined" ? Object : UserType + ]) +], PostController.prototype, "updatePost", null); +_ts_decorate([ + UseGuards(JwtAuthGuard), + Delete(POST_DELETE_ENDPOINT), + _ts_param(0, Param('id')), + _ts_param(1, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String, + typeof UserType === "undefined" ? Object : UserType + ]) +], PostController.prototype, "deletePost", null); +_ts_decorate([ + UseInterceptors(MongooseClassSerializerInterceptor(Comment)), + UseGuards(JwtAuthGuard), + Post(POST_CREATE_COMMENT_ENDPOINT), + _ts_param(0, Param('id')), + _ts_param(1, Body()), + _ts_param(2, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String, + typeof CreateCommentDto === "undefined" ? Object : CreateCommentDto, + typeof UserType === "undefined" ? Object : UserType + ]) +], PostController.prototype, "createPostComment", null); +PostController = _ts_decorate([ + Controller(POST_CONTROLLER_ROUTE), + UseInterceptors(MongooseClassSerializerInterceptor(PostType)), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + typeof PostService === "undefined" ? Object : PostService, + typeof CommentService === "undefined" ? Object : CommentService + ]) +], PostController); diff --git a/crates/swc/tests/fixture/sourcemap/014/input/.swcrc b/crates/swc/tests/fixture/sourcemap/014/input/.swcrc new file mode 100644 index 00000000000..44899292f8e --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/014/input/.swcrc @@ -0,0 +1,16 @@ +{ + "sourceMaps": true, + "jsc": { + "target": "es2022", + "parser": { + "syntax": "typescript", + "tsx": true, + "decorators": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "keepClassNames": true + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/sourcemap/014/input/UserController.ts b/crates/swc/tests/fixture/sourcemap/014/input/UserController.ts new file mode 100644 index 00000000000..b726947cb83 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/014/input/UserController.ts @@ -0,0 +1,48 @@ +import { + Controller, + Post, + UseGuards, + Body, + Put, + Param, + ForbiddenException, + UseInterceptors, +} from '@nestjs/common'; + +import { + USER_CONTROLLER_ROUTE, + USER_CREATE_ENDPOINT, + USER_UPDATE_ENDPOINT, +} from '@server/constants/controllers'; +import { CreateUserDto } from '@server/user/dto/CreateUserDto'; +import { UpdateUserDto } from '@server/user/dto/UpdateUserDto'; +import { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard'; +import { User } from '@server/decorators/UserDecorator'; +import { User as UserType } from '@server/user/schemas/UserSchema'; +import { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor'; +import { UserService } from '@server/user/UserService'; + +@Controller(USER_CONTROLLER_ROUTE) +@UseInterceptors(MongooseClassSerializerInterceptor(UserType)) +export class UserController { + constructor(private userService: UserService) { } + + @Post(USER_CREATE_ENDPOINT) + async signup(@Body() createUserDto: CreateUserDto) { + return this.userService.create(createUserDto); + } + + @UseGuards(JwtAuthGuard) + @Put(USER_UPDATE_ENDPOINT) + async update( + @Param('id') userId: string, + @Body() updateUserDto: UpdateUserDto, + @User() user: UserType, + ) { + if (user.id !== userId) { + throw new ForbiddenException(); + } + + return this.userService.update(userId, updateUserDto); + } +} diff --git a/crates/swc/tests/fixture/sourcemap/014/output/UserController.map b/crates/swc/tests/fixture/sourcemap/014/output/UserController.map new file mode 100644 index 00000000000..2319d96de07 --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/014/output/UserController.map @@ -0,0 +1,41 @@ +{ + "mappings": "AAAA;;;AAAA,SACIA,UAAU,EACVC,IAAI,EACJC,SAAS,EACTC,IAAI,EACJC,GAAG,EACHC,KAAK,EACLC,kBAAkB,EAClBC,eAAe,QACZ,gBAAgB,CAAC;AAExB,SACIC,qBAAqB,EACrBC,oBAAoB,EACpBC,oBAAoB,QACjB,+BAA+B,CAAC;AACvC,SAASC,aAAa,QAAQ,gCAAgC,CAAC;AAC/D,SAASC,aAAa,QAAQ,gCAAgC,CAAC;AAC/D,SAASC,YAAY,QAAQ,kCAAkC,CAAC;AAChE,SAASC,IAAI,QAAQ,kCAAkC,CAAC;AACxD,SAASA,IAAI,IAAIC,QAAQ,QAAQ,iCAAiC,CAAC;AACnE,SAASC,kCAAkC,QAAQ,yDAAyD,CAAC;AAC7G,SAASC,WAAW,QAAQ,0BAA0B,CAAC;AAIvD,WAAaC,cAAc,GAApB;IACHC,YAAoBC,WAAwB,CAAE;QAA1BA,mBAAAA,WAAwB,CAAA;KAAK;UAG3CC,MAAM,CAAC,AAAQC,aAA4B,EAAE;QAC/C,OAAO,IAAI,CAACF,WAAW,CAACG,MAAM,CAACD,aAAa,CAAC,CAAC;KACjD;UAIKE,MAAM,CACR,AAAaC,MAAc,EAC3B,AAAQC,aAA4B,EACpC,AAAQC,IAAc,EACxB;QACE,IAAIA,IAAI,CAACC,EAAE,KAAKH,MAAM,EAAE;YACpB,MAAM,IAAInB,kBAAkB,EAAE,CAAC;SAClC;QAED,OAAO,IAAI,CAACc,WAAW,CAACI,MAAM,CAACC,MAAM,EAAEC,aAAa,CAAC,CAAC;KACzD;CACJ,CAAA;;IAlBIzB,IAAI,CAACQ,oBAAoB,CAAC;IACbN,aAAAA,IAAI,EAAE,CAAA;;;eAAgB,aAAa,4BAAb,aAAa;;GAJxCe,cAAc;;IAQtBhB,SAAS,CAACW,YAAY,CAAC;IACvBT,GAAG,CAACM,oBAAoB,CAAC;IAErBL,aAAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IACXF,aAAAA,IAAI,EAAE,CAAA;IACNW,aAAAA,IAAI,EAAE,CAAA;;;;eADgB,aAAa,4BAAb,aAAa;eACtB,QAAQ,4BAAR,QAAQ;;GAbjBI,cAAc;AAAdA,cAAc;IAF1BlB,UAAU,CAACQ,qBAAqB,CAAC;IACjCD,eAAe,CAACS,kCAAkC,CAACD,QAAQ,CAAC,CAAC;;;eAEzB,WAAW,4BAAX,WAAW;;GADnCG,cAAc", + "names": [ + "Controller", + "Post", + "UseGuards", + "Body", + "Put", + "Param", + "ForbiddenException", + "UseInterceptors", + "USER_CONTROLLER_ROUTE", + "USER_CREATE_ENDPOINT", + "USER_UPDATE_ENDPOINT", + "CreateUserDto", + "UpdateUserDto", + "JwtAuthGuard", + "User", + "UserType", + "MongooseClassSerializerInterceptor", + "UserService", + "UserController", + "constructor", + "userService", + "signup", + "createUserDto", + "create", + "update", + "userId", + "updateUserDto", + "user", + "id" + ], + "sources": [ + "../../input/UserController.ts" + ], + "sourcesContent": [ + "import {\n Controller,\n Post,\n UseGuards,\n Body,\n Put,\n Param,\n ForbiddenException,\n UseInterceptors,\n} from '@nestjs/common';\n\nimport {\n USER_CONTROLLER_ROUTE,\n USER_CREATE_ENDPOINT,\n USER_UPDATE_ENDPOINT,\n} from '@server/constants/controllers';\nimport { CreateUserDto } from '@server/user/dto/CreateUserDto';\nimport { UpdateUserDto } from '@server/user/dto/UpdateUserDto';\nimport { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard';\nimport { User } from '@server/decorators/UserDecorator';\nimport { User as UserType } from '@server/user/schemas/UserSchema';\nimport { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor';\nimport { UserService } from '@server/user/UserService';\n\n@Controller(USER_CONTROLLER_ROUTE)\n@UseInterceptors(MongooseClassSerializerInterceptor(UserType))\nexport class UserController {\n constructor(private userService: UserService) { }\n\n @Post(USER_CREATE_ENDPOINT)\n async signup(@Body() createUserDto: CreateUserDto) {\n return this.userService.create(createUserDto);\n }\n\n @UseGuards(JwtAuthGuard)\n @Put(USER_UPDATE_ENDPOINT)\n async update(\n @Param('id') userId: string,\n @Body() updateUserDto: UpdateUserDto,\n @User() user: UserType,\n ) {\n if (user.id !== userId) {\n throw new ForbiddenException();\n }\n\n return this.userService.update(userId, updateUserDto);\n }\n}\n" + ], + "version": 3 +} diff --git a/crates/swc/tests/fixture/sourcemap/014/output/UserController.ts b/crates/swc/tests/fixture/sourcemap/014/output/UserController.ts new file mode 100644 index 00000000000..38e1e34f9de --- /dev/null +++ b/crates/swc/tests/fixture/sourcemap/014/output/UserController.ts @@ -0,0 +1,55 @@ +import _ts_decorate from "@swc/helpers/src/_ts_decorate.mjs"; +import _ts_metadata from "@swc/helpers/src/_ts_metadata.mjs"; +import _ts_param from "@swc/helpers/src/_ts_param.mjs"; +import { Controller, Post, UseGuards, Body, Put, Param, ForbiddenException, UseInterceptors } from '@nestjs/common'; +import { USER_CONTROLLER_ROUTE, USER_CREATE_ENDPOINT, USER_UPDATE_ENDPOINT } from '@server/constants/controllers'; +import { CreateUserDto } from '@server/user/dto/CreateUserDto'; +import { UpdateUserDto } from '@server/user/dto/UpdateUserDto'; +import { JwtAuthGuard } from '@server/auth/guards/JwtAuthGuard'; +import { User } from '@server/decorators/UserDecorator'; +import { User as UserType } from '@server/user/schemas/UserSchema'; +import { MongooseClassSerializerInterceptor } from '@server/interceptors/MongooseClassSerializerInterceptor'; +import { UserService } from '@server/user/UserService'; +export let UserController = class UserController { + constructor(userService){ + this.userService = userService; + } + async signup(createUserDto) { + return this.userService.create(createUserDto); + } + async update(userId, updateUserDto, user) { + if (user.id !== userId) { + throw new ForbiddenException(); + } + return this.userService.update(userId, updateUserDto); + } +}; +_ts_decorate([ + Post(USER_CREATE_ENDPOINT), + _ts_param(0, Body()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + typeof CreateUserDto === "undefined" ? Object : CreateUserDto + ]) +], UserController.prototype, "signup", null); +_ts_decorate([ + UseGuards(JwtAuthGuard), + Put(USER_UPDATE_ENDPOINT), + _ts_param(0, Param('id')), + _ts_param(1, Body()), + _ts_param(2, User()), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + String, + typeof UpdateUserDto === "undefined" ? Object : UpdateUserDto, + typeof UserType === "undefined" ? Object : UserType + ]) +], UserController.prototype, "update", null); +UserController = _ts_decorate([ + Controller(USER_CONTROLLER_ROUTE), + UseInterceptors(MongooseClassSerializerInterceptor(UserType)), + _ts_metadata("design:type", Function), + _ts_metadata("design:paramtypes", [ + typeof UserService === "undefined" ? Object : UserService + ]) +], UserController); diff --git a/crates/swc_ecma_ast/src/ident.rs b/crates/swc_ecma_ast/src/ident.rs index 42f7ff98c5b..96949056fbc 100644 --- a/crates/swc_ecma_ast/src/ident.rs +++ b/crates/swc_ecma_ast/src/ident.rs @@ -4,7 +4,7 @@ use scoped_tls::scoped_thread_local; use serde::{Deserialize, Serialize}; use swc_atoms::{js_word, JsWord}; use swc_common::{ - ast_node, util::take::Take, EqIgnoreSpan, Span, Spanned, SyntaxContext, DUMMY_SP, + ast_node, util::take::Take, BytePos, EqIgnoreSpan, Span, Spanned, SyntaxContext, DUMMY_SP, }; use unicode_id::UnicodeID; @@ -156,6 +156,13 @@ impl Ident { EQ_IGNORE_SPAN_IGNORE_CTXT.set(&(), op) } + /// Preserve syntax context while drop `span.lo` and `span.hi`. + pub fn without_loc(mut self) -> Ident { + self.span.lo = BytePos::DUMMY; + self.span.hi = BytePos::DUMMY; + self + } + /// Creates `Id` using `JsWord` and `SyntaxContext` of `self`. pub fn to_id(&self) -> Id { (self.sym.clone(), self.span.ctxt) diff --git a/crates/swc_ecma_codegen/src/lib.rs b/crates/swc_ecma_codegen/src/lib.rs index 337104d7c29..0a74a8f6d21 100644 --- a/crates/swc_ecma_codegen/src/lib.rs +++ b/crates/swc_ecma_codegen/src/lib.rs @@ -1293,7 +1293,7 @@ where fn emit_class_method(&mut self, n: &ClassMethod) -> Result { self.emit_leading_comments_of_span(n.span(), false)?; - srcmap!(n, true); + // srcmap!(n, true); for d in &n.function.decorators { emit!(d); @@ -1370,6 +1370,7 @@ where Some(&n.function.params), ListFormat::CommaListElements, )?; + punct!(")"); if let Some(ty) = &n.function.return_type { diff --git a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs index bf40f0ebae3..8a4358890d0 100644 --- a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs +++ b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs @@ -62,7 +62,7 @@ impl ParamMetadata { Decorator { span: DUMMY_SP, expr: Box::new(Expr::Call(CallExpr { - span: DUMMY_SP, + span: decorator_expr.span(), callee: helper!(ts, ts_param, "__param"), args: vec![param_index.as_arg(), decorator_expr.as_arg()], type_args: Default::default(), diff --git a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs index e22f44d3c3f..2cb1341d85d 100644 --- a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs +++ b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs @@ -122,6 +122,13 @@ impl TscDecorator { return Expr::Ident(var_name); } + PropName::Ident(i) => { + return Expr::Lit(Lit::Str(Str { + span: DUMMY_SP, + raw: None, + value: i.sym.clone(), + })) + } _ => {} } diff --git a/crates/swc_ecma_transforms_typescript/src/strip.rs b/crates/swc_ecma_transforms_typescript/src/strip.rs index 6281c088eb1..b3c43c619d4 100644 --- a/crates/swc_ecma_transforms_typescript/src/strip.rs +++ b/crates/swc_ecma_transforms_typescript/src/strip.rs @@ -1802,9 +1802,10 @@ where extra_props.push(ident.id.clone()); } let assign_expr = Box::new(Expr::Assign(AssignExpr { - span: DUMMY_SP, + span: ident.span.with_ctxt(SyntaxContext::empty()), left: PatOrExpr::Expr(Box::new( - ThisExpr { span: DUMMY_SP }.make_member(ident.id.clone()), + ThisExpr { span: DUMMY_SP } + .make_member(ident.id.clone().without_loc()), )), op: op!("="), right: Box::new(Expr::Ident(ident.id)),