From fa108b6130c57d7e032527ac83bb254318d72db5 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Sun, 7 Jan 2024 22:38:38 +0700 Subject: [PATCH 01/15] feat: add unit test for azure function adapter --- package.json | 7 +- packages/azure-functions/src/adapter.test.ts | 18 + pnpm-lock.yaml | 923 +++++++------------ 3 files changed, 374 insertions(+), 574 deletions(-) create mode 100644 packages/azure-functions/src/adapter.test.ts diff --git a/package.json b/package.json index 3f099c9c..40293c48 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "2.0.0-alpha.8", "description": "Azure Function Nodejs Lightweight framework with Dependency Injection", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "vitest", "format": "prettier --write '**/*.ts'", "dev": "nx run @nammatham/core:build && nx run-many -t dev --projects=@nammatham/* --parallel=5", "pre-local": "tsx ./scripts/pre-local.ts", @@ -32,8 +32,6 @@ "@types/node": "^18.11.18", "@typescript-eslint/eslint-plugin": "^5.55.0", "@typescript-eslint/parser": "^5.55.0", - "ava": "^5.1.1", - "c8": "^7.12.0", "eslint": "^8.36.0", "execa": "^8.0.1", "fs-extra": "^11.2.0", @@ -43,7 +41,8 @@ "prettier": "^2.8.3", "tsup": "^8.0.1", "tsx": "^4.7.0", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "vitest": "^1.1.3" }, "publishConfig": { "registry": "https://registry.npmjs.org/" diff --git a/packages/azure-functions/src/adapter.test.ts b/packages/azure-functions/src/adapter.test.ts new file mode 100644 index 00000000..1db0b316 --- /dev/null +++ b/packages/azure-functions/src/adapter.test.ts @@ -0,0 +1,18 @@ +import { expect, test } from 'vitest'; +import { AzureFunctionsAdapter } from './adapter'; +import { AzureFunctionsTrigger } from './trigger'; +import { NammathamApp } from '@nammatham/core'; + +test(`${AzureFunctionsAdapter.name} should be created correctly`, async () => { + // Arrange + const adapter = new AzureFunctionsAdapter(); + // Act + const app = adapter.createApp(); + const func = adapter.createTrigger(); + + // Assert + expect(func).toBeInstanceOf(AzureFunctionsTrigger); + expect(app).toBeInstanceOf(NammathamApp); + expect(app.runtime === 'azure-functions').toBe(true); + expect(app.isDevelopment).toBe(false); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dd9c0bf4..5f3f3ea7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,12 +23,6 @@ importers: '@typescript-eslint/parser': specifier: ^5.55.0 version: 5.62.0(eslint@8.56.0)(typescript@5.3.3) - ava: - specifier: ^5.1.1 - version: 5.3.1 - c8: - specifier: ^7.12.0 - version: 7.14.0 eslint: specifier: ^8.36.0 version: 8.56.0 @@ -59,6 +53,9 @@ importers: typescript: specifier: ^5.3.3 version: 5.3.3 + vitest: + specifier: ^1.1.3 + version: 1.1.3(@types/node@18.19.4) examples/azure-functions: dependencies: @@ -66,13 +63,13 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@nammatham/azure-functions': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/azure-functions '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/core '@nammatham/express': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/express devDependencies: cross-env: @@ -94,13 +91,13 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@nammatham/azure-functions': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/azure-functions '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/core '@nammatham/express': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/express devDependencies: cross-env: @@ -122,13 +119,13 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@nammatham/azure-functions': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/azure-functions '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/core '@nammatham/express': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/express devDependencies: cross-env: @@ -150,16 +147,16 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@nammatham/azure-functions': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/azure-functions '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/core '@nammatham/express': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/express '@nammatham/trpc-azure-functions': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../../packages/trpc-azure-functions '@trpc/client': specifier: ^10.45.0 @@ -190,7 +187,7 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../core colorette: specifier: ^2.0.20 @@ -233,7 +230,7 @@ importers: packages/express: dependencies: '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../core '@types/express': specifier: ^4.17.21 @@ -248,13 +245,13 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@nammatham/azure-functions': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../azure-functions '@nammatham/core': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../core '@nammatham/express': - specifier: 2.0.0-alpha.7 + specifier: 2.0.0-alpha.8 version: link:../express '@trpc/server': specifier: ^10.45.0 @@ -284,10 +281,6 @@ packages: undici: 5.20.0 dev: false - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - /@esbuild/aix-ppc64@0.19.11: resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} engines: {node: '>=12'} @@ -683,9 +676,11 @@ packages: wrap-ansi-cjs: /wrap-ansi@7.0.0 dev: true - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 dev: true /@jridgewell/gen-mapping@0.3.3: @@ -961,6 +956,10 @@ packages: dev: true optional: true + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + /@trpc/client@10.45.0(@trpc/server@10.45.0): resolution: {integrity: sha512-m091R1qte9rvkvL8N1e/mzrbb8S4gb+Q4ZNJnEGDgd7kic/6a8DFgSciBTiCoSp0YwOTVhyQzSrrA/sZI6PhBg==} peerDependencies: @@ -984,6 +983,10 @@ packages: dependencies: '@types/node': 18.19.4 + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + /@types/express-serve-static-core@4.17.41: resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} dependencies: @@ -1010,10 +1013,6 @@ packages: /@types/http-errors@2.0.4: resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - /@types/istanbul-lib-coverage@2.0.6: - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - dev: true - /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true @@ -1212,6 +1211,45 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true + /@vitest/expect@1.1.3: + resolution: {integrity: sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==} + dependencies: + '@vitest/spy': 1.1.3 + '@vitest/utils': 1.1.3 + chai: 4.4.0 + dev: true + + /@vitest/runner@1.1.3: + resolution: {integrity: sha512-Va2XbWMnhSdDEh/OFxyUltgQuuDRxnarK1hW5QNN4URpQrqq6jtt8cfww/pQQ4i0LjoYxh/3bYWvDFlR9tU73g==} + dependencies: + '@vitest/utils': 1.1.3 + p-limit: 5.0.0 + pathe: 1.1.1 + dev: true + + /@vitest/snapshot@1.1.3: + resolution: {integrity: sha512-U0r8pRXsLAdxSVAyGNcqOU2H3Z4Y2dAAGGelL50O0QRMdi1WWeYHdrH/QWpN1e8juWfVKsb8B+pyJwTC+4Gy9w==} + dependencies: + magic-string: 0.30.5 + pathe: 1.1.1 + pretty-format: 29.7.0 + dev: true + + /@vitest/spy@1.1.3: + resolution: {integrity: sha512-Ec0qWyGS5LhATFQtldvChPTAHv08yHIOZfiNcjwRQbFPHpkih0md9KAbs7TfeIfL7OFKoe7B/6ukBTqByubXkQ==} + dependencies: + tinyspy: 2.2.0 + dev: true + + /@vitest/utils@1.1.3: + resolution: {integrity: sha512-Dyt3UMcdElTll2H75vhxfpZu03uFpXRCHxWnzcrFjZxT1kTbq8ALUYIeBgGolo1gldVdI0YSlQRacsqxTwNqwg==} + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + /@yarnpkg/lockfile@1.1.0: resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} dev: true @@ -1269,14 +1307,6 @@ packages: hasBin: true dev: true - /aggregate-error@4.0.1: - resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} - engines: {node: '>=12'} - dependencies: - clean-stack: 4.2.0 - indent-string: 5.0.0 - dev: true - /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -1322,6 +1352,11 @@ packages: color-convert: 2.0.1 dev: true + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -1356,11 +1391,6 @@ packages: is-array-buffer: 3.0.2 dev: true - /array-find-index@1.0.2: - resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} - engines: {node: '>=0.10.0'} - dev: true - /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: false @@ -1383,14 +1413,8 @@ packages: is-shared-array-buffer: 1.0.2 dev: true - /arrgv@1.0.2: - resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==} - engines: {node: '>=8.0.0'} - dev: true - - /arrify@3.0.0: - resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} - engines: {node: '>=12'} + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true /asynckit@0.4.0: @@ -1402,63 +1426,6 @@ packages: engines: {node: '>=8.0.0'} dev: false - /ava@5.3.1: - resolution: {integrity: sha512-Scv9a4gMOXB6+ni4toLuhAm9KYWEjsgBglJl+kMGI5+IVDt120CCDZyB5HNU9DjmLI2t4I0GbnxGLmmRfGTJGg==} - engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'} - hasBin: true - peerDependencies: - '@ava/typescript': '*' - peerDependenciesMeta: - '@ava/typescript': - optional: true - dependencies: - acorn: 8.11.3 - acorn-walk: 8.3.1 - ansi-styles: 6.2.1 - arrgv: 1.0.2 - arrify: 3.0.0 - callsites: 4.1.0 - cbor: 8.1.0 - chalk: 5.3.0 - chokidar: 3.5.3 - chunkd: 2.0.1 - ci-info: 3.9.0 - ci-parallel-vars: 1.0.1 - clean-yaml-object: 0.1.0 - cli-truncate: 3.1.0 - code-excerpt: 4.0.0 - common-path-prefix: 3.0.0 - concordance: 5.0.4 - currently-unhandled: 0.4.1 - debug: 4.3.4 - emittery: 1.0.1 - figures: 5.0.0 - globby: 13.2.2 - ignore-by-default: 2.1.0 - indent-string: 5.0.0 - is-error: 2.2.2 - is-plain-object: 5.0.0 - is-promise: 4.0.0 - matcher: 5.0.0 - mem: 9.0.2 - ms: 2.1.3 - p-event: 5.0.1 - p-map: 5.5.0 - picomatch: 2.3.1 - pkg-conf: 4.0.0 - plur: 5.1.0 - pretty-ms: 8.0.0 - resolve-cwd: 3.0.0 - stack-utils: 2.0.6 - strip-ansi: 7.1.0 - supertap: 3.0.1 - temp-dir: 3.0.0 - write-file-atomic: 5.0.1 - yargs: 17.7.2 - transitivePeerDependencies: - - supports-color - dev: true - /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -1494,10 +1461,6 @@ packages: readable-stream: 3.6.2 dev: true - /blueimp-md5@2.19.0: - resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} - dev: true - /body-parser@1.20.1: resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -1574,25 +1537,6 @@ packages: engines: {node: '>= 0.8'} dev: false - /c8@7.14.0: - resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==} - engines: {node: '>=10.12.0'} - hasBin: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.1.6 - rimraf: 3.0.2 - test-exclude: 6.0.0 - v8-to-istanbul: 9.2.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 - dev: true - /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -1610,16 +1554,17 @@ packages: engines: {node: '>=6'} dev: true - /callsites@4.1.0: - resolution: {integrity: sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==} - engines: {node: '>=12.20'} - dev: true - - /cbor@8.1.0: - resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} - engines: {node: '>=12.19'} + /chai@4.4.0: + resolution: {integrity: sha512-x9cHNq1uvkCdU+5xTkNh5WtgD4e4yDFCsp9jVc7N7qVeKeftv3gO/ZrviX5d+3ZfxdYnZXZYujjRInu1RogU6A==} + engines: {node: '>=4'} dependencies: - nofilter: 3.1.0 + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 dev: true /chalk@2.4.2: @@ -1639,15 +1584,16 @@ packages: supports-color: 7.2.0 dev: true - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true - /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1663,31 +1609,6 @@ packages: fsevents: 2.3.3 dev: true - /chunkd@2.0.1: - resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} - dev: true - - /ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - dev: true - - /ci-parallel-vars@1.0.1: - resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==} - dev: true - - /clean-stack@4.2.0: - resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} - engines: {node: '>=12'} - dependencies: - escape-string-regexp: 5.0.0 - dev: true - - /clean-yaml-object@0.1.0: - resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} - engines: {node: '>=0.10.0'} - dev: true - /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -1705,14 +1626,6 @@ packages: engines: {node: '>=6'} dev: true - /cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - dev: true - /cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -1735,13 +1648,6 @@ packages: wrap-ansi: 7.0.0 dev: true - /code-excerpt@4.0.0: - resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - convert-to-spaces: 2.0.1 - dev: true - /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -1779,28 +1685,10 @@ packages: engines: {node: '>= 6'} dev: true - /common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - dev: true - /concat-map@0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: true - /concordance@5.0.4: - resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} - engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} - dependencies: - date-time: 3.1.0 - esutils: 2.0.3 - fast-diff: 1.3.0 - js-string-escape: 1.0.1 - lodash: 4.17.21 - md5-hex: 3.0.1 - semver: 7.5.4 - well-known-symbols: 2.0.0 - dev: true - /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -1813,15 +1701,6 @@ packages: engines: {node: '>= 0.6'} dev: false - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - /convert-to-spaces@2.0.1: - resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /cookie-signature@1.0.6: resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} dev: false @@ -1859,20 +1738,6 @@ packages: which: 2.0.2 dev: true - /currently-unhandled@0.4.1: - resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} - engines: {node: '>=0.10.0'} - dependencies: - array-find-index: 1.0.2 - dev: true - - /date-time@3.1.0: - resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} - engines: {node: '>=6'} - dependencies: - time-zone: 1.0.0 - dev: true - /dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} dev: false @@ -1912,6 +1777,13 @@ packages: ms: 2.1.2 dev: true + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -1953,6 +1825,11 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dev: false + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1984,11 +1861,6 @@ packages: resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} dev: false - /emittery@1.0.1: - resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==} - engines: {node: '>=14.16'} - dev: true - /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -2128,21 +2000,11 @@ packages: engines: {node: '>=0.8.0'} dev: true - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true - /escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - dev: true - /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -2250,6 +2112,12 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.5 + dev: true + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2356,10 +2224,6 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - dev: true - /fast-glob@3.2.7: resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} engines: {node: '>=8'} @@ -2412,14 +2276,6 @@ packages: escape-string-regexp: 1.0.5 dev: true - /figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} - dependencies: - escape-string-regexp: 5.0.0 - is-unicode-supported: 1.3.0 - dev: true - /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2457,14 +2313,6 @@ packages: path-exists: 4.0.0 dev: true - /find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - dev: true - /flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2499,14 +2347,6 @@ packages: is-callable: 1.2.7 dev: true - /foreground-child@2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - dev: true - /foreground-child@3.1.1: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} @@ -2581,6 +2421,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + /get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: @@ -2687,17 +2531,6 @@ packages: slash: 3.0.0 dev: true - /globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.0 - merge2: 1.4.1 - slash: 4.0.0 - dev: true - /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -2759,10 +2592,6 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -2797,11 +2626,6 @@ packages: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} dev: true - /ignore-by-default@2.1.0: - resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} - engines: {node: '>=10 <11 || >=12 <13 || >=14'} - dev: true - /ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} @@ -2820,11 +2644,6 @@ packages: engines: {node: '>=0.8.19'} dev: true - /indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - dev: true - /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -2849,11 +2668,6 @@ packages: engines: {node: '>= 0.10'} dev: false - /irregular-plurals@3.5.0: - resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} - engines: {node: '>=8'} - dev: true - /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: @@ -2911,10 +2725,6 @@ packages: hasBin: true dev: true - /is-error@2.2.2: - resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} - dev: true - /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2925,11 +2735,6 @@ packages: engines: {node: '>=8'} dev: true - /is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - dev: true - /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2959,15 +2764,6 @@ packages: engines: {node: '>=8'} dev: true - /is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: true - - /is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - dev: true - /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -3013,11 +2809,6 @@ packages: which-typed-array: 1.1.13 dev: true - /is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - dev: true - /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: @@ -3039,28 +2830,6 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - dev: true - - /istanbul-reports@3.1.6: - resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - dev: true - /jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} @@ -3074,11 +2843,6 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} - /js-string-escape@1.0.1: - resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} - engines: {node: '>= 0.8'} - dev: true - /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -3166,16 +2930,19 @@ packages: strip-bom: 3.0.0 dev: true - /load-json-file@7.0.1: - resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.4.2 + pkg-types: 1.0.3 + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -3183,13 +2950,6 @@ packages: p-locate: 5.0.0 dev: true - /locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-locate: 6.0.0 - dev: true - /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true @@ -3198,14 +2958,16 @@ packages: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} dev: true - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - /long@4.0.0: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} dev: false + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + dev: true + /lru-cache@10.1.0: resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} engines: {node: 14 || >=16.14} @@ -3218,32 +2980,11 @@ packages: yallist: 4.0.0 dev: true - /make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - dependencies: - semver: 7.5.4 - dev: true - - /map-age-cleaner@0.1.3: - resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} - engines: {node: '>=6'} - dependencies: - p-defer: 1.0.0 - dev: true - - /matcher@5.0.0: - resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - escape-string-regexp: 5.0.0 - dev: true - - /md5-hex@3.0.1: - resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} - engines: {node: '>=8'} + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} + engines: {node: '>=12'} dependencies: - blueimp-md5: 2.19.0 + '@jridgewell/sourcemap-codec': 1.4.15 dev: true /media-typer@0.3.0: @@ -3251,14 +2992,6 @@ packages: engines: {node: '>= 0.6'} dev: false - /mem@9.0.2: - resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} - engines: {node: '>=12.20'} - dependencies: - map-age-cleaner: 0.1.3 - mimic-fn: 4.0.0 - dev: true - /memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -3343,6 +3076,15 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dev: true + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.3.2 + dev: true + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: false @@ -3367,6 +3109,12 @@ packages: thenify-all: 1.6.0 dev: true + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -3410,11 +3158,6 @@ packages: undefsafe: 2.0.5 dev: true - /nofilter@3.1.0: - resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} - engines: {node: '>=12.19'} - dev: true - /nopt@1.0.10: resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} hasBin: true @@ -3608,18 +3351,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /p-defer@1.0.0: - resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} - engines: {node: '>=4'} - dev: true - - /p-event@5.0.1: - resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-timeout: 5.1.0 - dev: true - /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -3627,9 +3358,9 @@ packages: yocto-queue: 0.1.0 dev: true - /p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} dependencies: yocto-queue: 1.0.0 dev: true @@ -3641,25 +3372,6 @@ packages: p-limit: 3.1.0 dev: true - /p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-limit: 4.0.0 - dev: true - - /p-map@5.5.0: - resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} - engines: {node: '>=12'} - dependencies: - aggregate-error: 4.0.1 - dev: true - - /p-timeout@5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} - dev: true - /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -3675,11 +3387,6 @@ packages: json-parse-better-errors: 1.0.2 dev: true - /parse-ms@3.0.0: - resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} - engines: {node: '>=12'} - dev: true - /parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -3690,11 +3397,6 @@ packages: engines: {node: '>=8'} dev: true - /path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -3743,6 +3445,18 @@ packages: engines: {node: '>=8'} dev: true + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -3812,19 +3526,12 @@ packages: engines: {node: '>= 6'} dev: true - /pkg-conf@4.0.0: - resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: - find-up: 6.3.0 - load-json-file: 7.0.1 - dev: true - - /plur@5.1.0: - resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - irregular-plurals: 3.5.0 + jsonc-parser: 3.2.0 + mlly: 1.4.2 + pathe: 1.1.1 dev: true /postcss-load-config@4.0.2: @@ -3843,6 +3550,15 @@ packages: yaml: 2.3.4 dev: true + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -3854,11 +3570,13 @@ packages: hasBin: true dev: true - /pretty-ms@8.0.0: - resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} - engines: {node: '>=14.16'} + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - parse-ms: 3.0.0 + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 dev: true /process-warning@3.0.0: @@ -3928,6 +3646,10 @@ packages: unpipe: 1.0.0 dev: false + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + /read-pkg@3.0.0: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} engines: {node: '>=4'} @@ -3983,13 +3705,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4137,13 +3852,6 @@ packages: - supports-color dev: false - /serialize-error@7.0.1: - resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} - engines: {node: '>=10'} - dependencies: - type-fest: 0.13.1 - dev: true - /serve-static@1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} @@ -4213,6 +3921,10 @@ packages: get-intrinsic: 1.2.2 object-inspect: 1.13.1 + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true @@ -4234,25 +3946,17 @@ packages: engines: {node: '>=8'} dev: true - /slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - dev: true - - /slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - dev: true - /sonic-boom@3.7.0: resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==} dependencies: atomic-sleep: 1.0.0 dev: false + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + /source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} @@ -4291,11 +3995,8 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true /statuses@2.0.1: @@ -4303,6 +4004,10 @@ packages: engines: {node: '>= 0.8'} dev: false + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: true + /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -4398,6 +4103,12 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + dependencies: + acorn: 8.11.3 + dev: true + /strong-log-transformer@2.1.0: resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} engines: {node: '>=4'} @@ -4422,16 +4133,6 @@ packages: ts-interface-checker: 0.1.13 dev: true - /supertap@3.0.1: - resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - indent-string: 5.0.0 - js-yaml: 3.14.1 - serialize-error: 7.0.1 - strip-ansi: 7.1.0 - dev: true - /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4462,20 +4163,6 @@ packages: readable-stream: 3.6.2 dev: true - /temp-dir@3.0.0: - resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} - engines: {node: '>=14.16'} - dev: true - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -4503,9 +4190,18 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true - /time-zone@1.0.0: - resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} - engines: {node: '>=4'} + /tinybench@2.5.1: + resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} + dev: true + + /tinypool@0.8.1: + resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} + engines: {node: '>=14.0.0'} dev: true /tmp@0.0.33: @@ -4647,9 +4343,9 @@ packages: prelude-ls: 1.2.1 dev: true - /type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} dev: true /type-fest@0.20.2: @@ -4714,6 +4410,10 @@ packages: hasBin: true dev: true + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} + dev: true + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -4771,15 +4471,6 @@ packages: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true - /v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.20 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 - dev: true - /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -4792,13 +4483,122 @@ packages: engines: {node: '>= 0.8'} dev: false - /webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + /vite-node@1.1.3(@types/node@18.19.4): + resolution: {integrity: sha512-BLSO72YAkIUuNrOx+8uznYICJfTEbvBAmWClY3hpath5+h1mbPS5OMn42lrTxXuyCazVyZoDkSRnju78GiVCqA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 5.0.11(@types/node@18.19.4) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser dev: true - /well-known-symbols@2.0.0: - resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} - engines: {node: '>=6'} + /vite@5.0.11(@types/node@18.19.4): + resolution: {integrity: sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.19.4 + esbuild: 0.19.11 + postcss: 8.4.33 + rollup: 4.9.2 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vitest@1.1.3(@types/node@18.19.4): + resolution: {integrity: sha512-2l8om1NOkiA90/Y207PsEvJLYygddsOyr81wLQ20Ra8IlLKbyQncWsGZjnbkyG2KwwuTXLQjEPOJuxGMG8qJBQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/node': 18.19.4 + '@vitest/expect': 1.1.3 + '@vitest/runner': 1.1.3 + '@vitest/snapshot': 1.1.3 + '@vitest/spy': 1.1.3 + '@vitest/utils': 1.1.3 + acorn-walk: 8.3.1 + cac: 6.7.14 + chai: 4.4.0 + debug: 4.3.4 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.5 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 1.3.0 + tinybench: 2.5.1 + tinypool: 0.8.1 + vite: 5.0.11(@types/node@18.19.4) + vite-node: 1.1.3(@types/node@18.19.4) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} dev: true /whatwg-url@7.1.0: @@ -4845,6 +4645,15 @@ packages: isexe: 2.0.0 dev: true + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -4875,14 +4684,6 @@ packages: /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - /write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 4.1.0 - dev: true - /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -4897,29 +4698,11 @@ packages: engines: {node: '>= 14'} dev: true - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true - /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} dev: true - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} From 072f80d0620b0bfa08fecd1f69ba0e743ebd95a1 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Sun, 7 Jan 2024 22:43:12 +0700 Subject: [PATCH 02/15] [AzureFunctions] add test case for AzureFunctionsHandlerResolver --- packages/azure-functions/src/adapter.test.ts | 2 ++ packages/core/src/nammatham-app.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/azure-functions/src/adapter.test.ts b/packages/azure-functions/src/adapter.test.ts index 1db0b316..c14cfb9b 100644 --- a/packages/azure-functions/src/adapter.test.ts +++ b/packages/azure-functions/src/adapter.test.ts @@ -2,6 +2,7 @@ import { expect, test } from 'vitest'; import { AzureFunctionsAdapter } from './adapter'; import { AzureFunctionsTrigger } from './trigger'; import { NammathamApp } from '@nammatham/core'; +import { AzureFunctionsHandlerResolver } from './handler-resolver'; test(`${AzureFunctionsAdapter.name} should be created correctly`, async () => { // Arrange @@ -15,4 +16,5 @@ test(`${AzureFunctionsAdapter.name} should be created correctly`, async () => { expect(app).toBeInstanceOf(NammathamApp); expect(app.runtime === 'azure-functions').toBe(true); expect(app.isDevelopment).toBe(false); + expect(app.handlerResolver).toBeInstanceOf(AzureFunctionsHandlerResolver); }); diff --git a/packages/core/src/nammatham-app.ts b/packages/core/src/nammatham-app.ts index 81852fd0..3ccc7f5f 100644 --- a/packages/core/src/nammatham-app.ts +++ b/packages/core/src/nammatham-app.ts @@ -19,7 +19,7 @@ export class NammathamApp { */ private _isDevelopment: boolean | undefined; - constructor(protected handlerResolver: BaseHandlerResolver) {} + constructor(public readonly handlerResolver: BaseHandlerResolver) {} /** * Start register functions on the runtime e.g. Azure Functions From 45b0314a71799f0ce73de55268785541d756000c Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Sun, 7 Jan 2024 22:47:47 +0700 Subject: [PATCH 03/15] add coverage script --- package.json | 2 + pnpm-lock.yaml | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/package.json b/package.json index 40293c48..074566b3 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Azure Function Nodejs Lightweight framework with Dependency Injection", "scripts": { "test": "vitest", + "test:coverage": "vitest run --coverage", "format": "prettier --write '**/*.ts'", "dev": "nx run @nammatham/core:build && nx run-many -t dev --projects=@nammatham/* --parallel=5", "pre-local": "tsx ./scripts/pre-local.ts", @@ -32,6 +33,7 @@ "@types/node": "^18.11.18", "@typescript-eslint/eslint-plugin": "^5.55.0", "@typescript-eslint/parser": "^5.55.0", + "@vitest/coverage-v8": "^1.1.3", "eslint": "^8.36.0", "execa": "^8.0.1", "fs-extra": "^11.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f3f3ea7..6d3409f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@typescript-eslint/parser': specifier: ^5.55.0 version: 5.62.0(eslint@8.56.0)(typescript@5.3.3) + '@vitest/coverage-v8': + specifier: ^1.1.3 + version: 1.1.3(vitest@1.1.3) eslint: specifier: ^8.36.0 version: 8.56.0 @@ -273,6 +276,14 @@ packages: engines: {node: '>=0.10.0'} dev: true + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + /@azure/functions@4.1.0: resolution: {integrity: sha512-45WDaJZiTmvaIOPSdWWKL5NgzgUWsNzXDNlF7oCMLS43lE602qG7XE6Hdg9ewPWBj55URHRU7UWTHk4uDVqBGg==} engines: {node: '>=18.0'} @@ -281,6 +292,37 @@ packages: undici: 5.20.0 dev: false + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + /@esbuild/aix-ppc64@0.19.11: resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} engines: {node: '>=12'} @@ -676,6 +718,11 @@ packages: wrap-ansi-cjs: /wrap-ansi@7.0.0 dev: true + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + /@jest/schemas@29.6.3: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1013,6 +1060,10 @@ packages: /@types/http-errors@2.0.4: resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true @@ -1211,6 +1262,29 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true + /@vitest/coverage-v8@1.1.3(vitest@1.1.3): + resolution: {integrity: sha512-Uput7t3eIcbSTOTQBzGtS+0kah96bX+szW9qQrLeGe3UmgL2Akn8POnyC2lH7XsnREZOds9aCUTxgXf+4HX5RA==} + peerDependencies: + vitest: ^1.0.0 + dependencies: + '@ampproject/remapping': 2.2.1 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + magic-string: 0.30.5 + magicast: 0.3.2 + picocolors: 1.0.0 + std-env: 3.7.0 + test-exclude: 6.0.0 + v8-to-istanbul: 9.2.0 + vitest: 1.1.3(@types/node@18.19.4) + transitivePeerDependencies: + - supports-color + dev: true + /@vitest/expect@1.1.3: resolution: {integrity: sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==} dependencies: @@ -1701,6 +1775,10 @@ packages: engines: {node: '>= 0.6'} dev: false + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + /cookie-signature@1.0.6: resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} dev: false @@ -2592,6 +2670,10 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -2830,6 +2912,39 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + /jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} @@ -2987,6 +3102,21 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /magicast@0.3.2: + resolution: {integrity: sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + source-map-js: 1.0.2 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + /media-typer@0.3.0: resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} engines: {node: '>= 0.6'} @@ -3957,6 +4087,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + /source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} @@ -4163,6 +4298,15 @@ packages: readable-stream: 3.6.2 dev: true + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -4218,6 +4362,11 @@ packages: rimraf: 3.0.2 dev: true + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -4471,6 +4620,15 @@ packages: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.20 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + dev: true + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: From 4c669629ccc1b0f010cc903ecc3201bd9cb0cd81 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Mon, 8 Jan 2024 11:45:52 +0700 Subject: [PATCH 04/15] [azure-functions] add test for azureFunctionsHandler --- packages/azure-functions/src/handler.test.ts | 34 ++++++++++++++++++++ packages/azure-functions/src/handler.ts | 4 ++- packages/azure-functions/src/trigger.ts | 3 +- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 packages/azure-functions/src/handler.test.ts diff --git a/packages/azure-functions/src/handler.test.ts b/packages/azure-functions/src/handler.test.ts new file mode 100644 index 00000000..35c7f676 --- /dev/null +++ b/packages/azure-functions/src/handler.test.ts @@ -0,0 +1,34 @@ +import { expect, test } from 'vitest'; +import { AzureFunctionsHandler } from './handler'; +import { InvocationContext } from '@azure/functions'; +test(`${AzureFunctionsHandler.name}.handler should be invoked correctly`, async () => { + // Arrange + const handler = new AzureFunctionsHandler('test', { + extraInputs: [], + extraOutputs: [], + endpointOption: { + type: 'http', + route: 'test', + methods: ['GET'], + } + }, () => ''); + + + // Act + const endpoint = handler.handler((ctx) => 'handlerResult'); + const result = endpoint.invokeHandler({}, new InvocationContext()); + + // Assert + expect(result).toBe('handlerResult'); + // NOTE: invokeHandler should test end-to-end + expect(endpoint.invokeHandler).toBeInstanceOf(Function); + // NOTE: registerFunc should test end-to-end + expect(endpoint.registerFunc).toBeInstanceOf(Function); + + expect(handler).toBeInstanceOf(AzureFunctionsHandler); + expect(endpoint.endpointOption?.type).toBe('http'); + expect(endpoint.endpointOption?.route).toBe('test'); + expect(endpoint.endpointOption?.methods).toEqual(['GET']); + expect(endpoint.type).toBe('azure-functions'); + expect(endpoint.name).toBe('test'); +}); diff --git a/packages/azure-functions/src/handler.ts b/packages/azure-functions/src/handler.ts index 678c0888..301854cc 100644 --- a/packages/azure-functions/src/handler.ts +++ b/packages/azure-functions/src/handler.ts @@ -1,11 +1,13 @@ +import { WithEndpointOption } from '@nammatham/core'; import { NammathamContext } from './nammatham-context'; import type { InvocationContext } from '@azure/functions'; import type { HandlerFunction, RegisterFunctionOption, AzureFunctionsEndpoint, FunctionOption } from './types'; + export class AzureFunctionsHandler { constructor( public funcName: string, - public functionOption: FunctionOption, + public functionOption: WithEndpointOption & FunctionOption, public registerFunc: RegisterFunctionOption ) {} diff --git a/packages/azure-functions/src/trigger.ts b/packages/azure-functions/src/trigger.ts index 6d4e4e68..64c30f76 100644 --- a/packages/azure-functions/src/trigger.ts +++ b/packages/azure-functions/src/trigger.ts @@ -53,7 +53,7 @@ export class AzureFunctionsTrigger extends BaseFunctionTrigger { ...option, endpointOption: { type: 'http', - route: option?.route, + route: option?.route ?? funcName, methods: option?.methods, }, }), @@ -92,6 +92,7 @@ export class AzureFunctionsTrigger extends BaseFunctionTrigger { endpointOption: { ...opt?.endpointOption, route: (opt?.endpointOption as HttpEndpointOption)?.route ?? funcName, + type: (opt?.endpointOption as HttpEndpointOption)?.type ?? 'http', }, extraInputs: opt?.extraInputs ?? [], extraOutputs: opt?.extraOutputs ?? [], From 79ef56f0711ee6b0bde560ea2d0e724780cd360f Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Mon, 8 Jan 2024 12:03:57 +0700 Subject: [PATCH 05/15] [azure-functions] add test for utils --- packages/azure-functions/src/types.ts | 2 +- packages/azure-functions/src/utils.test.ts | 199 +++++++++++++++++++++ packages/azure-functions/src/utils.ts | 16 +- 3 files changed, 209 insertions(+), 8 deletions(-) create mode 100644 packages/azure-functions/src/utils.test.ts diff --git a/packages/azure-functions/src/types.ts b/packages/azure-functions/src/types.ts index 01d6313f..db197056 100644 --- a/packages/azure-functions/src/types.ts +++ b/packages/azure-functions/src/types.ts @@ -1,5 +1,5 @@ import type { FunctionInput, FunctionOutput, InvocationContext } from '@azure/functions'; -import { NammathamContext } from './nammatham-context'; +import type { NammathamContext } from './nammatham-context'; import type { NammamthamEndpoint, PromiseLike } from '@nammatham/core'; export type HandlerFunction = (ctx: NammathamContext) => PromiseLike; diff --git a/packages/azure-functions/src/utils.test.ts b/packages/azure-functions/src/utils.test.ts new file mode 100644 index 00000000..44e56857 --- /dev/null +++ b/packages/azure-functions/src/utils.test.ts @@ -0,0 +1,199 @@ +import { expect, test, describe } from 'vitest'; +import * as utils from './utils'; +describe(`Test utils: ${utils.getMethods.name}`, () => { + test(`${utils.getMethods.name} should parsed to uppercase array`, async () => { + // Arrange + const func = { + endpointOption: { + type: 'http', + methods: ['get', 'post', 'put', 'delete'], + } + } as any; + + // Act + const result = utils.getMethods(func); + + // Assert + expect(result).toEqual(['GET', 'POST', 'PUT', 'DELETE']); + }); + + test(`${utils.getMethods.name} should return empty array if methods is not defined`, async () => { + // Arrange + const func = { + endpointOption: { + type: 'http', + } + } as any; + + // Act + const result = utils.getMethods(func); + + // Assert + expect(result).toEqual([]); + }); +}); + +describe(`Test utils: ${utils.getFullUrl.name}`, () => { + test(`${utils.getFullUrl.name} should return full url`, async () => { + // Arrange + const func = { + endpointOption: { + route: 'test', + } + } as any; + + // Act + const result = utils.getFullUrl(func, 3000); + + // Assert + expect(result).toEqual('http://localhost:3000/api/test'); + }); + + test(`${utils.getFullUrl.name} should return full url with prefix slash in route`, async () => { + // Arrange + const func = { + endpointOption: { + route: '/test', + } + } as any; + + // Act + const result = utils.getFullUrl(func, 3000); + + // Assert + expect(result).toEqual('http://localhost:3000/api/test'); + }); + + test(`${utils.getFullUrl.name} should return empty string if route is not defined`, async () => { + // Arrange + const func = { + endpointOption: { + } + } as any; + + // Act + const result = utils.getFullUrl(func, 3000); + + // Assert + expect(result).toEqual(''); + }); +}); + +describe(`Test utils: ${utils.delay.name}`, () => { + test(`${utils.delay.name} should delay`, async () => { + // Arrange + const start = Date.now(); + + // Act + await utils.delay(10); + + // Assert + expect(Date.now() - start).toBeGreaterThanOrEqual(10); + }); +}); + +describe(`Test utils: ${utils.printRegisteredFunctions.name}`, () => { + test(`${utils.printRegisteredFunctions.name} should print functions`, async () => { + // Arrange + const app = { + functions: [ + { + type: 'azure-functions', + name: 'test', + endpointOption: { + type: 'http', + route: 'test', + methods: ['get', 'post', 'put', 'delete'], + } + }, + { + type: 'azure-functions', + name: 'test2', + endpointOption: { + type: 'timer', + route: 'test2', + methods: ['get', 'post', 'put', 'delete'], + } + }, + ], + } as any; + const option = { + port: 3000, + } as any; + + // Act + const result = await utils.printRegisteredFunctions(app, option); + + // Assert + expect(result).toEqual(app.functions.filter((func: any) => func?.endpointOption?.type === 'http')); + }); + + test(`${utils.printRegisteredFunctions.name} should not print functions if there is no function`, async () => { + // Arrange + const app = { + functions: [], + } as any; + const option = { + port: 3000, + } as any; + + // Act + const result = await utils.printRegisteredFunctions(app, option); + + // Assert + expect(result).toEqual([]); + }); +}); + +describe(`Test utils: ${utils.printRegisteredNonHttpFunctions.name}`, () => { + test(`${utils.printRegisteredNonHttpFunctions.name} should print functions`, async () => { + // Arrange + const app = { + functions: [ + { + type: 'azure-functions', + name: 'test', + endpointOption: { + type: 'http', + route: 'test', + methods: ['get', 'post', 'put', 'delete'], + } + }, + { + type: 'azure-functions', + name: 'test2', + endpointOption: { + type: 'timer', + route: 'test2', + methods: ['get', 'post', 'put', 'delete'], + } + }, + ], + } as any; + const option = { + port: 3000, + } as any; + + // Act + const result = await utils.printRegisteredNonHttpFunctions(app, option); + + // Assert + expect(result).toEqual(app.functions.filter((func: any) => func?.endpointOption?.type !== 'http')); + }); + + test(`${utils.printRegisteredNonHttpFunctions.name} should not print functions if there is no function`, async () => { + // Arrange + const app = { + functions: [], + } as any; + const option = { + port: 3000, + } as any; + + // Act + const result = await utils.printRegisteredNonHttpFunctions(app, option); + + // Assert + expect(result).toEqual([]); + }); +}); \ No newline at end of file diff --git a/packages/azure-functions/src/utils.ts b/packages/azure-functions/src/utils.ts index f138f5e9..2c7cf973 100644 --- a/packages/azure-functions/src/utils.ts +++ b/packages/azure-functions/src/utils.ts @@ -2,7 +2,7 @@ import { blue, green, yellow } from 'colorette'; import { AfterServerStartedMetadata, NammathamApp, trimSlash } from '@nammatham/core'; import { AzureFunctionsEndpoint } from './types'; -function getMethods(func: AzureFunctionsEndpoint): string[] { +export function getMethods(func: AzureFunctionsEndpoint): string[] { if (!Array.isArray(func.endpointOption?.methods)) { return []; } @@ -10,19 +10,19 @@ function getMethods(func: AzureFunctionsEndpoint): string[] { return methods; } -function getFullUrl(func: AzureFunctionsEndpoint, port?: number): string { +export function getFullUrl(func: AzureFunctionsEndpoint, port?: number): string { const endpoint = func.endpointOption?.route ?? func.name; if(typeof endpoint !== 'string') return ''; return `http://localhost${port ? `:${port}` : ''}/api/${trimSlash(endpoint)}`; } -const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); +export const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); -export async function printRegisteredFunctions(app: NammathamApp, option: AfterServerStartedMetadata) { +export async function printRegisteredFunctions(app: NammathamApp, option: AfterServerStartedMetadata): Promise[]> { const azureFunctions = app.functions .filter(func => func.type === 'azure-functions') .filter(func => func.endpointOption?.type === 'http') as AzureFunctionsEndpoint[]; - if (azureFunctions.length === 0) return; + if (azureFunctions.length === 0) return []; await delay(100); console.log(`\n${yellow('Functions:')}\n`); for (const func of azureFunctions) { @@ -30,17 +30,18 @@ export async function printRegisteredFunctions(app: NammathamApp, option: AfterS console.log(`\t${yellow(func.name)}: ${blue(methods)} ${green(getFullUrl(func, option.port))}\n`); } console.log(''); + return azureFunctions; } /** * FIXME: This functions is duplicated with printRegisteredFunctions, it should be merged later. */ -export async function printRegisteredNonHttpFunctions(app: NammathamApp, option: AfterServerStartedMetadata) { +export async function printRegisteredNonHttpFunctions(app: NammathamApp, option: AfterServerStartedMetadata): Promise[]> { const azureFunctions = app.functions.filter(func => func.type === 'azure-functions').filter(func => func.endpointOption?.type !== 'http') as AzureFunctionsEndpoint< any, any >[]; - if (azureFunctions.length === 0) return; + if (azureFunctions.length === 0) return []; await delay(100); console.log(`${yellow(`----------------------------------------------`)}\n`); console.log(`\n${yellow('Non-HTTP Functions (In Develpment Mode Only):')}\n`); @@ -49,4 +50,5 @@ export async function printRegisteredNonHttpFunctions(app: NammathamApp, option: console.log(`\t${yellow(func.name)}: ${blue(methods)} ${green(getFullUrl(func, option.port))}\n`); } console.log(''); + return azureFunctions; } From e4bf0953c9715f597266454dd4ad559a818590c1 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Mon, 8 Jan 2024 12:06:10 +0700 Subject: [PATCH 06/15] github actions: add coverage --- .github/workflows/test.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d339a0d..6a61868d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,18 +2,18 @@ name: "Build & Test" on: push: - branches: [ main, dev ] + branches: [ main ] paths-ignore: - '**/*.md' - '.github' pull_request: - branches: [ main, dev ] + branches: [ main ] paths-ignore: - '**/*.md' - '.github' env: - pnpm_version: 7 + pnpm_version: 8 jobs: build: @@ -22,7 +22,7 @@ jobs: strategy: matrix: - node-version: [16, 18] + node-version: [16, 18, 20] os: [ubuntu-latest, windows-latest] steps: @@ -36,10 +36,8 @@ jobs: with: version: ${{ env.pnpm_version }} - run: pnpm install - - run: npx nx run nammatham:build - - run: npx nx run nammatham:typecheck - - run: npx nx run nammatham:test - - run: npx nx run nammatham:test:coverage + - run: pnpm build + - run: pnpm test:coverage - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 with: From 21b2806225881c39e495b2c5c8634c8f3ff31021 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Mon, 8 Jan 2024 12:10:42 +0700 Subject: [PATCH 07/15] fix: type --- packages/core/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 9539b5d2..37a87784 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -22,7 +22,7 @@ export interface GenericEndpointOption extends EndpointOptionBase, Record }; +export type WithEndpointOption = { endpointOption?: EndpointOption }; export interface NammamthamEndpoint { type: string; From 988266c0960037e7639d5395edbcc2f3676170e3 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Mon, 8 Jan 2024 12:29:54 +0700 Subject: [PATCH 08/15] ignore scripts for coverage test dir --- vitest.config.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 vitest.config.ts diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 00000000..7c484909 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,14 @@ +/// +import { configDefaults, defineConfig } from 'vitest/config' + +export default defineConfig({ + + test: { + coverage: { + exclude: [ + ...configDefaults.coverage.exclude ?? [], + 'scripts', + ] + }, + }, +}); From 83e393e830eeda0830e1f4f357c12696385422f2 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Wed, 10 Jan 2024 19:39:09 +0700 Subject: [PATCH 09/15] [azure-functions] refactor http helper --- .../azure-functions/src/http/HttpRequest.ts | 43 +------------------ .../azure-functions/src/http/http-helpers.ts | 40 +++++++++++++++++ 2 files changed, 42 insertions(+), 41 deletions(-) create mode 100644 packages/azure-functions/src/http/http-helpers.ts diff --git a/packages/azure-functions/src/http/HttpRequest.ts b/packages/azure-functions/src/http/HttpRequest.ts index bb220184..c3a0c3b5 100644 --- a/packages/azure-functions/src/http/HttpRequest.ts +++ b/packages/azure-functions/src/http/HttpRequest.ts @@ -3,55 +3,16 @@ import * as types from '@azure/functions'; import { HttpRequestParams, HttpRequestUser } from '@azure/functions'; import { Blob } from 'buffer'; import express from 'express'; -import { IncomingHttpHeaders } from 'node:http'; import { logger } from '@nammatham/core'; import { ReadableStream } from 'stream/web'; import { FormData, Headers, Request as uRequest } from 'undici'; import { URLSearchParams } from 'url'; - -function convertExpressReqHeaderToHeadersInit(_headers: IncomingHttpHeaders): HeadersInit { - const headers: Record> = {}; - - for (const [key, value] of Object.entries(_headers)) { - if (Array.isArray(value)) { - headers[key] = value; - } else if (value !== undefined) { - headers[key] = value; - } - } - - return headers as HeadersInit; -} - -function convertExpressQueryToURLSearchParams(query: express.Request['query']): URLSearchParams { - const params = new URLSearchParams(); - - for (const [key, value] of Object.entries(query)) { - if (Array.isArray(value)) { - for (const v of value) { - params.append(key, String(v)); - } - } else if (value !== undefined) { - params.append(key, String(value)); - } - } - - return params; -} - -function getExpressReqFullUrl(req: express.Request): string { - const protocol = req.protocol; - const host = req.get('host'); - const path = req.originalUrl; - - return `${protocol}://${host}${path}`; -} +import { convertExpressQueryToURLSearchParams, convertExpressReqHeaderToHeadersInit, getExpressReqFullUrl } from './http-helpers'; export class HttpRequest implements types.HttpRequest { readonly query: URLSearchParams; readonly params: HttpRequestParams; - #cachedUser?: HttpRequestUser | null; #uReq: uRequest; #body?: Buffer | string; @@ -81,8 +42,8 @@ export class HttpRequest implements types.HttpRequest { } /** - * This requres to call `extractHttpUserFromHeaders` in `@azure/functions` internally. * In development, we may don't care this. + * @deprecated This requres to call `extractHttpUserFromHeaders` in `@azure/functions` internally. */ get user(): HttpRequestUser | null { logger.warn(`HttpRequest.user is not supported in development`); diff --git a/packages/azure-functions/src/http/http-helpers.ts b/packages/azure-functions/src/http/http-helpers.ts new file mode 100644 index 00000000..195f641e --- /dev/null +++ b/packages/azure-functions/src/http/http-helpers.ts @@ -0,0 +1,40 @@ +import { IncomingHttpHeaders } from 'node:http'; +import express from 'express'; + +export function convertExpressReqHeaderToHeadersInit(_headers: IncomingHttpHeaders): HeadersInit { + const headers: Record> = {}; + + for (const [key, value] of Object.entries(_headers)) { + if (Array.isArray(value)) { + headers[key] = value; + } else if (value !== undefined) { + headers[key] = value; + } + } + + return headers as HeadersInit; +} + +export function convertExpressQueryToURLSearchParams(query: express.Request['query']): URLSearchParams { + const params = new URLSearchParams(); + + for (const [key, value] of Object.entries(query)) { + if (Array.isArray(value)) { + for (const v of value) { + params.append(key, String(v)); + } + } else if (value !== undefined) { + params.append(key, String(value)); + } + } + + return params; +} + +export function getExpressReqFullUrl(req: express.Request): string { + const protocol = req.protocol; + const host = req.get('host'); + const path = req.originalUrl; + + return `${protocol}://${host}${path}`; +} From a757c99cc015334b563dc6aaf6722983a9378bc4 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Wed, 10 Jan 2024 19:54:15 +0700 Subject: [PATCH 10/15] add eslint for all packages --- .eslintrc.cjs | 10 +++++++++ .eslintrc.js | 24 ---------------------- package.json | 2 ++ packages/azure-functions/package.json | 3 ++- packages/core/package.json | 3 ++- packages/core/src/nammatham-app.ts | 4 ++-- packages/express/package.json | 3 ++- packages/trpc-azure-functions/package.json | 3 ++- 8 files changed, 22 insertions(+), 30 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000..20bc9cc7 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,10 @@ +/* eslint-env node */ +module.exports = { + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + root: true, + rules: { + '@typescript-eslint/consistent-type-imports': 'error', + } + }; \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 7d6d4041..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - // https://stackoverflow.com/questions/58510287/parseroptions-project-has-been-set-for-typescript-eslint-parser - overrides: [ - { - files: ['*.ts', '*.tsx'], // Your TypeScript files extension - - // As mentioned in the comments, you should extend TypeScript plugins here, - // instead of extending them outside the `overrides`. - // If you don't want to extend any rules, you don't need an `extends` attribute. - extends: [ - 'plugin:@typescript-eslint/recommended', - // 'plugin:@typescript-eslint/recommended-requiring-type-checking', - // 'plugin:@typescript-eslint/strict', - ], - - parserOptions: { - project: ['./tsconfig.json'], // Specify it only for TypeScript files - }, - }, - ], - root: true, -}; diff --git a/package.json b/package.json index 074566b3..753b2e94 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "post-local": "tsx ./scripts/post-local.ts", "release": "run-s build releaseOnly", "releaseOnly": "tsx ./scripts/release.ts", + "lint": "nx run-many -t lint --projects=@nammatham/* --parallel=5", + "lint:fix": "nx run-many -t lint:fix --projects=@nammatham/* --parallel=5", "build": "nx run-many -t build --parallel=10", "azurite": "pnpx azurite --silent --location ./.azurite --debug ./.azurite/debug.log" }, diff --git a/packages/azure-functions/package.json b/packages/azure-functions/package.json index f5585e15..a06d4b0d 100644 --- a/packages/azure-functions/package.json +++ b/packages/azure-functions/package.json @@ -8,7 +8,8 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit", + "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", + "lint:fix": "npx eslint --fix ./src && npx prettier -c src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ diff --git a/packages/core/package.json b/packages/core/package.json index 4e774c13..f352451a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -8,7 +8,8 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit", + "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", + "lint:fix": "npx eslint --fix ./src && npx prettier -c src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ diff --git a/packages/core/src/nammatham-app.ts b/packages/core/src/nammatham-app.ts index 3ccc7f5f..1e9f69d0 100644 --- a/packages/core/src/nammatham-app.ts +++ b/packages/core/src/nammatham-app.ts @@ -1,7 +1,7 @@ import { magenta } from 'colorette'; import { logger } from './main'; -import { BaseHandlerResolver } from './bases'; -import { NammamthamEndpoint } from './types'; +import type { BaseHandlerResolver } from './bases'; +import type { NammamthamEndpoint } from './types'; export class NammathamApp { protected readonly _functions: NammamthamEndpoint[] = []; diff --git a/packages/express/package.json b/packages/express/package.json index 0bca1e7b..172ef2b8 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -8,7 +8,8 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit", + "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", + "lint:fix": "npx eslint --fix ./src && npx prettier -c src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ diff --git a/packages/trpc-azure-functions/package.json b/packages/trpc-azure-functions/package.json index 717bc2a9..2dbc0f31 100644 --- a/packages/trpc-azure-functions/package.json +++ b/packages/trpc-azure-functions/package.json @@ -8,7 +8,8 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit", + "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", + "lint:fix": "npx eslint --fix ./src && npx prettier -w src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ From c5b9cbd7e1a31f73b5ab8802b5066536fa387b8f Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Wed, 10 Jan 2024 20:02:34 +0700 Subject: [PATCH 11/15] fix with eslint --- packages/azure-functions/src/handler-resolver.ts | 10 ++++++---- packages/azure-functions/src/handler.ts | 2 +- packages/azure-functions/src/http/HttpRequest.ts | 15 ++++++++------- packages/azure-functions/src/http/http-helpers.ts | 4 ++-- packages/azure-functions/src/trigger.ts | 9 +++++---- packages/azure-functions/src/utils.ts | 5 +++-- packages/core/src/bases/base-handler-resolver.ts | 4 ++-- packages/core/src/bases/base-runtime-adapter.ts | 2 +- packages/core/src/init-nammatham.ts | 4 ++-- packages/express/src/express-server.ts | 5 +++-- packages/express/src/middleware.ts | 7 ++++--- packages/express/src/types.ts | 2 +- packages/trpc-azure-functions/src/main.ts | 2 +- .../src/trpc-azure-functions.ts | 13 ++++++++----- packages/trpc-azure-functions/src/trpc.ts | 8 ++------ packages/trpc-azure-functions/src/types.ts | 2 +- 16 files changed, 50 insertions(+), 44 deletions(-) diff --git a/packages/azure-functions/src/handler-resolver.ts b/packages/azure-functions/src/handler-resolver.ts index 462e3b25..865f0e1b 100644 --- a/packages/azure-functions/src/handler-resolver.ts +++ b/packages/azure-functions/src/handler-resolver.ts @@ -1,6 +1,8 @@ -import { BaseHandlerResolver, NammathamApp, logger, AfterServerStartedMetadata } from '@nammatham/core'; -import { Cookie, HttpResponse, InvocationContext, LogLevel } from '@azure/functions'; -import { AzureFunctionsEndpoint } from './types'; +import type { NammathamApp, AfterServerStartedMetadata } from '@nammatham/core'; +import { BaseHandlerResolver, logger } from '@nammatham/core'; +import type { Cookie, LogLevel } from '@azure/functions'; +import { HttpResponse, InvocationContext } from '@azure/functions'; +import type { AzureFunctionsEndpoint } from './types'; import type { Request as ExpressRequest, Response as ExpressResponse, @@ -29,7 +31,7 @@ function logExecutedFunction( * Map InvocationContext log level to logger */ -function logHandler(level: LogLevel, ...args: any[]) { +function logHandler(level: LogLevel, ...args: unknown[]) { if (level === 'information') { logger.info(...args); } else if (level === 'error') { diff --git a/packages/azure-functions/src/handler.ts b/packages/azure-functions/src/handler.ts index 301854cc..2b80a950 100644 --- a/packages/azure-functions/src/handler.ts +++ b/packages/azure-functions/src/handler.ts @@ -1,4 +1,4 @@ -import { WithEndpointOption } from '@nammatham/core'; +import type { WithEndpointOption } from '@nammatham/core'; import { NammathamContext } from './nammatham-context'; import type { InvocationContext } from '@azure/functions'; import type { HandlerFunction, RegisterFunctionOption, AzureFunctionsEndpoint, FunctionOption } from './types'; diff --git a/packages/azure-functions/src/http/HttpRequest.ts b/packages/azure-functions/src/http/HttpRequest.ts index c3a0c3b5..0fed1d8e 100644 --- a/packages/azure-functions/src/http/HttpRequest.ts +++ b/packages/azure-functions/src/http/HttpRequest.ts @@ -1,12 +1,13 @@ // Adapted from https://github.com/Azure/azure-functions-nodejs-library/blob/v4.x/src/http/HttpRequest.ts -import * as types from '@azure/functions'; -import { HttpRequestParams, HttpRequestUser } from '@azure/functions'; -import { Blob } from 'buffer'; -import express from 'express'; +import type * as types from '@azure/functions'; +import type { HttpRequestParams, HttpRequestUser } from '@azure/functions'; +import type { Blob } from 'buffer'; +import type express from 'express'; import { logger } from '@nammatham/core'; -import { ReadableStream } from 'stream/web'; -import { FormData, Headers, Request as uRequest } from 'undici'; -import { URLSearchParams } from 'url'; +import type { ReadableStream } from 'stream/web'; +import type { FormData, Headers} from 'undici'; +import { Request as uRequest } from 'undici'; +import type { URLSearchParams } from 'url'; import { convertExpressQueryToURLSearchParams, convertExpressReqHeaderToHeadersInit, getExpressReqFullUrl } from './http-helpers'; export class HttpRequest implements types.HttpRequest { diff --git a/packages/azure-functions/src/http/http-helpers.ts b/packages/azure-functions/src/http/http-helpers.ts index 195f641e..802b6d1e 100644 --- a/packages/azure-functions/src/http/http-helpers.ts +++ b/packages/azure-functions/src/http/http-helpers.ts @@ -1,5 +1,5 @@ -import { IncomingHttpHeaders } from 'node:http'; -import express from 'express'; +import type { IncomingHttpHeaders } from 'node:http'; +import type express from 'express'; export function convertExpressReqHeaderToHeadersInit(_headers: IncomingHttpHeaders): HeadersInit { const headers: Record> = {}; diff --git a/packages/azure-functions/src/trigger.ts b/packages/azure-functions/src/trigger.ts index 64c30f76..f8ceae71 100644 --- a/packages/azure-functions/src/trigger.ts +++ b/packages/azure-functions/src/trigger.ts @@ -1,8 +1,9 @@ -import type { GenericFunctionOptions, HttpFunctionOptions, HttpRequest, HttpResponse, HttpResponseInit, Timer, TimerFunctionOptions } from '@azure/functions'; -import { app, HttpMethodFunctionOptions } from '@azure/functions'; +import type { GenericFunctionOptions, HttpFunctionOptions, HttpRequest, HttpResponse, HttpResponseInit, Timer, TimerFunctionOptions , HttpMethodFunctionOptions } from '@azure/functions'; +import { app } from '@azure/functions'; import { AzureFunctionsHandler } from './handler'; -import { FunctionOption } from './types'; -import { HttpEndpointOption, WithEndpointOption, BaseFunctionTrigger } from '@nammatham/core'; +import type { FunctionOption } from './types'; +import type { HttpEndpointOption, WithEndpointOption} from '@nammatham/core'; +import { BaseFunctionTrigger } from '@nammatham/core'; export class AzureFunctionsTrigger extends BaseFunctionTrigger { generic(funcName: string, option: Omit) { diff --git a/packages/azure-functions/src/utils.ts b/packages/azure-functions/src/utils.ts index 2c7cf973..2161220d 100644 --- a/packages/azure-functions/src/utils.ts +++ b/packages/azure-functions/src/utils.ts @@ -1,6 +1,7 @@ import { blue, green, yellow } from 'colorette'; -import { AfterServerStartedMetadata, NammathamApp, trimSlash } from '@nammatham/core'; -import { AzureFunctionsEndpoint } from './types'; +import type { AfterServerStartedMetadata, NammathamApp} from '@nammatham/core'; +import { trimSlash } from '@nammatham/core'; +import type { AzureFunctionsEndpoint } from './types'; export function getMethods(func: AzureFunctionsEndpoint): string[] { if (!Array.isArray(func.endpointOption?.methods)) { diff --git a/packages/core/src/bases/base-handler-resolver.ts b/packages/core/src/bases/base-handler-resolver.ts index ce8198b2..40b8b5b6 100644 --- a/packages/core/src/bases/base-handler-resolver.ts +++ b/packages/core/src/bases/base-handler-resolver.ts @@ -1,6 +1,6 @@ -import { AfterServerStartedMetadata, NammamthamEndpoint } from '../types'; +import type { AfterServerStartedMetadata, NammamthamEndpoint } from '../types'; import type { Request, Response } from 'express'; -import { NammathamApp } from '../nammatham-app'; +import type { NammathamApp } from '../nammatham-app'; export abstract class BaseHandlerResolver { abstract resolveHandler(endpoint: NammamthamEndpoint, req: Request, res: Response): any; diff --git a/packages/core/src/bases/base-runtime-adapter.ts b/packages/core/src/bases/base-runtime-adapter.ts index d7fb0f74..6d62ef07 100644 --- a/packages/core/src/bases/base-runtime-adapter.ts +++ b/packages/core/src/bases/base-runtime-adapter.ts @@ -1,4 +1,4 @@ -import { NammathamApp } from '../nammatham-app'; +import type { NammathamApp } from '../nammatham-app'; export abstract class BaseRuntimeAdapter { abstract createTrigger(): FunctionTrigger; diff --git a/packages/core/src/init-nammatham.ts b/packages/core/src/init-nammatham.ts index 78c7f353..9db509a8 100644 --- a/packages/core/src/init-nammatham.ts +++ b/packages/core/src/init-nammatham.ts @@ -1,6 +1,6 @@ -import { BaseRuntimeAdapter } from './bases/base-runtime-adapter'; +import type { BaseRuntimeAdapter } from './bases/base-runtime-adapter'; import { DefaultAdapter } from './default-adapter'; -import { NammathamApp } from './nammatham-app'; +import type { NammathamApp } from './nammatham-app'; import { logger } from './main'; import { yellow } from 'colorette'; diff --git a/packages/express/src/express-server.ts b/packages/express/src/express-server.ts index 691c89e8..ce9efbf2 100644 --- a/packages/express/src/express-server.ts +++ b/packages/express/src/express-server.ts @@ -1,7 +1,8 @@ import express from 'express'; import { createExpressMiddleware } from './middleware'; -import { BaseHandlerResolver, NammathamApp, logger } from '@nammatham/core'; -import { NammathamHttpHandlerOption } from './types'; +import type { BaseHandlerResolver, NammathamApp} from '@nammatham/core'; +import { logger } from '@nammatham/core'; +import type { NammathamHttpHandlerOption } from './types'; export interface ExpressServerOption { prefix?: string; diff --git a/packages/express/src/middleware.ts b/packages/express/src/middleware.ts index 908c2ec8..0efe5654 100644 --- a/packages/express/src/middleware.ts +++ b/packages/express/src/middleware.ts @@ -1,7 +1,8 @@ // Adapted from: https://github.com/trpc/trpc/tree/main/packages/server/src/adapters/express.ts -import express from 'express'; -import { NammathamHttpHandlerOption } from './types'; -import { logger, HttpMethod } from '@nammatham/core'; +import type express from 'express'; +import type { NammathamHttpHandlerOption } from './types'; +import type { HttpMethod } from '@nammatham/core'; +import { logger } from '@nammatham/core'; interface NammathamAppRequestOption extends NammathamHttpHandlerOption { req: express.Request; diff --git a/packages/express/src/types.ts b/packages/express/src/types.ts index 4e0dc4e4..febbc3fc 100644 --- a/packages/express/src/types.ts +++ b/packages/express/src/types.ts @@ -1,4 +1,4 @@ -import { BaseHandlerResolver, NammathamApp } from '@nammatham/core'; +import type { BaseHandlerResolver, NammathamApp } from '@nammatham/core'; export interface NammathamHttpHandlerOption { handlerResolver: BaseHandlerResolver; diff --git a/packages/trpc-azure-functions/src/main.ts b/packages/trpc-azure-functions/src/main.ts index ef655b1a..156783c7 100644 --- a/packages/trpc-azure-functions/src/main.ts +++ b/packages/trpc-azure-functions/src/main.ts @@ -1,2 +1,2 @@ export * from './types'; -export * from './trpc-azure-functions'; \ No newline at end of file +export * from './trpc-azure-functions'; diff --git a/packages/trpc-azure-functions/src/trpc-azure-functions.ts b/packages/trpc-azure-functions/src/trpc-azure-functions.ts index 1aa74e3a..c5286257 100644 --- a/packages/trpc-azure-functions/src/trpc-azure-functions.ts +++ b/packages/trpc-azure-functions/src/trpc-azure-functions.ts @@ -1,9 +1,12 @@ -import { BaseHandlerResolver, NammathamApp, logger, trimSlash } from '@nammatham/core'; -import { HttpRequest as AzureHttpRequest } from '@azure/functions'; -import { AzureFunctionsOptions, wrapAzureFunctionsRequestHandler } from 'trpc-azure-functions-adapter'; -import { AnyRouter } from '@trpc/server'; +import type { BaseHandlerResolver } from '@nammatham/core'; +import { NammathamApp, logger, trimSlash } from '@nammatham/core'; +import type { HttpRequest as AzureHttpRequest } from '@azure/functions'; +import type { AzureFunctionsOptions } from 'trpc-azure-functions-adapter'; +import { wrapAzureFunctionsRequestHandler } from 'trpc-azure-functions-adapter'; +import type { AnyRouter } from '@trpc/server'; import { AzureFunctionsTrigger } from '@nammatham/azure-functions'; -import { ExpressServerOption, startExpress } from '@nammatham/express'; +import type { ExpressServerOption } from '@nammatham/express'; +import { startExpress } from '@nammatham/express'; import express from 'express'; import * as trpcExpress from '@trpc/server/adapters/express'; import { createContext } from './trpc'; diff --git a/packages/trpc-azure-functions/src/trpc.ts b/packages/trpc-azure-functions/src/trpc.ts index 1aca12ba..fb75409d 100644 --- a/packages/trpc-azure-functions/src/trpc.ts +++ b/packages/trpc-azure-functions/src/trpc.ts @@ -1,10 +1,6 @@ import { initTRPC } from '@trpc/server'; -import * as trpcExpress from '@trpc/server/adapters/express'; +import type * as trpcExpress from '@trpc/server/adapters/express'; // created for each request -export const createContext = ({ - req, - res, -}: trpcExpress.CreateExpressContextOptions) => ({}); // no context +export const createContext = ({ req, res }: trpcExpress.CreateExpressContextOptions) => ({}); // no context export type Context = Awaited>; - diff --git a/packages/trpc-azure-functions/src/types.ts b/packages/trpc-azure-functions/src/types.ts index 72cf77a0..c48c9539 100644 --- a/packages/trpc-azure-functions/src/types.ts +++ b/packages/trpc-azure-functions/src/types.ts @@ -1 +1 @@ -export type trpc = 'trpc'; \ No newline at end of file +export type trpc = 'trpc'; From 419d6b0a036a9ff27d758d44696c53030fc96712 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Wed, 10 Jan 2024 20:26:26 +0700 Subject: [PATCH 12/15] fix: following by eslint & prettier --- .eslintrc.cjs | 1 + package.json | 2 +- packages/azure-functions/package.json | 5 +-- .../azure-functions/src/handler-resolver.ts | 9 ++--- packages/azure-functions/src/handler.test.ts | 27 ++++++++------- packages/azure-functions/src/handler.ts | 1 - .../azure-functions/src/http/HttpRequest.ts | 10 ++++-- packages/azure-functions/src/trigger.ts | 34 +++++++++---------- packages/azure-functions/src/types.ts | 8 +++-- packages/azure-functions/src/utils.test.ts | 21 ++++++------ packages/azure-functions/src/utils.ts | 27 +++++++++------ packages/core/package.json | 5 +-- packages/core/src/logger.ts | 2 +- packages/core/src/main.ts | 2 +- packages/core/src/nammatham-app.ts | 3 +- packages/express/package.json | 5 +-- packages/express/src/express-server.ts | 9 +++-- packages/express/src/types.ts | 2 +- packages/trpc-azure-functions/package.json | 5 +-- 19 files changed, 100 insertions(+), 78 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 20bc9cc7..8bcc4b81 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,6 +4,7 @@ module.exports = { parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint'], root: true, + ignorePatterns: ["**.test.ts"], rules: { '@typescript-eslint/consistent-type-imports': 'error', } diff --git a/package.json b/package.json index 753b2e94..fdeaf26f 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,12 @@ "scripts": { "test": "vitest", "test:coverage": "vitest run --coverage", - "format": "prettier --write '**/*.ts'", "dev": "nx run @nammatham/core:build && nx run-many -t dev --projects=@nammatham/* --parallel=5", "pre-local": "tsx ./scripts/pre-local.ts", "post-local": "tsx ./scripts/post-local.ts", "release": "run-s build releaseOnly", "releaseOnly": "tsx ./scripts/release.ts", + "format": "nx run-many -t format --projects=@nammatham/* --parallel=5", "lint": "nx run-many -t lint --projects=@nammatham/* --parallel=5", "lint:fix": "nx run-many -t lint:fix --projects=@nammatham/* --parallel=5", "build": "nx run-many -t build --parallel=10", diff --git a/packages/azure-functions/package.json b/packages/azure-functions/package.json index a06d4b0d..95b807d1 100644 --- a/packages/azure-functions/package.json +++ b/packages/azure-functions/package.json @@ -8,8 +8,9 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", - "lint:fix": "npx eslint --fix ./src && npx prettier -c src", + "format": "prettier -w src", + "lint": "tsc --noEmit && eslint ./src && prettier -c src", + "lint:fix": "eslint --fix ./src && prettier -c src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ diff --git a/packages/azure-functions/src/handler-resolver.ts b/packages/azure-functions/src/handler-resolver.ts index 865f0e1b..80405b54 100644 --- a/packages/azure-functions/src/handler-resolver.ts +++ b/packages/azure-functions/src/handler-resolver.ts @@ -119,11 +119,12 @@ export class AzureFunctionsHandlerResolver extends BaseHandlerResolver { logger.info( `Executing 'Functions.${endpoint.name}' (Reason='This function was programmatically called via the host APIs.', Id=${context.invocationId})` ); - let result: any; + let result: HttpResponse | string | undefined | unknown; try { result = await endpoint.invokeHandler(new HttpRequest(req), context); logExecutedFunction(startTime, endpoint, context, 'Succeeded'); - if (result === undefined) return; + if (result === undefined || result === null) return; + if (typeof result === 'string') return res.send(result); const response = result instanceof HttpResponse ? result : new HttpResponse(result); return await convertHttpResponseToExpressResponse(res, response); } catch (error) { @@ -136,8 +137,8 @@ export class AzureFunctionsHandlerResolver extends BaseHandlerResolver { override async resolveRegisterHandler(app: NammathamApp) { logger.debug(`Starting using Azure Functions register handler`); const azureFunctions = app.functions.filter(func => func.type === 'azure-functions') as AzureFunctionsEndpoint< - any, - any + unknown, + unknown >[]; if (azureFunctions.length === 0) { diff --git a/packages/azure-functions/src/handler.test.ts b/packages/azure-functions/src/handler.test.ts index 35c7f676..45d72ff1 100644 --- a/packages/azure-functions/src/handler.test.ts +++ b/packages/azure-functions/src/handler.test.ts @@ -3,26 +3,29 @@ import { AzureFunctionsHandler } from './handler'; import { InvocationContext } from '@azure/functions'; test(`${AzureFunctionsHandler.name}.handler should be invoked correctly`, async () => { // Arrange - const handler = new AzureFunctionsHandler('test', { - extraInputs: [], - extraOutputs: [], - endpointOption: { - type: 'http', - route: 'test', - methods: ['GET'], - } - }, () => ''); - + const handler = new AzureFunctionsHandler( + 'test', + { + extraInputs: [], + extraOutputs: [], + endpointOption: { + type: 'http', + route: 'test', + methods: ['GET'], + }, + }, + () => '' + ); // Act - const endpoint = handler.handler((ctx) => 'handlerResult'); + const endpoint = handler.handler(() => 'handlerResult'); const result = endpoint.invokeHandler({}, new InvocationContext()); // Assert expect(result).toBe('handlerResult'); // NOTE: invokeHandler should test end-to-end expect(endpoint.invokeHandler).toBeInstanceOf(Function); - // NOTE: registerFunc should test end-to-end + // NOTE: registerFunc should test end-to-end expect(endpoint.registerFunc).toBeInstanceOf(Function); expect(handler).toBeInstanceOf(AzureFunctionsHandler); diff --git a/packages/azure-functions/src/handler.ts b/packages/azure-functions/src/handler.ts index 2b80a950..271477a9 100644 --- a/packages/azure-functions/src/handler.ts +++ b/packages/azure-functions/src/handler.ts @@ -3,7 +3,6 @@ import { NammathamContext } from './nammatham-context'; import type { InvocationContext } from '@azure/functions'; import type { HandlerFunction, RegisterFunctionOption, AzureFunctionsEndpoint, FunctionOption } from './types'; - export class AzureFunctionsHandler { constructor( public funcName: string, diff --git a/packages/azure-functions/src/http/HttpRequest.ts b/packages/azure-functions/src/http/HttpRequest.ts index 0fed1d8e..f628b446 100644 --- a/packages/azure-functions/src/http/HttpRequest.ts +++ b/packages/azure-functions/src/http/HttpRequest.ts @@ -5,10 +5,14 @@ import type { Blob } from 'buffer'; import type express from 'express'; import { logger } from '@nammatham/core'; import type { ReadableStream } from 'stream/web'; -import type { FormData, Headers} from 'undici'; +import type { FormData, Headers } from 'undici'; import { Request as uRequest } from 'undici'; import type { URLSearchParams } from 'url'; -import { convertExpressQueryToURLSearchParams, convertExpressReqHeaderToHeadersInit, getExpressReqFullUrl } from './http-helpers'; +import { + convertExpressQueryToURLSearchParams, + convertExpressReqHeaderToHeadersInit, + getExpressReqFullUrl, +} from './http-helpers'; export class HttpRequest implements types.HttpRequest { readonly query: URLSearchParams; @@ -51,7 +55,7 @@ export class HttpRequest implements types.HttpRequest { return null; } - get body(): ReadableStream | null { + get body(): ReadableStream | null { return this.#uReq.body; } diff --git a/packages/azure-functions/src/trigger.ts b/packages/azure-functions/src/trigger.ts index f8ceae71..447557a8 100644 --- a/packages/azure-functions/src/trigger.ts +++ b/packages/azure-functions/src/trigger.ts @@ -1,8 +1,17 @@ -import type { GenericFunctionOptions, HttpFunctionOptions, HttpRequest, HttpResponse, HttpResponseInit, Timer, TimerFunctionOptions , HttpMethodFunctionOptions } from '@azure/functions'; +import type { + GenericFunctionOptions, + HttpFunctionOptions, + HttpRequest, + HttpResponse, + HttpResponseInit, + Timer, + TimerFunctionOptions, + HttpMethodFunctionOptions, +} from '@azure/functions'; import { app } from '@azure/functions'; import { AzureFunctionsHandler } from './handler'; import type { FunctionOption } from './types'; -import type { HttpEndpointOption, WithEndpointOption} from '@nammatham/core'; +import type { HttpEndpointOption, WithEndpointOption } from '@nammatham/core'; import { BaseFunctionTrigger } from '@nammatham/core'; export class AzureFunctionsTrigger extends BaseFunctionTrigger { @@ -68,21 +77,12 @@ export class AzureFunctionsTrigger extends BaseFunctionTrigger { } timer(funcName: string, option: Omit) { - return new AzureFunctionsHandler( - funcName, - this.parseFunctionOption(funcName, option), - funcOption => { - app.timer(funcName, { - ...option, - ...funcOption, - }); - } - ); - } - - storageQueue(funcName: string, option: any) { - // TODO: Implement later - return new AzureFunctionsHandler(funcName, this.parseFunctionOption(funcName, option), option); + return new AzureFunctionsHandler(funcName, this.parseFunctionOption(funcName, option), funcOption => { + app.timer(funcName, { + ...option, + ...funcOption, + }); + }); } private parseFunctionOption( diff --git a/packages/azure-functions/src/types.ts b/packages/azure-functions/src/types.ts index db197056..9d53c3ac 100644 --- a/packages/azure-functions/src/types.ts +++ b/packages/azure-functions/src/types.ts @@ -2,9 +2,13 @@ import type { FunctionInput, FunctionOutput, InvocationContext } from '@azure/fu import type { NammathamContext } from './nammatham-context'; import type { NammamthamEndpoint, PromiseLike } from '@nammatham/core'; -export type HandlerFunction = (ctx: NammathamContext) => PromiseLike; +export type HandlerFunction = ( + ctx: NammathamContext +) => PromiseLike; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type AnyHandler = (triggerInput: unknown, context: InvocationContext) => PromiseLike; -export type AnyHandler = (triggerInput: any, context: InvocationContext) => PromiseLike; export type RegisterFunctionOption = (option: { handler: AnyHandler; extraInputs: FunctionInput[]; diff --git a/packages/azure-functions/src/utils.test.ts b/packages/azure-functions/src/utils.test.ts index 44e56857..5ad8188e 100644 --- a/packages/azure-functions/src/utils.test.ts +++ b/packages/azure-functions/src/utils.test.ts @@ -7,7 +7,7 @@ describe(`Test utils: ${utils.getMethods.name}`, () => { endpointOption: { type: 'http', methods: ['get', 'post', 'put', 'delete'], - } + }, } as any; // Act @@ -22,7 +22,7 @@ describe(`Test utils: ${utils.getMethods.name}`, () => { const func = { endpointOption: { type: 'http', - } + }, } as any; // Act @@ -39,7 +39,7 @@ describe(`Test utils: ${utils.getFullUrl.name}`, () => { const func = { endpointOption: { route: 'test', - } + }, } as any; // Act @@ -54,7 +54,7 @@ describe(`Test utils: ${utils.getFullUrl.name}`, () => { const func = { endpointOption: { route: '/test', - } + }, } as any; // Act @@ -67,8 +67,7 @@ describe(`Test utils: ${utils.getFullUrl.name}`, () => { test(`${utils.getFullUrl.name} should return empty string if route is not defined`, async () => { // Arrange const func = { - endpointOption: { - } + endpointOption: {}, } as any; // Act @@ -104,7 +103,7 @@ describe(`Test utils: ${utils.printRegisteredFunctions.name}`, () => { type: 'http', route: 'test', methods: ['get', 'post', 'put', 'delete'], - } + }, }, { type: 'azure-functions', @@ -113,7 +112,7 @@ describe(`Test utils: ${utils.printRegisteredFunctions.name}`, () => { type: 'timer', route: 'test2', methods: ['get', 'post', 'put', 'delete'], - } + }, }, ], } as any; @@ -157,7 +156,7 @@ describe(`Test utils: ${utils.printRegisteredNonHttpFunctions.name}`, () => { type: 'http', route: 'test', methods: ['get', 'post', 'put', 'delete'], - } + }, }, { type: 'azure-functions', @@ -166,7 +165,7 @@ describe(`Test utils: ${utils.printRegisteredNonHttpFunctions.name}`, () => { type: 'timer', route: 'test2', methods: ['get', 'post', 'put', 'delete'], - } + }, }, ], } as any; @@ -196,4 +195,4 @@ describe(`Test utils: ${utils.printRegisteredNonHttpFunctions.name}`, () => { // Assert expect(result).toEqual([]); }); -}); \ No newline at end of file +}); diff --git a/packages/azure-functions/src/utils.ts b/packages/azure-functions/src/utils.ts index 2161220d..f6cd0433 100644 --- a/packages/azure-functions/src/utils.ts +++ b/packages/azure-functions/src/utils.ts @@ -1,9 +1,9 @@ import { blue, green, yellow } from 'colorette'; -import type { AfterServerStartedMetadata, NammathamApp} from '@nammatham/core'; +import type { AfterServerStartedMetadata, NammathamApp } from '@nammatham/core'; import { trimSlash } from '@nammatham/core'; import type { AzureFunctionsEndpoint } from './types'; -export function getMethods(func: AzureFunctionsEndpoint): string[] { +export function getMethods(func: AzureFunctionsEndpoint): string[] { if (!Array.isArray(func.endpointOption?.methods)) { return []; } @@ -11,18 +11,21 @@ export function getMethods(func: AzureFunctionsEndpoint): string[] { return methods; } -export function getFullUrl(func: AzureFunctionsEndpoint, port?: number): string { +export function getFullUrl(func: AzureFunctionsEndpoint, port?: number): string { const endpoint = func.endpointOption?.route ?? func.name; - if(typeof endpoint !== 'string') return ''; + if (typeof endpoint !== 'string') return ''; return `http://localhost${port ? `:${port}` : ''}/api/${trimSlash(endpoint)}`; } export const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); -export async function printRegisteredFunctions(app: NammathamApp, option: AfterServerStartedMetadata): Promise[]> { +export async function printRegisteredFunctions( + app: NammathamApp, + option: AfterServerStartedMetadata +): Promise[]> { const azureFunctions = app.functions .filter(func => func.type === 'azure-functions') - .filter(func => func.endpointOption?.type === 'http') as AzureFunctionsEndpoint[]; + .filter(func => func.endpointOption?.type === 'http') as AzureFunctionsEndpoint[]; if (azureFunctions.length === 0) return []; await delay(100); console.log(`\n${yellow('Functions:')}\n`); @@ -37,11 +40,13 @@ export async function printRegisteredFunctions(app: NammathamApp, option: AfterS /** * FIXME: This functions is duplicated with printRegisteredFunctions, it should be merged later. */ -export async function printRegisteredNonHttpFunctions(app: NammathamApp, option: AfterServerStartedMetadata): Promise[]> { - const azureFunctions = app.functions.filter(func => func.type === 'azure-functions').filter(func => func.endpointOption?.type !== 'http') as AzureFunctionsEndpoint< - any, - any - >[]; +export async function printRegisteredNonHttpFunctions( + app: NammathamApp, + option: AfterServerStartedMetadata +): Promise[]> { + const azureFunctions = app.functions + .filter(func => func.type === 'azure-functions') + .filter(func => func.endpointOption?.type !== 'http') as AzureFunctionsEndpoint[]; if (azureFunctions.length === 0) return []; await delay(100); console.log(`${yellow(`----------------------------------------------`)}\n`); diff --git a/packages/core/package.json b/packages/core/package.json index f352451a..9f2be98c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -8,8 +8,9 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", - "lint:fix": "npx eslint --fix ./src && npx prettier -c src", + "format": "prettier -w src", + "lint": "tsc --noEmit && eslint ./src && prettier -c src", + "lint:fix": "eslint --fix ./src && prettier -c src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ diff --git a/packages/core/src/logger.ts b/packages/core/src/logger.ts index 983c2c04..028983e2 100644 --- a/packages/core/src/logger.ts +++ b/packages/core/src/logger.ts @@ -67,4 +67,4 @@ class ConsoleLogger extends BaseLogger { } } -export const logger: BaseLogger = isDevelopment ? new PinoLogger(_logger): new ConsoleLogger(); +export const logger: BaseLogger = isDevelopment ? new PinoLogger(_logger) : new ConsoleLogger(); diff --git a/packages/core/src/main.ts b/packages/core/src/main.ts index 34109a13..645b664b 100644 --- a/packages/core/src/main.ts +++ b/packages/core/src/main.ts @@ -4,4 +4,4 @@ export * from './nammatham-app'; export * from './types'; export * from './default-adapter'; export * from './bases'; -export * from './utils'; \ No newline at end of file +export * from './utils'; diff --git a/packages/core/src/nammatham-app.ts b/packages/core/src/nammatham-app.ts index 1e9f69d0..ba2b1a40 100644 --- a/packages/core/src/nammatham-app.ts +++ b/packages/core/src/nammatham-app.ts @@ -13,7 +13,7 @@ export class NammathamApp { /** * Use when run app in development mode or not, * Mostly used for plugins, e.g. expressPlugin - * + * * For example, expressPlugin will not start express server in production mode for Azure Functions Adapter, * because Azure Functions will start the server for us. */ @@ -69,5 +69,4 @@ export class NammathamApp { setDevelopment(isDev: boolean) { this._isDevelopment = isDev; } - } diff --git a/packages/express/package.json b/packages/express/package.json index 172ef2b8..4c1ffb4f 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -8,8 +8,9 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", - "lint:fix": "npx eslint --fix ./src && npx prettier -c src", + "format": "prettier -w src", + "lint": "tsc --noEmit && eslint ./src && prettier -c src", + "lint:fix": "eslint --fix ./src && prettier -c src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ diff --git a/packages/express/src/express-server.ts b/packages/express/src/express-server.ts index ce9efbf2..c35921be 100644 --- a/packages/express/src/express-server.ts +++ b/packages/express/src/express-server.ts @@ -1,6 +1,6 @@ import express from 'express'; import { createExpressMiddleware } from './middleware'; -import type { BaseHandlerResolver, NammathamApp} from '@nammatham/core'; +import type { BaseHandlerResolver, NammathamApp } from '@nammatham/core'; import { logger } from '@nammatham/core'; import type { NammathamHttpHandlerOption } from './types'; @@ -35,7 +35,10 @@ export function expressPlugin(option?: ExpressServerOption) { }; } -export function startExpress({ app, handlerResolver }: NammathamHttpHandlerOption, expressOption?: ExpressServerOption) { +export function startExpress( + { app, handlerResolver }: NammathamHttpHandlerOption, + expressOption?: ExpressServerOption +) { logger.debug('Starting express server'); const expressApp = expressOption?.expressApp ?? express(); const port = expressOption?.port ?? 3000; @@ -51,7 +54,7 @@ export function startExpress({ app, handlerResolver }: NammathamHttpHandlerOptio handlerResolver, option: { allowAllFunctionsAccessByHttp, - } + }, // createContext, }) ); diff --git a/packages/express/src/types.ts b/packages/express/src/types.ts index febbc3fc..01b77d5c 100644 --- a/packages/express/src/types.ts +++ b/packages/express/src/types.ts @@ -8,4 +8,4 @@ export interface NammathamHttpHandlerOption { export interface NammathamHttpOption { allowAllFunctionsAccessByHttp?: boolean; -} \ No newline at end of file +} diff --git a/packages/trpc-azure-functions/package.json b/packages/trpc-azure-functions/package.json index 2dbc0f31..fd6c8892 100644 --- a/packages/trpc-azure-functions/package.json +++ b/packages/trpc-azure-functions/package.json @@ -8,8 +8,9 @@ "test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm run build", "build": "tsup src/main.ts --dts", - "lint": "tsc --noEmit && npx eslint ./src && npx prettier -c src", - "lint:fix": "npx eslint --fix ./src && npx prettier -w src", + "format": "prettier -w src", + "lint": "tsc --noEmit && eslint ./src && prettier -c src", + "lint:fix": "eslint --fix ./src && prettier -w src", "dev": "nodemon --watch src --ext ts --exec 'npm run build'" }, "keywords": [ From 40a0f4ef0c2f2b7502c0476a0bdb25bf0152dcae Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Wed, 10 Jan 2024 21:07:11 +0700 Subject: [PATCH 13/15] [azure-functions] add unit test for http request --- packages/azure-functions/package.json | 5 +- .../src/http/HttpRequest.test.ts | 37 +++++++++ .../azure-functions/src/http/HttpRequest.ts | 6 +- .../src/http/http-helper.test.ts | 83 +++++++++++++++++++ pnpm-lock.yaml | 37 ++++++--- 5 files changed, 152 insertions(+), 16 deletions(-) create mode 100644 packages/azure-functions/src/http/HttpRequest.test.ts create mode 100644 packages/azure-functions/src/http/http-helper.test.ts diff --git a/packages/azure-functions/package.json b/packages/azure-functions/package.json index 95b807d1..6942f8ef 100644 --- a/packages/azure-functions/package.json +++ b/packages/azure-functions/package.json @@ -20,8 +20,8 @@ "author": "Thada Wangthammang", "license": "MIT", "dependencies": { - "@nammatham/core": "2.0.0-alpha.8", "@azure/functions": "^4.1.0", + "@nammatham/core": "2.0.0-alpha.8", "colorette": "^2.0.20", "express": "^4.18.2", "undici": "5.20.0", @@ -36,6 +36,7 @@ }, "devDependencies": { "@types/express": "^4.17.21", - "@types/uuid": "^9.0.7" + "@types/uuid": "^9.0.7", + "node-mocks-http": "^1.14.1" } } \ No newline at end of file diff --git a/packages/azure-functions/src/http/HttpRequest.test.ts b/packages/azure-functions/src/http/HttpRequest.test.ts new file mode 100644 index 00000000..7c75a51c --- /dev/null +++ b/packages/azure-functions/src/http/HttpRequest.test.ts @@ -0,0 +1,37 @@ +import { expect, test } from 'vitest'; +import { HttpRequest } from './HttpRequest'; +import httpMocks from 'node-mocks-http'; +import exp from 'constants'; + +test('Test HttpRequest', () => { + // Arrange + const req = httpMocks.createRequest({ + method: 'GET', + protocol: 'https', + // get: (key: string) => 'localhost', + url: '/api/test', + query: { + a: '1', + b: '2', + }, + headers: { + x: '1', + y: '2', + }, + }); + + // Act + const result = new HttpRequest(req); + + // Assert + expect(result.method).toBe('GET'); + expect(result.url).toBe('https://undefined/api/test'); + expect(result.query.get('a')).toBe('1'); + expect(result.query.get('b')).toBe('2'); + expect(result.headers.get('x')).toBe('1'); + expect(result.headers.get('y')).toBe('2'); + expect(result.body).toBe(null); + expect(result.params).toStrictEqual({}); + expect(result.user).toBe(null); + expect(result.bodyUsed).toBe(false); +}); diff --git a/packages/azure-functions/src/http/HttpRequest.ts b/packages/azure-functions/src/http/HttpRequest.ts index f628b446..bdc8fbe3 100644 --- a/packages/azure-functions/src/http/HttpRequest.ts +++ b/packages/azure-functions/src/http/HttpRequest.ts @@ -3,11 +3,11 @@ import type * as types from '@azure/functions'; import type { HttpRequestParams, HttpRequestUser } from '@azure/functions'; import type { Blob } from 'buffer'; import type express from 'express'; -import { logger } from '@nammatham/core'; +import type { URLSearchParams } from 'url'; import type { ReadableStream } from 'stream/web'; import type { FormData, Headers } from 'undici'; +import { logger } from '@nammatham/core'; import { Request as uRequest } from 'undici'; -import type { URLSearchParams } from 'url'; import { convertExpressQueryToURLSearchParams, convertExpressReqHeaderToHeadersInit, @@ -25,7 +25,7 @@ export class HttpRequest implements types.HttpRequest { const url = getExpressReqFullUrl(req); this.#body = req.body; this.#uReq = new uRequest(url, { - body: this.#body, + body: req.method === 'GET' ? undefined : req.body, method: req.method, headers: convertExpressReqHeaderToHeadersInit(req.headers), }); diff --git a/packages/azure-functions/src/http/http-helper.test.ts b/packages/azure-functions/src/http/http-helper.test.ts new file mode 100644 index 00000000..7f3b6d7e --- /dev/null +++ b/packages/azure-functions/src/http/http-helper.test.ts @@ -0,0 +1,83 @@ +import { expect, test } from 'vitest'; +import * as httpHelpers from './http-helpers'; +import e, { Request as ExpressRequest } from 'express'; + +test('Test convertExpressQueryToURLSearchParams with string', () => { + // Arrange + const query = { + a: '1', + b: '2', + c: '3', + }; + + // Act + const result = httpHelpers.convertExpressQueryToURLSearchParams(query); + + // Assert + expect(result).toBeInstanceOf(URLSearchParams); + expect(result.get('a')).toBe('1'); + expect(result.get('b')).toBe('2'); + expect(result.get('c')).toBe('3'); + expect(result.toString()).toBe('a=1&b=2&c=3'); +}); + +test('Test convertExpressQueryToURLSearchParams with array', () => { + // Arrange + const query = { + a: ['1', '2', '3'], + b: ['4', '5', '6'], + }; + + // Act + const result = httpHelpers.convertExpressQueryToURLSearchParams(query); + + // Assert + expect(result).toBeInstanceOf(URLSearchParams); + expect(result.get('a')).toBe('1'); + expect(result.get('b')).toBe('4'); + expect(result.toString()).toBe('a=1&a=2&a=3&b=4&b=5&b=6'); +}); + +test('Test convertExpressHeadersToHeaders with string', () => { + // Arrange + const headers = { + a: '1', + b: '2', + c: '3', + }; + + // Act + const result = httpHelpers.convertExpressReqHeaderToHeadersInit(headers); + + // Assert + expect(result).toStrictEqual(headers); +}); + +test('Test convertExpressHeadersToHeaders with array', () => { + // Arrange + const headers = { + a: ['1', '2', '3'], + b: ['4', '5', '6'], + }; + + // Act + const result = httpHelpers.convertExpressReqHeaderToHeadersInit(headers); + + // Assert + expect(result).toStrictEqual(headers); +}); + +test('Test getExpressReqFullUrl', () => { + // Arrange + const req = { + protocol: 'https', + get: () => 'localhost', + originalUrl: '/api/test', + } as any as ExpressRequest; + + // Act + const result = httpHelpers.getExpressReqFullUrl(req); + + // Assert + expect(result).toBe('https://localhost/api/test'); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d3409f9..78d7282a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -211,6 +211,9 @@ importers: '@types/uuid': specifier: ^9.0.7 version: 9.0.7 + node-mocks-http: + specifier: ^1.14.1 + version: 1.14.1 packages/core: dependencies: @@ -1360,7 +1363,6 @@ packages: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - dev: false /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1768,7 +1770,6 @@ packages: engines: {node: '>= 0.6'} dependencies: safe-buffer: 5.2.1 - dev: false /content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} @@ -1893,6 +1894,11 @@ packages: engines: {node: '>=0.4.0'} dev: true + /depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + dev: true + /depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -2450,7 +2456,6 @@ packages: /fresh@0.5.2: resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} engines: {node: '>= 0.6'} - dev: false /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -3120,7 +3125,6 @@ packages: /media-typer@0.3.0: resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} engines: {node: '>= 0.6'} - dev: false /memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} @@ -3129,7 +3133,6 @@ packages: /merge-descriptors@1.0.1: resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} - dev: false /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -3143,7 +3146,6 @@ packages: /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - dev: false /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} @@ -3167,7 +3169,6 @@ packages: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} hasBin: true - dev: false /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} @@ -3256,7 +3257,6 @@ packages: /negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - dev: false /nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -3271,6 +3271,24 @@ packages: hasBin: true dev: true + /node-mocks-http@1.14.1: + resolution: {integrity: sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==} + engines: {node: '>=14'} + dependencies: + '@types/express': 4.17.21 + '@types/node': 20.10.6 + accepts: 1.3.8 + content-disposition: 0.5.4 + depd: 1.1.2 + fresh: 0.5.2 + merge-descriptors: 1.0.1 + methods: 1.1.2 + mime: 1.6.0 + parseurl: 1.3.3 + range-parser: 1.2.1 + type-is: 1.6.18 + dev: true + /nodemon@2.0.22: resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} engines: {node: '>=8.10.0'} @@ -3520,7 +3538,6 @@ packages: /parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - dev: false /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -3764,7 +3781,6 @@ packages: /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - dev: false /raw-body@2.5.1: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} @@ -4513,7 +4529,6 @@ packages: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - dev: false /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} From 1a23618f8e1aa9593e35908b1c5ee0d102e0c532 Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Wed, 10 Jan 2024 21:20:06 +0700 Subject: [PATCH 14/15] [azure-functions] add test for trigger & nammatham --- .../src/nammatham-context.test.ts | 15 ++++++++ packages/azure-functions/src/trigger.test.ts | 34 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 packages/azure-functions/src/nammatham-context.test.ts create mode 100644 packages/azure-functions/src/trigger.test.ts diff --git a/packages/azure-functions/src/nammatham-context.test.ts b/packages/azure-functions/src/nammatham-context.test.ts new file mode 100644 index 00000000..0b4ea0b5 --- /dev/null +++ b/packages/azure-functions/src/nammatham-context.test.ts @@ -0,0 +1,15 @@ +import { expect, test } from 'vitest'; +import { NammathamContext } from './nammatham-context'; +import { AzureFunctionsTrigger } from './trigger'; +import { InvocationContext } from '@azure/functions'; + +test('NammathamContext should be created', () => { + const trigger = new AzureFunctionsTrigger(); + const context = new InvocationContext(); + + const result = new NammathamContext(context, trigger); + + expect(result).toBeInstanceOf(NammathamContext); + expect(result.context).toStrictEqual(context); + expect(result.trigger).toStrictEqual(trigger); +}); diff --git a/packages/azure-functions/src/trigger.test.ts b/packages/azure-functions/src/trigger.test.ts new file mode 100644 index 00000000..3490e160 --- /dev/null +++ b/packages/azure-functions/src/trigger.test.ts @@ -0,0 +1,34 @@ +import { expect, test } from 'vitest'; +import { AzureFunctionsTrigger } from './trigger'; +import { AzureFunctionsHandler } from './handler'; + +test('Trigger HTTP GET', () => { + const trigger = new AzureFunctionsTrigger(); + const result = trigger.httpGet('test'); + expect(result).toBeInstanceOf(AzureFunctionsHandler); +}); + +test('Trigger HTTP POST', () => { + const trigger = new AzureFunctionsTrigger(); + const result = trigger.httpPost('test'); + expect(result).toBeInstanceOf(AzureFunctionsHandler); +}); + +test('Trigger HTTP PUT', () => { + const trigger = new AzureFunctionsTrigger(); + const result = trigger.httpPut('test'); + expect(result).toBeInstanceOf(AzureFunctionsHandler); +}); + +test('Trigger HTTP DELETE', () => { + const trigger = new AzureFunctionsTrigger(); + const result = trigger.httpDelete('test'); + expect(result).toBeInstanceOf(AzureFunctionsHandler); +}); + +test('Trigger HTTP', () => { + const trigger = new AzureFunctionsTrigger(); + const result = trigger.http('test'); + expect(result).toBeInstanceOf(AzureFunctionsHandler); +}); + From d81ee043270c89bb870efb28122f512634c445ed Mon Sep 17 00:00:00 2001 From: Thada Wangthammang Date: Thu, 11 Jan 2024 11:43:13 +0700 Subject: [PATCH 15/15] apply new rule lint --- .eslintrc.cjs | 47 +++++-- package.json | 2 + packages/azure-functions/src/adapter.ts | 3 +- .../azure-functions/src/handler-resolver.ts | 15 ++- packages/azure-functions/src/handler.ts | 6 +- .../azure-functions/src/http/HttpRequest.ts | 8 +- .../azure-functions/src/http/http-helpers.ts | 2 +- .../azure-functions/src/nammatham-context.ts | 1 + packages/azure-functions/src/trigger.test.ts | 1 - packages/azure-functions/src/trigger.ts | 9 +- packages/azure-functions/src/types.ts | 3 +- packages/azure-functions/src/utils.ts | 4 +- .../core/src/bases/base-handler-resolver.ts | 3 +- packages/core/src/default-adapter/adapter.ts | 4 +- .../src/default-adapter/handler-resolver.ts | 2 +- packages/core/src/init-nammatham.ts | 8 +- packages/core/src/nammatham-app.ts | 6 +- packages/express/src/express-server.ts | 7 +- packages/express/src/middleware.ts | 4 +- .../src/trpc-azure-functions.ts | 14 +- packages/trpc-azure-functions/src/trpc.ts | 1 - pnpm-lock.yaml | 124 ++++++++++++++++++ 22 files changed, 227 insertions(+), 47 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 8bcc4b81..99d68354 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,11 +1,40 @@ /* eslint-env node */ module.exports = { - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - root: true, - ignorePatterns: ["**.test.ts"], - rules: { - '@typescript-eslint/consistent-type-imports': 'error', - } - }; \ No newline at end of file + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'perfectionist', 'unused-imports'], + root: true, + ignorePatterns: ['**.test.ts'], + rules: { + /** + * Unused import and vars: + * https://github.com/sweepline/eslint-plugin-unused-imports + */ + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/consistent-type-imports': 'error', + /** + * For config: https://eslint-plugin-perfectionist.azat.io/rules/sort-imports + */ + 'perfectionist/sort-imports': [ + 'error', + { + type: 'line-length', + order: 'asc', + groups: [ + 'type', + ['builtin', 'external'], + 'internal-type', + 'internal', + ['parent-type', 'sibling-type', 'index-type'], + ['parent', 'sibling', 'index'], + 'side-effect', + 'style', + 'object', + 'unknown', + ], + 'newlines-between': 'always', + 'internal-pattern': ['@/nammatham/**'], + }, + ], + }, +}; diff --git a/package.json b/package.json index fdeaf26f..4874d38f 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "@typescript-eslint/parser": "^5.55.0", "@vitest/coverage-v8": "^1.1.3", "eslint": "^8.36.0", + "eslint-plugin-perfectionist": "^2.5.0", + "eslint-plugin-unused-imports": "^3.0.0", "execa": "^8.0.1", "fs-extra": "^11.2.0", "nodemon": "^2.0.20", diff --git a/packages/azure-functions/src/adapter.ts b/packages/azure-functions/src/adapter.ts index 142a191a..66c0172e 100644 --- a/packages/azure-functions/src/adapter.ts +++ b/packages/azure-functions/src/adapter.ts @@ -1,6 +1,7 @@ import { BaseRuntimeAdapter, NammathamApp } from '@nammatham/core'; -import { AzureFunctionsHandlerResolver } from './handler-resolver'; + import { AzureFunctionsTrigger } from './trigger'; +import { AzureFunctionsHandlerResolver } from './handler-resolver'; export class AzureFunctionsAdapter extends BaseRuntimeAdapter { createTrigger() { diff --git a/packages/azure-functions/src/handler-resolver.ts b/packages/azure-functions/src/handler-resolver.ts index 80405b54..a501daa3 100644 --- a/packages/azure-functions/src/handler-resolver.ts +++ b/packages/azure-functions/src/handler-resolver.ts @@ -1,17 +1,20 @@ -import type { NammathamApp, AfterServerStartedMetadata } from '@nammatham/core'; -import { BaseHandlerResolver, logger } from '@nammatham/core'; import type { Cookie, LogLevel } from '@azure/functions'; -import { HttpResponse, InvocationContext } from '@azure/functions'; -import type { AzureFunctionsEndpoint } from './types'; +import type { NammathamApp, AfterServerStartedMetadata } from '@nammatham/core'; import type { Request as ExpressRequest, Response as ExpressResponse, CookieOptions as ExpressCookieOptions, } from 'express'; -import { HttpRequest } from './http/HttpRequest'; + +import { yellow } from 'colorette'; import { v4 as uuidv4 } from 'uuid'; +import { BaseHandlerResolver, logger } from '@nammatham/core'; +import { HttpResponse, InvocationContext } from '@azure/functions'; + +import type { AzureFunctionsEndpoint } from './types'; + +import { HttpRequest } from './http/HttpRequest'; import { printRegisteredFunctions, printRegisteredNonHttpFunctions } from './utils'; -import { yellow } from 'colorette'; function logExecutedFunction( startTime: number, diff --git a/packages/azure-functions/src/handler.ts b/packages/azure-functions/src/handler.ts index 271477a9..d521bcd0 100644 --- a/packages/azure-functions/src/handler.ts +++ b/packages/azure-functions/src/handler.ts @@ -1,8 +1,10 @@ -import type { WithEndpointOption } from '@nammatham/core'; -import { NammathamContext } from './nammatham-context'; import type { InvocationContext } from '@azure/functions'; +import type { WithEndpointOption } from '@nammatham/core'; + import type { HandlerFunction, RegisterFunctionOption, AzureFunctionsEndpoint, FunctionOption } from './types'; +import { NammathamContext } from './nammatham-context'; + export class AzureFunctionsHandler { constructor( public funcName: string, diff --git a/packages/azure-functions/src/http/HttpRequest.ts b/packages/azure-functions/src/http/HttpRequest.ts index bdc8fbe3..40324226 100644 --- a/packages/azure-functions/src/http/HttpRequest.ts +++ b/packages/azure-functions/src/http/HttpRequest.ts @@ -1,13 +1,15 @@ // Adapted from https://github.com/Azure/azure-functions-nodejs-library/blob/v4.x/src/http/HttpRequest.ts -import type * as types from '@azure/functions'; -import type { HttpRequestParams, HttpRequestUser } from '@azure/functions'; import type { Blob } from 'buffer'; import type express from 'express'; import type { URLSearchParams } from 'url'; -import type { ReadableStream } from 'stream/web'; +import type * as types from '@azure/functions'; import type { FormData, Headers } from 'undici'; +import type { ReadableStream } from 'stream/web'; +import type { HttpRequestParams, HttpRequestUser } from '@azure/functions'; + import { logger } from '@nammatham/core'; import { Request as uRequest } from 'undici'; + import { convertExpressQueryToURLSearchParams, convertExpressReqHeaderToHeadersInit, diff --git a/packages/azure-functions/src/http/http-helpers.ts b/packages/azure-functions/src/http/http-helpers.ts index 802b6d1e..3c64bfc9 100644 --- a/packages/azure-functions/src/http/http-helpers.ts +++ b/packages/azure-functions/src/http/http-helpers.ts @@ -1,5 +1,5 @@ -import type { IncomingHttpHeaders } from 'node:http'; import type express from 'express'; +import type { IncomingHttpHeaders } from 'node:http'; export function convertExpressReqHeaderToHeadersInit(_headers: IncomingHttpHeaders): HeadersInit { const headers: Record> = {}; diff --git a/packages/azure-functions/src/nammatham-context.ts b/packages/azure-functions/src/nammatham-context.ts index e7a705da..d5a34fbc 100644 --- a/packages/azure-functions/src/nammatham-context.ts +++ b/packages/azure-functions/src/nammatham-context.ts @@ -1,4 +1,5 @@ import type { InvocationContext } from '@azure/functions'; + import { NammathamContextBase } from '@nammatham/core'; export class NammathamContext extends NammathamContextBase { diff --git a/packages/azure-functions/src/trigger.test.ts b/packages/azure-functions/src/trigger.test.ts index 3490e160..129599bc 100644 --- a/packages/azure-functions/src/trigger.test.ts +++ b/packages/azure-functions/src/trigger.test.ts @@ -31,4 +31,3 @@ test('Trigger HTTP', () => { const result = trigger.http('test'); expect(result).toBeInstanceOf(AzureFunctionsHandler); }); - diff --git a/packages/azure-functions/src/trigger.ts b/packages/azure-functions/src/trigger.ts index 447557a8..a8587854 100644 --- a/packages/azure-functions/src/trigger.ts +++ b/packages/azure-functions/src/trigger.ts @@ -1,3 +1,4 @@ +import type { HttpEndpointOption, WithEndpointOption } from '@nammatham/core'; import type { GenericFunctionOptions, HttpFunctionOptions, @@ -8,12 +9,14 @@ import type { TimerFunctionOptions, HttpMethodFunctionOptions, } from '@azure/functions'; + import { app } from '@azure/functions'; -import { AzureFunctionsHandler } from './handler'; -import type { FunctionOption } from './types'; -import type { HttpEndpointOption, WithEndpointOption } from '@nammatham/core'; import { BaseFunctionTrigger } from '@nammatham/core'; +import type { FunctionOption } from './types'; + +import { AzureFunctionsHandler } from './handler'; + export class AzureFunctionsTrigger extends BaseFunctionTrigger { generic(funcName: string, option: Omit) { return new AzureFunctionsHandler( diff --git a/packages/azure-functions/src/types.ts b/packages/azure-functions/src/types.ts index 9d53c3ac..e7d38627 100644 --- a/packages/azure-functions/src/types.ts +++ b/packages/azure-functions/src/types.ts @@ -1,6 +1,7 @@ +import type { NammamthamEndpoint, PromiseLike } from '@nammatham/core'; import type { FunctionInput, FunctionOutput, InvocationContext } from '@azure/functions'; + import type { NammathamContext } from './nammatham-context'; -import type { NammamthamEndpoint, PromiseLike } from '@nammatham/core'; export type HandlerFunction = ( ctx: NammathamContext diff --git a/packages/azure-functions/src/utils.ts b/packages/azure-functions/src/utils.ts index f6cd0433..04a93253 100644 --- a/packages/azure-functions/src/utils.ts +++ b/packages/azure-functions/src/utils.ts @@ -1,6 +1,8 @@ -import { blue, green, yellow } from 'colorette'; import type { AfterServerStartedMetadata, NammathamApp } from '@nammatham/core'; + import { trimSlash } from '@nammatham/core'; +import { blue, green, yellow } from 'colorette'; + import type { AzureFunctionsEndpoint } from './types'; export function getMethods(func: AzureFunctionsEndpoint): string[] { diff --git a/packages/core/src/bases/base-handler-resolver.ts b/packages/core/src/bases/base-handler-resolver.ts index 40b8b5b6..818bb87c 100644 --- a/packages/core/src/bases/base-handler-resolver.ts +++ b/packages/core/src/bases/base-handler-resolver.ts @@ -1,6 +1,7 @@ -import type { AfterServerStartedMetadata, NammamthamEndpoint } from '../types'; import type { Request, Response } from 'express'; + import type { NammathamApp } from '../nammatham-app'; +import type { AfterServerStartedMetadata, NammamthamEndpoint } from '../types'; export abstract class BaseHandlerResolver { abstract resolveHandler(endpoint: NammamthamEndpoint, req: Request, res: Response): any; diff --git a/packages/core/src/default-adapter/adapter.ts b/packages/core/src/default-adapter/adapter.ts index d705f2b0..867baf89 100644 --- a/packages/core/src/default-adapter/adapter.ts +++ b/packages/core/src/default-adapter/adapter.ts @@ -1,6 +1,6 @@ -import { NammathamApp } from '../nammatham-app'; -import { BaseRuntimeAdapter } from '../bases'; import { DefaultTrigger } from './trigger'; +import { BaseRuntimeAdapter } from '../bases'; +import { NammathamApp } from '../nammatham-app'; import { DefaultHandlerResolver } from './handler-resolver'; export class DefaultAdapter extends BaseRuntimeAdapter { diff --git a/packages/core/src/default-adapter/handler-resolver.ts b/packages/core/src/default-adapter/handler-resolver.ts index 920d75df..a2c58bb0 100644 --- a/packages/core/src/default-adapter/handler-resolver.ts +++ b/packages/core/src/default-adapter/handler-resolver.ts @@ -1,5 +1,5 @@ -import { BaseHandlerResolver } from '../bases'; import { logger } from '../main'; +import { BaseHandlerResolver } from '../bases'; export class DefaultHandlerResolver extends BaseHandlerResolver { override resolveHandler() { diff --git a/packages/core/src/init-nammatham.ts b/packages/core/src/init-nammatham.ts index 9db509a8..2ddce3c1 100644 --- a/packages/core/src/init-nammatham.ts +++ b/packages/core/src/init-nammatham.ts @@ -1,8 +1,10 @@ -import type { BaseRuntimeAdapter } from './bases/base-runtime-adapter'; -import { DefaultAdapter } from './default-adapter'; +import { yellow } from 'colorette'; + import type { NammathamApp } from './nammatham-app'; +import type { BaseRuntimeAdapter } from './bases/base-runtime-adapter'; + import { logger } from './main'; -import { yellow } from 'colorette'; +import { DefaultAdapter } from './default-adapter'; export interface NammathamRuntime> { func: ReturnType; diff --git a/packages/core/src/nammatham-app.ts b/packages/core/src/nammatham-app.ts index ba2b1a40..7e2b1a8a 100644 --- a/packages/core/src/nammatham-app.ts +++ b/packages/core/src/nammatham-app.ts @@ -1,7 +1,9 @@ import { magenta } from 'colorette'; -import { logger } from './main'; -import type { BaseHandlerResolver } from './bases'; + import type { NammamthamEndpoint } from './types'; +import type { BaseHandlerResolver } from './bases'; + +import { logger } from './main'; export class NammathamApp { protected readonly _functions: NammamthamEndpoint[] = []; diff --git a/packages/express/src/express-server.ts b/packages/express/src/express-server.ts index c35921be..9aea1ea2 100644 --- a/packages/express/src/express-server.ts +++ b/packages/express/src/express-server.ts @@ -1,9 +1,12 @@ -import express from 'express'; -import { createExpressMiddleware } from './middleware'; import type { BaseHandlerResolver, NammathamApp } from '@nammatham/core'; + +import express from 'express'; import { logger } from '@nammatham/core'; + import type { NammathamHttpHandlerOption } from './types'; +import { createExpressMiddleware } from './middleware'; + export interface ExpressServerOption { prefix?: string; port?: number; diff --git a/packages/express/src/middleware.ts b/packages/express/src/middleware.ts index 0efe5654..44179d8e 100644 --- a/packages/express/src/middleware.ts +++ b/packages/express/src/middleware.ts @@ -1,9 +1,11 @@ // Adapted from: https://github.com/trpc/trpc/tree/main/packages/server/src/adapters/express.ts import type express from 'express'; -import type { NammathamHttpHandlerOption } from './types'; import type { HttpMethod } from '@nammatham/core'; + import { logger } from '@nammatham/core'; +import type { NammathamHttpHandlerOption } from './types'; + interface NammathamAppRequestOption extends NammathamHttpHandlerOption { req: express.Request; res: express.Response; diff --git a/packages/trpc-azure-functions/src/trpc-azure-functions.ts b/packages/trpc-azure-functions/src/trpc-azure-functions.ts index c5286257..98f9f35d 100644 --- a/packages/trpc-azure-functions/src/trpc-azure-functions.ts +++ b/packages/trpc-azure-functions/src/trpc-azure-functions.ts @@ -1,14 +1,16 @@ +import type { AnyRouter } from '@trpc/server'; import type { BaseHandlerResolver } from '@nammatham/core'; -import { NammathamApp, logger, trimSlash } from '@nammatham/core'; +import type { ExpressServerOption } from '@nammatham/express'; import type { HttpRequest as AzureHttpRequest } from '@azure/functions'; import type { AzureFunctionsOptions } from 'trpc-azure-functions-adapter'; -import { wrapAzureFunctionsRequestHandler } from 'trpc-azure-functions-adapter'; -import type { AnyRouter } from '@trpc/server'; -import { AzureFunctionsTrigger } from '@nammatham/azure-functions'; -import type { ExpressServerOption } from '@nammatham/express'; -import { startExpress } from '@nammatham/express'; + import express from 'express'; +import { startExpress } from '@nammatham/express'; import * as trpcExpress from '@trpc/server/adapters/express'; +import { NammathamApp, logger, trimSlash } from '@nammatham/core'; +import { AzureFunctionsTrigger } from '@nammatham/azure-functions'; +import { wrapAzureFunctionsRequestHandler } from 'trpc-azure-functions-adapter'; + import { createContext } from './trpc'; export interface TrpcAzureFunctionsPluginOption { diff --git a/packages/trpc-azure-functions/src/trpc.ts b/packages/trpc-azure-functions/src/trpc.ts index fb75409d..b486c4f8 100644 --- a/packages/trpc-azure-functions/src/trpc.ts +++ b/packages/trpc-azure-functions/src/trpc.ts @@ -1,4 +1,3 @@ -import { initTRPC } from '@trpc/server'; import type * as trpcExpress from '@trpc/server/adapters/express'; // created for each request diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78d7282a..0e278e4f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,12 @@ importers: eslint: specifier: ^8.36.0 version: 8.56.0 + eslint-plugin-perfectionist: + specifier: ^2.5.0 + version: 2.5.0(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-unused-imports: + specifier: ^3.0.0 + version: 3.0.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.56.0) execa: specifier: ^8.0.1 version: 8.0.1 @@ -1187,6 +1193,14 @@ packages: '@typescript-eslint/visitor-keys': 5.62.0 dev: true + /@typescript-eslint/scope-manager@6.18.1: + resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 + dev: true + /@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1212,6 +1226,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types@6.18.1: + resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + /@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.3): resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1233,6 +1252,28 @@ packages: - supports-color dev: true + /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3): + resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1253,6 +1294,25 @@ packages: - typescript dev: true + /@typescript-eslint/utils@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + eslint: 8.56.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /@typescript-eslint/visitor-keys@5.62.0: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1261,6 +1321,14 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@typescript-eslint/visitor-keys@6.18.1: + resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.18.1 + eslint-visitor-keys: 3.4.3 + dev: true + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true @@ -2089,6 +2157,53 @@ packages: engines: {node: '>=10'} dev: true + /eslint-plugin-perfectionist@2.5.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-F6XXcq4mKKUe/SREoMGQqzgw6cgCgf3pFzkFfQVIGtqD1yXVpQjnhTepzhBeZfxZwgMzR9HO4yH4CUhIQ2WBcQ==} + peerDependencies: + astro-eslint-parser: ^0.16.0 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.33.0 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true + dependencies: + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + minimatch: 9.0.3 + natural-compare-lite: 1.4.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.56.0): + resolution: {integrity: sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^6.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-rule-composer: 0.3.0 + dev: true + + /eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + dev: true + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -4420,6 +4535,15 @@ packages: '@trpc/server': 10.45.0 dev: false + /ts-api-utils@1.0.3(typescript@5.3.3): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.3.3 + dev: true + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true