Skip to content

Commit 94c2909

Browse files
authored
refactor: add eslint (#6)
1 parent 68c4da5 commit 94c2909

22 files changed

+1243
-406
lines changed

.eslintrc.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"extends": "@dcl/eslint-config/sdk",
3+
"parserOptions": {
4+
"project": [
5+
"tsconfig.json",
6+
"test/tsconfig.json"
7+
]
8+
},
9+
"ignorePatterns": [
10+
"jest.config.js"
11+
],
12+
"rules": {
13+
"prettier/prettier": ["error", {
14+
"printWidth": 120,
15+
"semi": false,
16+
"singleQuote": true,
17+
"trailingComma": "none",
18+
"tabWidth": 2
19+
}]
20+
}
21+
}

jest.config.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
module.exports = {
2-
globals: {
3-
"ts-jest": {
4-
tsconfig: "test/tsconfig.json",
5-
},
6-
},
7-
moduleFileExtensions: ["ts", "js"],
2+
moduleFileExtensions: ['ts', 'js'],
83
transform: {
9-
"^.+\\.(ts|tsx)$": "ts-jest",
4+
'^.+\\.(ts|tsx)$': ['ts-jest', { tsconfig: 'test/tsconfig.json' }]
105
},
11-
coverageDirectory: "coverage",
12-
collectCoverageFrom: ["src/**/*.ts", "src/**/*.js"],
13-
testMatch: ["**/*.spec.(ts)"],
14-
testEnvironment: "node",
6+
coverageDirectory: 'coverage',
7+
collectCoverageFrom: [
8+
'src/**/*.ts',
9+
'!src/bin/**',
10+
'!src/index.ts'
11+
],
12+
testMatch: ['**/*.spec.(ts)'],
13+
testEnvironment: 'node'
1514
}

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@
22
"name": "template-server",
33
"scripts": {
44
"build": "tsc -p tsconfig.json",
5-
"lint:check": "echo 1",
5+
"lint:check": "eslint '**/*.{js,ts}'",
6+
"lint:fix": "eslint '**/*.{js,ts}' --fix",
67
"start": "node --trace-warnings --abort-on-uncaught-exception --unhandled-rejections=strict dist/index.js",
78
"test": "jest --forceExit --detectOpenHandles --coverage --verbose"
89
},
910
"devDependencies": {
1011
"@types/node": "^20.2.5",
1112
"@well-known-components/test-helpers": "^1.5.0",
12-
"typescript": "^4.8.3"
13+
"typescript": "^4.8.3",
14+
"@dcl/eslint-config": "^2.2.1"
1315
},
1416
"prettier": {
1517
"printWidth": 120,
16-
"semi": false
18+
"semi": false,
19+
"singleQuote": true,
20+
"trailingComma": "none",
21+
"tabWidth": 2
1722
},
1823
"dependencies": {
1924
"@dcl/schemas": "^7.4.1",

src/adapters/fetch.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { IFetchComponent } from "@well-known-components/http-server"
2-
import * as nodeFetch from "node-fetch"
1+
import { IFetchComponent } from '@well-known-components/http-server'
2+
import * as nodeFetch from 'node-fetch'
33

44
export async function createFetchComponent() {
55
const fetch: IFetchComponent = {
66
async fetch(url: nodeFetch.RequestInfo, init?: nodeFetch.RequestInit): Promise<nodeFetch.Response> {
77
return nodeFetch.default(url, init)
8-
},
8+
}
99
}
1010

1111
return fetch

src/adapters/runner.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IBaseComponent } from "@well-known-components/interfaces";
1+
import { IBaseComponent } from '@well-known-components/interfaces'
22

33
export type RunnerComponentArg = {
44
readonly isRunning: boolean
@@ -11,8 +11,7 @@ export type IRunnerComponent = IBaseComponent & {
1111
// this component runs a loop while the application is enabled. and waits until it
1212
// finishes the loop to stop the service
1313
export function createRunnerComponent(): IRunnerComponent {
14-
15-
let delegates: Promise<any>[] = []
14+
const delegates: Promise<any>[] = []
1615
let isRunning = false
1716

1817
return {
@@ -26,7 +25,13 @@ export function createRunnerComponent(): IRunnerComponent {
2625
},
2726
runTask(delegate) {
2827
if (!isRunning) throw new Error('You can only run tasks while the component is running')
29-
delegates.push(delegate({ get isRunning() { return isRunning } }))
30-
},
28+
delegates.push(
29+
delegate({
30+
get isRunning() {
31+
return isRunning
32+
}
33+
})
34+
)
35+
}
3136
}
32-
}
37+
}

