prime-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.eslintrc.js +25 -0
  2. package/.prettierrc +4 -0
  3. package/README.md +63 -0
  4. package/dist/app.module.d.ts +2 -0
  5. package/dist/app.module.js +32 -0
  6. package/dist/app.module.js.map +1 -0
  7. package/dist/app.service.d.ts +9 -0
  8. package/dist/app.service.js +39 -0
  9. package/dist/app.service.js.map +1 -0
  10. package/dist/external/aws/sqs/sqs.provider.d.ts +12 -0
  11. package/dist/external/aws/sqs/sqs.provider.js +31 -0
  12. package/dist/external/aws/sqs/sqs.provider.js.map +1 -0
  13. package/dist/external/aws/sqs/sqs.service.d.ts +17 -0
  14. package/dist/external/aws/sqs/sqs.service.js +53 -0
  15. package/dist/external/aws/sqs/sqs.service.js.map +1 -0
  16. package/dist/external/aws/sqs.provider.d.ts +12 -0
  17. package/dist/external/aws/sqs.provider.js +31 -0
  18. package/dist/external/aws/sqs.provider.js.map +1 -0
  19. package/dist/external/aws/sqs.service.d.ts +17 -0
  20. package/dist/external/aws/sqs.service.js +53 -0
  21. package/dist/external/aws/sqs.service.js.map +1 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +10 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/lib/events/events.d.ts +2 -0
  26. package/dist/lib/events/events.js +17 -0
  27. package/dist/lib/events/events.js.map +1 -0
  28. package/dist/lib/queue/interfaces/consumer.interface.d.ts +6 -0
  29. package/dist/lib/queue/interfaces/consumer.interface.js +5 -0
  30. package/dist/lib/queue/interfaces/consumer.interface.js.map +1 -0
  31. package/dist/lib/queue/interfaces/queue.interface.d.ts +11 -0
  32. package/dist/lib/queue/interfaces/queue.interface.js +5 -0
  33. package/dist/lib/queue/interfaces/queue.interface.js.map +1 -0
  34. package/dist/lib/queue/queue.d.ts +16 -0
  35. package/dist/lib/queue/queue.js +77 -0
  36. package/dist/lib/queue/queue.js.map +1 -0
  37. package/dist/lib/queue/queue.module.d.ts +5 -0
  38. package/dist/lib/queue/queue.module.js +30 -0
  39. package/dist/lib/queue/queue.module.js.map +1 -0
  40. package/dist/lib/queue/types/queue.type.d.ts +7 -0
  41. package/dist/lib/queue/types/queue.type.js +3 -0
  42. package/dist/lib/queue/types/queue.type.js.map +1 -0
  43. package/dist/lib/storage/storage.d.ts +2 -0
  44. package/dist/lib/storage/storage.js +17 -0
  45. package/dist/lib/storage/storage.js.map +1 -0
  46. package/dist/main.d.ts +1 -0
  47. package/dist/main.js +10 -0
  48. package/dist/main.js.map +1 -0
  49. package/dist/tsconfig.build.tsbuildinfo +1 -0
  50. package/nest-cli.json +8 -0
  51. package/package.json +73 -0
  52. package/queue-publish.bash +4 -0
  53. package/queue.bash +7 -0
  54. package/src/app.module.ts +19 -0
  55. package/src/app.service.ts +26 -0
  56. package/src/external/aws/sqs/sqs.provider.ts +39 -0
  57. package/src/external/aws/sqs/sqs.service.ts +50 -0
  58. package/src/index.ts +5 -0
  59. package/src/lib/events/events.ts +4 -0
  60. package/src/lib/queue/interfaces/consumer.interface.ts +8 -0
  61. package/src/lib/queue/interfaces/queue.interface.ts +9 -0
  62. package/src/lib/queue/queue.module.ts +17 -0
  63. package/src/lib/queue/queue.ts +80 -0
  64. package/src/lib/queue/types/queue.type.ts +8 -0
  65. package/src/lib/storage/storage.ts +4 -0
  66. package/src/main.ts +8 -0
  67. package/test/app.e2e-spec.ts +24 -0
  68. package/test/jest-e2e.json +9 -0
  69. package/tsconfig.build.json +4 -0
  70. package/tsconfig.json +21 -0
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "prime-sdk",
3
+ "version": "1.0.0",
4
+ "description": "swiss army knife",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "author": "",
8
+ "private": false,
9
+ "license": "UNLICENSED",
10
+ "scripts": {
11
+ "build": "nest build",
12
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
13
+ "start": "nest start",
14
+ "start:dev": "nest start --watch",
15
+ "start:debug": "nest start --debug --watch",
16
+ "start:prod": "node dist/main",
17
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
18
+ "test": "jest",
19
+ "test:watch": "jest --watch",
20
+ "test:cov": "jest --coverage",
21
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
22
+ "test:e2e": "jest --config ./test/jest-e2e.json"
23
+ },
24
+ "dependencies": {
25
+ "@aws-sdk/client-sqs": "^3.569.0",
26
+ "@nestjs/common": "^10.0.0",
27
+ "@nestjs/config": "^3.2.2",
28
+ "@nestjs/core": "^10.0.0",
29
+ "@nestjs/platform-express": "^10.0.0",
30
+ "reflect-metadata": "^0.2.0",
31
+ "rxjs": "^7.8.1"
32
+ },
33
+ "devDependencies": {
34
+ "@nestjs/cli": "^10.0.0",
35
+ "@nestjs/schematics": "^10.0.0",
36
+ "@nestjs/testing": "^10.0.0",
37
+ "@types/express": "^4.17.17",
38
+ "@types/jest": "^29.5.2",
39
+ "@types/node": "^20.3.1",
40
+ "@types/supertest": "^6.0.0",
41
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
42
+ "@typescript-eslint/parser": "^6.0.0",
43
+ "eslint": "^8.42.0",
44
+ "eslint-config-prettier": "^9.0.0",
45
+ "eslint-plugin-prettier": "^5.0.0",
46
+ "jest": "^29.5.0",
47
+ "prettier": "^3.0.0",
48
+ "source-map-support": "^0.5.21",
49
+ "supertest": "^6.3.3",
50
+ "ts-jest": "^29.1.0",
51
+ "ts-loader": "^9.4.3",
52
+ "ts-node": "^10.9.1",
53
+ "tsconfig-paths": "^4.2.0",
54
+ "typescript": "^5.1.3"
55
+ },
56
+ "jest": {
57
+ "moduleFileExtensions": [
58
+ "js",
59
+ "json",
60
+ "ts"
61
+ ],
62
+ "rootDir": "src",
63
+ "testRegex": ".*\\.spec\\.ts$",
64
+ "transform": {
65
+ "^.+\\.(t|j)s$": "ts-jest"
66
+ },
67
+ "collectCoverageFrom": [
68
+ "**/*.(t|j)s"
69
+ ],
70
+ "coverageDirectory": "../coverage",
71
+ "testEnvironment": "node"
72
+ }
73
+ }
@@ -0,0 +1,4 @@
1
+ awslocal sqs send-message --queue-url=http://localhost:4566/000000000000/teste --message-body='{
2
+ "token": "NWMwOWRiM2MzNTk3MDViMWI4YjRmODZhNzBjOThkYWFmZmZiODQ4ODM4Nzc2OGJkYjE2OWIyZDFlYTFkNDc0MWRlZDFhNjk2NjM4ZjM3NGMwZDlhNmY0ZDY2Y2FlM2U0ODQ0NzU3ZmYwMTFiMjdlZjkyMzg2YThkZDUwYmUzNjAwNTkzZGYwZGY3M2ZhNzFhNzExM2U2ZWRkOGIxYjNjNzMwMDA0ZTRmYTM3MGZiMGZhYmU1NTYwNzFiYTIyYmYwM2RiY2ZiMjBkYmM5Y2JmNzI1NmM4NjE3ZGRjOWIzN2FlZWJlNzc2N2YxYTQ4N2E5MWRhYWUzOTE4Y2M1Yzg2MmUwMzA5ZjQyZWI0OTIyZTBmYTk2ZGUyYmFiY2FjNjhmMWI0ZWEyNTBiMDc5MzVkZmNmMjRiMzIzZjdkYjY0ODkzYWJhZTc2NzIzOGY2OTBlOTM4NTBkMWY4ZWQ3MDNiYQ==",
3
+ "fkUsersRequestVerification": 9
4
+ }'
package/queue.bash ADDED
@@ -0,0 +1,7 @@
1
+ awslocal sqs delete-queue --queue-url=http://localhost:4566/000000000000/teste
2
+ awslocal sqs create-queue --queue-name teste
3
+ awslocal sqs purge-queue --queue-url=http://localhost:4566/000000000000/teste
4
+
5
+ awslocal sns delete-topic --topic-arn arn:aws:sns:us-east-1:000000000000:identity-validation-requested
6
+ awslocal sns create-topic --name identity-validation-requested
7
+ awslocal sns subscribe --topic-arn arn:aws:sns:us-east-1:000000000000:identity-validation-requested --protocol sqs --notification-endpoint arn:aws:sqs:us-east-1:000000000000:teste --attributes RawMessageDelivery=true
@@ -0,0 +1,19 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { AppService } from './app.service';
3
+ import { QueueModule } from './lib/queue/queue.module';
4
+
5
+ @Module({
6
+ imports: [
7
+ QueueModule.forRoot({
8
+ credentials: {
9
+ accessKeyId: '000000000',
10
+ secretAccessKey: '000000000',
11
+ },
12
+ endpoint: 'http://localhost:4566/',
13
+ region: 'us-east-1',
14
+ }),
15
+ ],
16
+ providers: [AppService],
17
+ exports: [],
18
+ })
19
+ export class AppModule {}
@@ -0,0 +1,26 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { IConsumer } from './lib/queue/interfaces/consumer.interface';
3
+ import { Message } from '@aws-sdk/client-sqs';
4
+ import { Queue } from './lib/queue/queue';
5
+
6
+ @Injectable()
7
+ export class AppService implements IConsumer {
8
+ constructor(private readonly queueHandler: Queue) {
9
+ this.queueHandler.handler({
10
+ QueueUrl: `${'teste'}`,
11
+ context: this,
12
+ bulk: 1,
13
+ waitTimeSeconds: 20,
14
+ });
15
+ }
16
+
17
+ handleMessage(message: Message | Message[]): Promise<void> {
18
+ console.log(message);
19
+ return;
20
+ }
21
+
22
+ handleError(error: unknown): Promise<void> {
23
+ console.log(error);
24
+ return;
25
+ }
26
+ }
@@ -0,0 +1,39 @@
1
+ import { SQSClient } from '@aws-sdk/client-sqs';
2
+ import { DynamicModule } from '@nestjs/common';
3
+
4
+ export type SqsSetup = {
5
+ region: string;
6
+ endpoint: string;
7
+ credentials: {
8
+ accessKeyId: string;
9
+ secretAccessKey: string;
10
+ };
11
+ };
12
+
13
+ const SqsProvider = (params: SqsSetup) => {
14
+ return {
15
+ provide: 'CONNECTION_SQS',
16
+ useFactory: () => {
17
+ return new SQSClient({
18
+ region: params.region,
19
+ endpoint: params.endpoint,
20
+ credentials: {
21
+ accessKeyId: params.credentials.accessKeyId,
22
+ secretAccessKey: params.credentials.secretAccessKey,
23
+ },
24
+ });
25
+ },
26
+ };
27
+ };
28
+
29
+ export class SqsModule {
30
+ static forRoot(params: SqsSetup): DynamicModule {
31
+ const sqsProvider = SqsProvider(params);
32
+
33
+ return {
34
+ module: SqsModule,
35
+ providers: [sqsProvider],
36
+ exports: [sqsProvider],
37
+ };
38
+ }
39
+ }
@@ -0,0 +1,50 @@
1
+ import {
2
+ DeleteMessageCommand,
3
+ ReceiveMessageCommand,
4
+ ReceiveMessageResult,
5
+ SQSClient,
6
+ } from '@aws-sdk/client-sqs';
7
+ import { Inject, Injectable } from '@nestjs/common';
8
+ import { IQueue } from 'src/lib/queue/interfaces/queue.interface';
9
+
10
+ @Injectable()
11
+ export class Sqs implements IQueue {
12
+ private queueUrl: string;
13
+ private bulk: number;
14
+ private waitTimeSeconds: number;
15
+
16
+ constructor(@Inject('CONNECTION_SQS') private readonly client: SQSClient) {}
17
+
18
+ setup({ waitTimeSeconds, bulk, queueUrl }) {
19
+ this.waitTimeSeconds = waitTimeSeconds;
20
+ this.bulk = bulk;
21
+ this.queueUrl = queueUrl;
22
+ }
23
+
24
+ async sendCommand(
25
+ command: ReceiveMessageCommand | DeleteMessageCommand,
26
+ ): Promise<unknown> {
27
+ return this.client.send(command);
28
+ }
29
+
30
+ async receiveMessages(): Promise<ReceiveMessageResult> {
31
+ const input = {
32
+ QueueUrl: this.queueUrl,
33
+ MaxNumberOfMessages: this.bulk,
34
+ WaitTimeSeconds: this.waitTimeSeconds,
35
+ };
36
+
37
+ const command = new ReceiveMessageCommand(input);
38
+
39
+ return (await this.sendCommand(command)) as ReceiveMessageResult;
40
+ }
41
+
42
+ async deleteMessage(receiptHandle): Promise<unknown> {
43
+ const deleteCommand = new DeleteMessageCommand({
44
+ QueueUrl: this.queueUrl,
45
+ ReceiptHandle: receiptHandle,
46
+ });
47
+
48
+ return await this.sendCommand(deleteCommand);
49
+ }
50
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { QueueModule } from './lib/queue/queue.module';
2
+ import { Queue } from './lib/queue/queue';
3
+ import { IConsumer } from './lib/queue/interfaces/consumer.interface';
4
+
5
+ export { QueueModule, Queue, IConsumer };
@@ -0,0 +1,4 @@
1
+ import { Injectable } from '@nestjs/common';
2
+
3
+ @Injectable()
4
+ export class Events {}
@@ -0,0 +1,8 @@
1
+ import { Message } from '@aws-sdk/client-sqs';
2
+
3
+ export interface IConsumer {
4
+ handleMessage(message: Array<Message> | Message): Promise<void>;
5
+ handleError(error: unknown): Promise<void>;
6
+ }
7
+
8
+ export const IConsumer = Symbol('IConsumer');
@@ -0,0 +1,9 @@
1
+ import { Message, ReceiveMessageResult } from '@aws-sdk/client-sqs';
2
+
3
+ export interface IQueue {
4
+ deleteMessage(message: Array<Message> | Message): Promise<unknown>;
5
+ receiveMessages(): Promise<ReceiveMessageResult>;
6
+ setup({ waitTimeSeconds, bulk, queueUrl }): void;
7
+ }
8
+
9
+ export const IQueue = Symbol('IQueue');
@@ -0,0 +1,17 @@
1
+ import { DynamicModule, Module } from '@nestjs/common';
2
+ import { Queue } from './queue';
3
+ import { IQueue } from './interfaces/queue.interface';
4
+ import { Sqs } from '../../external/aws/sqs/sqs.service';
5
+ import { SqsModule, SqsSetup } from '../../external/aws/sqs/sqs.provider';
6
+
7
+ @Module({})
8
+ export class QueueModule {
9
+ static forRoot(params: SqsSetup): DynamicModule {
10
+ return {
11
+ module: QueueModule,
12
+ imports: [SqsModule.forRoot(params)],
13
+ providers: [Queue, { provide: IQueue, useClass: Sqs }],
14
+ exports: [Queue, { provide: IQueue, useClass: Sqs }],
15
+ };
16
+ }
17
+ }
@@ -0,0 +1,80 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { QueueConfig } from './types/queue.type';
3
+ import { IConsumer } from './interfaces/consumer.interface';
4
+ import { IQueue } from './interfaces/queue.interface';
5
+ import { Message, ReceiveMessageResult } from '@aws-sdk/client-sqs';
6
+
7
+ @Injectable()
8
+ export class Queue {
9
+ private queueUrl: string = null;
10
+
11
+ private bulk: number = 1;
12
+
13
+ private context: IConsumer = null;
14
+
15
+ private inWork: boolean = false;
16
+
17
+ private waitTimeSeconds: number = 20;
18
+
19
+ constructor(@Inject(IQueue) private readonly broker: IQueue) {}
20
+
21
+ async handler({
22
+ QueueUrl = null,
23
+ context = null,
24
+ bulk = 1,
25
+ waitTimeSeconds = 20,
26
+ }: QueueConfig): Promise<void> {
27
+ this.queueUrl = QueueUrl;
28
+ this.bulk = bulk;
29
+ this.context = context;
30
+ this.waitTimeSeconds = waitTimeSeconds;
31
+
32
+ this.broker.setup({
33
+ waitTimeSeconds: this.waitTimeSeconds,
34
+ bulk: this.bulk,
35
+ queueUrl: this.queueUrl,
36
+ });
37
+
38
+ while (!this.inWork) {
39
+ await this.run();
40
+ }
41
+ }
42
+
43
+ async run() {
44
+ this.inWork = true;
45
+ const response = await this.receiveMessages();
46
+
47
+ try {
48
+ if (this.bulk === 1) {
49
+ const message = response.Messages?.[0] || null;
50
+
51
+ if (message) {
52
+ await this.context.handleMessage(message);
53
+
54
+ await this.deleteMessage(message.ReceiptHandle);
55
+ }
56
+
57
+ this.inWork = false;
58
+
59
+ return;
60
+ }
61
+
62
+ await this.context.handleMessage(response.Messages);
63
+
64
+ response.Messages.forEach(async (message: Message) => {
65
+ await this.deleteMessage(message.ReceiptHandle);
66
+ });
67
+ } catch (error) {
68
+ await this.context.handleError(error);
69
+ }
70
+ this.inWork = false;
71
+ }
72
+
73
+ async receiveMessages(): Promise<ReceiveMessageResult> {
74
+ return await this.broker.receiveMessages();
75
+ }
76
+
77
+ async deleteMessage(receiptHandle): Promise<unknown> {
78
+ return await this.broker.deleteMessage(receiptHandle);
79
+ }
80
+ }
@@ -0,0 +1,8 @@
1
+ import { IConsumer } from '../interfaces/consumer.interface';
2
+
3
+ export type QueueConfig = {
4
+ QueueUrl: string;
5
+ context: IConsumer;
6
+ bulk: number;
7
+ waitTimeSeconds?: number;
8
+ };
@@ -0,0 +1,4 @@
1
+ import { Injectable } from '@nestjs/common';
2
+
3
+ @Injectable()
4
+ export class Storage {}
package/src/main.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { NestFactory } from '@nestjs/core';
2
+ import { AppModule } from './app.module';
3
+
4
+ async function bootstrap() {
5
+ const app = await NestFactory.create(AppModule);
6
+ await app.listen(3000);
7
+ }
8
+ bootstrap();
@@ -0,0 +1,24 @@
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { INestApplication } from '@nestjs/common';
3
+ import * as request from 'supertest';
4
+ import { AppModule } from './../src/app.module';
5
+
6
+ describe('AppController (e2e)', () => {
7
+ let app: INestApplication;
8
+
9
+ beforeEach(async () => {
10
+ const moduleFixture: TestingModule = 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
+ });
@@ -0,0 +1,9 @@
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
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "declaration": true,
5
+ "removeComments": true,
6
+ "emitDecoratorMetadata": true,
7
+ "experimentalDecorators": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "target": "ES2021",
10
+ "sourceMap": true,
11
+ "outDir": "./dist",
12
+ "baseUrl": "./",
13
+ "incremental": true,
14
+ "skipLibCheck": true,
15
+ "strictNullChecks": false,
16
+ "noImplicitAny": false,
17
+ "strictBindCallApply": false,
18
+ "forceConsistentCasingInFileNames": false,
19
+ "noFallthroughCasesInSwitch": false
20
+ }
21
+ }