diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..5b04878 --- /dev/null +++ b/.npmignore @@ -0,0 +1,28 @@ +# Arquivos de configuração +.eslintrc +.prettierrc +.stylelintrc + +# Arquivos de teste +__tests__ +test/ +tests/ +*.test.ts +*.spec.ts + +# Pastas e arquivos de build +dist/ +build/ +lib/ +*.log + +# Arquivos temporários +*.tmp + +# Dependências locais instaladas +node_modules/ + +# Outros arquivos que não são necessários para o pacote publicado +.editorconfig +.gitignore +.npmrc diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c7c144..bb57725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Implementing tests for Logger, Router and Server + - Creating Simpler server README.md file. - Creating Simpler server response method. diff --git a/jest.config.js b/jest.config.js index a639884..a65df93 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,6 @@ -export const preset = "ts-jest"; -export const testEnvironment = "node"; -export const testMatch = ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"]; +/* eslint-disable no-undef */ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + testMatch: ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"], +}; diff --git a/package-lock.json b/package-lock.json index 9b3ab44..b17404e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,22 @@ { "name": "simpler", - "version": "0.0.1", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "simpler", - "version": "0.0.1", + "version": "0.1.0", "license": "ISC", "devDependencies": { "@types/jest": "^29.5.12", "@types/node": "^20.14.9", + "@types/supertest": "^6.0.2", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", "eslint": "^8.57.0", "jest": "^29.7.0", + "supertest": "^7.0.0", "ts-jest": "^29.1.5", "ts-node-dev": "^2.0.0", "typescript": "^5.5.3" @@ -1349,6 +1351,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1392,6 +1400,12 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/methods": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", + "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", + "dev": true + }, "node_modules/@types/node": { "version": "20.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", @@ -1419,6 +1433,27 @@ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", "dev": true }, + "node_modules/@types/superagent": { + "version": "8.1.7", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.7.tgz", + "integrity": "sha512-NmIsd0Yj4DDhftfWvvAku482PZum4DBW7U51OvS8gvOkDDY0WT1jsVyDV3hK+vplrsYw8oDwi9QxOM7U68iwww==", + "dev": true, + "dependencies": { + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*" + } + }, + "node_modules/@types/supertest": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz", + "integrity": "sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==", + "dev": true, + "dependencies": { + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" + } + }, "node_modules/@types/yargs": { "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", @@ -1783,6 +1818,18 @@ "node": ">=8" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -1998,6 +2045,25 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2154,6 +2220,27 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2166,6 +2253,12 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -2253,6 +2346,32 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2262,6 +2381,16 @@ "node": ">=8" } }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -2346,6 +2475,27 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -2616,6 +2766,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -2710,6 +2866,34 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", + "integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==", + "dev": true, + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2757,6 +2941,25 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -2846,6 +3049,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2867,6 +3082,42 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -2879,6 +3130,15 @@ "node": ">= 0.4" } }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3917,6 +4177,15 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", @@ -3930,6 +4199,39 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -4017,6 +4319,18 @@ "node": ">=8" } }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4333,6 +4647,21 @@ } ] }, + "node_modules/qs": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", + "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4494,6 +4823,23 @@ "node": ">=10" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4515,6 +4861,24 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -4648,6 +5012,39 @@ "node": ">=0.10.0" } }, + "node_modules/superagent": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz", + "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==", + "dev": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^3.5.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supertest": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz", + "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==", + "dev": true, + "dependencies": { + "methods": "^1.1.2", + "superagent": "^9.0.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 8c57e45..5581480 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,11 @@ "types": "dist/index.d.ts", "scripts": { "build": "tsc", + "prepublishOnly": "npm run build", "start": "node dist/dev.js", "dev": "ts-node-dev --respawn --transpile-only src/dev.ts", "lint": "eslint . --ext .ts", - "test": "jest" + "test": "jest --config jest.config.js" }, "repository": { "type": "git", diff --git a/src/index.ts b/src/index.ts index 9269bb2..a477c52 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import Server from "./Server"; +import Server from "./main/Server"; const Simpler = Server diff --git a/src/Logger/index.ts b/src/main/Logger/index.ts similarity index 100% rename from src/Logger/index.ts rename to src/main/Logger/index.ts diff --git a/src/Logger/logger.interface.ts b/src/main/Logger/logger.interface.ts similarity index 100% rename from src/Logger/logger.interface.ts rename to src/main/Logger/logger.interface.ts diff --git a/src/Logger/logger.ts b/src/main/Logger/logger.ts similarity index 100% rename from src/Logger/logger.ts rename to src/main/Logger/logger.ts diff --git a/src/Router/index.ts b/src/main/Router/index.ts similarity index 100% rename from src/Router/index.ts rename to src/main/Router/index.ts diff --git a/src/Router/router.interface.ts b/src/main/Router/router.interface.ts similarity index 100% rename from src/Router/router.interface.ts rename to src/main/Router/router.interface.ts diff --git a/src/Router/router.ts b/src/main/Router/router.ts similarity index 100% rename from src/Router/router.ts rename to src/main/Router/router.ts diff --git a/src/Server/index.ts b/src/main/Server/index.ts similarity index 100% rename from src/Server/index.ts rename to src/main/Server/index.ts diff --git a/src/Server/server.interface.ts b/src/main/Server/server.interface.ts similarity index 100% rename from src/Server/server.interface.ts rename to src/main/Server/server.interface.ts diff --git a/src/Server/server.ts b/src/main/Server/server.ts similarity index 98% rename from src/Server/server.ts rename to src/main/Server/server.ts index 918cf3a..3d7bb25 100644 --- a/src/Server/server.ts +++ b/src/main/Server/server.ts @@ -5,7 +5,7 @@ import type ILogger from "../Logger/logger.interface"; import Router from "../Router"; import Logger from "../Logger"; import path from "path"; -import { fileTypes } from "../utils/consts"; +import { fileTypes } from "../../utils/consts"; import { readFile } from "fs/promises"; class Server implements IServer { @@ -120,6 +120,8 @@ class Server implements IServer { ); }); } + + return this.httpServer; } async serveStaticFiles( diff --git a/src/tests/Logger.test.ts b/src/tests/Logger.test.ts new file mode 100644 index 0000000..978dc18 --- /dev/null +++ b/src/tests/Logger.test.ts @@ -0,0 +1,41 @@ +import Logger from "../main/Logger"; + +describe("Logger", () => { + let logger: Logger; + let consoleLogSpy: jest.SpyInstance; + let consoleErrorSpy: jest.SpyInstance; + + beforeEach(() => { + logger = new Logger(); + consoleLogSpy = jest.spyOn(console, "log").mockImplementation(() => {}); + consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {}); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test("log should call console.log with the correct message", () => { + const message = "Test log message"; + logger.log(message); + expect(consoleLogSpy).toHaveBeenCalledWith(message); + }); + + test("logIfVerbose should call log if isVerbose is true", () => { + const message = "Verbose log message"; + logger.logIfVerbose(message, true); + expect(consoleLogSpy).toHaveBeenCalledWith(message); + }); + + test("logIfVerbose should not call log if isVerbose is false", () => { + const message = "Non-verbose log message"; + logger.logIfVerbose(message, false); + expect(consoleLogSpy).not.toHaveBeenCalled(); + }); + + test("error should call console.error with the correct message", () => { + const message = "Test error message"; + logger.error(message); + expect(consoleErrorSpy).toHaveBeenCalledWith(message); + }); +}); diff --git a/src/tests/Router.test.ts b/src/tests/Router.test.ts new file mode 100644 index 0000000..0916e0b --- /dev/null +++ b/src/tests/Router.test.ts @@ -0,0 +1,80 @@ +import Router from "../main/Router"; + +describe("Router", () => { + let router: Router; + + beforeEach(() => { + router = new Router(); + }); + + describe("addRoute", () => { + it("should add a new route", () => { + const callback: RouteCallback = (_req, res) => { + res.writeHead(200, { "Content-Type": "application/json" }); + res.end(JSON.stringify({ message: "success" })); + }; + + router.addRoute("/test", ["GET"], callback); + + const route = router.getRoute("/test", "GET"); + expect(route).not.toBeNull(); + expect(route?.url).toBe("/test"); + expect(route?.method).toContain("GET"); + expect(route?.callback).toBe(callback); + }); + }); + + describe("getRoute", () => { + it("should return the correct route", () => { + const callback: RouteCallback = (_req, res) => { + res.writeHead(200, { "Content-Type": "application/json" }); + res.end(JSON.stringify({ message: "success" })); + }; + + router.addRoute("/test/:id", ["GET"], callback); + + const route = router.getRoute("/test/1", "GET"); + expect(route).not.toBeNull(); + expect(route?.url).toBe("/test/:id"); + expect(route?.method).toContain("GET"); + }); + + it("should return null for non-existing route", () => { + const route = router.getRoute("/non-existent", "GET"); + expect(route).toBeNull(); + }); + }); + + describe("getPathVariables", () => { + it("should extract path variables correctly", () => { + const pathVariables = router.getPathVariables("/test/123", "/test/:id"); + expect(pathVariables).toEqual({ id: "123" }); + }); + }); + + describe("getQueryParams", () => { + it("should extract query parameters correctly", () => { + const queryParams = router.getQueryParams( + "/test?_fields=_all&_sort=createdIn DESC" + ); + expect(queryParams).toEqual({ _fields: "_all", _sort: "createdIn DESC" }); + }); + }); + + describe("addStaticDirectory", () => { + it("should add a static directory", () => { + router.addStaticDirectory("assets"); + const staticDirs = router.getStaticDirs(); + expect(staticDirs).toContain("assets"); + }); + }); + + describe("addStaticDirectories", () => { + it("should add multiple static directories", () => { + router.addStaticDirectories(["assets", "uploads"]); + const staticDirs = router.getStaticDirs(); + expect(staticDirs).toContain("assets"); + expect(staticDirs).toContain("uploads"); + }); + }); +}); diff --git a/src/tests/Server.test.ts b/src/tests/Server.test.ts new file mode 100644 index 0000000..15d430e --- /dev/null +++ b/src/tests/Server.test.ts @@ -0,0 +1,96 @@ +import http, { IncomingMessage, ServerResponse } from "http"; +import Server from "../main/Server"; // Ajuste o caminho conforme necessário +import { readFile } from "fs/promises"; +import path from "path"; + +jest.mock("http"); +jest.mock("fs/promises"); + +describe("Server", () => { + let server: Server; + let mockRequest: Partial; + let mockResponse: Partial; + + beforeEach(() => { + server = new Server(true); + + mockRequest = { + url: "/unknown", + method: "GET", + on: jest.fn().mockImplementation((event, callback) => { + if (event === "data") { + callback(""); + } + if (event === "end") { + callback(); + } + }), + }; + + mockResponse = { + writeHead: jest.fn(), + end: jest.fn(), + }; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it("should create and start the server on the specified port", () => { + const listenMock = jest.fn(); + (http.createServer as jest.Mock).mockReturnValue({ listen: listenMock }); + + const port = 3001; + server.listen(port); + + expect(http.createServer).toHaveBeenCalled(); + expect(listenMock).toHaveBeenCalledWith(port, expect.any(Function)); + }); + + it("should serve static files", async () => { + (readFile as jest.Mock).mockResolvedValue("file content"); + + const req = { url: "/test.txt" } as IncomingMessage; + const res = mockResponse as ServerResponse; + const staticDirsSpy = jest + .spyOn(server.router, "getStaticDirs") + .mockReturnValue(["static"]); + const filePath = path.join(__dirname, "../main/static/test.txt"); + + const result = await server.serveStaticFiles(req, res); + + expect(result).toBe(true); + expect(readFile).toHaveBeenCalledWith(filePath); + expect(mockResponse.writeHead).toHaveBeenCalledWith(200, { + "Content-Type": "application/octet-stream", + }); + expect(mockResponse.end).toHaveBeenCalledWith("file content"); + staticDirsSpy.mockRestore(); + }); + + it("should handle request and call route callback", () => { + const route: Route = { + url: "/test", + method: ["GET"], + callback: jest.fn(), + }; + + const pathVariables = { id: "123" }; + const queryParams = { search: "test" }; + const req = mockRequest as IncomingMessage; + const res = mockResponse as ServerResponse; + + server.handleRequest(req, res, route, pathVariables, queryParams); + + req.on?.("end", () => { + expect(route.callback).toHaveBeenCalledWith( + req, + res, + "", + pathVariables, + queryParams + ); + }); + }); +}); diff --git a/src/typings/global.d.ts b/src/typings/global.d.ts index 30a30a3..4b4852f 100644 --- a/src/typings/global.d.ts +++ b/src/typings/global.d.ts @@ -1,15 +1,21 @@ -type FILE_EXTENSIONS = - | ".html" - | ".js" - | ".css" - | ".json" - | ".png" - | ".jpg" - | ".gif" - | ".wav" - | ".mp4" - | ".woff" - | ".ttf" - | ".eot" - | ".otf" - | ".svg"; +import Server from "../main/Server"; + +declare global { + type FILE_EXTENSIONS = + | ".html" + | ".js" + | ".css" + | ".json" + | ".png" + | ".jpg" + | ".gif" + | ".wav" + | ".mp4" + | ".woff" + | ".ttf" + | ".eot" + | ".otf" + | ".svg"; + + type Simpler = Server; +} diff --git a/src/typings/server.d.ts b/src/typings/server.d.ts index a872dd1..c1ad132 100644 --- a/src/typings/server.d.ts +++ b/src/typings/server.d.ts @@ -9,7 +9,11 @@ declare global { queryParams: Record ) => void; - type ListenFunction = (port?: number) => void; + type ListenFunction = ( + port?: number + ) => + | http.Server + | undefined; type ResponseFunction = ( res: ServerResponse, diff --git a/tsconfig.json b/tsconfig.json index 2d8a193..0c33f48 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,15 @@ { - "compilerOptions": { - "target": "ES6", - "module": "commonjs", - "strict": true, - "declaration": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "outDir": "./dist", - "rootDir": "./src" - }, - "include": ["src"], - "exclude": ["node_modules"] - } - \ No newline at end of file + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "strict": true, + "declaration": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*", "src/typings/**/*"], + "exclude": ["node_modules"] +}