src/adapters/sqs.ts

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,40 @@ export interface ITaskQueue<T> {
1313
publish(job: T): Promise<TaskQueueMessage>
1414
// awaits for a job. then calls and waits for the taskRunner argument.
1515
// the result is then returned to the wrapper function.
16-
consumeAndProcessJob<R>(taskRunner: (job: T, message: TaskQueueMessage) => Promise<R>): Promise<{ result: R | undefined }>
16+
consumeAndProcessJob<R>(
17+
taskRunner: (job: T, message: TaskQueueMessage) => Promise<R>
18+
): Promise<{ result: R | undefined }>
1719
}
1820

1921
export const queueMetrics = validateMetricsDeclaration({
2022
job_queue_duration_seconds: {
2123
type: IMetricsComponent.HistogramType,
2224
help: 'Duration of each job in seconds',
23-
labelNames: ["queue_name"],
25+
labelNames: ['queue_name'],
2426
buckets: [1, 10, 100, 200, 300, 400, 500, 600, 700, 1000, 1200, 1600, 1800, 3600]
2527
},
2628
job_queue_enqueue_total: {
2729
type: IMetricsComponent.CounterType,
28-
help: "Total amount of enqueued jobs",
29-
labelNames: ["queue_name"],
30+
help: 'Total amount of enqueued jobs',
31+
labelNames: ['queue_name']
3032
},
3133
job_queue_failures_total: {
3234
type: IMetricsComponent.CounterType,
33-
help: "Total amount of failed tasks",
34-
labelNames: ["queue_name"],
35-
},
35+
help: 'Total amount of failed tasks',
36+
labelNames: ['queue_name']
37+
}
3638
})
3739

3840
type SNSOverSQSMessage = {
3941
Message: string
4042
}
4143

42-
43-
export function createMemoryQueueAdapter<T>(components: Pick<AppComponents, "logs" | 'metrics'>, options: { queueName: string }): ITaskQueue<T> & IBaseComponent {
44-
type InternalElement = { message: TaskQueueMessage, job: T }
45-
const q = new AsyncQueue<InternalElement>((action) => void 0)
44+
export function createMemoryQueueAdapter<T>(
45+
components: Pick<AppComponents, 'logs' | 'metrics'>,
46+
options: { queueName: string }
47+
): ITaskQueue<T> & IBaseComponent {
48+
type InternalElement = { message: TaskQueueMessage; job: T }
49+
const q = new AsyncQueue<InternalElement>((_action) => void 0)
4650
let lastJobId = 0
4751

4852
const logger = components.logs.getLogger(options.queueName)
@@ -77,12 +81,14 @@ export function createMemoryQueueAdapter<T>(components: Pick<AppComponents, "log
7781
}
7882
}
7983
return { result: undefined }
80-
},
84+
}
8185
}
8286
}
8387

