diff --git a/.github/workflows/build_test_validate.yml b/.github/workflows/build_test_validate.yml index d0d4f0caa..58947f2ee 100644 --- a/.github/workflows/build_test_validate.yml +++ b/.github/workflows/build_test_validate.yml @@ -47,6 +47,53 @@ jobs: USER_ID: ${{secrets.user_id}} - run: npm run test + code-coverage: + runs-on: ubuntu-latest + strategy: + matrix: + coverage: + - name: "Abstractions" + path: "./packages/abstractions/coverage" + - name: "Authentication Azure" + path: "./packages/authentication/azure/coverage" + - name: "Authentication Spfx" + path: "./packages/authentication/spfx/coverage" + - name: "Http Fetch" + path: "./packages/http/fetch/coverage" + - name: "Serialization Form" + path: "./packages/serialization/form/coverage" + - name: "Serialization JSON" + path: "./packages/serialization/json/coverage" + - name: "Serialization Text" + path: "./packages/serialization/text/coverage" + - name: "Serialization Multipart" + path: "./packages/serialization/multipart/coverage" + - name: "Bundle" + path: "./packages/bundle/coverage" + steps: + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 + with: + node-version: 22.x + - run: npm ci + - run: npm run build + - run: npm run test:coverage + - name: Code Coverage Report ${{ matrix.coverage.name }} + uses: irongut/CodeCoverageSummary@v1.3.0 + with: + filename: ${{ matrix.coverage.path }}/cobertura-coverage.xml + format: markdown + hide_branch_rate: false + output: both + badge: true + - name: Archive coverage files + uses: actions/upload-artifact@v4 + with: + name: Coverage files for ${{ matrix.coverage.name }} + path: ${{ matrix.coverage.path }} + + publish-npm: if: "${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && contains(github.event.head_commit.message, 'chore: release main') }}" needs: [build, check-typescript-version-matrix] @@ -75,7 +122,7 @@ jobs: # Use this as a PR status check for GitHub Policy Service instead of individual matrix entry checks. check-typescript-version-matrix: runs-on: ubuntu-latest - needs: [build] + needs: [build,code-coverage] if: always() steps: - name: All build matrix options are successful diff --git a/eslint.config.mjs b/eslint.config.mjs index 764dd3434..f21a9f405 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -34,9 +34,9 @@ export default [{ "plugin:@typescript-eslint/stylistic-type-checked", "prettier", "@microsoft/eslint-config-msgraph/core", + "plugin:jsdoc/recommended-typescript-error" ), { plugins: { - jsdoc, "prefer-arrow": preferArrow, "@typescript-eslint": typescriptEslint, header, @@ -57,12 +57,12 @@ export default [{ "packages/abstractions/tsconfig.json", "packages/bundle/tsconfig.json", "packages/authentication/azure/tsconfig.json", - "packages/authentication/azure/tsconfig.json", + "packages/authentication/spfx/tsconfig.json", "packages/http/fetch/tsconfig.json", "packages/serialization/form/tsconfig.json", "packages/serialization/json/tsconfig.json", + "packages/serialization/text/tsconfig.json", "packages/serialization/multipart/tsconfig.json", - "packages/authentication/azure/tsconfig.json", "packages/test/tsconfig.json", ], }, diff --git a/package-lock.json b/package-lock.json index 03fca7ac1..c1e7bd36c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", "@vitest/browser": "^2.0.1", + "@vitest/coverage-istanbul": "^2.1.4", "@vitest/coverage-v8": "^2.0.1", "@vitest/ui": "^2.0.1", "eslint": "^9.7.0", @@ -216,129 +217,191 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", + "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "node_modules/@babel/compat-data": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz", + "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==", "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "dev": true, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, "engines": { "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz", + "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/parser": "^7.26.0", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, - "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, - "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, - "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { @@ -368,6 +431,47 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", @@ -3883,6 +3987,30 @@ } } }, + "node_modules/@vitest/coverage-istanbul": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.4.tgz", + "integrity": "sha512-NLmfjzXnRSmLF/h4hYkzjvd7hZ85DRZzPUqXu0McPFCMczDfNmOjMoM3KaxjFaEmOc1YzX9HHbU/Rr9VO+35ow==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.3", + "debug": "^4.3.7", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-instrument": "^6.0.3", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magicast": "^0.3.5", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "2.1.4" + } + }, "node_modules/@vitest/coverage-v8": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.4.tgz", @@ -5098,6 +5226,38 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -5244,6 +5404,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001675", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001675.tgz", + "integrity": "sha512-/wV1bQwPrkLiQMjaJF5yUMVM/VdRPOCU8QZ+PmG6uW6DvYSrNY1bpwHI/3mOcUosLaJCzYDi5o91IQB51ft6cg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chai": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", @@ -5863,6 +6043,12 @@ "node": ">=14" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -6664,6 +6850,12 @@ "node": ">=0.10.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.5.49", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.49.tgz", + "integrity": "sha512-ZXfs1Of8fDb6z7WEYZjXpgIRF6MEu8JdeGA0A40aZq6OQbS+eJpnnV49epZRna2DU/YsEjSQuGtQPPtvt6J65A==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -7025,11 +7217,10 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -8145,6 +8336,15 @@ "node": "^16.13.0 || >=18.0.0" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -9600,6 +9800,22 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -9811,6 +10027,18 @@ "node": ">=12.0.0" } }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -11021,11 +11249,10 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -11335,9 +11562,9 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/msw": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.5.2.tgz", - "integrity": "sha512-eBsFgU30NYtrfC62XzS1rdAzFK+Br0zKU4ORqD9Qliq86362DWZyPiD6FLfMgy0Ktik83DPTXmqPMz2bqwmJdA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.6.0.tgz", + "integrity": "sha512-n3tx2w0MZ3H4pxY0ozrQ4sNPzK/dGtlr2cIIyuEsgq2Bhy4wvcW6ZH2w/gXM9+MEUY6HC1fWhqtcXDxVZr5Jxw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -11346,6 +11573,7 @@ "@bundled-es-modules/tough-cookie": "^0.1.6", "@inquirer/confirm": "^5.0.0", "@mswjs/interceptors": "^0.36.5", + "@open-draft/deferred-promise": "^2.2.0", "@open-draft/until": "^2.1.0", "@types/cookie": "^0.6.0", "@types/statuses": "^2.0.4", @@ -11624,6 +11852,12 @@ "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", "dev": true }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, "node_modules/nopt": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", @@ -15208,6 +15442,36 @@ "yarn": "*" } }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 6efa0509a..d0c232a4c 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@typescript-eslint/parser": "^8.1.0", "@vitest/browser": "^2.0.1", "@vitest/coverage-v8": "^2.0.1", + "@vitest/coverage-istanbul": "^2.1.4", "@vitest/ui": "^2.0.1", "eslint": "^9.7.0", "eslint-config-prettier": "^9.1.0", @@ -42,6 +43,7 @@ "test:browser": "lerna run --scope \"@microsoft/*\" test:browser", "test:node": "lerna run --scope \"@microsoft/*\" test:node", "test": "npm run test:node && npm run test:browser", + "test:coverage": "lerna run test:coverage", "test:integrated": "lerna run test:integrated", "tsc:version": "tsc --version", "prettier:base": "prettier --parser typescript", @@ -50,7 +52,7 @@ "lint": "npm run lint:eslint", "lint:eslint": "eslint --quiet \"packages/*/src/**/*.ts\"", "lint:eslint:fix": "npm run lint:eslint -- --fix", - "lint:eslint:loud": "eslint \"packages/*/src/**/*.ts\"", + "lint:eslint:loud": "eslint \"packages/*/src/**/*.ts\" \"packages/*/*/src/**/*.ts\"", "prepare": "husky" } } diff --git a/packages/abstractions/README.md b/packages/abstractions/README.md index 69f27c5a6..19d2e5c6c 100644 --- a/packages/abstractions/README.md +++ b/packages/abstractions/README.md @@ -1,11 +1,37 @@ +# Microsoft Kiota Abstractions Library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-abstractions?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-abstractions) -The Kiota abstractions Library is the javascript library defining the basic constructs the Kiota projects need once an SDK has been generated from an OpenAPI definition. +The Kiota abstractions Library is the TypeScript library defining the basic constructs the Kiota projects need once an SDK has been generated from an OpenAPI definition. -A Kiota generated project will need a reference to the abstraction package to build and run. +A [Kiota](https://github.com/microsoft/kiota) generated project will need a reference to the abstraction package to build and run. -Read more about Kiota here. +Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README.md). ## Using the abstractions +In order to use this library, install the package by running: + `npm i @microsoft/kiota-abstractions` + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/abstractions/package.json b/packages/abstractions/package.json index df9c6c7af..b634303c3 100644 --- a/packages/abstractions/package.json +++ b/packages/abstractions/package.json @@ -14,6 +14,7 @@ "clean": "rimraf ./dist", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "repository": "git://github.com/microsoft/kiota-typescript.git", @@ -42,5 +43,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/abstractions/src/apiClientBuilder.ts b/packages/abstractions/src/apiClientBuilder.ts index 1cfadc8c0..b08e0c859 100644 --- a/packages/abstractions/src/apiClientBuilder.ts +++ b/packages/abstractions/src/apiClientBuilder.ts @@ -28,7 +28,7 @@ export function registerDefaultDeserializer(type: new () => ParseNodeFactory): v /** * Enables the backing store on default serialization writers and the given serialization writer. * @param original The serialization writer to enable the backing store on. - * @return A new serialization writer with the backing store enabled. + * @returns A new serialization writer with the backing store enabled. */ export function enableBackingStoreForSerializationWriterFactory(original: SerializationWriterFactory): SerializationWriterFactory { if (!original) throw new Error("Original must be specified"); @@ -45,7 +45,7 @@ export function enableBackingStoreForSerializationWriterFactory(original: Serial /** * Enables the backing store on default parse node factories and the given parse node factory. * @param original The parse node factory to enable the backing store on. - * @return A new parse node factory with the backing store enabled. + * @returns A new parse node factory with the backing store enabled. */ export function enableBackingStoreForParseNodeFactory(original: ParseNodeFactory): ParseNodeFactory { if (!original) throw new Error("Original must be specified"); @@ -58,6 +58,10 @@ export function enableBackingStoreForParseNodeFactory(original: ParseNodeFactory enableBackingStoreForParseNodeRegistry(ParseNodeFactoryRegistry.defaultInstance); return result; } +/** + * Enables the backing store on the given parse node factory registry. + * @param registry The parse node factory registry to enable the backing store on. + */ function enableBackingStoreForParseNodeRegistry(registry: ParseNodeFactoryRegistry): void { for (const [k, v] of registry.contentTypeAssociatedFactories) { if (!(v instanceof BackingStoreParseNodeFactory || v instanceof ParseNodeFactoryRegistry)) { @@ -65,6 +69,10 @@ function enableBackingStoreForParseNodeRegistry(registry: ParseNodeFactoryRegist } } } +/** + * Enables the backing store on the given serialization factory registry. + * @param registry The serialization factory registry to enable the backing store on. + */ function enableBackingStoreForSerializationRegistry(registry: SerializationWriterFactoryRegistry): void { for (const [k, v] of registry.contentTypeAssociatedFactories) { if (!(v instanceof BackingStoreSerializationWriterProxyFactory || v instanceof SerializationWriterFactoryRegistry)) { diff --git a/packages/abstractions/src/authentication/accessTokenProvider.ts b/packages/abstractions/src/authentication/accessTokenProvider.ts index 400062d33..8e7f2cfcf 100644 --- a/packages/abstractions/src/authentication/accessTokenProvider.ts +++ b/packages/abstractions/src/authentication/accessTokenProvider.ts @@ -7,7 +7,6 @@ import { type AllowedHostsValidator } from "./allowedHostsValidator"; /** - * @interface * An AccessTokenProvider implementation retrieves an access token * to be used by an AuthenticationProvider implementation. */ @@ -15,7 +14,7 @@ export interface AccessTokenProvider { /** * Retrieves an access token for the given target URL. * @param {string} url - The target URL. - * @param {Record} - The additional authentication context to pass to the authentication library. + * @param {Record} additionalAuthenticationContext - The additional authentication context to pass to the authentication library. * @returns {Promise} The access token. */ getAuthorizationToken: (url?: string, additionalAuthenticationContext?: Record) => Promise; diff --git a/packages/abstractions/src/authentication/allowedHostsValidator.ts b/packages/abstractions/src/authentication/allowedHostsValidator.ts index c632eeff4..efdd8deca 100644 --- a/packages/abstractions/src/authentication/allowedHostsValidator.ts +++ b/packages/abstractions/src/authentication/allowedHostsValidator.ts @@ -5,8 +5,10 @@ * ------------------------------------------------------------------------------------------- */ -/** Maintains a list of valid hosts and allows authentication providers to - * check whether a host is valid before authenticating a request */ +/** + * Maintains a list of valid hosts and allows authentication providers to + * check whether a host is valid before authenticating a request + */ export class AllowedHostsValidator { private allowedHosts: Set; /** @@ -35,6 +37,7 @@ export class AllowedHostsValidator { /** * Checks whether the provided host is valid. * @param url The url to check. + * @returns True if the host is valid, false otherwise. */ public isUrlHostValid(url: string): boolean { if (!url) return false; diff --git a/packages/abstractions/src/authentication/anonymousAuthenticationProvider.ts b/packages/abstractions/src/authentication/anonymousAuthenticationProvider.ts index 854157667..9e8bad921 100644 --- a/packages/abstractions/src/authentication/anonymousAuthenticationProvider.ts +++ b/packages/abstractions/src/authentication/anonymousAuthenticationProvider.ts @@ -9,12 +9,7 @@ import { type AuthenticationProvider } from "./authenticationProvider"; /** This authentication provider does not perform any authentication. */ export class AnonymousAuthenticationProvider implements AuthenticationProvider { - public authenticateRequest = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _: RequestInformation, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _2?: Record, - ): Promise => { + public authenticateRequest = (_: RequestInformation, _2?: Record): Promise => { return Promise.resolve(); }; } diff --git a/packages/abstractions/src/authentication/apiKeyAuthenticationProvider.ts b/packages/abstractions/src/authentication/apiKeyAuthenticationProvider.ts index e5f0dbc3f..60a5cdd18 100644 --- a/packages/abstractions/src/authentication/apiKeyAuthenticationProvider.ts +++ b/packages/abstractions/src/authentication/apiKeyAuthenticationProvider.ts @@ -13,7 +13,6 @@ import { validateProtocol } from "./validateProtocol"; export class ApiKeyAuthenticationProvider implements AuthenticationProvider { private readonly validator: AllowedHostsValidator; /** - * @constructor Creates an instance of ApiKeyAuthenticationProvider * @param apiKey The API Key to use for authentication * @param parameterName The name of the parameter to use for authentication * @param location The location of the parameter to use for authentication diff --git a/packages/abstractions/src/authentication/authenticationProvider.ts b/packages/abstractions/src/authentication/authenticationProvider.ts index 4219e2bb8..cc3836dc2 100644 --- a/packages/abstractions/src/authentication/authenticationProvider.ts +++ b/packages/abstractions/src/authentication/authenticationProvider.ts @@ -7,16 +7,14 @@ import { type RequestInformation } from "../requestInformation"; /** - * @interface - * Interface to be implementated to provide authentication information for a request. - * @property {Function} authenticateRequest - The function to authenticate the request. + * Interface to be implemented to provide authentication information for a request. */ export interface AuthenticationProvider { /** * Authenticates the application and returns a token base on the provided Uri. * @param request the request to authenticate. - * @param {Record} - The additional authentication context to pass to the authentication library. - * @return a Promise to await for the authentication to be completed. + * @param {Record} additionalAuthenticationContext - The additional authentication context to pass to the authentication library. + * @returns a Promise to await for the authentication to be completed. */ authenticateRequest: (request: RequestInformation, additionalAuthenticationContext?: Record) => Promise; } diff --git a/packages/abstractions/src/authentication/baseBearerTokenAuthenticationProvider.ts b/packages/abstractions/src/authentication/baseBearerTokenAuthenticationProvider.ts index cbb92e51f..c51ac4a2f 100644 --- a/packages/abstractions/src/authentication/baseBearerTokenAuthenticationProvider.ts +++ b/packages/abstractions/src/authentication/baseBearerTokenAuthenticationProvider.ts @@ -13,8 +13,8 @@ import type { AuthenticationProvider } from "./authenticationProvider"; export class BaseBearerTokenAuthenticationProvider implements AuthenticationProvider { private static readonly authorizationHeaderKey = "Authorization"; /** - * - * @param accessTokenProvider + * The constructor for the BaseBearerTokenAuthenticationProvider + * @param accessTokenProvider The AccessTokenProvider instance that this provider will use to authenticate requests. */ public constructor(public readonly accessTokenProvider: AccessTokenProvider) {} diff --git a/packages/abstractions/src/authentication/validateProtocol.ts b/packages/abstractions/src/authentication/validateProtocol.ts index 72b08ea0d..5dad7d10a 100644 --- a/packages/abstractions/src/authentication/validateProtocol.ts +++ b/packages/abstractions/src/authentication/validateProtocol.ts @@ -7,11 +7,20 @@ import { inNodeEnv } from "../utils"; const localhostStrings: Set = new Set(["localhost", "[::1]", "::1", "127.0.0.1"]); +/** + * Validates the protocol of the url. + * @param url - The url to validate. + */ export function validateProtocol(url: string): void { if (!isLocalhostUrl(url) && !url.toLocaleLowerCase().startsWith("https://") && !windowUrlStartsWithHttps()) { throw new Error("Authentication scheme can only be used with https requests"); } } + +/** + * Checks if the window url starts with https. + * @returns True if the window url starts with https, false otherwise. + */ function windowUrlStartsWithHttps(): boolean { if (!inNodeEnv()) { return window.location.protocol.toLocaleLowerCase() === "https:"; @@ -19,6 +28,11 @@ function windowUrlStartsWithHttps(): boolean { return false; } +/** + * Checks if the url is a localhost url. + * @param urlString - The url to check. + * @returns True if the url is a localhost url, false otherwise. + */ export function isLocalhostUrl(urlString: string): boolean { try { const url = new URL(urlString); diff --git a/packages/abstractions/src/dateOnly.ts b/packages/abstractions/src/dateOnly.ts index 05a3acbb5..15e142176 100644 --- a/packages/abstractions/src/dateOnly.ts +++ b/packages/abstractions/src/dateOnly.ts @@ -11,6 +11,10 @@ export class DateOnly implements DateOnlyInterface { /** * Creates a new DateOnly from the given string. + * @param root0 The year, month, and day + * @param root0.year The year + * @param root0.month The month + * @param root0.day The day * @returns The new DateOnly * @throws An error if the year is invalid * @throws An error if the month is invalid @@ -78,24 +82,25 @@ interface DateOnlyInterface { /** * The year * @default 0 - * @minium 0 */ year: number; /** * The month * @default 1 - * @minium 1 - * @maximum 12 */ month: number; /** * The day * @default 1 - * @minium 1 - * @maximum 31 */ day: number; } +/** + * Formats a segment of a date to a string + * @param segment The segment to format + * @param digits The number of digits to pad + * @returns The formatted segment + */ export function formatSegment(segment: number, digits = 2): string { return segment.toString().padStart(digits, "0"); } diff --git a/packages/abstractions/src/duration.ts b/packages/abstractions/src/duration.ts index 6cbd442f7..29c6ddb25 100644 --- a/packages/abstractions/src/duration.ts +++ b/packages/abstractions/src/duration.ts @@ -12,6 +12,15 @@ import { parse as parseDuration, serialize as serializeDuration } from "tinydura export class Duration implements DurationInterface { /** * Creates a new Duration value from the given parameters. + * @param root0 The years, months, weeks, days, hours, minutes, seconds, and negative flag + * @param root0.years The years + * @param root0.months The months + * @param root0.weeks The weeks + * @param root0.days The days + * @param root0.hours The hours + * @param root0.minutes The minutes + * @param root0.seconds The seconds + * @param root0.negative The negative flag * @returns The new Duration * @throws An error if years is invalid * @throws An error if months is invalid diff --git a/packages/abstractions/src/headers.ts b/packages/abstractions/src/headers.ts index d39e1f46a..b0799fb59 100644 --- a/packages/abstractions/src/headers.ts +++ b/packages/abstractions/src/headers.ts @@ -8,7 +8,6 @@ import { createRecordWithCaseInsensitiveKeys } from "./recordWithCaseInsensitive /** * A collection class for HTTP headers. The keys are case-insensitive. - * @extends Map * @example * ```typescript * const headers = new Headers(); @@ -67,6 +66,7 @@ export class Headers extends Map> { /** * Checks if a header exists. * @param key The name of the header to check for. + * @returns whether or not a header with the given name/key exists. */ public has(key: string): boolean { return !!key && !!this.headers[key]; @@ -248,6 +248,7 @@ export class Headers extends Map> { /** * check if the headers collection is empty + * @returns a boolean indicating if the headers collection is empty */ public isEmpty(): boolean { return Object.keys(this.headers).length === 0; diff --git a/packages/abstractions/src/multipartBody.ts b/packages/abstractions/src/multipartBody.ts index 1f72778a9..be048e06b 100644 --- a/packages/abstractions/src/multipartBody.ts +++ b/packages/abstractions/src/multipartBody.ts @@ -158,10 +158,7 @@ export const serializeMultipartBody = (writer: SerializationWriter, multipartBod writer.writeStringValue(undefined, "\r\n"); }; -export const deserializeIntoMultipartBody = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _: Partial | undefined = new MultipartBody(), -): Record void> => { +export const deserializeIntoMultipartBody = (_: Partial | undefined = new MultipartBody()): Record void> => { throw new Error("Not implemented"); }; export const createMessageFromDiscriminatorValue = (parseNode: ParseNode | undefined) => { diff --git a/packages/abstractions/src/recordWithCaseInsensitiveKeys.ts b/packages/abstractions/src/recordWithCaseInsensitiveKeys.ts index fd00cfba3..7005c37f7 100644 --- a/packages/abstractions/src/recordWithCaseInsensitiveKeys.ts +++ b/packages/abstractions/src/recordWithCaseInsensitiveKeys.ts @@ -5,6 +5,11 @@ * ------------------------------------------------------------------------------------------- */ +/** + * A function that takes a property name and returns its canonical form. + * @param canon The function that canonicalizes the property name. + * @returns A new object that can be used as a dictionary with case-insensitive keys. + */ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { const keysNormalizationMap = new Map(); return new Proxy>( @@ -12,6 +17,9 @@ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { { /** * Intercept the get operation on the dictionary object and forward it to the target object using Reflect.get. + * @param target The target object. + * @param prop The property to get. + * @returns The value of the property. */ get(target, prop) { const normalKey = canon(prop); @@ -19,6 +27,10 @@ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { }, /** * Intercept the set operation on the dictionary object and forward it to the target object using Reflect.set. + * @param target The target object. + * @param prop The property to set. + * @param value The value to set. + * @returns A boolean indicating whether the property was set. */ set(target, prop, value) { const nonNormalKey = prop.toString(); @@ -28,6 +40,9 @@ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { }, /** * Intercept the has operation on the dictionary object and forward it to the target object using Reflect.has. + * @param _ the target object. + * @param prop The property to check. + * @returns A boolean indicating whether the property exists. */ has(_, prop) { const normalKey = canon(prop); @@ -35,6 +50,10 @@ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { }, /** * Intercept the defineProperty operation on the dictionary object and forward it to the target object using Reflect.defineProperty. + * @param target The target object. + * @param prop The property to define. + * @param attribs The attributes of the property. + * @returns A boolean indicating whether the property was defined. */ defineProperty(target, prop, attribs) { const nonNormalKey = prop.toString(); @@ -44,6 +63,9 @@ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { }, /** * Intercept the deleteProperty operation on the dictionary object and forward it to the target object using Reflect.deleteProperty. + * @param target The target object. + * @param prop The property to delete. + * @returns A boolean indicating whether the property was deleted. */ deleteProperty(target, prop) { const normalKey = canon(prop); @@ -52,6 +74,9 @@ function dictionaryWithCanonicalKeys(canon: (prop: keyof any) => string) { }, /** * Intercept the getOwnPropertyDescriptor operation on the dictionary object and forward it to the target object using Reflect.getOwnPropertyDescriptor. + * @param target The target object. + * @param prop The property to gets its descriptor. + * @returns The property descriptor. */ getOwnPropertyDescriptor(target, prop) { return Reflect.getOwnPropertyDescriptor(target, canon(prop)); diff --git a/packages/abstractions/src/requestAdapter.ts b/packages/abstractions/src/requestAdapter.ts index 46428f07d..cda4565d2 100644 --- a/packages/abstractions/src/requestAdapter.ts +++ b/packages/abstractions/src/requestAdapter.ts @@ -15,25 +15,23 @@ import type { TimeOnly } from "./timeOnly"; export interface RequestAdapter { /** * Gets the serialization writer factory currently in use for the HTTP core service. - * @return the serialization writer factory currently in use for the HTTP core service. + * @returns the serialization writer factory currently in use for the HTTP core service. */ getSerializationWriterFactory(): SerializationWriterFactory; /** * Executes the HTTP request specified by the given RequestInformation and returns the deserialized response model. * @param requestInfo the request info to execute. - * @param errorMappings the error factories mapping to use in case of a failed request. * @param type the class of the response model to deserialize the response into. - * @typeParam ModelType the type of the response model to deserialize the response into. - * @return a {@link Promise} with the deserialized response model. + * @param errorMappings the error factories mapping to use in case of a failed request. + * @returns a {@link Promise} with the deserialized response model. */ send(requestInfo: RequestInformation, type: ParsableFactory, errorMappings: ErrorMappings | undefined): Promise; /** * Executes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. * @param requestInfo the request info to execute. - * @param errorMappings the error factories mapping to use in case of a failed request. * @param type the class of the response model to deserialize the response into. - * @typeParam ModelType the type of the response model to deserialize the response into. - * @return a {@link Promise} with the deserialized response model collection. + * @param errorMappings the error factories mapping to use in case of a failed request. + * @returns a {@link Promise} with the deserialized response model collection. */ sendCollection(requestInfo: RequestInformation, type: ParsableFactory, errorMappings: ErrorMappings | undefined): Promise; /** @@ -41,45 +39,40 @@ export interface RequestAdapter { * @param requestInfo the request info to execute. * @param responseType the class of the response model to deserialize the response into. * @param errorMappings the error factories mapping to use in case of a failed request. - * @param type the class of the response model to deserialize the response into. - * @typeParam ResponseType the type of the response model to deserialize the response into. - * @return a {@link Promise} with the deserialized response model collection. + * @returns a {@link Promise} with the deserialized response model collection. */ sendCollectionOfPrimitive>(requestInfo: RequestInformation, responseType: Exclude, errorMappings: ErrorMappings | undefined): Promise; /** * Executes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. * @param requestInfo the request info to execute. - * @param errorMappings the error factories mapping to use in case of a failed request. * @param responseType the class of the response model to deserialize the response into. - * @typeParam ResponseType the type of the response model to deserialize the response into. - * @return a {@link Promise} with the deserialized primitive response model. + * @param errorMappings the error factories mapping to use in case of a failed request. + * @returns a {@link Promise} with the deserialized primitive response model. */ sendPrimitive(requestInfo: RequestInformation, responseType: PrimitiveTypesForDeserialization, errorMappings: ErrorMappings | undefined): Promise; /** * Executes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. * @param requestInfo the request info to execute. * @param errorMappings the error factories mapping to use in case of a failed request. - * @return a {@link Promise} of void. + * @returns a {@link Promise} of void. */ sendNoResponseContent(requestInfo: RequestInformation, errorMappings: ErrorMappings | undefined): Promise; /** * Executes the HTTP request specified by the given RequestInformation and returns the deserialized enum response model. - * * @template EnumObject - The type of the enum object. Must extend Record. - * @param {RequestInformation} requestInfo - The request info to execute. - * @param {EnumObject} enumObject - The Enum object expected in the response. - * @param {ErrorMappings | undefined} errorMappings - the error factories mapping to use in case of a failed request. - * @returns {Promise} - A promise that resolves to the response of the request, or undefined if an error occurred. + * @param requestInfo - The request info to execute. + * @param enumObject - The Enum object expected in the response. + * @param errorMappings - the error factories mapping to use in case of a failed request. + * @returns A promise that resolves to the response of the request, or undefined if an error occurred. */ sendEnum>(requestInfo: RequestInformation, enumObject: EnumObject, errorMappings: ErrorMappings | undefined): Promise; /** * Executes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. - * * @template EnumObject - The type of the enum objects. Must extend Record. - * @param {RequestInformation} requestInfo - The request info to execute. - * @param {EnumObject} enumObject - The Enum object expected in the response. - * @param {ErrorMappings | undefined} errorMappings - the error factories mapping to use in case of a failed request. - * @returns {Promise} - with the deserialized response model collection. + * @param requestInfo - The request info to execute. + * @param enumObject - The Enum object expected in the response. + * @param errorMappings - the error factories mapping to use in case of a failed request. + * @returns a promise with the deserialized response model collection. */ sendCollectionOfEnum>(requestInfo: RequestInformation, enumObject: EnumObject, errorMappings: ErrorMappings | undefined): Promise; /** @@ -92,8 +85,7 @@ export interface RequestAdapter { /** * Converts the given RequestInformation into a native HTTP request used by the implementing adapter. * @param requestInfo the request info to convert. - * @typeParam T the type of the native request. - * @return a {@link Promise} with the native request. + * @returns a {@link Promise} with the native request. */ convertToNativeRequest(requestInfo: RequestInformation): Promise; } diff --git a/packages/abstractions/src/requestInformation.ts b/packages/abstractions/src/requestInformation.ts index af6e6a634..f3c5a3491 100644 --- a/packages/abstractions/src/requestInformation.ts +++ b/packages/abstractions/src/requestInformation.ts @@ -45,8 +45,10 @@ export class RequestInformation implements RequestInformationSetContent { public pathParameters: Record = createRecordWithCaseInsensitiveKeys(); /** The URL template for the request */ public urlTemplate?: string; - /** Gets the URL of the request */ - // eslint-disable-next-line @typescript-eslint/naming-convention + /** + * Gets the URL of the request + * @returns the url string + */ public get URL(): string { const rawUrl = this.pathParameters[RequestInformation.raw_url_key] as string; if (this.uri) { @@ -92,24 +94,36 @@ export class RequestInformation implements RequestInformationSetContent { /** The Request Headers. */ public headers: Headers = new Headers(); private _requestOptions: Record = createRecordWithCaseInsensitiveKeys(); - /** Gets the request options for the request. */ + /** + * Gets the request options for the request. + * @returns the request options. + */ public getRequestOptions() { return this._requestOptions; } - /** Adds the headers for the request. */ + /** + * Adds the headers for the request. + * @param source The source collection to add the headers to + */ public addRequestHeaders(source: Record | undefined) { if (source) { this.headers.addAllRaw(source); } } - /** Adds the request options for the request. */ + /** + * Adds the request options for the request. + * @param options the options to add. + */ public addRequestOptions(options: RequestOption[] | undefined) { if (!options || options.length === 0) return; options.forEach((option) => { this._requestOptions[option.getKey()] = option; }); } - /** Removes the request options for the request. */ + /** + * Removes the request options for the request. + * @param options the options to remove. + */ public removeRequestOptions(...options: RequestOption[]) { if (!options || options.length === 0) return; options.forEach((option) => { @@ -122,10 +136,10 @@ export class RequestInformation implements RequestInformationSetContent { private static readonly requestTypeKey = "com.microsoft.kiota.request.type"; /** * Sets the request body from a model with the specified content type. - * @param value the models. - * @param contentType the content type. * @param requestAdapter The adapter service to get the serialization writer from. - * @typeParam T the model type. + * @param contentType the content type. + * @param value the models. + * @param modelSerializerFunction the serialization function for the model type. */ public setContentFromParsable = (requestAdapter?: RequestAdapter, contentType?: string, value?: T[] | T, modelSerializerFunction?: ModelSerializerFunction): void => { trace.getTracer(RequestInformation.tracerKey).startActiveSpan("setContentFromParsable", (span) => { @@ -140,12 +154,7 @@ export class RequestInformation implements RequestInformationSetContent { if (Array.isArray(value)) { span.setAttribute(RequestInformation.requestTypeKey, "object[]"); - writer.writeCollectionOfObjectValues( - undefined, - value, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - modelSerializerFunction, - ); + writer.writeCollectionOfObjectValues(undefined, value, modelSerializerFunction); } else { span.setAttribute(RequestInformation.requestTypeKey, "object"); writer.writeObjectValue(undefined, value, modelSerializerFunction); @@ -172,10 +181,9 @@ export class RequestInformation implements RequestInformationSetContent { }; /** * Sets the request body from a model with the specified content type. - * @param value the scalar values to serialize. - * @param contentType the content type. * @param requestAdapter The adapter service to get the serialization writer from. - * @typeParam T the model type. + * @param contentType the content type. + * @param value the scalar values to serialize. */ public setContentFromScalar = (requestAdapter: RequestAdapter | undefined, contentType: string | undefined, value: T[] | T): void => { trace.getTracer(RequestInformation.tracerKey).startActiveSpan("setContentFromScalar", (span) => { diff --git a/packages/abstractions/src/responseHandler.ts b/packages/abstractions/src/responseHandler.ts index 82408fa73..944e40175 100644 --- a/packages/abstractions/src/responseHandler.ts +++ b/packages/abstractions/src/responseHandler.ts @@ -12,9 +12,7 @@ export interface ResponseHandler { * Callback method that is invoked when a response is received. * @param response The native response object. * @param errorMappings the error factories mapping to use in case of a failed request. - * @typeParam NativeResponseType The type of the native response object. - * @typeParam ModelType The type of the response model object. - * @return A {@link Promise} that represents the asynchronous operation and contains the deserialized response. + * @returns A {@link Promise} that represents the asynchronous operation and contains the deserialized response. */ handleResponse(response: NativeResponseType, errorMappings: ErrorMappings | undefined): Promise; } diff --git a/packages/abstractions/src/responseHandlerOptions.ts b/packages/abstractions/src/responseHandlerOptions.ts index 73521276e..e8a3610eb 100644 --- a/packages/abstractions/src/responseHandlerOptions.ts +++ b/packages/abstractions/src/responseHandlerOptions.ts @@ -11,13 +11,10 @@ import type { ResponseHandler } from "./responseHandler"; export const ResponseHandlerOptionKey = "ResponseHandlerOptionKey"; /** - * @class - * @implements RequestOption * Options to intercept the request from the main pipeline. */ export class ResponseHandlerOption implements RequestOption { /** - * @public * The response handler to be used when processing the response. */ public responseHandler?: ResponseHandler; diff --git a/packages/abstractions/src/serialization/additionalDataHolder.ts b/packages/abstractions/src/serialization/additionalDataHolder.ts index d3ca73c6b..e8e72a2b1 100644 --- a/packages/abstractions/src/serialization/additionalDataHolder.ts +++ b/packages/abstractions/src/serialization/additionalDataHolder.ts @@ -9,7 +9,7 @@ export interface AdditionalDataHolder { /** * Gets the additional data for this object that did not belong to the properties. - * @return The additional data for this object. + * @returns The additional data for this object. */ additionalData?: Record; } diff --git a/packages/abstractions/src/serialization/kiotaJsonSerializer.ts b/packages/abstractions/src/serialization/kiotaJsonSerializer.ts index a3a7204d9..6995919a6 100644 --- a/packages/abstractions/src/serialization/kiotaJsonSerializer.ts +++ b/packages/abstractions/src/serialization/kiotaJsonSerializer.ts @@ -32,7 +32,7 @@ export function serializeToJsonAsString(value: T, serializat /** * Serializes a collection of parsable objects into a buffer - * @param value the value to serialize + * @param values the value to serialize * @param serializationFunction the serialization function for the model type * @returns a string representing the serialized value */ @@ -42,7 +42,7 @@ export function serializeCollectionToJson(values: T[], seria /** * Serializes a collection of parsable objects into a string representation - * @param value the value to serialize + * @param values the value to serialize * @param serializationFunction the serialization function for the model type * @returns a string representing the serialized value */ diff --git a/packages/abstractions/src/serialization/kiotaSerializer.ts b/packages/abstractions/src/serialization/kiotaSerializer.ts index 09b08a2f2..f8fa5f300 100644 --- a/packages/abstractions/src/serialization/kiotaSerializer.ts +++ b/packages/abstractions/src/serialization/kiotaSerializer.ts @@ -38,7 +38,7 @@ export function serializeToString(contentType: string, value /** * Serializes a collection of parsable objects into a buffer * @param contentType the content type to serialize to - * @param value the value to serialize + * @param values the value to serialize * @param serializationFunction the serialization function for the model type * @returns a string representing the serialized value */ @@ -51,7 +51,7 @@ export function serializeCollection(contentType: string, val /** * Serializes a collection of parsable objects into a string representation * @param contentType the content type to serialize to - * @param value the value to serialize + * @param values the value to serialize * @param serializationFunction the serialization function for the model type * @returns a string representing the serialized value */ @@ -60,6 +60,13 @@ export function serializeCollectionToString(contentType: str return getStringValueFromBuffer(buffer); } +/** + * Gets a serialization writer for a given content type + * @param contentType the content type to serialize to + * @param value the value to serialize + * @param serializationFunction the serialization function for the model type + * @returns the serialization writer for the given content type + */ function getSerializationWriter(contentType: string, value: unknown, serializationFunction: unknown): SerializationWriter { if (!contentType) { throw new Error("content type cannot be undefined or empty"); @@ -73,6 +80,11 @@ function getSerializationWriter(contentType: string, value: unknown, serializati return SerializationWriterFactoryRegistry.defaultInstance.getSerializationWriter(contentType); } +/** + * Gets a string value from a buffer + * @param buffer the buffer to get a string from + * @returns the string representation of the buffer + */ function getStringValueFromBuffer(buffer: ArrayBuffer): string { const decoder = new TextDecoder(); return decoder.decode(buffer); @@ -92,6 +104,13 @@ export function deserialize(contentType: string, bufferOrStr const reader = getParseNode(contentType, bufferOrString, factory); return reader.getObjectValue(factory); } +/** + * Deserializes a buffer into a parsable object + * @param contentType the content type to serialize to + * @param buffer the value to deserialize + * @param factory the factory for the model type + * @returns the deserialized parsable object + */ function getParseNode(contentType: string, buffer: ArrayBuffer, factory: unknown): ParseNode { if (!contentType) { throw new Error("content type cannot be undefined or empty"); @@ -119,6 +138,11 @@ export function deserializeCollection(contentType: string, b return reader.getCollectionOfObjectValues(factory); } +/** + * Deserializes a buffer into a a collection of parsable object + * @param value the string to get a buffer from + * @returns the ArrayBuffer representation of the string + */ function getBufferFromString(value: string): ArrayBuffer { const encoder = new TextEncoder(); return encoder.encode(value).buffer; diff --git a/packages/abstractions/src/serialization/parsable.ts b/packages/abstractions/src/serialization/parsable.ts index c1f5ec3a0..a38779120 100644 --- a/packages/abstractions/src/serialization/parsable.ts +++ b/packages/abstractions/src/serialization/parsable.ts @@ -8,6 +8,5 @@ /** * Defines a serializable model object. */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface Parsable {} diff --git a/packages/abstractions/src/serialization/parseNode.ts b/packages/abstractions/src/serialization/parseNode.ts index d0eaafc87..42a705184 100644 --- a/packages/abstractions/src/serialization/parseNode.ts +++ b/packages/abstractions/src/serialization/parseNode.ts @@ -18,90 +18,90 @@ import type { ParsableFactory } from "./parsableFactory"; export interface ParseNode { /** * Gets the string value of the node. - * @return the string value of the node. + * @returns the string value of the node. */ getStringValue(): string | undefined; /** * Gets a new parse node for the given identifier. * @param identifier the identifier of the current node property. - * @return a new parse node for the given identifier. + * @returns a new parse node for the given identifier. */ getChildNode(identifier: string): ParseNode | undefined; /** * Gets the boolean value of the node. - * @return the boolean value of the node. + * @returns the boolean value of the node. */ getBooleanValue(): boolean | undefined; /** * Gets the Number value of the node. - * @return the Number value of the node. + * @returns the Number value of the node. */ getNumberValue(): number | undefined; /** * Gets the Guid value of the node. - * @return the Guid value of the node. + * @returns the Guid value of the node. */ getGuidValue(): Guid | undefined; /** * Gets the Date value of the node. - * @return the Date value of the node. + * @returns the Date value of the node. */ getDateValue(): Date | undefined; /** * Gets the Duration value of the node. - * @return the Duration value of the node. + * @returns the Duration value of the node. */ getDurationValue(): Duration | undefined; /** * Gets the DateOnly value of the node. - * @return the DateOnly value of the node. + * @returns the DateOnly value of the node. */ getDateOnlyValue(): DateOnly | undefined; /** * Gets the TimeOnly value of the node. - * @return the TimeOnly value of the node. + * @returns the TimeOnly value of the node. */ getTimeOnlyValue(): TimeOnly | undefined; /** * Gets the collection of primitive values of the node. - * @return the collection of primitive values of the node. + * @returns the collection of primitive values of the node. */ getCollectionOfPrimitiveValues(): T[] | undefined; /** * Gets the collection of object values of the node. - * @return the collection of object values of the node. + * @returns the collection of object values of the node. */ getCollectionOfObjectValues(parsableFactory: ParsableFactory): T[] | undefined; /** * Gets the model object value of the node. - * @return the model object value of the node. + * @returns the model object value of the node. */ getObjectValue(parsableFactory: ParsableFactory): T; /** * Gets the Enum values of the node. - * @return the Enum values of the node. + * @returns the Enum values of the node. */ getCollectionOfEnumValues(type: any): T[]; /** * Gets the Enum value of the node. - * @return the Enum value of the node. + * @returns the Enum value of the node. */ getEnumValue(type: any): T | undefined; /** * Gets the callback called before the node is deserialized. - * @return the callback called before the node is deserialized. + * @returns the callback called before the node is deserialized. */ onBeforeAssignFieldValues: ((value: Parsable) => void) | undefined; /** * Gets the callback called after the node is deserialized. - * @return the callback called after the node is deserialized. + * @returns the callback called after the node is deserialized. */ onAfterAssignFieldValues: ((value: Parsable) => void) | undefined; /** * Gets the byte array value of the node. - * @return the byte array value of the node. + * @returns the byte array value of the node. */ getByteArrayValue(): ArrayBuffer | undefined; } diff --git a/packages/abstractions/src/serialization/parseNodeFactory.ts b/packages/abstractions/src/serialization/parseNodeFactory.ts index 24b4ebe9f..7d8882939 100644 --- a/packages/abstractions/src/serialization/parseNodeFactory.ts +++ b/packages/abstractions/src/serialization/parseNodeFactory.ts @@ -16,9 +16,9 @@ export interface ParseNodeFactory { getValidContentType(): string; /** * Creates a {@link ParseNode} from the given {@link ArrayBuffer} and content type. - * @param content the {@link ArrayBuffer} to read from. * @param contentType the content type of the {@link ArrayBuffer}. - * @return a {@link ParseNode} that can deserialize the given {@link ArrayBuffer}. + * @param content the {@link ArrayBuffer} to read from. + * @returns a {@link ParseNode} that can deserialize the given {@link ArrayBuffer}. */ getRootParseNode(contentType: string, content: ArrayBuffer): ParseNode; } diff --git a/packages/abstractions/src/serialization/serializationWriter.ts b/packages/abstractions/src/serialization/serializationWriter.ts index 3328f4fdf..a8c37c7de 100644 --- a/packages/abstractions/src/serialization/serializationWriter.ts +++ b/packages/abstractions/src/serialization/serializationWriter.ts @@ -71,13 +71,13 @@ export interface SerializationWriter { /** * Writes the specified collection of primitive values to the stream with an optional given key. * @param key the key to write the value with. - * @param value the value to write to the stream. + * @param values the value to write to the stream. */ writeCollectionOfPrimitiveValues(key?: string, values?: T[] | null): void; /** * Writes the specified collection of object values to the stream with an optional given key. * @param key the key to write the value with. - * @param value the value to write to the stream. + * @param values the value to write to the stream. */ writeCollectionOfObjectValues(key?: string, values?: T[] | null, serializerMethod?: ModelSerializerFunction): void; /** @@ -100,7 +100,7 @@ export interface SerializationWriter { writeNullValue(key?: string): void; /** * Gets the value of the serialized content. - * @return the value of the serialized content. + * @returns the value of the serialized content. */ getSerializedContent(): ArrayBuffer; /** @@ -110,17 +110,17 @@ export interface SerializationWriter { writeAdditionalData(value: Record | undefined): void; /** * Gets the callback called before the object gets serialized. - * @return the callback called before the object gets serialized. + * @returns the callback called before the object gets serialized. */ onBeforeObjectSerialization: ((value: Parsable) => void) | undefined; /** * Gets the callback called after the object gets serialized. - * @return the callback called after the object gets serialized. + * @returns the callback called after the object gets serialized. */ onAfterObjectSerialization: ((value: Parsable) => void) | undefined; /** * Gets the callback called right after the serialization process starts. - * @return the callback called right after the serialization process starts. + * @returns the callback called right after the serialization process starts. */ onStartObjectSerialization: ((value: Parsable, writer: SerializationWriter) => void) | undefined; } diff --git a/packages/abstractions/src/serialization/serializationWriterFactory.ts b/packages/abstractions/src/serialization/serializationWriterFactory.ts index 4a7736065..2bcc3c712 100644 --- a/packages/abstractions/src/serialization/serializationWriterFactory.ts +++ b/packages/abstractions/src/serialization/serializationWriterFactory.ts @@ -10,13 +10,13 @@ import type { SerializationWriter } from "./serializationWriter"; export interface SerializationWriterFactory { /** * Gets the content type this factory creates serialization writers for. - * @return the content type this factory creates serialization writers for. + * @returns the content type this factory creates serialization writers for. */ getValidContentType(): string; /** * Creates a new SerializationWriter instance for the given content type. * @param contentType the content type to create a serialization writer for. - * @return a new SerializationWriter instance for the given content type. + * @returns a new SerializationWriter instance for the given content type. */ getSerializationWriter(contentType: string): SerializationWriter; } diff --git a/packages/abstractions/src/serialization/untypedArray.ts b/packages/abstractions/src/serialization/untypedArray.ts index 36ec81730..fae6611ee 100644 --- a/packages/abstractions/src/serialization/untypedArray.ts +++ b/packages/abstractions/src/serialization/untypedArray.ts @@ -17,7 +17,7 @@ export interface UntypedArray extends UntypedNode { /** * Type guard to assert that an UntypedNode instance is an UntypedArray. * @param node The UntypedNode to check. - * @return boolean indicating if the node is an UntypedArray. + * @returns boolean indicating if the node is an UntypedArray. */ export const isUntypedArray = (node: UntypedNode): node is UntypedArray => { const proposedNode = node as UntypedArray; @@ -27,7 +27,7 @@ export const isUntypedArray = (node: UntypedNode): node is UntypedArray => { /** * Factory to create an UntypedArray from an array of UntypedNodes. * @param value The value to create from. - * @return The created UntypedArray. + * @returns The created UntypedArray. */ export const createUntypedArray = (value: UntypedNode[]): UntypedArray => { return { diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts index 787d35451..1506e0919 100644 --- a/packages/abstractions/src/serialization/untypedBoolean.ts +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -17,7 +17,7 @@ export interface UntypedBoolean extends UntypedNode { /** * Type guard to assert that an UntypedNode instance is an UntypedBoolean. * @param node The UntypedNode to check. - * @return boolean indicating if the node is an UntypedBoolean. + * @returns boolean indicating if the node is an UntypedBoolean. */ export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { const proposedNode = node as UntypedBoolean; @@ -27,7 +27,7 @@ export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { /** * Factory to create an UntypedBoolean from a boolean. * @param value The boolean value to create from. - * @return The created UntypedBoolean. + * @returns The created UntypedBoolean. */ export function createUntypedBoolean(value: boolean): UntypedBoolean { return { diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts index c06003b52..d6ef678a0 100644 --- a/packages/abstractions/src/serialization/untypedNode.ts +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -5,7 +5,6 @@ * ------------------------------------------------------------------------------------------- */ -/* eslint-disable @typescript-eslint/no-unused-vars */ import type { Parsable } from "./parsable"; import type { ParseNode } from "./parseNode"; import type { SerializationWriter } from "./serializationWriter"; @@ -26,6 +25,8 @@ export interface UntypedNode extends Parsable { /** * Factory to create an UntypedNode from a string during deserialization. + * @param _parseNode The ParseNode to deserialize. + * @returns A function that can deserialize an UntypedNode. */ export const createUntypedNodeFromDiscriminatorValue: ParsableFactory = (_parseNode: ParseNode | undefined): ((_instance?: Parsable) => Record void>) => { return deserializeIntoUntypedNode; @@ -34,7 +35,7 @@ export const createUntypedNodeFromDiscriminatorValue: ParsableFactory { const potentialNode = node as UntypedNode; @@ -43,6 +44,8 @@ export const isUntypedNode = (node: unknown): node is UntypedNode => { /** * The deserialization implementation for UntypedNode. + * @param untypedNode - The UntypedNode to deserialize. + * @returns A function that can deserialize a ParseNode into the provided UntypedNode. */ export const deserializeIntoUntypedNode: DeserializeIntoModelFunction = (untypedNode: Partial | undefined = {}): Record void> => { return { @@ -57,6 +60,8 @@ export const deserializeIntoUntypedNode: DeserializeIntoModelFunction | undefined = {}): void => { return; diff --git a/packages/abstractions/src/serialization/untypedNull.ts b/packages/abstractions/src/serialization/untypedNull.ts index 172df01d1..47ab71413 100644 --- a/packages/abstractions/src/serialization/untypedNull.ts +++ b/packages/abstractions/src/serialization/untypedNull.ts @@ -17,7 +17,7 @@ export interface UntypedNull extends UntypedNode { /** * Type guard to assert that an object instance is an UntypedNull. * @param node The object to check. - * @return boolean indicating if the node is an UntypedNull. + * @returns boolean indicating if the node is an UntypedNull. */ export function isUntypedNull(node: UntypedNode): node is UntypedNull { return node.value === null; @@ -25,7 +25,7 @@ export function isUntypedNull(node: UntypedNode): node is UntypedNull { /** * Factory to create an UntypedNull from a boolean. - * @return The created UntypedNull. + * @returns The created UntypedNull. */ export function createUntypedNull(): UntypedNull { return { diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts index 0b3a97bf5..370f299f5 100644 --- a/packages/abstractions/src/serialization/untypedNumber.ts +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -17,7 +17,7 @@ export interface UntypedNumber extends UntypedNode { /** * Type guard to assert that an object instance is an UntypedNumber. * @param node The object to check. - * @return boolean indicating if the node is an UntypedNumber. + * @returns boolean indicating if the node is an UntypedNumber. */ export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { const proposedNode = node as UntypedNumber; @@ -27,7 +27,7 @@ export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { /** * Factory to create an UntypedNumber from a number. * @param value The number value to create from. - * @return The created UntypedNumber. + * @returns The created UntypedNumber. */ export function createUntypedNumber(value: number): UntypedNumber { return { diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index eb6efb8d4..6cba9f1a1 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -17,7 +17,7 @@ export interface UntypedObject extends UntypedNode { /** * Type guard to assert that an object instance is an UntypedObject. * @param node The object to check. - * @return boolean indicating if the node is an UntypedObject. + * @returns boolean indicating if the node is an UntypedObject. */ export const isUntypedObject = (node: UntypedNode): node is UntypedObject => { const proposedNode = node as UntypedObject; @@ -27,7 +27,7 @@ export const isUntypedObject = (node: UntypedNode): node is UntypedObject => { /** * Factory to create an UntypedObject from a Record. * @param value The Record value to create from. - * @return The created UntypedObject. + * @returns The created UntypedObject. */ export const createUntypedObject = (value: Record): UntypedObject => { return { diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts index b6346f876..67e799885 100644 --- a/packages/abstractions/src/serialization/untypedString.ts +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -17,7 +17,7 @@ export interface UntypedString extends UntypedNode { /** * Type guard to assert that an object instance is an UntypedString. * @param node The object to check. - * @return boolean indicating if the node is an UntypedString. + * @returns boolean indicating if the node is an UntypedString. */ export function isUntypedString(node: UntypedNode): node is UntypedString { const proposedNode = node as UntypedString; @@ -27,7 +27,7 @@ export function isUntypedString(node: UntypedNode): node is UntypedString { /** * Factory to create an UntypedString from a string. * @param value The string value to create from. - * @return The created UntypedString. + * @returns The created UntypedString. */ export function createUntypedString(value: string): UntypedString { return { diff --git a/packages/abstractions/src/store/backingStore.ts b/packages/abstractions/src/store/backingStore.ts index 67b065454..ce8635976 100644 --- a/packages/abstractions/src/store/backingStore.ts +++ b/packages/abstractions/src/store/backingStore.ts @@ -11,7 +11,7 @@ export interface BackingStore { /** * Gets a value from the backing store based on its key. Returns null if the value hasn't changed and "ReturnOnlyChangedValues" is true. - * @return The value from the backing store. + * @returns The value from the backing store. * @param key The key to lookup the backing store with. */ get(key: string): T | undefined; @@ -24,19 +24,19 @@ export interface BackingStore { set(key: string, value: T): void; /** * Enumerates all the values stored in the backing store. Values will be filtered if "ReturnOnlyChangedValues" is true. - * @return The values available in the backing store. + * @returns The values available in the backing store. */ enumerate(): { key: string; value: unknown }[]; /** * Enumerates the keys for all values that changed to null. - * @return The keys for the values that changed to null. + * @returns The keys for the values that changed to null. */ enumerateKeysForValuesChangedToNull(): string[]; /** * Creates a subscription to any data change happening. * @param callback Callback to be invoked on data changes where the first parameter is the data key, the second the previous value and the third the new value. * @param subscriptionId The subscription Id to use. - * @return The subscription Id to use when removing the subscription + * @returns The subscription Id to use when removing the subscription */ subscribe(callback: () => { key: string; previousValue: unknown; newValue: unknown }, subscriptionId?: string): string; /** diff --git a/packages/abstractions/src/store/backingStoreFactory.ts b/packages/abstractions/src/store/backingStoreFactory.ts index 61b44502c..d74b4c3f1 100644 --- a/packages/abstractions/src/store/backingStoreFactory.ts +++ b/packages/abstractions/src/store/backingStoreFactory.ts @@ -10,7 +10,7 @@ import type { BackingStore } from "./backingStore"; export interface BackingStoreFactory { /** * Creates a new instance of the backing store. - * @return a new instance of the backing store. + * @returns a new instance of the backing store. */ createBackingStore(): BackingStore; } diff --git a/packages/abstractions/src/store/backingStoreUtils.ts b/packages/abstractions/src/store/backingStoreUtils.ts index 1608c7750..4034280c8 100644 --- a/packages/abstractions/src/store/backingStoreUtils.ts +++ b/packages/abstractions/src/store/backingStoreUtils.ts @@ -10,8 +10,8 @@ export const BackingStoreKey = "backingStoreEnabled"; /** * Check if the object is an instance a BackedModel - * @param obj - * @returns + * @param fields The fields of the object + * @returns boolean indicating if the object is a BackedModel */ export function isBackingStoreEnabled(fields: Record void>): boolean { // Check if the fields contain the backing store key diff --git a/packages/abstractions/src/store/inMemoryBackingStore.ts b/packages/abstractions/src/store/inMemoryBackingStore.ts index f5444c8de..8d7f684b5 100644 --- a/packages/abstractions/src/store/inMemoryBackingStore.ts +++ b/packages/abstractions/src/store/inMemoryBackingStore.ts @@ -46,7 +46,6 @@ export class InMemoryBackingStore implements BackingStore { public enumerate(): storeEntry[] { let filterableArray = [...this.store.entries()]; if (this.returnOnlyChangedValues) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars filterableArray = filterableArray.filter(([_, v]) => v.changed); } return filterableArray.map(([key, value]) => { diff --git a/packages/abstractions/src/timeOnly.ts b/packages/abstractions/src/timeOnly.ts index b25a357e6..91497d47c 100644 --- a/packages/abstractions/src/timeOnly.ts +++ b/packages/abstractions/src/timeOnly.ts @@ -11,6 +11,11 @@ import { formatSegment } from "./dateOnly"; export class TimeOnly implements TimeOnlyInterface { /** * Creates a new TimeOnly from the given parameters. + * @param root0 The hours, minutes, seconds, and milliseconds + * @param root0.hours The hours + * @param root0.minutes The minutes + * @param root0.seconds The seconds + * @param root0.picoseconds The milliseconds * @returns The new TimeOnly * @throws An error if the milliseconds are invalid * @throws An error if the seconds are invalid @@ -103,29 +108,21 @@ interface TimeOnlyInterface { /** * The hours * @default 0 - * @minimum 0 - * @maximum 23 */ hours: number; /** * The minutes * @default 0 - * @minimum 0 - * @maximum 59 */ minutes: number; /** * The seconds * @default 0 - * @minimum 0 - * @maximum 59 */ seconds: number; /** * The milliseconds * @default 0 - * @minimum 0 - * @maximum 9999999 */ picoseconds: number; } diff --git a/packages/abstractions/src/utils/enumUtils.ts b/packages/abstractions/src/utils/enumUtils.ts index d8492227e..772c17a58 100644 --- a/packages/abstractions/src/utils/enumUtils.ts +++ b/packages/abstractions/src/utils/enumUtils.ts @@ -4,6 +4,7 @@ * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ + const reverseRecord = (input: Record): Record => { const entries = Object.entries(input).map(([key, value]) => [value, key]); return Object.fromEntries(entries) as Record; @@ -13,8 +14,7 @@ const reverseRecord = (input: Record): Record(stringValue: string, originalType: Record): T | undefined => { const reversed: Record = reverseRecord(originalType); diff --git a/packages/abstractions/src/utils/guidUtils.ts b/packages/abstractions/src/utils/guidUtils.ts index 92709b023..73088ec20 100644 --- a/packages/abstractions/src/utils/guidUtils.ts +++ b/packages/abstractions/src/utils/guidUtils.ts @@ -6,6 +6,11 @@ */ import { Guid } from "guid-typescript"; +/** + * Parses a string into a Guid object. + * @param source The source string. + * @returns The Guid object. + */ export function parseGuidString(source?: string): Guid | undefined { if (source && Guid.isGuid(source)) { return Guid.parse(source); diff --git a/packages/abstractions/vite.config.mts b/packages/abstractions/vite.config.mts index 4a6f89f2f..a33394f07 100644 --- a/packages/abstractions/vite.config.mts +++ b/packages/abstractions/vite.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/test{Entity,Enum}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html","cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/authentication/azure/README.md b/packages/authentication/azure/README.md index 1fe69db01..45e626de8 100644 --- a/packages/authentication/azure/README.md +++ b/packages/authentication/azure/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota Authentication Azure Library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-authentication-azure?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-authentication-azure) The Kiota Authentication Azure Library is an implementation to authenticate HTTP requests using @azure/identity. @@ -9,3 +11,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the Kiota Authentication Azure 1. `npm i @microsoft/kiota-authentication-azure -S`. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/authentication/azure/package.json b/packages/authentication/azure/package.json index fd6b2d472..361bc5a7e 100644 --- a/packages/authentication/azure/package.json +++ b/packages/authentication/azure/package.json @@ -12,6 +12,7 @@ "test:node": "vitest run", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test": "npm run test:node && npm run test:browser", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", "clean": "rimraf ./dist" @@ -38,5 +39,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/authentication/azure/src/azureIdentityAccessTokenProvider.ts b/packages/authentication/azure/src/azureIdentityAccessTokenProvider.ts index 9bf08e7d7..9643c4ee3 100644 --- a/packages/authentication/azure/src/azureIdentityAccessTokenProvider.ts +++ b/packages/authentication/azure/src/azureIdentityAccessTokenProvider.ts @@ -14,7 +14,6 @@ import { type ObservabilityOptions, ObservabilityOptionsImpl } from "./observabi /** Access token provider that leverages the Azure Identity library to retrieve an access token. */ export class AzureIdentityAccessTokenProvider implements AccessTokenProvider { /** - *@constructor *@param credentials The tokenCredential implementation to use for authentication. *@param scopes The scopes to use for authentication. *@param options The options to use for authentication. @@ -55,7 +54,7 @@ export class AzureIdentityAccessTokenProvider implements AccessTokenProvider { } }); }; - private getAuthorizationTokenInternal = async (url?: string, additionalAuthenticationContext?: Record, span?: Span): Promise => { + private readonly getAuthorizationTokenInternal = async (url?: string, additionalAuthenticationContext?: Record, span?: Span): Promise => { if (!url || !this.allowedHostsValidator.isUrlHostValid(url)) { span?.setAttribute("com.microsoft.kiota.authentication.is_url_valid", false); return ""; @@ -63,7 +62,7 @@ export class AzureIdentityAccessTokenProvider implements AccessTokenProvider { validateProtocol(url); span?.setAttribute("com.microsoft.kiota.authentication.is_url_valid", true); let decodedClaims = ""; - if (additionalAuthenticationContext && additionalAuthenticationContext[AzureIdentityAccessTokenProvider.claimsKey]) { + if (additionalAuthenticationContext?.[AzureIdentityAccessTokenProvider.claimsKey]) { const rawClaims = additionalAuthenticationContext[AzureIdentityAccessTokenProvider.claimsKey] as string; decodedClaims = inNodeEnv() ? Buffer.from(rawClaims, "base64").toString() : atob(rawClaims); } @@ -81,7 +80,7 @@ export class AzureIdentityAccessTokenProvider implements AccessTokenProvider { const result = await this.credentials.getToken(this.scopes, localOptions); return result?.token ?? ""; }; - private getSchemeAndHostFromUrl = (url: string): string[] => { + private readonly getSchemeAndHostFromUrl = (url: string): string[] => { const urlParts = url.split("://"); if (urlParts.length === 0) { // relative url @@ -96,13 +95,13 @@ export class AzureIdentityAccessTokenProvider implements AccessTokenProvider { throw new Error("invalid url"); } }; - private getSchemeFromLocation = (): string => { + private readonly getSchemeFromLocation = (): string => { if (!inNodeEnv()) { return window.location.protocol.replace(":", ""); } return ""; }; - private getHostFromLocation = (): string => { + private readonly getHostFromLocation = (): string => { if (!inNodeEnv()) { return window.location.host; } diff --git a/packages/authentication/azure/src/azureIdentityAuthenticationProvider.ts b/packages/authentication/azure/src/azureIdentityAuthenticationProvider.ts index a4db39f34..4c329b8b2 100644 --- a/packages/authentication/azure/src/azureIdentityAuthenticationProvider.ts +++ b/packages/authentication/azure/src/azureIdentityAuthenticationProvider.ts @@ -13,7 +13,6 @@ import { type ObservabilityOptions, ObservabilityOptionsImpl } from "./observabi export class AzureIdentityAuthenticationProvider extends BaseBearerTokenAuthenticationProvider { /** - *@constructor *@param credentials The tokenCredential implementation to use for authentication. *@param scopes The scopes to use for authentication. *@param options The options to use for authentication. diff --git a/packages/authentication/azure/vitest.config.mts b/packages/authentication/azure/vitest.config.mts index 4a6f89f2f..c72aaa3fc 100644 --- a/packages/authentication/azure/vitest.config.mts +++ b/packages/authentication/azure/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/test{Entity,Enum}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/authentication/spfx/README.md b/packages/authentication/spfx/README.md index d9c04d181..c7d932565 100644 --- a/packages/authentication/spfx/README.md +++ b/packages/authentication/spfx/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota Authentication SharePoint Library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-authentication-spfx?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-authentication-spfx) The Kiota Authentication SharePoint Framework Library is an implementation to authenticate HTTP requests in SharePoint Framework solutions. This Authentication library, re uses some infrastructure from the SPFx context to obtain a valid token for the required API. @@ -59,3 +61,25 @@ If you have generated a Kiota client for Microsoft Graph, you can also use this }) .catch(e => {console.log(e)}); ``` + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/authentication/spfx/package.json b/packages/authentication/spfx/package.json index 5d8f98e74..69ff852a1 100644 --- a/packages/authentication/spfx/package.json +++ b/packages/authentication/spfx/package.json @@ -12,6 +12,7 @@ "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", "test": "npm run test:node && npm run test:browser", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", "clean": "rimraf ./dist" @@ -48,5 +49,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/authentication/spfx/src/azureAdSpfxAccessTokenProvider.ts b/packages/authentication/spfx/src/azureAdSpfxAccessTokenProvider.ts index 5fe07bddf..a5e8f821e 100644 --- a/packages/authentication/spfx/src/azureAdSpfxAccessTokenProvider.ts +++ b/packages/authentication/spfx/src/azureAdSpfxAccessTokenProvider.ts @@ -15,11 +15,11 @@ export class AzureAdSpfxAccessTokenProvider implements AccessTokenProvider { private readonly allowedHostsValidator: AllowedHostsValidator; /** - *@constructor *@param tokenProvider The tokenProvider provided by the SharePoint framework *@param applicationIdUri The application ID URI of the Azure AD App that we want to Authenticate *@param allowedHosts The allowed hosts to use for authentication. *@param useCachedToken Allows the developer to specify if cached tokens should be returned. + *@param observabilityOptions The observability options to use for authentication. */ public constructor( private readonly tokenProvider: AadTokenProvider, @@ -52,9 +52,9 @@ export class AzureAdSpfxAccessTokenProvider implements AccessTokenProvider { } }); }; - private getAuthorizationTokenInternal = async ( + private readonly getAuthorizationTokenInternal = async ( url?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + additionalAuthenticationContext?: Record, span?: Span, ): Promise => { diff --git a/packages/authentication/spfx/src/azureAdSpfxAuthenticationProvider.ts b/packages/authentication/spfx/src/azureAdSpfxAuthenticationProvider.ts index fa1b7cf40..bb4e9515e 100644 --- a/packages/authentication/spfx/src/azureAdSpfxAuthenticationProvider.ts +++ b/packages/authentication/spfx/src/azureAdSpfxAuthenticationProvider.ts @@ -13,11 +13,11 @@ import { type ObservabilityOptions, ObservabilityOptionsImpl } from "./observabi export class AzureAdSpfxAuthenticationProvider extends BaseBearerTokenAuthenticationProvider { /** - *@constructor *@param tokenProvider The tokenProvider provided by the SharePoint framework *@param applicationIdUri The application ID URI of the Azure AD App that we want to Authenticate *@param allowedHosts The allowed hosts to use for authentication. *@param useCachedToken Allows the developer to specify if cached tokens should be returned. + *@param observabilityOptions The observability options to use. */ public constructor(tokenProvider: AadTokenProvider, applicationIdUri: string, allowedHosts: Set = new Set(["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn", "canary.graph.microsoft.com"]), useCachedToken?: boolean, observabilityOptions: ObservabilityOptions = new ObservabilityOptionsImpl()) { super(new AzureAdSpfxAccessTokenProvider(tokenProvider, applicationIdUri, allowedHosts, useCachedToken, observabilityOptions)); diff --git a/packages/authentication/spfx/vitest.config.mts b/packages/authentication/spfx/vitest.config.mts index fea50b1b5..c14f3d47f 100644 --- a/packages/authentication/spfx/vitest.config.mts +++ b/packages/authentication/spfx/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/mockAadTokenProvider.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/bundle/README.md b/packages/bundle/README.md index 58c4aa5b3..9d27d6193 100644 --- a/packages/bundle/README.md +++ b/packages/bundle/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota Bundle library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-bundle?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-bundle) The Kiota Bundle Library provides default implementations for client setup. @@ -8,3 +10,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the bundle `npm i @microsoft/kiota-bundle` + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/bundle/package.json b/packages/bundle/package.json index b146b39e5..e81771393 100644 --- a/packages/bundle/package.json +++ b/packages/bundle/package.json @@ -14,6 +14,7 @@ "clean": "rimraf ./dist", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "repository": "git://github.com/microsoft/kiota-typescript.git", @@ -39,5 +40,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/bundle/src/index.ts b/packages/bundle/src/index.ts index bfd236bcd..f180f9f99 100644 --- a/packages/bundle/src/index.ts +++ b/packages/bundle/src/index.ts @@ -5,6 +5,4 @@ * ------------------------------------------------------------------------------------------- */ -/* eslint-disable @typescript-eslint/triple-slash-reference*/ - export * from "./defaultRequestAdapter"; diff --git a/packages/bundle/vite.config.mts b/packages/bundle/vite.config.mts index 4a6f89f2f..c72aaa3fc 100644 --- a/packages/bundle/vite.config.mts +++ b/packages/bundle/vite.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/test{Entity,Enum}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/http/fetch/README.md b/packages/http/fetch/README.md index 2bea3ab69..12db04da1 100644 --- a/packages/http/fetch/README.md +++ b/packages/http/fetch/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota HTTP - Fetch library + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-http-fetchlibrary?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-http-fetchlibrary) The Kiota Http Fetch Library is an implementation using the Fetch API to make requests. @@ -9,3 +11,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the Kiota Fetch library implementations 1. `npm i @microsoft/kiota-http-fetchlibrary`. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/http/fetch/package.json b/packages/http/fetch/package.json index 94016d46e..8728f683d 100644 --- a/packages/http/fetch/package.json +++ b/packages/http/fetch/package.json @@ -30,6 +30,7 @@ "lint:fix": "eslint . --ext .ts --fix", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "dependencies": { @@ -40,5 +41,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/http/fetch/src/fetchRequestAdapter.ts b/packages/http/fetch/src/fetchRequestAdapter.ts index 53f89d226..6209ad587 100644 --- a/packages/http/fetch/src/fetchRequestAdapter.ts +++ b/packages/http/fetch/src/fetchRequestAdapter.ts @@ -54,14 +54,14 @@ export class FetchRequestAdapter implements RequestAdapter { this.observabilityOptions = new ObservabilityOptionsImpl(observabilityOptions); } } - private getResponseContentType = (response: Response): string | undefined => { + private readonly getResponseContentType = (response: Response): string | undefined => { const header = response.headers.get("content-type")?.toLowerCase(); if (!header) return undefined; const segments = header.split(";"); if (segments.length === 0) return undefined; else return segments[0]; }; - private getResponseHandler = (response: RequestInformation): ResponseHandler | undefined => { + private readonly getResponseHandler = (response: RequestInformation): ResponseHandler | undefined => { const options = response.getRequestOptions(); const responseHandlerOption = options[ResponseHandlerOptionKey] as ResponseHandlerOption; return responseHandlerOption?.responseHandler; @@ -157,7 +157,7 @@ export class FetchRequestAdapter implements RequestAdapter { } }); }; - private startTracingSpan = (requestInfo: RequestInformation, methodName: string, callback: (arg0: Span) => Promise): Promise => { + private readonly startTracingSpan = (requestInfo: RequestInformation, methodName: string, callback: (arg0: Span) => Promise): Promise => { const urlTemplate = decodeURIComponent(requestInfo.urlTemplate ?? ""); const telemetryPathValue = urlTemplate.replace(/\{\?[^}]+\}/gi, ""); return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan(`${methodName} - ${telemetryPathValue}`, async (span) => { @@ -221,7 +221,6 @@ export class FetchRequestAdapter implements RequestAdapter { if (this.shouldReturnUndefined(response)) return undefined; switch (responseType) { case "ArrayBuffer": - // eslint-disable-next-line no-case-declarations if (!response.body) { return undefined; } @@ -264,7 +263,7 @@ export class FetchRequestAdapter implements RequestAdapter { } finally { span.end(); } - }) as Promise; + }); }; public sendNoResponseContent = (requestInfo: RequestInformation, errorMappings: ErrorMappings | undefined): Promise => { if (!requestInfo) { @@ -308,7 +307,7 @@ export class FetchRequestAdapter implements RequestAdapter { try { span.setAttribute(FetchRequestAdapter.responseTypeAttributeKey, "enum"); const result = rootNode.getEnumValue(enumObject); - return result as unknown as EnumObject[keyof EnumObject]; + return result as EnumObject[keyof EnumObject]; } finally { deserializeSpan.end(); } @@ -356,7 +355,7 @@ export class FetchRequestAdapter implements RequestAdapter { } }); }; - public enableBackingStore = (backingStoreFactory?: BackingStoreFactory | undefined): void => { + public enableBackingStore = (backingStoreFactory?: BackingStoreFactory): void => { this.parseNodeFactory = enableBackingStoreForParseNodeFactory(this.parseNodeFactory); this.serializationWriterFactory = enableBackingStoreForSerializationWriterFactory(this.serializationWriterFactory); if (!this.serializationWriterFactory || !this.parseNodeFactory) throw new Error("unable to enable backing store"); @@ -364,7 +363,7 @@ export class FetchRequestAdapter implements RequestAdapter { BackingStoreFactorySingleton.instance = backingStoreFactory; } }; - private getRootParseNode = (response: Response): Promise => { + private readonly getRootParseNode = (response: Response): Promise => { return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("getRootParseNode", async (span) => { try { const payload = await response.arrayBuffer(); @@ -377,18 +376,21 @@ export class FetchRequestAdapter implements RequestAdapter { } }); }; - private shouldReturnUndefined = (response: Response): boolean => { + private readonly shouldReturnUndefined = (response: Response): boolean => { return response.status === 204 || !response.body; }; - /** purges the response body if it hasn't been read to release the connection to the server */ - private purgeResponseBody = async (response: Response): Promise => { + /** + * purges the response body if it hasn't been read to release the connection to the server + * @param response the response to purge + */ + private readonly purgeResponseBody = async (response: Response): Promise => { if (!response.bodyUsed && response.body) { await response.arrayBuffer(); } }; public static readonly errorMappingFoundAttributeName = "com.microsoft.kiota.error.mapping_found"; public static readonly errorBodyFoundAttributeName = "com.microsoft.kiota.error.body_found"; - private throwIfFailedResponse = (response: Response, errorMappings: ErrorMappings | undefined, spanForAttributes: Span): Promise => { + private readonly throwIfFailedResponse = (response: Response, errorMappings: ErrorMappings | undefined, spanForAttributes: Span): Promise => { return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("throwIfFailedResponse", async (span) => { try { if (response.ok) return; @@ -415,17 +417,17 @@ export class FetchRequestAdapter implements RequestAdapter { spanForAttributes.setAttribute(FetchRequestAdapter.errorMappingFoundAttributeName, true); const rootNode = await this.getRootParseNode(response); - let error = trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("getObjectValue", (deserializeSpan) => { + let deserializedError = trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("getObjectValue", (deserializeSpan) => { try { return rootNode.getObjectValue(factory); } finally { deserializeSpan.end(); } }); - spanForAttributes.setAttribute(FetchRequestAdapter.errorBodyFoundAttributeName, !!error); + spanForAttributes.setAttribute(FetchRequestAdapter.errorBodyFoundAttributeName, !!deserializedError); - if (!error) error = new DefaultApiError("unexpected error type" + typeof error) as unknown as Parsable; - const errorObject = error as ApiError; + if (!deserializedError) deserializedError = new DefaultApiError("unexpected error type" + typeof deserializedError) as unknown as Parsable; + const errorObject = deserializedError as ApiError; errorObject.responseStatusCode = statusCode; errorObject.responseHeaders = responseHeaders; spanForAttributes.recordException(errorObject); @@ -435,7 +437,7 @@ export class FetchRequestAdapter implements RequestAdapter { } }); }; - private getHttpResponseMessage = (requestInfo: RequestInformation, spanForAttributes: Span, claims?: string): Promise => { + private readonly getHttpResponseMessage = (requestInfo: RequestInformation, spanForAttributes: Span, claims?: string): Promise => { return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("getHttpResponseMessage", async (span) => { try { if (!requestInfo) { @@ -444,7 +446,7 @@ export class FetchRequestAdapter implements RequestAdapter { this.setBaseUrlForRequestInformation(requestInfo); const additionalContext = {} as Record; if (claims) { - additionalContext["claims"] = claims; + additionalContext.claims = claims; } await this.authenticationProvider.authenticateRequest(requestInfo, additionalContext); const request = await this.getRequestFromRequestInformation(requestInfo, spanForAttributes); @@ -473,7 +475,7 @@ export class FetchRequestAdapter implements RequestAdapter { }); }; public static readonly authenticateChallengedEventKey = "com.microsoft.kiota.authenticate_challenge_received"; - private retryCAEResponseIfRequired = async (requestInfo: RequestInformation, response: Response, spanForAttributes: Span, claims?: string) => { + private readonly retryCAEResponseIfRequired = async (requestInfo: RequestInformation, response: Response, spanForAttributes: Span, claims?: string) => { return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("retryCAEResponseIfRequired", async (span) => { try { const responseClaims = this.getClaimsFromResponse(response, claims); @@ -489,7 +491,7 @@ export class FetchRequestAdapter implements RequestAdapter { } }); }; - private getClaimsFromResponse = (response: Response, claims?: string) => { + private readonly getClaimsFromResponse = (response: Response, claims?: string) => { if (response.status === 401 && !claims) { // avoid infinite loop, we only retry once // no need to check for the content since it's an array and it doesn't need to be rewound @@ -506,16 +508,17 @@ export class FetchRequestAdapter implements RequestAdapter { } return undefined; }; - private setBaseUrlForRequestInformation = (requestInfo: RequestInformation): void => { - requestInfo.pathParameters["baseurl"] = this.baseUrl; + private readonly setBaseUrlForRequestInformation = (requestInfo: RequestInformation): void => { + requestInfo.pathParameters.baseurl = this.baseUrl; }; - private getRequestFromRequestInformation = (requestInfo: RequestInformation, spanForAttributes: Span): Promise => { + private readonly getRequestFromRequestInformation = (requestInfo: RequestInformation, spanForAttributes: Span): Promise => { + // eslint-disable-next-line @typescript-eslint/require-await return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("getRequestFromRequestInformation", async (span) => { try { const method = requestInfo.httpMethod?.toString(); const uri = requestInfo.URL; spanForAttributes.setAttribute("http.request.method", method ?? ""); - const uriContainsScheme = uri.indexOf("://") > -1; + const uriContainsScheme = uri.includes("://"); const schemeSplatUri = uri.split("://"); if (uriContainsScheme) { spanForAttributes.setAttribute("server.address", schemeSplatUri[0]); @@ -548,7 +551,7 @@ export class FetchRequestAdapter implements RequestAdapter { } }); }; - private foldHeaderValue = (value: string[] | null): string => { + private readonly foldHeaderValue = (value: string[] | null): string => { if (!value || value.length < 1) { return ""; } else if (value.length === 1) { diff --git a/packages/http/fetch/src/httpClient.ts b/packages/http/fetch/src/httpClient.ts index abece54d6..1ae0fcfe1 100644 --- a/packages/http/fetch/src/httpClient.ts +++ b/packages/http/fetch/src/httpClient.ts @@ -14,18 +14,13 @@ import { MiddlewareFactory } from "./"; export class HttpClient { private middleware: Middleware | undefined; /** - * @public - * @constructor - * Creates an instance of a HttpClient which contains the middlewares and fetch implementation for request execution. - * @param {...Middleware} middleware - The first middleware of the middleware chain or a sequence of all the Middleware handlers - * If middlewares param is undefined, the httpClient instance will use the default array of middlewares. - * Set middlewares to `null` if you do not wish to use middlewares. - * If custom fetch is undefined, the httpClient instance uses the `DefaultFetchHandler` - * @param {(request: string, init?: RequestInit) => Promise < Response >} custom fetch function - a Fetch API implementation * + * Creates an instance of a HttpClient which contains the middlewares and fetch implementation for request execution. + * @param customFetch - custom fetch function - a Fetch API implementation + * @param middlewares - an array of Middleware handlers */ public constructor( - private customFetch?: (request: string, init: RequestInit) => Promise, + private readonly customFetch?: (request: string, init: RequestInit) => Promise, ...middlewares: Middleware[] ) { // If no middlewares are provided, use the default ones @@ -33,6 +28,7 @@ export class HttpClient { // If a custom fetch function is provided, add a CustomFetchHandler to the end of the middleware chain if (this.customFetch) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument middlewares.push(new CustomFetchHandler(customFetch as any)); } @@ -41,11 +37,9 @@ export class HttpClient { } /** - * @private * Processes the middleware parameter passed to set this.middleware property * The calling function should validate if middleware is not undefined or not empty. - * @param {...Middleware} middleware - The middleware passed - * @returns Nothing + * @param middleware - The middleware passed */ private setMiddleware(...middleware: Middleware[]): void { for (let i = 0; i < middleware.length - 1; i++) { @@ -57,7 +51,8 @@ export class HttpClient { /** * Executes a request and returns a promise resolving the response. * @param url the request url. - * @param options request options. + * @param requestInit the RequestInit object. + * @param requestOptions the request options. * @returns the promise resolving the response. */ public async executeFetch(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { diff --git a/packages/http/fetch/src/kiotaClientFactory.ts b/packages/http/fetch/src/kiotaClientFactory.ts index 2370cded4..a0761c183 100644 --- a/packages/http/fetch/src/kiotaClientFactory.ts +++ b/packages/http/fetch/src/kiotaClientFactory.ts @@ -9,17 +9,15 @@ import { Middleware, MiddlewareFactory } from "."; import { HttpClient } from "./httpClient"; /** - * @class + * * Class containing function(s) related to the middleware pipelines. */ export class KiotaClientFactory { /** - * @public - * @static * Returns an instance of HttpClient with the provided middlewares and custom fetch implementation both parameters are optional. * if not provided, the default fetch implementation and middlewares will be used. - * @param {(request: string, init?: RequestInit) => Promise < Response >} customFetch - a Fetch API implementation - * @param {Middleware[]} middlewares - an aray of Middleware handlers + * @param customFetch - a Fetch API implementation + * @param middlewares - an aray of Middleware handlers * If middlewares param is undefined, the httpClient instance will use the default array of middlewares. * Set middlewares to `null` if you do not wish to use middlewares. * If custom fetch is undefined, the httpClient instance uses the `DefaultFetchHandler` @@ -45,6 +43,7 @@ export class KiotaClientFactory { * KiotaClientFactory.create(); * ``` */ + // eslint-disable-next-line @typescript-eslint/no-unsafe-return public static create(customFetch: (request: string, init: RequestInit) => Promise = (...args) => fetch(...args) as any, middlewares?: Middleware[]): HttpClient { const middleware = middlewares || MiddlewareFactory.getDefaultMiddlewares(customFetch); return new HttpClient(customFetch, ...middleware); diff --git a/packages/http/fetch/src/middlewares/browser/middlewareFactory.ts b/packages/http/fetch/src/middlewares/browser/middlewareFactory.ts index b503d7d08..deb913054 100644 --- a/packages/http/fetch/src/middlewares/browser/middlewareFactory.ts +++ b/packages/http/fetch/src/middlewares/browser/middlewareFactory.ts @@ -14,16 +14,16 @@ import { UserAgentHandler } from "../userAgentHandler"; import { CompressionHandler } from "../compressionHandler"; /** - * @class + * * Class containing function(s) related to the middleware pipelines. */ export class MiddlewareFactory { /** - * @public - * @static + * @param customFetch - The custom fetch implementation * Returns the default middleware chain an array with the middleware handlers * @returns an array of the middleware handlers of the default middleware chain */ + // eslint-disable-next-line @typescript-eslint/no-unsafe-return public static getDefaultMiddlewares(customFetch: (request: string, init: RequestInit) => Promise = (...args) => fetch(...args) as any): Middleware[] { // Browsers handles redirection automatically and do not require the redirectionHandler return [new RetryHandler(), new ParametersNameDecodingHandler(), new UserAgentHandler(), new CompressionHandler(), new HeadersInspectionHandler(), new CustomFetchHandler(customFetch)]; diff --git a/packages/http/fetch/src/middlewares/chaosHandler.ts b/packages/http/fetch/src/middlewares/chaosHandler.ts index 72504eaf3..7688b7252 100644 --- a/packages/http/fetch/src/middlewares/chaosHandler.ts +++ b/packages/http/fetch/src/middlewares/chaosHandler.ts @@ -20,16 +20,14 @@ import type { ChaosHandlerOptions } from "./options/chaosHandlerOptions"; import { ChaosStrategy } from "./options/chaosStrategy"; /** - * @class + * * Class - * @implements Middleware + * Middleware * Class representing RedirectHandler */ export class ChaosHandler implements Middleware { /** * A member holding options to customize the handler behavior - * - * @private */ options: ChaosHandlerOptions = { chaosStrategy: ChaosStrategy.RANDOM, @@ -39,19 +37,16 @@ export class ChaosHandler implements Middleware { /** * container for the manual map that has been written by the client - * - * @private */ - private manualMap: Map>; + private readonly manualMap: Map>; /** @inheritdoc */ next: Middleware | undefined; /** - * @public - * @constructor + * * To create an instance of ChaosHandler - * @param {ChaosHandlerOptions} [options = new ChaosHandlerOptions()] - The chaos handler options instance + * @param [options] - The chaos handler options instance * @param manualMap - The Map passed by user containing url-statusCode info */ public constructor(options?: Partial, manualMap?: Map>) { @@ -62,25 +57,24 @@ export class ChaosHandler implements Middleware { } this.options = chaosOptions; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment this.manualMap = manualMap ?? new Map(); } /** * Fetches a random status code for the RANDOM mode from the predefined array - * @private - * @param {string} requestMethod - the API method for the request + * @param requestMethod - the API method for the request * @returns a random status code from a given set of status codes */ private generateRandomStatusCode(requestMethod: HttpMethod): number { - const statusCodeArray: number[] = methodStatusCode[requestMethod] as number[]; + const statusCodeArray: number[] = methodStatusCode[requestMethod]; return statusCodeArray[Math.floor(Math.random() * statusCodeArray.length)]; } /** * Strips out the host url and returns the relative url only - * @private - * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object - * @param {string} urlMethod - the complete URL + * @param chaosHandlerOptions - The ChaosHandlerOptions object + * @param urlMethod - the complete URL * @returns the string as relative URL */ private getRelativeURL(chaosHandlerOptions: ChaosHandlerOptions, urlMethod: string): string { @@ -94,10 +88,10 @@ export class ChaosHandler implements Middleware { /** * Gets a status code from the options or a randomly generated status code - * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object - * @param {string} requestURL - the URL for the request - * @param {HttpMethod} requestMethod - the API method for the request - * @returns {number} generated statusCode + * @param chaosHandlerOptions - The ChaosHandlerOptions object + * @param requestURL - the URL for the request + * @param requestMethod - the API method for the request + * @returns generated statusCode */ private getStatusCode(chaosHandlerOptions: ChaosHandlerOptions, requestURL: string, requestMethod: HttpMethod): number { if (chaosHandlerOptions.chaosStrategy === ChaosStrategy.MANUAL) { @@ -136,14 +130,13 @@ export class ChaosHandler implements Middleware { /** * Generates a respondy for the chaoe response - * @private - * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object - * @param {string} requestID - request id - * @param {string} requestDate - date of the request - * * @returns response body + * @param chaosHandlerOptions - The ChaosHandlerOptions object + * @param statusCode - the status code for the response + * @returns the response body */ private createResponseBody(chaosHandlerOptions: ChaosHandlerOptions, statusCode: number) { if (chaosHandlerOptions.responseBody) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return chaosHandlerOptions.responseBody; } let body: any; @@ -160,14 +153,15 @@ export class ChaosHandler implements Middleware { } else { body = {}; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return body; } /** * Composes a new chaotic response code with the configured parameters - * @param {string} url - * @param {FetchRequestInit} fetchRequestInit - * @returns {Response} + * @param url The url of the request + * @param fetchRequestInit The fetch request init object + * @returns a response object with the configured parameters */ private createChaosResponse(url: string, fetchRequestInit: FetchRequestInit): any { if (fetchRequestInit.method === undefined) { @@ -176,6 +170,7 @@ export class ChaosHandler implements Middleware { const requestMethod = fetchRequestInit.method as HttpMethod; const statusCode = this.getStatusCode(this.options, url, requestMethod); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const responseBody = this.createResponseBody(this.options, statusCode); const stringBody = typeof responseBody === "string" ? responseBody : JSON.stringify(responseBody); @@ -188,7 +183,7 @@ export class ChaosHandler implements Middleware { }; } - public execute(url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { const obsOptions = getObservabilityOptionsFromRequest(requestOptions); if (obsOptions) { return trace.getTracer(obsOptions.getTracerInstrumentationName()).startActiveSpan("chaosHandler - execute", (span) => { @@ -203,7 +198,7 @@ export class ChaosHandler implements Middleware { return this.runChaos(url, requestInit, requestOptions); } public static readonly chaosHandlerTriggeredEventKey = "com.microsoft.kiota.chaos_handler_triggered"; - private runChaos(url: string, requestInit: RequestInit, requestOptions?: Record | undefined, span?: Span): Promise { + private runChaos(url: string, requestInit: RequestInit, requestOptions?: Record, span?: Span): Promise { if (Math.floor(Math.random() * 100) < this.options.chaosPercentage) { span?.addEvent(ChaosHandler.chaosHandlerTriggeredEventKey); return Promise.resolve(this.createChaosResponse(url, requestInit as FetchRequestInit)); diff --git a/packages/http/fetch/src/middlewares/compressionHandler.ts b/packages/http/fetch/src/middlewares/compressionHandler.ts index 0411effbb..c62dea6f1 100644 --- a/packages/http/fetch/src/middlewares/compressionHandler.ts +++ b/packages/http/fetch/src/middlewares/compressionHandler.ts @@ -21,24 +21,18 @@ export class CompressionHandler implements Middleware { next: Middleware | undefined; /** - * @private - * @static * A member holding the name of content range header */ private static readonly CONTENT_RANGE_HEADER = "Content-Range"; /** - * @private - * @static * A member holding the name of content encoding header */ private static readonly CONTENT_ENCODING_HEADER = "Content-Encoding"; /** - * @public - * @constructor * Creates a new instance of the CompressionHandler class - * @param {CompressionHandlerOptions} handlerOptions The options for the compression handler. + * @param handlerOptions The options for the compression handler. * @returns An instance of the CompressionHandler class */ public constructor(private readonly handlerOptions: CompressionHandlerOptions = new CompressionHandlerOptions()) { @@ -50,7 +44,7 @@ export class CompressionHandler implements Middleware { /** * @inheritdoc */ - public execute(url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { let currentOptions = this.handlerOptions; if (requestOptions?.[CompressionHandlerOptionsKey]) { currentOptions = requestOptions[CompressionHandlerOptionsKey] as CompressionHandlerOptions; @@ -194,6 +188,7 @@ export class CompressionHandler implements Middleware { } private async compressUsingZlib(body: unknown): Promise { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const zlib = await import("zlib"); return await new Promise((resolve, reject) => { diff --git a/packages/http/fetch/src/middlewares/customFetchHandler.ts b/packages/http/fetch/src/middlewares/customFetchHandler.ts index 6a7bc8c0d..7cc51af53 100644 --- a/packages/http/fetch/src/middlewares/customFetchHandler.ts +++ b/packages/http/fetch/src/middlewares/customFetchHandler.ts @@ -12,14 +12,13 @@ import type { Middleware } from "./middleware"; /** - * @class - * @implements Middleware + * Middleware * Class for FetchHandler */ export class CustomFetchHandler implements Middleware { /** - * @private + * * The next middleware in the middleware chain */ next: Middleware | undefined; diff --git a/packages/http/fetch/src/middlewares/headersInspectionHandler.ts b/packages/http/fetch/src/middlewares/headersInspectionHandler.ts index bb5986b68..f154b95fa 100644 --- a/packages/http/fetch/src/middlewares/headersInspectionHandler.ts +++ b/packages/http/fetch/src/middlewares/headersInspectionHandler.ts @@ -13,24 +13,22 @@ import type { Middleware } from "./middleware"; import { HeadersInspectionOptions, HeadersInspectionOptionsKey } from "./options/headersInspectionOptions"; /** - * @class - * @implements Middleware + * Middleware * Inspects the headers of the request and response */ export class HeadersInspectionHandler implements Middleware { /** - * @constructor - * @public + * * Creates new instance of HeadersInspectionHandler - * @param {HeadersInspectionOptions} _options The options for inspecting the headers + * @param _options The options for inspecting the headers */ public constructor(private readonly _options: HeadersInspectionOptions = new HeadersInspectionOptions()) {} /** - * @private + * * The next middleware in the middleware chain */ next: Middleware | undefined; - public execute(url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { let currentOptions = this._options; if (requestOptions?.[HeadersInspectionOptionsKey]) { currentOptions = requestOptions[HeadersInspectionOptionsKey] as HeadersInspectionOptions; diff --git a/packages/http/fetch/src/middlewares/middleware.ts b/packages/http/fetch/src/middlewares/middleware.ts index 349bf7623..7c3aff1a5 100644 --- a/packages/http/fetch/src/middlewares/middleware.ts +++ b/packages/http/fetch/src/middlewares/middleware.ts @@ -12,12 +12,11 @@ export interface Middleware { next: Middleware | undefined; /** - * @public - * @async * Main method of the middleware. + * @param url The url for the request * @param requestInit The Fetch RequestInit object. - * @param url The URL of the request. - * @return A promise that resolves to the response object. + * @param requestOptions The request options. + * @returns A promise that resolves to the response object. */ execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise; } diff --git a/packages/http/fetch/src/middlewares/middlewareFactory.ts b/packages/http/fetch/src/middlewares/middlewareFactory.ts index 96ef7edb3..5fed8588c 100644 --- a/packages/http/fetch/src/middlewares/middlewareFactory.ts +++ b/packages/http/fetch/src/middlewares/middlewareFactory.ts @@ -15,16 +15,16 @@ import { UserAgentHandler } from "./userAgentHandler"; import { CompressionHandler } from "./compressionHandler"; /** - * @class + * * Class containing function(s) related to the middleware pipelines. */ export class MiddlewareFactory { /** - * @public - * @static + * @param customFetch - The custom fetch implementation * Returns the default middleware chain an array with the middleware handlers * @returns an array of the middleware handlers of the default middleware chain */ + // eslint-disable-next-line @typescript-eslint/no-unsafe-return public static getDefaultMiddlewares(customFetch: (request: string, init: RequestInit) => Promise = (...args) => fetch(...args) as any): Middleware[] { return [new RetryHandler(), new RedirectHandler(), new ParametersNameDecodingHandler(), new UserAgentHandler(), new CompressionHandler(), new HeadersInspectionHandler(), new CustomFetchHandler(customFetch)]; } diff --git a/packages/http/fetch/src/middlewares/options/ChaosHandlerData.ts b/packages/http/fetch/src/middlewares/options/ChaosHandlerData.ts index e013ad08c..689bf1ed7 100644 --- a/packages/http/fetch/src/middlewares/options/ChaosHandlerData.ts +++ b/packages/http/fetch/src/middlewares/options/ChaosHandlerData.ts @@ -8,7 +8,7 @@ /** * Contains RequestMethod to corresponding array of possible status codes, used for Random mode */ -export const methodStatusCode: { [key: string]: number[] } = { +export const methodStatusCode: Record = { GET: [429, 500, 502, 503, 504], POST: [429, 500, 502, 503, 504, 507], PUT: [429, 500, 502, 503, 504, 507], @@ -19,7 +19,7 @@ export const methodStatusCode: { [key: string]: number[] } = { /** * Contains statusCode to statusMessage map */ -export const httpStatusCode: { [key: number]: string } = { +export const httpStatusCode: Record = { 100: "Continue", 101: "Switching Protocols", 102: "Processing", diff --git a/packages/http/fetch/src/middlewares/options/chaosHandlerOptions.ts b/packages/http/fetch/src/middlewares/options/chaosHandlerOptions.ts index 4d348c786..e797b1f93 100644 --- a/packages/http/fetch/src/middlewares/options/chaosHandlerOptions.ts +++ b/packages/http/fetch/src/middlewares/options/chaosHandlerOptions.ts @@ -16,35 +16,24 @@ export const ChaosHandlerOptionsKey = "ChaosHandlerOptionsKey"; /** * interface representing ChaosHandlerOptions - * @interface - * interface - * @implements MiddlewareOptions */ export interface ChaosHandlerOptions { /** * Speficies the base url path for the destination server, used when relative paths are preffered to strip out paths - * - * @public */ baseUrl?: string; /** * Specifies the startegy used for the Testing Handler -> RANDOM/MANUAL - * - * @public */ chaosStrategy: ChaosStrategy; /** * Status code to be returned in the response - * - * @public */ statusCode?: number; /** * The Message to be returned in the response - * - * @public */ statusMessage: string; @@ -52,21 +41,16 @@ export interface ChaosHandlerOptions { * The percentage of randomness/chaos in the handler * * Setting the default value as 10% - * @public */ chaosPercentage: number; /** * The response body to be returned in the response - * - * @public */ responseBody?: any; /** * The response headers to be returned in the response - * - * @public */ headers?: FetchHeaders; } diff --git a/packages/http/fetch/src/middlewares/options/chaosStrategy.ts b/packages/http/fetch/src/middlewares/options/chaosStrategy.ts index 5450f86df..aeeac436c 100644 --- a/packages/http/fetch/src/middlewares/options/chaosStrategy.ts +++ b/packages/http/fetch/src/middlewares/options/chaosStrategy.ts @@ -11,7 +11,6 @@ /** * Strategy used for Testing Handler - * @enum */ export enum ChaosStrategy { MANUAL, diff --git a/packages/http/fetch/src/middlewares/options/headersInspectionOptions.ts b/packages/http/fetch/src/middlewares/options/headersInspectionOptions.ts index d913dc459..bf8284f4b 100644 --- a/packages/http/fetch/src/middlewares/options/headersInspectionOptions.ts +++ b/packages/http/fetch/src/middlewares/options/headersInspectionOptions.ts @@ -10,27 +10,21 @@ import { type RequestOption, Headers } from "@microsoft/kiota-abstractions"; export const HeadersInspectionOptionsKey = "HeadersInspectionOptionsKey"; /** - * @interface * Signature to define the HeadersInspectionOptions constructor parameters - * @property {boolean} [inspectRequestHeaders = false] - Whether to inspect request headers - * @property {boolean} [inspectResponseHeaders = false] - Whether to inspect response headers */ export interface HeadersInspectionOptionsParams { /** - * @member * whether to inspect request headers */ inspectRequestHeaders?: boolean; /** - * @member * whether to inspect response headers */ inspectResponseHeaders?: boolean; } /** - * @class - * @implements RequestOption + * RequestOption * Options * Options to inspect headers */ @@ -38,8 +32,6 @@ export class HeadersInspectionOptions implements RequestOption { private readonly requestHeaders: Headers = new Headers(); private readonly responseHeaders = new Headers(); /** - * @public - * @getter * Gets the request headers * @returns the request headers */ @@ -48,8 +40,6 @@ export class HeadersInspectionOptions implements RequestOption { } /** - * @public - * @getter * Gets the response headers * @returns the response headers */ @@ -58,26 +48,21 @@ export class HeadersInspectionOptions implements RequestOption { } /** - * @public - * @member * @default false * whether to inspect request headers */ public inspectRequestHeaders: boolean; /** - * @public - * @member * @default false * whether to inspect response headers */ public inspectResponseHeaders: boolean; /** - * @public - * @constructor + * * To create an instance of HeadersInspectionOptions - * @param {HeadersInspectionOptionsParams} [options = {}] - The headers inspection options value + * @param [options] - The headers inspection options value * @returns An instance of HeadersInspectionOptions * @example const options = new HeadersInspectionOptions({ inspectRequestHeaders: true, inspectResponseHeaders: true }); */ diff --git a/packages/http/fetch/src/middlewares/options/parametersNameDecodingOptions.ts b/packages/http/fetch/src/middlewares/options/parametersNameDecodingOptions.ts index c41fd8366..41cdf1574 100644 --- a/packages/http/fetch/src/middlewares/options/parametersNameDecodingOptions.ts +++ b/packages/http/fetch/src/middlewares/options/parametersNameDecodingOptions.ts @@ -14,18 +14,15 @@ import type { RequestOption } from "@microsoft/kiota-abstractions"; export const ParametersNameDecodingHandlerOptionsKey = "RetryHandlerOptionKey"; /** - * @interface * Signature to define the ParametersNameDecodingHandlerOptions constructor parameters */ export interface ParametersNameDecodingHandlerOptionsParams { /** - * @member * Whether to decode the specified characters in the request query parameters names - * * @default true + * @default true */ enable?: boolean; /** - * @member * The characters to decode * @default [".", "-", "~", "$"] */ @@ -35,13 +32,13 @@ export interface ParametersNameDecodingHandlerOptionsParams { /** The ParametersNameDecodingOptions request class */ export class ParametersNameDecodingHandlerOptions implements RequestOption { /** - * @public + * * Whether to decode the specified characters in the request query parameters names */ public enable: boolean; /** - * @public + * * The characters to decode * @default [".", "-", "~", "$"] */ @@ -52,10 +49,9 @@ export class ParametersNameDecodingHandlerOptions implements RequestOption { } /** - * @public - * @constructor + * * To create an instance of ParametersNameDecodingHandlerOptions - * @param {ParametersNameDecodingHandlerOptionsParams} [options = {}] - The optional parameters + * @param [options] - The optional parameters * @returns An instance of ParametersNameDecodingHandlerOptions * @example ParametersNameDecodingHandlerOptions({ enable: true, charactersToDecode: [".", "-", "~", "$"] }); */ diff --git a/packages/http/fetch/src/middlewares/options/redirectHandlerOptions.ts b/packages/http/fetch/src/middlewares/options/redirectHandlerOptions.ts index 72dbb4de4..bf0cbd1ef 100644 --- a/packages/http/fetch/src/middlewares/options/redirectHandlerOptions.ts +++ b/packages/http/fetch/src/middlewares/options/redirectHandlerOptions.ts @@ -12,7 +12,7 @@ import type { RequestOption } from "@microsoft/kiota-abstractions"; /** - * @type + * * A type declaration for shouldRetry callback */ export type ShouldRedirect = (response: Response) => boolean; @@ -25,48 +25,43 @@ export interface RedirectHandlerOptionsParams { } /** - * @class - * @implements MiddlewareOptions + * MiddlewareOptions * A class representing RedirectHandlerOptions */ export class RedirectHandlerOptions implements RequestOption { /** - * @private - * @static * A member holding default max redirects value */ - private static DEFAULT_MAX_REDIRECTS = 5; + private static readonly DEFAULT_MAX_REDIRECTS = 5; /** - * @private - * @static * A member holding maximum max redirects value */ - private static MAX_MAX_REDIRECTS = 20; + private static readonly MAX_MAX_REDIRECTS = 20; /** - * @private + * * A member holding default shouldRedirect callback + * @returns true */ - private static defaultShouldRetry: ShouldRedirect = () => true; + private static readonly defaultShouldRetry: ShouldRedirect = () => true; /** - * @public + * * A member holding the max redirects value */ public maxRedirects: number; /** - * @public + * * A member holding the should redirect callback */ public shouldRedirect: ShouldRedirect; /** - * @public - * @constructor + * * To create an instance of RedirectHandlerOptions - * @param {RedirectHandlerOptionsParams} [options = {}] - The redirect handler options instance + * @param [options] - The redirect handler options instance * @returns An instance of RedirectHandlerOptions * @throws Error if maxRedirects is more than 20 or less than 0 * @example const options = new RedirectHandlerOptions({ maxRedirects: 5 }); diff --git a/packages/http/fetch/src/middlewares/options/retryHandlerOptions.ts b/packages/http/fetch/src/middlewares/options/retryHandlerOptions.ts index ab61c7fbe..cd3996382 100644 --- a/packages/http/fetch/src/middlewares/options/retryHandlerOptions.ts +++ b/packages/http/fetch/src/middlewares/options/retryHandlerOptions.ts @@ -14,77 +14,64 @@ import type { RequestOption } from "@microsoft/kiota-abstractions"; import type { FetchResponse } from "../../utils/fetchDefinitions"; /** - * @type + * * A type declaration for shouldRetry callback */ export type ShouldRetry = (delay: number, attempt: number, request: string, options: RequestInit | undefined, response: FetchResponse) => boolean; export const RetryHandlerOptionKey = "RetryHandlerOptionKey"; /** - * @interface * Signature to define the RetryHandlerOptions constructor parameters */ export interface RetryHandlerOptionsParams { /** - * @member * The delay value in seconds * @default 3 */ delay?: number; /** - * @member * The maxRetries value * @default 3 */ maxRetries?: number; /** - * @member * The shouldRetry callback function */ shouldRetry?: ShouldRetry; } /** - * @class - * @implements RequestOption + * RequestOption * Options * Class for RetryHandlerOptions */ export class RetryHandlerOptions implements RequestOption { /** - * @private - * @static * A member holding default delay value in seconds */ - private static DEFAULT_DELAY = 3; + private static readonly DEFAULT_DELAY = 3; /** - * @private - * @static * A member holding default maxRetries value */ - private static DEFAULT_MAX_RETRIES = 3; + private static readonly DEFAULT_MAX_RETRIES = 3; /** - * @private - * @static * A member holding maximum delay value in seconds */ - private static MAX_DELAY = 180; + private static readonly MAX_DELAY = 180; /** - * @private - * @static * A member holding maximum maxRetries value */ - private static MAX_MAX_RETRIES = 10; + private static readonly MAX_MAX_RETRIES = 10; /** - * @private * A member holding default shouldRetry callback + * @returns true */ - private static defaultShouldRetry: ShouldRetry = () => true; + private static readonly defaultShouldRetry: ShouldRetry = () => true; /* * @public @@ -93,22 +80,21 @@ export class RetryHandlerOptions implements RequestOption { public delay: number; /** - * @public + * * A member holding maxRetries value */ public maxRetries: number; /** - * @public + * * A member holding shouldRetry callback */ public shouldRetry: ShouldRetry; /** - * @public - * @constructor + * * To create an instance of RetryHandlerOptions - * @param {RetryHandlerOptionsParams} options - The RetryHandlerOptionsParams object + * @param options - The RetryHandlerOptionsParams object * @returns An instance of RetryHandlerOptions * @example const options = new RetryHandlerOptions({ maxRetries: 4 }); */ @@ -131,10 +117,10 @@ export class RetryHandlerOptions implements RequestOption { } /** - * @private + * * Creates an error object with a message and name - * @param {string} message - The error message - * @param {string} name - The error name + * @param message - The error message + * @param name - The error name * @returns An error object */ private createError(message: string, name: string): Error { @@ -144,7 +130,7 @@ export class RetryHandlerOptions implements RequestOption { } /** - * @public + * * To get the maximum delay * @returns A maximum delay */ diff --git a/packages/http/fetch/src/middlewares/options/userAgentHandlerOptions.ts b/packages/http/fetch/src/middlewares/options/userAgentHandlerOptions.ts index 356071e7d..b6deab523 100644 --- a/packages/http/fetch/src/middlewares/options/userAgentHandlerOptions.ts +++ b/packages/http/fetch/src/middlewares/options/userAgentHandlerOptions.ts @@ -11,29 +11,21 @@ import { libraryVersion } from "./version"; export const UserAgentHandlerOptionsKey = "UserAgentHandlerOptionKey"; /** - * @interface - * Signature to define the user agent handler options - * @property {boolean} [enable = true] - Whether to add the user agent header to the request - * @property {string} [productName = "kiota-typescript"] - The product name to be added to the user agent header - * @property {string} [productVersion = "1.0.0-preview.12"] - The product version to be added to the user agent header * * Represents the options for the UserAgentHandler. */ export interface UserAgentHandlerOptionsParams { /** - * @member * @default true * Specifies whether to add the user agent header to the request */ enable?: boolean; /** - * @member * @default "kiota-typescript" * The product name to be added to the user agent header */ productName?: string; /** - * @member * @default "1.0.0-preview.12" * The product version to be added to the user agent header */ @@ -45,20 +37,17 @@ export interface UserAgentHandlerOptionsParams { */ export class UserAgentHandlerOptions implements RequestOption { /** - * @member * Specifies whether to add the user agent header to the request */ public enable: boolean; /** - * @member * @default "kiota-typescript" * The product name to be added to the user agent header */ public productName: string; /** - * @member * The product version to be added to the user agent header */ public productVersion: string; @@ -68,10 +57,9 @@ export class UserAgentHandlerOptions implements RequestOption { } /** - * @public - * @constructor + * * To create an instance of UserAgentHandlerOptions - * @param {UserAgentHandlerOptionsParams} [options = {}] - The options for the UserAgentHandler + * @param [options] - The options for the UserAgentHandler * @example const options = new UserAgentHandlerOptions({ enable: false }); */ public constructor(options: Partial = {}) { diff --git a/packages/http/fetch/src/middlewares/options/version.ts b/packages/http/fetch/src/middlewares/options/version.ts index 8c30fb8e8..ebc5e2b05 100644 --- a/packages/http/fetch/src/middlewares/options/version.ts +++ b/packages/http/fetch/src/middlewares/options/version.ts @@ -1,3 +1,10 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + // x-release-please-start-version export const libraryVersion = "1.0.0-preview.24"; // x-release-please-end diff --git a/packages/http/fetch/src/middlewares/parametersNameDecodingHandler.ts b/packages/http/fetch/src/middlewares/parametersNameDecodingHandler.ts index 1827fdc02..22bf2eca3 100644 --- a/packages/http/fetch/src/middlewares/parametersNameDecodingHandler.ts +++ b/packages/http/fetch/src/middlewares/parametersNameDecodingHandler.ts @@ -18,10 +18,9 @@ import { ParametersNameDecodingHandlerOptions, ParametersNameDecodingHandlerOpti export class ParametersNameDecodingHandler implements Middleware { /** - * @public - * @constructor + * * To create an instance of ParametersNameDecodingHandler - * @param {ParametersNameDecodingHandlerOptions} [options = new ParametersNameDecodingHandlerOptions()] - The parameters name decoding handler options value + * @param [options] - The parameters name decoding handler options value */ public constructor(private readonly options: ParametersNameDecodingHandlerOptions = new ParametersNameDecodingHandlerOptions()) { if (!options) { @@ -31,17 +30,15 @@ export class ParametersNameDecodingHandler implements Middleware { /** @inheritdoc */ next: Middleware | undefined; /** - * @public - * @async * To execute the current middleware - * @param {string} url - The url to be fetched - * @param {FetchRequestInit} requestInit - The request init object - * @param {Record} [requestOptions] - The request options + * @param url - The url to be fetched + * @param requestInit - The request init object + * @param requestOptions - The request options * @returns A Promise that resolves to nothing */ public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { let currentOptions = this.options; - if (requestOptions && requestOptions[ParametersNameDecodingHandlerOptionsKey]) { + if (requestOptions?.[ParametersNameDecodingHandlerOptionsKey]) { currentOptions = requestOptions[ParametersNameDecodingHandlerOptionsKey] as ParametersNameDecodingHandlerOptions; } const obsOptions = getObservabilityOptionsFromRequest(requestOptions); @@ -59,7 +56,7 @@ export class ParametersNameDecodingHandler implements Middleware { } private decodeParameters(url: string, requestInit: RequestInit, currentOptions: ParametersNameDecodingHandlerOptions, requestOptions?: Record): Promise { let updatedUrl = url; - if (currentOptions && currentOptions.enable && url.indexOf("%") > -1 && currentOptions.charactersToDecode && currentOptions.charactersToDecode.length > 0) { + if (currentOptions && currentOptions.enable && url.includes("%") && currentOptions.charactersToDecode && currentOptions.charactersToDecode.length > 0) { currentOptions.charactersToDecode.forEach((character) => { updatedUrl = updatedUrl.replace(new RegExp(`%${character.charCodeAt(0).toString(16)}`, "gi"), character); }); diff --git a/packages/http/fetch/src/middlewares/redirectHandler.ts b/packages/http/fetch/src/middlewares/redirectHandler.ts index 61390773f..57634503e 100644 --- a/packages/http/fetch/src/middlewares/redirectHandler.ts +++ b/packages/http/fetch/src/middlewares/redirectHandler.ts @@ -18,18 +18,16 @@ import type { Middleware } from "./middleware"; import { RedirectHandlerOptionKey, RedirectHandlerOptions } from "./options/redirectHandlerOptions"; /** - * @class + * * Class - * @implements Middleware + * Middleware * Class representing RedirectHandler */ export class RedirectHandler implements Middleware { /** - * @private - * @static * A member holding the array of redirect status codes */ - private static REDIRECT_STATUS_CODES: Set = new Set([ + private static readonly REDIRECT_STATUS_CODES = new Set([ 301, // Moved Permanently 302, // Found 303, // See Other @@ -38,53 +36,44 @@ export class RedirectHandler implements Middleware { ]); /** - * @private - * @static * A member holding SeeOther status code */ - private static STATUS_CODE_SEE_OTHER = 303; + private static readonly STATUS_CODE_SEE_OTHER = 303; /** - * @private - * @static * A member holding the name of the location header */ - private static LOCATION_HEADER = "Location"; + private static readonly LOCATION_HEADER = "Location"; /** - * @private - * @static * A member representing the authorization header name */ - private static AUTHORIZATION_HEADER = "Authorization"; + private static readonly AUTHORIZATION_HEADER = "Authorization"; /** - * @private - * @static * A member holding the manual redirect value */ - private static MANUAL_REDIRECT = "manual"; + private static readonly MANUAL_REDIRECT = "manual"; /** Next middleware to be executed*/ next: Middleware | undefined; /** * - * @public - * @constructor + * * To create an instance of RedirectHandler - * @param {RedirectHandlerOptions} [options = new RedirectHandlerOptions()] - The redirect handler options instance + * @param [options] - The redirect handler options instance * @returns An instance of RedirectHandler */ - public constructor(private options: RedirectHandlerOptions = new RedirectHandlerOptions()) { + public constructor(private readonly options: RedirectHandlerOptions = new RedirectHandlerOptions()) { if (!options) { throw new Error("The options parameter is required."); } } /** - * @private + * * To check whether the response has the redirect status code or not - * @param {Response} response - The response object + * @param response - The response object * @returns A boolean representing whether the response contains the redirect status code or not */ private isRedirect(response: FetchResponse): boolean { @@ -92,9 +81,9 @@ export class RedirectHandler implements Middleware { } /** - * @private + * * To check whether the response has location header or not - * @param {Response} response - The response object + * @param response - The response object * @returns A boolean representing the whether the response has location header or not */ private hasLocationHeader(response: FetchResponse): boolean { @@ -102,9 +91,9 @@ export class RedirectHandler implements Middleware { } /** - * @private + * * To get the redirect url from location header in response object - * @param {Response} response - The response object + * @param response - The response object * @returns A redirect url from location header */ private getLocationHeader(response: FetchResponse): string | null { @@ -112,20 +101,20 @@ export class RedirectHandler implements Middleware { } /** - * @private + * * To check whether the given url is a relative url or not - * @param {string} url - The url string value + * @param url - The url string value * @returns A boolean representing whether the given url is a relative url or not */ private isRelativeURL(url: string): boolean { - return url.indexOf("://") === -1; + return !url.includes("://"); } /** - * @private + * * To check whether the authorization header in the request should be dropped for consequent redirected requests - * @param {string} requestUrl - The request url value - * @param {string} redirectUrl - The redirect url value + * @param requestUrl - The request url value + * @param redirectUrl - The redirect url value * @returns A boolean representing whether the authorization header in the request should be dropped for consequent redirected requests */ private shouldDropAuthorizationHeader(requestUrl: string, redirectUrl: string): boolean { @@ -144,14 +133,13 @@ export class RedirectHandler implements Middleware { } /** - * @private - * @async * To execute the next middleware and to handle in case of redirect response returned by the server - * @param {Context} context - The context object - * @param {number} redirectCount - The redirect count value - * @param {Record} [requestOptions = {}] - The request options - * @param {RedirectHandlerOptions} currentOptions - The redirect handler options instance - * @param {string} tracerName - The name to use for the tracer + * @param url - The url string value + * @param fetchRequestInit - The Fetch RequestInit object + * @param redirectCount - The redirect count value + * @param currentOptions - The redirect handler options instance + * @param requestOptions - The request options + * @param tracerName - The name to use for the tracer * @returns A promise that resolves to nothing */ private async executeWithRedirect(url: string, fetchRequestInit: FetchRequestInit, redirectCount: number, currentOptions: RedirectHandlerOptions, requestOptions?: Record, tracerName?: string): Promise { @@ -162,7 +150,7 @@ export class RedirectHandler implements Middleware { if (redirectCount < currentOptions.maxRedirects && this.isRedirect(response) && this.hasLocationHeader(response) && currentOptions.shouldRedirect(response)) { ++redirectCount; if (response.status === RedirectHandler.STATUS_CODE_SEE_OTHER) { - fetchRequestInit["method"] = HttpMethod.GET; + fetchRequestInit.method = HttpMethod.GET; delete fetchRequestInit.body; } else { const redirectUrl = this.getLocationHeader(response); @@ -191,16 +179,16 @@ export class RedirectHandler implements Middleware { } /** - * @public - * @async - * To execute the current middleware - * @param {Context} context - The context object of the request - * @returns A Promise that resolves to nothing + * Executes the request and returns a promise resolving the response. + * @param url - The url for the request + * @param requestInit - The Fetch RequestInit object. + * @param requestOptions - The request options. + * @returns A Promise that resolves to the response. */ public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { const redirectCount = 0; let currentOptions = this.options; - if (requestOptions && requestOptions[RedirectHandlerOptionKey]) { + if (requestOptions?.[RedirectHandlerOptionKey]) { currentOptions = requestOptions[RedirectHandlerOptionKey] as RedirectHandlerOptions; } (requestInit as FetchRequestInit).redirect = RedirectHandler.MANUAL_REDIRECT; diff --git a/packages/http/fetch/src/middlewares/retryHandler.ts b/packages/http/fetch/src/middlewares/retryHandler.ts index 9bad5f0e4..c5f9c7401 100644 --- a/packages/http/fetch/src/middlewares/retryHandler.ts +++ b/packages/http/fetch/src/middlewares/retryHandler.ts @@ -19,50 +19,42 @@ import { type Middleware } from "./middleware"; import { RetryHandlerOptionKey, RetryHandlerOptions } from "./options/retryHandlerOptions"; /** - * @class - * @implements Middleware + * Middleware * Class for RetryHandler */ export class RetryHandler implements Middleware { /** - * @private - * @static * A list of status codes that needs to be retried */ - private static RETRY_STATUS_CODES: Set = new Set([ + private static readonly RETRY_STATUS_CODES = new Set([ 429, // Too many requests 503, // Service unavailable 504, // Gateway timeout ]); /** - * @private - * @static * A member holding the name of retry attempt header */ - private static RETRY_ATTEMPT_HEADER = "Retry-Attempt"; + private static readonly RETRY_ATTEMPT_HEADER = "Retry-Attempt"; /** - * @private - * @static * A member holding the name of retry after header */ - private static RETRY_AFTER_HEADER = "Retry-After"; + private static readonly RETRY_AFTER_HEADER = "Retry-After"; /** - * @private + * * The next middleware in the middleware chain */ next: Middleware | undefined; /** - * @public - * @constructor + * * To create an instance of RetryHandler - * @param {RetryHandlerOptions} [options = new RetryHandlerOptions()] - The retry handler options value + * @param [options] - The retry handler options value * @returns An instance of RetryHandler */ - public constructor(private options: RetryHandlerOptions = new RetryHandlerOptions()) { + public constructor(private readonly options: RetryHandlerOptions = new RetryHandlerOptions()) { if (!options) { throw new Error("The options parameter is required."); } @@ -70,9 +62,9 @@ export class RetryHandler implements Middleware { /** * - * @private + * * To check whether the response has the retry status code - * @param {Response} response - The response object + * @param response - The response object * @returns Whether the response has retry status code or not */ private isRetry(response: FetchResponse): boolean { @@ -80,9 +72,9 @@ export class RetryHandler implements Middleware { } /** - * @private + * * To check whether the payload is buffered or not - * @param {RequestInit} options - The options of a request + * @param options - The options of a request * @returns Whether the payload is buffered or not */ private isBuffered(options: FetchRequestInit): boolean { @@ -98,11 +90,11 @@ export class RetryHandler implements Middleware { } /** - * @private + * * To get the delay for a retry - * @param {Response} response - The response object - * @param {number} retryAttempts - The current attempt count - * @param {number} delay - The delay value in seconds + * @param response - The response object + * @param retryAttempts - The current attempt count + * @param delay - The delay value in seconds * @returns A delay for a retry */ private getDelay(response: FetchResponse, retryAttempts: number, delay: number): number { @@ -125,9 +117,9 @@ export class RetryHandler implements Middleware { } /** - * @private + * * To get an exponential back off value - * @param {number} attempts - The current attempt count + * @param attempts - The current attempt count * @returns An exponential back off value */ private getExponentialBackOffTime(attempts: number): number { @@ -135,11 +127,9 @@ export class RetryHandler implements Middleware { } /** - * @private - * @async * To add delay for the execution - * @param {number} delaySeconds - The delay value in seconds - * @returns Nothing + * @param delaySeconds - The delay value in seconds + * @returns A Promise that resolves to nothing */ private async sleep(delaySeconds: number): Promise { const delayMilliseconds = delaySeconds * 1000; @@ -147,14 +137,13 @@ export class RetryHandler implements Middleware { } /** - * @private - * @async * To execute the middleware with retries - * @param {Context} context - The context object - * @param {number} retryAttempts - The current attempt count - * @param {Record} [requestOptions = {}] - The request options - * @param {RetryHandlerOptions} currentOptions - The retry middleware options instance - * @param {string} tracerName - The name to use for the tracer + * @param url - The request url + * @param fetchRequestInit - The request options + * @param retryAttempts - The current attempt count + * @param currentOptions - The current request options for the retry handler. + * @param requestOptions - The retry middleware options instance + * @param tracerName - The name to use for the tracer * @returns A Promise that resolves to nothing */ private async executeWithRetry(url: string, fetchRequestInit: FetchRequestInit, retryAttempts: number, currentOptions: RetryHandlerOptions, requestOptions?: Record, tracerName?: string): Promise { @@ -192,17 +181,17 @@ export class RetryHandler implements Middleware { } /** - * @public - * @async * To execute the current middleware - * @param {Context} context - The context object of the request + * @param url - The request url + * @param requestInit - The request options + * @param requestOptions - The request options * @returns A Promise that resolves to nothing */ public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { const retryAttempts = 0; let currentOptions = this.options; - if (requestOptions && requestOptions[RetryHandlerOptionKey]) { + if (requestOptions?.[RetryHandlerOptionKey]) { currentOptions = requestOptions[RetryHandlerOptionKey] as RetryHandlerOptions; } const obsOptions = getObservabilityOptionsFromRequest(requestOptions); diff --git a/packages/http/fetch/src/middlewares/telemetryHandler.ts b/packages/http/fetch/src/middlewares/telemetryHandler.ts index 1a6e1fd85..2183cf1a7 100644 --- a/packages/http/fetch/src/middlewares/telemetryHandler.ts +++ b/packages/http/fetch/src/middlewares/telemetryHandler.ts @@ -11,12 +11,12 @@ import type { TelemetryHandlerOptions } from "./options/telemetryHandlerOptions" export const TelemetryHandlerOptionsKey = "TelemetryHandlerOptionsKey"; export class TelemetryHandler implements Middleware { - constructor(private telemetryHandlerOptions: TelemetryHandlerOptions) {} + constructor(private readonly telemetryHandlerOptions: TelemetryHandlerOptions) {} next: Middleware | undefined; execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { - if (this.telemetryHandlerOptions && this.telemetryHandlerOptions.telemetryConfigurator) { + if (this.telemetryHandlerOptions?.telemetryConfigurator) { this.telemetryHandlerOptions.telemetryConfigurator(url, requestInit, requestOptions, this.telemetryHandlerOptions.telemetryInformation); - } else if (requestOptions && requestOptions[TelemetryHandlerOptionsKey]) { + } else if (requestOptions?.[TelemetryHandlerOptionsKey]) { (requestOptions[TelemetryHandlerOptionsKey] as TelemetryHandlerOptions).telemetryConfigurator(url, requestInit, requestOptions); } if (!this.next) { diff --git a/packages/http/fetch/src/middlewares/urlReplaceHandler.ts b/packages/http/fetch/src/middlewares/urlReplaceHandler.ts index f16ba7398..425c8ae8c 100644 --- a/packages/http/fetch/src/middlewares/urlReplaceHandler.ts +++ b/packages/http/fetch/src/middlewares/urlReplaceHandler.ts @@ -17,10 +17,9 @@ import { UrlReplaceHandlerOptions, UrlReplaceHandlerOptionsKey } from "./options */ export class UrlReplaceHandler implements Middleware { /** - * @public - * @constructor + * * Creates a new instance of the UrlReplaceHandler class - * @param {UrlReplaceHandlerOptions} handlerOptions The options for the url replace handler. + * @param handlerOptions The options for the url replace handler. * @returns An instance of the UrlReplaceHandler class */ public constructor(private readonly handlerOptions: UrlReplaceHandlerOptions = new UrlReplaceHandlerOptions()) { @@ -32,9 +31,9 @@ export class UrlReplaceHandler implements Middleware { /** * @inheritdoc */ - public execute(url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { let currentOptions = this.handlerOptions; - if (requestOptions && requestOptions[UrlReplaceHandlerOptionsKey]) { + if (requestOptions?.[UrlReplaceHandlerOptionsKey]) { currentOptions = requestOptions[UrlReplaceHandlerOptionsKey] as UrlReplaceHandlerOptions; } const obsOptions = getObservabilityOptionsFromRequest(requestOptions); @@ -50,7 +49,7 @@ export class UrlReplaceHandler implements Middleware { } return this.replaceTokensInUrl(currentOptions, url, requestInit, requestOptions); } - private replaceTokensInUrl(options: UrlReplaceHandlerOptions, url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + private replaceTokensInUrl(options: UrlReplaceHandlerOptions, url: string, requestInit: RequestInit, requestOptions?: Record): Promise { if (options.enabled) { Object.keys(options.urlReplacements).forEach((replacementKey) => { url = url.replace(replacementKey, options.urlReplacements[replacementKey]); diff --git a/packages/http/fetch/src/middlewares/userAgentHandler.ts b/packages/http/fetch/src/middlewares/userAgentHandler.ts index ef2c0eda6..5dabcc976 100644 --- a/packages/http/fetch/src/middlewares/userAgentHandler.ts +++ b/packages/http/fetch/src/middlewares/userAgentHandler.ts @@ -21,16 +21,14 @@ import { UserAgentHandlerOptions, UserAgentHandlerOptionsKey } from "./options/u const USER_AGENT_HEADER_KEY = "User-Agent"; export class UserAgentHandler implements Middleware { /** - * @public - * @constructor * To create an instance of UserAgentHandler - * @param {UserAgentHandlerOption} [options = new UserAgentHandlerOption()] - The options for the middleware + * @param _options - The options for the middleware */ public constructor(private readonly _options: UserAgentHandlerOptions = new UserAgentHandlerOptions()) {} /** @inheritdoc */ next: Middleware | undefined; /** @inheritdoc */ - public execute(url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + public execute(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { const obsOptions = getObservabilityOptionsFromRequest(requestOptions); if (obsOptions) { return trace.getTracer(obsOptions.getTracerInstrumentationName()).startActiveSpan("userAgentHandler - execute", (span) => { @@ -45,19 +43,19 @@ export class UserAgentHandler implements Middleware { return this.addValue(url, requestInit, requestOptions); } } - private async addValue(url: string, requestInit: RequestInit, requestOptions?: Record | undefined): Promise { + private async addValue(url: string, requestInit: RequestInit, requestOptions?: Record): Promise { let currentOptions = this._options; - if (requestOptions && requestOptions[UserAgentHandlerOptionsKey]) { + if (requestOptions?.[UserAgentHandlerOptionsKey]) { currentOptions = requestOptions[UserAgentHandlerOptionsKey] as UserAgentHandlerOptions; } if (currentOptions.enable) { const additionalValue = `${currentOptions.productName}/${currentOptions.productVersion}`; const currentValue = getRequestHeader(requestInit as FetchRequestInit, USER_AGENT_HEADER_KEY); - if (!currentValue || currentValue.indexOf(additionalValue) === -1) { + if (!currentValue?.includes(additionalValue)) { appendRequestHeader(requestInit as FetchRequestInit, USER_AGENT_HEADER_KEY, additionalValue, " "); } } - const response = await this.next?.execute(url, requestInit as RequestInit, requestOptions); + const response = await this.next?.execute(url, requestInit, requestOptions); if (!response) throw new Error("No response returned by the next middleware"); return response; } diff --git a/packages/http/fetch/src/observabilityOptions.ts b/packages/http/fetch/src/observabilityOptions.ts index c53c57dea..8eee2217e 100644 --- a/packages/http/fetch/src/observabilityOptions.ts +++ b/packages/http/fetch/src/observabilityOptions.ts @@ -1,3 +1,9 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ import type { RequestOption } from "@microsoft/kiota-abstractions"; /** Holds the tracing, metrics and logging configuration for the request adapter */ @@ -28,6 +34,11 @@ export class ObservabilityOptionsImpl implements ObservabilityOptions, Observabi } } +/** + * Gets the observability options from the request options + * @param requestOptions The request options + * @returns The observability options + */ export function getObservabilityOptionsFromRequest(requestOptions?: Record): ObservabilityOptionsInternal | undefined { if (requestOptions) { const observabilityOptions = requestOptions[ObservabilityOptionKey]; diff --git a/packages/http/fetch/src/utils/headersUtil.ts b/packages/http/fetch/src/utils/headersUtil.ts index dec92d8fb..189a013ca 100644 --- a/packages/http/fetch/src/utils/headersUtil.ts +++ b/packages/http/fetch/src/utils/headersUtil.ts @@ -12,10 +12,9 @@ import type { FetchRequestInit } from "./fetchDefinitions"; */ /** - * @constant * To get the request header from the request - * @param {FetchOptions|undefined} options - The request options object - * @param {string} key - The header key string + * @param options - The request options object + * @param key - The header key string * @returns A header value for the given key from the request */ export const getRequestHeader = (options: FetchRequestInit | undefined, key: string): string | undefined => { @@ -26,12 +25,10 @@ export const getRequestHeader = (options: FetchRequestInit | undefined, key: str }; /** - * @constant * To set the header value to the given request - * @param {FetchOptions|undefined} options - The request options object - * @param {string} key - The header key string - * @param {string } value - The header value string - * @returns Nothing + * @param options - The request options object + * @param key - The header key string + * @param value - The header value string */ export const setRequestHeader = (options: FetchRequestInit | undefined, key: string, value: string): void => { if (options) { @@ -43,11 +40,9 @@ export const setRequestHeader = (options: FetchRequestInit | undefined, key: str }; /** - * @constant * To delete the header key to the given request - * @param {FetchOptions|undefined} options - The request options object - * @param {string} key - The header key string - * @returns Nothing + * @param options - The request options object + * @param key - The header key string */ export const deleteRequestHeader = (options: FetchRequestInit | undefined, key: string): void => { if (options) { @@ -59,13 +54,11 @@ export const deleteRequestHeader = (options: FetchRequestInit | undefined, key: }; /** - * @constant * To append the header value to the given request - * @param {FetchOptions|undefined} options - The request options object - * @param {string} key - The header key string - * @param {string } value - The header value string - * @param {string} separator - The separator string - * @returns Nothing + * @param options - The request options object + * @param key - The header key string + * @param value - The header value string + * @param separator - The separator string */ export const appendRequestHeader = (options: FetchRequestInit | undefined, key: string, value: string, separator = ", "): void => { if (options) { diff --git a/packages/http/fetch/vitest.config.mts b/packages/http/fetch/vitest.config.mts index 838c4e31b..c3ae27a2e 100644 --- a/packages/http/fetch/vitest.config.mts +++ b/packages/http/fetch/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/*/{testUtils,dummyFetchHandler,testCallBackMiddleware,mockEntity,mockParseNodeFactory,index}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/serialization/form/README.md b/packages/serialization/form/README.md index d4f84cda3..3674e398c 100644 --- a/packages/serialization/form/README.md +++ b/packages/serialization/form/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota URI Form Encoded Serialization Library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-serialization-form?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-serialization-form) The Form Serialization Library is an implementation to handle URI form encoded payloads. @@ -9,3 +11,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the Serialization Form implementations 1. `npm i @microsoft/kiota-serialization-form`. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/serialization/form/package.json b/packages/serialization/form/package.json index f1b519b6b..72df85823 100644 --- a/packages/serialization/form/package.json +++ b/packages/serialization/form/package.json @@ -18,6 +18,7 @@ "clean": "rimraf ./dist", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "repository": { @@ -44,5 +45,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/serialization/form/src/formParseNode.ts b/packages/serialization/form/src/formParseNode.ts index c9229ec8f..888af8b92 100644 --- a/packages/serialization/form/src/formParseNode.ts +++ b/packages/serialization/form/src/formParseNode.ts @@ -10,7 +10,8 @@ import { createBackedModelProxyHandler, DateOnly, Duration, type Parsable, type export class FormParseNode implements ParseNode { private readonly _fields: Record = {}; /** - * + * Creates a new instance of FormParseNode + * @param _rawString the raw string to parse */ constructor(private readonly _rawString: string) { if (!_rawString) { @@ -29,7 +30,7 @@ export class FormParseNode implements ParseNode { } }); } - private normalizeKey = (key: string): string => decodeURIComponent(key).trim(); + private readonly normalizeKey = (key: string): string => decodeURIComponent(key).trim(); public getByteArrayValue(): ArrayBuffer | undefined { throw new Error("serialization of byt arrays is not supported with URI encoding"); } @@ -104,6 +105,7 @@ export class FormParseNode implements ParseNode { if (!rawValues) { return []; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return rawValues.split(",").map((x) => getEnumValueFromStringValue(x, type) as T); }; public getEnumValue = (type: any): T | undefined => { @@ -113,7 +115,7 @@ export class FormParseNode implements ParseNode { } return getEnumValueFromStringValue(rawValue, type as Record) as T; }; - private assignFieldValues = (model: T, parsableFactory: ParsableFactory): void => { + private readonly assignFieldValues = (model: T, parsableFactory: ParsableFactory): void => { const fields = parsableFactory(this)(model); Object.entries(this._fields) .filter((x) => !/^null$/i.test(x[1])) diff --git a/packages/serialization/form/src/formSerializationWriter.ts b/packages/serialization/form/src/formSerializationWriter.ts index 3d85508fd..c33002ea5 100644 --- a/packages/serialization/form/src/formSerializationWriter.ts +++ b/packages/serialization/form/src/formSerializationWriter.ts @@ -12,14 +12,14 @@ import type { Guid } from "guid-typescript"; export class FormSerializationWriter implements SerializationWriter { public writeByteArrayValue( // eslint-disable-next-line @typescript-eslint/no-unused-vars - key?: string | undefined, + key?: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars - value?: ArrayBuffer | null | undefined, + value?: ArrayBuffer | null, ): void { throw new Error("serialization of byt arrays is not supported with URI encoding"); } private readonly writer: string[] = []; - private static propertySeparator = `&`; + private static readonly propertySeparator = `&`; private depth = -1; public onBeforeObjectSerialization: ((value: Parsable) => void) | undefined; public onAfterObjectSerialization: ((value: Parsable) => void) | undefined; @@ -34,10 +34,10 @@ export class FormSerializationWriter implements SerializationWriter { this.writer.push(FormSerializationWriter.propertySeparator); } }; - private writePropertyName = (key: string): void => { + private readonly writePropertyName = (key: string): void => { this.writer.push(encodeURIComponent(key)); }; - private shouldWriteValueOrNull = (key?: string, value?: T | null): boolean => { + private readonly shouldWriteValueOrNull = (key?: string, value?: T | null): boolean => { if (value === null) { this.writeNullValue(key); return false; @@ -90,9 +90,8 @@ export class FormSerializationWriter implements SerializationWriter { } }; public writeCollectionOfObjectValues = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars _key?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + _values?: T[] | null, ): void => { throw new Error(`serialization of collections is not supported with URI encoding`); @@ -115,14 +114,15 @@ export class FormSerializationWriter implements SerializationWriter { serializerMethod(this, value); this.onAfterObjectSerialization && this.onAfterObjectSerialization(value); if (this.writer.length > 0 && this.writer[this.writer.length - 1] === FormSerializationWriter.propertySeparator) { - //removing the last separator + // removing the last separator this.writer.pop(); } key && this.writer.push(FormSerializationWriter.propertySeparator); } }; - public writeEnumValue = (key?: string | undefined, ...values: (T | null | undefined)[]): void => { + public writeEnumValue = (key?: string, ...values: (T | null | undefined)[]): void => { if (values.length > 0) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions const rawValues = values.filter((x) => x !== undefined).map((x) => `${x}`); if (rawValues.length > 0) { this.writeStringValue( @@ -136,7 +136,7 @@ export class FormSerializationWriter implements SerializationWriter { return this.convertStringToArrayBuffer(this.writer.join(``)); }; - private convertStringToArrayBuffer = (str: string): ArrayBuffer => { + private readonly convertStringToArrayBuffer = (str: string): ArrayBuffer => { const encoder = new TextEncoder(); const encodedString = encoder.encode(str); return encodedString.buffer; @@ -145,12 +145,14 @@ export class FormSerializationWriter implements SerializationWriter { public writeAdditionalData = (additionalData: Record | undefined): void => { // Do not use !value here, because value can be `false`. if (additionalData === undefined) return; + // eslint-disable-next-line guard-for-in for (const key in additionalData) { this.writeAnyValue(key, additionalData[key]); } }; - private writeAnyValue = (key?: string | undefined, value?: unknown | null | undefined): void => { + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + private readonly writeAnyValue = (key?: string, value?: unknown | null): void => { if (value === null) { return this.writeNullValue(key); } @@ -172,6 +174,7 @@ export class FormSerializationWriter implements SerializationWriter { } else if (valueType === "number") { this.writeNumberValue(key, value as any as number); } else { + // eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions throw new Error(`encountered unknown ${value} value type during serialization ${valueType} for key ${key}`); } } diff --git a/packages/serialization/form/vitest.config.mts b/packages/serialization/form/vitest.config.mts index 16577bafc..de8d56a22 100644 --- a/packages/serialization/form/vitest.config.mts +++ b/packages/serialization/form/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/*/{testEntity,index}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/serialization/json/README.md b/packages/serialization/json/README.md index 4c728ea76..91504fc30 100644 --- a/packages/serialization/json/README.md +++ b/packages/serialization/json/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota JSON Serialization library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-serialization-json?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-serialization-json) The JSON Serialization Library is an implementation to handle JSON payloads. @@ -9,3 +11,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the Serialization JSON implementations 1. `npm i @microsoft/kiota-serialization-json`. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/serialization/json/package.json b/packages/serialization/json/package.json index ba7145bbd..99e875c9c 100644 --- a/packages/serialization/json/package.json +++ b/packages/serialization/json/package.json @@ -18,6 +18,7 @@ "clean": "rimraf ./dist", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "repository": { @@ -44,5 +45,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/serialization/json/src/browser/jsonParseNodeFactory.ts b/packages/serialization/json/src/browser/jsonParseNodeFactory.ts index e4386fee1..6b2e92d61 100644 --- a/packages/serialization/json/src/browser/jsonParseNodeFactory.ts +++ b/packages/serialization/json/src/browser/jsonParseNodeFactory.ts @@ -27,6 +27,7 @@ export class JsonParseNodeFactory implements ParseNodeFactory { private convertArrayBufferToJson(content: ArrayBuffer) { const decoder = new TextDecoder(); const contentAsStr = decoder.decode(content); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return JSON.parse(contentAsStr); } } diff --git a/packages/serialization/json/src/jsonParseNode.ts b/packages/serialization/json/src/jsonParseNode.ts index 8550dab21..5295239a2 100644 --- a/packages/serialization/json/src/jsonParseNode.ts +++ b/packages/serialization/json/src/jsonParseNode.ts @@ -72,7 +72,7 @@ export class JsonParseNode implements ParseNode { value = createUntypedNumber(this._jsonNode as number) as unknown as T; } else if (Array.isArray(this._jsonNode)) { const nodes: UntypedNode[] = []; - // eslint-disable-next-line @typescript-eslint/no-unused-vars + this._jsonNode.forEach((x) => { nodes.push(new JsonParseNode(x).getObjectValue(createUntypedNodeFromDiscriminatorValue)); }); @@ -89,18 +89,18 @@ export class JsonParseNode implements ParseNode { return value; } const enableBackingStore = isBackingStoreEnabled(parsableFactory(this)(temp)); - const value: T = enableBackingStore ? new Proxy(temp, createBackedModelProxyHandler()) : temp; + const objectValue: T = enableBackingStore ? new Proxy(temp, createBackedModelProxyHandler()) : temp; if (this.onBeforeAssignFieldValues) { - this.onBeforeAssignFieldValues(value); + this.onBeforeAssignFieldValues(objectValue); } - this.assignFieldValues(value, parsableFactory); + this.assignFieldValues(objectValue, parsableFactory); if (this.onAfterAssignFieldValues) { - this.onAfterAssignFieldValues(value); + this.onAfterAssignFieldValues(objectValue); } - return value; + return objectValue; }; - private assignFieldValues = (model: T, parsableFactory: ParsableFactory): void => { + private readonly assignFieldValues = (model: T, parsableFactory: ParsableFactory): void => { const fields = parsableFactory(this)(model); if (!this._jsonNode) return; Object.entries(this._jsonNode).forEach(([k, v]) => { diff --git a/packages/serialization/json/src/jsonParseNodeFactory.ts b/packages/serialization/json/src/jsonParseNodeFactory.ts index 42889849a..7efff83bb 100644 --- a/packages/serialization/json/src/jsonParseNodeFactory.ts +++ b/packages/serialization/json/src/jsonParseNodeFactory.ts @@ -27,6 +27,7 @@ export class JsonParseNodeFactory implements ParseNodeFactory { private convertArrayBufferToJson(content: ArrayBuffer) { const decoder = new TextDecoder(); const contentAsStr = decoder.decode(content); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return JSON.parse(contentAsStr); } } diff --git a/packages/serialization/json/src/jsonSerializationWriter.ts b/packages/serialization/json/src/jsonSerializationWriter.ts index 299ca29be..bedb8dfc9 100644 --- a/packages/serialization/json/src/jsonSerializationWriter.ts +++ b/packages/serialization/json/src/jsonSerializationWriter.ts @@ -10,7 +10,7 @@ import { DateOnly, Duration, isUntypedNode, type ModelSerializerFunction, type P import type { Guid } from "guid-typescript"; export class JsonSerializationWriter implements SerializationWriter { - public writeByteArrayValue(key?: string | undefined, value?: ArrayBuffer | undefined): void { + public writeByteArrayValue(key?: string, value?: ArrayBuffer): void { if (!value) { throw new Error("value cannot be undefined"); } @@ -18,8 +18,8 @@ export class JsonSerializationWriter implements SerializationWriter { this.writeStringValue(key, b64); } private readonly writer: string[] = []; - private static propertySeparator = `,`; - private shouldWriteValueOrNull = (key?: string, value?: T | null): boolean => { + private static readonly propertySeparator = `,`; + private readonly shouldWriteValueOrNull = (key?: string, value?: T | null): boolean => { if (value === null) { this.writeNullValue(key); return false; @@ -40,7 +40,7 @@ export class JsonSerializationWriter implements SerializationWriter { key && this.writer.push(JsonSerializationWriter.propertySeparator); } }; - private writePropertyName = (key: string): void => { + private readonly writePropertyName = (key: string): void => { this.writer.push(`"${key}":`); }; public writeBooleanValue = (key?: string, value?: boolean | null): void => { @@ -72,6 +72,7 @@ export class JsonSerializationWriter implements SerializationWriter { if (this.shouldWriteValueOrNull(key, value)) { key && this.writePropertyName(key); + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions this.writer.push(`"${value}"`); key && this.writer.push(JsonSerializationWriter.propertySeparator); } @@ -114,7 +115,7 @@ export class JsonSerializationWriter implements SerializationWriter { this.writer.push(JsonSerializationWriter.propertySeparator); }); if (values.length > 0) { - //removing the last separator + // removing the last separator this.writer.pop(); } this.endArray(); @@ -209,8 +210,9 @@ export class JsonSerializationWriter implements SerializationWriter { } }; - public writeEnumValue = (key?: string | undefined, ...values: (T | undefined | null)[]): void => { + public writeEnumValue = (key?: string, ...values: (T | undefined | null)[]): void => { if (values.length > 0) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions const rawValues = values.filter((x) => x !== undefined).map((x) => `${x}`); if (rawValues.length > 0) { this.writeStringValue( @@ -240,13 +242,14 @@ export class JsonSerializationWriter implements SerializationWriter { } }; - private readonly writeNonParsableObjectValue = (key?: string | undefined, value?: object | undefined) => { + private readonly writeNonParsableObjectValue = (key?: string, value?: object) => { if (key) { this.writePropertyName(key); } this.writer.push(JSON.stringify(value), JsonSerializationWriter.propertySeparator); }; - private readonly writeAnyValue = (key?: string | undefined, value?: unknown | null | undefined): void => { + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + private readonly writeAnyValue = (key?: string, value?: unknown | null): void => { if (value === undefined) { return; } diff --git a/packages/serialization/json/vitest.config.mts b/packages/serialization/json/vitest.config.mts index 36bcf8909..61e5e2216 100644 --- a/packages/serialization/json/vitest.config.mts +++ b/packages/serialization/json/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/*/{testEntity,index,untypedTestEntiy,unionOfObjectsAndPrimitives,testUtils}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, }); diff --git a/packages/serialization/multipart/README.md b/packages/serialization/multipart/README.md index b91ab6983..096d31f90 100644 --- a/packages/serialization/multipart/README.md +++ b/packages/serialization/multipart/README.md @@ -1,3 +1,5 @@ +# Microsoft Kiota Multipart Serialization Library for TypeScript + [![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-serialization-multipart?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-serialization-multipart) The Multipart Serialization Library is an implementation to handle multipart form data payloads. @@ -9,3 +11,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the Serialization Multipart implementations 1. `npm i @microsoft/kiota-serialization-multipart`. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/serialization/multipart/package.json b/packages/serialization/multipart/package.json index adba44826..970a4f3ae 100644 --- a/packages/serialization/multipart/package.json +++ b/packages/serialization/multipart/package.json @@ -14,6 +14,7 @@ "clean": "rimraf -rf ./dist", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "repository": { @@ -43,5 +44,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/serialization/multipart/src/multipartSerializationWriter.ts b/packages/serialization/multipart/src/multipartSerializationWriter.ts index 133c2734f..e03b70998 100644 --- a/packages/serialization/multipart/src/multipartSerializationWriter.ts +++ b/packages/serialization/multipart/src/multipartSerializationWriter.ts @@ -12,10 +12,9 @@ import type { Guid } from "guid-typescript"; /** Serialization writer for multipart/form-data */ export class MultipartSerializationWriter implements SerializationWriter { public writeByteArrayValue( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - key?: string | undefined, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - value?: ArrayBuffer | undefined, + key?: string, + + value?: ArrayBuffer, ): void { if (!value) { throw new Error("value cannot be undefined"); @@ -41,7 +40,7 @@ export class MultipartSerializationWriter implements SerializationWriter { this.writeRawStringValue(value); } }; - private writeRawStringValue = (value?: string | null): void => { + private readonly writeRawStringValue = (value?: string | null): void => { if (value) { this.writeByteArrayValue(undefined, new TextEncoder().encode(value).buffer); } @@ -79,17 +78,15 @@ export class MultipartSerializationWriter implements SerializationWriter { throw new Error(`serialization of null values is not supported with multipart`); }; public writeCollectionOfPrimitiveValues = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars _key?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + _values?: T[] | null, ): void => { throw new Error(`serialization of collections is not supported with multipart`); }; public writeCollectionOfObjectValues = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars _key?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + _values?: T[] | null, ): void => { throw new Error(`serialization of collections is not supported with multipart`); @@ -111,7 +108,7 @@ export class MultipartSerializationWriter implements SerializationWriter { }; public writeEnumValue = ( // eslint-disable-next-line @typescript-eslint/no-unused-vars - key?: string | undefined, + key?: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars ...values: (T | null | undefined)[] ): void => { diff --git a/packages/serialization/multipart/vitest.config.mts b/packages/serialization/multipart/vitest.config.mts index 16577bafc..de8d56a22 100644 --- a/packages/serialization/multipart/vitest.config.mts +++ b/packages/serialization/multipart/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/*/{testEntity,index}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/packages/serialization/text/README.md b/packages/serialization/text/README.md index 493f4446a..b51a49f21 100644 --- a/packages/serialization/text/README.md +++ b/packages/serialization/text/README.md @@ -1,5 +1,6 @@ -[![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-serialization-text?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-serialization-text) +# Microsoft Kiota Text Serialization Library for Python +[![npm version badge](https://img.shields.io/npm/v/@microsoft/kiota-serialization-text?color=blue)](https://www.npmjs.com/package/@microsoft/kiota-serialization-text) The Text Serialization Library is an implementation to handle text/plain payloads. @@ -10,3 +11,25 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README ## Using the Serialization text implementations 1. `npm i @microsoft/kiota-serialization-text`. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit . + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/packages/serialization/text/package.json b/packages/serialization/text/package.json index 6d06b28d2..630a4a57c 100644 --- a/packages/serialization/text/package.json +++ b/packages/serialization/text/package.json @@ -18,6 +18,7 @@ "clean": "rimraf -rf ./dist", "test:browser": "vitest run --browser.name=chrome --browser.headless --browser.provider=webdriverio", "test:node": "vitest --run", + "test:coverage": "vitest run --coverage.enabled --coverage.provider=istanbul", "test": "npm run test:node && npm run test:browser" }, "repository": { @@ -44,5 +45,8 @@ }, "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "defaults" + ] } diff --git a/packages/serialization/text/src/textParseNode.ts b/packages/serialization/text/src/textParseNode.ts index 8bfa6c0a3..9f1a3e7ad 100644 --- a/packages/serialization/text/src/textParseNode.ts +++ b/packages/serialization/text/src/textParseNode.ts @@ -7,13 +7,13 @@ import { DateOnly, Duration, type Parsable, type ParsableFactory, parseGuidString, type ParseNode, TimeOnly, inNodeEnv, getEnumValueFromStringValue } from "@microsoft/kiota-abstractions"; +/** + * This class represents a text parse node. + */ export class TextParseNode implements ParseNode { - private static noStructuredDataMessage = "text does not support structured data"; - /** - * - */ + private static readonly noStructuredDataMessage = "text does not support structured data"; constructor(private readonly text: string) { - if (this.text && this.text.length > 1 && this.text.charAt(0) === '"' && this.text.charAt(this.text.length - 1) === '"') { + if (this.text && this.text.length > 1 && this.text.startsWith('"') && this.text.endsWith('"')) { this.text = this.text.substring(1, this.text.length - 2); } } @@ -59,7 +59,6 @@ export class TextParseNode implements ParseNode { throw new Error(TextParseNode.noStructuredDataMessage); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars public getCollectionOfEnumValues = (type: any): T[] => { throw new Error(TextParseNode.noStructuredDataMessage); }; diff --git a/packages/serialization/text/src/textSerializationWriter.ts b/packages/serialization/text/src/textSerializationWriter.ts index 11dd51398..b90b46fa0 100644 --- a/packages/serialization/text/src/textSerializationWriter.ts +++ b/packages/serialization/text/src/textSerializationWriter.ts @@ -10,7 +10,7 @@ import { inNodeEnv, type DateOnly, type Duration, type ModelSerializerFunction, import type { Guid } from "guid-typescript"; export class TextSerializationWriter implements SerializationWriter { - public writeByteArrayValue(key?: string | undefined, value?: ArrayBuffer | null | undefined): void { + public writeByteArrayValue(key?: string, value?: ArrayBuffer | null): void { if (!value) { throw new Error("value cannot be undefined"); } @@ -18,7 +18,7 @@ export class TextSerializationWriter implements SerializationWriter { this.writeStringValue(key, b64); } - private static noStructuredDataMessage = "text does not support structured data"; + private static readonly noStructuredDataMessage = "text does not support structured data"; private readonly writer: string[] = []; public onBeforeObjectSerialization: ((value: Parsable) => void) | undefined; public onAfterObjectSerialization: ((value: Parsable) => void) | undefined; @@ -56,6 +56,7 @@ export class TextSerializationWriter implements SerializationWriter { } if (value) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions this.writeStringValue(key, `"${value}"`); } }; @@ -99,33 +100,31 @@ export class TextSerializationWriter implements SerializationWriter { this.writeStringValue(key, `null`); }; public writeCollectionOfPrimitiveValues = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars key?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + values?: T[] | null, ): void => { throw new Error(TextSerializationWriter.noStructuredDataMessage); }; public writeCollectionOfObjectValues = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars key?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + values?: T[] | null, serializerMethod?: ModelSerializerFunction, ): void => { throw new Error(TextSerializationWriter.noStructuredDataMessage); }; public writeObjectValue = ( - // eslint-disable-next-line @typescript-eslint/no-unused-vars key?: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + value?: T | null, serializerMethod?: ModelSerializerFunction, ): void => { throw new Error(TextSerializationWriter.noStructuredDataMessage); }; - public writeEnumValue = (key?: string | undefined, ...values: (T | null | undefined)[]): void => { + public writeEnumValue = (key?: string, ...values: (T | null | undefined)[]): void => { if (values.length > 0) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions const rawValues = values.filter((x) => x !== undefined).map((x) => `${x}`); if (rawValues.length > 0) { this.writeStringValue( @@ -139,13 +138,12 @@ export class TextSerializationWriter implements SerializationWriter { return this.convertStringToArrayBuffer(this.writer.join(``)); }; - private convertStringToArrayBuffer = (str: string): ArrayBuffer => { + private readonly convertStringToArrayBuffer = (str: string): ArrayBuffer => { const encoder = new TextEncoder(); const encodedString = encoder.encode(str); return encodedString.buffer; }; - // eslint-disable-next-line @typescript-eslint/no-unused-vars public writeAdditionalData = (value: Record | undefined): void => { throw new Error(TextSerializationWriter.noStructuredDataMessage); }; diff --git a/packages/serialization/text/vitest.config.mts b/packages/serialization/text/vitest.config.mts index 16577bafc..de8d56a22 100644 --- a/packages/serialization/text/vitest.config.mts +++ b/packages/serialization/text/vitest.config.mts @@ -5,7 +5,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, "**/*/{testEntity,index}.ts"], include: [...configDefaults.include, "test/**/*.ts"], coverage: { - reporter: ["html"], + reporter: ["html", "cobertura"], }, }, -}); \ No newline at end of file +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index 1413ea416..690767c75 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -26,25 +26,25 @@ }, "references": [ { - "path": "./abstractions/tsconfig.json" + "path": "./packages/abstractions/tsconfig.json" }, { - "path": "./serialization/form/tsconfig.json" + "path": "./packages/serialization/form/tsconfig.json" }, { - "path": "./serialization/json/tsconfig.json" + "path": "./packages/serialization/json/tsconfig.json" }, { - "path": "./serialization/text/tsconfig.json" + "path": "./packages/serialization/text/tsconfig.json" }, { - "path": "./http/fetch/tsconfig.json" + "path": "./packages/http/fetch/tsconfig.json" }, { - "path": "./authentication/azure/tsconfig.json" + "path": "./packages/authentication/azure/tsconfig.json" }, { - "path": "./authentication/spfx/tsconfig.json" + "path": "./packages/authentication/spfx/tsconfig.json" } ], "exclude": [