├── .editorconfig
├── .eslintrc.json
├── .gitignore
├── .prettierrc
├── CHANGELOG.md
├── README.md
├── commitlint.config.js
├── package-lock.json
├── package.json
├── src
├── aws.module.ts
├── constants.ts
├── index.ts
├── interfaces
│ ├── IFile.ts
│ ├── aws-s3-module-options.interface.ts
│ ├── aws-ses-module-options.interface.ts
│ ├── aws-sns-module-options.interface.ts
│ └── s3-get-signed-url-request.interface.ts
└── service
│ ├── aws-logger.service.ts
│ ├── aws.s3.service.ts
│ ├── aws.ses.service.ts
│ ├── aws.sns.service.ts
│ └── generator.service.ts
├── test
├── app.e2e-spec.ts
└── jest-e2e.json
├── tsconfig.build.json
├── tsconfig.json
└── tslint.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 4
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | [{src, scripts}/**.{ts, json, js}]
11 | end_of_line = lf
12 |
13 | [*.yml]
14 | indent_size = 2
15 |
16 | [*.md]
17 | max_line_length = off
18 | trim_trailing_whitespace = false
19 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@typescript-eslint/tslint",
4 | "eslint-plugin-import-helpers"
5 | ],
6 | "parser": "@typescript-eslint/parser",
7 | "parserOptions": {
8 | "ecmaVersion": 2017,
9 | "ecmaFeatures": {
10 | "modules": true
11 | },
12 | "sourceType": "module",
13 | "project": "tsconfig.json"
14 | },
15 | "rules": {
16 | "@typescript-eslint/tslint/config": [
17 | "error",
18 | {
19 | "lintFile": "./tslint.json"
20 | }
21 | ],
22 | "import-helpers/order-imports": [
23 | "error",
24 | {
25 | // example configuration
26 | "newlinesBetween": "always",
27 | "groups": [
28 | "module",
29 | "/^@shared/",
30 | [
31 | "parent",
32 | "sibling",
33 | "index"
34 | ]
35 | ],
36 | "alphabetize": {
37 | "order": "asc",
38 | "ignoreCase": true
39 | }
40 | }
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### JetBrains template
3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
5 |
6 | # User-specific stuff:
7 | .idea/**/workspace.xml
8 | .idea/**/tasks.xml
9 | .idea/dictionaries
10 |
11 | # Sensitive or high-churn files:
12 | .idea/**/dataSources/
13 | .idea/**/dataSources.ids
14 | .idea/**/dataSources.xml
15 | .idea/**/dataSources.local.xml
16 | .idea/**/sqlDataSources.xml
17 | .idea/**/dynamic.xml
18 | .idea/**/uiDesigner.xml
19 | .directory
20 |
21 | # Gradle:
22 | .idea/**/gradle.xml
23 | .idea/**/libraries
24 |
25 | # CMake
26 | cmake-build-debug/
27 |
28 | # Mongo Explorer plugin:
29 | .idea/**/mongoSettings.xml
30 |
31 | ## File-based project format:
32 | *.iws
33 |
34 | ## Plugin-specific files:
35 |
36 | # IntelliJ
37 | out/
38 |
39 | # mpeltonen/sbt-idea plugin
40 | .idea_modules/
41 |
42 | # JIRA plugin
43 | atlassian-ide-plugin.xml
44 |
45 | # Cursive Clojure plugin
46 | .idea/replstate.xml
47 |
48 | # Crashlytics plugin (for Android Studio and IntelliJ)
49 | com_crashlytics_export_strings.xml
50 | crashlytics.properties
51 | crashlytics-build.properties
52 | fabric.properties
53 | ### VisualStudio template
54 | ## Ignore Visual Studio temporary files, build results, and
55 | ## files generated by popular Visual Studio add-ons.
56 | ##
57 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
58 |
59 | # User-specific files
60 | *.suo
61 | *.user
62 | *.userosscache
63 | *.sln.docstates
64 |
65 | # User-specific files (MonoDevelop/Xamarin Studio)
66 | *.userprefs
67 |
68 | # Build results
69 | [Dd]ebug/
70 | [Dd]ebugPublic/
71 | [Rr]elease/
72 | [Rr]eleases/
73 | x64/
74 | x86/
75 | bld/
76 | [Bb]in/
77 | [Oo]bj/
78 | [Ll]og/
79 |
80 | # Visual Studio 2015 cache/options directory
81 | .vs/
82 | # Visual Code cache/options directory
83 | .vscode/
84 | # Uncomment if you have tasks that create the project's static files in wwwroot
85 | #wwwroot/
86 |
87 | # MSTest test Results
88 | [Tt]est[Rr]esult*/
89 | [Bb]uild[Ll]og.*
90 |
91 | # NUNIT
92 | *.VisualState.xml
93 | TestResult.xml
94 |
95 | # Build Results of an ATL Project
96 | [Dd]ebugPS/
97 | [Rr]eleasePS/
98 | dlldata.c
99 |
100 | # Benchmark Results
101 | BenchmarkDotNet.Artifacts/
102 |
103 | # .NET Core
104 | project.lock.json
105 | project.fragment.lock.json
106 | artifacts/
107 | **/Properties/launchSettings.json
108 |
109 | *_i.c
110 | *_p.c
111 | *_i.h
112 | *.ilk
113 | *.meta
114 | *.obj
115 | *.pch
116 | *.pdb
117 | *.pgc
118 | *.pgd
119 | *.rsp
120 | *.sbr
121 | *.tlb
122 | *.tli
123 | *.tlh
124 | *.tmp
125 | *.tmp_proj
126 | *.log
127 | *.vspscc
128 | *.vssscc
129 | .builds
130 | *.pidb
131 | *.svclog
132 | *.scc
133 |
134 | # Chutzpah Test files
135 | _Chutzpah*
136 |
137 | # Visual C++ cache files
138 | ipch/
139 | *.aps
140 | *.ncb
141 | *.opendb
142 | *.opensdf
143 | *.sdf
144 | *.cachefile
145 | *.VC.db
146 | *.VC.VC.opendb
147 |
148 | # Visual Studio profiler
149 | *.psess
150 | *.vsp
151 | *.vspx
152 | *.sap
153 |
154 | # Visual Studio Trace Files
155 | *.e2e
156 |
157 | # TFS 2012 Local Workspace
158 | $tf/
159 |
160 | # Guidance Automation Toolkit
161 | *.gpState
162 |
163 | # ReSharper is a .NET coding add-in
164 | _ReSharper*/
165 | *.[Rr]e[Ss]harper
166 | *.DotSettings.user
167 |
168 | # JustCode is a .NET coding add-in
169 | .JustCode
170 |
171 | # TeamCity is a build add-in
172 | _TeamCity*
173 |
174 | # DotCover is a Code Coverage Tool
175 | *.dotCover
176 |
177 | # AxoCover is a Code Coverage Tool
178 | .axoCover/*
179 | !.axoCover/settings.json
180 |
181 | # Visual Studio code coverage results
182 | *.coverage
183 | *.coveragexml
184 |
185 | # NCrunch
186 | _NCrunch_*
187 | .*crunch*.local.xml
188 | nCrunchTemp_*
189 |
190 | # MightyMoose
191 | *.mm.*
192 | AutoTest.Net/
193 |
194 | # Web workbench (sass)
195 | .sass-cache/
196 |
197 | # Installshield output folder
198 | [Ee]xpress/
199 |
200 | # DocProject is a documentation generator add-in
201 | DocProject/buildhelp/
202 | DocProject/Help/*.HxT
203 | DocProject/Help/*.HxC
204 | DocProject/Help/*.hhc
205 | DocProject/Help/*.hhk
206 | DocProject/Help/*.hhp
207 | DocProject/Help/Html2
208 | DocProject/Help/html
209 |
210 | # Click-Once directory
211 | publish/
212 |
213 | # Publish Web Output
214 | *.[Pp]ublish.xml
215 | *.azurePubxml
216 | # Note: Comment the next line if you want to checkin your web deploy settings,
217 | # but database connection strings (with potential passwords) will be unencrypted
218 | *.pubxml
219 | *.publishproj
220 |
221 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
222 | # checkin your Azure Web App publish settings, but sensitive information contained
223 | # in these scripts will be unencrypted
224 | PublishScripts/
225 |
226 | # NuGet Packages
227 | *.nupkg
228 | # The packages folder can be ignored because of Package Restore
229 | **/[Pp]ackages/*
230 | # except build/, which is used as an MSBuild target.
231 | !**/[Pp]ackages/build/
232 | # Uncomment if necessary however generally it will be regenerated when needed
233 | #!**/[Pp]ackages/repositories.config
234 | # NuGet v3's project.json files produces more ignorable files
235 | *.nuget.props
236 | *.nuget.targets
237 |
238 | # Microsoft Azure Build Output
239 | csx/
240 | *.build.csdef
241 |
242 | # Microsoft Azure Emulator
243 | ecf/
244 | rcf/
245 |
246 | # Windows Store app package directories and files
247 | AppPackages/
248 | BundleArtifacts/
249 | Package.StoreAssociation.xml
250 | _pkginfo.txt
251 | *.appx
252 |
253 | # Visual Studio cache files
254 | # files ending in .cache can be ignored
255 | *.[Cc]ache
256 | # but keep track of directories ending in .cache
257 | !*.[Cc]ache/
258 |
259 | # Others
260 | ClientBin/
261 | ~$*
262 | *~
263 | *.dbmdl
264 | *.dbproj.schemaview
265 | *.jfm
266 | *.pfx
267 | *.publishsettings
268 | orleans.codegen.cs
269 |
270 | # Since there are multiple workflows, uncomment next line to ignore bower_components
271 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
272 | #bower_components/
273 |
274 | # RIA/Silverlight projects
275 | Generated_Code/
276 |
277 | # Backup & report files from converting an old project file
278 | # to a newer Visual Studio version. Backup files are not needed,
279 | # because we have git ;-)
280 | _UpgradeReport_Files/
281 | Backup*/
282 | UpgradeLog*.XML
283 | UpgradeLog*.htm
284 |
285 | # SQL Server files
286 | *.mdf
287 | *.ldf
288 | *.ndf
289 |
290 | # Business Intelligence projects
291 | *.rdl.data
292 | *.bim.layout
293 | *.bim_*.settings
294 |
295 | # Microsoft Fakes
296 | FakesAssemblies/
297 |
298 | # GhostDoc plugin setting file
299 | *.GhostDoc.xml
300 |
301 | # Node.js Tools for Visual Studio
302 | .ntvs_analysis.dat
303 | node_modules/
304 |
305 | # Typescript v1 declaration files
306 | typings/
307 |
308 | # Visual Studio 6 build log
309 | *.plg
310 |
311 | # Visual Studio 6 workspace options file
312 | *.opt
313 |
314 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
315 | *.vbw
316 |
317 | # Visual Studio LightSwitch build output
318 | **/*.HTMLClient/GeneratedArtifacts
319 | **/*.DesktopClient/GeneratedArtifacts
320 | **/*.DesktopClient/ModelManifest.xml
321 | **/*.Server/GeneratedArtifacts
322 | **/*.Server/ModelManifest.xml
323 | _Pvt_Extensions
324 |
325 | # Paket dependency manager
326 | .paket/paket.exe
327 | paket-files/
328 |
329 | # FAKE - F# Make
330 | .fake/
331 |
332 | # JetBrains Rider
333 | .idea/
334 | *.sln.iml
335 |
336 | # CodeRush
337 | .cr/
338 |
339 | # Python Tools for Visual Studio (PTVS)
340 | __pycache__/
341 | *.pyc
342 |
343 | # Cake - Uncomment if you are using it
344 | # tools/**
345 | # !tools/packages.config
346 |
347 | # Tabs Studio
348 | *.tss
349 |
350 | # Telerik's JustMock configuration file
351 | *.jmconfig
352 |
353 | # BizTalk build output
354 | *.btp.cs
355 | *.btm.cs
356 | *.odx.cs
357 | *.xsd.cs
358 |
359 | # OpenCover UI analysis results
360 | OpenCover/
361 | coverage/
362 |
363 | ### macOS template
364 | # General
365 | .DS_Store
366 | .AppleDouble
367 | .LSOverride
368 |
369 | # Icon must end with two \r
370 | Icon
371 |
372 | # Thumbnails
373 | ._*
374 |
375 | # Files that might appear in the root of a volume
376 | .DocumentRevisions-V100
377 | .fseventsd
378 | .Spotlight-V100
379 | .TemporaryItems
380 | .Trashes
381 | .VolumeIcon.icns
382 | .com.apple.timemachine.donotpresent
383 |
384 | # Directories potentially created on remote AFP share
385 | .AppleDB
386 | .AppleDesktop
387 | Network Trash Folder
388 | Temporary Items
389 | .apdisk
390 |
391 | =======
392 | # Local
393 | docker-compose.yml
394 | *.env
395 | dist
396 | logs
397 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.0 (2019-10-08)
2 |
3 |
4 | ### Bug Fixes
5 |
6 | * **build.sh:** data directory creation ([9d26d6f](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/9d26d6f))
7 | * **build.sh:** HOST environment variable ([6064305](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/6064305))
8 | * **build.sh:** installed and loaded node_module from local ([01030bd](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/01030bd))
9 | * **build.sh:** missing space typo ([dcc9ceb](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/dcc9ceb))
10 | * **build.sh:** persisted data in eventstore and mysql database ([0e7eed4](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/0e7eed4))
11 | * **dockerfile:** loaded node_modules from local ([0b36c5d](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/0b36c5d))
12 | * **Dockerfile:** loaded ormconfig.js ([2650f6b](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/2650f6b))
13 | * **envVar.sh:** HOST environment variable export ([b7c97c2](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/b7c97c2))
14 |
15 |
16 | ### Features
17 |
18 | * **cleanup.sh:** added script that cleans up environment ([3456484](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/3456484))
19 | * **commitlint config:** initiated commitlint configuration ([af81914](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/af81914))
20 | * **containers:** added adminer ([2634cc2](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/2634cc2))
21 | * **dockerfile:** prod dockerfile ([7416ea1](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/7416ea1))
22 | * **package-lock.json:** added dependencies for commit control ([0422d82](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/0422d82))
23 | * **package.json:** added commit control using conventional comits spex ([533f916](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/533f916))
24 | * **symanticrelease:** symantic release configuration and script ([26aeec5](https://github.com/0xb4lamx/nestjs-boilerplate-microservice/commit/26aeec5))
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 | A MODULE FOR AWS SERVICES (sns,s3,ses)
10 |
11 |
17 |
18 | ### Installation
19 | ##### Installation missing dependencies (aws_sdk , nodeMailer)
20 | > npm install
21 |
22 | ### About AWS SERVICES
23 |
24 | This module is a thin layer on top of the [AWS_SERVICES API](https://aws.amazon.com/fr/#).
25 |
26 |
27 |
28 | ### Quick Start
29 |
30 | To configure your API connection, import the `AWS` module according to the service you want to use by using the appropriate method. For example to use the SMS Service you need to import the module `AWS` with the `forRootSnsAsync()` Method.Basically, you configure the module with a `AwsCredentialsConfigParams` object depending to te Service used. To see the documentation of Api AWS create an account on https://aws.amazon.com/fr/#.
31 |
32 | For example, your `AppModule` might look like this :
33 |
34 | ```typescript
35 |
36 | import { Module } from '@nestjs/common';
37 |
38 |
39 |
40 | @Module({
41 | imports: [
42 |
43 | AwsModule.forRootSnsAsync({
44 | useFactory: async () => {
45 | return {
46 |
47 | accessKeyId:'YOUR ACCESS KEY ID',
48 | secretAccessKey: 'YOUR SERCRET ACCESS KEY',
49 | region: 'REGION SERVICE',
50 |
51 | };
52 | },
53 | inject: [],
54 | }),
55 | controllers: [AppController],
56 | providers: [AppService],
57 |
58 |
59 | })
60 | export class AppModule { }
61 | ```
62 | Depending on which service you want to use you have access to the method of the requested service (SNS_SERVICE, S3_SERVICE,SES_SERVICE) which you can inject into any provider.
63 |
64 | HERE AN EXAMPLE OF AN SNS SERVICE :
65 | ```typescript
66 | import { Injectable, Inject, Logger, HttpStatus } from '@nestjs/common';
67 | import * as AWS from 'aws-sdk';
68 | import { CONFIG_CONNECTION_OPTIONS } from '../constants';
69 | import { ConfigurationOptions } from 'aws-sdk/lib/config';
70 | import { PublishResponse } from 'aws-sdk/clients/sns';
71 | /**
72 | * @export
73 | * @class AwsSnsService
74 | */
75 | @Injectable()
76 | export class AwsSnsService {
77 | private readonly _sns: AWS.SNS;
78 | private _smsOptions: AWS.SNS.PublishInput;
79 | constructor(
80 | @Inject(CONFIG_CONNECTION_OPTIONS) private _options: ConfigurationOptions,
81 | ) {
82 | Logger.log('initialising AWS Module', 'SNS SERVICE');
83 | AWS.config.update(this._options);
84 | this._sns = new AWS.SNS();
85 | }
86 |
87 | /**
88 | *
89 | * SNS AMAZON SEND SMS
90 | *
91 | * @param {string} mobileNumber
92 | * @param {string} messageToSend
93 | * @param {string} subjectOfSms
94 | * @memberof AwsSnsService
95 | */
96 | async sendSMS(
97 | mobileNumber: string,
98 | messageToSend: string,
99 | subjectOfSms: string,
100 | ) {
101 | this._smsOptions = {
102 | Message: messageToSend,
103 | Subject: subjectOfSms,
104 | PhoneNumber: mobileNumber,
105 | };
106 |
107 | return [
108 | await this._sns.publish(
109 | this._smsOptions).promise().then((info: PublishResponse) => {
110 | console.log('RESPONSE SMS DETAILS ====>', info);
111 | return [
112 | {
113 | success: HttpStatus.OK,
114 | message: 'SMS SUCCESSFULLY SENDED',
115 | data: info,
116 | },
117 | ];
118 | }).catch((err) => {
119 | console.log('ERROR : FAILD REQUEST !! ====>', err);
120 | return [
121 | {
122 | error: HttpStatus.EXPECTATION_FAILED,
123 | message: ['FAILD TO SEND SMS ', err],
124 | },
125 | ];
126 | }),
127 | ];
128 | }
129 | }
130 |
131 | ```
132 |
133 |
134 |
135 | ### To Do
136 |
137 | - [x] Tests
138 |
139 | ### Change Log
140 |
141 | See [Changelog](CHANGELOG.md) for more information.
142 |
143 | ### Author
144 |
145 | **ABBES Mohamed Amine**
146 |
147 | ### License
148 |
149 | Licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
150 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = { extends: ['@commitlint/config-conventional'] };
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nestjs-aws",
3 | "private": true,
4 | "version": "1.0.0",
5 | "description": "Nest TypeScript AWS Module repository",
6 | "author": "ABBES Mohamed Amine ",
7 | "license": "MIT",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/box2home/nestjs-aws"
11 | },
12 | "bugs": "https://github.com/box2home/nestjs-aws/issues",
13 | "main": "dist/index.js",
14 | "files": [
15 | "dist/**/*",
16 | "*.md"
17 | ],
18 | "scripts": {
19 | "release": "npx -p @semantic-release/changelog -p @semantic-release/git@beta -p semantic-release@beta semantic-release --no-ci",
20 | "commit": "npx git-cz",
21 | "start:dev": "tsc -w",
22 | "prebuild": "rm -rf dist",
23 | "build": "tsc -p tsconfig.json",
24 | "format": "prettier --write \"src/**/*.ts\"",
25 | "lint": "tslint -p tsconfig.json -c tslint.json",
26 | "test": "jest",
27 | "test:watch": "jest --watch",
28 | "test:cov": "jest --coverage",
29 | "test:e2e": "jest --config ./test/jest-e2e.json",
30 | "prepare": "npm run build"
31 | },
32 | "dependencies": {
33 | "@nestjs/common": "^7.6.13",
34 | "@nestjs/core": "^6.5.3",
35 | "aws-sdk": "^2.795.0",
36 | "class-transformer": "^0.3.1",
37 | "mime-types": "~2.1.24",
38 | "nodemailer": "^6.4.16",
39 | "pretty-error": "^2.1.1",
40 | "reflect-metadata": "~0.1.13",
41 | "rimraf": "2.6.3",
42 | "rxjs": "^6.5.2",
43 | "uuid": "^3.3.3",
44 | "xml2js": "^0.4.21"
45 | },
46 | "devDependencies": {
47 | "@commitlint/cli": "^12.0.1",
48 | "@commitlint/config-conventional": "^12.0.1",
49 | "@nestjs/testing": "^6.6.4",
50 | "@types/dotenv": "^6.1.1",
51 | "@types/express": "^4.17.0",
52 | "@types/express-rate-limit": "^3.3.0",
53 | "@types/jest": "^24.0.13",
54 | "@types/jquery": "^3.3.31",
55 | "@types/lodash": "^4.14.134",
56 | "@types/mime-types": "^2.1.0",
57 | "@types/morgan": "^1.7.35",
58 | "@types/node": "^12.0.7",
59 | "@types/nodemailer": "^6.2.2",
60 | "@types/supertest": "^2.0.7",
61 | "@types/uuid": "^3.4.4",
62 | "@typescript-eslint/eslint-plugin-tslint": "^1.11.0",
63 | "@typescript-eslint/parser": "^1.11.0",
64 | "cz-conventional-changelog": "^3.0.2",
65 | "eslint": "^6.0.1",
66 | "eslint-plugin-import-helpers": "^1.0.2",
67 | "husky": "^3.0.8",
68 | "jest": "^26.0.1",
69 | "lint-staged": "~8.2.0",
70 | "prettier": "^1.18.2",
71 | "supertest": "^4.0.2",
72 | "ts-jest": "^26.1.0",
73 | "ts-node": "^8.1.0",
74 | "tsc-watch": "^2.2.1",
75 | "tsconfig-paths": "^3.8.0",
76 | "tslint": "^5.17.0",
77 | "tslint-config-prettier": "~1.18.0",
78 | "tslint-consistent-codestyle": "^1.15.1",
79 | "tslint-eslint-rules": "^5.4.0",
80 | "tslint-plugin-prettier": "^2.0.1",
81 | "typescript": "^3.8.3"
82 | },
83 | "jest": {
84 | "moduleFileExtensions": [
85 | "js",
86 | "json",
87 | "ts"
88 | ],
89 | "rootDir": "src",
90 | "testRegex": ".spec.ts$",
91 | "transform": {
92 | "^.+\\.(t|j)s$": "ts-jest"
93 | },
94 | "collectCoverageFrom": [
95 | "**/*.(t|j)s"
96 | ],
97 | "coverageDirectory": "../coverage",
98 | "testEnvironment": "node"
99 | },
100 | "lint-staged": {
101 | "*.@(ts)": [
102 | "tslint --fix -p .",
103 | "git add"
104 | ]
105 | },
106 | "config": {
107 | "commitizen": {
108 | "path": "./node_modules/cz-conventional-changelog",
109 | "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true"
110 | }
111 | },
112 | "husky": {
113 | "hooks": {
114 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/aws.module.ts:
--------------------------------------------------------------------------------
1 | import { DynamicModule, Module } from '@nestjs/common';
2 |
3 | import { CONFIG_CONNECTION_OPTIONS } from './constants';
4 | import { IS3ModuleAsyncOptions } from './interfaces/aws-s3-module-options.interface';
5 | import { ISESModuleAsyncOptions } from './interfaces/aws-ses-module-options.interface';
6 | import { ISNSModuleAsyncOptions } from './interfaces/aws-sns-module-options.interface';
7 | import { AwsS3Service } from './service/aws.s3.service';
8 | import { AwsSesService } from './service/aws.ses.service';
9 | import { AwsSnsService } from './service/aws.sns.service';
10 | import { GeneratorService } from './service/generator.service';
11 |
12 | /**
13 | * @export
14 | * @class AwsModule
15 | */
16 | @Module({})
17 | export class AwsModule {
18 | static forRootSnsAsync(options: ISNSModuleAsyncOptions): DynamicModule {
19 | return {
20 | module: AwsModule,
21 | providers: [
22 | {
23 | provide: CONFIG_CONNECTION_OPTIONS,
24 | useFactory: options.useFactory,
25 | inject: options.inject || [],
26 | },
27 | AwsSnsService,
28 | ],
29 | exports: [AwsSnsService],
30 | };
31 | }
32 |
33 | static forRootSesAsync(options: ISESModuleAsyncOptions): DynamicModule {
34 | return {
35 | module: AwsModule,
36 | providers: [
37 | {
38 | provide: CONFIG_CONNECTION_OPTIONS,
39 | useFactory: options.useFactory,
40 | inject: options.inject || [],
41 | },
42 | AwsSesService,
43 | ],
44 | exports: [AwsSesService],
45 | };
46 | }
47 |
48 | static forRootS3Async(options: IS3ModuleAsyncOptions): DynamicModule {
49 | return {
50 | module: AwsModule,
51 | providers: [
52 | {
53 | provide: CONFIG_CONNECTION_OPTIONS,
54 | useFactory: options.useFactory,
55 | inject: options.inject || [],
56 | },
57 | AwsS3Service,
58 | GeneratorService,
59 | ],
60 | exports: [AwsS3Service, GeneratorService],
61 | };
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 | export const CONFIG_CONNECTION_OPTIONS = 'CONFIG_CONNECTION_OPTIONS';
2 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './constants';
2 | export * from './service/aws.s3.service';
3 | export * from './service/aws.ses.service';
4 | export * from './service/aws.sns.service';
5 | export * from './service/generator.service';
6 | export * from './aws.module';
7 | export * from './interfaces/IFile';
8 | export * from './interfaces/s3-get-signed-url-request.interface';
9 | export * from './interfaces/aws-ses-module-options.interface';
10 | export * from './interfaces/aws-s3-module-options.interface';
11 | export * from './interfaces/aws-sns-module-options.interface';
12 | export * from './service/aws-logger.service';
13 |
--------------------------------------------------------------------------------
/src/interfaces/IFile.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @export
5 | * @interface IFile
6 | */
7 | export interface IFile {
8 | encoding: string;
9 | buffer: Buffer;
10 | fieldname: string;
11 | mimetype: string;
12 | originalname: string;
13 | size: number;
14 | }
15 |
--------------------------------------------------------------------------------
/src/interfaces/aws-s3-module-options.interface.ts:
--------------------------------------------------------------------------------
1 | import { ModuleMetadata } from '@nestjs/common/interfaces';
2 | import { ConfigurationOptions } from 'aws-sdk';
3 |
4 | /**
5 | * @export
6 | * @interface IS3ModuleAsyncOptions
7 | * @extends {Pick}
8 | */
9 | export interface IS3ModuleAsyncOptions extends Pick {
10 | useFactory: (...args: any[]) => Promise | ConfigurationOptions;
11 | inject?: any[];
12 | }
13 |
--------------------------------------------------------------------------------
/src/interfaces/aws-ses-module-options.interface.ts:
--------------------------------------------------------------------------------
1 | import { ModuleMetadata } from '@nestjs/common/interfaces';
2 | import { Options } from 'nodemailer/lib/smtp-transport';
3 |
4 | export declare type SMTPTransportOptions = Options;
5 |
6 | /**
7 | * @export
8 | * @interface ISESModuleAsyncOptions
9 | * @extends {Pick}
10 | */
11 | export interface ISESModuleAsyncOptions extends Pick {
12 | useFactory: (...args: any[]) => Promise | SMTPTransportOptions;
13 | inject?: any[];
14 | }
15 |
--------------------------------------------------------------------------------
/src/interfaces/aws-sns-module-options.interface.ts:
--------------------------------------------------------------------------------
1 | import { ModuleMetadata } from '@nestjs/common/interfaces';
2 | import { ConfigurationOptions } from 'aws-sdk';
3 | /**
4 | * @export
5 | * @interface ISNSModuleAsyncOptions
6 | * @extends {Pick}
7 | */
8 | export interface ISNSModuleAsyncOptions extends Pick {
9 | useFactory: (...args: any[]) => Promise | ConfigurationOptions;
10 | inject?: any[];
11 | }
12 |
--------------------------------------------------------------------------------
/src/interfaces/s3-get-signed-url-request.interface.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @export
5 | * @interface IGetSignedUrlRequest
6 | */
7 | export interface IGetSignedUrlRequest {
8 | Bucket: string;
9 | Key: string;
10 | Expires?: number;
11 | }
12 |
--------------------------------------------------------------------------------
/src/service/aws-logger.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Logger } from '@nestjs/common';
2 |
3 | @Injectable()
4 | export class AwsLogger extends Logger {
5 | error(message: string, trace: any) {
6 | super.error(message, trace);
7 | }
8 |
9 | log(message: string, trace: string) {
10 | super.log(message, trace);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/service/aws.s3.service.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Injectable,
3 | Inject,
4 | Logger,
5 | HttpStatus,
6 | HttpException,
7 | } from '@nestjs/common';
8 | import * as AWS from 'aws-sdk';
9 | import {
10 | CopyObjectRequest,
11 | DeleteObjectRequest,
12 | ListObjectsRequest,
13 | } from 'aws-sdk/clients/s3';
14 |
15 | import { CONFIG_CONNECTION_OPTIONS } from '../constants';
16 | import { IGetSignedUrlRequest } from '../interfaces/s3-get-signed-url-request.interface';
17 |
18 | /**
19 | * @export
20 | * @class AwsS3Service
21 | */
22 | @Injectable()
23 | export class AwsS3Service {
24 | private readonly _s3: AWS.S3;
25 |
26 | constructor(
27 | @Inject(CONFIG_CONNECTION_OPTIONS)
28 | private _options: AWS.S3.Types.ClientConfiguration,
29 | ) {
30 | Logger.log('initialising Aws Module', 'AWS S3 SERVICE');
31 | this._s3 = new AWS.S3(_options);
32 | }
33 |
34 | async upload(params: AWS.S3.Types.PutObjectRequest) {
35 | return this._s3
36 | .putObject(params)
37 | .promise()
38 | .then((info: AWS.S3.Types.PutObjectOutput) => {
39 | Logger.log(`success[S3]: ${JSON.stringify(info)}`);
40 | return [
41 | {
42 | statusCode: HttpStatus.OK,
43 | message: 'success',
44 | data: {
45 | url: `https://${params.Bucket}.s3-${this._s3.config.region}.amazonaws.com/${params.Key}`,
46 | },
47 | },
48 | ];
49 | })
50 | .catch((err: AWS.AWSError) => {
51 | Logger.error(
52 | err.message,
53 | `success[S3]: ${JSON.stringify(err)}`,
54 | );
55 | throw new HttpException(
56 | {
57 | statusCode: err.statusCode,
58 | message: 'error',
59 | data: err,
60 | },
61 | HttpStatus.BAD_REQUEST,
62 | );
63 | });
64 | }
65 |
66 | async getObject(params: AWS.S3.Types.GetObjectAclRequest) {
67 | try {
68 | return this._s3
69 | .getObject(params)
70 | .promise()
71 | .then(fileData => {
72 | return fileData.Body.toString('utf-8');
73 | });
74 | } catch (error) {
75 | throw new HttpException(
76 | {
77 | statusCode: error.statusCode,
78 | message: 'error',
79 | data: error,
80 | },
81 | HttpStatus.BAD_REQUEST,
82 | );
83 | }
84 | }
85 |
86 | async getUploadSignedUrl(params: IGetSignedUrlRequest) {
87 | try {
88 | return this._s3
89 | .getSignedUrlPromise('putObject', {
90 | ...params,
91 | ACL: 'public-read',
92 | })
93 | .then((signedUrl: string) => {
94 | Logger.log(
95 | `signed url generated successfully: ${signedUrl}`,
96 | );
97 | return signedUrl;
98 | });
99 | } catch (err) {
100 | Logger.error(
101 | err.message,
102 | `unable to generate the signed url: ${JSON.stringify(err)}`,
103 | );
104 | throw new HttpException(err.message, HttpStatus.BAD_REQUEST);
105 | }
106 | }
107 |
108 | async copyObject(params: CopyObjectRequest) {
109 | try {
110 | return this._s3.copyObject(params, async function(err, data) {
111 | if (err) Logger.log(err, err.stack);
112 | // an error occurred
113 | else {
114 | Logger.log(data);
115 | return data;
116 | } // successful response
117 | });
118 | } catch (err) {
119 | Logger.error(
120 | err.message,
121 | `unable to copy object: ${JSON.stringify(err)}`,
122 | );
123 | throw new HttpException(err.message, HttpStatus.BAD_REQUEST);
124 | }
125 | }
126 |
127 | async deleteObject(params: DeleteObjectRequest) {
128 | try {
129 | return this._s3.deleteObject(params).promise();
130 | } catch (err) {
131 | Logger.error(
132 | err.message,
133 | `unable to delete object: ${JSON.stringify(err)}`,
134 | );
135 | throw new HttpException(err.message, HttpStatus.BAD_REQUEST);
136 | }
137 | }
138 |
139 | async listObjects(params: ListObjectsRequest) {
140 | try {
141 | return this._s3.listObjects(params).promise();
142 | } catch (err) {
143 | Logger.error(err.message, `unable to ${JSON.stringify(err)}`);
144 | throw new HttpException(err.message, HttpStatus.BAD_REQUEST);
145 | }
146 | }
147 |
148 | async checkExistenceFileFromBucket(params: AWS.S3.Types.HeadObjectRequest) {
149 | try {
150 | // Check if the object exists
151 | const signedUrl = await this._s3.headObject(params).promise();
152 |
153 | return signedUrl ? true: false
154 | } catch (err) {
155 | // Log the error and throw an exception
156 | console.error('Error checking object existence:', err.message);
157 | Logger.error(err.message, `Unable to ${JSON.stringify(err)}`);
158 | return false
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/service/aws.ses.service.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import { HttpStatus, HttpException, Inject, Injectable, Logger } from '@nestjs/common';
3 | import { createTransport, SendMailOptions, SentMessageInfo, Transporter } from 'nodemailer';
4 | import { Options } from 'nodemailer/lib/smtp-connection';
5 |
6 | import { CONFIG_CONNECTION_OPTIONS } from '../constants';
7 |
8 | @Injectable()
9 | export class AwsSesService {
10 | private readonly _transporter: Transporter;
11 |
12 | constructor(@Inject(CONFIG_CONNECTION_OPTIONS) private _options: Options) {
13 | Logger.log('initialising AWS Module', 'SES SERVICE');
14 | // create reusable transporter object using the default SMTP transport
15 | this._transporter = createTransport(this._options);
16 | }
17 |
18 | /**
19 | *
20 | * @param {SendMailOptions} mailOptions
21 | */
22 | async sendMail(mailOptions: SendMailOptions) {
23 | // promise send mail
24 | return this._transporter
25 | .sendMail(mailOptions)
26 | .then((info: SentMessageInfo) => {
27 | Logger.log('success[sendMail]:', info);
28 | return {
29 | statusCode: HttpStatus.OK,
30 | message: 'Mail Sent',
31 | data: info,
32 | };
33 | })
34 | .catch((err) => {
35 | Logger.log('error[sendMail]:', err);
36 | throw new HttpException({
37 | statusCode: HttpStatus.BAD_REQUEST,
38 | message: 'Failed to send',
39 | data: err,
40 | }, HttpStatus.BAD_REQUEST);
41 | });
42 | }
43 | }
--------------------------------------------------------------------------------
/src/service/aws.sns.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Inject, Logger, HttpStatus, HttpException } from '@nestjs/common';
2 | import { SNS } from 'aws-sdk';
3 | import { PublishResponse, PublishInput } from 'aws-sdk/clients/sns';
4 | import { ConfigurationOptions } from 'aws-sdk';
5 |
6 | import { CONFIG_CONNECTION_OPTIONS } from '../constants';
7 |
8 | /**
9 | * @export
10 | * @class AwsSnsService
11 | */
12 | @Injectable()
13 | export class AwsSnsService {
14 | private readonly _sns: SNS;
15 | constructor(@Inject(CONFIG_CONNECTION_OPTIONS) private _options: ConfigurationOptions) {
16 | Logger.log('initialising AWS Module', 'SNS SERVICE');
17 | this._sns = new SNS(this._options);
18 | }
19 |
20 | async sendSMS(smsOptions: PublishInput) {
21 |
22 | return this._sns
23 | .publish(smsOptions)
24 | .promise()
25 | .then((info: PublishResponse) => {
26 | Logger.log(` success[sendSms]: ${JSON.stringify(info)}`);
27 | return [
28 | {
29 | statusCode: HttpStatus.OK,
30 | message: 'Sms sent',
31 | data: info,
32 | },
33 | ];
34 | })
35 | .catch((err) => {
36 | Logger.error('error[sendSms]:', err);
37 | throw new HttpException({
38 | statusCode: HttpStatus.BAD_REQUEST,
39 | message: 'Failed to send',
40 | data: err,
41 | }, HttpStatus.BAD_REQUEST);
42 | });
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/service/generator.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import * as uuid from 'uuid/v1';
3 |
4 | /**
5 | * @export
6 | * @class GeneratorService
7 | */
8 | @Injectable()
9 | export class GeneratorService {
10 | public uuid(): string {
11 | return uuid();
12 | }
13 |
14 | public fileName(ext: string) {
15 | return this.uuid() + '.' + ext;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import * as request from 'supertest';
2 | import { Test } from '@nestjs/testing';
3 | import { AppModule } from './../src/app.module';
4 | import { INestApplication } from '@nestjs/common';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeAll(async () => {
10 | const moduleFixture = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it('/ (GET)', () => {
19 | return request(app.getHttpServer())
20 | .get('/')
21 | .expect(200)
22 | .expect('Hello World!');
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": ["js", "json", "ts"],
3 | "rootDir": ".",
4 | "testEnvironment": "node",
5 | "testRegex": ".e2e-spec.ts$",
6 | "transform": {
7 | "^.+\\.(t|j)s$": "ts-jest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": [
4 | "node_modules",
5 | "dist",
6 | "test",
7 | "**/*spec.ts"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "noImplicitAny": false,
6 | "importHelpers": true,
7 | "removeComments": true,
8 | "noLib": false,
9 | "allowSyntheticDefaultImports": true,
10 | "emitDecoratorMetadata": true,
11 | "experimentalDecorators": true,
12 | "target": "es2017",
13 | "sourceMap": true,
14 | "outDir": "./dist",
15 | "baseUrl": "./src",
16 | "incremental": true
17 | },
18 | "include": [
19 | "src/**/*",
20 | "index.ts"
21 | ],
22 | "exclude": [
23 | "node_modules",
24 | "**/*.spec.ts"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "error",
3 | "extends": [
4 | "tslint:recommended"
5 | ],
6 | "rulesDirectory": [
7 | "node_modules/tslint-eslint-rules/dist/rules",
8 | "tslint-config-prettier",
9 | "tslint-consistent-codestyle"
10 | ],
11 | "jsRules": {
12 | "no-unused-expression": true
13 | },
14 | "rules": {
15 | "no-angle-bracket-type-assertion": false,
16 | "adjacent-overload-signatures": true,
17 | "array-type": [
18 | true,
19 | "array-simple"
20 | ],
21 | "arrow-parens": true,
22 | "arrow-return-shorthand": true,
23 | "no-multi-spaces": true,
24 | "ban-comma-operator": true,
25 | "class-name": true,
26 | "comment-format": [
27 | true,
28 | "check-space"
29 | ],
30 | "eofline": true,
31 | "forin": true,
32 | "indent": [
33 | true,
34 | "spaces"
35 | ],
36 | "new-parens": true,
37 | "no-arg": true,
38 | "no-conditional-assignment": true,
39 | "no-consecutive-blank-lines": [
40 | true,
41 | 1
42 | ],
43 | "no-console": [
44 | true,
45 | "debug",
46 | "log",
47 | "time",
48 | "timeEnd",
49 | "trace"
50 | ],
51 | "no-construct": true,
52 | "no-debugger": true,
53 | "no-default-export": true,
54 | "no-duplicate-imports": true,
55 | "no-duplicate-switch-case": true,
56 | "no-empty-interface": true,
57 | "no-eval": true,
58 | "no-implicit-dependencies": true,
59 | "no-invalid-this": true,
60 | "no-inferrable-types": [
61 | true,
62 | "ignore-params"
63 | ],
64 | "no-irregular-whitespace": true,
65 | "no-require-imports": true,
66 | "no-return-await": true,
67 | "no-shadowed-variable": true,
68 | "no-sparse-arrays": true,
69 | "no-string-literal": true,
70 | "no-submodule-imports": false,
71 | "no-switch-case-fall-through": true,
72 | "no-this-assignment": true,
73 | "no-trailing-whitespace": true,
74 | "no-unnecessary-callback-wrapper": true,
75 | "no-unnecessary-initializer": true,
76 | "no-unsafe-finally": true,
77 | "no-unused-expression": true,
78 | "no-var-keyword": true,
79 | "number-literal-format": true,
80 | "object-literal-shorthand": true,
81 | "one-line": [
82 | true,
83 | "check-open-brace",
84 | "check-catch",
85 | "check-else",
86 | "check-finally",
87 | "check-whitespace"
88 | ],
89 | "one-variable-per-declaration": [
90 | true,
91 | "ignore-for-loop"
92 | ],
93 | "only-arrow-functions": [
94 | true,
95 | "allow-named-functions"
96 | ],
97 | "prefer-const": true,
98 | "prefer-for-of": true,
99 | "prefer-object-spread": true,
100 | "prefer-switch": [
101 | true,
102 | {
103 | "min-cases": 3
104 | }
105 | ],
106 | "quotemark": [
107 | true,
108 | "single",
109 | "avoid-escape"
110 | ],
111 | "radix": true,
112 | "semicolon": [
113 | true,
114 | "always"
115 | ],
116 | "space-before-function-paren": [
117 | true,
118 | {
119 | "anonymous": false,
120 | "named": false,
121 | "asyncArrow": true,
122 | "method": false,
123 | "constructor": false
124 | }
125 | ],
126 | "space-within-parens": [
127 | true,
128 | 0
129 | ],
130 | "switch-final-break": true,
131 | "trailing-comma": [
132 | true,
133 | {
134 | "singleline": "never",
135 | "multiline": "always"
136 | }
137 | ],
138 | "triple-equals": [
139 | true,
140 | "allow-null-check"
141 | ],
142 | "typedef-whitespace": [
143 | true,
144 | {
145 | "call-signature": "nospace",
146 | "index-signature": "nospace",
147 | "parameter": "nospace",
148 | "property-declaration": "nospace",
149 | "variable-declaration": "nospace"
150 | }
151 | ],
152 | "unified-signatures": true,
153 | "use-isnan": true,
154 | "variable-name": [
155 | true,
156 | "ban-keywords"
157 | ],
158 | "whitespace": [
159 | true,
160 | "check-branch",
161 | "check-decl",
162 | "check-operator",
163 | "check-separator",
164 | "check-type",
165 | "check-type-operator",
166 | "check-rest-spread"
167 | ],
168 | /* custom rules */
169 | "no-unused": [
170 | true,
171 | "unused-class-expression-name",
172 | "unused-function-expression-name",
173 | "unused-catch-binding"
174 | ],
175 | "ext-curly": false,
176 | "naming-convention": [
177 | true,
178 | {
179 | "type": "default",
180 | "format": "camelCase",
181 | "leadingUnderscore": "forbid",
182 | "trailingUnderscore": "forbid"
183 | },
184 | {
185 | "type": "variable",
186 | "modifiers": [
187 | "global",
188 | "const"
189 | ],
190 | "format": [
191 | "camelCase",
192 | "PascalCase",
193 | "UPPER_CASE"
194 | ]
195 | },
196 | {
197 | "type": "parameter",
198 | "modifiers": "unused",
199 | "leadingUnderscore": "allow"
200 | },
201 | {
202 | "type": "member",
203 | "modifiers": "private",
204 | "leadingUnderscore": "require"
205 | },
206 | {
207 | "type": "member",
208 | "modifiers": "protected",
209 | "leadingUnderscore": "require"
210 | },
211 | {
212 | "type": "property",
213 | "modifiers": [
214 | "public",
215 | "static",
216 | "const"
217 | ],
218 | "format": "UPPER_CASE"
219 | },
220 | {
221 | "type": "type",
222 | "format": "PascalCase"
223 | },
224 | {
225 | "type": "interface",
226 | "prefix": "I"
227 | },
228 | {
229 | "type": "genericTypeParameter",
230 | "regex": "^[A-Z]$"
231 | },
232 | {
233 | "type": "enumMember",
234 | "format": "PascalCase"
235 | }
236 | ],
237 | "no-as-type-assertion": true,
238 | "no-accessor-recursion": true,
239 | "no-collapsible-if": true,
240 | "no-return-undefined": [
241 | true,
242 | "allow-void-expression"
243 | ],
244 | // "no-unnecessary-else": true,
245 | "no-unnecessary-type-annotation": true,
246 | "no-var-before-return": true,
247 | "object-shorthand-properties-first": true,
248 | "parameter-properties": [
249 | true,
250 | "leading",
251 | "member-access"
252 | ],
253 | "prefer-const-enum": true,
254 | "prefer-while": true,
255 | "member-access": [
256 | false
257 | ],
258 | "ordered-imports": [
259 | false
260 | ],
261 | "max-line-length": [
262 | true,
263 | 150
264 | ],
265 | "member-ordering": [
266 | false
267 | ],
268 | "interface-name": [
269 | false
270 | ],
271 | "object-literal-sort-keys": false
272 | }
273 | }
274 |
--------------------------------------------------------------------------------