84-
85-
export function createSqsAdapter<T>(components: Pick<AppComponents, "logs" | 'metrics'>, options: { queueUrl: string, queueRegion?: string }): ITaskQueue<T> {
88+
export function createSqsAdapter<T>(
89+
components: Pick<AppComponents, 'logs' | 'metrics'>,
90+
options: { queueUrl: string; queueRegion?: string }
91+
): ITaskQueue<T> {
8692
const logger = components.logs.getLogger(options.queueUrl)
8793

8894
const sqs = new SQS({ apiVersion: 'latest', region: options.queueRegion })
@@ -93,11 +99,12 @@ export function createSqsAdapter<T>(components: Pick<AppComponents, "logs" | 'me
9399
Message: JSON.stringify(job)
94100
}
95101

96-
const published = await sqs.sendMessage(
97-
{
102+
const published = await sqs
103+
.sendMessage({
98104
QueueUrl: options.queueUrl,
99-
MessageBody: JSON.stringify(snsOverSqs),
100-
}).promise()
105+
MessageBody: JSON.stringify(snsOverSqs)
106+
})
107+
.promise()
101108

102109
const m: TaskQueueMessage = { id: published.MessageId! }
103110

@@ -126,7 +133,9 @@ export function createSqsAdapter<T>(components: Pick<AppComponents, "logs" | 'me
126133
if (response.Messages && response.Messages.length > 0) {
127134
for (const it of response.Messages) {
128135
const message: TaskQueueMessage = { id: it.MessageId! }
129-
const { end } = components.metrics.startTimer('job_queue_duration_seconds', { queue_name: options.queueUrl })
136+
const { end } = components.metrics.startTimer('job_queue_duration_seconds', {
137+
queue_name: options.queueUrl
138+
})
130139
try {
131140
logger.info(`Processing job`, { id: message.id })
132141
const result = await taskRunner(JSON.parse(it.Body!), message)
@@ -150,7 +159,7 @@ export function createSqsAdapter<T>(components: Pick<AppComponents, "logs" | 'me
150159
await sleep(1000)
151160
}
152161
}
153-
},
162+
}
154163
}
155164
}
156165

src/adapters/storage.ts

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
1-
import { IBaseComponent } from "@well-known-components/interfaces"
2-
import AWS from "aws-sdk";
3-
import { readFile, writeFile } from "fs/promises";
1+
import { IBaseComponent } from '@well-known-components/interfaces'
2+
import AWS from 'aws-sdk'
3+
import { readFile, writeFile } from 'fs/promises'
44

55
export type IStorageComponent = IBaseComponent & {
6-
storeFile(key: string, filePath: string): Promise<void>
6+
storeFile(key: string, filePath: string): Promise<void>
77
}
88

9-
export async function createS3StorageComponent(bucketName: string, endpoint: string | undefined = undefined): Promise<IStorageComponent> {
10-
const s3 = new AWS.S3({
11-
endpoint,
12-
s3ForcePathStyle: true,
13-
});
14-
return {
15-
storeFile: async function (key: string, filePath: string) {
16-
try {
17-
// Read file content
18-
const fileContent = await readFile(filePath);
19-
20-
// Parameters for the upload
21-
const params = {
22-
Bucket: bucketName,
23-
Key: key, // File name (key) in the bucket
24-
Body: fileContent, // File content
25-
};
26-
27-
// Upload to S3
28-
const result = await s3.upload(params).promise();
29-
console.log("File uploaded successfully:", result);
30-
} catch (error) {
31-
console.error("Error uploading file:", error);
32-
}
9+
export async function createS3StorageComponent(
10+
bucketName: string,
11+
endpoint: string | undefined = undefined
12+
): Promise<IStorageComponent> {
13+
const s3 = new AWS.S3({
14+
endpoint,
15+
s3ForcePathStyle: true
16+
})
17+
return {
18+
storeFile: async function (key: string, filePath: string) {
19+
try {
20+
// Read file content
21+
const fileContent = await readFile(filePath)
22+
23+
// Parameters for the upload
24+
const params = {
25+
Bucket: bucketName,
26+
Key: key, // File name (key) in the bucket
27+
Body: fileContent // File content
3328
}
29+
30+
// Upload to S3
31+
const result = await s3.upload(params).promise()
32+
console.log('File uploaded successfully:', result)
33+
} catch (error) {
34+
console.error('Error uploading file:', error)
35+
}
3436
}
37+
}
3538
}
3639

3740
export function createLocalStorageComponent(): IStorageComponent {
38-
return {
39-
storeFile: async function (key: string, filePath: string) {
40-
try {
41-
// Read file content
42-
const fileContent = await readFile(filePath);
43-
44-
await writeFile(key, fileContent)
45-
console.log("File copied successfully:");
46-
} catch (error) {
47-
console.error("Error copying file:", error);
48-
}
49-
}
41+
return {
42+
storeFile: async function (key: string, filePath: string) {
43+
try {
44+
// Read file content
45+
const fileContent = await readFile(filePath)
46+
47+
await writeFile(key, fileContent)
48+
console.log('File copied successfully:')
49+
} catch (error) {
50+
console.error('Error copying file:', error)
51+
}
5052
}
51-
}
53+
}
54+
}

src/components.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
1-
import { createDotEnvConfigComponent } from "@well-known-components/env-config-provider"
2-
import { createServerComponent, createStatusCheckComponent } from "@well-known-components/http-server"
3-
import { createLogComponent } from "@well-known-components/logger"
4-
import { createFetchComponent } from "./adapters/fetch"
5-
import { createMetricsComponent, instrumentHttpServerWithMetrics } from "@well-known-components/metrics"
6-
import { AppComponents, GlobalContext } from "./types"
7-
import { metricDeclarations } from "./metrics"
8-
import { createMemoryQueueAdapter, createSqsAdapter } from "./adapters/sqs"
9-
import { DeploymentToSqs } from "@dcl/schemas/dist/misc/deployments-to-sqs"
10-
import AWS from "aws-sdk"
11-
import { createRunnerComponent } from "./adapters/runner"
12-
import mitt from "mitt"
13-
import { createS3StorageComponent } from "./adapters/storage"
1+
import { createDotEnvConfigComponent } from '@well-known-components/env-config-provider'
2+
import { createServerComponent, createStatusCheckComponent } from '@well-known-components/http-server'
3+
import { createLogComponent } from '@well-known-components/logger'
4+
import { createFetchComponent } from './adapters/fetch'
5+
import { createMetricsComponent, instrumentHttpServerWithMetrics } from '@well-known-components/metrics'
6+
import { AppComponents, GlobalContext } from './types'
7+
import { metricDeclarations } from './metrics'
8+
import { createMemoryQueueAdapter, createSqsAdapter } from './adapters/sqs'
9+
import { DeploymentToSqs } from '@dcl/schemas/dist/misc/deployments-to-sqs'
10+
import AWS from 'aws-sdk'
11+
import { createRunnerComponent } from './adapters/runner'
12+
import mitt from 'mitt'
13+
import { createS3StorageComponent } from './adapters/storage'
1414

1515
// Initialize all the components of the app
1616
export async function initComponents(): Promise<AppComponents> {
17-
const config = await createDotEnvConfigComponent({ path: [".env.default", ".env"] })
17+
const config = await createDotEnvConfigComponent({ path: ['.env.default', '.env'] })
1818
const metrics = await createMetricsComponent(metricDeclarations, { config })
1919
const logs = await createLogComponent({ metrics })
20-
const server = await createServerComponent<GlobalContext>({ config, logs }, {
21-
cors: {}
22-
})
20+
const server = await createServerComponent<GlobalContext>(
21+
{ config, logs },
22+
{
23+
cors: {}
24+
}
25+
)
2326
const statusChecks = await createStatusCheckComponent({ server, config })
2427
const fetch = await createFetchComponent()
2528

@@ -31,13 +34,13 @@ export async function initComponents(): Promise<AppComponents> {
3134
}
3235

3336
const sqsQueue = await config.getString('TASK_QUEUE')
34-
const taskQueue = sqsQueue ?
35-
createSqsAdapter<DeploymentToSqs>({ logs, metrics }, { queueUrl: sqsQueue, queueRegion: AWS_REGION }) :
36-
createMemoryQueueAdapter<DeploymentToSqs>({ logs, metrics }, { queueName: "ConversionTaskQueue" })
37+
const taskQueue = sqsQueue
38+
? createSqsAdapter<DeploymentToSqs>({ logs, metrics }, { queueUrl: sqsQueue, queueRegion: AWS_REGION })
39+
: createMemoryQueueAdapter<DeploymentToSqs>({ logs, metrics }, { queueName: 'ConversionTaskQueue' })
3740

3841
const bucket = await config.getString('BUCKET')
3942
if (!bucket) {
40-
throw new Error("Missing BUCKET");
43+
throw new Error('Missing BUCKET')
4144
}
4245
const awsEndpoint = await config.getString('AWS_ENDPOINT')
4346
const storage = await createS3StorageComponent(bucket, awsEndpoint)
@@ -54,6 +57,6 @@ export async function initComponents(): Promise<AppComponents> {
5457
taskQueue,
5558
runner,
5659
deploymentsByPointer: mitt(),
57-
storage,
60+
storage
5861
}
5962
}

0 commit comments

Comments
 (0)