diff --git a/.gitignore b/.gitignore index 23d3bf9f9b2a..cadfa4fd91ed 100644 --- a/.gitignore +++ b/.gitignore @@ -183,3 +183,6 @@ _recordings /artifacts sdk/template/template-dpg/src/src + +# tshy +.tshy-build-tmp diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 80c435110fd4..d95c2a48b694 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -3705,6 +3705,25 @@ packages: vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) dev: false + /@vitest/coverage-istanbul@1.2.2(vitest@1.2.2): + resolution: {integrity: sha512-tJybwO8JT4H9ANz0T0/tJ1M5g3BkuHKYF1w5YO3z9sAiHBdGANrxN9c5lomJx1WSnLzCxQR5xxlJ4TLKbzrR3w==} + peerDependencies: + vitest: ^1.0.0 + dependencies: + debug: 4.3.4(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.1 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + magicast: 0.3.3 + picocolors: 1.0.0 + test-exclude: 6.0.0 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) + transitivePeerDependencies: + - supports-color + dev: false + /@vitest/expect@1.2.2: resolution: {integrity: sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==} dependencies: @@ -4350,6 +4369,11 @@ packages: supports-color: 7.2.0 dev: false + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /character-entities-legacy@1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} dev: false @@ -6634,6 +6658,19 @@ packages: - supports-color dev: false + /istanbul-lib-instrument@6.0.1: + resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.23.9 + '@babel/parser': 7.23.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + dev: false + /istanbul-lib-processinfo@2.0.3: resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==} engines: {node: '>=8'} @@ -7224,6 +7261,14 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false + /magicast@0.3.3: + resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==} + dependencies: + '@babel/parser': 7.23.9 + '@babel/types': 7.23.9 + source-map-js: 1.0.2 + dev: false + /make-dir@1.3.0: resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} engines: {node: '>=4'} @@ -8550,6 +8595,14 @@ packages: engines: {node: '>=8'} dev: false + /resolve-import@1.4.5: + resolution: {integrity: sha512-HXb4YqODuuXT7Icq1Z++0g2JmhgbUHSs3VT2xR83gqvAPUikYT2Xk+562KHQgiaNkbBOlPddYrDLsC44qQggzw==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + dependencies: + glob: 10.3.10 + walk-up-path: 3.0.1 + dev: false + /resolve@1.19.0: resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} dependencies: @@ -9205,6 +9258,17 @@ packages: engines: {node: '>= 0.4'} dev: false + /sync-content@1.0.2: + resolution: {integrity: sha512-znd3rYiiSxU3WteWyS9a6FXkTA/Wjk8WQsOyzHbineeL837dLn3DA4MRhsIX3qGcxDMH6+uuFV4axztssk7wEQ==} + engines: {node: '>=14'} + hasBin: true + dependencies: + glob: 10.3.10 + mkdirp: 3.0.1 + path-scurry: 1.10.1 + rimraf: 5.0.5 + dev: false + /tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} dependencies: @@ -9460,6 +9524,22 @@ packages: strip-bom: 3.0.0 dev: false + /tshy@1.11.0: + resolution: {integrity: sha512-5T5PVyuYQKTcOKz5a2lpwx4WKi8yEzQGO0Q5l+9clJMYupMaTI7ONEwKggGAZDQQGIgCOyUCfBWnSkG0XdJc+A==} + engines: {node: 16 >=16.17 || 18 >=18.15.0 || >=20.6.1} + hasBin: true + dependencies: + chalk: 5.3.0 + chokidar: 3.5.3 + foreground-child: 3.1.1 + mkdirp: 3.0.1 + resolve-import: 1.4.5 + rimraf: 5.0.5 + sync-content: 1.0.2 + typescript: 5.3.3 + walk-up-path: 3.0.1 + dev: false + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: false @@ -9581,6 +9661,12 @@ packages: hasBin: true dev: false + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + /typescript@5.3.3: resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} @@ -9871,6 +9957,10 @@ packages: engines: {node: '>=0.10.0'} dev: false + /walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + dev: false + /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: @@ -10203,7 +10293,7 @@ packages: dev: false file:projects/abort-controller.tgz: - resolution: {integrity: sha512-2/wrw99JB2E8EA/YOzTM6XFxWrQ3iZ6Tx/mTbs4rqv/VVAhE+HWlk0NfSWACrrnhO8eDVhij7n38NDae5aFHFQ==, tarball: file:projects/abort-controller.tgz} + resolution: {integrity: sha512-ZOH84LdHwT/VUIhlmqCEidQgdswG04dwkWMUQFMw9BOaRWV5hLZ3PQS6IprYtL1cV0h+i93nvpThd1L05yw2Kg==, tarball: file:projects/abort-controller.tgz} name: '@rush-temp/abort-controller' version: 0.0.0 dependencies: @@ -10211,6 +10301,8 @@ packages: '@types/chai': 4.3.11 '@types/mocha': 10.0.6 '@types/node': 18.19.14 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) c8: 8.0.1 chai: 4.3.10 cross-env: 7.0.3 @@ -10225,17 +10317,28 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/agrifood-farming.tgz: @@ -17866,7 +17969,7 @@ packages: dev: false file:projects/core-auth.tgz: - resolution: {integrity: sha512-k/FlgP8O3N4bqcqcNbZa+t4hVg5HoslH/NxqS6bWMsWasCb8/lfqA2sq2IACPhM22I/UvBGdH+QO2DH0cDb0rg==, tarball: file:projects/core-auth.tgz} + resolution: {integrity: sha512-4CPwbovKrGbzSvHmhN5YlLormsiBI5Lqu1IS4Z09YyML1VyQdeTg5QSirYbFFBCIwIk1pwesJWnWdo27Ba0PFw==, tarball: file:projects/core-auth.tgz} name: '@rush-temp/core-auth' version: 0.0.0 dependencies: @@ -17874,24 +17977,40 @@ packages: '@types/chai': 4.3.11 '@types/mocha': 10.0.6 '@types/node': 18.19.14 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 cross-env: 7.0.3 eslint: 8.56.0 inherits: 2.0.4 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 util: 0.12.5 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color + - terser + - webdriverio dev: false file:projects/core-client-1.tgz: - resolution: {integrity: sha512-5TQtFVeFpawpIKY+PyO96TfzuLqTbmoRTVvi9/Vkth/1Qe2KX8thgPRckjEVxdwoHn1gvXOqLvUCpMvHoHgHSw==, tarball: file:projects/core-client-1.tgz} + resolution: {integrity: sha512-NKtG/n9Jl1uDZAywMh0CBewums3kHZHWm1Xxe7vTL989fuurdALdkSPNvZWTKjLUrhGg2DrEH9LehGSPPxjFGg==, tarball: file:projects/core-client-1.tgz} name: '@rush-temp/core-client-1' version: 0.0.0 dependencies: @@ -17900,6 +18019,8 @@ packages: '@types/mocha': 10.0.6 '@types/node': 18.19.14 '@types/sinon': 17.0.3 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 cross-env: 7.0.3 eslint: 8.56.0 @@ -17915,23 +18036,34 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 sinon: 17.0.1 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 util: 0.12.5 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/core-client.tgz: - resolution: {integrity: sha512-Lh7qHNRNsty9gMlYMPXk9zz4Se9cbpo/CSmAGZzUWj7raLHhl9/ivwvHBDJ6QEIhUuS32W/6KY0qSTXUgGh7Yw==, tarball: file:projects/core-client.tgz} + resolution: {integrity: sha512-cTckrYKSXWFUSQIgLYDMQuqYFrizEk0H1KjUxUgBGhRu7JN+PwTIkR/pZqnFUmsKJi/p+kuotKV1AfWuVI4VkA==, tarball: file:projects/core-client.tgz} name: '@rush-temp/core-client' version: 0.0.0 dependencies: @@ -17940,6 +18072,8 @@ packages: '@types/mocha': 10.0.6 '@types/node': 18.19.14 '@types/sinon': 17.0.3 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 cross-env: 7.0.3 eslint: 8.56.0 @@ -17954,48 +18088,77 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 sinon: 17.0.1 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/core-http-compat.tgz: - resolution: {integrity: sha512-lsOiQC4ZxjpqKvW1lyUGknEsLNF2sqaKWaVWKPt1uKIjU9rdSwkTyVkMMQH2AQF9955/+hlgPaCzDmjaYnMiEA==, tarball: file:projects/core-http-compat.tgz} + resolution: {integrity: sha512-ebjf/HnM+En4ADvkBSy1YlPU/4YvUc2pDPNn5ph7rqWlEIKkZ3MRx0Ol81sx5I1Mf30zpK1xxGFKLMO/O7j/HQ==, tarball: file:projects/core-http-compat.tgz} name: '@rush-temp/core-http-compat' version: 0.0.0 dependencies: '@microsoft/api-extractor': 7.39.5(@types/node@18.19.14) '@types/mocha': 10.0.6 '@types/node': 18.19.14 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) cross-env: 7.0.3 eslint: 8.56.0 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 typescript: 5.3.3 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color + - terser + - webdriverio dev: false file:projects/core-lro.tgz: - resolution: {integrity: sha512-UDSyDyJLwoP4Tkw4ZDWjK0JdSPukzcrwvhHroq/e9v36l2/IUOmycq3623dzJE9ZaycczU9TMO2dfSAOgQSZPA==, tarball: file:projects/core-lro.tgz} + resolution: {integrity: sha512-T8QX6ypsxKzfo85yPS8fbuBDiwy8y9OD7zcPsCuBrON0JWj/Tl/VV1ZrAs8auk/V2p1v5r8zn+nHkRb1Jn1sNA==, tarball: file:projects/core-lro.tgz} name: '@rush-temp/core-lro' version: 0.0.0 dependencies: '@microsoft/api-extractor': 7.39.5(@types/node@18.19.14) '@types/mocha': 10.0.6 '@types/node': 18.19.14 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) c8: 8.0.1 cross-env: 7.0.3 eslint: 8.56.0 @@ -18009,21 +18172,32 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/core-paging.tgz: - resolution: {integrity: sha512-NdCa3zq9kMdBrsNNE7yE2pFV84Lp8N09CKbZwf7+aVeutuxq98H4lkeWeP7OPdWIdjPriWlGik3+suBc4oalIA==, tarball: file:projects/core-paging.tgz} + resolution: {integrity: sha512-HniT4IZautZZNjBX9/hnE0QA8fEHnkt2fTW2mfjrT8zEZa197w/BPTN7QtJjJKDpKeESdwvWvCvoEqQPzXP3HQ==, tarball: file:projects/core-paging.tgz} name: '@rush-temp/core-paging' version: 0.0.0 dependencies: @@ -18031,6 +18205,8 @@ packages: '@types/chai': 4.3.11 '@types/mocha': 10.0.6 '@types/node': 18.19.14 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 cross-env: 7.0.3 eslint: 8.56.0 @@ -18044,32 +18220,47 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/core-rest-pipeline.tgz: - resolution: {integrity: sha512-YgzdZvnjIYzOpSIQVjj0bCwoMHaETLnQcXy/hGJSwdHE1m2XXloR3P/lmAq/XomhgkSAmlWyt90ZMobVdSlTug==, tarball: file:projects/core-rest-pipeline.tgz} + resolution: {integrity: sha512-OyJjNf9jA6C3xzUyxFtOrS2PHojJz7YInM2hDNMQ4QoAGpiYwiOBoisBbZn97qnEbWvMIIOoDuqfxZl4H93Mhg==, tarball: file:projects/core-rest-pipeline.tgz} name: '@rush-temp/core-rest-pipeline' version: 0.0.0 dependencies: '@microsoft/api-extractor': 7.39.5(@types/node@18.19.14) + '@opentelemetry/api': 1.7.0 '@types/node': 18.19.14 '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) eslint: 8.56.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 playwright: 1.41.2 - rimraf: 3.0.2 + prettier: 3.2.5 + rimraf: 5.0.5 + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) @@ -18090,13 +18281,15 @@ packages: dev: false file:projects/core-sse.tgz: - resolution: {integrity: sha512-zVbXKb0xK2twMqBqkOjBZcBU6iM3jg5jK69sP5p1VOy/dpv/9cvLz3Ju0ssVKEZ7s4iFYFXH55gWirROg/skHQ==, tarball: file:projects/core-sse.tgz} + resolution: {integrity: sha512-u6Dn5xeqCIcyz3erh9YybZRXDTsK4MTxQoz7xUIhzTkLZGeXpjSeqE8Y+DzEGHosrAH4Ve+rMhMSNOIAB+Yjsg==, tarball: file:projects/core-sse.tgz} name: '@rush-temp/core-sse' version: 0.0.0 dependencies: '@microsoft/api-extractor': 7.39.5(@types/node@18.19.14) '@types/mocha': 10.0.6 '@types/node': 18.19.14 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) c8: 8.0.1 cross-env: 7.0.3 dotenv: 16.4.1 @@ -18115,23 +18308,33 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 + playwright: 1.41.2 + prettier: 3.2.5 puppeteer: 22.0.0(typescript@5.3.3) - rimraf: 3.0.2 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 - typescript: 5.3.3 + typescript: 5.2.2 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug - - encoding + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/core-tracing.tgz: - resolution: {integrity: sha512-NBH2ccsB+stxZdNlyyWx7pf1fW5Jx43oZbLRusWg8pRTGvhG7/Bd6sbbqBvyKZtOQNQPgkNMrPaKJuMiwA4LiA==, tarball: file:projects/core-tracing.tgz} + resolution: {integrity: sha512-R1YPBfJRbnDsUtURM8BeyglkiuCu8hSnDtxIhKcqtggAfxCPVJCrHkFOza/vCydFldOZ59mMy2u99JxoEG5uCw==, tarball: file:projects/core-tracing.tgz} name: '@rush-temp/core-tracing' version: 0.0.0 dependencies: @@ -18140,6 +18343,8 @@ packages: '@types/mocha': 10.0.6 '@types/node': 18.19.14 '@types/sinon': 17.0.3 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 cross-env: 7.0.3 eslint: 8.56.0 @@ -18154,32 +18359,46 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 sinon: 17.0.1 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 util: 0.12.5 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/core-util.tgz: - resolution: {integrity: sha512-2tHqjTT6bvLqM8sxxZhFflAAxpiimTbqWceE8v0o1haQMH/dYj5htgkKIlpzv7m5hYTEM1+G0xqaeg/R+2f6oA==, tarball: file:projects/core-util.tgz} + resolution: {integrity: sha512-Y6INME+i05ZuVc42gHW0DzG/lJIQE3PkRSI95oq2FkbqDM9atXJZch1dbN2Lk9d/eK2w0LC/nTcSqB/hO8HbWg==, tarball: file:projects/core-util.tgz} name: '@rush-temp/core-util' version: 0.0.0 dependencies: '@microsoft/api-extractor': 7.39.5(@types/node@18.19.14) '@types/node': 18.19.14 '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) eslint: 8.56.0 playwright: 1.41.2 - rimraf: 3.0.2 + prettier: 3.2.5 + rimraf: 5.0.5 + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) @@ -18200,7 +18419,7 @@ packages: dev: false file:projects/core-xml.tgz: - resolution: {integrity: sha512-fplIoYvTiZo9RkFVzYIW0JqhC6i4SeqGewhLcJFruTbBgvpqrSt826S990Yx2O/sRFuqQJY9a1j7tsdtGOwQkA==, tarball: file:projects/core-xml.tgz} + resolution: {integrity: sha512-kA9N+dwE/LH47qRSMQ3XL9/wUJ+yQVEJoFWsO2jRhFa8r0AxIcLr+yVtGDbRNE22DVQicoYXbKMvn5lfQczv2Q==, tarball: file:projects/core-xml.tgz} name: '@rush-temp/core-xml' version: 0.0.0 dependencies: @@ -18209,6 +18428,8 @@ packages: '@types/mocha': 10.0.6 '@types/node': 18.19.14 '@types/trusted-types': 2.0.7 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 cross-env: 7.0.3 eslint: 8.56.0 @@ -18224,18 +18445,29 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 - rimraf: 3.0.2 + playwright: 1.41.2 + prettier: 3.2.5 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 util: 0.12.5 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/cosmos.tgz: @@ -19407,7 +19639,7 @@ packages: dev: false file:projects/logger.tgz: - resolution: {integrity: sha512-o8R6+QSwNNqFvN3yPZeuzryPXS5D4el63qrGwcv8H2pri8EA0q145hOHl+Q+uKjVuxZWSVljfZD7NbuGPm3i9Q==, tarball: file:projects/logger.tgz} + resolution: {integrity: sha512-+LoU5v1HOljNcaU5YYBKmjt0CrfrcKS1dxDGqUVTIpc0jAUMg2Efi1FVT51DjTEib0f3j2BKkECCDZn7M61UXw==, tarball: file:projects/logger.tgz} name: '@rush-temp/logger' version: 0.0.0 dependencies: @@ -19416,6 +19648,8 @@ packages: '@types/mocha': 10.0.6 '@types/node': 18.19.14 '@types/sinon': 17.0.3 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) c8: 8.0.1 chai: 4.3.10 cross-env: 7.0.3 @@ -19431,20 +19665,30 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 + playwright: 1.41.2 + prettier: 3.2.5 puppeteer: 22.0.0(typescript@5.3.3) - rimraf: 3.0.2 + rimraf: 5.0.5 sinon: 17.0.1 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug - - encoding + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/maps-common.tgz: @@ -19974,7 +20218,7 @@ packages: dev: false file:projects/openai-assistants.tgz: - resolution: {integrity: sha512-ylSkGDLi7sv7WZkt8ZvUDFrwX1t8nvAaAKhyKI9I/tIE5zajBroPU9pW0gQn+hfpvcL+VNIOfX3xiILKnuu0zA==, tarball: file:projects/openai-assistants.tgz} + resolution: {integrity: sha512-sAmQpau4Yt0j6ZWlakq60s7g0PJlloqpTh3opxH6LgYqH5ZMNQVHFUaoAHVVCEj4y7Al/hF68AfuyOYt8yX2LA==, tarball: file:projects/openai-assistants.tgz} name: '@rush-temp/openai-assistants' version: 0.0.0 dependencies: @@ -20220,7 +20464,7 @@ packages: dev: false file:projects/perf-core-rest-pipeline.tgz: - resolution: {integrity: sha512-FSxsbCaTZBDfL4/OyAawE3MC51c6eNb95XrhiC7iWLi16eC1wo78fUZm6PPHdm+1X8sWLi7zLoHOVOkGcUp7Cg==, tarball: file:projects/perf-core-rest-pipeline.tgz} + resolution: {integrity: sha512-d4G9rQMyMyIAfEwY9p+m6QCM9OTaEjS8/pvg89QnJRW56qqxRwI64iGfApGfQX55YXqdtLM+m4Q+a+dR8Uq/mA==, tarball: file:projects/perf-core-rest-pipeline.tgz} name: '@rush-temp/perf-core-rest-pipeline' version: 0.0.0 dependencies: @@ -20231,7 +20475,8 @@ packages: dotenv: 16.4.1 eslint: 8.56.0 express: 4.18.2 - rimraf: 3.0.2 + prettier: 2.8.8 + rimraf: 5.0.5 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) tslib: 2.6.2 typescript: 5.3.3 @@ -21831,7 +22076,7 @@ packages: dev: false file:projects/ts-http-runtime.tgz: - resolution: {integrity: sha512-x/Tbt2f58Xli8JDy1l8YzBrYAgtg1HdqH/ncNTR5vTUyZAoOzfvzLDPCa4vt5r0joSAhRicLn2PXX7hpLOD7yQ==, tarball: file:projects/ts-http-runtime.tgz} + resolution: {integrity: sha512-lFJQ9ZtxAp9AECs8vgj6/+U//6TFzhrhnhnBeDFKeUAP5cpTpypwFoAfTCrttvF7Xqrc/sc1322LzrGbUU5b4g==, tarball: file:projects/ts-http-runtime.tgz} name: '@rush-temp/ts-http-runtime' version: 0.0.0 dependencies: @@ -21842,6 +22087,8 @@ packages: '@types/mocha': 10.0.6 '@types/node': 18.19.14 '@types/sinon': 17.0.3 + '@vitest/browser': 1.2.2(playwright@1.41.2)(vitest@1.2.2) + '@vitest/coverage-istanbul': 1.2.2(vitest@1.2.2) chai: 4.3.10 chai-as-promised: 7.1.1(chai@4.3.10) cross-env: 7.0.3 @@ -21860,21 +22107,31 @@ packages: karma-mocha-reporter: 2.2.5(karma@6.4.2) karma-sourcemap-loader: 0.3.8 mocha: 10.2.0 + playwright: 1.41.2 + prettier: 3.2.5 puppeteer: 22.0.0(typescript@5.3.3) - rimraf: 3.0.2 + rimraf: 5.0.5 sinon: 17.0.1 ts-node: 10.9.2(@types/node@18.19.14)(typescript@5.3.3) + tshy: 1.11.0 tslib: 2.6.2 typescript: 5.3.3 util: 0.12.5 + vitest: 1.2.2(@types/node@18.19.14)(@vitest/browser@1.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - bufferutil - - debug - - encoding + - '@edge-runtime/vm' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - lightningcss + - safaridriver + - sass + - stylus + - sugarss - supports-color - - utf-8-validate + - terser + - webdriverio dev: false file:projects/vite-plugin-browser-test-map.tgz: diff --git a/common/tools/dev-tool/src/commands/run/build-test.ts b/common/tools/dev-tool/src/commands/run/build-test.ts new file mode 100644 index 000000000000..5fcda0e59c5d --- /dev/null +++ b/common/tools/dev-tool/src/commands/run/build-test.ts @@ -0,0 +1,221 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import path from "node:path"; +import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs"; +import { leafCommand, makeCommandInfo } from "../../framework/command"; +import { createPrinter } from "../../util/printer"; +import { resolveProject } from "../../util/resolveProject"; +import { spawnSync } from "node:child_process"; + +const log = createPrinter("build-test"); + +export const commandInfo = makeCommandInfo("build-test", "build a package for testing", { + "browser-test": { + kind: "boolean", + default: true, + description: "build a bundle for browser testing", + }, + "browser-config": { + kind: "string", + default: "tsconfig.browser.config.json", + description: "path to the browser config file", + }, +}); + +export default leafCommand(commandInfo, async (options) => { + const browserTest = options["browser-test"]; + const browserConfig = options["browser-config"]; + + const info = await resolveProject(process.cwd()); + + let moduleField = info.packageJson.module; + if (!moduleField) { + const defaultExport = info.packageJson.exports?.["."]?.import as any; + if (defaultExport) { + moduleField = defaultExport?.default; + } + } + + if (!moduleField) { + log.error(info.name, "does not specify a `module` field or `exports` top level field."); + return false; + } + + // Read the imports + const importMap = new Map(); + const importField = (info.packageJson as any)?.imports; + if (importField) { + const keys = Object.keys(importField); + for (const key of keys) { + importMap.set(key, importField[key]); + } + } + + // Build the overrides - hard code to browser for now + const overrides = new Map(); + overrides.set("esm", new OverrideSet("esm", "browser")); + const sources = new Set(getSources()); + for (const file of sources) { + for (const override of overrides.values()) { + override.addOverride(file, sources); + } + } + + for (const [name, pf] of overrides.entries()) { + if (pf.map.size === 0) { + overrides.delete(name); + } + } + + if (browserTest) { + // Test for valid file + if (!existsSync(browserConfig)) { + log.error(`The file ${browserConfig} does not exist.`); + return false; + } + + const browserConfigStat = statSync(browserConfig); + if (!browserConfigStat.isFile()) { + log.error(`The file ${browserConfig} does not exist.`); + return false; + } + + log.info(`Building for browser testing...`); + const esmMap = overrides.has("esm") ? overrides.get("esm")!.map : new Map(); + compileForEnvironment("browser", browserConfig, importMap, esmMap); + } + + return true; +}); + +function compileForEnvironment( + type: string, + tsConfig: string, + importMap: Map, + overrideMap: Map, +): boolean { + const tsconfigPath = path.join(process.cwd(), tsConfig); + const tsConfigFile = readFileSync(tsconfigPath, "utf8"); + const tsConfigJSON = JSON.parse(tsConfigFile); + const outputPath = tsConfigJSON.compilerOptions.outDir; + if (!existsSync(tsconfigPath)) { + log.error(`TypeScript config ${tsConfig} does not exist`); + return false; + } + + const browserTestPath = path.join(process.cwd(), outputPath); + if (!existsSync(browserTestPath)) { + mkdirSync(browserTestPath, { recursive: true }); + } + + // Create import map + const imports: Record = {}; + for (const [key, value] of importMap.entries()) { + imports[key] = value; + } + + const packageJson = { + type: "module", + imports, + }; + writeFileSync(path.join(browserTestPath, "package.json"), JSON.stringify(packageJson, null, 2)); + + const res = spawnSync(`tsc -p ${tsConfig}`, [], { + stdio: "inherit", + shell: true, + cwd: process.cwd(), + }); + + if (res.status || res.signal) { + log.error(res); + return false; + } + + for (const [override, original] of overrideMap.entries()) { + log.info(`Replacing for : ${original} => ${override}`); + copyOverrides(type, outputPath, original); + } + + return true; +} + +function copyOverrides(type: string, rootDir: string, filePath: string): void { + const fileParsed = path.parse(filePath); + const fileToReplace = path.join(process.cwd(), path.normalize(fileParsed.dir)); + const fileToReplaceWith = path.join( + fileParsed.root, + fileParsed.dir, + `${fileParsed.name}-${type}.mts` + ); + if (existsSync(fileToReplace) && existsSync(fileToReplaceWith)) { + log.info(`Copying over ${fileToReplaceWith} to ${fileToReplace}`); + const relativeDir = path.relative(process.cwd(), fileParsed.dir); + + overrideFile( + rootDir, + relativeDir, + `${fileParsed.name}-${type}.d.mts`, + `${fileParsed.name}.d.ts` + ); + overrideFile( + rootDir, + relativeDir, + `${fileParsed.name}-${type}.d.mts.map`, + `${fileParsed.name}.d.ts.map` + ); + overrideFile(rootDir, relativeDir, `${fileParsed.name}-${type}.mjs`, `${fileParsed.name}.js`); + overrideFile( + rootDir, + relativeDir, + `${fileParsed.name}-${type}.mjs.map`, + `${fileParsed.name}.js.map` + ); + } +} + +function overrideFile( + rootDir: string, + relativeDir: string, + sourceFile: string, + destinationFile: string +): void { + const sourceFileType = path.join(process.cwd(), rootDir, relativeDir, sourceFile); + const destFileType = path.join(process.cwd(), rootDir, relativeDir, destinationFile); + + cpSync(sourceFileType, destFileType, { force: true }); +} + +class OverrideSet { + public map: Map; + + constructor(public type: "esm" | "commonjs", public name: string) { + this.map = new Map(); + } + + addOverride(file: string, sources: Set) { + const extension = this.type === "esm" ? "mts" : "cts"; + const suffix = `-${this.name}.${extension}`; + if (!file.endsWith(suffix)) { + return; + } + const originalFile = file.substring(0, file.length - suffix.length) + ".ts"; + if (sources.has(originalFile)) { + this.map.set(file, originalFile); + } + } +} + +function getSources(dir: string = "src"): string[] { + const sources: string[] = []; + const entries = readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory()) { + sources.push(...getSources(path.join(dir, entry.name))); + } else if (entry.isFile()) { + sources.push(path.join(dir, entry.name)); + } + } + + return sources; +} diff --git a/common/tools/dev-tool/src/commands/run/bundle.ts b/common/tools/dev-tool/src/commands/run/bundle.ts index 42250327c2ae..fb9c0ba65665 100644 --- a/common/tools/dev-tool/src/commands/run/bundle.ts +++ b/common/tools/dev-tool/src/commands/run/bundle.ts @@ -76,20 +76,28 @@ export default leafCommand(commandInfo, async (options) => { const info = await resolveProject(process.cwd()); - if (!info.packageJson.module) { - log.error(info.name, "does not specify a `module` field."); + let moduleField = info.packageJson.module; + if (!moduleField) { + const defaultExport = info.packageJson.exports?.["."]?.import as any; + if (defaultExport) { + moduleField = defaultExport?.default; + } + } + + if (!moduleField) { + log.error(info.name, "does not specify a `module` field or `exports` top level field."); return false; } const basePath = path - .relative(process.cwd(), path.dirname(path.parse(info.packageJson.module).dir)) + .relative(process.cwd(), path.dirname(path.parse(moduleField).dir)) .split(path.sep) .join("/"); if (options.production) { const baseConfig: rollup.RollupOptions = { // Use the package's module field if it has one - input: info.packageJson.module, + input: moduleField, external: [ ...nodeBuiltins, ...Object.keys(info.packageJson.dependencies), diff --git a/common/tools/dev-tool/src/commands/run/index.ts b/common/tools/dev-tool/src/commands/run/index.ts index 25b51597fb06..1c9cc35c2a04 100644 --- a/common/tools/dev-tool/src/commands/run/index.ts +++ b/common/tools/dev-tool/src/commands/run/index.ts @@ -13,6 +13,7 @@ export default subCommand(commandInfo, { "check-api": () => import("./check-api"), "extract-api": () => import("./extract-api"), bundle: () => import("./bundle"), + "build-test": () => import("./build-test"), // "vendored" is a special command that passes through execution to dev-tool's own commands vendored: () => import("./vendored"), diff --git a/common/tools/dev-tool/src/commands/run/testVitest.ts b/common/tools/dev-tool/src/commands/run/testVitest.ts index 7c6772335927..20e83160b70a 100644 --- a/common/tools/dev-tool/src/commands/run/testVitest.ts +++ b/common/tools/dev-tool/src/commands/run/testVitest.ts @@ -44,14 +44,13 @@ export default leafCommand(commandInfo, async (options) => { await playwrightInstall(); } - const reporterArgs = `--reporter=verbose --reporter=junit --outputFile=test-results${options["browser"] ? ".browser" : ""}.xml`; - const args = options["browser"] ? "-c vitest.browser.config.mts" : ""; + const args = options["browser"] ? "-c vitest.browser.config.ts" : ""; const updatedArgs = options["--"]?.map((opt) => opt.includes("**") && !opt.startsWith("'") && !opt.startsWith('"') ? `"${opt}"` : opt, ); const vitestArgs = updatedArgs?.length ? updatedArgs.join(" ") : ""; const command = { - command: `vitest ${reporterArgs} ${args} ${vitestArgs}`, + command: `vitest ${args} ${vitestArgs}`, name: "vitest", }; diff --git a/sdk/.eslintrc.json b/sdk/.eslintrc.json index a26419d4d49d..ce844818d028 100644 --- a/sdk/.eslintrc.json +++ b/sdk/.eslintrc.json @@ -1,5 +1,10 @@ { "plugins": ["@azure/azure-sdk"], "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], - "ignorePatterns": ["**/test/perf/track-1"] + "ignorePatterns": ["**/test/perf/track-1"], + "rules": { + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-files-required": "off", + "@azure/azure-sdk/ts-package-json-main-is-cjs": "off", + "@azure/azure-sdk/ts-package-json-types": "off"} } diff --git a/sdk/core/abort-controller/.eslintrc.json b/sdk/core/abort-controller/.eslintrc.json index e71d23ff6f57..e5855730fa1b 100644 --- a/sdk/core/abort-controller/.eslintrc.json +++ b/sdk/core/abort-controller/.eslintrc.json @@ -2,6 +2,10 @@ "plugins": ["@azure/azure-sdk"], "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], "rules": { - "@azure/azure-sdk/ts-package-json-types": "off" + "@azure/azure-sdk/ts-package-json-types": "off", + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-main-is-cjs": "off", + "@azure/azure-sdk/ts-package-json-files-required": "off", + "@azure/azure-sdk/ts-package-json-engine-is-present": "off" } } diff --git a/sdk/core/abort-controller/.tshy/browser.json b/sdk/core/abort-controller/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/abort-controller/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/abort-controller/.tshy/build.json b/sdk/core/abort-controller/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/abort-controller/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/abort-controller/.tshy/commonjs.json b/sdk/core/abort-controller/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/abort-controller/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/abort-controller/.tshy/esm.json b/sdk/core/abort-controller/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/abort-controller/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/abort-controller/.tshy/react-native.json b/sdk/core/abort-controller/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/abort-controller/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/abort-controller/api-extractor.json b/sdk/core/abort-controller/api-extractor.json index 8265070b9a1f..afa2f2217c45 100644 --- a/sdk/core/abort-controller/api-extractor.json +++ b/sdk/core/abort-controller/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "./dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/abort-controller.d.ts" + "publicTrimmedFilePath": "./dist/abort-controller.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/abort-controller/karma.conf.js b/sdk/core/abort-controller/karma.conf.js deleted file mode 100644 index 7b9e227715fa..000000000000 --- a/sdk/core/abort-controller/karma.conf.js +++ /dev/null @@ -1,107 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); -require("dotenv").config({ path: "../.env" }); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-junit-reporter", - "karma-sourcemap-loader", - ], - - // list of files / patterns to load in the browser - files: [ - "dist-test/index.browser.js", - { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true }, - ], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/abort-controller/package.json b/sdk/core/abort-controller/package.json index c376fffb4e8f..2c8150cad33d 100644 --- a/sdk/core/abort-controller/package.json +++ b/sdk/core/abort-controller/package.json @@ -3,43 +3,46 @@ "sdk-type": "client", "version": "2.0.1", "description": "Microsoft Azure SDK for JavaScript - Aborter", - "main": "./dist/index.js", - "module": "dist-esm/src/index.js", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md", + "repository": "github:Azure/azure-sdk-for-js", + "sideEffects": false, + "type": "module", + "main": "./dist/commonjs/index.js", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, - "types": "./types/src/index.d.ts", + "types": "./dist/commonjs/index.d.ts", "files": [ "dist/", - "dist-esm/src/", - "shims-public.d.ts", - "types/src", "README.md", "LICENSE" ], "engines": { "node": ">=18.0.0" }, - "repository": "github:Azure/azure-sdk-for-js", "keywords": [ "azure", "aborter", @@ -51,42 +54,61 @@ "browser", "cloud" ], - "author": "Microsoft Corporation", - "license": "MIT", - "bugs": { - "url": "https://github.com/Azure/azure-sdk-for-js/issues" + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" }, - "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md", - "sideEffects": false, "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "c8": "^8.0.0", - "rimraf": "^3.0.0", - "ts-node": "^10.0.0", - "typescript": "~5.3.3" + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", + "typescript": "~5.3.3", + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/abort-controller/shims-public.d.ts b/sdk/core/abort-controller/shims-public.d.ts deleted file mode 100644 index 002bec375f33..000000000000 --- a/sdk/core/abort-controller/shims-public.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -// forward declaration of Event in case DOM libs are not present. -interface Event {} diff --git a/sdk/core/abort-controller/src/index.ts b/sdk/core/abort-controller/src/index.ts index f22e413114b8..91a77fce5e23 100644 --- a/sdk/core/abort-controller/src/index.ts +++ b/sdk/core/abort-controller/src/index.ts @@ -1,5 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { AbortError } from "./AbortError"; -export { AbortSignalLike } from "./AbortSignalLike"; +declare global { + interface Event {} +} + +export { AbortError } from "./AbortError.js"; +export { AbortSignalLike } from "./AbortSignalLike.js"; diff --git a/sdk/core/abort-controller/test/aborter.spec.ts b/sdk/core/abort-controller/test/aborter.spec.ts index bd527ec064d8..f53e3409f92e 100644 --- a/sdk/core/abort-controller/test/aborter.spec.ts +++ b/sdk/core/abort-controller/test/aborter.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortError, AbortSignalLike } from "../src"; -import { assert } from "chai"; +import { AbortError, AbortSignalLike } from "../src/index.js"; +import { describe, it, assert } from "vitest"; describe("AbortSignalLike", () => { it("is compatible with the standard AbortSignal", () => { diff --git a/sdk/core/abort-controller/tsconfig.browser.config.json b/sdk/core/abort-controller/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/abort-controller/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/abort-controller/tsconfig.json b/sdk/core/abort-controller/tsconfig.json index 4e6c254ba490..11995de4bc8e 100644 --- a/sdk/core/abort-controller/tsconfig.json +++ b/sdk/core/abort-controller/tsconfig.json @@ -1,9 +1,12 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "declarationDir": "./types", - "outDir": "./dist-esm" + "paths": { + "@azure/abort-controller": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "exclude": ["node_modules", "./types/**/*.d.ts", "./samples/**/*.ts"], - "include": ["./src/**/*.ts", "./test/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/abort-controller/vitest.browser.config.ts b/sdk/core/abort-controller/vitest.browser.config.ts new file mode 100644 index 000000000000..005a2f7d4b67 --- /dev/null +++ b/sdk/core/abort-controller/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/abort-controller/vitest.config.ts b/sdk/core/abort-controller/vitest.config.ts new file mode 100644 index 000000000000..e94c7dd91c76 --- /dev/null +++ b/sdk/core/abort-controller/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-amqp/src/util/runtimeInfo.ts b/sdk/core/core-amqp/src/util/runtimeInfo.ts index 019c1e4befc2..226080b94a09 100644 --- a/sdk/core/core-amqp/src/util/runtimeInfo.ts +++ b/sdk/core/core-amqp/src/util/runtimeInfo.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as os from "os"; +import * as os from "node:os"; /** * Returns information about the platform this function is being run on. diff --git a/sdk/core/core-auth/.tshy/browser.json b/sdk/core/core-auth/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-auth/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-auth/.tshy/build.json b/sdk/core/core-auth/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-auth/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-auth/.tshy/commonjs.json b/sdk/core/core-auth/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/core-auth/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-auth/.tshy/esm.json b/sdk/core/core-auth/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/core-auth/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-auth/.tshy/react-native.json b/sdk/core/core-auth/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/core-auth/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-auth/api-extractor.json b/sdk/core/core-auth/api-extractor.json index 9ba08984e174..6ab753a81c62 100644 --- a/sdk/core/core-auth/api-extractor.json +++ b/sdk/core/core-auth/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-auth.d.ts" + "publicTrimmedFilePath": "./dist/core-auth.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-auth/package.json b/sdk/core/core-auth/package.json index b44bee37a2e0..7ebcb0cf1fbf 100644 --- a/sdk/core/core-auth/package.json +++ b/sdk/core/core-auth/package.json @@ -3,35 +3,32 @@ "version": "1.6.1", "description": "Provides low-level interfaces and helper methods for authentication in Azure SDK", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "types": "./types/latest/core-auth.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "echo skipped", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", "files": [ "dist/", - "dist-esm/src/", - "types/latest/core-auth.d.ts", "README.md", "LICENSE" ], @@ -51,29 +48,63 @@ }, "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-auth/README.md", "sideEffects": false, + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.1.0", - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", "eslint": "^8.0.0", - "inherits": "^2.0.3", - "mocha": "^10.0.0", - "rimraf": "^3.0.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "util": "^0.12.1", - "ts-node": "^10.0.0" + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-auth/samples/.gitkeep b/sdk/core/core-auth/samples/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sdk/core/core-auth/src/azureKeyCredential.ts b/sdk/core/core-auth/src/azureKeyCredential.ts index 1371bd249946..af0e6d92b8b6 100644 --- a/sdk/core/core-auth/src/azureKeyCredential.ts +++ b/sdk/core/core-auth/src/azureKeyCredential.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { KeyCredential } from "./keyCredential"; +import { KeyCredential } from "./keyCredential.js"; /** * A static-key-based credential that supports updating diff --git a/sdk/core/core-auth/src/index.ts b/sdk/core/core-auth/src/index.ts index ea8f14018787..0ff0e82007d2 100644 --- a/sdk/core/core-auth/src/index.ts +++ b/sdk/core/core-auth/src/index.ts @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { AzureKeyCredential } from "./azureKeyCredential"; -export { KeyCredential, isKeyCredential } from "./keyCredential"; +export { AzureKeyCredential } from "./azureKeyCredential.js"; +export { KeyCredential, isKeyCredential } from "./keyCredential.js"; export { AzureNamedKeyCredential, NamedKeyCredential, isNamedKeyCredential, -} from "./azureNamedKeyCredential"; -export { AzureSASCredential, SASCredential, isSASCredential } from "./azureSASCredential"; +} from "./azureNamedKeyCredential.js"; +export { AzureSASCredential, SASCredential, isSASCredential } from "./azureSASCredential.js"; export { TokenCredential, GetTokenOptions, AccessToken, isTokenCredential, -} from "./tokenCredential"; +} from "./tokenCredential.js"; -export { TracingContext } from "./tracing"; +export { TracingContext } from "./tracing.js"; diff --git a/sdk/core/core-auth/src/tokenCredential.ts b/sdk/core/core-auth/src/tokenCredential.ts index 53861c29d61a..aeb30286b9aa 100644 --- a/sdk/core/core-auth/src/tokenCredential.ts +++ b/sdk/core/core-auth/src/tokenCredential.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { AbortSignalLike } from "@azure/abort-controller"; -import { TracingContext } from "./tracing"; +import { TracingContext } from "./tracing.js"; /** * Represents a credential capable of providing an authentication token. diff --git a/sdk/core/core-auth/test/index.spec.ts b/sdk/core/core-auth/test/index.spec.ts index f05d70ac702d..b83d7d4ab81f 100644 --- a/sdk/core/core-auth/test/index.spec.ts +++ b/sdk/core/core-auth/test/index.spec.ts @@ -9,8 +9,8 @@ import { isNamedKeyCredential, isSASCredential, isTokenCredential, -} from "../src/index"; -import { assert } from "chai"; +} from "../src/index.js"; +import { describe, it, assert } from "vitest"; describe("AzureKeyCredential", () => { it("credential constructor throws on invalid key", () => { diff --git a/sdk/core/core-auth/tsconfig.browser.config.json b/sdk/core/core-auth/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-auth/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-auth/tsconfig.json b/sdk/core/core-auth/tsconfig.json index 4f5fa20b2111..e2be38a48288 100644 --- a/sdk/core/core-auth/tsconfig.json +++ b/sdk/core/core-auth/tsconfig.json @@ -1,7 +1,12 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "declarationDir": "./types", - "outDir": "./dist-esm" - } + "paths": { + "@azure/core-auth": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." + }, + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/core-auth/vitest.browser.config.ts b/sdk/core/core-auth/vitest.browser.config.ts new file mode 100644 index 000000000000..a069e1a00e08 --- /dev/null +++ b/sdk/core/core-auth/vitest.browser.config.ts @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + slowHijackESM: false, + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-auth/vitest.config.ts b/sdk/core/core-auth/vitest.config.ts new file mode 100644 index 000000000000..e94c7dd91c76 --- /dev/null +++ b/sdk/core/core-auth/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-client-rest/.tshy/browser.json b/sdk/core/core-client-rest/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-client-rest/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-client-rest/.tshy/build.json b/sdk/core/core-client-rest/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-client-rest/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-client-rest/.tshy/commonjs.json b/sdk/core/core-client-rest/.tshy/commonjs.json new file mode 100644 index 000000000000..ae3ede446c84 --- /dev/null +++ b/sdk/core/core-client-rest/.tshy/commonjs.json @@ -0,0 +1,15 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/helpers/isReadableStream-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-client-rest/.tshy/esm.json b/sdk/core/core-client-rest/.tshy/esm.json new file mode 100644 index 000000000000..29841e01bfbf --- /dev/null +++ b/sdk/core/core-client-rest/.tshy/esm.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/helpers/isReadableStream-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-client-rest/.tshy/react-native.json b/sdk/core/core-client-rest/.tshy/react-native.json new file mode 100644 index 000000000000..bedd55a0df32 --- /dev/null +++ b/sdk/core/core-client-rest/.tshy/react-native.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/helpers/isReadableStream-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-client-rest/api-extractor.json b/sdk/core/core-client-rest/api-extractor.json index 26337c79ce43..be9b07536365 100644 --- a/sdk/core/core-client-rest/api-extractor.json +++ b/sdk/core/core-client-rest/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-client-rest.d.ts" + "publicTrimmedFilePath": "./dist/core-client-rest.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-client-rest/karma.conf.js b/sdk/core/core-client-rest/karma.conf.js deleted file mode 100644 index 5882b35ea001..000000000000 --- a/sdk/core/core-client-rest/karma.conf.js +++ /dev/null @@ -1,114 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: ["dist-test/index.browser.js"], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - // EXAMPLE: envPreprocessor: ["ACCOUNT_NAME", "ACCOUNT_SAS"], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadlessNoSandbox"], - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: "ChromeHeadless", - flags: ["--no-sandbox"], - }, - }, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-client-rest/package.json b/sdk/core/core-client-rest/package.json index 60489a77ad07..43e2e265acbc 100644 --- a/sdk/core/core-client-rest/package.json +++ b/sdk/core/core-client-rest/package.json @@ -3,38 +3,32 @@ "version": "1.2.1", "description": "Core library for interfacing with Azure Rest Clients", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/helpers/isReadableStream.js": "./dist-esm/src/helpers/isReadableStream.browser.js" - }, - "types": "types/latest/core-client-rest.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/latest/core-client-rest.d.ts", "README.md", "LICENSE" ], @@ -54,42 +48,66 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-client-rest/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { "@azure/core-auth": "^1.3.0", "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-util": "^1.0.0", "@azure/abort-controller": "^2.0.0", "@azure/core-tracing": "^1.0.1", - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "@types/sinon": "^17.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "inherits": "^2.0.3", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-mocha": "^2.0.1", - "karma-sourcemap-loader": "^0.3.8", - "karma": "^6.2.0", - "mocha": "^10.0.0", - "rimraf": "^3.0.0", - "sinon": "^17.0.0", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.55.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "ts-node": "^10.0.0" + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-client-rest/src/apiVersionPolicy.ts b/sdk/core/core-client-rest/src/apiVersionPolicy.ts index dab0d5dd7b55..7e29abac08b6 100644 --- a/sdk/core/core-client-rest/src/apiVersionPolicy.ts +++ b/sdk/core/core-client-rest/src/apiVersionPolicy.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { PipelinePolicy } from "@azure/core-rest-pipeline"; -import { ClientOptions } from "./common"; +import { ClientOptions } from "./common.js"; export const apiVersionPolicyName = "ApiVersionPolicy"; diff --git a/sdk/core/core-client-rest/src/clientHelpers.ts b/sdk/core/core-client-rest/src/clientHelpers.ts index 7932446fcc15..7bfaaff89a68 100644 --- a/sdk/core/core-client-rest/src/clientHelpers.ts +++ b/sdk/core/core-client-rest/src/clientHelpers.ts @@ -10,9 +10,9 @@ import { } from "@azure/core-rest-pipeline"; import { KeyCredential, TokenCredential, isTokenCredential } from "@azure/core-auth"; -import { ClientOptions } from "./common"; -import { apiVersionPolicy } from "./apiVersionPolicy"; -import { keyCredentialAuthenticationPolicy } from "./keyCredentialAuthenticationPolicy"; +import { ClientOptions } from "./common.js"; +import { apiVersionPolicy } from "./apiVersionPolicy.js"; +import { keyCredentialAuthenticationPolicy } from "./keyCredentialAuthenticationPolicy.js"; let cachedHttpClient: HttpClient | undefined; diff --git a/sdk/core/core-client-rest/src/getClient.ts b/sdk/core/core-client-rest/src/getClient.ts index 86448ac0411d..fd44bbb43f6b 100644 --- a/sdk/core/core-client-rest/src/getClient.ts +++ b/sdk/core/core-client-rest/src/getClient.ts @@ -3,7 +3,7 @@ import { KeyCredential, TokenCredential, isTokenCredential } from "@azure/core-auth"; import { HttpClient, HttpMethods, Pipeline, PipelineOptions } from "@azure/core-rest-pipeline"; -import { createDefaultPipeline } from "./clientHelpers"; +import { createDefaultPipeline } from "./clientHelpers.js"; import { Client, ClientOptions, @@ -11,9 +11,9 @@ import { HttpNodeStreamResponse, RequestParameters, StreamableMethod, -} from "./common"; -import { sendRequest } from "./sendRequest"; -import { buildRequestUrl } from "./urlHelpers"; +} from "./common.js"; +import { sendRequest } from "./sendRequest.js"; +import { buildRequestUrl } from "./urlHelpers.js"; /** * Creates a client with a default pipeline diff --git a/sdk/core/core-client-rest/src/helpers/isReadableStream.browser.ts b/sdk/core/core-client-rest/src/helpers/isReadableStream-browser.mts similarity index 100% rename from sdk/core/core-client-rest/src/helpers/isReadableStream.browser.ts rename to sdk/core/core-client-rest/src/helpers/isReadableStream-browser.mts diff --git a/sdk/core/core-client-rest/src/index.ts b/sdk/core/core-client-rest/src/index.ts index 046849c9f07b..f7dc55e71ec9 100644 --- a/sdk/core/core-client-rest/src/index.ts +++ b/sdk/core/core-client-rest/src/index.ts @@ -6,8 +6,11 @@ * @packageDocumentation */ -export { createRestError } from "./restError"; -export { addCredentialPipelinePolicy, AddCredentialPipelinePolicyOptions } from "./clientHelpers"; -export { operationOptionsToRequestParameters } from "./operationOptionHelpers"; -export * from "./getClient"; -export * from "./common"; +export { createRestError } from "./restError.js"; +export { + addCredentialPipelinePolicy, + AddCredentialPipelinePolicyOptions, +} from "./clientHelpers.js"; +export { operationOptionsToRequestParameters } from "./operationOptionHelpers.js"; +export * from "./getClient.js"; +export * from "./common.js"; diff --git a/sdk/core/core-client-rest/src/operationOptionHelpers.ts b/sdk/core/core-client-rest/src/operationOptionHelpers.ts index 21cb63127a52..d4a3fb666612 100644 --- a/sdk/core/core-client-rest/src/operationOptionHelpers.ts +++ b/sdk/core/core-client-rest/src/operationOptionHelpers.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { OperationOptions, RequestParameters } from "./common"; +import { OperationOptions, RequestParameters } from "./common.js"; /** * Helper function to convert OperationOptions to RequestParameters diff --git a/sdk/core/core-client-rest/src/restError.ts b/sdk/core/core-client-rest/src/restError.ts index a4b6d1d809bf..786539b0a407 100644 --- a/sdk/core/core-client-rest/src/restError.ts +++ b/sdk/core/core-client-rest/src/restError.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { PipelineResponse, RestError, createHttpHeaders } from "@azure/core-rest-pipeline"; -import { PathUncheckedResponse } from "./common"; +import { PathUncheckedResponse } from "./common.js"; /** * Creates a rest error from a PathUnchecked response diff --git a/sdk/core/core-client-rest/src/sendRequest.ts b/sdk/core/core-client-rest/src/sendRequest.ts index 674abfa84113..01502436ac8c 100644 --- a/sdk/core/core-client-rest/src/sendRequest.ts +++ b/sdk/core/core-client-rest/src/sendRequest.ts @@ -15,9 +15,9 @@ import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline"; -import { getCachedDefaultHttpsClient } from "./clientHelpers"; -import { isReadableStream } from "./helpers/isReadableStream"; -import { HttpResponse, RequestParameters } from "./common"; +import { getCachedDefaultHttpsClient } from "./clientHelpers.js"; +import { isReadableStream } from "./helpers/isReadableStream.js"; +import { HttpResponse, RequestParameters } from "./common.js"; /** * Helper function to send request used by the client diff --git a/sdk/core/core-client-rest/src/urlHelpers.ts b/sdk/core/core-client-rest/src/urlHelpers.ts index 3ed6408a78a2..62bb97b7177a 100644 --- a/sdk/core/core-client-rest/src/urlHelpers.ts +++ b/sdk/core/core-client-rest/src/urlHelpers.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { RequestParameters } from "./common"; +import { RequestParameters } from "./common.js"; /** * Builds the request url, filling in query and path parameters diff --git a/sdk/core/core-client-rest/test/browser/streams.spec.ts b/sdk/core/core-client-rest/test/browser/streams.spec.ts index f66828e3a68c..d6b4dbd585ec 100644 --- a/sdk/core/core-client-rest/test/browser/streams.spec.ts +++ b/sdk/core/core-client-rest/test/browser/streams.spec.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { getClient } from "../../src/getClient"; -import sinon from "sinon"; +import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest"; +import { getClient } from "../../src/getClient.js"; function createResponse(statusCode: number, body = ""): Response { const stream = new ReadableStream({ @@ -29,18 +28,22 @@ function createResponse(statusCode: number, body = ""): Response { const mockBaseUrl = "https://example.org"; describe("[Browser] Streams", () => { - let fetchMock: sinon.SinonStub; beforeEach(() => { - fetchMock = sinon.stub(self, "fetch"); + vi.stubGlobal("fetch", vi.fn()); }); afterEach(() => { - sinon.restore(); + vi.restoreAllMocks(); + vi.unstubAllGlobals(); + if (vi.isFakeTimers()) { + vi.useRealTimers(); + } }); it("should get a JSON body response as a stream", async () => { const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + const fetchMock = vi.mocked(fetch); + fetchMock.mockResolvedValue(createResponse(200, responseText)); const client = getClient(mockBaseUrl); const result = await client.pathUnchecked("/foo").get().asBrowserStream(); @@ -48,24 +51,28 @@ describe("[Browser] Streams", () => { // Read the first chunk const chunk = await reader.read(); assert.equal(chunk.done, false); - assert.isTrue(fetchMock.calledOnce); + expect(fetchMock).toHaveBeenCalledOnce(); }); it("should get a JSON body response", async () => { const responseText = "An appropriate response."; const client = getClient(mockBaseUrl); - fetchMock.returns(createResponse(200, responseText)); + const fetchMock = vi.mocked(fetch); + fetchMock.mockResolvedValue(createResponse(200, responseText)); const result = await client.pathUnchecked("/foo").get(); assert.deepEqual(result.body, responseText); - assert.isTrue(fetchMock.calledOnce); + expect(fetchMock).toHaveBeenCalledOnce(); }); it("should be able to handle errors on normal response", async () => { const client = getClient(mockBaseUrl); - fetchMock.throwsException(new Error("ExpectedException")); + + const fetchMock = vi.mocked(fetch); + fetchMock.mockRejectedValue(new Error("ExpectedException")); + try { await client.pathUnchecked("/foo").get(); } catch (e: any) { @@ -75,7 +82,10 @@ describe("[Browser] Streams", () => { it("should be able to handle errors on streamed response", async () => { const client = getClient(mockBaseUrl); - fetchMock.throwsException(new Error("ExpectedException")); + + const fetchMock = vi.mocked(fetch); + fetchMock.mockRejectedValue(new Error("ExpectedException")); + try { await client.pathUnchecked("/foo").get().asNodeStream(); } catch (e: any) { diff --git a/sdk/core/core-client-rest/test/clientHelpers.spec.ts b/sdk/core/core-client-rest/test/clientHelpers.spec.ts index c159ea1f2e36..b70fb32b8015 100644 --- a/sdk/core/core-client-rest/test/clientHelpers.spec.ts +++ b/sdk/core/core-client-rest/test/clientHelpers.spec.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createDefaultPipeline } from "../src/clientHelpers"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { createDefaultPipeline } from "../src/clientHelpers.js"; import { bearerTokenAuthenticationPolicyName } from "@azure/core-rest-pipeline"; -import { keyCredentialAuthenticationPolicyName } from "../src/keyCredentialAuthenticationPolicy"; +import { keyCredentialAuthenticationPolicyName } from "../src/keyCredentialAuthenticationPolicy.js"; import { TokenCredential } from "@azure/core-auth"; -import { fail } from "assert"; -import { apiVersionPolicyName } from "../src/apiVersionPolicy"; +import { apiVersionPolicyName } from "../src/apiVersionPolicy.js"; + describe("clientHelpers", () => { const mockBaseUrl = "https://example.org"; it("should create a default pipeline with no credentials", () => { @@ -42,7 +42,7 @@ describe("clientHelpers", () => { it("should throw if key credentials but no Api Header Name", () => { try { createDefaultPipeline(mockBaseUrl, { key: "mockKey" }); - fail("Expected to throw an error"); + assert.fail("Expected to throw an error"); } catch (error: any) { assert.equal((error as Error).message, "Missing API Key Header Name"); } diff --git a/sdk/core/core-client-rest/test/createRestError.spec.ts b/sdk/core/core-client-rest/test/createRestError.spec.ts index d0ec198884fa..b832eccaa81d 100644 --- a/sdk/core/core-client-rest/test/createRestError.spec.ts +++ b/sdk/core/core-client-rest/test/createRestError.spec.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createRestError } from "../src/restError"; +import { createRestError } from "../src/restError.js"; import { PipelineRequest } from "@azure/core-rest-pipeline"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; describe("createRestError", () => { it("should create a rest error from a PathUnchecked response with standard error", () => { diff --git a/sdk/core/core-client-rest/test/getClient.spec.ts b/sdk/core/core-client-rest/test/getClient.spec.ts index b70f36035d25..b2a387fd07cc 100644 --- a/sdk/core/core-client-rest/test/getClient.spec.ts +++ b/sdk/core/core-client-rest/test/getClient.spec.ts @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { getCachedDefaultHttpsClient } from "../src/clientHelpers"; -import { getClient } from "../src/getClient"; -import sinon from "sinon"; +import { describe, it, assert, vi, afterEach } from "vitest"; +import { getCachedDefaultHttpsClient } from "../src/clientHelpers.js"; +import { getClient } from "../src/getClient.js"; import { HttpClient, PipelinePolicy, @@ -16,13 +15,13 @@ import { describe("getClient", () => { afterEach(() => { - sinon.restore(); + vi.restoreAllMocks(); }); describe("#apiVersionPolicy", () => { it("should add apiVersion to requests if apiVersion is absent", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, request: req } as PipelineResponse; }); @@ -42,7 +41,7 @@ describe("getClient", () => { it("should use operation-level apiVersion even if we config the client one", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, request: req } as PipelineResponse; }); @@ -70,7 +69,7 @@ describe("getClient", () => { it("should use apiVersion in url directly even if we config the client one", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, request: req } as PipelineResponse; }); @@ -94,7 +93,7 @@ describe("getClient", () => { it("should not encode url when skip query parameter encoding and api version parameter exists", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, @@ -123,7 +122,7 @@ describe("getClient", () => { it("should encode url when not skip query parameter encoding and api version parameter exists", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, @@ -152,7 +151,7 @@ describe("getClient", () => { it("should append api version correctly", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, @@ -175,7 +174,8 @@ describe("getClient", () => { }); it("should insert policies in the correct pipeline position", async function () { - const sendRequest = (request: PipelineRequest, next: SendRequest) => next(request); + const sendRequest = (request: PipelineRequest, next: SendRequest): Promise => + next(request); const retryPolicy: PipelinePolicy = { name: "retry", sendRequest, diff --git a/sdk/core/core-client-rest/test/node/streams.spec.ts b/sdk/core/core-client-rest/test/node/streams.spec.ts index 30aad454f90f..653d6c26a447 100644 --- a/sdk/core/core-client-rest/test/node/streams.spec.ts +++ b/sdk/core/core-client-rest/test/node/streams.spec.ts @@ -1,61 +1,75 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import https from "https"; -import { assert } from "chai"; -import { getClient } from "../../src/getClient"; -import sinon from "sinon"; -import { ClientRequest, IncomingHttpHeaders, IncomingMessage } from "http"; -import { PassThrough } from "stream"; +import { describe, it, assert, afterEach, vi } from "vitest"; +import { ClientRequest, type IncomingHttpHeaders, IncomingMessage } from "node:http"; +import { PassThrough } from "node:stream"; + +vi.mock("https", async () => { + const actual = await vi.importActual("https"); + return { + ...actual, + request: vi.fn(), + }; +}); + +import * as https from "https"; const mockBaseUrl = "https://example.org"; describe("[Node] Streams", () => { afterEach(() => { - sinon.restore(); - }); - - let stubbedHttpsRequest: sinon.SinonStub; - beforeEach(function () { - stubbedHttpsRequest = sinon.stub(https, "request"); + vi.resetAllMocks(); }); it("should get a JSON body response as a stream", async () => { + vi.mocked(https.request).mockImplementation((_url, cb) => { + const response = createResponse(200, JSON.stringify({ foo: "foo" })); + const callback = cb as (res: IncomingMessage) => void; + callback(response); + return createRequest(); + }); + + const { getClient } = await import("../../src/getClient.js"); + const client = getClient(mockBaseUrl); const expectedBody = { foo: "foo" }; - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const promise = client.pathUnchecked("/foo").get().asNodeStream(); - stubbedHttpsRequest.yield(createResponse(200, JSON.stringify(expectedBody))); - const response = await promise; const stringBody = await readStreamToBuffer(response.body!); assert.deepEqual(stringBody.toString(), JSON.stringify(expectedBody)); - assert.isTrue(stubbedHttpsRequest.calledOnce); }); it("should get a JSON body response", async () => { + vi.mocked(https.request).mockImplementation((_url, cb) => { + const response = createResponse(200, JSON.stringify({ foo: "foo" })); + const callback = cb as (res: IncomingMessage) => void; + callback(response); + return createRequest(); + }); + + const { getClient } = await import("../../src/getClient.js"); + const client = getClient(mockBaseUrl); const expectedBody = { foo: "foo" }; - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const promise = client.pathUnchecked("/foo").get(); - - stubbedHttpsRequest.yields(createResponse(200, JSON.stringify(expectedBody))); - const response = await promise; assert.deepEqual(response.body, expectedBody); - assert.isTrue(stubbedHttpsRequest.calledOnce); }); it("should be able to handle errors on normal response", async () => { + vi.mocked(https.request).mockImplementation(() => { + throw new Error("ExpectedException"); + }); + + const { getClient } = await import("../../src/getClient.js"); const client = getClient(mockBaseUrl); - stubbedHttpsRequest.throwsException(new Error("ExpectedException")); + try { await client.pathUnchecked("/foo").get(); } catch (e: any) { @@ -64,8 +78,13 @@ describe("[Node] Streams", () => { }); it("should be able to handle errors on streamed response", async () => { + vi.mocked(https.request).mockImplementation(() => { + throw new Error("ExpectedException"); + }); + + const { getClient } = await import("../../src/getClient.js"); const client = getClient(mockBaseUrl); - stubbedHttpsRequest.throwsException(new Error("ExpectedException")); + try { await client.pathUnchecked("/foo").get().asNodeStream(); } catch (e: any) { diff --git a/sdk/core/core-client-rest/test/sendRequest.spec.ts b/sdk/core/core-client-rest/test/sendRequest.spec.ts index 4aceb939020c..6ac4f861cc0a 100644 --- a/sdk/core/core-client-rest/test/sendRequest.spec.ts +++ b/sdk/core/core-client-rest/test/sendRequest.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { sendRequest } from "../src/sendRequest"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { sendRequest } from "../src/sendRequest.js"; import { FormDataValue, Pipeline, diff --git a/sdk/core/core-client-rest/test/urlHelpers.spec.ts b/sdk/core/core-client-rest/test/urlHelpers.spec.ts index 43a1545b565e..80789ce54a53 100644 --- a/sdk/core/core-client-rest/test/urlHelpers.spec.ts +++ b/sdk/core/core-client-rest/test/urlHelpers.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { buildBaseUrl, buildRequestUrl } from "../src/urlHelpers"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { buildBaseUrl, buildRequestUrl } from "../src/urlHelpers.js"; describe("urlHelpers", () => { const mockBaseUrl = "https://example.org"; diff --git a/sdk/core/core-client-rest/tsconfig.browser.config.json b/sdk/core/core-client-rest/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-client-rest/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-client-rest/tsconfig.json b/sdk/core/core-client-rest/tsconfig.json index 82e643af7e8c..a1e0a7e5f501 100644 --- a/sdk/core/core-client-rest/tsconfig.json +++ b/sdk/core/core-client-rest/tsconfig.json @@ -1,8 +1,12 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest" + "paths": { + "@azure-rest/core-client": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts", "test/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/core-client-rest/vitest.browser.config.ts b/sdk/core/core-client-rest/vitest.browser.config.ts new file mode 100644 index 000000000000..1501cfe97310 --- /dev/null +++ b/sdk/core/core-client-rest/vitest.browser.config.ts @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + slowHijackESM: false, + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-client-rest/vitest.config.ts b/sdk/core/core-client-rest/vitest.config.ts new file mode 100644 index 000000000000..f38ae6760b4c --- /dev/null +++ b/sdk/core/core-client-rest/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts", "test/**/node/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-client/.tshy/browser.json b/sdk/core/core-client/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-client/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-client/.tshy/build.json b/sdk/core/core-client/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-client/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-client/.tshy/commonjs.json b/sdk/core/core-client/.tshy/commonjs.json new file mode 100644 index 000000000000..c0f38bdd7176 --- /dev/null +++ b/sdk/core/core-client/.tshy/commonjs.json @@ -0,0 +1,15 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/base64-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-client/.tshy/esm.json b/sdk/core/core-client/.tshy/esm.json new file mode 100644 index 000000000000..0c45c26618b2 --- /dev/null +++ b/sdk/core/core-client/.tshy/esm.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/base64-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-client/.tshy/react-native.json b/sdk/core/core-client/.tshy/react-native.json new file mode 100644 index 000000000000..2b28336a2d5f --- /dev/null +++ b/sdk/core/core-client/.tshy/react-native.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/base64-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-client/api-extractor.json b/sdk/core/core-client/api-extractor.json index be3fab8cd6db..7bbc40c31bc4 100644 --- a/sdk/core/core-client/api-extractor.json +++ b/sdk/core/core-client/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-client.d.ts" + "publicTrimmedFilePath": "./dist/core-client.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-client/karma.conf.js b/sdk/core/core-client/karma.conf.js deleted file mode 100644 index 6c6511f22729..000000000000 --- a/sdk/core/core-client/karma.conf.js +++ /dev/null @@ -1,108 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: ["dist-test/index.browser.js"], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - // EXAMPLE: envPreprocessor: ["ACCOUNT_NAME", "ACCOUNT_SAS"], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-client/package.json b/sdk/core/core-client/package.json index 9fada6bfd244..a06be38084b2 100644 --- a/sdk/core/core-client/package.json +++ b/sdk/core/core-client/package.json @@ -3,41 +3,32 @@ "version": "1.8.1", "description": "Core library for interfacing with AutoRest generated code", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/base64.js": "./dist-esm/src/base64.browser.js" - }, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js" - }, - "types": "types/latest/core-client.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "cross-env TS_NODE_FILES=true dev-tool run test:node-ts-input --no-test-proxy=true --timeout 50000", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/latest/core-client.d.ts", "README.md", "LICENSE" ], @@ -57,46 +48,68 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-client/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.4.0", "@azure/core-rest-pipeline": "^1.9.1", "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", + "@azure/core-util": "^1.6.1", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { - "@azure/core-xml": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", - "@types/node": "^18.0.0", - "@types/sinon": "^17.0.0", - "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure/core-xml": "^1.3.4", "@azure/dev-tool": "^1.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "inherits": "^2.0.3", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "rimraf": "^3.0.0", - "sinon": "^17.0.0", - "ts-node": "^10.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@microsoft/api-extractor": "^7.39.5", + "@types/node": "^18.0.0", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "util": "^0.12.1", - "esm": "^3.2.18" + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-client/samples/.gitkeep b/sdk/core/core-client/samples/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sdk/core/core-client/src/authorizeRequestOnClaimChallenge.ts b/sdk/core/core-client/src/authorizeRequestOnClaimChallenge.ts index 9f20031d0dbb..ae8c085ff2db 100644 --- a/sdk/core/core-client/src/authorizeRequestOnClaimChallenge.ts +++ b/sdk/core/core-client/src/authorizeRequestOnClaimChallenge.ts @@ -2,8 +2,8 @@ // Licensed under the MIT license. import { AuthorizeRequestOnChallengeOptions } from "@azure/core-rest-pipeline"; -import { logger as coreClientLogger } from "./log"; -import { decodeStringToString } from "./base64"; +import { logger as coreClientLogger } from "./log.js"; +import { decodeStringToString } from "./base64.js"; /** * Converts: `Bearer a="b", c="d", Bearer d="e", f="g"`. diff --git a/sdk/core/core-client/src/base64.browser.ts b/sdk/core/core-client/src/base64-browser.mts similarity index 95% rename from sdk/core/core-client/src/base64.browser.ts rename to sdk/core/core-client/src/base64-browser.mts index 09693991054e..7a60188251aa 100644 --- a/sdk/core/core-client/src/base64.browser.ts +++ b/sdk/core/core-client/src/base64-browser.mts @@ -10,6 +10,7 @@ declare global { /** * Encodes a string in base64 format. * @param value - the string to encode + * @internal */ export function encodeString(value: string): string { return btoa(value); @@ -18,6 +19,7 @@ export function encodeString(value: string): string { /** * Encodes a byte array in base64 format. * @param value - the Uint8Aray to encode + * @internal */ export function encodeByteArray(value: Uint8Array): string { let str = ""; @@ -30,6 +32,7 @@ export function encodeByteArray(value: Uint8Array): string { /** * Decodes a base64 string into a byte array. * @param value - the base64 string to decode + * @internal */ export function decodeString(value: string): Uint8Array { const byteString = atob(value); @@ -43,6 +46,7 @@ export function decodeString(value: string): Uint8Array { /** * Decodes a base64 string into a string. * @param value - the base64 string to decode + * @internal */ export function decodeStringToString(value: string): string { return atob(value); diff --git a/sdk/core/core-client/src/base64.ts b/sdk/core/core-client/src/base64.ts index 88156ef1833c..fda75354e886 100644 --- a/sdk/core/core-client/src/base64.ts +++ b/sdk/core/core-client/src/base64.ts @@ -16,8 +16,6 @@ export function encodeString(value: string): string { * @internal */ export function encodeByteArray(value: Uint8Array): string { - // Buffer.from accepts | -- the TypeScript definition is off here - // https://nodejs.org/api/buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length const bufferValue = value instanceof Buffer ? value : Buffer.from(value.buffer as ArrayBuffer); return bufferValue.toString("base64"); } diff --git a/sdk/core/core-client/src/deserializationPolicy.ts b/sdk/core/core-client/src/deserializationPolicy.ts index d96de44f7736..24d4f6a18648 100644 --- a/sdk/core/core-client/src/deserializationPolicy.ts +++ b/sdk/core/core-client/src/deserializationPolicy.ts @@ -10,7 +10,7 @@ import { SerializerOptions, XML_CHARKEY, XmlOptions, -} from "./interfaces"; +} from "./interfaces.js"; import { PipelinePolicy, PipelineRequest, @@ -18,8 +18,8 @@ import { RestError, SendRequest, } from "@azure/core-rest-pipeline"; -import { MapperTypeNames } from "./serializer"; -import { getOperationRequestInfo } from "./operationHelpers"; +import { MapperTypeNames } from "./serializer.js"; +import { getOperationRequestInfo } from "./operationHelpers.js"; const defaultJsonContentTypes = ["application/json", "text/json"]; const defaultXmlContentTypes = ["application/xml", "application/atom+xml"]; diff --git a/sdk/core/core-client/src/index.ts b/sdk/core/core-client/src/index.ts index c081d040615b..85fd433db349 100644 --- a/sdk/core/core-client/src/index.ts +++ b/sdk/core/core-client/src/index.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { createSerializer, MapperTypeNames } from "./serializer"; -export { ServiceClient, ServiceClientOptions } from "./serviceClient"; -export { createClientPipeline, InternalClientPipelineOptions } from "./pipeline"; +export { createSerializer, MapperTypeNames } from "./serializer.js"; +export { ServiceClient, ServiceClientOptions } from "./serviceClient.js"; +export { createClientPipeline, InternalClientPipelineOptions } from "./pipeline.js"; export { OperationSpec, OperationArguments, @@ -41,17 +41,17 @@ export { RawResponseCallback, CommonClientOptions, AdditionalPolicyConfig, -} from "./interfaces"; +} from "./interfaces.js"; export { deserializationPolicy, deserializationPolicyName, DeserializationPolicyOptions, DeserializationContentTypes, -} from "./deserializationPolicy"; +} from "./deserializationPolicy.js"; export { serializationPolicy, serializationPolicyName, SerializationPolicyOptions, -} from "./serializationPolicy"; -export { authorizeRequestOnClaimChallenge } from "./authorizeRequestOnClaimChallenge"; -export { authorizeRequestOnTenantChallenge } from "./authorizeRequestOnTenantChallenge"; +} from "./serializationPolicy.js"; +export { authorizeRequestOnClaimChallenge } from "./authorizeRequestOnClaimChallenge.js"; +export { authorizeRequestOnTenantChallenge } from "./authorizeRequestOnTenantChallenge.js"; diff --git a/sdk/core/core-client/src/interfaceHelpers.ts b/sdk/core/core-client/src/interfaceHelpers.ts index ede045834f54..258e6850a528 100644 --- a/sdk/core/core-client/src/interfaceHelpers.ts +++ b/sdk/core/core-client/src/interfaceHelpers.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { OperationParameter, OperationSpec } from "./interfaces"; -import { MapperTypeNames } from "./serializer"; +import { OperationParameter, OperationSpec } from "./interfaces.js"; +import { MapperTypeNames } from "./serializer.js"; /** * Gets the list of status codes for streaming responses. diff --git a/sdk/core/core-client/src/operationHelpers.ts b/sdk/core/core-client/src/operationHelpers.ts index 242121ee7599..c385d2e93aaf 100644 --- a/sdk/core/core-client/src/operationHelpers.ts +++ b/sdk/core/core-client/src/operationHelpers.ts @@ -9,7 +9,7 @@ import { OperationRequest, OperationRequestInfo, ParameterPath, -} from "./interfaces"; +} from "./interfaces.js"; /** * @internal diff --git a/sdk/core/core-client/src/pipeline.ts b/sdk/core/core-client/src/pipeline.ts index 5488693a0ee5..aee5071dd4d8 100644 --- a/sdk/core/core-client/src/pipeline.ts +++ b/sdk/core/core-client/src/pipeline.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { DeserializationPolicyOptions, deserializationPolicy } from "./deserializationPolicy"; +import { DeserializationPolicyOptions, deserializationPolicy } from "./deserializationPolicy.js"; import { InternalPipelineOptions, Pipeline, bearerTokenAuthenticationPolicy, createPipelineFromOptions, } from "@azure/core-rest-pipeline"; -import { SerializationPolicyOptions, serializationPolicy } from "./serializationPolicy"; +import { SerializationPolicyOptions, serializationPolicy } from "./serializationPolicy.js"; import { TokenCredential } from "@azure/core-auth"; /** diff --git a/sdk/core/core-client/src/serializationPolicy.ts b/sdk/core/core-client/src/serializationPolicy.ts index 193ec3c1c263..c786c2d553aa 100644 --- a/sdk/core/core-client/src/serializationPolicy.ts +++ b/sdk/core/core-client/src/serializationPolicy.ts @@ -11,14 +11,14 @@ import { XML_ATTRKEY, XML_CHARKEY, XmlOptions, -} from "./interfaces"; +} from "./interfaces.js"; import { PipelinePolicy, PipelineResponse, SendRequest } from "@azure/core-rest-pipeline"; import { getOperationArgumentValueFromParameter, getOperationRequestInfo, -} from "./operationHelpers"; -import { MapperTypeNames } from "./serializer"; -import { getPathStringFromParameter } from "./interfaceHelpers"; +} from "./operationHelpers.js"; +import { MapperTypeNames } from "./serializer.js"; +import { getPathStringFromParameter } from "./interfaceHelpers.js"; /** * The programmatic identifier of the serializationPolicy. diff --git a/sdk/core/core-client/src/serializer.ts b/sdk/core/core-client/src/serializer.ts index 0f1455e0e71e..060b83f5770b 100644 --- a/sdk/core/core-client/src/serializer.ts +++ b/sdk/core/core-client/src/serializer.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as base64 from "./base64"; +import * as base64 from "./base64.js"; import { BaseMapper, CompositeMapper, @@ -16,8 +16,8 @@ import { SerializerOptions, XML_ATTRKEY, XML_CHARKEY, -} from "./interfaces"; -import { isDuration, isValidUuid } from "./utils"; +} from "./interfaces.js"; +import { isDuration, isValidUuid } from "./utils.js"; class SerializerImpl implements Serializer { constructor( diff --git a/sdk/core/core-client/src/serviceClient.ts b/sdk/core/core-client/src/serviceClient.ts index a8eb8b917496..c53c781b01d6 100644 --- a/sdk/core/core-client/src/serviceClient.ts +++ b/sdk/core/core-client/src/serviceClient.ts @@ -6,7 +6,7 @@ import { OperationArguments, OperationRequest, OperationSpec, -} from "./interfaces"; +} from "./interfaces.js"; import { HttpClient, Pipeline, @@ -15,13 +15,13 @@ import { createPipelineRequest, } from "@azure/core-rest-pipeline"; import { TokenCredential } from "@azure/core-auth"; -import { createClientPipeline } from "./pipeline"; -import { flattenResponse } from "./utils"; -import { getCachedDefaultHttpClient } from "./httpClientCache"; -import { getOperationRequestInfo } from "./operationHelpers"; -import { getRequestUrl } from "./urlHelpers"; -import { getStreamingResponseStatusCodes } from "./interfaceHelpers"; -import { logger } from "./log"; +import { createClientPipeline } from "./pipeline.js"; +import { flattenResponse } from "./utils.js"; +import { getCachedDefaultHttpClient } from "./httpClientCache.js"; +import { getOperationRequestInfo } from "./operationHelpers.js"; +import { getRequestUrl } from "./urlHelpers.js"; +import { getStreamingResponseStatusCodes } from "./interfaceHelpers.js"; +import { logger } from "./log.js"; /** * Options to be provided while creating the client. diff --git a/sdk/core/core-client/src/urlHelpers.ts b/sdk/core/core-client/src/urlHelpers.ts index b541ece8e0b8..d91d1384f03f 100644 --- a/sdk/core/core-client/src/urlHelpers.ts +++ b/sdk/core/core-client/src/urlHelpers.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { OperationArguments, OperationSpec, QueryCollectionFormat } from "./interfaces"; -import { getOperationArgumentValueFromParameter } from "./operationHelpers"; -import { getPathStringFromParameter } from "./interfaceHelpers"; +import { OperationArguments, OperationSpec, QueryCollectionFormat } from "./interfaces.js"; +import { getOperationArgumentValueFromParameter } from "./operationHelpers.js"; +import { getPathStringFromParameter } from "./interfaceHelpers.js"; const CollectionFormatToDelimiterMap: { [key in QueryCollectionFormat]: string } = { CSV: ",", diff --git a/sdk/core/core-client/src/utils.ts b/sdk/core/core-client/src/utils.ts index c28f9e9759a2..cc29c5e060da 100644 --- a/sdk/core/core-client/src/utils.ts +++ b/sdk/core/core-client/src/utils.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { CompositeMapper, FullOperationResponse, OperationResponseMap } from "./interfaces"; +import { CompositeMapper, FullOperationResponse, OperationResponseMap } from "./interfaces.js"; /** * The union of all possible types for a primitive response body. diff --git a/sdk/core/core-client/test/authorizeRequestOnClaimChallenge.spec.ts b/sdk/core/core-client/test/authorizeRequestOnClaimChallenge.spec.ts index 81c5c8680abb..e70e182e0d9e 100644 --- a/sdk/core/core-client/test/authorizeRequestOnClaimChallenge.spec.ts +++ b/sdk/core/core-client/test/authorizeRequestOnClaimChallenge.spec.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert } from "vitest"; import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; import { HttpClient, @@ -13,9 +14,8 @@ import { import { authorizeRequestOnClaimChallenge, parseCAEChallenge, -} from "../src/authorizeRequestOnClaimChallenge"; -import { assert } from "chai"; -import { encodeString } from "../src/base64"; +} from "../src/authorizeRequestOnClaimChallenge.js"; +import { encodeString } from "../src/base64.js"; describe("authorizeRequestOnClaimChallenge", function () { it(`should try to get the access token if the response has a valid claims parameter on the WWW-Authenticate header`, async function () { diff --git a/sdk/core/core-client/test/authorizeRequestOnTenantChallenge.spec.ts b/sdk/core/core-client/test/authorizeRequestOnTenantChallenge.spec.ts index d1cd3ea13b24..4b97cdfe4439 100644 --- a/sdk/core/core-client/test/authorizeRequestOnTenantChallenge.spec.ts +++ b/sdk/core/core-client/test/authorizeRequestOnTenantChallenge.spec.ts @@ -1,23 +1,25 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert, expect, vi, beforeEach, type Mock } from "vitest"; import { AccessToken, GetTokenOptions } from "@azure/core-auth"; -import { bearerTokenAuthenticationPolicy, createHttpHeaders } from "@azure/core-rest-pipeline"; - -import { assert } from "chai"; -import { authorizeRequestOnTenantChallenge } from "../src"; -import sinon from "sinon"; +import { + PipelineResponse, + bearerTokenAuthenticationPolicy, + createHttpHeaders, +} from "@azure/core-rest-pipeline"; +import { authorizeRequestOnTenantChallenge } from "../src/index.js"; describe("storageBearerTokenChallengeAuthenticationPolicy", function () { const fakeGuid = "3a4e2c3b-defc-466c-b0c8-6a419bf92858"; - let getTokenStub: sinon.SinonStub< + let getTokenStub: Mock< [string | string[], GetTokenOptions | undefined], Promise >; beforeEach(() => { - getTokenStub = sinon - .stub<[string | string[], GetTokenOptions | undefined], Promise>() - .resolves({ expiresOnTimestamp: 1, token: "originalToken" }); + getTokenStub = vi + .fn<[string | string[], GetTokenOptions | undefined], Promise>() + .mockResolvedValue({ expiresOnTimestamp: 1, token: "originalToken" }); }); it("should not try to get challenge info if request succeeded initially", async () => { @@ -51,7 +53,7 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, ); - assert.equal(getTokenStub.callCount, 1); + expect(getTokenStub).toBeCalledTimes(1); }); it("should fail with 401 if no challenge is present", async () => { @@ -126,9 +128,9 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, ); - assert.equal(getTokenStub.callCount, 2); - const lastGetTokenCall = getTokenStub.getCall(1); - assert.equal(lastGetTokenCall.args[1]?.tenantId, fakeGuid); + expect(getTokenStub).toBeCalledTimes(2); + const lastGetTokenCall = getTokenStub.mock.calls[1]; + assert.equal(lastGetTokenCall[1]?.tenantId, fakeGuid); }); it("should use the scopes returned in the challenge", async () => { @@ -170,10 +172,10 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, ); - assert.equal(getTokenStub.callCount, 2); - const lastGetTokenCall = getTokenStub.getCall(1); - assert.equal(lastGetTokenCall.args[1]?.tenantId, fakeGuid); - assert.equal(lastGetTokenCall.args[0], "https://storage.azure.com/.default"); + expect(getTokenStub).toBeCalledTimes(2); + const lastGetTokenCall = getTokenStub.mock.calls[1]; + assert.equal(lastGetTokenCall[1]?.tenantId, fakeGuid); + assert.equal(lastGetTokenCall[0], "https://storage.azure.com/.default"); }); it("should use the original scopes returned if there is none in the challenge", async () => { @@ -215,10 +217,10 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, ); - assert.equal(getTokenStub.callCount, 2); - const lastGetTokenCall = getTokenStub.getCall(1); - assert.equal(lastGetTokenCall.args[1]?.tenantId, fakeGuid); - assert.equal(lastGetTokenCall.args[0], "https://example.org/.default"); + expect(getTokenStub).toBeCalledTimes(2); + const lastGetTokenCall = getTokenStub.mock.calls[1]; + assert.equal(lastGetTokenCall[1]?.tenantId, fakeGuid); + assert.equal(lastGetTokenCall[0], "https://example.org/.default"); }); it("should if request failed after first challenge stop retrying", async () => { @@ -252,13 +254,13 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { ); assert.equal(response.status, 401); - assert.equal(getTokenStub.callCount, 2); + expect(getTokenStub).toBeCalledTimes(2); }); it("should reuse token if it hasn't expired", async () => { - getTokenStub = sinon - .stub<[string | string[], GetTokenOptions | undefined], Promise>() - .resolves({ expiresOnTimestamp: Date.now() + 100000000, token: "originalToken" }); + getTokenStub = vi + .fn<[string | string[], GetTokenOptions | undefined], Promise>() + .mockResolvedValue({ expiresOnTimestamp: Date.now() + 100000000, token: "originalToken" }); const policy = bearerTokenAuthenticationPolicy({ credential: { getToken: getTokenStub }, @@ -268,7 +270,7 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, }); - const sendTestRequest = () => + const sendTestRequest = (): Promise => policy.sendRequest( { headers: createHttpHeaders(), @@ -293,13 +295,13 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { await sendTestRequest(); await sendTestRequest(); - assert.equal(getTokenStub.callCount, 1); + expect(getTokenStub).toBeCalledTimes(1); }); it("should refresh token if it has expired", async () => { - getTokenStub = sinon - .stub<[string | string[], GetTokenOptions | undefined], Promise>() - .resolves({ expiresOnTimestamp: Date.now() - 1000000, token: "originalToken" }); + getTokenStub = vi + .fn<[string | string[], GetTokenOptions | undefined], Promise>() + .mockResolvedValue({ expiresOnTimestamp: Date.now() - 1000000, token: "originalToken" }); const policy = bearerTokenAuthenticationPolicy({ credential: { getToken: getTokenStub }, @@ -309,7 +311,7 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, }); - const sendTestRequest = () => + const sendTestRequest = (): Promise => policy.sendRequest( { headers: createHttpHeaders(), @@ -336,14 +338,14 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { // We are setting expiration time in the past everytime we refresh the token // so we expect 3 calls to refresh the token - assert.equal(getTokenStub.callCount, 3); + expect(getTokenStub).toBeCalledTimes(3); }); it("should refresh token if valid but within window it has expired", async () => { - getTokenStub = sinon - .stub<[string | string[], GetTokenOptions | undefined], Promise>() + getTokenStub = vi + .fn<[string | string[], GetTokenOptions | undefined], Promise>() // Refresh window is 1000ms setting 999 to make sure we are in the refresh window - .resolves({ expiresOnTimestamp: Date.now() + 999, token: "originalToken" }); + .mockResolvedValue({ expiresOnTimestamp: Date.now() + 999, token: "originalToken" }); const policy = bearerTokenAuthenticationPolicy({ credential: { getToken: getTokenStub }, @@ -353,7 +355,7 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { }, }); - const sendTestRequest = () => + const sendTestRequest = (): Promise => policy.sendRequest( { headers: createHttpHeaders(), @@ -379,6 +381,6 @@ describe("storageBearerTokenChallengeAuthenticationPolicy", function () { // We are setting expiration time within the refresh window // so we expect 2 calls to refresh the token - assert.equal(getTokenStub.callCount, 2); + expect(getTokenStub).toBeCalledTimes(2); }); }); diff --git a/sdk/core/core-client/test/browser/serializer.spec.ts b/sdk/core/core-client/test/browser/serializer.spec.ts index f791a06478f2..ad53e6f78453 100644 --- a/sdk/core/core-client/test/browser/serializer.spec.ts +++ b/sdk/core/core-client/test/browser/serializer.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Mapper, createSerializer } from "../../src"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { Mapper, createSerializer } from "../../src/index.js"; describe("Serializer (browser specific)", function () { describe("serialize", function () { diff --git a/sdk/core/core-client/test/deserializationPolicy.spec.ts b/sdk/core/core-client/test/deserializationPolicy.spec.ts index 5a9a686abb11..737ba11eb9c6 100644 --- a/sdk/core/core-client/test/deserializationPolicy.spec.ts +++ b/sdk/core/core-client/test/deserializationPolicy.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as sinon from "sinon"; +import { describe, it, assert, vi } from "vitest"; import { CompositeMapper, FullOperationResponse, @@ -10,7 +10,7 @@ import { SerializerOptions, createSerializer, deserializationPolicy, -} from "../src"; +} from "../src/index.js"; import { PipelineResponse, RawHttpHeaders, @@ -18,8 +18,7 @@ import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline"; -import { assert } from "chai"; -import { getOperationRequestInfo } from "../src/operationHelpers"; +import { getOperationRequestInfo } from "../src/operationHelpers.js"; import { parseXML } from "@azure/core-xml"; describe("deserializationPolicy", function () { @@ -823,8 +822,8 @@ async function getDeserializedResponse( bodyAsText: options.bodyAsText, status: options.status ?? 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(res); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(res); const response = await policy.sendRequest(request, next); return response; diff --git a/sdk/core/core-client/test/serializationPolicy.spec.ts b/sdk/core/core-client/test/serializationPolicy.spec.ts index c6d402f573cb..50e2dbd793ad 100644 --- a/sdk/core/core-client/test/serializationPolicy.spec.ts +++ b/sdk/core/core-client/test/serializationPolicy.spec.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { MapperTypeNames, createSerializer } from "../src"; -import { serializeHeaders, serializeRequestBody } from "../src/serializationPolicy"; -import { Mappers } from "./testMappers1"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { MapperTypeNames, createSerializer } from "../src/index.js"; +import { serializeHeaders, serializeRequestBody } from "../src/serializationPolicy.js"; +import { Mappers } from "./testMappers1.js"; import { createPipelineRequest } from "@azure/core-rest-pipeline"; import { stringifyXML } from "@azure/core-xml"; diff --git a/sdk/core/core-client/test/serializer.spec.ts b/sdk/core/core-client/test/serializer.spec.ts index 7edce7080ff1..db736ad372cb 100644 --- a/sdk/core/core-client/test/serializer.spec.ts +++ b/sdk/core/core-client/test/serializer.spec.ts @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as MediaMappers from "./testMappers2"; +import { describe, it, assert } from "vitest"; +import * as MediaMappers from "./testMappers2.js"; import { CompositeMapper, DictionaryMapper, @@ -9,9 +10,8 @@ import { Mapper, SequenceMapper, createSerializer, -} from "../src"; -import { Mappers } from "./testMappers1"; -import { assert } from "chai"; +} from "../src/index.js"; +import { Mappers } from "./testMappers1.js"; const Serializer = createSerializer(Mappers); const valid_uuid = "ceaafd1e-f936-429f-bbfc-82ee75dddc33"; diff --git a/sdk/core/core-client/test/serviceClient.spec.ts b/sdk/core/core-client/test/serviceClient.spec.ts index 79d9b399067c..a61365859f68 100644 --- a/sdk/core/core-client/test/serviceClient.spec.ts +++ b/sdk/core/core-client/test/serviceClient.spec.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert } from "vitest"; import { CompositeMapper, DictionaryMapper, @@ -16,7 +17,7 @@ import { ServiceClient, createSerializer, serializationPolicy, -} from "../src"; +} from "../src/index.js"; import { HttpClient, PipelinePolicy, @@ -30,12 +31,11 @@ import { import { getOperationArgumentValueFromParameter, getOperationRequestInfo, -} from "../src/operationHelpers"; +} from "../src/operationHelpers.js"; import { TokenCredential } from "@azure/core-auth"; -import { assert } from "chai"; -import { assertServiceClientResponse } from "./utils/serviceClient"; -import { deserializationPolicy } from "../src/deserializationPolicy"; -import { getCachedDefaultHttpClient } from "../src/httpClientCache"; +import { assertServiceClientResponse } from "./utils/serviceClient.js"; +import { deserializationPolicy } from "../src/deserializationPolicy.js"; +import { getCachedDefaultHttpClient } from "../src/httpClientCache.js"; describe("ServiceClient", function () { describe("Auth scopes", () => { diff --git a/sdk/core/core-client/test/testMappers1.ts b/sdk/core/core-client/test/testMappers1.ts index d8eecc18da49..137d0b2f5950 100644 --- a/sdk/core/core-client/test/testMappers1.ts +++ b/sdk/core/core-client/test/testMappers1.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { CompositeMapper } from "../src/interfaces"; +import { CompositeMapper } from "../src/interfaces.js"; const QueueDescription: CompositeMapper = { serializedName: "QueueDescription", diff --git a/sdk/core/core-client/test/testMappers2.ts b/sdk/core/core-client/test/testMappers2.ts index 8a4f7c989eb2..ab77b5abb484 100644 --- a/sdk/core/core-client/test/testMappers2.ts +++ b/sdk/core/core-client/test/testMappers2.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { CompositeMapper } from "../src/interfaces"; +import { CompositeMapper } from "../src/interfaces.js"; export const JobOutput: CompositeMapper = { type: { diff --git a/sdk/core/core-client/test/urlHelpers.spec.ts b/sdk/core/core-client/test/urlHelpers.spec.ts index 52323a01591a..1ad941b8a198 100644 --- a/sdk/core/core-client/test/urlHelpers.spec.ts +++ b/sdk/core/core-client/test/urlHelpers.spec.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert } from "vitest"; import { OperationQueryParameter, OperationSpec, OperationURLParameter, createSerializer, -} from "../src"; -import { appendQueryParams, getRequestUrl } from "../src/urlHelpers"; -import { assert } from "chai"; +} from "../src/index.js"; +import { appendQueryParams, getRequestUrl } from "../src/urlHelpers.js"; describe("getRequestUrl", function () { const urlParameter: OperationURLParameter = { diff --git a/sdk/core/core-client/test/utils/serviceClient.ts b/sdk/core/core-client/test/utils/serviceClient.ts index 44dd27db54c0..a668ffbd3d5e 100644 --- a/sdk/core/core-client/test/utils/serviceClient.ts +++ b/sdk/core/core-client/test/utils/serviceClient.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { assert } from "vitest"; import { FullOperationResponse, OperationRequest, @@ -9,7 +10,7 @@ import { ServiceClient, createSerializer, deserializationPolicy, -} from "../../src"; +} from "../../src/index.js"; import { HttpClient, HttpHeaders, @@ -17,7 +18,6 @@ import { createEmptyPipeline, createHttpHeaders, } from "@azure/core-rest-pipeline"; -import { assert } from "chai"; /** * Representation of a Service Client test case where the response status is 200. diff --git a/sdk/core/core-client/tsconfig.browser.config.json b/sdk/core/core-client/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-client/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-client/tsconfig.json b/sdk/core/core-client/tsconfig.json index 82e643af7e8c..c48ee63cf26d 100644 --- a/sdk/core/core-client/tsconfig.json +++ b/sdk/core/core-client/tsconfig.json @@ -1,8 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest" + "paths": { + "@azure/core-client": ["./src/index.ts"] + }, + "lib": ["DOM"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts", "test/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/core-client/vitest.browser.config.ts b/sdk/core/core-client/vitest.browser.config.ts new file mode 100644 index 000000000000..1501cfe97310 --- /dev/null +++ b/sdk/core/core-client/vitest.browser.config.ts @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + slowHijackESM: false, + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-client/vitest.config.ts b/sdk/core/core-client/vitest.config.ts new file mode 100644 index 000000000000..e94c7dd91c76 --- /dev/null +++ b/sdk/core/core-client/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-http-compat/.tshy/browser.json b/sdk/core/core-http-compat/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-http-compat/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-http-compat/.tshy/build.json b/sdk/core/core-http-compat/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-http-compat/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-http-compat/.tshy/commonjs.json b/sdk/core/core-http-compat/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/core-http-compat/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-http-compat/.tshy/esm.json b/sdk/core/core-http-compat/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/core-http-compat/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-http-compat/.tshy/react-native.json b/sdk/core/core-http-compat/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/core-http-compat/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-http-compat/api-extractor.json b/sdk/core/core-http-compat/api-extractor.json index 8f4418654132..654456848a46 100644 --- a/sdk/core/core-http-compat/api-extractor.json +++ b/sdk/core/core-http-compat/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-http-compat.d.ts" + "publicTrimmedFilePath": "./dist/core-http-compat.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-http-compat/package.json b/sdk/core/core-http-compat/package.json index 91783084c57f..96e7052d1442 100644 --- a/sdk/core/core-http-compat/package.json +++ b/sdk/core/core-http-compat/package.json @@ -3,35 +3,32 @@ "version": "2.0.2", "description": "Core HTTP Compatibility Library to bridge the gap between Core V1 & V2 packages.", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "types": "types/latest/core-http-compat.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "echo skipped", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "echo skipped", - "test:node": "echo skipped", - "test": "npm run clean && npm run build && npm run unit-test:node && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "echo skipped", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/latest/core-http-compat.d.ts", "README.md", "LICENSE" ], @@ -51,26 +48,64 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-compat/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "echo skipped", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "echo skipped", + "test:node": "echo skipped", + "test": "npm run clean && npm run build && npm run unit-test:node && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { + "@azure/abort-controller": "^2.0.0", "@azure/core-rest-pipeline": "^1.3.0", - "@azure/core-client": "^1.3.0", - "@azure/abort-controller": "^2.0.0" + "@azure/core-client": "^1.3.0" }, "devDependencies": { "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@azure/test-utils": "^1.0.0", "@azure/dev-tool": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", - "mocha": "^10.0.0", - "eslint": "^8.0.0", - "rimraf": "^3.0.0", - "cross-env": "^7.0.2", - "typescript": "~5.3.3", - "ts-node": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", "@types/node": "^18.0.0", - "@types/mocha": "^10.0.0" + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", + "typescript": "~5.3.3", + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-http-compat/src/extendedClient.ts b/sdk/core/core-http-compat/src/extendedClient.ts index a5f403bae1d7..219367d7d4c4 100644 --- a/sdk/core/core-http-compat/src/extendedClient.ts +++ b/sdk/core/core-http-compat/src/extendedClient.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { KeepAliveOptions } from "./policies/keepAliveOptions"; +import { KeepAliveOptions } from "./policies/keepAliveOptions.js"; import { createDisableKeepAlivePolicy, pipelineContainsDisableKeepAlivePolicy, -} from "./policies/disableKeepAlivePolicy"; -import { RedirectOptions } from "./policies/redirectOptions"; +} from "./policies/disableKeepAlivePolicy.js"; +import { RedirectOptions } from "./policies/redirectOptions.js"; import { redirectPolicyName } from "@azure/core-rest-pipeline"; import { CommonClientOptions, @@ -17,7 +17,7 @@ import { ServiceClient, ServiceClientOptions, } from "@azure/core-client"; -import { toCompatResponse } from "./response"; +import { toCompatResponse } from "./response.js"; /** * Options specific to Shim Clients. diff --git a/sdk/core/core-http-compat/src/httpClientAdapter.ts b/sdk/core/core-http-compat/src/httpClientAdapter.ts index 2553145d5de1..79000f95b64b 100644 --- a/sdk/core/core-http-compat/src/httpClientAdapter.ts +++ b/sdk/core/core-http-compat/src/httpClientAdapter.ts @@ -2,9 +2,9 @@ // Licensed under the MIT license. import { HttpClient, PipelineRequest, PipelineResponse } from "@azure/core-rest-pipeline"; -import { RequestPolicy } from "./policies/requestPolicyFactoryPolicy"; -import { toPipelineResponse } from "./response"; -import { toWebResourceLike } from "./util"; +import { RequestPolicy } from "./policies/requestPolicyFactoryPolicy.js"; +import { toPipelineResponse } from "./response.js"; +import { toWebResourceLike } from "./util.js"; /** * Converts a RequestPolicy based HttpClient to a PipelineRequest based HttpClient. diff --git a/sdk/core/core-http-compat/src/index.ts b/sdk/core/core-http-compat/src/index.ts index 36e0c307bfb9..77c0d201bb9f 100644 --- a/sdk/core/core-http-compat/src/index.ts +++ b/sdk/core/core-http-compat/src/index.ts @@ -11,8 +11,8 @@ export { ExtendedServiceClientOptions, ExtendedCommonClientOptions, ExtendedClientOptions, -} from "./extendedClient"; -export { CompatResponse } from "./response"; +} from "./extendedClient.js"; +export { CompatResponse } from "./response.js"; export { requestPolicyFactoryPolicyName, createRequestPolicyFactoryPolicy, @@ -20,11 +20,11 @@ export { RequestPolicy, RequestPolicyOptionsLike, HttpPipelineLogLevel, -} from "./policies/requestPolicyFactoryPolicy"; -export { KeepAliveOptions } from "./policies/keepAliveOptions"; -export { RedirectOptions } from "./policies/redirectOptions"; -export { disableKeepAlivePolicyName } from "./policies/disableKeepAlivePolicy"; -export { convertHttpClient } from "./httpClientAdapter"; +} from "./policies/requestPolicyFactoryPolicy.js"; +export { KeepAliveOptions } from "./policies/keepAliveOptions.js"; +export { RedirectOptions } from "./policies/redirectOptions.js"; +export { disableKeepAlivePolicyName } from "./policies/disableKeepAlivePolicy.js"; +export { convertHttpClient } from "./httpClientAdapter.js"; export { WebResourceLike, HttpHeadersLike, @@ -32,4 +32,4 @@ export { HttpHeader, TransferProgressEvent, toHttpHeadersLike, -} from "./util"; +} from "./util.js"; diff --git a/sdk/core/core-http-compat/src/policies/requestPolicyFactoryPolicy.ts b/sdk/core/core-http-compat/src/policies/requestPolicyFactoryPolicy.ts index 937fe979349f..c45e7ff400cf 100644 --- a/sdk/core/core-http-compat/src/policies/requestPolicyFactoryPolicy.ts +++ b/sdk/core/core-http-compat/src/policies/requestPolicyFactoryPolicy.ts @@ -7,8 +7,8 @@ import { PipelineResponse, SendRequest, } from "@azure/core-rest-pipeline"; -import { WebResourceLike, toPipelineRequest, toWebResourceLike } from "../util"; -import { CompatResponse, toCompatResponse, toPipelineResponse } from "../response"; +import { WebResourceLike, toPipelineRequest, toWebResourceLike } from "../util.js"; +import { CompatResponse, toCompatResponse, toPipelineResponse } from "../response.js"; /** * A compatible interface for core-http request policies diff --git a/sdk/core/core-http-compat/src/response.ts b/sdk/core/core-http-compat/src/response.ts index d56fc65f2cc8..0aad940955e3 100644 --- a/sdk/core/core-http-compat/src/response.ts +++ b/sdk/core/core-http-compat/src/response.ts @@ -9,7 +9,7 @@ import { toHttpHeadersLike, toPipelineRequest, toWebResourceLike, -} from "./util"; +} from "./util.js"; /** * Http Response that is compatible with the core-v1(core-http). */ diff --git a/sdk/core/core-http-compat/test/cloneRequestPolicy.ts b/sdk/core/core-http-compat/test/cloneRequestPolicy.ts index b72247d508d1..de41aa4a4a87 100644 --- a/sdk/core/core-http-compat/test/cloneRequestPolicy.ts +++ b/sdk/core/core-http-compat/test/cloneRequestPolicy.ts @@ -7,7 +7,7 @@ import { RequestPolicyFactory, RequestPolicyOptionsLike, WebResourceLike, -} from "../src/index"; +} from "../src/index.js"; export function cloneRequestPolicy(): RequestPolicyFactory { return { diff --git a/sdk/core/core-http-compat/test/extendedClient.spec.ts b/sdk/core/core-http-compat/test/extendedClient.spec.ts index 712cb80033d2..fbc4cb7ebd98 100644 --- a/sdk/core/core-http-compat/test/extendedClient.spec.ts +++ b/sdk/core/core-http-compat/test/extendedClient.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "@azure/test-utils"; +import { describe, it, assert } from "vitest"; import { PipelinePolicy, createEmptyPipeline, createHttpHeaders } from "@azure/core-rest-pipeline"; import { DictionaryMapper, @@ -11,11 +11,11 @@ import { createSerializer, serializationPolicy, } from "@azure/core-client"; -import { ExtendedServiceClient, disableKeepAlivePolicyName } from "../src/index"; +import { ExtendedServiceClient, disableKeepAlivePolicyName } from "../src/index.js"; import { pipelineContainsDisableKeepAlivePolicy, createDisableKeepAlivePolicy, -} from "../src/policies/disableKeepAlivePolicy"; +} from "../src/policies/disableKeepAlivePolicy.js"; describe("Extended Client", () => { it("should add the disable keep alive policy", () => { diff --git a/sdk/core/core-http-compat/test/mutatePolicies.ts b/sdk/core/core-http-compat/test/mutatePolicies.ts index 68afb3b5e078..b8617cb6cae7 100644 --- a/sdk/core/core-http-compat/test/mutatePolicies.ts +++ b/sdk/core/core-http-compat/test/mutatePolicies.ts @@ -7,7 +7,7 @@ import { RequestPolicyFactory, RequestPolicyOptionsLike, WebResourceLike, -} from "../src/index"; +} from "../src/index.js"; export interface MutateOptions { headersToSet?: { [name: string]: string }; diff --git a/sdk/core/core-http-compat/test/requestPolicyFactoryPolicy.spec.ts b/sdk/core/core-http-compat/test/requestPolicyFactoryPolicy.spec.ts index ee50d4212fa9..ff80208c1cde 100644 --- a/sdk/core/core-http-compat/test/requestPolicyFactoryPolicy.spec.ts +++ b/sdk/core/core-http-compat/test/requestPolicyFactoryPolicy.spec.ts @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "@azure/test-utils"; +import { describe, it, assert } from "vitest"; import { HttpClient, createEmptyPipeline, createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline"; -import { createRequestPolicyFactoryPolicy } from "../src/policies/requestPolicyFactoryPolicy"; -import { mutateRequestPolicy, mutateResponsePolicy } from "./mutatePolicies"; -import { cloneRequestPolicy } from "./cloneRequestPolicy"; +import { createRequestPolicyFactoryPolicy } from "../src/policies/requestPolicyFactoryPolicy.js"; +import { mutateRequestPolicy, mutateResponsePolicy } from "./mutatePolicies.js"; +import { cloneRequestPolicy } from "./cloneRequestPolicy.js"; const originalClientRequestSymbol = Symbol.for("@azure/core-client original request"); diff --git a/sdk/core/core-http-compat/tsconfig.browser.config.json b/sdk/core/core-http-compat/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-http-compat/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-http-compat/tsconfig.json b/sdk/core/core-http-compat/tsconfig.json index f72f73553146..7d53dba17c74 100644 --- a/sdk/core/core-http-compat/tsconfig.json +++ b/sdk/core/core-http-compat/tsconfig.json @@ -1,9 +1,12 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest", - "rootDir": "./" + "paths": { + "@azure/core-http-compat": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts", "test/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/core-http-compat/vitest.browser.config.ts b/sdk/core/core-http-compat/vitest.browser.config.ts new file mode 100644 index 000000000000..6b383703b637 --- /dev/null +++ b/sdk/core/core-http-compat/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-http-compat/vitest.config.ts b/sdk/core/core-http-compat/vitest.config.ts new file mode 100644 index 000000000000..7c014c00af62 --- /dev/null +++ b/sdk/core/core-http-compat/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-lro/.tshy/browser.json b/sdk/core/core-lro/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-lro/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-lro/.tshy/build.json b/sdk/core/core-lro/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-lro/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-lro/.tshy/commonjs.json b/sdk/core/core-lro/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/core-lro/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-lro/.tshy/esm.json b/sdk/core/core-lro/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/core-lro/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-lro/.tshy/react-native.json b/sdk/core/core-lro/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/core-lro/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-lro/api-extractor.json b/sdk/core/core-lro/api-extractor.json index fa69d94125e8..ee813ed62952 100644 --- a/sdk/core/core-lro/api-extractor.json +++ b/sdk/core/core-lro/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/core-lro.d.ts" + "publicTrimmedFilePath": "./dist/core-lro.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-lro/karma.conf.js b/sdk/core/core-lro/karma.conf.js deleted file mode 100644 index cda6e8f1e655..000000000000 --- a/sdk/core/core-lro/karma.conf.js +++ /dev/null @@ -1,85 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); -require("dotenv").config({ path: "../.env" }); - -module.exports = function (config) { - config.set({ - basePath: "./", - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - files: [ - "dist-test/index.browser.js", - { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true }, - ], - - exclude: [], - - preprocessors: { - "**/*.js": ["sourcemap", "env"], - //"dist-test/index.browser.js": ["coverage"] - }, - - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", - outputFile: "test-results.browser.xml", - suite: "", - useBrowserName: false, - nameFormatter: undefined, - classNameFormatter: undefined, - properties: {}, - }, - - port: 9328, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: false, - - // --no-sandbox allows our tests to run in Linux without having to change the system. - browsers: ["ChromeHeadlessNoSandbox"], - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: "ChromeHeadless", - flags: ["--no-sandbox"], - }, - }, - - singleRun: false, - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-lro/package.json b/sdk/core/core-lro/package.json index 662ff83ebf0d..c62b96607510 100644 --- a/sdk/core/core-lro/package.json +++ b/sdk/core/core-lro/package.json @@ -2,8 +2,32 @@ "name": "@azure/core-lro", "author": "Microsoft Corporation", "sdk-type": "client", + "type": "module", "version": "2.6.1", "description": "Isomorphic client library for supporting long-running operations in node.js and browser.", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", "tags": [ "isomorphic", "browser", @@ -24,16 +48,6 @@ "azure", "cloud" ], - "main": "./dist/index.js", - "module": "dist-esm/src/index.js", - "types": "./types/core-lro.d.ts", - "files": [ - "types/core-lro.d.ts", - "dist-esm/src", - "dist/", - "README.md", - "LICENSE" - ], "engines": { "node": ">=18.0.0" }, @@ -41,39 +55,21 @@ "os": false, "process": false }, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js" - }, "license": "MIT", "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-lro/README.md", "repository": "github:Azure/azure-sdk-for-js", "bugs": { "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, - "nyc": { - "extension": [ - ".ts" - ], - "exclude": [ - "coverage/**/*", - "**/*.d.ts", - "**/*.js" - ], - "reporter": [ - "text", - "html", - "cobertura" - ], - "all": true - }, + "sideEffects": false, "scripts": { "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* types *.log browser statistics.html coverage src/**/*.js test/**/*.js", + "clean": "rimraf --glob dist dist-* types *.log browser statistics.html coverage src/**/*.js test/**/*.js", "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", + "extract-api": "tshy && api-extractor run --local", "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "integration-test:browser": "echo skipped", "integration-test:node": "echo skipped", @@ -84,43 +80,47 @@ "test:browser": "npm run build:test && npm run unit-test:browser && npm run integration-test:browser", "test:node": "npm run build:test && npm run unit-test:node && npm run integration-test:node", "test": "npm run build:test && npm run unit-test", - "unit-test": "npm run unit-test:node && npm run unit-test:browser", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true" + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" }, - "sideEffects": false, "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/core-rest-pipeline": "^1.1.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@azure/dev-tool": "^1.0.0", - "@azure/test-utils": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "c8": "^8.0.0", - "rimraf": "^3.0.0", - "ts-node": "^10.0.0", - "typescript": "~5.3.3" + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", + "typescript": "~5.3.3", + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-lro/src/http/models.ts b/sdk/core/core-lro/src/http/models.ts index c914b1d07f4e..c14eb56ef658 100644 --- a/sdk/core/core-lro/src/http/models.ts +++ b/sdk/core/core-lro/src/http/models.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { AbortSignalLike } from "@azure/abort-controller"; -import { LroError } from "../poller/models"; +import { LroError } from "../poller/models.js"; // TODO: rename to ResourceLocationConfig /** diff --git a/sdk/core/core-lro/src/http/operation.ts b/sdk/core/core-lro/src/http/operation.ts index 3d210a8e27e6..59381dea9a76 100644 --- a/sdk/core/core-lro/src/http/operation.ts +++ b/sdk/core/core-lro/src/http/operation.ts @@ -8,17 +8,17 @@ import { LroResponse, RawResponse, ResponseBody, -} from "./models"; +} from "./models.js"; import { LroError, OperationConfig, OperationStatus, RestorableOperationState, StateProxy, -} from "../poller/models"; -import { initOperation, pollOperation } from "../poller/operation"; +} from "../poller/models.js"; +import { initOperation, pollOperation } from "../poller/operation.js"; import { AbortSignalLike } from "@azure/abort-controller"; -import { logger } from "../logger"; +import { logger } from "../logger.js"; function getOperationLocationPollingUrl(inputs: { operationLocation?: string; @@ -367,7 +367,8 @@ export async function pollHttpOperation(inputs: { * The expansion here is intentional because `lro` could be an object that * references an inner this, so we need to preserve a reference to it. */ - poll: async (location, inputOptions) => lro.sendPollRequest(location, inputOptions), + poll: async (location: string, inputOptions?: { abortSignal?: AbortSignalLike }) => + lro.sendPollRequest(location, inputOptions), setErrorAsResult, }); } diff --git a/sdk/core/core-lro/src/http/poller.ts b/sdk/core/core-lro/src/http/poller.ts index 7e29dadcd0e4..ff30fd5534c2 100644 --- a/sdk/core/core-lro/src/http/poller.ts +++ b/sdk/core/core-lro/src/http/poller.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LongRunningOperation, LroResponse } from "./models"; -import { OperationState, SimplePollerLike } from "../poller/models"; +import { LongRunningOperation, LroResponse } from "./models.js"; +import { OperationState, SimplePollerLike } from "../poller/models.js"; import { getErrorFromResponse, getOperationLocation, @@ -12,9 +12,9 @@ import { inferLroMode, isOperationError, parseRetryAfter, -} from "./operation"; -import { CreateHttpPollerOptions } from "./models"; -import { buildCreatePoller } from "../poller/poller"; +} from "./operation.js"; +import { CreateHttpPollerOptions } from "./models.js"; +import { buildCreatePoller } from "../poller/poller.js"; /** * Creates a poller that can be used to poll a long-running operation. diff --git a/sdk/core/core-lro/src/index.ts b/sdk/core/core-lro/src/index.ts index 3b5770426bf5..6f8a47de4dbb 100644 --- a/sdk/core/core-lro/src/index.ts +++ b/sdk/core/core-lro/src/index.ts @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { createHttpPoller } from "./http/poller"; +export { createHttpPoller } from "./http/poller.js"; export { CancelOnProgress, OperationState, OperationStatus, SimplePollerLike, -} from "./poller/models"; -export { CreateHttpPollerOptions } from "./http/models"; +} from "./poller/models.js"; +export { CreateHttpPollerOptions } from "./http/models.js"; export { LroResourceLocationConfig, LongRunningOperation, LroResponse, RawResponse, -} from "./http/models"; +} from "./http/models.js"; /** * This can be uncommented to expose the protocol-agnostic poller @@ -29,7 +29,7 @@ export { // export { buildCreatePoller } from "./poller/poller"; /** legacy */ -export * from "./legacy/lroEngine"; -export * from "./legacy/poller"; -export * from "./legacy/pollOperation"; -export { PollerLike } from "./legacy/models"; +export * from "./legacy/lroEngine/index.js"; +export * from "./legacy/poller.js"; +export * from "./legacy/pollOperation.js"; +export { PollerLike } from "./legacy/models.js"; diff --git a/sdk/core/core-lro/src/legacy/lroEngine/index.ts b/sdk/core/core-lro/src/legacy/lroEngine/index.ts index 9d77fcd5b8fd..a028cb8974f7 100644 --- a/sdk/core/core-lro/src/legacy/lroEngine/index.ts +++ b/sdk/core/core-lro/src/legacy/lroEngine/index.ts @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { LroEngine } from "./lroEngine"; -export { LroEngineOptions } from "./models"; +export { LroEngine } from "./lroEngine.js"; +export { LroEngineOptions } from "./models.js"; diff --git a/sdk/core/core-lro/src/legacy/lroEngine/lroEngine.ts b/sdk/core/core-lro/src/legacy/lroEngine/lroEngine.ts index a1c1c8bd7bbd..88c37ac7d1d9 100644 --- a/sdk/core/core-lro/src/legacy/lroEngine/lroEngine.ts +++ b/sdk/core/core-lro/src/legacy/lroEngine/lroEngine.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LroEngineOptions, PollerConfig } from "./models"; -import { GenericPollOperation } from "./operation"; -import { LongRunningOperation } from "../../http/models"; -import { POLL_INTERVAL_IN_MS } from "../../poller/constants"; -import { PollOperationState } from "../pollOperation"; -import { Poller } from "../poller"; -import { RestorableOperationState } from "../../poller/models"; -import { deserializeState } from "../../poller/operation"; +import { LroEngineOptions, PollerConfig } from "./models.js"; +import { GenericPollOperation } from "./operation.js"; +import { LongRunningOperation } from "../../http/models.js"; +import { POLL_INTERVAL_IN_MS } from "../../poller/constants.js"; +import { PollOperationState } from "../pollOperation.js"; +import { Poller } from "../poller.js"; +import { RestorableOperationState } from "../../poller/models.js"; +import { deserializeState } from "../../poller/operation.js"; /** * The LRO Engine, a class that performs polling. diff --git a/sdk/core/core-lro/src/legacy/lroEngine/models.ts b/sdk/core/core-lro/src/legacy/lroEngine/models.ts index c2ee85447c77..49dffa734a4a 100644 --- a/sdk/core/core-lro/src/legacy/lroEngine/models.ts +++ b/sdk/core/core-lro/src/legacy/lroEngine/models.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LroResourceLocationConfig, RawResponse } from "../../http/models"; +import { LroResourceLocationConfig, RawResponse } from "../../http/models.js"; /** * Options for the LRO poller. diff --git a/sdk/core/core-lro/src/legacy/lroEngine/operation.ts b/sdk/core/core-lro/src/legacy/lroEngine/operation.ts index 9394fb6d9e32..9fe1ef5690b8 100644 --- a/sdk/core/core-lro/src/legacy/lroEngine/operation.ts +++ b/sdk/core/core-lro/src/legacy/lroEngine/operation.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LongRunningOperation, LroResourceLocationConfig, RawResponse } from "../../http/models"; -import { PollOperation, PollOperationState } from "../pollOperation"; -import { RestorableOperationState, StateProxy } from "../../poller/models"; -import { initHttpOperation, pollHttpOperation } from "../../http/operation"; +import { LongRunningOperation, LroResourceLocationConfig, RawResponse } from "../../http/models.js"; +import { PollOperation, PollOperationState } from "../pollOperation.js"; +import { RestorableOperationState, StateProxy } from "../../poller/models.js"; +import { initHttpOperation, pollHttpOperation } from "../../http/operation.js"; import { AbortSignalLike } from "@azure/abort-controller"; -import { PollerConfig } from "./models"; -import { logger } from "../../logger"; +import { PollerConfig } from "./models.js"; +import { logger } from "../../logger.js"; const createStateProxy: >() => StateProxy< TState, diff --git a/sdk/core/core-lro/src/legacy/models.ts b/sdk/core/core-lro/src/legacy/models.ts index 25d5507a10cb..6316e1048720 100644 --- a/sdk/core/core-lro/src/legacy/models.ts +++ b/sdk/core/core-lro/src/legacy/models.ts @@ -2,8 +2,8 @@ // Licensed under the MIT license. import { AbortSignalLike } from "@azure/abort-controller"; -import { CancelOnProgress } from "../poller/models"; -import { PollOperationState } from "./pollOperation"; +import { CancelOnProgress } from "../poller/models.js"; +import { PollOperationState } from "./pollOperation.js"; /** * Abstract representation of a poller, intended to expose just the minimal API that the user needs to work with. diff --git a/sdk/core/core-lro/src/legacy/poller.ts b/sdk/core/core-lro/src/legacy/poller.ts index 9609ef5e8297..53b6082b1040 100644 --- a/sdk/core/core-lro/src/legacy/poller.ts +++ b/sdk/core/core-lro/src/legacy/poller.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PollOperation, PollOperationState } from "./pollOperation"; +import { PollOperation, PollOperationState } from "./pollOperation.js"; import { AbortSignalLike } from "@azure/abort-controller"; -import { CancelOnProgress } from "../poller/models"; -import { PollerLike } from "./models"; +import { CancelOnProgress } from "../poller/models.js"; +import { PollerLike } from "./models.js"; /** * PollProgressCallback is the type of the callback functions sent to onProgress. diff --git a/sdk/core/core-lro/src/poller/operation.ts b/sdk/core/core-lro/src/poller/operation.ts index 7f17b9d648eb..1428873b169c 100644 --- a/sdk/core/core-lro/src/poller/operation.ts +++ b/sdk/core/core-lro/src/poller/operation.ts @@ -8,9 +8,9 @@ import { OperationStatus, RestorableOperationState, StateProxy, -} from "./models"; -import { logger } from "../logger"; -import { terminalStates } from "./constants"; +} from "./models.js"; +import { logger } from "../logger.js"; +import { terminalStates } from "./constants.js"; /** * Deserializes the state diff --git a/sdk/core/core-lro/src/poller/poller.ts b/sdk/core/core-lro/src/poller/poller.ts index 557529ab2c6c..a927a7686548 100644 --- a/sdk/core/core-lro/src/poller/poller.ts +++ b/sdk/core/core-lro/src/poller/poller.ts @@ -10,9 +10,9 @@ import { RestorableOperationState, SimplePollerLike, StateProxy, -} from "./models"; -import { deserializeState, initOperation, pollOperation } from "./operation"; -import { POLL_INTERVAL_IN_MS } from "./constants"; +} from "./models.js"; +import { deserializeState, initOperation, pollOperation } from "./operation.js"; +import { POLL_INTERVAL_IN_MS } from "./constants.js"; import { delay } from "@azure/core-util"; const createStateProxy: >() => StateProxy< diff --git a/sdk/core/core-lro/test/getYieldedValue.ts b/sdk/core/core-lro/test/getYieldedValue.ts new file mode 100644 index 000000000000..b8a0cea9a32e --- /dev/null +++ b/sdk/core/core-lro/test/getYieldedValue.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { assert } from "vitest"; + +/** + * Returns the currently yielded value from an iterator if it exists, otherwise, it throws an assertion failure. + * @param iteratorResult - The result of the current iteration + * @returns the currently yielded value + */ +export function getYieldedValue(iteratorResult: IteratorResult): YT { + if (iteratorResult.done) { + assert.fail(`Expected an item but did not get any`); + } + return iteratorResult.value; +} diff --git a/sdk/core/core-lro/test/lro.spec.ts b/sdk/core/core-lro/test/lro.spec.ts index 9b7e7aa1c88b..9eaccf6c527d 100644 --- a/sdk/core/core-lro/test/lro.spec.ts +++ b/sdk/core/core-lro/test/lro.spec.ts @@ -6,9 +6,10 @@ import { assertDivergentBehavior, assertError, createDoubleHeaders, -} from "./utils/utils"; -import { assert, matrix } from "@azure/test-utils"; -import { createRunLroWith, createTestPoller } from "./utils/router"; +} from "./utils/utils.js"; +import { describe, it, assert } from "vitest"; +import { createRunLroWith, createTestPoller } from "./utils/router.js"; +import { matrix } from "./matrix.js"; matrix( [ diff --git a/sdk/core/core-lro/test/matrix.ts b/sdk/core/core-lro/test/matrix.ts new file mode 100644 index 000000000000..14b3295e4ae3 --- /dev/null +++ b/sdk/core/core-lro/test/matrix.ts @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** + * Takes a jagged 2D array and a function and runs the function with every + * possible combination of elements of each of the arrays + * + * For strong type-checking, it is important that the `matrix` have a strong + * type, such as a `const` literal. + * + * @param values - jagged 2D array specifying the arguments and their possible + * values + * @param handler - the function to run with the different argument combinations + * + * @example + * ```typescript + * matrix([ + * [true, false], + * [1, 2, 3] + * ] as const, + * (useLabels: boolean, attempts: number) => { + * // This body will run six times with the following parameters: + * // - true, 1 + * // - true, 2 + * // - true, 3 + * // - false, 1 + * // - false, 2 + * // - false, 3 + * }); + * ``` + */ +export function matrix>( + values: T, + handler: ( + ...args: { [idx in keyof T]: T[idx] extends ReadonlyArray ? U : never } + ) => Promise, +): void { + // Classic recursive approach + if (values.length === 0) { + (handler as () => Promise)(); + } else { + for (const v of values[0]) { + matrix(values.slice(1), (...args) => (handler as any)(v, ...args)); + } + } +} diff --git a/sdk/core/core-lro/test/utils/coreRestPipelineLro.ts b/sdk/core/core-lro/test/utils/coreRestPipelineLro.ts index 1144bf30d10f..9d2bfc71d6d3 100644 --- a/sdk/core/core-lro/test/utils/coreRestPipelineLro.ts +++ b/sdk/core/core-lro/test/utils/coreRestPipelineLro.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LongRunningOperation, LroResponse } from "../../src"; +import { LongRunningOperation, LroResponse } from "../../src/index.js"; import { AbortSignalLike } from "@azure/abort-controller"; import { PipelineRequest } from "@azure/core-rest-pipeline"; diff --git a/sdk/core/core-lro/test/utils/router.ts b/sdk/core/core-lro/test/utils/router.ts index 4f0767a54741..7ba657c9fe72 100644 --- a/sdk/core/core-lro/test/utils/router.ts +++ b/sdk/core/core-lro/test/utils/router.ts @@ -17,12 +17,12 @@ import { State, createProcessor, generate, -} from "./utils"; -import { LroEngine, LroResponse, SimplePollerLike, createHttpPoller } from "../../src"; -import { LroResourceLocationConfig, RawResponse, ResponseBody } from "../../src/http/models"; +} from "./utils.js"; +import { LroEngine, LroResponse, SimplePollerLike, createHttpPoller } from "../../src/index.js"; +import { LroResourceLocationConfig, RawResponse, ResponseBody } from "../../src/http/models.js"; import { AbortError } from "@azure/abort-controller"; -import { createCoreRestPipelineLro } from "./coreRestPipelineLro"; -import { getYieldedValue } from "@azure/test-utils"; +import { createCoreRestPipelineLro } from "./coreRestPipelineLro.js"; +import { getYieldedValue } from "../getYieldedValue.js"; /** * Dummy value for the path of the initial request diff --git a/sdk/core/core-lro/test/utils/utils.ts b/sdk/core/core-lro/test/utils/utils.ts index 58515a1b10f5..a4fae1ed18df 100644 --- a/sdk/core/core-lro/test/utils/utils.ts +++ b/sdk/core/core-lro/test/utils/utils.ts @@ -8,8 +8,8 @@ import { createHttpHeaders, isRestError, } from "@azure/core-rest-pipeline"; -import { ResponseBody } from "../../src/http/models"; -import { assert } from "@azure/test-utils"; +import { ResponseBody } from "../../src/http/models.js"; +import { assert } from "vitest"; export interface RouteProcessor { method: string; diff --git a/sdk/core/core-lro/tsconfig.browser.config.json b/sdk/core/core-lro/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-lro/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-lro/tsconfig.json b/sdk/core/core-lro/tsconfig.json index 03fc9ff7ca4c..3e8c17549c80 100644 --- a/sdk/core/core-lro/tsconfig.json +++ b/sdk/core/core-lro/tsconfig.json @@ -1,9 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types" + "paths": { + "@azure/core-lro": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "exclude": ["node_modules", "./samples/**/*.ts"], - "include": ["./src/**/*.ts", "./test/**/*.ts"] + "exclude": ["./samples/**/*.ts"], + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/core-lro/vitest.browser.config.ts b/sdk/core/core-lro/vitest.browser.config.ts new file mode 100644 index 000000000000..6b383703b637 --- /dev/null +++ b/sdk/core/core-lro/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-lro/vitest.config.ts b/sdk/core/core-lro/vitest.config.ts new file mode 100644 index 000000000000..f46a08861fab --- /dev/null +++ b/sdk/core/core-lro/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "v8", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-paging/.eslintrc.json b/sdk/core/core-paging/.eslintrc.json index 591615ee984d..8ac2c924a7f0 100644 --- a/sdk/core/core-paging/.eslintrc.json +++ b/sdk/core/core-paging/.eslintrc.json @@ -2,8 +2,10 @@ "plugins": ["@azure/azure-sdk"], "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], "rules": { - // `package.json`'s sideEffects has to be true because this package loads a - // polyfill. - "@azure/azure-sdk/ts-package-json-sideeffects": "off" + "@azure/azure-sdk/ts-package-json-sideeffects": "off", + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-files-required": "off", + "@azure/azure-sdk/ts-package-json-main-is-cjs": "off", + "@azure/azure-sdk/ts-package-json-types": "off" } } diff --git a/sdk/core/core-paging/.tshy/browser.json b/sdk/core/core-paging/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-paging/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-paging/.tshy/build.json b/sdk/core/core-paging/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-paging/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-paging/.tshy/commonjs.json b/sdk/core/core-paging/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/core-paging/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-paging/.tshy/esm.json b/sdk/core/core-paging/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/core-paging/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-paging/.tshy/react-native.json b/sdk/core/core-paging/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/core-paging/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-paging/api-extractor.json b/sdk/core/core-paging/api-extractor.json index a56e56bfda67..9a1dd2ae62c0 100644 --- a/sdk/core/core-paging/api-extractor.json +++ b/sdk/core/core-paging/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-paging.d.ts" + "publicTrimmedFilePath": "./dist/core-paging.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-paging/karma.conf.js b/sdk/core/core-paging/karma.conf.js deleted file mode 100644 index 6c6511f22729..000000000000 --- a/sdk/core/core-paging/karma.conf.js +++ /dev/null @@ -1,108 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: ["dist-test/index.browser.js"], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - // EXAMPLE: envPreprocessor: ["ACCOUNT_NAME", "ACCOUNT_SAS"], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-paging/package.json b/sdk/core/core-paging/package.json index fe5376918373..5cdfdfe26017 100644 --- a/sdk/core/core-paging/package.json +++ b/sdk/core/core-paging/package.json @@ -4,6 +4,30 @@ "sdk-type": "client", "version": "1.5.1", "description": "Core types for paging async iterable iterators", + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, "tags": [ "microsoft", "clientruntime" @@ -14,20 +38,8 @@ "azure", "cloud" ], - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "types": "./types/latest/core-paging.d.ts", - "typesVersions": { - "<3.6": { - "types/latest/*": [ - "types/3.1/*" - ] - } - }, "files": [ - "types/latest/core-paging.d.ts", "dist/", - "dist-esm/src/", "LICENSE", "README.md" ], @@ -40,14 +52,16 @@ "bugs": { "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, + "sideEffects": true, + "private": false, "scripts": { "build:samples": "echo Obsolete", - "build:test": "echo skipped", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp *.tgz types *.log", + "clean": "rimraf --glob dist dist-* temp *.tgz types *.log", "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", + "extract-api": "tshy && api-extractor run --local", "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", "integration-test:browser": "echo skipped", "integration-test:node": "echo skipped", @@ -56,40 +70,29 @@ "lint:fix": "eslint package.json src --ext .ts --fix --fix-type [problem,suggestion]", "pack": "npm pack 2>&1", "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", "unit-test": "npm run unit-test:node && npm run unit-test:browser" }, - "sideEffects": true, - "private": false, "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "rimraf": "^3.0.0", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "ts-node": "^10.0.0" + "vitest": "^1.2.2" }, "//metadata": { "sampleConfiguration": { @@ -101,5 +104,19 @@ ] }, "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-paging/src/getPagedAsyncIterator.ts b/sdk/core/core-paging/src/getPagedAsyncIterator.ts index 448462329de6..2eed55afe860 100644 --- a/sdk/core/core-paging/src/getPagedAsyncIterator.ts +++ b/sdk/core/core-paging/src/getPagedAsyncIterator.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PageSettings, PagedAsyncIterableIterator, PagedResult } from "./models"; +import { PageSettings, PagedAsyncIterableIterator, PagedResult } from "./models.js"; /** * returns an async iterator that iterates over results. It also has a `byPage` diff --git a/sdk/core/core-paging/src/index.ts b/sdk/core/core-paging/src/index.ts index 4e318417281f..da4a1e554528 100644 --- a/sdk/core/core-paging/src/index.ts +++ b/sdk/core/core-paging/src/index.ts @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export * from "./models"; -export * from "./getPagedAsyncIterator"; +export * from "./models.js"; +export * from "./getPagedAsyncIterator.js"; diff --git a/sdk/core/core-paging/test/getPagedAsyncIterator.spec.ts b/sdk/core/core-paging/test/getPagedAsyncIterator.spec.ts index a11f172b8bf7..9d72391dfd69 100644 --- a/sdk/core/core-paging/test/getPagedAsyncIterator.spec.ts +++ b/sdk/core/core-paging/test/getPagedAsyncIterator.spec.ts @@ -1,10 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { getPagedAsyncIterator, PagedResult, PageSettings } from "../src"; +import { describe, it, assert } from "vitest"; +import { + getPagedAsyncIterator, + PagedAsyncIterableIterator, + PagedResult, + PageSettings, +} from "../src/index.js"; -function buildIterator(input: T) { +function buildIterator(input: T): PagedAsyncIterableIterator { return getPagedAsyncIterator({ firstPageLink: 0, getPage: async () => ({ page: input }), @@ -60,7 +65,7 @@ describe("getPagedAsyncIterator", function () { }, }; const iterator = getPagedAsyncIterator(pagedResult); - let receivedItems = []; + const receivedItems = []; for await (const val of iterator) { receivedItems.push(val); } @@ -82,8 +87,8 @@ describe("getPagedAsyncIterator", function () { const collection = Array.from(Array(10), (_, i) => i + 1); const pagedResult: PagedResult, PageSettings, number> = { firstPageLink: 0, - async getPage(pageLink, maxPageSize) { - const top = maxPageSize || 5; + async getPage(pageLink, innerMaxPageSize) { + const top = innerMaxPageSize || 5; if (pageLink < collection.length) { return Promise.resolve({ page: { @@ -102,7 +107,7 @@ describe("getPagedAsyncIterator", function () { PageSettings, number >(pagedResult); - let receivedItems = []; // they're pages too + const receivedItems = []; // they're pages too let pagesCount = 0; for await (const val of iterator) { ++pagesCount; @@ -122,17 +127,17 @@ describe("getPagedAsyncIterator", function () { }); describe("Iterator over object", function () { - interface collectionObject { + interface CollectionObject { elements: number[]; next: number; } it("should return an iterator over an object that can extract elements", async function () { - const collection: collectionObject = { + const collection: CollectionObject = { elements: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], next: 0, }; - const pagedResult: PagedResult = { + const pagedResult: PagedResult = { firstPageLink: 0, getPage: async () => ({ page: collection }), toElements: (page) => page.elements, @@ -170,7 +175,9 @@ describe("getPagedAsyncIterator", function () { describe("Strong typing experience", function () { type IsAny = boolean extends (T extends never ? true : false) ? true : false; + // eslint-disable-next-line @typescript-eslint/no-empty-function function assertNotAny extends true ? never : any>(_: T): void {} + // eslint-disable-next-line @typescript-eslint/no-empty-function function assertAny extends false ? never : any>(_: T): void {} const totalElementsCount = 100; diff --git a/sdk/core/core-paging/tsconfig.browser.config.json b/sdk/core/core-paging/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-paging/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-paging/tsconfig.json b/sdk/core/core-paging/tsconfig.json index a39070c75bb3..37aaa8bf5021 100644 --- a/sdk/core/core-paging/tsconfig.json +++ b/sdk/core/core-paging/tsconfig.json @@ -1,11 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest", "paths": { - "@azure/core-paging": ["./src/index"] - } + "@azure/core-paging": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts", "test/**/*.ts", "samples-dev/**/*.ts"] + "exclude": ["./samples/**/*.ts"], + "include": ["./src/**/*.ts", "./src/**/*.mts", "./samples-dev/**/*.ts"] } diff --git a/sdk/core/core-paging/vitest.browser.config.ts b/sdk/core/core-paging/vitest.browser.config.ts new file mode 100644 index 000000000000..005a2f7d4b67 --- /dev/null +++ b/sdk/core/core-paging/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-paging/vitest.config.ts b/sdk/core/core-paging/vitest.config.ts new file mode 100644 index 000000000000..7c014c00af62 --- /dev/null +++ b/sdk/core/core-paging/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-rest-pipeline/.tshy/browser.json b/sdk/core/core-rest-pipeline/.tshy/browser.json new file mode 100644 index 000000000000..80ee974f70b0 --- /dev/null +++ b/sdk/core/core-rest-pipeline/.tshy/browser.json @@ -0,0 +1,15 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/defaultHttpClient-react-native.mts", + ".././src/util/userAgentPlatform-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-rest-pipeline/.tshy/build.json b/sdk/core/core-rest-pipeline/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-rest-pipeline/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-rest-pipeline/.tshy/commonjs.json b/sdk/core/core-rest-pipeline/.tshy/commonjs.json new file mode 100644 index 000000000000..d003c0ec8c0d --- /dev/null +++ b/sdk/core/core-rest-pipeline/.tshy/commonjs.json @@ -0,0 +1,22 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/defaultHttpClient-browser.mts", + "../src/policies/decompressResponsePolicy-browser.mts", + "../src/policies/proxyPolicy-browser.mts", + "../src/util/concat-browser.mts", + "../src/util/inspect-browser.mts", + "../src/util/userAgentPlatform-browser.mts", + "../src/defaultHttpClient-react-native.mts", + "../src/util/userAgentPlatform-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-rest-pipeline/.tshy/esm.json b/sdk/core/core-rest-pipeline/.tshy/esm.json new file mode 100644 index 000000000000..75ed41fa5d3c --- /dev/null +++ b/sdk/core/core-rest-pipeline/.tshy/esm.json @@ -0,0 +1,21 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/defaultHttpClient-browser.mts", + ".././src/policies/decompressResponsePolicy-browser.mts", + ".././src/policies/proxyPolicy-browser.mts", + ".././src/util/concat-browser.mts", + ".././src/util/inspect-browser.mts", + ".././src/util/userAgentPlatform-browser.mts", + ".././src/defaultHttpClient-react-native.mts", + ".././src/util/userAgentPlatform-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-rest-pipeline/.tshy/react-native.json b/sdk/core/core-rest-pipeline/.tshy/react-native.json new file mode 100644 index 000000000000..97df88d94cff --- /dev/null +++ b/sdk/core/core-rest-pipeline/.tshy/react-native.json @@ -0,0 +1,19 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/defaultHttpClient-browser.mts", + ".././src/policies/decompressResponsePolicy-browser.mts", + ".././src/policies/proxyPolicy-browser.mts", + ".././src/util/concat-browser.mts", + ".././src/util/inspect-browser.mts", + ".././src/util/userAgentPlatform-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-rest-pipeline/api-extractor.json b/sdk/core/core-rest-pipeline/api-extractor.json index 0e57a5f62e66..2e195a0d12de 100644 --- a/sdk/core/core-rest-pipeline/api-extractor.json +++ b/sdk/core/core-rest-pipeline/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-rest-pipeline.d.ts" + "publicTrimmedFilePath": "./dist/core-rest-pipeline.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-rest-pipeline/core-rest-pipeline.shims.d.ts b/sdk/core/core-rest-pipeline/core-rest-pipeline.shims.d.ts deleted file mode 100644 index 718d5fdc777b..000000000000 --- a/sdk/core/core-rest-pipeline/core-rest-pipeline.shims.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -declare global { - interface FormData {} - interface Blob {} - interface File {} - interface ReadableStream {} - interface TransformStream {} -} - -export * from "./types/latest/core-rest-pipeline"; diff --git a/sdk/core/core-rest-pipeline/package.json b/sdk/core/core-rest-pipeline/package.json index cc16e37dd4f3..db949431144f 100644 --- a/sdk/core/core-rest-pipeline/package.json +++ b/sdk/core/core-rest-pipeline/package.json @@ -3,49 +3,32 @@ "version": "1.14.1", "description": "Isomorphic client library for making HTTP requests in node.js and browser.", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/defaultHttpClient.js": "./dist-esm/src/defaultHttpClient.browser.js", - "./dist-esm/src/policies/decompressResponsePolicy.js": "./dist-esm/src/policies/decompressResponsePolicy.browser.js", - "./dist-esm/src/policies/proxyPolicy.js": "./dist-esm/src/policies/proxyPolicy.browser.js", - "./dist-esm/src/util/concat.js": "./dist-esm/src/util/concat.browser.js", - "./dist-esm/src/util/inspect.js": "./dist-esm/src/util/inspect.browser.js", - "./dist-esm/src/util/userAgentPlatform.js": "./dist-esm/src/util/userAgentPlatform.browser.js" - }, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js", - "./dist-esm/src/defaultHttpClient.js": "./dist-esm/src/defaultHttpClient.native.js", - "./dist-esm/src/util/userAgentPlatform.js": "./dist-esm/src/util/userAgentPlatform.native.js" - }, - "types": "core-rest-pipeline.shims.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "echo Obsolete", - "build": "npm run clean && tsc -p . && dev-tool run bundle --browser-test false && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run unit-test:node && npm run integration-test:node", - "test": "npm run test:node && npm run test:browser", - "unit-test:browser": "dev-tool run test:vitest --no-test-proxy=true --browser=true", - "unit-test:node": "dev-tool run test:vitest --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/latest/core-rest-pipeline.d.ts", - "core-rest-pipeline.shims.d.ts", "LICENSE", "README.md" ], @@ -65,6 +48,28 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-rest-pipeline/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "//metadata": { "constantPaths": [ { @@ -88,21 +93,39 @@ "@azure/core-tracing": "^1.0.1", "@azure/core-util": "^1.3.0", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0", "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0" + "https-proxy-agent": "^5.0.0", + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@azure-tools/vite-plugin-browser-test-map": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", + "@microsoft/api-extractor": "^7.39.5", + "@opentelemetry/api": "^1.4.1", "@types/node": "^18.0.0", - "@vitest/browser": "^1.2.1", - "eslint": "^8.0.0", - "playwright": "^1.39.0", - "rimraf": "^3.0.0", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "vitest": "^1.2.1" + "vitest": "^1.2.2" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-rest-pipeline/review/core-rest-pipeline.api.md b/sdk/core/core-rest-pipeline/review/core-rest-pipeline.api.md index 1f6b0890cbab..1e231925ac89 100644 --- a/sdk/core/core-rest-pipeline/review/core-rest-pipeline.api.md +++ b/sdk/core/core-rest-pipeline/review/core-rest-pipeline.api.md @@ -8,7 +8,7 @@ import type { AbortSignalLike } from '@azure/abort-controller'; import type { AccessToken } from '@azure/core-auth'; -import type { AzureLogger } from '@azure/logger'; +import { AzureLogger } from '@azure/logger'; import type { Debugger } from '@azure/logger'; import type { GetTokenOptions } from '@azure/core-auth'; import type { OperationTracingOptions } from '@azure/core-tracing'; diff --git a/sdk/core/core-rest-pipeline/samples-dev/.gitkeep b/sdk/core/core-rest-pipeline/samples-dev/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sdk/core/core-rest-pipeline/src/createPipelineFromOptions.ts b/sdk/core/core-rest-pipeline/src/createPipelineFromOptions.ts index 2aaec80a9f08..85d5da2cfb75 100644 --- a/sdk/core/core-rest-pipeline/src/createPipelineFromOptions.ts +++ b/sdk/core/core-rest-pipeline/src/createPipelineFromOptions.ts @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { type LogPolicyOptions, logPolicy } from "./policies/logPolicy"; -import { type Pipeline, createEmptyPipeline } from "./pipeline"; -import type { PipelineRetryOptions, TlsSettings, ProxySettings } from "./interfaces"; -import { type RedirectPolicyOptions, redirectPolicy } from "./policies/redirectPolicy"; -import { type UserAgentPolicyOptions, userAgentPolicy } from "./policies/userAgentPolicy"; -import { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy"; -import { decompressResponsePolicy } from "./policies/decompressResponsePolicy"; -import { defaultRetryPolicy } from "./policies/defaultRetryPolicy"; -import { formDataPolicy } from "./policies/formDataPolicy"; +import { type LogPolicyOptions, logPolicy } from "./policies/logPolicy.js"; +import { type Pipeline, createEmptyPipeline } from "./pipeline.js"; +import type { PipelineRetryOptions, TlsSettings, ProxySettings } from "./interfaces.js"; +import { type RedirectPolicyOptions, redirectPolicy } from "./policies/redirectPolicy.js"; +import { type UserAgentPolicyOptions, userAgentPolicy } from "./policies/userAgentPolicy.js"; +import { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js"; +import { decompressResponsePolicy } from "./policies/decompressResponsePolicy.js"; +import { defaultRetryPolicy } from "./policies/defaultRetryPolicy.js"; +import { formDataPolicy } from "./policies/formDataPolicy.js"; import { isNode } from "@azure/core-util"; -import { proxyPolicy } from "./policies/proxyPolicy"; -import { setClientRequestIdPolicy } from "./policies/setClientRequestIdPolicy"; -import { tlsPolicy } from "./policies/tlsPolicy"; -import { tracingPolicy } from "./policies/tracingPolicy"; +import { proxyPolicy } from "./policies/proxyPolicy.js"; +import { setClientRequestIdPolicy } from "./policies/setClientRequestIdPolicy.js"; +import { tlsPolicy } from "./policies/tlsPolicy.js"; +import { tracingPolicy } from "./policies/tracingPolicy.js"; /** * Defines options that are used to configure the HTTP pipeline for diff --git a/sdk/core/core-rest-pipeline/src/defaultHttpClient.browser.ts b/sdk/core/core-rest-pipeline/src/defaultHttpClient-browser.mts similarity index 67% rename from sdk/core/core-rest-pipeline/src/defaultHttpClient.browser.ts rename to sdk/core/core-rest-pipeline/src/defaultHttpClient-browser.mts index 94659fb1a8c0..2c0df0c1b0f7 100644 --- a/sdk/core/core-rest-pipeline/src/defaultHttpClient.browser.ts +++ b/sdk/core/core-rest-pipeline/src/defaultHttpClient-browser.mts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { HttpClient } from "./interfaces"; -import { createFetchHttpClient } from "./fetchHttpClient"; +import type { HttpClient } from "./interfaces.js"; +import { createFetchHttpClient } from "./fetchHttpClient.js"; /** * Create the correct HttpClient for the current environment. diff --git a/sdk/core/ts-http-runtime/src/defaultHttpClient.native.ts b/sdk/core/core-rest-pipeline/src/defaultHttpClient-react-native.mts similarity index 68% rename from sdk/core/ts-http-runtime/src/defaultHttpClient.native.ts rename to sdk/core/core-rest-pipeline/src/defaultHttpClient-react-native.mts index d9708b80da71..a14d458f5b59 100644 --- a/sdk/core/ts-http-runtime/src/defaultHttpClient.native.ts +++ b/sdk/core/core-rest-pipeline/src/defaultHttpClient-react-native.mts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { HttpClient } from "./interfaces"; -import { createXhrHttpClient } from "./xhrHttpClient"; +import type { HttpClient } from "./interfaces.js"; +import { createXhrHttpClient } from "./xhrHttpClient.js"; /** * Create the correct HttpClient for the current environment. diff --git a/sdk/core/core-rest-pipeline/src/defaultHttpClient.ts b/sdk/core/core-rest-pipeline/src/defaultHttpClient.ts index 8d6173bbd9d4..86b9b16013b6 100644 --- a/sdk/core/core-rest-pipeline/src/defaultHttpClient.ts +++ b/sdk/core/core-rest-pipeline/src/defaultHttpClient.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { HttpClient } from "./interfaces"; -import { createNodeHttpClient } from "./nodeHttpClient"; +import type { HttpClient } from "./interfaces.js"; +import { createNodeHttpClient } from "./nodeHttpClient.js"; /** * Create the correct HttpClient for the current environment. diff --git a/sdk/core/core-rest-pipeline/src/fetchHttpClient.ts b/sdk/core/core-rest-pipeline/src/fetchHttpClient.ts index 606060b7f654..5940ce2795b5 100644 --- a/sdk/core/core-rest-pipeline/src/fetchHttpClient.ts +++ b/sdk/core/core-rest-pipeline/src/fetchHttpClient.ts @@ -8,10 +8,10 @@ import type { PipelineRequest, PipelineResponse, TransferProgressEvent, -} from "./interfaces"; -import { RestError } from "./restError"; -import { createHttpHeaders } from "./httpHeaders"; -import { isNodeReadableStream, isWebReadableStream } from "./util/typeGuards"; +} from "./interfaces.js"; +import { RestError } from "./restError.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { isNodeReadableStream, isWebReadableStream } from "./util/typeGuards.js"; /** * Checks if the body is a Blob or Blob-like @@ -103,7 +103,7 @@ async function buildPipelineResponse( httpResponse: Response, request: PipelineRequest, abortControllerCleanup?: () => void, -) { +): Promise { const headers = buildPipelineHeaders(httpResponse); const response: PipelineResponse = { request, @@ -184,6 +184,7 @@ function setupAbortSignal(request: PipelineRequest): { /** * Gets the specific error */ +// eslint-disable-next-line @azure/azure-sdk/ts-use-interface-parameters function getError(e: RestError, request: PipelineRequest): RestError { if (e && e?.name === "AbortError") { return e; @@ -198,7 +199,7 @@ function getError(e: RestError, request: PipelineRequest): RestError { /** * Converts PipelineRequest headers to Fetch headers */ -function buildFetchHeaders(pipelineHeaders: PipelineHeaders) { +function buildFetchHeaders(pipelineHeaders: PipelineHeaders): Headers { const headers = new Headers(); for (const [name, value] of pipelineHeaders) { headers.append(name, value); @@ -216,7 +217,20 @@ function buildPipelineHeaders(httpResponse: Response): PipelineHeaders { return responseHeaders; } -function buildRequestBody(request: PipelineRequest) { +interface BuildRequestBodyResponse { + body: + | string + | Blob + | ReadableStream + | ArrayBuffer + | ArrayBufferView + | FormData + | null + | undefined; + streaming: boolean; +} + +function buildRequestBody(request: PipelineRequest): BuildRequestBodyResponse { const body = typeof request.body === "function" ? request.body() : request.body; if (isNodeReadableStream(body)) { throw new Error("Node streams are not supported in browser environment."); diff --git a/sdk/core/core-rest-pipeline/src/httpHeaders.ts b/sdk/core/core-rest-pipeline/src/httpHeaders.ts index 5bb3c911f86b..4b97b3a6f029 100644 --- a/sdk/core/core-rest-pipeline/src/httpHeaders.ts +++ b/sdk/core/core-rest-pipeline/src/httpHeaders.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { HttpHeaders, RawHttpHeaders, RawHttpHeadersInput } from "./interfaces"; +import type { HttpHeaders, RawHttpHeaders, RawHttpHeadersInput } from "./interfaces.js"; interface HeaderEntry { name: string; diff --git a/sdk/core/core-rest-pipeline/src/index.ts b/sdk/core/core-rest-pipeline/src/index.ts index 4f2c1fd29eec..07d7dbc411aa 100644 --- a/sdk/core/core-rest-pipeline/src/index.ts +++ b/sdk/core/core-rest-pipeline/src/index.ts @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +/* eslint-disable @typescript-eslint/no-unused-vars */ +declare global { + interface FormData {} + interface Blob {} + interface File {} + interface ReadableStream {} + interface TransformStream {} +} +/* eslint-enable @typescript-eslint/no-unused-vars */ + export type { Agent, BodyPart, @@ -22,74 +32,77 @@ export type { SendRequest, TlsSettings, TransferProgressEvent, -} from "./interfaces"; +} from "./interfaces.js"; export { type AddPolicyOptions as AddPipelineOptions, type PipelinePhase, type PipelinePolicy, type Pipeline, createEmptyPipeline, -} from "./pipeline"; +} from "./pipeline.js"; export { createPipelineFromOptions, type TelemetryOptions, type InternalPipelineOptions, type PipelineOptions, -} from "./createPipelineFromOptions"; -export { createDefaultHttpClient } from "./defaultHttpClient"; -export { createHttpHeaders } from "./httpHeaders"; -export { createPipelineRequest, type PipelineRequestOptions } from "./pipelineRequest"; -export { RestError, type RestErrorOptions, isRestError } from "./restError"; +} from "./createPipelineFromOptions.js"; +export { createDefaultHttpClient } from "./defaultHttpClient.js"; +export { createHttpHeaders } from "./httpHeaders.js"; +export { createPipelineRequest, type PipelineRequestOptions } from "./pipelineRequest.js"; +export { RestError, type RestErrorOptions, isRestError } from "./restError.js"; export { decompressResponsePolicy, decompressResponsePolicyName, -} from "./policies/decompressResponsePolicy"; +} from "./policies/decompressResponsePolicy.js"; export { exponentialRetryPolicy, type ExponentialRetryPolicyOptions, exponentialRetryPolicyName, -} from "./policies/exponentialRetryPolicy"; +} from "./policies/exponentialRetryPolicy.js"; export { setClientRequestIdPolicy, setClientRequestIdPolicyName, -} from "./policies/setClientRequestIdPolicy"; -export { logPolicy, logPolicyName, type LogPolicyOptions } from "./policies/logPolicy"; -export { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy"; -export { proxyPolicy, proxyPolicyName, getDefaultProxySettings } from "./policies/proxyPolicy"; +} from "./policies/setClientRequestIdPolicy.js"; +export { logPolicy, logPolicyName, type LogPolicyOptions } from "./policies/logPolicy.js"; +export { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js"; +export { proxyPolicy, proxyPolicyName, getDefaultProxySettings } from "./policies/proxyPolicy.js"; export { redirectPolicy, redirectPolicyName, type RedirectPolicyOptions, -} from "./policies/redirectPolicy"; +} from "./policies/redirectPolicy.js"; export { systemErrorRetryPolicy, type SystemErrorRetryPolicyOptions, systemErrorRetryPolicyName, -} from "./policies/systemErrorRetryPolicy"; +} from "./policies/systemErrorRetryPolicy.js"; export { throttlingRetryPolicy, throttlingRetryPolicyName, type ThrottlingRetryPolicyOptions, -} from "./policies/throttlingRetryPolicy"; -export { retryPolicy, type RetryPolicyOptions } from "./policies/retryPolicy"; +} from "./policies/throttlingRetryPolicy.js"; +export { retryPolicy, type RetryPolicyOptions } from "./policies/retryPolicy.js"; export type { RetryStrategy, RetryInformation, RetryModifiers, -} from "./retryStrategies/retryStrategy"; +} from "./retryStrategies/retryStrategy.js"; export { tracingPolicy, tracingPolicyName, type TracingPolicyOptions, -} from "./policies/tracingPolicy"; -export { defaultRetryPolicy, type DefaultRetryPolicyOptions } from "./policies/defaultRetryPolicy"; +} from "./policies/tracingPolicy.js"; +export { + defaultRetryPolicy, + type DefaultRetryPolicyOptions, +} from "./policies/defaultRetryPolicy.js"; export { userAgentPolicy, userAgentPolicyName, type UserAgentPolicyOptions, -} from "./policies/userAgentPolicy"; -export { tlsPolicy, tlsPolicyName } from "./policies/tlsPolicy"; -export { formDataPolicy, formDataPolicyName } from "./policies/formDataPolicy"; +} from "./policies/userAgentPolicy.js"; +export { tlsPolicy, tlsPolicyName } from "./policies/tlsPolicy.js"; +export { formDataPolicy, formDataPolicyName } from "./policies/formDataPolicy.js"; export { bearerTokenAuthenticationPolicy, type BearerTokenAuthenticationPolicyOptions, @@ -97,16 +110,16 @@ export { type ChallengeCallbacks, type AuthorizeRequestOptions, type AuthorizeRequestOnChallengeOptions, -} from "./policies/bearerTokenAuthenticationPolicy"; -export { ndJsonPolicy, ndJsonPolicyName } from "./policies/ndJsonPolicy"; +} from "./policies/bearerTokenAuthenticationPolicy.js"; +export { ndJsonPolicy, ndJsonPolicyName } from "./policies/ndJsonPolicy.js"; export { auxiliaryAuthenticationHeaderPolicy, type AuxiliaryAuthenticationHeaderPolicyOptions, auxiliaryAuthenticationHeaderPolicyName, -} from "./policies/auxiliaryAuthenticationHeaderPolicy"; +} from "./policies/auxiliaryAuthenticationHeaderPolicy.js"; export { createFile, createFileFromStream, type CreateFileOptions, type CreateFileFromStreamOptions, -} from "./util/file"; +} from "./util/file.js"; diff --git a/sdk/core/core-rest-pipeline/src/nodeHttpClient.ts b/sdk/core/core-rest-pipeline/src/nodeHttpClient.ts index fdfc6b537808..5ec65a4f7538 100644 --- a/sdk/core/core-rest-pipeline/src/nodeHttpClient.ts +++ b/sdk/core/core-rest-pipeline/src/nodeHttpClient.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as http from "http"; -import * as https from "https"; -import * as zlib from "zlib"; -import { Transform } from "stream"; +import * as http from "node:http"; +import * as https from "node:https"; +import * as zlib from "node:zlib"; +import { Transform } from "node:stream"; import { AbortError } from "@azure/abort-controller"; import type { HttpClient, @@ -14,11 +14,11 @@ import type { RequestBodyType, TlsSettings, TransferProgressEvent, -} from "./interfaces"; -import { createHttpHeaders } from "./httpHeaders"; -import { RestError } from "./restError"; -import type { IncomingMessage } from "http"; -import { logger } from "./log"; +} from "./interfaces.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { RestError } from "./restError.js"; +import type { IncomingMessage } from "node:http"; +import { logger } from "./log.js"; const DEFAULT_TLS_SETTINGS = {}; diff --git a/sdk/core/core-rest-pipeline/src/pipeline.ts b/sdk/core/core-rest-pipeline/src/pipeline.ts index 06b37e06a193..32274db4afe8 100644 --- a/sdk/core/core-rest-pipeline/src/pipeline.ts +++ b/sdk/core/core-rest-pipeline/src/pipeline.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { HttpClient, PipelineRequest, PipelineResponse, SendRequest } from "./interfaces"; +import type { HttpClient, PipelineRequest, PipelineResponse, SendRequest } from "./interfaces.js"; /** * Policies are executed in phases. diff --git a/sdk/core/core-rest-pipeline/src/pipelineRequest.ts b/sdk/core/core-rest-pipeline/src/pipelineRequest.ts index 9cd9569fc3ff..2df6e122df17 100644 --- a/sdk/core/core-rest-pipeline/src/pipelineRequest.ts +++ b/sdk/core/core-rest-pipeline/src/pipelineRequest.ts @@ -10,8 +10,8 @@ import type { ProxySettings, RequestBodyType, TransferProgressEvent, -} from "./interfaces"; -import { createHttpHeaders } from "./httpHeaders"; +} from "./interfaces.js"; +import { createHttpHeaders } from "./httpHeaders.js"; import type { AbortSignalLike } from "@azure/abort-controller"; import { randomUUID } from "@azure/core-util"; import type { OperationTracingOptions } from "@azure/core-tracing"; diff --git a/sdk/core/core-rest-pipeline/src/policies/auxiliaryAuthenticationHeaderPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/auxiliaryAuthenticationHeaderPolicy.ts index cb73ecfbf57e..fa2686b02a0a 100644 --- a/sdk/core/core-rest-pipeline/src/policies/auxiliaryAuthenticationHeaderPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/auxiliaryAuthenticationHeaderPolicy.ts @@ -3,11 +3,11 @@ import type { GetTokenOptions, TokenCredential } from "@azure/core-auth"; import type { AzureLogger } from "@azure/logger"; -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { type AccessTokenGetter, createTokenCycler } from "../util/tokenCycler"; -import { logger as coreLogger } from "../log"; -import type { AuthorizeRequestOptions } from "./bearerTokenAuthenticationPolicy"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { type AccessTokenGetter, createTokenCycler } from "../util/tokenCycler.js"; +import { logger as coreLogger } from "../log.js"; +import type { AuthorizeRequestOptions } from "./bearerTokenAuthenticationPolicy.js"; /** * The programmatic identifier of the auxiliaryAuthenticationHeaderPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/bearerTokenAuthenticationPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/bearerTokenAuthenticationPolicy.ts index 5f90147a9a6f..e50408b79dfd 100644 --- a/sdk/core/core-rest-pipeline/src/policies/bearerTokenAuthenticationPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/bearerTokenAuthenticationPolicy.ts @@ -3,10 +3,10 @@ import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; import type { AzureLogger } from "@azure/logger"; -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { createTokenCycler } from "../util/tokenCycler"; -import { logger as coreLogger } from "../log"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { createTokenCycler } from "../util/tokenCycler.js"; +import { logger as coreLogger } from "../log.js"; /** * The programmatic identifier of the bearerTokenAuthenticationPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy.browser.ts b/sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy-browser.mts similarity index 100% rename from sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy.browser.ts rename to sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy-browser.mts diff --git a/sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy.ts b/sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy.ts index e42cae3b7a88..14ec7137635e 100644 --- a/sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/decompressResponsePolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the decompressResponsePolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/defaultRetryPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/defaultRetryPolicy.ts index 78aa44c9af59..4d3d195ef746 100644 --- a/sdk/core/core-rest-pipeline/src/policies/defaultRetryPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/defaultRetryPolicy.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRetryOptions } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy"; -import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import type { PipelineRetryOptions } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js"; +import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * Name of the {@link defaultRetryPolicy} diff --git a/sdk/core/core-rest-pipeline/src/policies/exponentialRetryPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/exponentialRetryPolicy.ts index b7e8948ee632..f5719f1068e8 100644 --- a/sdk/core/core-rest-pipeline/src/policies/exponentialRetryPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/exponentialRetryPolicy.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelinePolicy } from "../pipeline"; -import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import type { PipelinePolicy } from "../pipeline.js"; +import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * The programmatic identifier of the exponentialRetryPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/formDataPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/formDataPolicy.ts index bf7361e48141..3ccf572ae7fe 100644 --- a/sdk/core/core-rest-pipeline/src/policies/formDataPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/formDataPolicy.ts @@ -2,15 +2,15 @@ // Licensed under the MIT license. import { stringToUint8Array } from "@azure/core-util"; -import { createHttpHeaders } from "../httpHeaders"; +import { createHttpHeaders } from "../httpHeaders.js"; import type { BodyPart, FormDataMap, PipelineRequest, PipelineResponse, SendRequest, -} from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; +} from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the formDataPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/logPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/logPolicy.ts index 6f59be11eb1f..2eb6d605f4d3 100644 --- a/sdk/core/core-rest-pipeline/src/policies/logPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/logPolicy.ts @@ -2,10 +2,10 @@ // Licensed under the MIT license. import type { Debugger } from "@azure/logger"; -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { logger as coreLogger } from "../log"; -import { Sanitizer } from "../util/sanitizer"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { logger as coreLogger } from "../log.js"; +import { Sanitizer } from "../util/sanitizer.js"; /** * The programmatic identifier of the logPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/multipartPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/multipartPolicy.ts index 449fac61bd92..bb034fd80cb8 100644 --- a/sdk/core/core-rest-pipeline/src/policies/multipartPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/multipartPolicy.ts @@ -2,10 +2,10 @@ // Licensed under the MIT license. import { randomUUID, stringToUint8Array } from "@azure/core-util"; -import type { BodyPart, HttpHeaders, PipelineRequest, PipelineResponse } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { concat } from "../util/concat"; -import { isBlob } from "../util/typeGuards"; +import type { BodyPart, HttpHeaders, PipelineRequest, PipelineResponse } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { concat } from "../util/concat.js"; +import { isBlob } from "../util/typeGuards.js"; function generateBoundary(): string { return `----AzSDKFormBoundary${randomUUID()}`; diff --git a/sdk/core/core-rest-pipeline/src/policies/ndJsonPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/ndJsonPolicy.ts index 7c4856733857..5a4debc21257 100644 --- a/sdk/core/core-rest-pipeline/src/policies/ndJsonPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/ndJsonPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the ndJsonPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/proxyPolicy.browser.ts b/sdk/core/core-rest-pipeline/src/policies/proxyPolicy-browser.mts similarity index 100% rename from sdk/core/core-rest-pipeline/src/policies/proxyPolicy.browser.ts rename to sdk/core/core-rest-pipeline/src/policies/proxyPolicy-browser.mts diff --git a/sdk/core/core-rest-pipeline/src/policies/proxyPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/proxyPolicy.ts index 1b8d0539bbaf..46b0adb0d749 100644 --- a/sdk/core/core-rest-pipeline/src/policies/proxyPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/proxyPolicy.ts @@ -1,13 +1,19 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type * as http from "http"; -import type * as https from "https"; -import { HttpsProxyAgent, type HttpsProxyAgentOptions } from "https-proxy-agent"; -import { HttpProxyAgent, type HttpProxyAgentOptions } from "http-proxy-agent"; -import type { PipelineRequest, PipelineResponse, ProxySettings, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { logger } from "../log"; +import type * as http from "node:http"; +import type * as https from "node:https"; +import * as process from "node:process"; +import createHttpsProxyAgent, { type HttpsProxyAgentOptions } from "https-proxy-agent"; +import createHttpProxyAgent, { type HttpProxyAgentOptions } from "http-proxy-agent"; +import type { + PipelineRequest, + PipelineResponse, + ProxySettings, + SendRequest, +} from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { logger } from "../log.js"; const HTTPS_PROXY = "HTTPS_PROXY"; const HTTP_PROXY = "HTTP_PROXY"; @@ -178,13 +184,13 @@ function setProxyAgentOnRequest(request: PipelineRequest, cachedAgents: CachedAg if (isInsecure) { if (!cachedAgents.httpProxyAgent) { const proxyAgentOptions = getProxyAgentOptions(proxySettings, request); - cachedAgents.httpProxyAgent = new HttpProxyAgent(proxyAgentOptions); + cachedAgents.httpProxyAgent = createHttpProxyAgent(proxyAgentOptions); } request.agent = cachedAgents.httpProxyAgent; } else { if (!cachedAgents.httpsProxyAgent) { const proxyAgentOptions = getProxyAgentOptions(proxySettings, request); - cachedAgents.httpsProxyAgent = new HttpsProxyAgent(proxyAgentOptions); + cachedAgents.httpsProxyAgent = createHttpsProxyAgent(proxyAgentOptions); } request.agent = cachedAgents.httpsProxyAgent; } diff --git a/sdk/core/core-rest-pipeline/src/policies/redirectPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/redirectPolicy.ts index 418a8cf6eecd..e83ecad04767 100644 --- a/sdk/core/core-rest-pipeline/src/policies/redirectPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/redirectPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the redirectPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/retryPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/retryPolicy.ts index 3ff2f2fba187..ffc9d01be438 100644 --- a/sdk/core/core-rest-pipeline/src/policies/retryPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/retryPolicy.ts @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { delay } from "../util/helpers"; -import { createClientLogger } from "@azure/logger"; -import type { RetryStrategy } from "../retryStrategies/retryStrategy"; -import type { RestError } from "../restError"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { delay } from "../util/helpers.js"; +import { type AzureLogger, createClientLogger } from "@azure/logger"; +import type { RetryStrategy } from "../retryStrategies/retryStrategy.js"; +import type { RestError } from "../restError.js"; import { AbortError } from "@azure/abort-controller"; -import type { AzureLogger } from "@azure/logger"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; const retryPolicyLogger = createClientLogger("core-rest-pipeline retryPolicy"); diff --git a/sdk/core/core-rest-pipeline/src/policies/setClientRequestIdPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/setClientRequestIdPolicy.ts index 77f547d06a61..56c5c1395c51 100644 --- a/sdk/core/core-rest-pipeline/src/policies/setClientRequestIdPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/setClientRequestIdPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the setClientRequestIdPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/systemErrorRetryPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/systemErrorRetryPolicy.ts index 82190b637046..6ec739fed8c8 100644 --- a/sdk/core/core-rest-pipeline/src/policies/systemErrorRetryPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/systemErrorRetryPolicy.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelinePolicy } from "../pipeline"; -import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import type { PipelinePolicy } from "../pipeline.js"; +import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * Name of the {@link systemErrorRetryPolicy} diff --git a/sdk/core/core-rest-pipeline/src/policies/throttlingRetryPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/throttlingRetryPolicy.ts index 6475762c4a19..1edf91b658f2 100644 --- a/sdk/core/core-rest-pipeline/src/policies/throttlingRetryPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/throttlingRetryPolicy.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelinePolicy } from "../pipeline"; -import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import type { PipelinePolicy } from "../pipeline.js"; +import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * Name of the {@link throttlingRetryPolicy} diff --git a/sdk/core/core-rest-pipeline/src/policies/tlsPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/tlsPolicy.ts index 0602d1c920cf..65de67a513d3 100644 --- a/sdk/core/core-rest-pipeline/src/policies/tlsPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/tlsPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelinePolicy } from "../pipeline"; -import type { TlsSettings } from "../interfaces"; +import type { PipelinePolicy } from "../pipeline.js"; +import type { TlsSettings } from "../interfaces.js"; /** * Name of the TLS Policy diff --git a/sdk/core/core-rest-pipeline/src/policies/tracingPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/tracingPolicy.ts index cb5d08f36ad4..826f6c2ca357 100644 --- a/sdk/core/core-rest-pipeline/src/policies/tracingPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/tracingPolicy.ts @@ -7,13 +7,13 @@ import { type TracingSpan, createTracingClient, } from "@azure/core-tracing"; -import { SDK_VERSION } from "../constants"; -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { getUserAgentValue } from "../util/userAgent"; -import { logger } from "../log"; +import { SDK_VERSION } from "../constants.js"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { getUserAgentValue } from "../util/userAgent.js"; +import { logger } from "../log.js"; import { getErrorMessage, isError } from "@azure/core-util"; -import { isRestError } from "../restError"; +import { isRestError } from "../restError.js"; /** * The programmatic identifier of the tracingPolicy. diff --git a/sdk/core/core-rest-pipeline/src/policies/userAgentPolicy.ts b/sdk/core/core-rest-pipeline/src/policies/userAgentPolicy.ts index e5f94dbe9c35..57c82272d04c 100644 --- a/sdk/core/core-rest-pipeline/src/policies/userAgentPolicy.ts +++ b/sdk/core/core-rest-pipeline/src/policies/userAgentPolicy.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import type { PipelinePolicy } from "../pipeline"; -import { getUserAgentHeaderName, getUserAgentValue } from "../util/userAgent"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { getUserAgentHeaderName, getUserAgentValue } from "../util/userAgent.js"; const UserAgentHeaderName = getUserAgentHeaderName(); diff --git a/sdk/core/core-rest-pipeline/src/restError.ts b/sdk/core/core-rest-pipeline/src/restError.ts index a9ee4d1c4390..cca8f62cdb6a 100644 --- a/sdk/core/core-rest-pipeline/src/restError.ts +++ b/sdk/core/core-rest-pipeline/src/restError.ts @@ -2,9 +2,9 @@ // Licensed under the MIT license. import { isError } from "@azure/core-util"; -import type { PipelineRequest, PipelineResponse } from "./interfaces"; -import { custom } from "./util/inspect"; -import { Sanitizer } from "./util/sanitizer"; +import type { PipelineRequest, PipelineResponse } from "./interfaces.js"; +import { custom } from "./util/inspect.js"; +import { Sanitizer } from "./util/sanitizer.js"; const errorSanitizer = new Sanitizer(); diff --git a/sdk/core/core-rest-pipeline/src/retryStrategies/exponentialRetryStrategy.ts b/sdk/core/core-rest-pipeline/src/retryStrategies/exponentialRetryStrategy.ts index 349466dfeaf3..0b4f1b8b163e 100644 --- a/sdk/core/core-rest-pipeline/src/retryStrategies/exponentialRetryStrategy.ts +++ b/sdk/core/core-rest-pipeline/src/retryStrategies/exponentialRetryStrategy.ts @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineResponse } from "../interfaces"; -import type { RestError } from "../restError"; +import type { PipelineResponse } from "../interfaces.js"; +import type { RestError } from "../restError.js"; import { getRandomIntegerInclusive } from "@azure/core-util"; -import type { RetryStrategy } from "./retryStrategy"; -import { isThrottlingRetryResponse } from "./throttlingRetryStrategy"; +import type { RetryStrategy } from "./retryStrategy.js"; +import { isThrottlingRetryResponse } from "./throttlingRetryStrategy.js"; // intervals are in milliseconds const DEFAULT_CLIENT_RETRY_INTERVAL = 1000; diff --git a/sdk/core/core-rest-pipeline/src/retryStrategies/retryStrategy.ts b/sdk/core/core-rest-pipeline/src/retryStrategies/retryStrategy.ts index 8b9e14153cf0..06835a0eb515 100644 --- a/sdk/core/core-rest-pipeline/src/retryStrategies/retryStrategy.ts +++ b/sdk/core/core-rest-pipeline/src/retryStrategies/retryStrategy.ts @@ -2,8 +2,8 @@ // Licensed under the MIT license. import type { AzureLogger } from "@azure/logger"; -import type { PipelineResponse } from "../interfaces"; -import type { RestError } from "../restError"; +import type { PipelineResponse } from "../interfaces.js"; +import type { RestError } from "../restError.js"; /** * Information provided to the retry strategy about the current progress of the retry policy. diff --git a/sdk/core/core-rest-pipeline/src/retryStrategies/throttlingRetryStrategy.ts b/sdk/core/core-rest-pipeline/src/retryStrategies/throttlingRetryStrategy.ts index 9078c08c5cd1..bfff96db49dc 100644 --- a/sdk/core/core-rest-pipeline/src/retryStrategies/throttlingRetryStrategy.ts +++ b/sdk/core/core-rest-pipeline/src/retryStrategies/throttlingRetryStrategy.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { PipelineResponse } from ".."; -import { parseHeaderValueAsNumber } from "../util/helpers"; -import type { RetryStrategy } from "./retryStrategy"; +import type { PipelineResponse } from "../index.js"; +import { parseHeaderValueAsNumber } from "../util/helpers.js"; +import type { RetryStrategy } from "./retryStrategy.js"; /** * The header that comes back from Azure services representing diff --git a/sdk/core/core-rest-pipeline/src/util/concat.browser.ts b/sdk/core/core-rest-pipeline/src/util/concat-browser.mts similarity index 97% rename from sdk/core/core-rest-pipeline/src/util/concat.browser.ts rename to sdk/core/core-rest-pipeline/src/util/concat-browser.mts index dfa02896c623..886c8b6fdb90 100644 --- a/sdk/core/core-rest-pipeline/src/util/concat.browser.ts +++ b/sdk/core/core-rest-pipeline/src/util/concat-browser.mts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { getRawContent } from "./file"; -import { isNodeReadableStream, isWebReadableStream } from "./typeGuards"; +import { getRawContent } from "./file.js"; +import { isNodeReadableStream, isWebReadableStream } from "./typeGuards.js"; /** * Drain the content of the given ReadableStream into a Blob. diff --git a/sdk/core/core-rest-pipeline/src/util/concat.ts b/sdk/core/core-rest-pipeline/src/util/concat.ts index 40a925309b1f..3ca0319db23b 100644 --- a/sdk/core/core-rest-pipeline/src/util/concat.ts +++ b/sdk/core/core-rest-pipeline/src/util/concat.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Readable } from "stream"; -import type { ReadableStream as AsyncIterableReadableStream } from "stream/web"; -import { isBlob } from "./typeGuards"; -import { getRawContent } from "./file"; +import { Readable } from "node:stream"; +import type { ReadableStream as AsyncIterableReadableStream } from "node:stream/web"; +import { isBlob } from "./typeGuards.js"; +import { getRawContent } from "./file.js"; async function* streamAsyncIterator( this: ReadableStream, diff --git a/sdk/core/core-rest-pipeline/src/util/file.ts b/sdk/core/core-rest-pipeline/src/util/file.ts index 6ed31cc8c863..f5cedf966d9f 100644 --- a/sdk/core/core-rest-pipeline/src/util/file.ts +++ b/sdk/core/core-rest-pipeline/src/util/file.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { isNode } from "@azure/core-util"; -import { isNodeReadableStream } from "./typeGuards"; +import { isNodeReadableStream } from "./typeGuards.js"; /** * Options passed into createFile specifying metadata about the file. diff --git a/sdk/core/core-rest-pipeline/src/util/helpers.ts b/sdk/core/core-rest-pipeline/src/util/helpers.ts index 453cefa9f2c3..b6f37b4167d6 100644 --- a/sdk/core/core-rest-pipeline/src/util/helpers.ts +++ b/sdk/core/core-rest-pipeline/src/util/helpers.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { AbortError, type AbortSignalLike } from "@azure/abort-controller"; -import type { PipelineResponse } from "../interfaces"; +import type { PipelineResponse } from "../interfaces.js"; const StandardAbortMessage = "The operation was aborted."; diff --git a/sdk/core/core-rest-pipeline/src/util/inspect.browser.ts b/sdk/core/core-rest-pipeline/src/util/inspect-browser.mts similarity index 100% rename from sdk/core/core-rest-pipeline/src/util/inspect.browser.ts rename to sdk/core/core-rest-pipeline/src/util/inspect-browser.mts diff --git a/sdk/core/core-rest-pipeline/src/util/inspect.ts b/sdk/core/core-rest-pipeline/src/util/inspect.ts index 27613c3494f5..c69ad2d36fb1 100644 --- a/sdk/core/core-rest-pipeline/src/util/inspect.ts +++ b/sdk/core/core-rest-pipeline/src/util/inspect.ts @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { inspect } from "util"; +import { inspect } from "node:util"; export const custom = inspect.custom; diff --git a/sdk/core/core-rest-pipeline/src/util/tokenCycler.ts b/sdk/core/core-rest-pipeline/src/util/tokenCycler.ts index 5df4bd0832a7..d048647bf873 100644 --- a/sdk/core/core-rest-pipeline/src/util/tokenCycler.ts +++ b/sdk/core/core-rest-pipeline/src/util/tokenCycler.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; -import { delay } from "./helpers"; +import { delay } from "./helpers.js"; /** * A function that gets a promise of an access token and allows providing diff --git a/sdk/core/core-rest-pipeline/src/util/userAgent.ts b/sdk/core/core-rest-pipeline/src/util/userAgent.ts index cffde1885d94..af452de2073d 100644 --- a/sdk/core/core-rest-pipeline/src/util/userAgent.ts +++ b/sdk/core/core-rest-pipeline/src/util/userAgent.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { getHeaderName, setPlatformSpecificData } from "./userAgentPlatform"; -import { SDK_VERSION } from "../constants"; +import { getHeaderName, setPlatformSpecificData } from "./userAgentPlatform.js"; +import { SDK_VERSION } from "../constants.js"; function getUserAgentString(telemetryInfo: Map): string { const parts: string[] = []; diff --git a/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.browser.ts b/sdk/core/core-rest-pipeline/src/util/userAgentPlatform-browser.mts similarity index 100% rename from sdk/core/core-rest-pipeline/src/util/userAgentPlatform.browser.ts rename to sdk/core/core-rest-pipeline/src/util/userAgentPlatform-browser.mts diff --git a/sdk/core/ts-http-runtime/src/util/userAgentPlatform.native.ts b/sdk/core/core-rest-pipeline/src/util/userAgentPlatform-react-native.mts similarity index 80% rename from sdk/core/ts-http-runtime/src/util/userAgentPlatform.native.ts rename to sdk/core/core-rest-pipeline/src/util/userAgentPlatform-react-native.mts index 66fd2d1e3a37..7ff2eb7abe9f 100644 --- a/sdk/core/ts-http-runtime/src/util/userAgentPlatform.native.ts +++ b/sdk/core/core-rest-pipeline/src/util/userAgentPlatform-react-native.mts @@ -4,7 +4,8 @@ /* * NOTE: When moving this file, please update "react-native" section in package.json. */ -const { Platform } = require("react-native"); // eslint-disable-line import/no-extraneous-dependencies, @typescript-eslint/no-require-imports +/* @ts-ignore */ +const { Platform } = await import("react-native"); /** * @internal diff --git a/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.ts b/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.ts index c1be64874b1c..a020aeeb9765 100644 --- a/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.ts +++ b/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.ts @@ -1,7 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as os from "os"; +import * as os from "node:os"; +import * as process from "node:process"; + +/** + * @internal + */ +interface ExtendedPlatformVersions extends NodeJS.ProcessVersions { + bun?: string; + deno?: string; +} /** * @internal @@ -14,6 +23,14 @@ export function getHeaderName(): string { * @internal */ export function setPlatformSpecificData(map: Map): void { - map.set("Node", process.version); + const versions = process.versions as ExtendedPlatformVersions; + if (versions.bun) { + map.set("Bun", versions.bun); + } else if (versions.deno) { + map.set("Deno", versions.deno); + } else if (versions.node) { + map.set("Node", versions.node); + } + map.set("OS", `(${os.arch()}-${os.type()}-${os.release()})`); } diff --git a/sdk/core/core-rest-pipeline/src/xhrHttpClient.ts b/sdk/core/core-rest-pipeline/src/xhrHttpClient.ts index 44b1d9ef8e65..5b3e3f19a5e7 100644 --- a/sdk/core/core-rest-pipeline/src/xhrHttpClient.ts +++ b/sdk/core/core-rest-pipeline/src/xhrHttpClient.ts @@ -8,10 +8,10 @@ import type { PipelineRequest, PipelineResponse, TransferProgressEvent, -} from "./interfaces"; -import { createHttpHeaders } from "./httpHeaders"; -import { RestError } from "./restError"; -import { isReadableStream } from "./util/typeGuards"; +} from "./interfaces.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { RestError } from "./restError.js"; +import { isReadableStream } from "./util/typeGuards.js"; /** * A HttpClient implementation that uses XMLHttpRequest to send HTTP requests. diff --git a/sdk/core/core-rest-pipeline/test/auxiliaryAuthenticationHeaderPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/auxiliaryAuthenticationHeaderPolicy.spec.ts index 7ff5d2e18a20..9799b75cd5a7 100644 --- a/sdk/core/core-rest-pipeline/test/auxiliaryAuthenticationHeaderPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/auxiliaryAuthenticationHeaderPolicy.spec.ts @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, beforeEach, afterEach, vi, expect } from "vitest"; import type { AccessToken, TokenCredential } from "@azure/core-auth"; import { type PipelinePolicy, @@ -10,8 +9,9 @@ import { auxiliaryAuthenticationHeaderPolicy, createHttpHeaders, createPipelineRequest, -} from "../src"; -import { DEFAULT_CYCLER_OPTIONS } from "../src/util/tokenCycler"; +} from "../src/index.js"; +import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest"; +import { DEFAULT_CYCLER_OPTIONS } from "../src/util/tokenCycler.js"; const { refreshWindowInMs: defaultRefreshWindow } = DEFAULT_CYCLER_OPTIONS; diff --git a/sdk/core/core-rest-pipeline/test/bearerTokenAuthenticationPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/bearerTokenAuthenticationPolicy.spec.ts index 0c4a901eb154..53d6a8b53e22 100644 --- a/sdk/core/core-rest-pipeline/test/bearerTokenAuthenticationPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/bearerTokenAuthenticationPolicy.spec.ts @@ -1,17 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, beforeEach, afterEach, vi, expect } from "vitest"; -import type { AccessToken, TokenCredential } from "@azure/core-auth"; +import { AccessToken, TokenCredential } from "@azure/core-auth"; +import type { PipelinePolicy, PipelineResponse, SendRequest } from "../src/index.js"; import { - type PipelinePolicy, - type PipelineResponse, - type SendRequest, bearerTokenAuthenticationPolicy, createHttpHeaders, createPipelineRequest, -} from "../src"; -import { DEFAULT_CYCLER_OPTIONS } from "../src/util/tokenCycler"; +} from "../src/index.js"; +import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest"; +import { DEFAULT_CYCLER_OPTIONS } from "../src/util/tokenCycler.js"; const { refreshWindowInMs: defaultRefreshWindow } = DEFAULT_CYCLER_OPTIONS; @@ -19,6 +17,7 @@ describe("BearerTokenAuthenticationPolicy", function () { beforeEach(() => { vi.useFakeTimers({ now: Date.now() }); }); + afterEach(() => { vi.useRealTimers(); }); diff --git a/sdk/core/core-rest-pipeline/test/browser/decompressResponsePolicy.spec.ts b/sdk/core/core-rest-pipeline/test/browser/decompressResponsePolicy.spec.ts index a1eeaea32b46..03356ca29d1d 100644 --- a/sdk/core/core-rest-pipeline/test/browser/decompressResponsePolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/browser/decompressResponsePolicy.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it } from "vitest"; -import { decompressResponsePolicy } from "../../src"; +import { describe, it, assert } from "vitest"; +import { decompressResponsePolicy } from "../../src/index.js"; describe("decompressResponsePolicy (browser)", function () { it("Throws on creation", function () { diff --git a/sdk/core/core-rest-pipeline/test/browser/fetchHttpClient.spec.ts b/sdk/core/core-rest-pipeline/test/browser/fetchHttpClient.spec.ts index 678ec3ce9151..a7ea8d62a3d3 100644 --- a/sdk/core/core-rest-pipeline/test/browser/fetchHttpClient.spec.ts +++ b/sdk/core/core-rest-pipeline/test/browser/fetchHttpClient.spec.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, beforeEach, afterEach, vi } from "vitest"; -import { createFetchHttpClient } from "../../src/fetchHttpClient"; -import { createPipelineRequest } from "../../src/pipelineRequest"; -import { png } from "./mocks/encodedPng"; -import { createHttpHeaders } from "../../src/httpHeaders"; -import { AbortError, type AbortSignalLike } from "@azure/abort-controller"; -import { delay } from "../../src/util/helpers"; +import { describe, it, assert, vi, beforeEach, afterEach } from "vitest"; +import { createFetchHttpClient } from "../../src/fetchHttpClient.js"; +import { createPipelineRequest } from "../../src/pipelineRequest.js"; +import { png } from "./mocks/encodedPng.js"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; +import { AbortError, AbortSignalLike } from "@azure/abort-controller"; +import { delay } from "../../src/util/helpers.js"; const streamBody = new ReadableStream({ async start(controller) { diff --git a/sdk/core/core-rest-pipeline/test/browser/proxyPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/browser/proxyPolicy.spec.ts index b2c497dc5936..56cb24ad7d75 100644 --- a/sdk/core/core-rest-pipeline/test/browser/proxyPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/browser/proxyPolicy.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it } from "vitest"; -import { proxyPolicy } from "../../src/policies/proxyPolicy.browser"; +import { describe, it, assert } from "vitest"; +import { proxyPolicy } from "../../src/index.js"; describe("proxyPolicy (browser)", function () { it("Throws on creation", function () { diff --git a/sdk/core/core-rest-pipeline/test/defaultLogPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/defaultLogPolicy.spec.ts index f6109417bd42..a5c2b11a29dc 100644 --- a/sdk/core/core-rest-pipeline/test/defaultLogPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/defaultLogPolicy.spec.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; -import type { PipelinePolicy } from "../src/pipeline"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; +import type { PipelinePolicy } from "../src/pipeline.js"; import { assert, describe, it, vi } from "vitest"; -import { createHttpHeaders } from "../src/httpHeaders"; -import { createPipelineFromOptions } from "../src/createPipelineFromOptions"; -import { createPipelineRequest } from "../src/pipelineRequest"; +import { createHttpHeaders } from "../src/httpHeaders.js"; +import { createPipelineFromOptions } from "../src/createPipelineFromOptions.js"; +import { createPipelineRequest } from "../src/pipelineRequest.js"; import { isNode } from "@azure/core-util"; describe("defaultLogPolicy", function () { diff --git a/sdk/core/core-rest-pipeline/test/defaultRetryPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/defaultRetryPolicy.spec.ts index 04d8f910c281..94d9008f33a7 100644 --- a/sdk/core/core-rest-pipeline/test/defaultRetryPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/defaultRetryPolicy.spec.ts @@ -1,10 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, afterEach, vi, expect } from "vitest"; - -import { RestError, type SendRequest, createPipelineRequest, defaultRetryPolicy } from "../src"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +import { + RestError, + type SendRequest, + createPipelineRequest, + defaultRetryPolicy, +} from "../src/index.js"; +import { describe, it, assert, expect, vi, afterEach } from "vitest"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("defaultRetryPolicy", function () { afterEach(function () { diff --git a/sdk/core/core-rest-pipeline/test/exponentialRetryPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/exponentialRetryPolicy.spec.ts index 01b41b2edb88..dd6f42b4cd04 100644 --- a/sdk/core/core-rest-pipeline/test/exponentialRetryPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/exponentialRetryPolicy.spec.ts @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { describe, it, afterEach, vi, expect } from "vitest"; - import { type PipelineResponse, RestError, @@ -10,8 +8,9 @@ import { createHttpHeaders, createPipelineRequest, exponentialRetryPolicy, -} from "../src"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +} from "../src/index.js"; +import { describe, it, expect, vi, afterEach } from "vitest"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("exponentialRetryPolicy", function () { afterEach(function () { diff --git a/sdk/core/core-rest-pipeline/test/formDataPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/formDataPolicy.spec.ts index 2cb97f7d8b13..5d4c16e32ad4 100644 --- a/sdk/core/core-rest-pipeline/test/formDataPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/formDataPolicy.spec.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi } from "vitest"; - +import { describe, it, assert, vi } from "vitest"; import { type PipelineResponse, type SendRequest, @@ -11,8 +10,8 @@ import { formDataPolicy, createFile, createFileFromStream, -} from "../src"; -import type { BodyPart, FormDataMap, MultipartRequestBody } from "../src/interfaces"; +} from "../src/index.js"; +import type { BodyPart, FormDataMap, MultipartRequestBody } from "../src/interfaces.js"; import { stringToUint8Array } from "@azure/core-util"; export async function performRequest(formData: FormDataMap): Promise { diff --git a/sdk/core/core-rest-pipeline/test/httpHeaders.spec.ts b/sdk/core/core-rest-pipeline/test/httpHeaders.spec.ts index 7064cd50fdcf..1660c88b789a 100644 --- a/sdk/core/core-rest-pipeline/test/httpHeaders.spec.ts +++ b/sdk/core/core-rest-pipeline/test/httpHeaders.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it } from "vitest"; -import { createHttpHeaders } from "../src/httpHeaders"; +import { describe, it, assert } from "vitest"; +import { createHttpHeaders } from "../src/httpHeaders.js"; describe("HttpHeaders", () => { it("toJSON() should use normalized header names", () => { diff --git a/sdk/core/core-rest-pipeline/test/multipartPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/multipartPolicy.spec.ts index 8ffa7a866424..33cc41ceea37 100644 --- a/sdk/core/core-rest-pipeline/test/multipartPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/multipartPolicy.spec.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createHttpHeaders } from "../src/httpHeaders"; -import type { PipelineRequest, PipelineResponse, SendRequest } from "../src/interfaces"; -import { createPipelineRequest } from "../src/pipelineRequest"; -import { multipartPolicy } from "../src/policies/multipartPolicy"; -import { assert, describe, it, vi, expect } from "vitest"; -import type { PipelineRequestOptions } from "../src/pipelineRequest"; +import { createHttpHeaders } from "../src/httpHeaders.js"; +import type { PipelineRequest, PipelineResponse, SendRequest } from "../src/interfaces.js"; +import { createPipelineRequest } from "../src/pipelineRequest.js"; +import { multipartPolicy } from "../src/policies/multipartPolicy.js"; +import { describe, it, assert, expect, vi } from "vitest"; +import type { PipelineRequestOptions } from "../src/pipelineRequest.js"; import { stringToUint8Array } from "@azure/core-util"; -import { assertBodyMatches } from "./util"; +import { assertBodyMatches } from "./util.js"; export async function performRequest( requestOptions: Omit, diff --git a/sdk/core/core-rest-pipeline/test/ndJsonPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/ndJsonPolicy.spec.ts index ecc4cc159ae8..b1de346b52b8 100644 --- a/sdk/core/core-rest-pipeline/test/ndJsonPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/ndJsonPolicy.spec.ts @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi } from "vitest"; - import { type PipelineResponse, type SendRequest, createHttpHeaders, createPipelineRequest, ndJsonPolicy, -} from "../src"; +} from "../src/index.js"; +import { describe, it, assert, vi } from "vitest"; describe("NdJsonPolicy", function () { it("Formats arrays correctly", async function () { diff --git a/sdk/core/core-rest-pipeline/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts b/sdk/core/core-rest-pipeline/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts index ebe57d5b1e14..367ff7a6f3c4 100644 --- a/sdk/core/core-rest-pipeline/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, beforeEach, afterEach, vi } from "vitest"; - +import { describe, it, assert, vi, beforeEach, afterEach } from "vitest"; import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; import { type AuthorizeRequestOnChallengeOptions, @@ -12,8 +11,8 @@ import { createEmptyPipeline, createHttpHeaders, createPipelineRequest, -} from "../../src"; -import { TextDecoder } from "util"; +} from "../../src/index.js"; +import { TextDecoder } from "node:util"; export interface TestChallenge { scope: string; diff --git a/sdk/core/core-rest-pipeline/test/node/decompressResponsePolicy.spec.ts b/sdk/core/core-rest-pipeline/test/node/decompressResponsePolicy.spec.ts index 2de34d9bda8b..12e8c13e2468 100644 --- a/sdk/core/core-rest-pipeline/test/node/decompressResponsePolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/decompressResponsePolicy.spec.ts @@ -1,9 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi } from "vitest"; - -import { type SendRequest, createPipelineRequest, decompressResponsePolicy } from "../../src"; +import { + type SendRequest, + createPipelineRequest, + decompressResponsePolicy, +} from "../../src/index.js"; +import { describe, it, assert, vi } from "vitest"; describe("decompressResponsePolicy (node)", function () { it("Sets the expected flag on the request", function () { diff --git a/sdk/core/core-rest-pipeline/test/node/formDataPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/node/formDataPolicy.spec.ts index 027ab03818ce..e2c740b216b4 100644 --- a/sdk/core/core-rest-pipeline/test/node/formDataPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/formDataPolicy.spec.ts @@ -2,12 +2,12 @@ // Licensed under the MIT license. import { assert, describe, it } from "vitest"; -import { createHttpHeaders } from "../../src/httpHeaders"; -import type { BodyPart, MultipartRequestBody } from "../../src/interfaces"; -import { isBlob } from "../../src/util/typeGuards"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; +import type { MultipartRequestBody } from "../../src/interfaces.js"; +import { isBlob } from "../../src/util/typeGuards.js"; import { Readable } from "stream"; -import { performRequest } from "../formDataPolicy.spec"; -import { createFile, createFileFromStream, getRawContent } from "../../src/util/file"; +import { performRequest } from "../formDataPolicy.spec.js"; +import { createFileFromStream, getRawContent } from "../../src/util/file.js"; describe("formDataPolicy (node-only)", function () { it("can upload a Node ReadableStream", async function () { diff --git a/sdk/core/core-rest-pipeline/test/node/getBodyLength.spec.ts b/sdk/core/core-rest-pipeline/test/node/getBodyLength.spec.ts index f5fb6726f8f0..1b170ce4024c 100644 --- a/sdk/core/core-rest-pipeline/test/node/getBodyLength.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/getBodyLength.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it } from "vitest"; -import { getBodyLength } from "../../src/nodeHttpClient"; +import { describe, it, assert } from "vitest"; +import { getBodyLength } from "../../src/nodeHttpClient.js"; describe("Get Body Length", function () { it("Gets the length of the ASCII string correctly", function () { diff --git a/sdk/core/core-rest-pipeline/test/node/multipartPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/node/multipartPolicy.spec.ts index f962eac09eca..11e9ef14b0b6 100644 --- a/sdk/core/core-rest-pipeline/test/node/multipartPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/multipartPolicy.spec.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createHttpHeaders } from "../../src/httpHeaders"; +import { describe, it, assert } from "vitest"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; import { isNode, stringToUint8Array } from "@azure/core-util"; import { Readable } from "stream"; -import { assert, describe, it } from "vitest"; -import { performRequest } from "../multipartPolicy.spec"; -import { assertBodyMatches } from "../util"; +import { performRequest } from "../multipartPolicy.spec.js"; +import { assertBodyMatches } from "../util.js"; describe("multipartPolicy (node-only)", function () { it.runIf(isNode)("supports Node ReadableStream body", async function () { diff --git a/sdk/core/core-rest-pipeline/test/node/nodeHttpClient.spec.ts b/sdk/core/core-rest-pipeline/test/node/nodeHttpClient.spec.ts index fc445823aa57..4398838b7e03 100644 --- a/sdk/core/core-rest-pipeline/test/node/nodeHttpClient.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/nodeHttpClient.spec.ts @@ -2,10 +2,9 @@ // Licensed under the MIT license. import { assert, describe, it, vi, beforeEach, afterEach } from "vitest"; - import { PassThrough, Writable } from "stream"; import type { ClientRequest, IncomingHttpHeaders, IncomingMessage } from "http"; -import { createDefaultHttpClient, createPipelineRequest } from "../../src"; +import { createDefaultHttpClient, createPipelineRequest } from "../../src/index.js"; vi.mock("https", async () => { const actual = await vi.importActual("https"); @@ -406,7 +405,7 @@ describe("NodeHttpClient", function () { }) as unknown as ClientRequest; vi.mocked(https.request).mockReturnValueOnce(writable); - const body = () => { + const body = (): PassThrough => { const stream = new PassThrough(); stream.write(requestText); stream.end(); diff --git a/sdk/core/core-rest-pipeline/test/node/pipeline.spec.ts b/sdk/core/core-rest-pipeline/test/node/pipeline.spec.ts index 1b7d39de2b05..1a22b3c03f27 100644 --- a/sdk/core/core-rest-pipeline/test/node/pipeline.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/pipeline.spec.ts @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { proxyPolicy, proxyPolicyName } from "../../src/policies/proxyPolicy"; -import { tlsPolicy, tlsPolicyName } from "../../src/policies/tlsPolicy"; - -import type { HttpClient } from "../../src/interfaces"; +import { proxyPolicy, proxyPolicyName } from "../../src/policies/proxyPolicy.js"; +import { tlsPolicy, tlsPolicyName } from "../../src/policies/tlsPolicy.js"; +import type { HttpClient } from "../../src/interfaces.js"; import { HttpsProxyAgent } from "https-proxy-agent"; import { assert, describe, it, afterEach, vi } from "vitest"; -import { createEmptyPipeline } from "../../src/pipeline"; -import { createHttpHeaders } from "../../src/httpHeaders"; -import { createNodeHttpClient } from "../../src/nodeHttpClient"; -import { createPipelineFromOptions } from "../../src/createPipelineFromOptions"; +import { createEmptyPipeline } from "../../src/pipeline.js"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; +import { createNodeHttpClient } from "../../src/nodeHttpClient.js"; +import { createPipelineFromOptions } from "../../src/createPipelineFromOptions.js"; vi.mock("https", async () => { const actual = await vi.importActual("https"); @@ -20,8 +19,8 @@ vi.mock("https", async () => { }; }); -import type { Agent } from "http"; -import * as https from "https"; +import type { Agent } from "node:http"; +import * as https from "node:https"; describe("HttpsPipeline", function () { describe("Agent creation", function () { diff --git a/sdk/core/core-rest-pipeline/test/node/proxyPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/node/proxyPolicy.spec.ts index 3a4cafd1019a..3a8860d3a09b 100644 --- a/sdk/core/core-rest-pipeline/test/node/proxyPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/proxyPolicy.spec.ts @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi, afterEach } from "vitest"; - import { type ProxySettings, type SendRequest, createPipelineRequest, getDefaultProxySettings, proxyPolicy, -} from "../../src"; +} from "../../src/index.js"; import { getProxyAgentOptions, globalNoProxyList, loadNoProxy, -} from "../../src/policies/proxyPolicy"; +} from "../../src/policies/proxyPolicy.js"; +import * as process from "node:process"; +import { describe, it, assert, vi, afterEach } from "vitest"; describe("proxyPolicy (node)", function () { it("Sets proxy settings on the request", function () { diff --git a/sdk/core/core-rest-pipeline/test/node/restError.spec.ts b/sdk/core/core-rest-pipeline/test/node/restError.spec.ts index 3cfef9edc871..92fc20c67982 100644 --- a/sdk/core/core-rest-pipeline/test/node/restError.spec.ts +++ b/sdk/core/core-rest-pipeline/test/node/restError.spec.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it } from "vitest"; +import { describe, it, assert } from "vitest"; import { - type PipelineResponse, + PipelineResponse, RestError, createHttpHeaders, createPipelineRequest, -} from "../../src"; -import { inspect } from "util"; +} from "../../src/index.js"; +import { inspect } from "node:util"; describe("RestError", function () { it("serializes properly in node", function () { diff --git a/sdk/core/core-rest-pipeline/test/pipeline.spec.ts b/sdk/core/core-rest-pipeline/test/pipeline.spec.ts index b92d102bea12..f08456a4d018 100644 --- a/sdk/core/core-rest-pipeline/test/pipeline.spec.ts +++ b/sdk/core/core-rest-pipeline/test/pipeline.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it } from "vitest"; +import { describe, it, assert } from "vitest"; import { type HttpClient, type PipelinePolicy, @@ -9,7 +9,7 @@ import { createHttpHeaders, createPipelineFromOptions, createPipelineRequest, -} from "../src"; +} from "../src/index.js"; describe("HttpsPipeline", function () { it("Newly created pipeline has no policies", function () { diff --git a/sdk/core/core-rest-pipeline/test/redirectPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/redirectPolicy.spec.ts index fdfea6229dee..5e8ab9f7495b 100644 --- a/sdk/core/core-rest-pipeline/test/redirectPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/redirectPolicy.spec.ts @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, expect, it, vi } from "vitest"; -import { redirectPolicy } from "../src/policies/redirectPolicy"; - +import { describe, it, assert, expect, vi } from "vitest"; +import { redirectPolicy } from "../src/policies/redirectPolicy.js"; import { type PipelineResponse, type SendRequest, createHttpHeaders, createPipelineRequest, -} from "../src"; +} from "../src/index.js"; describe("RedirectPolicy", () => { it("should not follow redirect if no location header", async () => { diff --git a/sdk/core/core-rest-pipeline/test/retryPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/retryPolicy.spec.ts index e4a90c8942dd..85fabba55faa 100644 --- a/sdk/core/core-rest-pipeline/test/retryPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/retryPolicy.spec.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert, expect, vi, afterEach } from "vitest"; import { type PipelineResponse, RestError, @@ -8,10 +9,9 @@ import { createHttpHeaders, createPipelineRequest, retryPolicy, -} from "../src"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; -import { assert, describe, it, afterEach, vi, expect } from "vitest"; -import { makeTestLogger } from "./util"; +} from "../src/index.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; +import { makeTestLogger } from "./util.js"; describe("retryPolicy", function () { afterEach(function () { diff --git a/sdk/core/core-rest-pipeline/test/sanitizer.spec.ts b/sdk/core/core-rest-pipeline/test/sanitizer.spec.ts index fbfb8ef6dd78..fb7b8ff24199 100644 --- a/sdk/core/core-rest-pipeline/test/sanitizer.spec.ts +++ b/sdk/core/core-rest-pipeline/test/sanitizer.spec.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { assert, describe, it } from "vitest"; -import { Sanitizer } from "../src/util/sanitizer"; +import { Sanitizer } from "../src/util/sanitizer.js"; describe("Sanitizer", function () { it("Redacts query parameters in url properties", function () { diff --git a/sdk/core/core-rest-pipeline/test/setClientRequestIdPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/setClientRequestIdPolicy.spec.ts index 796d2e3c294a..5c72a9ad92ef 100644 --- a/sdk/core/core-rest-pipeline/test/setClientRequestIdPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/setClientRequestIdPolicy.spec.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi } from "vitest"; - +import { describe, it, assert, vi } from "vitest"; import { type HttpClient, type PipelineResponse, @@ -11,7 +10,7 @@ import { createPipelineFromOptions, createPipelineRequest, setClientRequestIdPolicy, -} from "../src"; +} from "../src/index.js"; describe("setClientRequestIdPolicy", function () { it("should set the header name with `x-ms-client-request-id` if no header name is provided", async () => { diff --git a/sdk/core/core-rest-pipeline/test/systemErrorRetryPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/systemErrorRetryPolicy.spec.ts index c27012cdab51..f59f8c198158 100644 --- a/sdk/core/core-rest-pipeline/test/systemErrorRetryPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/systemErrorRetryPolicy.spec.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi, afterEach, expect } from "vitest"; - +import { describe, it, assert, expect, vi, afterEach } from "vitest"; import { type PipelineResponse, RestError, @@ -10,8 +9,8 @@ import { createHttpHeaders, createPipelineRequest, systemErrorRetryPolicy, -} from "../src"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +} from "../src/index.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("systemErrorRetryPolicy", function () { afterEach(function () { diff --git a/sdk/core/core-rest-pipeline/test/throttlingRetryPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/throttlingRetryPolicy.spec.ts index 51b31a0435ce..aa347c8c0bf4 100644 --- a/sdk/core/core-rest-pipeline/test/throttlingRetryPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/throttlingRetryPolicy.spec.ts @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { describe, it, afterEach, assert, vi, expect } from "vitest"; - +import { describe, it, assert, expect, vi, afterEach } from "vitest"; import { type PipelineResponse, type SendRequest, createHttpHeaders, createPipelineRequest, throttlingRetryPolicy, -} from "../src"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +} from "../src/index.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("throttlingRetryPolicy", function () { afterEach(function () { @@ -285,7 +284,6 @@ describe("throttlingRetryPolicy", function () { next.mockResolvedValueOnce(successResponse); await expect(policy.sendRequest(request, next)).rejects.toThrow("The operation was aborted."); - expect(next).toHaveBeenCalledOnce(); }); }); diff --git a/sdk/core/core-rest-pipeline/test/tracingPolicy.spec.ts b/sdk/core/core-rest-pipeline/test/tracingPolicy.spec.ts index bc6b23e0cf85..fc1b3ea71f02 100644 --- a/sdk/core/core-rest-pipeline/test/tracingPolicy.spec.ts +++ b/sdk/core/core-rest-pipeline/test/tracingPolicy.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, describe, it, vi, afterEach, beforeEach, expect, type Mock } from "vitest"; +import { describe, it, assert, expect, vi, beforeEach, afterEach, type Mock } from "vitest"; import { type PipelineRequest, type PipelineResponse, @@ -10,7 +10,7 @@ import { createHttpHeaders, createPipelineRequest, tracingPolicy, -} from "../src"; +} from "../src/index.js"; import { type Instrumenter, type InstrumenterSpanOptions, diff --git a/sdk/core/core-rest-pipeline/test/util.ts b/sdk/core/core-rest-pipeline/test/util.ts index 61331d808adf..c145048d140d 100644 --- a/sdk/core/core-rest-pipeline/test/util.ts +++ b/sdk/core/core-rest-pipeline/test/util.ts @@ -2,8 +2,8 @@ // Licensed under the MIT license. import type { AzureLogger } from "@azure/logger"; -import type { RequestBodyType } from "../src/interfaces"; -import { isNodeReadableStream } from "../src/util/typeGuards"; +import type { RequestBodyType } from "../src/interfaces.js"; +import { isNodeReadableStream } from "../src/util/typeGuards.js"; import { assert } from "vitest"; export function makeTestLogger(): { diff --git a/sdk/core/core-rest-pipeline/tsconfig.browser.config.json b/sdk/core/core-rest-pipeline/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-rest-pipeline/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-rest-pipeline/tsconfig.json b/sdk/core/core-rest-pipeline/tsconfig.json index 2c33ad6be57f..bb41058f8b8f 100644 --- a/sdk/core/core-rest-pipeline/tsconfig.json +++ b/sdk/core/core-rest-pipeline/tsconfig.json @@ -1,13 +1,14 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest", "paths": { - "@azure/core-rest-pipeline": ["./src/index"] + "@azure/core-rest-pipeline": ["./src/index.ts"] }, "lib": ["dom", "dom.iterable"], - "verbatimModuleSyntax": true + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts", "samples-dev/**/*.ts"] + "exclude": ["./samples/**/*.ts"], + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts", "./samples-dev/**/*.ts"] } diff --git a/sdk/core/core-rest-pipeline/vitest.browser.config.mts b/sdk/core/core-rest-pipeline/vitest.browser.config.mts deleted file mode 100644 index 8e7d959525d6..000000000000 --- a/sdk/core/core-rest-pipeline/vitest.browser.config.mts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import { defineConfig } from "vitest/config"; -import browserMap from "@azure-tools/vite-plugin-browser-test-map"; - -export default defineConfig({ - plugins: [browserMap()], - test: { - browser: { - enabled: true, - headless: true, - name: "chromium", - provider: "playwright", - }, - fakeTimers: { - toFake: ["setTimeout", "Date"], - }, - watch: false, - include: ["test/**/*.spec.ts"], - exclude: ["test/**/node/*.spec.ts"], - }, -}); diff --git a/sdk/core/core-rest-pipeline/vitest.browser.config.ts b/sdk/core/core-rest-pipeline/vitest.browser.config.ts new file mode 100644 index 000000000000..0b05437f23ac --- /dev/null +++ b/sdk/core/core-rest-pipeline/vitest.browser.config.ts @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; +import browserMap from "@azure-tools/vite-plugin-browser-test-map"; + +export default defineConfig({ + define: { + "process.env": process.env, + }, + plugins: [browserMap()], + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-rest-pipeline/vitest.config.ts b/sdk/core/core-rest-pipeline/vitest.config.ts index caa1f342fe4a..e94c7dd91c76 100644 --- a/sdk/core/core-rest-pipeline/vitest.config.ts +++ b/sdk/core/core-rest-pipeline/vitest.config.ts @@ -5,8 +5,27 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, watch: false, include: ["test/**/*.spec.ts"], exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, }, }); diff --git a/sdk/core/core-sse/.mocharc.json b/sdk/core/core-sse/.mocharc.json deleted file mode 100644 index 332e7113dd57..000000000000 --- a/sdk/core/core-sse/.mocharc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extension": ["ts"], - "timeout": "1200000", - "loader": "ts-node/esm" -} diff --git a/sdk/core/core-sse/.tshy/browser.json b/sdk/core/core-sse/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-sse/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-sse/.tshy/build.json b/sdk/core/core-sse/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-sse/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-sse/.tshy/commonjs.json b/sdk/core/core-sse/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/core-sse/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-sse/.tshy/esm.json b/sdk/core/core-sse/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/core-sse/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-sse/.tshy/react-native.json b/sdk/core/core-sse/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/core-sse/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-sse/api-extractor.json b/sdk/core/core-sse/api-extractor.json index 168f7db8f6bf..23ecf31193df 100644 --- a/sdk/core/core-sse/api-extractor.json +++ b/sdk/core/core-sse/api-extractor.json @@ -1,12 +1,12 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "./types/src/index.d.ts", + "mainEntryPointFilePath": "./dist/esm/index.d.ts", "docModel": { "enabled": true }, "apiReport": { "enabled": true, "reportFolder": "./review" }, "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/core-sse.d.ts" + "publicTrimmedFilePath": "./dist/core-sse.d.ts" }, "messages": { "tsdocMessageReporting": { "default": { "logLevel": "none" } }, diff --git a/sdk/core/core-sse/karma.conf.cjs b/sdk/core/core-sse/karma.conf.cjs deleted file mode 100644 index 578ee619aed2..000000000000 --- a/sdk/core/core-sse/karma.conf.cjs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); -require("dotenv").config(); -const { relativeRecordingsPath } = require("@azure-tools/test-recorder"); - -process.env.RECORDINGS_RELATIVE_PATH = relativeRecordingsPath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: [ - "dist-test/index.browser.js", - { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true }, - ], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - envPreprocessor: [ - "TEST_MODE", - ], - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - // --no-sandbox allows our tests to run in Linux without having to change the system. - // --disable-web-security allows us to authenticate from the browser without having to write tests using interactive auth, which would be far more complex. - browsers: ["ChromeHeadlessNoSandbox"], - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: "ChromeHeadless", - flags: ["--no-sandbox", "--disable-web-security"], - }, - }, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-sse/package.json b/sdk/core/core-sse/package.json index ef072e63a265..e25d5183b02c 100644 --- a/sdk/core/core-sse/package.json +++ b/sdk/core/core-sse/package.json @@ -3,36 +3,32 @@ "version": "2.0.1", "description": "Implementation of the Server-sent events protocol for Node.js and browsers.", "sdk-type": "client", - "main": "dist/index.cjs", - "module": "dist-esm/src/index.js", "type": "module", - "types": "types/core-sse.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "build:test": "tsc -p . && dev-tool run bundle", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "dev-tool samples run samples-dev", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint README.md package.json api-extractor.json src test --ext .ts,.javascript,.js --fix --fix-type [problem,suggestion]", - "lint": "eslint README.md package.json api-extractor.json src test --ext .ts,.javascript,.js", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "dev-tool run test:browser -- karma.conf.cjs", - "unit-test:node": "dev-tool run test:node-ts-input", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types", "README.md", "LICENSE" ], @@ -56,39 +52,47 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-sse/README.md", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "dev-tool samples run samples-dev", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@azure/test-utils": "^1.0.0", - "@azure-tools/test-recorder": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/mocha": "^10.0.0", + "@azure-tools/vite-plugin-browser-test-map": "^1.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "cross-env": "^7.0.3", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", "dotenv": "^16.0.0", - "eslint": "^8.16.0", - "esm": "^3.2.18", - "karma": "^6.4.0", - "karma-chrome-launcher": "^3.1.1", - "karma-coverage": "^2.2.0", - "karma-edge-launcher": "^0.4.2", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^2.1.2", - "karma-json-preprocessor": "^0.3.3", - "karma-json-to-file-reporter": "^1.0.1", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "c8": "^8.0.0", - "puppeteer": "^22.0.0", - "rimraf": "^3.0.2", - "ts-node": "^10.0.0", - "typescript": "~5.3.3" + "eslint": "^8.56.0", + "prettier": "^3.2.5", + "playwright": "^1.41.2", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", + "typescript": "~5.2.0", + "vitest": "^1.2.2" }, "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.6.2" }, "//metadata": { "sampleConfiguration": { @@ -99,5 +103,19 @@ "azure" ] } + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-sse/review/core-sse.api.md b/sdk/core/core-sse/review/core-sse.api.md index ef3dd4fd312d..df0566be13db 100644 --- a/sdk/core/core-sse/review/core-sse.api.md +++ b/sdk/core/core-sse/review/core-sse.api.md @@ -6,7 +6,7 @@ /// -import type { IncomingMessage } from 'http'; +import type { IncomingMessage } from 'node:http'; // @public export function createSseStream(chunkStream: ReadableStream): EventMessageStream; diff --git a/sdk/core/core-sse/src/sse.ts b/sdk/core/core-sse/src/sse.ts index d6261d439d10..bda42e7a88cc 100644 --- a/sdk/core/core-sse/src/sse.ts +++ b/sdk/core/core-sse/src/sse.ts @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { IncomingMessage } from "http"; +import type { IncomingMessage } from "node:http"; import { EventMessage, EventMessageStream, PartialSome } from "./models.js"; import { createStream, ensureAsyncIterable } from "./utils.js"; -const enum ControlChars { +enum ControlChars { NewLine = 10, CarriageReturn = 13, Space = 32, diff --git a/sdk/core/core-sse/src/utils.ts b/sdk/core/core-sse/src/utils.ts index 5b8872dccb1d..0fda70a14b75 100644 --- a/sdk/core/core-sse/src/utils.ts +++ b/sdk/core/core-sse/src/utils.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { IncomingMessage } from "http"; +import type { IncomingMessage } from "node:http"; export function createStream( asyncIter: AsyncIterableIterator, diff --git a/sdk/core/core-sse/test/internal/createStream.spec.ts b/sdk/core/core-sse/test/internal/createStream.spec.ts index a4ef3ddb696a..fd6669d8829a 100644 --- a/sdk/core/core-sse/test/internal/createStream.spec.ts +++ b/sdk/core/core-sse/test/internal/createStream.spec.ts @@ -1,11 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "@azure/test-utils"; +import { describe, it, assert, beforeEach } from "vitest"; import { createStream } from "../../src/utils.js"; -import { Context } from "mocha"; describe("createStream", () => { + beforeEach((ctx) => { + console.log("Context:", ctx.task.name); + console.log("Suite:", ctx.task.suite.name); + }); + const createIter = async function* (): AsyncGenerator { yield 1; yield 2; @@ -32,12 +36,13 @@ describe("createStream", () => { assert.isTrue(canceled); }); - it("creates disposable stream", async function (this: Context) { + it("creates disposable stream", async function () { let disposed = false; { - await using stream = createStream(createIter(), async () => { + const stream = createStream(createIter(), async () => { disposed = true; }); + await stream[Symbol.asyncDispose](); assert.isDefined(stream); } assert.isTrue(disposed); diff --git a/sdk/core/core-sse/test/matrix.ts b/sdk/core/core-sse/test/matrix.ts new file mode 100644 index 000000000000..14b3295e4ae3 --- /dev/null +++ b/sdk/core/core-sse/test/matrix.ts @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** + * Takes a jagged 2D array and a function and runs the function with every + * possible combination of elements of each of the arrays + * + * For strong type-checking, it is important that the `matrix` have a strong + * type, such as a `const` literal. + * + * @param values - jagged 2D array specifying the arguments and their possible + * values + * @param handler - the function to run with the different argument combinations + * + * @example + * ```typescript + * matrix([ + * [true, false], + * [1, 2, 3] + * ] as const, + * (useLabels: boolean, attempts: number) => { + * // This body will run six times with the following parameters: + * // - true, 1 + * // - true, 2 + * // - true, 3 + * // - false, 1 + * // - false, 2 + * // - false, 3 + * }); + * ``` + */ +export function matrix>( + values: T, + handler: ( + ...args: { [idx in keyof T]: T[idx] extends ReadonlyArray ? U : never } + ) => Promise, +): void { + // Classic recursive approach + if (values.length === 0) { + (handler as () => Promise)(); + } else { + for (const v of values[0]) { + matrix(values.slice(1), (...args) => (handler as any)(v, ...args)); + } + } +} diff --git a/sdk/core/core-sse/test/public/sse.ts b/sdk/core/core-sse/test/public/sse.ts index bc28e8eee19a..3d34e2db9259 100644 --- a/sdk/core/core-sse/test/public/sse.ts +++ b/sdk/core/core-sse/test/public/sse.ts @@ -18,12 +18,13 @@ import { genStrs, createRetry, } from "./util.js"; -import { assert, matrix } from "@azure/test-utils"; +import { describe, it, assert, SuiteCollector } from "vitest"; +import { matrix } from "../matrix.js"; export function buildSseTests( rtName: string, createStream: (cb: (write: (chunk: Uint8Array) => void) => void) => AsyncIterable, -): Mocha.Suite { +): SuiteCollector { return describe(`[${rtName}] Server-sent Events`, () => { matrix([[0, 1, 2, 10000]], async function (count: number) { matrix([[1, 3, 10]], async function (chunkLen: number) { diff --git a/sdk/core/core-sse/test/public/util.ts b/sdk/core/core-sse/test/public/util.ts index 0dd39aa77a13..ccf840d5ca10 100644 --- a/sdk/core/core-sse/test/public/util.ts +++ b/sdk/core/core-sse/test/public/util.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "@azure/test-utils"; +import { assert } from "vitest"; export async function assertAsyncIterable( iter: AsyncIterable, diff --git a/sdk/core/core-sse/tsconfig.browser.config.json b/sdk/core/core-sse/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-sse/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-sse/tsconfig.json b/sdk/core/core-sse/tsconfig.json index 1235b92f7174..4c1d9d742791 100644 --- a/sdk/core/core-sse/tsconfig.json +++ b/sdk/core/core-sse/tsconfig.json @@ -1,14 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types", - "paths": { "@azure/core-sse": ["./src/index.js"] }, + "paths": { + "@azure/core-sse": ["./src/index.ts"] + }, "module": "NodeNext", "moduleResolution": "NodeNext", "lib": ["esnext", "dom"], "rootDir": "." }, - "ts-node": { "esm": true }, - "include": ["src/**/*.ts", "test/**/*.ts", "samples-dev/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "samples-dev/**/*.ts"] } diff --git a/sdk/core/core-sse/vitest.browser.config.ts b/sdk/core/core-sse/vitest.browser.config.ts new file mode 100644 index 000000000000..2f6cb1fe1844 --- /dev/null +++ b/sdk/core/core-sse/vitest.browser.config.ts @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + env: { + "TEST_MODE": "playback", + }, + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-sse/vitest.config.ts b/sdk/core/core-sse/vitest.config.ts new file mode 100644 index 000000000000..7c014c00af62 --- /dev/null +++ b/sdk/core/core-sse/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-tracing/.tshy/browser.json b/sdk/core/core-tracing/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-tracing/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-tracing/.tshy/build.json b/sdk/core/core-tracing/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-tracing/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-tracing/.tshy/commonjs.json b/sdk/core/core-tracing/.tshy/commonjs.json new file mode 100644 index 000000000000..5ace94d041f3 --- /dev/null +++ b/sdk/core/core-tracing/.tshy/commonjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-tracing/.tshy/esm.json b/sdk/core/core-tracing/.tshy/esm.json new file mode 100644 index 000000000000..ff5264e692d1 --- /dev/null +++ b/sdk/core/core-tracing/.tshy/esm.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-tracing/.tshy/react-native.json b/sdk/core/core-tracing/.tshy/react-native.json new file mode 100644 index 000000000000..f431a06985d8 --- /dev/null +++ b/sdk/core/core-tracing/.tshy/react-native.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-tracing/api-extractor.json b/sdk/core/core-tracing/api-extractor.json index 2edf11c57ced..2e8c4eb9358b 100644 --- a/sdk/core/core-tracing/api-extractor.json +++ b/sdk/core/core-tracing/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/core-tracing.d.ts" + "publicTrimmedFilePath": "./dist/core-tracing.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-tracing/karma.conf.js b/sdk/core/core-tracing/karma.conf.js deleted file mode 100644 index 8a9ca6b90839..000000000000 --- a/sdk/core/core-tracing/karma.conf.js +++ /dev/null @@ -1,111 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: [ - "dist-test/index.browser.js", - { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true }, - ], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - "dist-test/index.js": ["coverage"], - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - envPreprocessor: ["ACCOUNT_NAME", "ACCOUNT_SAS"], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-tracing/package.json b/sdk/core/core-tracing/package.json index 893d1679c6b4..91dd01784e6c 100644 --- a/sdk/core/core-tracing/package.json +++ b/sdk/core/core-tracing/package.json @@ -3,39 +3,32 @@ "version": "1.0.2", "description": "Provides low-level interfaces and helper methods for tracing in Azure SDK", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "browser": {}, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js" - }, - "types": "types/core-tracing.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/core-tracing.d.ts", "README.md", "LICENSE" ], @@ -55,37 +48,46 @@ }, "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-tracing/README.md", "sideEffects": false, + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/core-auth": "^1.3.0", "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", "eslint": "^8.0.0", - "inherits": "^2.0.3", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "rimraf": "^3.0.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "util": "^0.12.1", - "sinon": "^17.0.0", - "@types/sinon": "^17.0.0", - "ts-node": "^10.0.0" + "vitest": "^1.2.2" }, "//metadata": { "sampleConfiguration": { @@ -96,5 +98,19 @@ ] }, "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-tracing/samples/v1/javascript/package.json b/sdk/core/core-tracing/samples/v1/javascript/package.json index 93177cbe98c0..2d2521b16a66 100644 --- a/sdk/core/core-tracing/samples/v1/javascript/package.json +++ b/sdk/core/core-tracing/samples/v1/javascript/package.json @@ -3,6 +3,7 @@ "private": true, "version": "1.0.0", "description": "Azure SDK Core client library samples for JavaScript", + "type": "module", "engines": { "node": ">=18.0.0" }, diff --git a/sdk/core/core-tracing/samples/v1/typescript/package.json b/sdk/core/core-tracing/samples/v1/typescript/package.json index 642f1c2e8a87..1fe6c808f3c2 100644 --- a/sdk/core/core-tracing/samples/v1/typescript/package.json +++ b/sdk/core/core-tracing/samples/v1/typescript/package.json @@ -3,6 +3,7 @@ "private": true, "version": "1.0.0", "description": "Azure SDK Core client library samples for TypeScript", + "type": "module", "engines": { "node": ">=18.0.0" }, diff --git a/sdk/core/core-tracing/src/index.ts b/sdk/core/core-tracing/src/index.ts index cf951c7deb39..6866815ca62a 100644 --- a/sdk/core/core-tracing/src/index.ts +++ b/sdk/core/core-tracing/src/index.ts @@ -17,6 +17,6 @@ export { TracingSpanKind, TracingSpanLink, TracingSpanOptions, -} from "./interfaces"; -export { useInstrumenter } from "./instrumenter"; -export { createTracingClient } from "./tracingClient"; +} from "./interfaces.js"; +export { useInstrumenter } from "./instrumenter.js"; +export { createTracingClient } from "./tracingClient.js"; diff --git a/sdk/core/core-tracing/src/instrumenter.ts b/sdk/core/core-tracing/src/instrumenter.ts index 2e86299f3496..f591634bf520 100644 --- a/sdk/core/core-tracing/src/instrumenter.ts +++ b/sdk/core/core-tracing/src/instrumenter.ts @@ -1,8 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Instrumenter, InstrumenterSpanOptions, TracingContext, TracingSpan } from "./interfaces"; -import { createTracingContext } from "./tracingContext"; +import { + Instrumenter, + InstrumenterSpanOptions, + TracingContext, + TracingSpan, +} from "./interfaces.js"; +import { createTracingContext } from "./tracingContext.js"; export function createDefaultTracingSpan(): TracingSpan { return { diff --git a/sdk/core/core-tracing/src/tracingClient.ts b/sdk/core/core-tracing/src/tracingClient.ts index 3e8f5917e265..810d11da9dc1 100644 --- a/sdk/core/core-tracing/src/tracingClient.ts +++ b/sdk/core/core-tracing/src/tracingClient.ts @@ -10,9 +10,9 @@ import { TracingContext, TracingSpan, TracingSpanOptions, -} from "./interfaces"; -import { getInstrumenter } from "./instrumenter"; -import { knownContextKeys } from "./tracingContext"; +} from "./interfaces.js"; +import { getInstrumenter } from "./instrumenter.js"; +import { knownContextKeys } from "./tracingContext.js"; /** * Creates a new tracing client. diff --git a/sdk/core/core-tracing/src/tracingContext.ts b/sdk/core/core-tracing/src/tracingContext.ts index d2b6594d5de5..6ebc8036dd9c 100644 --- a/sdk/core/core-tracing/src/tracingContext.ts +++ b/sdk/core/core-tracing/src/tracingContext.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TracingContext, TracingSpan } from "./interfaces"; +import { TracingContext, TracingSpan } from "./interfaces.js"; /** @internal */ export const knownContextKeys = { diff --git a/sdk/core/core-tracing/test/instrumenter.spec.ts b/sdk/core/core-tracing/test/instrumenter.spec.ts index bf030c667ef6..7226276bb737 100644 --- a/sdk/core/core-tracing/test/instrumenter.spec.ts +++ b/sdk/core/core-tracing/test/instrumenter.spec.ts @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Instrumenter, TracingSpan } from "../src/interfaces"; +import { Instrumenter, TracingSpan } from "../src/interfaces.js"; import { createDefaultInstrumenter, createDefaultTracingSpan, getInstrumenter, useInstrumenter, -} from "../src/instrumenter"; -import { createTracingContext, knownContextKeys } from "../src/tracingContext"; -import { assert } from "chai"; +} from "../src/instrumenter.js"; +import { createTracingContext, knownContextKeys } from "../src/tracingContext.js"; +import { describe, it, assert, beforeEach } from "vitest"; describe("Instrumenter", () => { describe("NoOpInstrumenter", () => { diff --git a/sdk/core/core-tracing/test/interfaces.spec.ts b/sdk/core/core-tracing/test/interfaces.spec.ts index 8db53c7c0ee2..23cbb3d5cb74 100644 --- a/sdk/core/core-tracing/test/interfaces.spec.ts +++ b/sdk/core/core-tracing/test/interfaces.spec.ts @@ -2,9 +2,9 @@ // Licensed under the MIT license. import * as coreAuth from "@azure/core-auth"; -import * as coreTracing from "../src"; -import { assert } from "chai"; -import { createTracingContext } from "../src/tracingContext"; +import * as coreTracing from "../src/index.js"; +import { describe, it, assert } from "vitest"; +import { createTracingContext } from "../src/tracingContext.js"; describe("Interface compatibility", () => { describe("OperationTracingOptions", () => { diff --git a/sdk/core/core-tracing/test/tracingClient.spec.ts b/sdk/core/core-tracing/test/tracingClient.spec.ts index dd4cc5b4ecc9..a1cf84c26576 100644 --- a/sdk/core/core-tracing/test/tracingClient.spec.ts +++ b/sdk/core/core-tracing/test/tracingClient.spec.ts @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Instrumenter, TracingClient, TracingContext, TracingSpan } from "../src/interfaces"; +import { Instrumenter, TracingClient, TracingContext, TracingSpan } from "../src/interfaces.js"; import { createDefaultInstrumenter, createDefaultTracingSpan, useInstrumenter, -} from "../src/instrumenter"; -import { createTracingContext, knownContextKeys } from "../src/tracingContext"; -import { assert } from "chai"; -import { createTracingClient } from "../src/tracingClient"; -import sinon from "sinon"; +} from "../src/instrumenter.js"; +import { createTracingContext, knownContextKeys } from "../src/tracingContext.js"; +import { describe, it, assert, expect, beforeEach, afterEach, vi } from "vitest"; +import { createTracingClient } from "../src/tracingClient.js"; describe("TracingClient", () => { let instrumenter: Instrumenter; @@ -33,7 +32,7 @@ describe("TracingClient", () => { }); afterEach(() => { - sinon.restore(); + vi.restoreAllMocks(); }); describe("#startSpan", () => { @@ -46,23 +45,20 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setAttributeSpy = sinon.spy(span, "setAttribute"); + const setAttributeSpy = vi.spyOn(span, "setAttribute"); client.startSpan("test", {}); - assert.isTrue( - setAttributeSpy.calledWith("az.namespace", expectedNamespace), - `expected span.setAttribute("az.namespace", "${expectedNamespace}") to have been called`, - ); + expect(setAttributeSpy).toBeCalledWith("az.namespace", expectedNamespace); }); it("passes package information to instrumenter", () => { - const instrumenterStartSpanSpy = sinon.spy(instrumenter, "startSpan"); + const instrumenterStartSpanSpy = vi.spyOn(instrumenter, "startSpan"); client.startSpan("test", {}); - assert.isTrue(instrumenterStartSpanSpy.called); - const args = instrumenterStartSpanSpy.getCall(0).args; - - assert.equal(args[0], "test"); - assert.equal(args[1]?.packageName, "test-package"); - assert.equal(args[1]?.packageVersion, "1.0.0"); + expect(instrumenterStartSpanSpy).toHaveBeenCalledOnce(); + expect(instrumenterStartSpanSpy).toHaveBeenCalledWith("test", { + packageName: "test-package", + packageVersion: "1.0.0", + tracingContext: undefined, + }); }); it("sets namespace on context", () => { @@ -112,14 +108,11 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setAttributeSpy = sinon.spy(span, "setAttribute"); + const setAttributeSpy = vi.spyOn(span, "setAttribute"); await client.withSpan(spanName, {}, async () => { // no op }); - assert.isTrue( - setAttributeSpy.calledWith("az.namespace", expectedNamespace), - `expected span.setAttribute("az.namespace", "${expectedNamespace}") to have been called`, - ); + expect(setAttributeSpy).toBeCalledWith("az.namespace", expectedNamespace); }); it("passes options and span to callback", async () => { @@ -172,10 +165,10 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setStatusSpy = sinon.spy(span, "setStatus"); + const setStatusSpy = vi.spyOn(span, "setStatus"); await client.withSpan(spanName, {}, () => Promise.resolve(42)); - assert.isTrue(setStatusSpy.calledWith(sinon.match({ status: "success" }))); + expect(setStatusSpy).toHaveBeenCalledWith({ status: "success" }); }); }); @@ -189,13 +182,13 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setStatusSpy = sinon.spy(span, "setStatus"); + const setStatusSpy = vi.spyOn(span, "setStatus"); let errorThrown = false; try { await client.withSpan(spanName, {}, () => Promise.reject(new Error("test"))); } catch (err: any) { errorThrown = true; - assert.isTrue(setStatusSpy.calledWith(sinon.match({ status: "error", error: err }))); + expect(setStatusSpy).toHaveBeenCalledWith({ status: "error", error: err }); } assert.isTrue(errorThrown); diff --git a/sdk/core/core-tracing/test/tracingContext.spec.ts b/sdk/core/core-tracing/test/tracingContext.spec.ts index 1766651220cc..6bca44162294 100644 --- a/sdk/core/core-tracing/test/tracingContext.spec.ts +++ b/sdk/core/core-tracing/test/tracingContext.spec.ts @@ -1,9 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TracingContextImpl, createTracingContext, knownContextKeys } from "../src/tracingContext"; -import { assert } from "chai"; -import { createDefaultTracingSpan } from "../src/instrumenter"; +import { + TracingContextImpl, + createTracingContext, + knownContextKeys, +} from "../src/tracingContext.js"; +import { describe, it, assert, beforeEach } from "vitest"; +import { createDefaultTracingSpan } from "../src/instrumenter.js"; describe("TracingContext", () => { describe("TracingContextImpl", () => { diff --git a/sdk/core/core-tracing/tsconfig.browser.config.json b/sdk/core/core-tracing/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-tracing/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-tracing/tsconfig.json b/sdk/core/core-tracing/tsconfig.json index 3615e0b8112f..f76619f65934 100644 --- a/sdk/core/core-tracing/tsconfig.json +++ b/sdk/core/core-tracing/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "declarationDir": "./types", - "outDir": "./dist-esm", "paths": { - "@azure/core-tracing": ["./src/index"] - } - } + "@azure/core-tracing": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." + }, + "exclude": ["./samples/**/*.ts"], + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts", "./samples-dev/**/*.ts"] } diff --git a/sdk/core/core-tracing/vitest.browser.config.ts b/sdk/core/core-tracing/vitest.browser.config.ts new file mode 100644 index 000000000000..005a2f7d4b67 --- /dev/null +++ b/sdk/core/core-tracing/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-tracing/vitest.config.ts b/sdk/core/core-tracing/vitest.config.ts new file mode 100644 index 000000000000..f46a08861fab --- /dev/null +++ b/sdk/core/core-tracing/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "v8", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/core-util/.eslintrc.json b/sdk/core/core-util/.eslintrc.json index cc81de60752d..75ebbc35ccc6 100644 --- a/sdk/core/core-util/.eslintrc.json +++ b/sdk/core/core-util/.eslintrc.json @@ -2,6 +2,9 @@ "plugins": ["@azure/azure-sdk"], "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], "rules": { - "@azure/azure-sdk/ts-package-json-module": "off" + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-files-required": "off", + "@azure/azure-sdk/ts-package-json-main-is-cjs": "off", + "@azure/azure-sdk/ts-package-json-types": "off" } } diff --git a/sdk/core/core-util/.tshy/browser.json b/sdk/core/core-util/.tshy/browser.json new file mode 100644 index 000000000000..9d5ec2447058 --- /dev/null +++ b/sdk/core/core-util/.tshy/browser.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/uuidUtils-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-util/.tshy/build.json b/sdk/core/core-util/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-util/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-util/.tshy/commonjs.json b/sdk/core/core-util/.tshy/commonjs.json new file mode 100644 index 000000000000..11bf01e4494c --- /dev/null +++ b/sdk/core/core-util/.tshy/commonjs.json @@ -0,0 +1,18 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/bytesEncoding-browser.mts", + "../src/sha256-browser.mts", + "../src/uuidUtils-browser.mts", + "../src/uuidUtils-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-util/.tshy/esm.json b/sdk/core/core-util/.tshy/esm.json new file mode 100644 index 000000000000..7738cb358389 --- /dev/null +++ b/sdk/core/core-util/.tshy/esm.json @@ -0,0 +1,17 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/bytesEncoding-browser.mts", + ".././src/sha256-browser.mts", + ".././src/uuidUtils-browser.mts", + ".././src/uuidUtils-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-util/.tshy/react-native.json b/sdk/core/core-util/.tshy/react-native.json new file mode 100644 index 000000000000..cfc2c4e8d1fb --- /dev/null +++ b/sdk/core/core-util/.tshy/react-native.json @@ -0,0 +1,16 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/bytesEncoding-browser.mts", + ".././src/sha256-browser.mts", + ".././src/uuidUtils-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-util/api-extractor.json b/sdk/core/core-util/api-extractor.json index eaef6fb85055..f79506f6e928 100644 --- a/sdk/core/core-util/api-extractor.json +++ b/sdk/core/core-util/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/index.d.ts", + "mainEntryPointFilePath": "./dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-util.d.ts" + "publicTrimmedFilePath": "./dist/core-util.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-util/karma.conf.js b/sdk/core/core-util/karma.conf.js deleted file mode 100644 index 6c6511f22729..000000000000 --- a/sdk/core/core-util/karma.conf.js +++ /dev/null @@ -1,108 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: ["dist-test/index.browser.js"], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - // EXAMPLE: envPreprocessor: ["ACCOUNT_NAME", "ACCOUNT_SAS"], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-util/package.json b/sdk/core/core-util/package.json index 612d06eac339..1e7f7850f300 100644 --- a/sdk/core/core-util/package.json +++ b/sdk/core/core-util/package.json @@ -3,44 +3,32 @@ "version": "1.7.1", "description": "Core library for shared utility methods", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/index.js", - "browser": { - "./dist-esm/sha256.js": "./dist-esm/sha256.browser.js", - "./dist-esm/uuidUtils.js": "./dist-esm/uuidUtils.browser.js", - "./dist-esm/bytesEncoding.js": "./dist-esm/bytesEncoding.browser.js" - }, - "react-native": { - "./dist/index.js": "./dist-esm/index.js", - "./dist-esm/uuidUtils.js": "./dist-esm/uuidUtils.native.js" - }, - "types": "types/latest/core-util.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "echo Obsolete", - "build": "npm run clean && tsc -p . && dev-tool run bundle --browser-test false && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run unit-test:node && npm run integration-test:node", - "test": "npm run test:node && npm run test:browser", - "unit-test:browser": "dev-tool run test:vitest --no-test-proxy=true --browser=true", - "unit-test:node": "dev-tool run test:vitest --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/", - "types/latest/core-util.d.ts", "README.md", "LICENSE" ], @@ -60,24 +48,63 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-util/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { "@azure/abort-controller": "^2.0.0", - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@azure-tools/vite-plugin-browser-test-map": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "@vitest/browser": "^1.2.1", - "eslint": "^8.0.0", - "playwright": "^1.39.0", - "rimraf": "^3.0.0", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "vitest": "^1.2.1" + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-util/src/bytesEncoding.browser.ts b/sdk/core/core-util/src/bytesEncoding-browser.mts similarity index 100% rename from sdk/core/core-util/src/bytesEncoding.browser.ts rename to sdk/core/core-util/src/bytesEncoding-browser.mts diff --git a/sdk/core/core-util/src/checkEnvironment.ts b/sdk/core/core-util/src/checkEnvironment.ts index 70b76ce42b78..15f2920a14a0 100644 --- a/sdk/core/core-util/src/checkEnvironment.ts +++ b/sdk/core/core-util/src/checkEnvironment.ts @@ -1,41 +1,39 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -declare global { - interface Window { - document: unknown; - } - - interface DedicatedWorkerGlobalScope { - constructor: { - name: string; - }; +interface Window { + document: unknown; +} - importScripts: (...paths: string[]) => void; - } +interface DedicatedWorkerGlobalScope { + constructor: { + name: string; + }; - interface Navigator { - product: string; - } + importScripts: (...paths: string[]) => void; +} - interface DenoGlobal { - version: { - deno: string; - }; - } +interface Navigator { + product: string; +} - interface BunGlobal { - version: string; - } +interface DenoGlobal { + version: { + deno: string; + }; +} - // eslint-disable-next-line @azure/azure-sdk/ts-no-window - const window: Window; - const self: DedicatedWorkerGlobalScope; - const Deno: DenoGlobal; - const Bun: BunGlobal; - const navigator: Navigator; +interface BunGlobal { + version: string; } +// eslint-disable-next-line @azure/azure-sdk/ts-no-window +declare const window: Window; +declare const self: DedicatedWorkerGlobalScope; +declare const Deno: DenoGlobal; +declare const Bun: BunGlobal; +declare const navigator: Navigator; + /** * A constant that indicates whether the environment the code is running is a Web Browser. */ @@ -69,9 +67,9 @@ export const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undef * A constant that indicates whether the environment the code is running is Node.JS. */ export const isNode = - typeof process !== "undefined" && - Boolean(process.version) && - Boolean(process.versions?.node) && + typeof globalThis.process !== "undefined" && + Boolean(globalThis.process.version) && + Boolean(globalThis.process.versions?.node) && // Deno thought it was a good idea to spoof process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions !isDeno && !isBun; diff --git a/sdk/core/core-util/src/createAbortablePromise.ts b/sdk/core/core-util/src/createAbortablePromise.ts index 343ac2dce50a..61cebba7e81b 100644 --- a/sdk/core/core-util/src/createAbortablePromise.ts +++ b/sdk/core/core-util/src/createAbortablePromise.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { AbortError } from "@azure/abort-controller"; -import type { AbortOptions } from "./aborterUtils"; +import type { AbortOptions } from "./aborterUtils.js"; /** * Options for the createAbortablePromise function. diff --git a/sdk/core/core-util/src/delay.ts b/sdk/core/core-util/src/delay.ts index 4d57d2723d72..e8f3a9993323 100644 --- a/sdk/core/core-util/src/delay.ts +++ b/sdk/core/core-util/src/delay.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { AbortOptions } from "./aborterUtils"; -import { createAbortablePromise } from "./createAbortablePromise"; +import type { AbortOptions } from "./aborterUtils.js"; +import { createAbortablePromise } from "./createAbortablePromise.js"; const StandardAbortMessage = "The delay was aborted."; diff --git a/sdk/core/core-util/src/error.ts b/sdk/core/core-util/src/error.ts index c6bce37777a7..f876780d95a8 100644 --- a/sdk/core/core-util/src/error.ts +++ b/sdk/core/core-util/src/error.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isObject } from "./object"; +import { isObject } from "./object.js"; /** * Typeguard for an error object shape (has name and message) diff --git a/sdk/core/core-util/src/index.ts b/sdk/core/core-util/src/index.ts index ad22b21263a3..e3a1b862622c 100644 --- a/sdk/core/core-util/src/index.ts +++ b/sdk/core/core-util/src/index.ts @@ -1,21 +1,28 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { delay, type DelayOptions } from "./delay"; +export { delay, type DelayOptions } from "./delay.js"; export { type AbortOptions, cancelablePromiseRace, type AbortablePromiseBuilder, -} from "./aborterUtils"; +} from "./aborterUtils.js"; export { createAbortablePromise, type CreateAbortablePromiseOptions, -} from "./createAbortablePromise"; -export { getRandomIntegerInclusive } from "./random"; -export { isObject, type UnknownObject } from "./object"; -export { isError, getErrorMessage } from "./error"; -export { computeSha256Hash, computeSha256Hmac } from "./sha256"; -export { isDefined, isObjectWithProperties, objectHasProperty } from "./typeGuards"; -export { randomUUID } from "./uuidUtils"; -export { isBrowser, isBun, isNode, isDeno, isReactNative, isWebWorker } from "./checkEnvironment"; -export { uint8ArrayToString, stringToUint8Array, type EncodingType } from "./bytesEncoding"; +} from "./createAbortablePromise.js"; +export { getRandomIntegerInclusive } from "./random.js"; +export { isObject, type UnknownObject } from "./object.js"; +export { isError, getErrorMessage } from "./error.js"; +export { computeSha256Hash, computeSha256Hmac } from "./sha256.js"; +export { isDefined, isObjectWithProperties, objectHasProperty } from "./typeGuards.js"; +export { randomUUID } from "./uuidUtils.js"; +export { + isBrowser, + isBun, + isNode, + isDeno, + isReactNative, + isWebWorker, +} from "./checkEnvironment.js"; +export { uint8ArrayToString, stringToUint8Array, type EncodingType } from "./bytesEncoding.js"; diff --git a/sdk/core/ts-http-runtime/src/util/sha256.browser.ts b/sdk/core/core-util/src/sha256-browser.mts similarity index 99% rename from sdk/core/ts-http-runtime/src/util/sha256.browser.ts rename to sdk/core/core-util/src/sha256-browser.mts index 6f6eb47aba68..5c466bd611bf 100644 --- a/sdk/core/ts-http-runtime/src/util/sha256.browser.ts +++ b/sdk/core/core-util/src/sha256-browser.mts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { stringToUint8Array, uint8ArrayToString } from "./bytesEncoding.browser"; +import { stringToUint8Array, uint8ArrayToString } from "./bytesEncoding.js"; // stubs for browser self.crypto interface JsonWebKey {} diff --git a/sdk/core/core-util/src/uuidUtils.browser.ts b/sdk/core/core-util/src/uuidUtils-browser.mts similarity index 90% rename from sdk/core/core-util/src/uuidUtils.browser.ts rename to sdk/core/core-util/src/uuidUtils-browser.mts index 69ff81071615..9452dcdd118c 100644 --- a/sdk/core/core-util/src/uuidUtils.browser.ts +++ b/sdk/core/core-util/src/uuidUtils-browser.mts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { generateUUID } from "./uuidUtils.native"; +import { generateUUID } from "./uuidUtils.common.js"; interface Crypto { randomUUID(): string; diff --git a/sdk/core/core-client/src/dom.d.ts b/sdk/core/core-util/src/uuidUtils-react-native.mts similarity index 59% rename from sdk/core/core-client/src/dom.d.ts rename to sdk/core/core-util/src/uuidUtils-react-native.mts index 88bcf1442b2f..bb681ec861b7 100644 --- a/sdk/core/core-client/src/dom.d.ts +++ b/sdk/core/core-util/src/uuidUtils-react-native.mts @@ -1,4 +1,4 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -/// +export { randomUUID } from "./uuidUtils.common.js"; diff --git a/sdk/core/ts-http-runtime/src/util/uuidUtils.native.ts b/sdk/core/core-util/src/uuidUtils.common.ts similarity index 91% rename from sdk/core/ts-http-runtime/src/util/uuidUtils.native.ts rename to sdk/core/core-util/src/uuidUtils.common.ts index fa7bb3c8d663..f0c36324e9b6 100644 --- a/sdk/core/ts-http-runtime/src/util/uuidUtils.native.ts +++ b/sdk/core/core-util/src/uuidUtils.common.ts @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -/* - * NOTE: When moving this file, please update "react-native" section in package.json. - */ - /** * Generated Universally Unique Identifier * diff --git a/sdk/core/core-util/src/uuidUtils.ts b/sdk/core/core-util/src/uuidUtils.ts index 96d2bfa34980..f5eb48438b16 100644 --- a/sdk/core/core-util/src/uuidUtils.ts +++ b/sdk/core/core-util/src/uuidUtils.ts @@ -2,7 +2,6 @@ // Licensed under the MIT license. import { randomUUID as v4RandomUUID } from "crypto"; -import { generateUUID } from "./uuidUtils.native"; interface Crypto { randomUUID(): string; @@ -13,16 +12,11 @@ declare const globalThis: { }; // NOTE: This is a workaround until we can use `globalThis.crypto.randomUUID` in Node.js 19+. -let uuidFunction = +const uuidFunction = typeof globalThis?.crypto?.randomUUID === "function" ? globalThis.crypto.randomUUID.bind(globalThis.crypto) : v4RandomUUID; -// Not defined in earlier versions of Node.js 14 -if (!uuidFunction) { - uuidFunction = generateUUID; -} - /** * Generated Universally Unique Identifier * diff --git a/sdk/core/core-util/test/public/aborterUtils.spec.ts b/sdk/core/core-util/test/public/aborterUtils.spec.ts index 5f319d31d24d..f1fe977eceb1 100644 --- a/sdk/core/core-util/test/public/aborterUtils.spec.ts +++ b/sdk/core/core-util/test/public/aborterUtils.spec.ts @@ -3,7 +3,7 @@ import type { AbortSignalLike } from "@azure/abort-controller"; import { describe, it, assert, expect, afterEach, vi } from "vitest"; -import { cancelablePromiseRace, createAbortablePromise } from "../../src"; +import { cancelablePromiseRace, createAbortablePromise } from "../../src/index.js"; describe("createAbortablePromise", function () { let token: ReturnType; diff --git a/sdk/core/core-util/test/public/browser/checkEnvironment.spec.ts b/sdk/core/core-util/test/public/browser/checkEnvironment.spec.ts index 797540189b47..1949a41813cf 100644 --- a/sdk/core/core-util/test/public/browser/checkEnvironment.spec.ts +++ b/sdk/core/core-util/test/public/browser/checkEnvironment.spec.ts @@ -1,7 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isBrowser, isBun, isDeno, isNode, isReactNative, isWebWorker } from "../../../src"; +import { + isBrowser, + isBun, + isDeno, + isNode, + isReactNative, + isWebWorker, +} from "../../../src/index.js"; import { describe, it, assert } from "vitest"; describe("checkEnvironment (browser)", function () { diff --git a/sdk/core/core-util/test/public/bytesEncoding.spec.ts b/sdk/core/core-util/test/public/bytesEncoding.spec.ts index ab84dac988e1..5ff9fa254719 100644 --- a/sdk/core/core-util/test/public/bytesEncoding.spec.ts +++ b/sdk/core/core-util/test/public/bytesEncoding.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { stringToUint8Array, uint8ArrayToString } from "../../src/bytesEncoding.js"; import { describe, it, assert } from "vitest"; -import { stringToUint8Array, uint8ArrayToString } from "../../src/bytesEncoding"; describe("bytesEncoding", function () { describe("base64ToBytes", function () { diff --git a/sdk/core/core-util/test/public/delay.spec.ts b/sdk/core/core-util/test/public/delay.spec.ts index 305661ec5e2b..21a107bba145 100644 --- a/sdk/core/core-util/test/public/delay.spec.ts +++ b/sdk/core/core-util/test/public/delay.spec.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { describe, it, assert, afterEach, vi } from "vitest"; -import { delay } from "../../src"; +import { delay } from "../../src/index.js"; describe("delay", function () { afterEach(function () { diff --git a/sdk/core/core-util/test/public/node/checkEnvironment.spec.ts b/sdk/core/core-util/test/public/node/checkEnvironment.spec.ts index 9484e26c5d31..d5d767bb8ae0 100644 --- a/sdk/core/core-util/test/public/node/checkEnvironment.spec.ts +++ b/sdk/core/core-util/test/public/node/checkEnvironment.spec.ts @@ -1,7 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isBrowser, isBun, isDeno, isNode, isReactNative, isWebWorker } from "../../../src"; +import { + isBrowser, + isBun, + isDeno, + isNode, + isReactNative, + isWebWorker, +} from "../../../src/index.js"; import { describe, it, assert } from "vitest"; describe("checkEnvironment (node)", function () { diff --git a/sdk/core/core-util/test/public/sha256.spec.ts b/sdk/core/core-util/test/public/sha256.spec.ts index 7b006aca41d3..27f01daa92c6 100644 --- a/sdk/core/core-util/test/public/sha256.spec.ts +++ b/sdk/core/core-util/test/public/sha256.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { computeSha256Hash, computeSha256Hmac } from "../../src/index"; +import { computeSha256Hash, computeSha256Hmac } from "../../src/index.js"; import { describe, it, assert } from "vitest"; describe("SHA-256", function () { diff --git a/sdk/core/core-util/test/public/typeGuards.spec.ts b/sdk/core/core-util/test/public/typeGuards.spec.ts index b71252fc5251..54711404022e 100644 --- a/sdk/core/core-util/test/public/typeGuards.spec.ts +++ b/sdk/core/core-util/test/public/typeGuards.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isDefined, isObjectWithProperties, objectHasProperty } from "../../src/index"; +import { isDefined, isObjectWithProperties, objectHasProperty } from "../../src/index.js"; import { describe, it, assert } from "vitest"; describe("Type guards", function () { diff --git a/sdk/core/core-util/test/public/uuidUtils.spec.ts b/sdk/core/core-util/test/public/uuidUtils.spec.ts index 857c46462216..343cccc18901 100644 --- a/sdk/core/core-util/test/public/uuidUtils.spec.ts +++ b/sdk/core/core-util/test/public/uuidUtils.spec.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { describe, it, assert } from "vitest"; -import { randomUUID } from "../../src/uuidUtils"; +import { randomUUID } from "../../src/uuidUtils.js"; describe("randomUUID", function () { it("should be a valid v4 UUID", function () { diff --git a/sdk/core/core-util/tsconfig.browser.config.json b/sdk/core/core-util/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-util/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-util/tsconfig.json b/sdk/core/core-util/tsconfig.json index 849d105b91c2..02617779f339 100644 --- a/sdk/core/core-util/tsconfig.json +++ b/sdk/core/core-util/tsconfig.json @@ -1,9 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest", - "verbatimModuleSyntax": true + "paths": { + "@azure/core-util": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts"] + "exclude": ["./samples/**/*.ts"], + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/core-util/vitest.browser.config.mts b/sdk/core/core-util/vitest.browser.config.mts deleted file mode 100644 index 9c4108d57842..000000000000 --- a/sdk/core/core-util/vitest.browser.config.mts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import { defineConfig } from "vitest/config"; -import browserMap from "@azure-tools/vite-plugin-browser-test-map"; - -export default defineConfig({ - plugins: [browserMap()], - test: { - browser: { - enabled: true, - headless: true, - name: "chromium", - provider: "playwright", - }, - fakeTimers: { - toFake: ["setTimeout"], - }, - watch: false, - include: ["test/**/*.spec.ts"], - exclude: ["test/**/node/*.spec.ts"], - }, -}); diff --git a/sdk/core/core-util/vitest.browser.config.ts b/sdk/core/core-util/vitest.browser.config.ts new file mode 100644 index 000000000000..dedf7900d14c --- /dev/null +++ b/sdk/core/core-util/vitest.browser.config.ts @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; +import browserMap from "@azure-tools/vite-plugin-browser-test-map"; + +export default defineConfig({ + plugins: [browserMap()], + define: { + "process.env": process.env, + }, + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-util/vitest.config.ts b/sdk/core/core-util/vitest.config.ts index caa1f342fe4a..7c014c00af62 100644 --- a/sdk/core/core-util/vitest.config.ts +++ b/sdk/core/core-util/vitest.config.ts @@ -5,8 +5,27 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, watch: false, include: ["test/**/*.spec.ts"], exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, }, }); diff --git a/sdk/core/core-xml/.tshy/browser.json b/sdk/core/core-xml/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/core-xml/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/core-xml/.tshy/build.json b/sdk/core/core-xml/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/core-xml/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/core-xml/.tshy/commonjs.json b/sdk/core/core-xml/.tshy/commonjs.json new file mode 100644 index 000000000000..8b5bba6f6ebc --- /dev/null +++ b/sdk/core/core-xml/.tshy/commonjs.json @@ -0,0 +1,15 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/xml-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/core-xml/.tshy/esm.json b/sdk/core/core-xml/.tshy/esm.json new file mode 100644 index 000000000000..7e1fcd5b0853 --- /dev/null +++ b/sdk/core/core-xml/.tshy/esm.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/xml-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/core-xml/.tshy/react-native.json b/sdk/core/core-xml/.tshy/react-native.json new file mode 100644 index 000000000000..dc2a5461ac4c --- /dev/null +++ b/sdk/core/core-xml/.tshy/react-native.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/xml-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/core-xml/api-extractor.json b/sdk/core/core-xml/api-extractor.json index 581978d314c5..59cf2d65f856 100644 --- a/sdk/core/core-xml/api-extractor.json +++ b/sdk/core/core-xml/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/latest/src/index.d.ts", + "mainEntryPointFilePath": "./dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/latest/core-xml.d.ts" + "publicTrimmedFilePath": "./dist/core-xml.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/core-xml/karma.conf.js b/sdk/core/core-xml/karma.conf.js deleted file mode 100644 index 6c6511f22729..000000000000 --- a/sdk/core/core-xml/karma.conf.js +++ /dev/null @@ -1,108 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: ["dist-test/index.browser.js"], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - //"dist-test/index.browser.js": ["coverage"] - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - // EXAMPLE: envPreprocessor: ["ACCOUNT_NAME", "ACCOUNT_SAS"], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/core-xml/package.json b/sdk/core/core-xml/package.json index 1146ca2934ce..3c758275eb9b 100644 --- a/sdk/core/core-xml/package.json +++ b/sdk/core/core-xml/package.json @@ -3,42 +3,32 @@ "version": "1.3.5", "description": "Core library for interacting with XML payloads", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/xml.js": "./dist-esm/src/xml.browser.js" - }, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js", - "./dist-esm/src/xml.js": "./dist-esm/src/xml.js" - }, - "types": "types/latest/core-xml.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "dev-tool samples run samples-dev", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/latest/core-xml.d.ts", "README.md", "LICENSE" ], @@ -58,38 +48,63 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-xml/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "dev-tool samples run samples-dev", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { - "tslib": "^2.2.0", - "fast-xml-parser": "^4.2.4" + "tslib": "^2.6.2", + "fast-xml-parser": "^4.3.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", "@types/trusted-types": "^2.0.0", - "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "inherits": "^2.0.3", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "rimraf": "^3.0.0", - "ts-node": "^10.0.0", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "util": "^0.12.1" + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/core-xml/src/index.ts b/sdk/core/core-xml/src/index.ts index 9bd015ddc3dd..fdc9c250be36 100644 --- a/sdk/core/core-xml/src/index.ts +++ b/sdk/core/core-xml/src/index.ts @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export { stringifyXML, parseXML } from "./xml"; -export { XML_ATTRKEY, XML_CHARKEY, XmlOptions } from "./xml.common"; +export { stringifyXML, parseXML } from "./xml.js"; +export { XML_ATTRKEY, XML_CHARKEY, XmlOptions } from "./xml.common.js"; diff --git a/sdk/core/core-xml/src/xml.browser.ts b/sdk/core/core-xml/src/xml-browser.mts similarity index 99% rename from sdk/core/core-xml/src/xml.browser.ts rename to sdk/core/core-xml/src/xml-browser.mts index 9ea20a66fd7a..e72cacd473c7 100644 --- a/sdk/core/core-xml/src/xml.browser.ts +++ b/sdk/core/core-xml/src/xml-browser.mts @@ -2,7 +2,7 @@ // Licensed under the MIT license. /// -import { XML_ATTRKEY, XML_CHARKEY, XmlOptions } from "./xml.common"; +import { XML_ATTRKEY, XML_CHARKEY, XmlOptions } from "./xml.common.js"; if (!document || !DOMParser || !Node || !XMLSerializer) { throw new Error( diff --git a/sdk/core/core-xml/src/xml.ts b/sdk/core/core-xml/src/xml.ts index 90a2e7b03272..8e78d689bd0f 100644 --- a/sdk/core/core-xml/src/xml.ts +++ b/sdk/core/core-xml/src/xml.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { XMLBuilder, XMLParser, XMLValidator } from "fast-xml-parser"; -import { XML_ATTRKEY, XML_CHARKEY, XmlOptions } from "./xml.common"; +import { XML_ATTRKEY, XML_CHARKEY, type XmlOptions } from "./xml.common.js"; function getCommonOptions(options: XmlOptions): { attributesGroupName: string; diff --git a/sdk/core/core-xml/test/xml.spec.ts b/sdk/core/core-xml/test/xml.spec.ts index d46b5479d53d..d627647daa9d 100644 --- a/sdk/core/core-xml/test/xml.spec.ts +++ b/sdk/core/core-xml/test/xml.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { parseXML, stringifyXML } from "../src"; -import { assert } from "chai"; +import { parseXML, stringifyXML } from "../src/index.js"; +import { describe, it, assert } from "vitest"; describe("XML serializer", function () { describe("parseXML(string)", function () { @@ -15,8 +15,8 @@ describe("XML serializer", function () { assert.ok(err instanceof Error); const error = err as Error; assert.ok( - error.message.includes("Document is empty") || // NodeJS v8 - error.message.includes("This page contains the following errors") || // Chrome + error.message.indexOf("Start tag expected, '<' not found") !== -1 || // Chrome + error.message.indexOf("Document is empty") !== -1 || // Legacy Chrome (error.message.startsWith("XML Parsing Error: syntax error") && error.message.includes("undefined")), // Firefox `error.message ("${error.message}") should have contained "Document is empty" or "undefined"`, @@ -33,8 +33,8 @@ describe("XML serializer", function () { assert.ok(err instanceof Error); const error = err as Error; assert.ok( - error.message.includes("Document is empty") || // NodeJS v8 - error.message.includes("This page contains the following errors") || // Chrome + error.message.indexOf("Start tag expected, '<' not found") !== -1 || // Chrome + error.message.indexOf("Document is empty") !== -1 || // Legacy Chrome (error.message.startsWith("XML Parsing Error: syntax error") && error.message.includes("null")), // Firefox `error.message ("${error.message}") should have contained "Document is empty" or "null"`, diff --git a/sdk/core/core-xml/tsconfig.browser.config.json b/sdk/core/core-xml/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/core-xml/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/core-xml/tsconfig.json b/sdk/core/core-xml/tsconfig.json index 80cf51c85585..1c307c28a654 100644 --- a/sdk/core/core-xml/tsconfig.json +++ b/sdk/core/core-xml/tsconfig.json @@ -1,12 +1,12 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types/latest", "paths": { - "@azure/core-xml": ["./src/index.js"] - } + "@azure/core-xml": ["./src/index.ts"] + }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "include": ["src/**/*.ts", "test/**/*.ts", "samples-dev/**/*.ts"], - "exclude": ["node_modules", "types", "temp", "browser", "dist", "dist-esm"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "test/**/*.ts", "samples-dev/**/*.ts"] } diff --git a/sdk/core/core-xml/vitest.browser.config.ts b/sdk/core/core-xml/vitest.browser.config.ts new file mode 100644 index 000000000000..005a2f7d4b67 --- /dev/null +++ b/sdk/core/core-xml/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/core-xml/vitest.config.ts b/sdk/core/core-xml/vitest.config.ts new file mode 100644 index 000000000000..7c014c00af62 --- /dev/null +++ b/sdk/core/core-xml/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/logger/.tshy/browser.json b/sdk/core/logger/.tshy/browser.json new file mode 100644 index 000000000000..32e74e04ec62 --- /dev/null +++ b/sdk/core/logger/.tshy/browser.json @@ -0,0 +1,12 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/logger/.tshy/build.json b/sdk/core/logger/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/logger/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/logger/.tshy/commonjs.json b/sdk/core/logger/.tshy/commonjs.json new file mode 100644 index 000000000000..af1973d6b07d --- /dev/null +++ b/sdk/core/logger/.tshy/commonjs.json @@ -0,0 +1,15 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/log-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/logger/.tshy/esm.json b/sdk/core/logger/.tshy/esm.json new file mode 100644 index 000000000000..0e44ac26aa0d --- /dev/null +++ b/sdk/core/logger/.tshy/esm.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/log-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/logger/.tshy/react-native.json b/sdk/core/logger/.tshy/react-native.json new file mode 100644 index 000000000000..1172ee291213 --- /dev/null +++ b/sdk/core/logger/.tshy/react-native.json @@ -0,0 +1,14 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/log-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/logger/api-extractor.json b/sdk/core/logger/api-extractor.json index f6215de57ec9..ca95154dc1dd 100644 --- a/sdk/core/logger/api-extractor.json +++ b/sdk/core/logger/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/logger.d.ts" + "publicTrimmedFilePath": "./dist/logger.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/logger/karma.conf.js b/sdk/core/logger/karma.conf.js deleted file mode 100644 index 6d297213ce86..000000000000 --- a/sdk/core/logger/karma.conf.js +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); -require("dotenv").config({ path: "../.env" }); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: [ - "dist-test/index.browser.js", - { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true }, - ], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - // "dist-test/index.browser.js": ["coverage"] - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadless"], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/logger/package.json b/sdk/core/logger/package.json index 83ac9aca4aad..c77fd2ea48df 100644 --- a/sdk/core/logger/package.json +++ b/sdk/core/logger/package.json @@ -3,46 +3,35 @@ "sdk-type": "client", "version": "1.0.5", "description": "Microsoft Azure SDK for JavaScript - Logger", - "main": "./dist/index.js", - "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/log.js": "./dist-esm/src/log.browser.js", - "process": false - }, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "engines": { "node": ">=18.0.0" }, - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "pretest": "npm run build:test", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" - }, - "types": "./types/logger.d.ts", "files": [ "dist/", - "dist-esm/src/", - "types/logger.d.ts", "README.md", "LICENSE" ], @@ -65,39 +54,63 @@ }, "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger/README.md", "sideEffects": false, + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "pretest": "npm run build:test", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run build-test && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", - "@types/chai": "^4.1.6", - "@types/mocha": "^10.0.0", + "@microsoft/api-extractor": "^7.39.5", "@types/node": "^18.0.0", - "@types/sinon": "^17.0.0", - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "dotenv": "^16.0.0", - "eslint": "^8.0.0", - "karma": "^6.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", - "mocha": "^10.0.0", - "c8": "^8.0.0", - "puppeteer": "^22.0.0", - "rimraf": "^3.0.0", - "sinon": "^17.0.0", - "ts-node": "^10.0.0", - "typescript": "~5.3.3" + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", + "dotenv": "^16.3.1", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", + "typescript": "~5.3.3", + "vitest": "^1.2.2" }, "//metadata": { "migrationDate": "2023-03-08T18:36:03.000Z" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/logger/src/debug.ts b/sdk/core/logger/src/debug.ts index 3b7e9ef71bff..51c967ba213a 100644 --- a/sdk/core/logger/src/debug.ts +++ b/sdk/core/logger/src/debug.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { log } from "./log"; +import { log } from "./log.js"; /** * A simple mechanism for enabling logging. diff --git a/sdk/core/logger/src/index.ts b/sdk/core/logger/src/index.ts index 13cc6ad32380..10e4a1fa7dc5 100644 --- a/sdk/core/logger/src/index.ts +++ b/sdk/core/logger/src/index.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import debug, { Debugger } from "./debug"; -export { Debugger } from "./debug"; +import debug, { type Debugger } from "./debug.js"; +export type { Debugger } from "./debug.js"; const registeredLoggers = new Set(); const logLevelFromEnv = diff --git a/sdk/core/logger/src/log.browser.ts b/sdk/core/logger/src/log-browser.mts similarity index 100% rename from sdk/core/logger/src/log.browser.ts rename to sdk/core/logger/src/log-browser.mts diff --git a/sdk/core/logger/src/log.ts b/sdk/core/logger/src/log.ts index 906dcfeed6f8..f3b357567120 100644 --- a/sdk/core/logger/src/log.ts +++ b/sdk/core/logger/src/log.ts @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { EOL } from "os"; -import util from "util"; +import { EOL } from "node:os"; +import util from "node:util"; +import * as process from "node:process"; export function log(message: unknown, ...args: any[]): void { process.stderr.write(`${util.format(message, ...args)}${EOL}`); diff --git a/sdk/core/logger/test/browser/logger.spec.ts b/sdk/core/logger/test/browser/logger.spec.ts index 0cb81af51eb4..ffdaaf558fc4 100644 --- a/sdk/core/logger/test/browser/logger.spec.ts +++ b/sdk/core/logger/test/browser/logger.spec.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as Logger from "../../src"; -import * as sinon from "sinon"; -import { assert } from "chai"; +import * as Logger from "../../src/index.js"; +import { describe, it, expect, afterEach, vi } from "vitest"; const testLogger = Logger.createClientLogger("test"); @@ -14,34 +13,31 @@ describe("AzureLogger (browser)", function () { afterEach(() => { Logger.setLogLevel(undefined); - sinon.restore(); + vi.restoreAllMocks(); }); it("logs to the correct console function", () => { Logger.setLogLevel("verbose"); - const debugStub = sinon.stub(console, "debug"); + const debugStub = vi.spyOn(console, "debug"); testLogger.verbose("verbose"); - assert.isTrue(debugStub.calledOnce, "console.debug called"); - assert.strictEqual( - debugStub.firstCall.args[0], - expectedTestMessage("azure:test:verbose", "verbose"), - ); - debugStub.restore(); - - const infoStub = sinon.stub(console, "info"); + expect(debugStub).toHaveBeenCalledTimes(1); + expect(debugStub).toHaveBeenCalledWith(expectedTestMessage("azure:test:verbose", "verbose")); + debugStub.mockRestore(); + + const infoStub = vi.spyOn(console, "info"); testLogger.info("info"); - assert.isTrue(infoStub.calledOnceWith(expectedTestMessage("azure:test:info", "info"))); - infoStub.restore(); + expect(infoStub).toHaveBeenCalledWith(expectedTestMessage("azure:test:info", "info")); + infoStub.mockRestore(); - const warningStub = sinon.stub(console, "warn"); + const warningStub = vi.spyOn(console, "warn"); testLogger.warning("warning"); - assert.isTrue(warningStub.calledOnceWith(expectedTestMessage("azure:test:warning", "warning"))); - warningStub.restore(); + expect(warningStub).toHaveBeenCalledWith(expectedTestMessage("azure:test:warning", "warning")); + warningStub.mockRestore(); - const errorStub = sinon.stub(console, "error"); + const errorStub = vi.spyOn(console, "error"); testLogger.error("error"); - assert.isTrue(errorStub.calledOnceWith(expectedTestMessage("azure:test:error", "error"))); - errorStub.restore(); + expect(errorStub).toHaveBeenCalledWith(expectedTestMessage("azure:test:error", "error")); + errorStub.mockRestore(); }); }); diff --git a/sdk/core/logger/test/debug.spec.ts b/sdk/core/logger/test/debug.spec.ts index d9a152a3eb72..27cfbd197659 100644 --- a/sdk/core/logger/test/debug.spec.ts +++ b/sdk/core/logger/test/debug.spec.ts @@ -1,13 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import debug, { Debugger } from "../src/debug"; -import { assert } from "chai"; -import { stub } from "sinon"; +import debug, { Debugger } from "../src/debug.js"; +import { describe, it, assert, expect, beforeEach, afterEach, vi, MockInstance } from "vitest"; describe("debug", function () { let logger: Debugger; - let logStub: sinon.SinonStub; + let logStub: MockInstance; function expectedTestMessage(namespace: string, message: string): string { return `${namespace} ${message}`; @@ -15,32 +14,36 @@ describe("debug", function () { beforeEach(() => { logger = debug("test"); - logStub = stub(logger, "log"); + logStub = vi.spyOn(logger, "log"); }); afterEach(() => { - logStub.restore(); + vi.restoreAllMocks(); logger.destroy(); debug.disable(); }); + it("logs when enabled", () => { debug.enable("test"); assert.isTrue(logger.enabled); const testMessage = "hello world!"; logger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test", testMessage))); + + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test", testMessage)); }); + it("does not log when not enabled", () => { const testMessage = "hello world!"; logger(testMessage); - assert.isTrue(logStub.notCalled); + expect(logStub).toHaveBeenCalledTimes(0); }); + it("stops logging after being disabled", () => { debug.enable("test"); assert.isTrue(logger.enabled); const testMessage = "hello world!"; logger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test", testMessage)); assert.strictEqual( debug.disable(), "test", @@ -48,8 +51,9 @@ describe("debug", function () { ); assert.isFalse(logger.enabled); logger(testMessage); - assert.isTrue(logStub.calledOnce, "Logger should not have been called a second time."); + expect(logStub).toHaveBeenCalledTimes(1); }); + it("extend() creates a new namespace", () => { const subLogger = logger.extend("foo"); assert.strictEqual(subLogger.namespace, "test:foo"); @@ -57,31 +61,36 @@ describe("debug", function () { const testMessage = "hello world!"; logger(testMessage); subLogger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test:foo", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test:foo", testMessage)); }); + it("enable() handles a csv list", () => { debug.enable("test,test2"); assert.isTrue(debug.enabled("test")); assert.isTrue(debug.enabled("test2")); }); + it("enable() supports wildcards", () => { const subLogger = logger.extend("foo"); debug.enable("test:*"); assert.isTrue(subLogger.enabled); const testMessage = "hello world!"; subLogger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test:foo", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test:foo", testMessage)); }); + it("enable() supports the global wildcard", () => { debug.enable("*"); assert.isTrue(debug.enabled("test")); assert.isTrue(debug.enabled("bar")); }); + it("enable() supports skips", () => { debug.enable("*,-test:*"); assert.isTrue(debug.enabled("bar")); assert.isFalse(debug.enabled("test:foo")); }); + it("names ending in * are always enabled", () => { assert.isTrue(debug.enabled("foo*")); }); diff --git a/sdk/core/logger/test/logger.spec.ts b/sdk/core/logger/test/logger.spec.ts index 16ab497805f6..c516cb177ddb 100644 --- a/sdk/core/logger/test/logger.spec.ts +++ b/sdk/core/logger/test/logger.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as Logger from "../src"; -import { assert } from "chai"; +import * as Logger from "../src/index.js"; +import { describe, it, assert } from "vitest"; const testLogger = Logger.createClientLogger("test"); diff --git a/sdk/core/logger/tsconfig.browser.config.json b/sdk/core/logger/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/logger/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/logger/tsconfig.json b/sdk/core/logger/tsconfig.json index ee5d66006a3a..849f95950c98 100644 --- a/sdk/core/logger/tsconfig.json +++ b/sdk/core/logger/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types", - "downlevelIteration": true + "paths": { + "@azure/logger": ["./src/index.ts"] + }, + "downlevelIteration": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "." }, - "exclude": ["node_modules", "./types/**/*.d.ts", "./samples/**/*.ts"], - "include": ["./src/**/*.ts", "./test/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.ts"] } diff --git a/sdk/core/logger/vitest.browser.config.ts b/sdk/core/logger/vitest.browser.config.ts new file mode 100644 index 000000000000..005a2f7d4b67 --- /dev/null +++ b/sdk/core/logger/vitest.browser.config.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/logger/vitest.config.ts b/sdk/core/logger/vitest.config.ts new file mode 100644 index 000000000000..e94c7dd91c76 --- /dev/null +++ b/sdk/core/logger/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/core/perf-tests/core-rest-pipeline/package.json b/sdk/core/perf-tests/core-rest-pipeline/package.json index 12ed24c6f05a..33a48c203f1b 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/package.json +++ b/sdk/core/perf-tests/core-rest-pipeline/package.json @@ -2,29 +2,30 @@ "name": "@azure-tests/perf-core-rest-pipeline", "sdk-type": "perf-test", "version": "1.0.0-beta.1", - "description": "", + "description": "Performance tests for @azure/core-rest-pipeline", "main": "", + "type": "module", "keywords": [], - "author": "", - "license": "ISC", + "author": "Microsoft Corporation", + "license": "MIT", "dependencies": { "@azure/core-rest-pipeline": "^1.1.0", "@azure/core-auth": "^1.3.0", "@azure/test-utils-perf": "^1.0.0", "dotenv": "^16.0.0", - "undici": "^6.0.0" + "undici": "^6.0.1" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@types/node": "^18.0.0", "@types/express": "^4.17.13", "concurrently": "^8.2.0", - "cross-env": "^7.0.3", "express": "^4.17.3", - "eslint": "^8.0.0", - "rimraf": "^3.0.0", + "eslint": "^8.56.0", + "prettier": "^2.5.1", + "rimraf": "^5.0.5", "ts-node": "^10.0.0", - "tslib": "^2.2.0", + "tslib": "^2.6.2", "typescript": "~5.3.3" }, "private": true, @@ -34,7 +35,7 @@ "build": "npm run clean && tsc -p .", "build:test": "echo skipped", "check-format": "dev-tool run vendored prettier --list-different --config ../../../../.prettierrc.json --ignore-path ../../../../.prettierignore \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-esm test-dist types *.tgz *.log ", + "clean": "rimraf --glob dist dist-esm test-dist types *.tgz *.log ", "format": "dev-tool run vendored prettier --write --config ../../../../.prettierrc.json --ignore-path ../../../../.prettierignore \"test/**/*.ts\" \"*.{js,json}\"", "integration-test:browser": "echo skipped", "integration-test:node": "echo skipped", diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/baseHttpTest.ts b/sdk/core/perf-tests/core-rest-pipeline/test/baseHttpTest.ts index 7e1f34fc43d9..5309bfba3f98 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/baseHttpTest.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/baseHttpTest.ts @@ -3,8 +3,8 @@ import express from "express"; import { PerfOptionDictionary, PerfTest } from "@azure/test-utils-perf"; -import { Server } from "http"; -import { AddressInfo } from "net"; +import { Server } from "node:http"; +import { AddressInfo } from "node:net"; let app: express.Application; let server: Server; diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/bearerTokenChallengeAuthenticationPolicy/wwwChallenge.spec.ts b/sdk/core/perf-tests/core-rest-pipeline/test/bearerTokenChallengeAuthenticationPolicy/wwwChallenge.spec.ts index 5f1ba9f65339..b18a7863d50d 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/bearerTokenChallengeAuthenticationPolicy/wwwChallenge.spec.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/bearerTokenChallengeAuthenticationPolicy/wwwChallenge.spec.ts @@ -1,5 +1,8 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + import { PerfTest } from "@azure/test-utils-perf"; -import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; +import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth"; import { AuthorizeRequestOnChallengeOptions, bearerTokenAuthenticationPolicy, @@ -11,7 +14,7 @@ import { PipelineRequest, PipelineResponse, } from "@azure/core-rest-pipeline"; -import { TextDecoder } from "util"; +import { TextDecoder } from "node:util"; export interface TestChallenge { scope: string; @@ -50,6 +53,7 @@ export function decodeString(value: string): Uint8Array { // [ { a: 'b', c: 'd' }, { d: 'e', f: 'g"' } ] // Important: // Do not use this in production, as values might contain the strings we use to split things up. +/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ function parseCAEChallenge(challenges: string): any[] { return challenges .split("Bearer ") @@ -195,6 +199,9 @@ export class BearerTokenAuthenticationPolicyChallengeTest extends PerfTest { async run(): Promise { const { pipeline, testHttpsClient, request } = BearerTokenAuthenticationPolicyChallengeTest; - await pipeline!.sendRequest(testHttpsClient!, request!); + if (!pipeline || !testHttpsClient || !request) { + throw new Error("Bad initialization for tests"); + } + await pipeline.sendRequest(testHttpsClient, request); } } diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/core-rest-pipeline.spec.ts b/sdk/core/perf-tests/core-rest-pipeline/test/core-rest-pipeline.spec.ts index f36bf83dba1f..992fa381f5be 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/core-rest-pipeline.spec.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/core-rest-pipeline.spec.ts @@ -7,7 +7,7 @@ import { createPipelineRequest, PipelineRequest, } from "@azure/core-rest-pipeline"; -import { BaseHttpTest } from "./baseHttpTest"; +import { BaseHttpTest } from "./baseHttpTest.js"; export class CoreRestPipelineTest extends BaseHttpTest { client: HttpClient; diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/fetch.spec.ts b/sdk/core/perf-tests/core-rest-pipeline/test/fetch.spec.ts index 0d32225ff447..0a5145e16715 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/fetch.spec.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/fetch.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { BaseHttpTest } from "./baseHttpTest"; +import { BaseHttpTest } from "./baseHttpTest.js"; export class FetchTest extends BaseHttpTest { constructor() { diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/http-request.spec.ts b/sdk/core/perf-tests/core-rest-pipeline/test/http-request.spec.ts index 92820113ed0f..5af5caa6d4e2 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/http-request.spec.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/http-request.spec.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as http from "http"; -import * as https from "https"; -import { BaseHttpTest } from "./baseHttpTest"; +import * as http from "node:http"; +import * as https from "node:https"; +import { BaseHttpTest } from "./baseHttpTest.js"; export class HttpRequestTest extends BaseHttpTest { static httpAgent = new http.Agent({ keepAlive: true }); diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/index.spec.ts b/sdk/core/perf-tests/core-rest-pipeline/test/index.spec.ts index 69d34b45b201..f9b124112322 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/index.spec.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/index.spec.ts @@ -1,9 +1,9 @@ import { createPerfProgram } from "@azure/test-utils-perf"; -import { BearerTokenAuthenticationPolicyChallengeTest } from "./bearerTokenChallengeAuthenticationPolicy/wwwChallenge.spec"; -import { CoreRestPipelineTest } from "./core-rest-pipeline.spec"; -import { FetchTest } from "./fetch.spec"; -import { HttpRequestTest } from "./http-request.spec"; -import { UndiciRequestTest } from "./undici-request.spec"; +import { BearerTokenAuthenticationPolicyChallengeTest } from "./bearerTokenChallengeAuthenticationPolicy/wwwChallenge.spec.js"; +import { CoreRestPipelineTest } from "./core-rest-pipeline.spec.js"; +import { FetchTest } from "./fetch.spec.js"; +import { HttpRequestTest } from "./http-request.spec.js"; +import { UndiciRequestTest } from "./undici-request.spec.js"; const perfProgram = createPerfProgram( BearerTokenAuthenticationPolicyChallengeTest, diff --git a/sdk/core/perf-tests/core-rest-pipeline/test/undici-request.spec.ts b/sdk/core/perf-tests/core-rest-pipeline/test/undici-request.spec.ts index a0d88c2ab761..8ce3667d5753 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/test/undici-request.spec.ts +++ b/sdk/core/perf-tests/core-rest-pipeline/test/undici-request.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { BaseHttpTest } from "./baseHttpTest"; +import { BaseHttpTest } from "./baseHttpTest.js"; import { request } from "undici"; export class UndiciRequestTest extends BaseHttpTest { diff --git a/sdk/core/perf-tests/core-rest-pipeline/tsconfig.json b/sdk/core/perf-tests/core-rest-pipeline/tsconfig.json index 8ba6bdb15cd1..08c50dbfa51d 100644 --- a/sdk/core/perf-tests/core-rest-pipeline/tsconfig.json +++ b/sdk/core/perf-tests/core-rest-pipeline/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../../../tsconfig.package", "compilerOptions": { "outDir": "./dist-esm", - "module": "CommonJS", + "module": "NodeNext", + "moduleResolution": "NodeNext", "target": "ESNext", "lib": ["ESNext", "DOM"] }, diff --git a/sdk/core/ts-http-runtime/.eslintrc.json b/sdk/core/ts-http-runtime/.eslintrc.json index 2958d8e155e5..bd2771a8f68a 100644 --- a/sdk/core/ts-http-runtime/.eslintrc.json +++ b/sdk/core/ts-http-runtime/.eslintrc.json @@ -2,7 +2,11 @@ "plugins": ["@azure/azure-sdk"], "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], "rules": { + "@azure/azure-sdk/ts-package-json-main-is-cjs": "off", + "@azure/azure-sdk/ts-package-json-files-required": "off", "@azure/azure-sdk/ts-package-json-engine-is-present": "off", - "@azure/azure-sdk/ts-package-json-name": "off" + "@azure/azure-sdk/ts-package-json-name": "off", + "@azure/azure-sdk/ts-package-json-module": "off", + "@azure/azure-sdk/ts-package-json-types": "off" } } diff --git a/sdk/core/ts-http-runtime/.tshy/browser.json b/sdk/core/ts-http-runtime/.tshy/browser.json new file mode 100644 index 000000000000..4634f8933466 --- /dev/null +++ b/sdk/core/ts-http-runtime/.tshy/browser.json @@ -0,0 +1,16 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/defaultHttpClient-react-native.mts", + ".././src/util/userAgentPlatform-react-native.mts", + ".././src/util/uuidUtils-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/browser" + } +} diff --git a/sdk/core/ts-http-runtime/.tshy/build.json b/sdk/core/ts-http-runtime/.tshy/build.json new file mode 100644 index 000000000000..c51b7f53052c --- /dev/null +++ b/sdk/core/ts-http-runtime/.tshy/build.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../src", + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext" + } +} diff --git a/sdk/core/ts-http-runtime/.tshy/commonjs.json b/sdk/core/ts-http-runtime/.tshy/commonjs.json new file mode 100644 index 000000000000..2310078413db --- /dev/null +++ b/sdk/core/ts-http-runtime/.tshy/commonjs.json @@ -0,0 +1,27 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.cts", + "../src/**/*.tsx" + ], + "exclude": [ + "../src/**/*.mts", + "../src/defaultHttpClient-browser.mts", + "../src/logger/log-browser.mts", + "../src/policies/decompressResponsePolicy-browser.mts", + "../src/policies/proxyPolicy-browser.mts", + "../src/util/bytesEncoding-browser.mts", + "../src/util/inspect-browser.mts", + "../src/util/sha256-browser.mts", + "../src/util/stream-browser.mts", + "../src/util/userAgentPlatform-browser.mts", + "../src/util/uuidUtils-browser.mts", + "../src/defaultHttpClient-react-native.mts", + "../src/util/userAgentPlatform-react-native.mts", + "../src/util/uuidUtils-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/commonjs" + } +} diff --git a/sdk/core/ts-http-runtime/.tshy/esm.json b/sdk/core/ts-http-runtime/.tshy/esm.json new file mode 100644 index 000000000000..ffb91e6622e4 --- /dev/null +++ b/sdk/core/ts-http-runtime/.tshy/esm.json @@ -0,0 +1,26 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/defaultHttpClient-browser.mts", + ".././src/logger/log-browser.mts", + ".././src/policies/decompressResponsePolicy-browser.mts", + ".././src/policies/proxyPolicy-browser.mts", + ".././src/util/bytesEncoding-browser.mts", + ".././src/util/inspect-browser.mts", + ".././src/util/sha256-browser.mts", + ".././src/util/stream-browser.mts", + ".././src/util/userAgentPlatform-browser.mts", + ".././src/util/uuidUtils-browser.mts", + ".././src/defaultHttpClient-react-native.mts", + ".././src/util/userAgentPlatform-react-native.mts", + ".././src/util/uuidUtils-react-native.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/esm" + } +} diff --git a/sdk/core/ts-http-runtime/.tshy/react-native.json b/sdk/core/ts-http-runtime/.tshy/react-native.json new file mode 100644 index 000000000000..c9df483f92fc --- /dev/null +++ b/sdk/core/ts-http-runtime/.tshy/react-native.json @@ -0,0 +1,23 @@ +{ + "extends": "./build.json", + "include": [ + "../src/**/*.ts", + "../src/**/*.mts", + "../src/**/*.tsx" + ], + "exclude": [ + ".././src/defaultHttpClient-browser.mts", + ".././src/logger/log-browser.mts", + ".././src/policies/decompressResponsePolicy-browser.mts", + ".././src/policies/proxyPolicy-browser.mts", + ".././src/util/bytesEncoding-browser.mts", + ".././src/util/inspect-browser.mts", + ".././src/util/sha256-browser.mts", + ".././src/util/stream-browser.mts", + ".././src/util/userAgentPlatform-browser.mts", + ".././src/util/uuidUtils-browser.mts" + ], + "compilerOptions": { + "outDir": "../.tshy-build/react-native" + } +} diff --git a/sdk/core/ts-http-runtime/api-extractor.json b/sdk/core/ts-http-runtime/api-extractor.json index 0f364e39d696..81ba4d4cee57 100644 --- a/sdk/core/ts-http-runtime/api-extractor.json +++ b/sdk/core/ts-http-runtime/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "dist/esm/index.d.ts", "docModel": { "enabled": true }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./types/ts-http-runtime.d.ts" + "publicTrimmedFilePath": "./dist/ts-http-runtime.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/core/ts-http-runtime/karma.conf.js b/sdk/core/ts-http-runtime/karma.conf.js deleted file mode 100644 index 7aa94b6b04f0..000000000000 --- a/sdk/core/ts-http-runtime/karma.conf.js +++ /dev/null @@ -1,119 +0,0 @@ -// https://github.com/karma-runner/karma-chrome-launcher -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "./", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha"], - - plugins: [ - "karma-mocha", - "karma-mocha-reporter", - "karma-chrome-launcher", - "karma-firefox-launcher", - "karma-env-preprocessor", - "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter", - ], - - // list of files / patterns to load in the browser - files: [ - "dist-test/index.browser.js", - { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true }, - ], - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "**/*.js": ["sourcemap", "env"], - // IMPORTANT: COMMENT following line if you want to debug in your browsers!! - // Preprocess source file to calculate code coverage, however this will make source file unreadable - "dist-test/index.js": ["coverage"], - }, - - // inject following environment values into browser testing with window.__env__ - // environment values MUST be exported or set with same console running "karma start" - // https://www.npmjs.com/package/karma-env-preprocessor - envPreprocessor: [], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], - - coverageReporter: { - // specify a common output directory - dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, - ], - }, - - junitReporter: { - outputDir: "", // results will be saved as $outputDir/$browserName.xml - outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile - suite: "", // suite will become the package name attribute in xml testsuite element - useBrowserName: false, // add browser name to report and classes names - nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element - classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element - properties: {}, // key value pair of properties to add to the section of the report - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' - browsers: ["ChromeHeadlessNoSandbox"], - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: "ChromeHeadless", - //--no-sandbox allows our tests to run in Linux without having to change the system. - // --disable-web-security allows us to authenticate from the browser without setting up special CORS configuration - flags: ["--no-sandbox", "--disable-web-security"], - }, - }, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - browserNoActivityTimeout: 600000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - client: { - mocha: { - // change Karma's debug.html to the mocha web reporter - reporter: "html", - timeout: "600000", - }, - }, - }); -}; diff --git a/sdk/core/ts-http-runtime/package.json b/sdk/core/ts-http-runtime/package.json index 74a2d153b8e6..d80b6328cbbe 100644 --- a/sdk/core/ts-http-runtime/package.json +++ b/sdk/core/ts-http-runtime/package.json @@ -3,55 +3,32 @@ "version": "1.0.0-beta.1", "description": "Isomorphic client library for making HTTP requests in node.js and browser.", "sdk-type": "client", - "main": "dist/index.js", - "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/defaultHttpClient.js": "./dist-esm/src/defaultHttpClient.browser.js", - "./dist-esm/src/policies/decompressResponsePolicy.js": "./dist-esm/src/policies/decompressResponsePolicy.browser.js", - "./dist-esm/src/policies/proxyPolicy.js": "./dist-esm/src/policies/proxyPolicy.browser.js", - "./dist-esm/src/util/inspect.js": "./dist-esm/src/util/inspect.browser.js", - "./dist-esm/src/util/userAgentPlatform.js": "./dist-esm/src/util/userAgentPlatform.browser.js", - "./dist-esm/src/util/sha256.js": "./dist-esm/src/util/sha256.browser.js", - "./dist-esm/src/util/uuidUtils.js": "./dist-esm/src/util/uuidUtils.browser.js", - "./dist-esm/src/util/stream.js": "./dist-esm/src/util/stream.browser.js", - "./dist-esm/src/util/bytesEncoding.js": "./dist-esm/src/util/bytesEncoding.browser.js", - "./dist-esm/src/logger/log.js": "./dist-esm/src/logger/log.browser.js", - "process": false - }, - "react-native": { - "./dist/index.js": "./dist-esm/src/index.js", - "./dist-esm/src/defaultHttpClient.js": "./dist-esm/src/defaultHttpClient.native.js", - "./dist-esm/src/util/userAgentPlatform.js": "./dist-esm/src/util/userAgentPlatform.native.js", - "./dist-esm/src/util/uuidUtils.js": "./dist-esm/src/util/uuidUtils.native.js" - }, - "types": "ts-http-runtime.shims.d.ts", - "scripts": { - "build:samples": "echo Obsolete", - "build:test": "tsc -p . && dev-tool run bundle", - "build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "clean": "rimraf dist dist-* temp types *.tgz *.log", - "execute:samples": "echo skipped", - "extract-api": "tsc -p . && api-extractor run --local", - "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", - "integration-test:browser": "echo skipped", - "integration-test:node": "echo skipped", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", - "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", - "lint": "eslint package.json api-extractor.json src test --ext .ts", - "pack": "npm pack 2>&1", - "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", - "test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node", - "test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", - "unit-test:browser": "karma start --single-run", - "unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true", - "unit-test": "npm run unit-test:node && npm run unit-test:browser" + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "browser": { + "types": "./dist/browser/index.d.ts", + "default": "./dist/browser/index.js" + }, + "react-native": { + "types": "./dist/react-native/index.d.ts", + "default": "./dist/react-native/index.js" + }, + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, "files": [ "dist/", - "dist-esm/src/", - "types/ts-http-runtime.d.ts", - "ts-http-runtime.shims.d.ts", "LICENSE", "README.md" ], @@ -71,6 +48,28 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/ts-http-runtime/", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "scripts": { + "build:samples": "echo Obsolete", + "build:test": "npm run clean && tshy && dev-tool run build-test", + "build": "npm run clean && tshy && api-extractor run --local", + "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf --glob dist dist-* temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "tshy && api-extractor run --local", + "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "integration-test:browser": "echo skipped", + "integration-test:node": "echo skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser", + "test:node": "npm run clean && tshy && npm run unit-test:node && npm run integration-test:node", + "test": "npm run clean && tshy && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test", + "unit-test:browser": "npm run build:test && dev-tool run test:vitest --no-test-proxy --browser", + "unit-test:node": "dev-tool run test:vitest --no-test-proxy", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, "//metadata": { "constantPaths": [ { @@ -89,41 +88,40 @@ "migrationDate": "2023-03-08T18:36:03.000Z" }, "dependencies": { - "tslib": "^2.2.0", "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0" + "https-proxy-agent": "^5.0.0", + "tslib": "^2.6.2" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", "@azure/eslint-plugin-azure-sdk": "^3.0.0", - "@microsoft/api-extractor": "^7.31.1", + "@azure-tools/vite-plugin-browser-test-map": "^1.0.0", + "@microsoft/api-extractor": "^7.39.5", "@opentelemetry/api": "^1.4.1", - "@types/chai": "^4.1.6", - "@types/chai-as-promised": "^7.1.0", - "@types/mocha": "^10.0.0", "@types/node": "^18.0.0", - "@types/sinon": "^17.0.0", - "chai": "^4.2.0", - "chai-as-promised": "^7.1.1", + "@vitest/browser": "^1.2.2", + "@vitest/coverage-istanbul": "^1.2.2", "cross-env": "^7.0.2", - "eslint": "^8.0.0", - "inherits": "^2.0.3", - "karma-chrome-launcher": "^3.1.0", - "karma-coverage": "^2.0.0", - "karma-env-preprocessor": "^0.1.1", - "karma-firefox-launcher": "^1.1.0", - "karma-junit-reporter": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-mocha": "^2.0.1", - "karma-sourcemap-loader": "^0.3.8", - "karma": "^6.3.0", - "mocha": "^10.0.0", - "puppeteer": "^22.0.0", - "rimraf": "^3.0.0", - "sinon": "^17.0.0", + "eslint": "^8.56.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tshy": "^1.11.0", "typescript": "~5.3.3", - "util": "^0.12.1", - "ts-node": "^10.0.0", - "esm": "^3.2.18" + "vitest": "^1.2.2" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "dialects": [ + "esm", + "commonjs" + ], + "esmDialects": [ + "browser", + "react-native" + ] } } diff --git a/sdk/core/ts-http-runtime/src/accessTokenCache.ts b/sdk/core/ts-http-runtime/src/accessTokenCache.ts index a869363b3979..b5d51b019e51 100644 --- a/sdk/core/ts-http-runtime/src/accessTokenCache.ts +++ b/sdk/core/ts-http-runtime/src/accessTokenCache.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken } from "./auth/tokenCredential"; +import { AccessToken } from "./auth/tokenCredential.js"; /** * Defines the default token refresh buffer duration. diff --git a/sdk/core/ts-http-runtime/src/auth/tokenCredential.ts b/sdk/core/ts-http-runtime/src/auth/tokenCredential.ts index 2d0b2ff148b1..77a891408721 100644 --- a/sdk/core/ts-http-runtime/src/auth/tokenCredential.ts +++ b/sdk/core/ts-http-runtime/src/auth/tokenCredential.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortSignalLike } from "../abort-controller/AbortSignalLike"; -import { TracingContext } from "../tracing/interfaces"; +import { AbortSignalLike } from "../abort-controller/AbortSignalLike.js"; +import { TracingContext } from "../tracing/interfaces.js"; /** * Represents a credential capable of providing an authentication token. diff --git a/sdk/core/ts-http-runtime/src/client/apiVersionPolicy.ts b/sdk/core/ts-http-runtime/src/client/apiVersionPolicy.ts index 64ea77be0522..7c6747f6f675 100644 --- a/sdk/core/ts-http-runtime/src/client/apiVersionPolicy.ts +++ b/sdk/core/ts-http-runtime/src/client/apiVersionPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelinePolicy } from "../pipeline"; -import { ClientOptions } from "./common"; +import { PipelinePolicy } from "../pipeline.js"; +import { ClientOptions } from "./common.js"; export const apiVersionPolicyName = "ApiVersionPolicy"; diff --git a/sdk/core/ts-http-runtime/src/client/clientHelpers.ts b/sdk/core/ts-http-runtime/src/client/clientHelpers.ts index 033aedbf2cf1..d5442abde70b 100644 --- a/sdk/core/ts-http-runtime/src/client/clientHelpers.ts +++ b/sdk/core/ts-http-runtime/src/client/clientHelpers.ts @@ -1,17 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { HttpClient } from "../interfaces"; -import { Pipeline } from "../pipeline"; -import { bearerTokenAuthenticationPolicy } from "../policies/bearerTokenAuthenticationPolicy"; -import { createDefaultHttpClient } from "../defaultHttpClient"; -import { createPipelineFromOptions } from "../createPipelineFromOptions"; -import { TokenCredential, isTokenCredential } from "../auth/tokenCredential"; -import { KeyCredential } from "../auth/keyCredential"; - -import { ClientOptions } from "./common"; -import { apiVersionPolicy } from "./apiVersionPolicy"; -import { keyCredentialAuthenticationPolicy } from "./keyCredentialAuthenticationPolicy"; +import { HttpClient } from "../interfaces.js"; +import { Pipeline } from "../pipeline.js"; +import { bearerTokenAuthenticationPolicy } from "../policies/bearerTokenAuthenticationPolicy.js"; +import { createDefaultHttpClient } from "../defaultHttpClient.js"; +import { createPipelineFromOptions } from "../createPipelineFromOptions.js"; +import { TokenCredential, isTokenCredential } from "../auth/tokenCredential.js"; +import { KeyCredential } from "../auth/keyCredential.js"; +import { ClientOptions } from "./common.js"; +import { apiVersionPolicy } from "./apiVersionPolicy.js"; +import { keyCredentialAuthenticationPolicy } from "./keyCredentialAuthenticationPolicy.js"; let cachedHttpClient: HttpClient | undefined; diff --git a/sdk/core/ts-http-runtime/src/client/common.ts b/sdk/core/ts-http-runtime/src/client/common.ts index 42ce95dbe581..bbd4af675d56 100644 --- a/sdk/core/ts-http-runtime/src/client/common.ts +++ b/sdk/core/ts-http-runtime/src/client/common.ts @@ -9,12 +9,12 @@ import { RequestBodyType, TransferProgressEvent, RawHttpHeadersInput, -} from "../interfaces"; -import { Pipeline, PipelinePolicy } from "../pipeline"; -import { AbortSignalLike } from "../abort-controller/AbortSignalLike"; -import { OperationTracingOptions } from "../tracing/interfaces"; -import { PipelineOptions } from "../createPipelineFromOptions"; -import { LogPolicyOptions } from "../policies/logPolicy"; +} from "../interfaces.js"; +import { Pipeline, PipelinePolicy } from "../pipeline.js"; +import { AbortSignalLike } from "../abort-controller/AbortSignalLike.js"; +import { OperationTracingOptions } from "../tracing/interfaces.js"; +import { PipelineOptions } from "../createPipelineFromOptions.js"; +import { LogPolicyOptions } from "../policies/logPolicy.js"; /** * Shape of the default request parameters, this may be overriden by the specific diff --git a/sdk/core/ts-http-runtime/src/client/getClient.ts b/sdk/core/ts-http-runtime/src/client/getClient.ts index b8ce7de452a0..7315027d6f59 100644 --- a/sdk/core/ts-http-runtime/src/client/getClient.ts +++ b/sdk/core/ts-http-runtime/src/client/getClient.ts @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TokenCredential, isTokenCredential } from "../auth/tokenCredential"; -import { KeyCredential } from "../auth/keyCredential"; -import { HttpClient, HttpMethods } from "../interfaces"; -import { Pipeline } from "../pipeline"; -import { createDefaultPipeline } from "./clientHelpers"; +import { TokenCredential, isTokenCredential } from "../auth/tokenCredential.js"; +import { KeyCredential } from "../auth/keyCredential.js"; +import { HttpClient, HttpMethods } from "../interfaces.js"; +import { Pipeline } from "../pipeline.js"; +import { createDefaultPipeline } from "./clientHelpers.js"; import { Client, ClientOptions, @@ -13,10 +13,10 @@ import { HttpNodeStreamResponse, RequestParameters, StreamableMethod, -} from "./common"; -import { sendRequest, sendRequestAsStream } from "./sendRequest"; -import { buildRequestUrl } from "./urlHelpers"; -import { PipelineOptions } from "../createPipelineFromOptions"; +} from "./common.js"; +import { sendRequest, sendRequestAsStream } from "./sendRequest.js"; +import { buildRequestUrl } from "./urlHelpers.js"; +import { PipelineOptions } from "../createPipelineFromOptions.js"; /** * Creates a client with a default pipeline @@ -63,7 +63,7 @@ export function getClient( const { allowInsecureConnection, httpClient } = clientOptions; const client = (path: string, ...args: Array) => { - const getUrl = (requestOptions: RequestParameters) => + const getUrl = (requestOptions: RequestParameters): string => buildRequestUrl(baseUrl, path, args, { allowInsecureConnection, ...requestOptions }); return { diff --git a/sdk/core/ts-http-runtime/src/client/keyCredentialAuthenticationPolicy.ts b/sdk/core/ts-http-runtime/src/client/keyCredentialAuthenticationPolicy.ts index f6778bd0292a..50bd549c4ec3 100644 --- a/sdk/core/ts-http-runtime/src/client/keyCredentialAuthenticationPolicy.ts +++ b/sdk/core/ts-http-runtime/src/client/keyCredentialAuthenticationPolicy.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { KeyCredential } from "../auth/keyCredential"; -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; +import { KeyCredential } from "../auth/keyCredential.js"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the bearerTokenAuthenticationPolicy. diff --git a/sdk/core/ts-http-runtime/src/client/operationOptionHelpers.ts b/sdk/core/ts-http-runtime/src/client/operationOptionHelpers.ts index 21cb63127a52..d4a3fb666612 100644 --- a/sdk/core/ts-http-runtime/src/client/operationOptionHelpers.ts +++ b/sdk/core/ts-http-runtime/src/client/operationOptionHelpers.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { OperationOptions, RequestParameters } from "./common"; +import { OperationOptions, RequestParameters } from "./common.js"; /** * Helper function to convert OperationOptions to RequestParameters diff --git a/sdk/core/ts-http-runtime/src/client/restError.ts b/sdk/core/ts-http-runtime/src/client/restError.ts index aa4a62b7d5c6..819c9aa36f09 100644 --- a/sdk/core/ts-http-runtime/src/client/restError.ts +++ b/sdk/core/ts-http-runtime/src/client/restError.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineResponse } from "../interfaces"; -import { RestError } from "../restError"; -import { createHttpHeaders } from "../httpHeaders"; -import { PathUncheckedResponse } from "./common"; +import { PipelineResponse } from "../interfaces.js"; +import { RestError } from "../restError.js"; +import { createHttpHeaders } from "../httpHeaders.js"; +import { PathUncheckedResponse } from "./common.js"; /** * Creates a rest error from a PathUnchecked response diff --git a/sdk/core/ts-http-runtime/src/client/sendRequest.ts b/sdk/core/ts-http-runtime/src/client/sendRequest.ts index 01a4a9fc6157..d295d6d2a6aa 100644 --- a/sdk/core/ts-http-runtime/src/client/sendRequest.ts +++ b/sdk/core/ts-http-runtime/src/client/sendRequest.ts @@ -9,15 +9,15 @@ import { PipelineResponse, RawHttpHeaders, RequestBodyType, -} from "../interfaces"; -import { RestError } from "../restError"; -import { Pipeline } from "../pipeline"; -import { createHttpHeaders } from "../httpHeaders"; -import { createPipelineRequest } from "../pipelineRequest"; -import { getCachedDefaultHttpsClient } from "./clientHelpers"; -import { isReadableStream } from "../util/typeGuards"; -import { HttpResponse, RequestParameters } from "./common"; -import { binaryArrayToString } from "./helpers/getBinaryBody"; +} from "../interfaces.js"; +import { RestError } from "../restError.js"; +import { Pipeline } from "../pipeline.js"; +import { createHttpHeaders } from "../httpHeaders.js"; +import { createPipelineRequest } from "../pipelineRequest.js"; +import { getCachedDefaultHttpsClient } from "./clientHelpers.js"; +import { isReadableStream } from "../util/typeGuards.js"; +import { HttpResponse, RequestParameters } from "./common.js"; +import { binaryArrayToString } from "./helpers/getBinaryBody.js"; /** * Helper function to send request used by the client @@ -203,7 +203,7 @@ function isFormData(body: unknown): body is FormDataMap { * Checks if binary data is in Uint8Array format, if so decode it to a binary string * to send over the wire */ -function processFormData(formData?: FormDataMap) { +function processFormData(formData?: FormDataMap): FormDataMap | undefined { if (!formData) { return formData; } diff --git a/sdk/core/ts-http-runtime/src/client/urlHelpers.ts b/sdk/core/ts-http-runtime/src/client/urlHelpers.ts index 48b013334af6..c36dc09b11ce 100644 --- a/sdk/core/ts-http-runtime/src/client/urlHelpers.ts +++ b/sdk/core/ts-http-runtime/src/client/urlHelpers.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { RequestParameters } from "./common"; +import { RequestParameters } from "./common.js"; /** * Builds the request url, filling in query and path parameters @@ -33,7 +33,7 @@ export function buildRequestUrl( ); } -function appendQueryParams(url: string, options: RequestParameters = {}) { +function appendQueryParams(url: string, options: RequestParameters = {}): string { if (!options.queryParameters) { return url; } @@ -57,7 +57,7 @@ function appendQueryParams(url: string, options: RequestParameters = {}) { return parsedUrl.toString(); } -function skipQueryParameterEncoding(url: URL) { +function skipQueryParameterEncoding(url: URL): URL { if (!url) { return url; } @@ -96,7 +96,7 @@ function buildRoutePath( routePath: string, pathParameters: string[], options: RequestParameters = {}, -) { +): string { for (const pathParam of pathParameters) { let value = pathParam; if (!options.skipUrlEncoding) { diff --git a/sdk/core/ts-http-runtime/src/createPipelineFromOptions.ts b/sdk/core/ts-http-runtime/src/createPipelineFromOptions.ts index 21ed37a18761..1ed1772b68cf 100644 --- a/sdk/core/ts-http-runtime/src/createPipelineFromOptions.ts +++ b/sdk/core/ts-http-runtime/src/createPipelineFromOptions.ts @@ -1,21 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LogPolicyOptions, logPolicy } from "./policies/logPolicy"; -import { Pipeline, createEmptyPipeline } from "./pipeline"; -import { PipelineRetryOptions, TlsSettings } from "./interfaces"; -import { RedirectPolicyOptions, redirectPolicy } from "./policies/redirectPolicy"; -import { UserAgentPolicyOptions, userAgentPolicy } from "./policies/userAgentPolicy"; -import { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy"; - -import { ProxySettings } from "."; -import { decompressResponsePolicy } from "./policies/decompressResponsePolicy"; -import { defaultRetryPolicy } from "./policies/defaultRetryPolicy"; -import { formDataPolicy } from "./policies/formDataPolicy"; -import { isNode } from "./util/checkEnvironment"; -import { proxyPolicy } from "./policies/proxyPolicy"; -import { tlsPolicy } from "./policies/tlsPolicy"; -import { tracingPolicy } from "./policies/tracingPolicy"; +import { type LogPolicyOptions, logPolicy } from "./policies/logPolicy.js"; +import { type Pipeline, createEmptyPipeline } from "./pipeline.js"; +import type { PipelineRetryOptions, TlsSettings } from "./interfaces.js"; +import { type RedirectPolicyOptions, redirectPolicy } from "./policies/redirectPolicy.js"; +import { type UserAgentPolicyOptions, userAgentPolicy } from "./policies/userAgentPolicy.js"; +import type { ProxySettings } from "./index.js"; +import { decompressResponsePolicy } from "./policies/decompressResponsePolicy.js"; +import { defaultRetryPolicy } from "./policies/defaultRetryPolicy.js"; +import { formDataPolicy } from "./policies/formDataPolicy.js"; +import { isNode } from "./util/checkEnvironment.js"; +import { proxyPolicy } from "./policies/proxyPolicy.js"; +import { tlsPolicy } from "./policies/tlsPolicy.js"; +import { tracingPolicy } from "./policies/tracingPolicy.js"; +import { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js"; /** * Defines options that are used to configure the HTTP pipeline for diff --git a/sdk/core/ts-http-runtime/src/defaultHttpClient.browser.ts b/sdk/core/ts-http-runtime/src/defaultHttpClient-browser.mts similarity index 67% rename from sdk/core/ts-http-runtime/src/defaultHttpClient.browser.ts rename to sdk/core/ts-http-runtime/src/defaultHttpClient-browser.mts index bc90779365aa..2c0df0c1b0f7 100644 --- a/sdk/core/ts-http-runtime/src/defaultHttpClient.browser.ts +++ b/sdk/core/ts-http-runtime/src/defaultHttpClient-browser.mts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { HttpClient } from "./interfaces"; -import { createFetchHttpClient } from "./fetchHttpClient"; +import type { HttpClient } from "./interfaces.js"; +import { createFetchHttpClient } from "./fetchHttpClient.js"; /** * Create the correct HttpClient for the current environment. diff --git a/sdk/core/core-rest-pipeline/src/defaultHttpClient.native.ts b/sdk/core/ts-http-runtime/src/defaultHttpClient-react-native.mts similarity index 68% rename from sdk/core/core-rest-pipeline/src/defaultHttpClient.native.ts rename to sdk/core/ts-http-runtime/src/defaultHttpClient-react-native.mts index 2255a689985b..a14d458f5b59 100644 --- a/sdk/core/core-rest-pipeline/src/defaultHttpClient.native.ts +++ b/sdk/core/ts-http-runtime/src/defaultHttpClient-react-native.mts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import type { HttpClient } from "./interfaces"; -import { createXhrHttpClient } from "./xhrHttpClient"; +import type { HttpClient } from "./interfaces.js"; +import { createXhrHttpClient } from "./xhrHttpClient.js"; /** * Create the correct HttpClient for the current environment. diff --git a/sdk/core/ts-http-runtime/src/defaultHttpClient.ts b/sdk/core/ts-http-runtime/src/defaultHttpClient.ts index 9b5def081c74..721e3a2aa750 100644 --- a/sdk/core/ts-http-runtime/src/defaultHttpClient.ts +++ b/sdk/core/ts-http-runtime/src/defaultHttpClient.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { HttpClient } from "./interfaces"; -import { createNodeHttpClient } from "./nodeHttpClient"; +import { HttpClient } from "./interfaces.js"; +import { createNodeHttpClient } from "./nodeHttpClient.js"; /** * Create the correct HttpClient for the current environment. diff --git a/sdk/core/ts-http-runtime/src/fetchHttpClient.ts b/sdk/core/ts-http-runtime/src/fetchHttpClient.ts index c9f4fe56804b..6b4cda3ed6c4 100644 --- a/sdk/core/ts-http-runtime/src/fetchHttpClient.ts +++ b/sdk/core/ts-http-runtime/src/fetchHttpClient.ts @@ -1,17 +1,17 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortError } from "./abort-controller/AbortError"; +import { AbortError } from "./abort-controller/AbortError.js"; import { HttpClient, HttpHeaders as PipelineHeaders, PipelineRequest, PipelineResponse, TransferProgressEvent, -} from "./interfaces"; -import { RestError } from "./restError"; -import { createHttpHeaders } from "./httpHeaders"; -import { isNodeReadableStream, isReadableStream } from "./util/typeGuards"; +} from "./interfaces.js"; +import { RestError } from "./restError.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { isNodeReadableStream, isReadableStream } from "./util/typeGuards.js"; /** * Checks if the body is a Blob or Blob-like @@ -103,7 +103,7 @@ async function buildPipelineResponse( httpResponse: Response, request: PipelineRequest, abortControllerCleanup?: () => void, -) { +): Promise { const headers = buildPipelineHeaders(httpResponse); const response: PipelineResponse = { request, @@ -184,6 +184,7 @@ function setupAbortSignal(request: PipelineRequest): { /** * Gets the specific error */ +// eslint-disable-next-line @azure/azure-sdk/ts-use-interface-parameters function getError(e: RestError, request: PipelineRequest): RestError { if (e && e?.name === "AbortError") { return e; @@ -198,7 +199,7 @@ function getError(e: RestError, request: PipelineRequest): RestError { /** * Converts PipelineRequest headers to Fetch headers */ -function buildFetchHeaders(pipelineHeaders: PipelineHeaders) { +function buildFetchHeaders(pipelineHeaders: PipelineHeaders): Headers { const headers = new Headers(); for (const [name, value] of pipelineHeaders) { headers.append(name, value); @@ -216,7 +217,15 @@ function buildPipelineHeaders(httpResponse: Response): PipelineHeaders { return responseHeaders; } -function buildRequestBody(request: PipelineRequest) { +function buildRequestBody(request: PipelineRequest): + | { + streaming: boolean; + body: ReadableStream; + } + | { + streaming: boolean; + body: string | Blob | ArrayBuffer | ArrayBufferView | FormData | null | undefined; + } { const body = typeof request.body === "function" ? request.body() : request.body; if (isNodeReadableStream(body)) { throw new Error("Node streams are not supported in browser environment."); diff --git a/sdk/core/ts-http-runtime/src/httpHeaders.ts b/sdk/core/ts-http-runtime/src/httpHeaders.ts index 683234e48c2f..28825d3a80b6 100644 --- a/sdk/core/ts-http-runtime/src/httpHeaders.ts +++ b/sdk/core/ts-http-runtime/src/httpHeaders.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { HttpHeaders, RawHttpHeaders, RawHttpHeadersInput } from "./interfaces"; +import { HttpHeaders, RawHttpHeaders, RawHttpHeadersInput } from "./interfaces.js"; interface HeaderEntry { name: string; diff --git a/sdk/core/ts-http-runtime/src/index.ts b/sdk/core/ts-http-runtime/src/index.ts index 6e71e450ed88..d5bab1bef502 100644 --- a/sdk/core/ts-http-runtime/src/index.ts +++ b/sdk/core/ts-http-runtime/src/index.ts @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +/* eslint-disable @typescript-eslint/no-unused-vars */ +declare global { + interface FormData {} + interface Blob {} + interface File {} + interface ReadableStream {} + interface TransformStream {} +} +/* eslint-enable @typescript-eslint/no-unused-vars */ + export { Agent, BodyPart, @@ -22,45 +32,49 @@ export { SendRequest, TlsSettings, TransferProgressEvent, -} from "./interfaces"; +} from "./interfaces.js"; export { AddPolicyOptions as AddPipelineOptions, PipelinePhase, PipelinePolicy, Pipeline, createEmptyPipeline, -} from "./pipeline"; +} from "./pipeline.js"; export { createPipelineFromOptions, TelemetryOptions, InternalPipelineOptions, PipelineOptions, -} from "./createPipelineFromOptions"; -export { createDefaultHttpClient } from "./defaultHttpClient"; -export { createHttpHeaders } from "./httpHeaders"; -export { createPipelineRequest, PipelineRequestOptions } from "./pipelineRequest"; -export { RestError, RestErrorOptions, isRestError } from "./restError"; +} from "./createPipelineFromOptions.js"; +export { createDefaultHttpClient } from "./defaultHttpClient.js"; +export { createHttpHeaders } from "./httpHeaders.js"; +export { createPipelineRequest, PipelineRequestOptions } from "./pipelineRequest.js"; +export { RestError, RestErrorOptions, isRestError } from "./restError.js"; export { decompressResponsePolicy, decompressResponsePolicyName, -} from "./policies/decompressResponsePolicy"; -export { logPolicy, logPolicyName, LogPolicyOptions } from "./policies/logPolicy"; -export { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy"; -export { proxyPolicy, proxyPolicyName, getDefaultProxySettings } from "./policies/proxyPolicy"; +} from "./policies/decompressResponsePolicy.js"; +export { logPolicy, logPolicyName, LogPolicyOptions } from "./policies/logPolicy.js"; +export { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js"; +export { proxyPolicy, proxyPolicyName, getDefaultProxySettings } from "./policies/proxyPolicy.js"; export { redirectPolicy, redirectPolicyName, RedirectPolicyOptions, -} from "./policies/redirectPolicy"; -export { tracingPolicy, tracingPolicyName, TracingPolicyOptions } from "./policies/tracingPolicy"; -export { defaultRetryPolicy, DefaultRetryPolicyOptions } from "./policies/defaultRetryPolicy"; +} from "./policies/redirectPolicy.js"; +export { + tracingPolicy, + tracingPolicyName, + TracingPolicyOptions, +} from "./policies/tracingPolicy.js"; +export { defaultRetryPolicy, DefaultRetryPolicyOptions } from "./policies/defaultRetryPolicy.js"; export { userAgentPolicy, userAgentPolicyName, UserAgentPolicyOptions, -} from "./policies/userAgentPolicy"; -export { tlsPolicy, tlsPolicyName } from "./policies/tlsPolicy"; -export { formDataPolicy, formDataPolicyName } from "./policies/formDataPolicy"; +} from "./policies/userAgentPolicy.js"; +export { tlsPolicy, tlsPolicyName } from "./policies/tlsPolicy.js"; +export { formDataPolicy, formDataPolicyName } from "./policies/formDataPolicy.js"; export { bearerTokenAuthenticationPolicy, BearerTokenAuthenticationPolicyOptions, @@ -68,11 +82,11 @@ export { ChallengeCallbacks, AuthorizeRequestOptions, AuthorizeRequestOnChallengeOptions, -} from "./policies/bearerTokenAuthenticationPolicy"; -export { AbortSignalLike } from "./abort-controller/AbortSignalLike"; -export { AbortError } from "./abort-controller/AbortError"; -export { AccessToken, GetTokenOptions, TokenCredential } from "./auth/tokenCredential"; -export { KeyCredential } from "./auth/keyCredential"; +} from "./policies/bearerTokenAuthenticationPolicy.js"; +export { AbortSignalLike } from "./abort-controller/AbortSignalLike.js"; +export { AbortError } from "./abort-controller/AbortError.js"; +export { AccessToken, GetTokenOptions, TokenCredential } from "./auth/tokenCredential.js"; +export { KeyCredential } from "./auth/keyCredential.js"; export { Instrumenter, InstrumenterSpanOptions, @@ -89,28 +103,32 @@ export { TracingSpanKind, TracingSpanLink, TracingSpanOptions, -} from "./tracing/interfaces"; -export { useInstrumenter } from "./tracing/instrumenter"; -export { createTracingClient } from "./tracing/tracingClient"; +} from "./tracing/interfaces.js"; +export { useInstrumenter } from "./tracing/instrumenter.js"; +export { createTracingClient } from "./tracing/tracingClient.js"; // from core-util -export { delay, DelayOptions } from "./util/delay"; -export { AbortOptions, cancelablePromiseRace, AbortablePromiseBuilder } from "./util/aborterUtils"; +export { delay, DelayOptions } from "./util/delay.js"; +export { + AbortOptions, + cancelablePromiseRace, + AbortablePromiseBuilder, +} from "./util/aborterUtils.js"; export { createAbortablePromise, CreateAbortablePromiseOptions, -} from "./util/createAbortablePromise"; -export { getRandomIntegerInclusive } from "./util/random"; -export { isObject, UnknownObject } from "./util/object"; -export { isError, getErrorMessage } from "./util/error"; +} from "./util/createAbortablePromise.js"; +export { getRandomIntegerInclusive } from "./util/random.js"; +export { isObject, UnknownObject } from "./util/object.js"; +export { isError, getErrorMessage } from "./util/error.js"; export { createFile, createFileFromStream, CreateFileOptions, CreateFileFromStreamOptions, -} from "./util/file"; -export { computeSha256Hash, computeSha256Hmac } from "./util/sha256"; -export { isDefined, isObjectWithProperties, objectHasProperty } from "./util/typeGuards"; -export { randomUUID } from "./util/uuidUtils"; +} from "./util/file.js"; +export { computeSha256Hash, computeSha256Hmac } from "./util/sha256.js"; +export { isDefined, isObjectWithProperties, objectHasProperty } from "./util/typeGuards.js"; +export { randomUUID } from "./util/uuidUtils.js"; export { isBrowser, isBun, @@ -118,20 +136,20 @@ export { isDeno, isReactNative, isWebWorker, -} from "./util/checkEnvironment"; -export { uint8ArrayToString, stringToUint8Array, EncodingType } from "./util/bytesEncoding"; +} from "./util/checkEnvironment.js"; +export { uint8ArrayToString, stringToUint8Array, EncodingType } from "./util/bytesEncoding.js"; export { Debugger, TypeSpecRuntimeLogger, TypeSpecRuntimeLogLevel, TypeSpecRuntimeClientLogger, -} from "./logger/logger"; +} from "./logger/logger.js"; // client -export { createRestError } from "./client/restError"; +export { createRestError } from "./client/restError.js"; export { addCredentialPipelinePolicy, AddCredentialPipelinePolicyOptions, -} from "./client/clientHelpers"; -export { operationOptionsToRequestParameters } from "./client/operationOptionHelpers"; -export * from "./client/getClient"; -export * from "./client/common"; +} from "./client/clientHelpers.js"; +export { operationOptionsToRequestParameters } from "./client/operationOptionHelpers.js"; +export * from "./client/getClient.js"; +export * from "./client/common.js"; diff --git a/sdk/core/ts-http-runtime/src/interfaces.ts b/sdk/core/ts-http-runtime/src/interfaces.ts index c3b60be4b9b1..31b64a326489 100644 --- a/sdk/core/ts-http-runtime/src/interfaces.ts +++ b/sdk/core/ts-http-runtime/src/interfaces.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortSignalLike } from "./abort-controller/AbortSignalLike"; -import { OperationTracingOptions } from "./tracing/interfaces"; +import { AbortSignalLike } from "./abort-controller/AbortSignalLike.js"; +import { OperationTracingOptions } from "./tracing/interfaces.js"; /** * A HttpHeaders collection represented as a simple JSON object. diff --git a/sdk/core/ts-http-runtime/src/log.ts b/sdk/core/ts-http-runtime/src/log.ts index 501332334462..a8a381c3807c 100644 --- a/sdk/core/ts-http-runtime/src/log.ts +++ b/sdk/core/ts-http-runtime/src/log.ts @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createClientLogger } from "./logger/logger"; +import { createClientLogger } from "./logger/logger.js"; export const logger = createClientLogger("ts-http-runtime"); diff --git a/sdk/core/ts-http-runtime/src/logger/debug.ts b/sdk/core/ts-http-runtime/src/logger/debug.ts index 72e778c93e31..4d46cc70e988 100644 --- a/sdk/core/ts-http-runtime/src/logger/debug.ts +++ b/sdk/core/ts-http-runtime/src/logger/debug.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { log } from "./log"; +import { log } from "./log.js"; /** * A simple mechanism for enabling logging. diff --git a/sdk/core/ts-http-runtime/src/logger/log.browser.ts b/sdk/core/ts-http-runtime/src/logger/log-browser.mts similarity index 100% rename from sdk/core/ts-http-runtime/src/logger/log.browser.ts rename to sdk/core/ts-http-runtime/src/logger/log-browser.mts diff --git a/sdk/core/ts-http-runtime/src/logger/log.ts b/sdk/core/ts-http-runtime/src/logger/log.ts index 906dcfeed6f8..f3b357567120 100644 --- a/sdk/core/ts-http-runtime/src/logger/log.ts +++ b/sdk/core/ts-http-runtime/src/logger/log.ts @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { EOL } from "os"; -import util from "util"; +import { EOL } from "node:os"; +import util from "node:util"; +import * as process from "node:process"; export function log(message: unknown, ...args: any[]): void { process.stderr.write(`${util.format(message, ...args)}${EOL}`); diff --git a/sdk/core/ts-http-runtime/src/logger/logger.ts b/sdk/core/ts-http-runtime/src/logger/logger.ts index 316faeaf8603..daed3d34d0b6 100644 --- a/sdk/core/ts-http-runtime/src/logger/logger.ts +++ b/sdk/core/ts-http-runtime/src/logger/logger.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import debug, { Debugger } from "./debug"; -export { Debugger } from "./debug"; +import debug, { Debugger } from "./debug.js"; +export { Debugger } from "./debug.js"; const registeredLoggers = new Set(); const logLevelFromEnv = diff --git a/sdk/core/ts-http-runtime/src/nodeHttpClient.ts b/sdk/core/ts-http-runtime/src/nodeHttpClient.ts index 7f86e27dd6e8..8f24df82bc7c 100644 --- a/sdk/core/ts-http-runtime/src/nodeHttpClient.ts +++ b/sdk/core/ts-http-runtime/src/nodeHttpClient.ts @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as http from "http"; -import * as https from "https"; -import * as zlib from "zlib"; -import { Transform } from "stream"; -import { AbortError } from "./abort-controller/AbortError"; +import * as http from "node:http"; +import * as https from "node:https"; +import * as zlib from "node:zlib"; +import { Transform } from "node:stream"; +import { AbortError } from "./abort-controller/AbortError.js"; import { HttpClient, HttpHeaders, @@ -14,11 +14,11 @@ import { RequestBodyType, TlsSettings, TransferProgressEvent, -} from "./interfaces"; -import { createHttpHeaders } from "./httpHeaders"; -import { RestError } from "./restError"; -import { IncomingMessage } from "http"; -import { logger } from "./log"; +} from "./interfaces.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { RestError } from "./restError.js"; +import { IncomingMessage } from "node:http"; +import { logger } from "./log.js"; const DEFAULT_TLS_SETTINGS = {}; diff --git a/sdk/core/ts-http-runtime/src/pipeline.ts b/sdk/core/ts-http-runtime/src/pipeline.ts index 018088279d3f..8e20f05897a3 100644 --- a/sdk/core/ts-http-runtime/src/pipeline.ts +++ b/sdk/core/ts-http-runtime/src/pipeline.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { HttpClient, PipelineRequest, PipelineResponse, SendRequest } from "./interfaces"; +import { HttpClient, PipelineRequest, PipelineResponse, SendRequest } from "./interfaces.js"; /** * Policies are executed in phases. diff --git a/sdk/core/ts-http-runtime/src/pipelineRequest.ts b/sdk/core/ts-http-runtime/src/pipelineRequest.ts index 320e8e0fa4fe..9ef55135037a 100644 --- a/sdk/core/ts-http-runtime/src/pipelineRequest.ts +++ b/sdk/core/ts-http-runtime/src/pipelineRequest.ts @@ -10,11 +10,11 @@ import { ProxySettings, RequestBodyType, TransferProgressEvent, -} from "./interfaces"; -import { createHttpHeaders } from "./httpHeaders"; -import { AbortSignalLike } from "./abort-controller/AbortSignalLike"; -import { randomUUID } from "./util/uuidUtils"; -import { OperationTracingOptions } from "./tracing/interfaces"; +} from "./interfaces.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { AbortSignalLike } from "./abort-controller/AbortSignalLike.js"; +import { randomUUID } from "./util/uuidUtils.js"; +import { OperationTracingOptions } from "./tracing/interfaces.js"; /** * Settings to initialize a request. diff --git a/sdk/core/ts-http-runtime/src/policies/bearerTokenAuthenticationPolicy.ts b/sdk/core/ts-http-runtime/src/policies/bearerTokenAuthenticationPolicy.ts index 8fc097c46da8..bc7cb57492f6 100644 --- a/sdk/core/ts-http-runtime/src/policies/bearerTokenAuthenticationPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/bearerTokenAuthenticationPolicy.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "../auth/tokenCredential"; -import { TypeSpecRuntimeLogger } from "../logger/logger"; -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { createTokenCycler } from "../util/tokenCycler"; -import { logger as coreLogger } from "../log"; +import { AccessToken, GetTokenOptions, TokenCredential } from "../auth/tokenCredential.js"; +import { TypeSpecRuntimeLogger } from "../logger/logger.js"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { createTokenCycler } from "../util/tokenCycler.js"; +import { logger as coreLogger } from "../log.js"; /** * The programmatic identifier of the bearerTokenAuthenticationPolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy.browser.ts b/sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy-browser.mts similarity index 100% rename from sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy.browser.ts rename to sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy-browser.mts diff --git a/sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy.ts b/sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy.ts index f52a2d2fdcb2..53ff3d9a4ea4 100644 --- a/sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/decompressResponsePolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the decompressResponsePolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/defaultRetryPolicy.ts b/sdk/core/ts-http-runtime/src/policies/defaultRetryPolicy.ts index 90fce25ceddb..66c62aada6f6 100644 --- a/sdk/core/ts-http-runtime/src/policies/defaultRetryPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/defaultRetryPolicy.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineRetryOptions } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy"; -import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import { PipelineRetryOptions } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js"; +import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * Name of the {@link defaultRetryPolicy} diff --git a/sdk/core/ts-http-runtime/src/policies/exponentialRetryPolicy.ts b/sdk/core/ts-http-runtime/src/policies/exponentialRetryPolicy.ts index fa02b51913f4..3f5bf5ff9988 100644 --- a/sdk/core/ts-http-runtime/src/policies/exponentialRetryPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/exponentialRetryPolicy.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelinePolicy } from "../pipeline"; -import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import { PipelinePolicy } from "../pipeline.js"; +import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * The programmatic identifier of the exponentialRetryPolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/formDataPolicy.ts b/sdk/core/ts-http-runtime/src/policies/formDataPolicy.ts index 205120c889fc..e97ecd121a0a 100644 --- a/sdk/core/ts-http-runtime/src/policies/formDataPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/formDataPolicy.ts @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { stringToUint8Array } from "../util/bytesEncoding"; -import { createHttpHeaders } from "../httpHeaders"; +import { stringToUint8Array } from "../util/bytesEncoding.js"; +import { createHttpHeaders } from "../httpHeaders.js"; import { BodyPart, FormDataMap, PipelineRequest, PipelineResponse, SendRequest, -} from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; +} from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the formDataPolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/logPolicy.ts b/sdk/core/ts-http-runtime/src/policies/logPolicy.ts index f6c91b706806..fa40a7fa660c 100644 --- a/sdk/core/ts-http-runtime/src/policies/logPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/logPolicy.ts @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Debugger } from "../logger/logger"; -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { logger as coreLogger } from "../log"; -import { Sanitizer } from "../util/sanitizer"; +import { Debugger } from "../logger/logger.js"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { logger as coreLogger } from "../log.js"; +import { Sanitizer } from "../util/sanitizer.js"; /** * The programmatic identifier of the logPolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/multipartPolicy.ts b/sdk/core/ts-http-runtime/src/policies/multipartPolicy.ts index 596d86dca5b1..651d3e5b03e5 100644 --- a/sdk/core/ts-http-runtime/src/policies/multipartPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/multipartPolicy.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { BodyPart, HttpHeaders, PipelineRequest, RequestBodyType } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { stringToUint8Array } from "../util/bytesEncoding"; -import { toStream, concatenateStreams } from "../util/stream"; -import { isBlob } from "../util/typeGuards"; -import { randomUUID } from "../util/uuidUtils"; +import { BodyPart, HttpHeaders, PipelineRequest, RequestBodyType } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { stringToUint8Array } from "../util/bytesEncoding.js"; +import { toStream, concatenateStreams } from "../util/stream.js"; +import { isBlob } from "../util/typeGuards.js"; +import { randomUUID } from "../util/uuidUtils.js"; function generateBoundary(): string { return `----AzSDKFormBoundary${randomUUID()}`; diff --git a/sdk/core/ts-http-runtime/src/policies/proxyPolicy.browser.ts b/sdk/core/ts-http-runtime/src/policies/proxyPolicy-browser.mts similarity index 100% rename from sdk/core/ts-http-runtime/src/policies/proxyPolicy.browser.ts rename to sdk/core/ts-http-runtime/src/policies/proxyPolicy-browser.mts diff --git a/sdk/core/ts-http-runtime/src/policies/proxyPolicy.ts b/sdk/core/ts-http-runtime/src/policies/proxyPolicy.ts index 61c1142915c4..b6a76548599a 100644 --- a/sdk/core/ts-http-runtime/src/policies/proxyPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/proxyPolicy.ts @@ -1,13 +1,19 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as http from "http"; -import * as https from "https"; -import { HttpsProxyAgent, HttpsProxyAgentOptions } from "https-proxy-agent"; -import { HttpProxyAgent, HttpProxyAgentOptions } from "http-proxy-agent"; -import { PipelineRequest, PipelineResponse, ProxySettings, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { logger } from "../log"; +import type * as http from "node:http"; +import type * as https from "node:https"; +import * as process from "node:process"; +import { HttpsProxyAgent, type HttpsProxyAgentOptions } from "https-proxy-agent"; +import { HttpProxyAgent, type HttpProxyAgentOptions } from "http-proxy-agent"; +import type { + PipelineRequest, + PipelineResponse, + ProxySettings, + SendRequest, +} from "../interfaces.js"; +import type { PipelinePolicy } from "../pipeline.js"; +import { logger } from "../log.js"; const HTTPS_PROXY = "HTTPS_PROXY"; const HTTP_PROXY = "HTTP_PROXY"; diff --git a/sdk/core/ts-http-runtime/src/policies/redirectPolicy.ts b/sdk/core/ts-http-runtime/src/policies/redirectPolicy.ts index 1893be5b13a3..a25f56ff04d5 100644 --- a/sdk/core/ts-http-runtime/src/policies/redirectPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/redirectPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; /** * The programmatic identifier of the redirectPolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/retryPolicy.ts b/sdk/core/ts-http-runtime/src/policies/retryPolicy.ts index d52c9b9a95a7..6f12d8c26c8b 100644 --- a/sdk/core/ts-http-runtime/src/policies/retryPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/retryPolicy.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { delay } from "../util/helpers"; -import { RetryStrategy } from "../retryStrategies/retryStrategy"; -import { RestError } from "../restError"; -import { AbortError } from "../abort-controller/AbortError"; -import { TypeSpecRuntimeLogger, createClientLogger } from "../logger/logger"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { delay } from "../util/helpers.js"; +import { RetryStrategy } from "../retryStrategies/retryStrategy.js"; +import { RestError } from "../restError.js"; +import { AbortError } from "../abort-controller/AbortError.js"; +import { TypeSpecRuntimeLogger, createClientLogger } from "../logger/logger.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; const retryPolicyLogger = createClientLogger("core-rest-pipeline retryPolicy"); diff --git a/sdk/core/ts-http-runtime/src/policies/systemErrorRetryPolicy.ts b/sdk/core/ts-http-runtime/src/policies/systemErrorRetryPolicy.ts index 504cf40cbec6..ef783fd661e6 100644 --- a/sdk/core/ts-http-runtime/src/policies/systemErrorRetryPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/systemErrorRetryPolicy.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelinePolicy } from "../pipeline"; -import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import { PipelinePolicy } from "../pipeline.js"; +import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * Name of the {@link systemErrorRetryPolicy} diff --git a/sdk/core/ts-http-runtime/src/policies/throttlingRetryPolicy.ts b/sdk/core/ts-http-runtime/src/policies/throttlingRetryPolicy.ts index 7cf262331a6d..33a6ccf3adf4 100644 --- a/sdk/core/ts-http-runtime/src/policies/throttlingRetryPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/throttlingRetryPolicy.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelinePolicy } from "../pipeline"; -import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy"; -import { retryPolicy } from "./retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../constants"; +import { PipelinePolicy } from "../pipeline.js"; +import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy.js"; +import { retryPolicy } from "./retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js"; /** * Name of the {@link throttlingRetryPolicy} diff --git a/sdk/core/ts-http-runtime/src/policies/tlsPolicy.ts b/sdk/core/ts-http-runtime/src/policies/tlsPolicy.ts index efba9098af14..cf85d5c3da40 100644 --- a/sdk/core/ts-http-runtime/src/policies/tlsPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/tlsPolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelinePolicy } from "../pipeline"; -import { TlsSettings } from "../interfaces"; +import { PipelinePolicy } from "../pipeline.js"; +import { TlsSettings } from "../interfaces.js"; /** * Name of the TLS Policy diff --git a/sdk/core/ts-http-runtime/src/policies/tracingPolicy.ts b/sdk/core/ts-http-runtime/src/policies/tracingPolicy.ts index fb47c4e3e813..0e572c1410f0 100644 --- a/sdk/core/ts-http-runtime/src/policies/tracingPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/tracingPolicy.ts @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TracingClient, TracingContext, TracingSpan } from "../tracing/interfaces"; -import { createTracingClient } from "../tracing/tracingClient"; -import { SDK_VERSION } from "../constants"; -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { getUserAgentValue } from "../util/userAgent"; -import { logger } from "../log"; -import { getErrorMessage, isError } from "../util/error"; -import { isRestError } from "../restError"; +import { TracingClient, TracingContext, TracingSpan } from "../tracing/interfaces.js"; +import { createTracingClient } from "../tracing/tracingClient.js"; +import { SDK_VERSION } from "../constants.js"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { getUserAgentValue } from "../util/userAgent.js"; +import { logger } from "../log.js"; +import { getErrorMessage, isError } from "../util/error.js"; +import { isRestError } from "../restError.js"; /** * The programmatic identifier of the tracingPolicy. diff --git a/sdk/core/ts-http-runtime/src/policies/userAgentPolicy.ts b/sdk/core/ts-http-runtime/src/policies/userAgentPolicy.ts index 0ab8d10e1c55..05871573c1d3 100644 --- a/sdk/core/ts-http-runtime/src/policies/userAgentPolicy.ts +++ b/sdk/core/ts-http-runtime/src/policies/userAgentPolicy.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces"; -import { PipelinePolicy } from "../pipeline"; -import { getUserAgentHeaderName, getUserAgentValue } from "../util/userAgent"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../interfaces.js"; +import { PipelinePolicy } from "../pipeline.js"; +import { getUserAgentHeaderName, getUserAgentValue } from "../util/userAgent.js"; const UserAgentHeaderName = getUserAgentHeaderName(); diff --git a/sdk/core/ts-http-runtime/src/restError.ts b/sdk/core/ts-http-runtime/src/restError.ts index dbf4603f88af..62228702496a 100644 --- a/sdk/core/ts-http-runtime/src/restError.ts +++ b/sdk/core/ts-http-runtime/src/restError.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isError } from "./util/error"; -import { PipelineRequest, PipelineResponse } from "./interfaces"; -import { custom } from "./util/inspect"; -import { Sanitizer } from "./util/sanitizer"; +import { isError } from "./util/error.js"; +import { PipelineRequest, PipelineResponse } from "./interfaces.js"; +import { custom } from "./util/inspect.js"; +import { Sanitizer } from "./util/sanitizer.js"; const errorSanitizer = new Sanitizer(); diff --git a/sdk/core/ts-http-runtime/src/retryStrategies/exponentialRetryStrategy.ts b/sdk/core/ts-http-runtime/src/retryStrategies/exponentialRetryStrategy.ts index 4d1ec408d2d8..ab79d644c61b 100644 --- a/sdk/core/ts-http-runtime/src/retryStrategies/exponentialRetryStrategy.ts +++ b/sdk/core/ts-http-runtime/src/retryStrategies/exponentialRetryStrategy.ts @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineResponse } from "../interfaces"; -import { RestError } from "../restError"; -import { getRandomIntegerInclusive } from "../util/random"; -import { RetryStrategy } from "./retryStrategy"; -import { isThrottlingRetryResponse } from "./throttlingRetryStrategy"; +import { PipelineResponse } from "../interfaces.js"; +import { RestError } from "../restError.js"; +import { getRandomIntegerInclusive } from "../util/random.js"; +import { RetryStrategy } from "./retryStrategy.js"; +import { isThrottlingRetryResponse } from "./throttlingRetryStrategy.js"; // intervals are in milliseconds const DEFAULT_CLIENT_RETRY_INTERVAL = 1000; diff --git a/sdk/core/ts-http-runtime/src/retryStrategies/retryStrategy.ts b/sdk/core/ts-http-runtime/src/retryStrategies/retryStrategy.ts index a5f352094d41..26b823c64037 100644 --- a/sdk/core/ts-http-runtime/src/retryStrategies/retryStrategy.ts +++ b/sdk/core/ts-http-runtime/src/retryStrategies/retryStrategy.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TypeSpecRuntimeLogger } from "../logger/logger"; -import { PipelineResponse } from "../interfaces"; -import { RestError } from "../restError"; +import { TypeSpecRuntimeLogger } from "../logger/logger.js"; +import { PipelineResponse } from "../interfaces.js"; +import { RestError } from "../restError.js"; /** * Information provided to the retry strategy about the current progress of the retry policy. diff --git a/sdk/core/ts-http-runtime/src/retryStrategies/throttlingRetryStrategy.ts b/sdk/core/ts-http-runtime/src/retryStrategies/throttlingRetryStrategy.ts index 6acf80cfa691..c76fad8ec2f8 100644 --- a/sdk/core/ts-http-runtime/src/retryStrategies/throttlingRetryStrategy.ts +++ b/sdk/core/ts-http-runtime/src/retryStrategies/throttlingRetryStrategy.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { PipelineResponse } from ".."; -import { parseHeaderValueAsNumber } from "../util/helpers"; -import { RetryStrategy } from "./retryStrategy"; +import { PipelineResponse } from "../index.js"; +import { parseHeaderValueAsNumber } from "../util/helpers.js"; +import { RetryStrategy } from "./retryStrategy.js"; /** * The header that comes back from services representing diff --git a/sdk/core/ts-http-runtime/src/tracing/instrumenter.ts b/sdk/core/ts-http-runtime/src/tracing/instrumenter.ts index eb7e6b2964bd..bada43875fd5 100644 --- a/sdk/core/ts-http-runtime/src/tracing/instrumenter.ts +++ b/sdk/core/ts-http-runtime/src/tracing/instrumenter.ts @@ -1,8 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Instrumenter, InstrumenterSpanOptions, TracingContext, TracingSpan } from "./interfaces"; -import { createTracingContext } from "./tracingContext"; +import { + Instrumenter, + InstrumenterSpanOptions, + TracingContext, + TracingSpan, +} from "./interfaces.js"; +import { createTracingContext } from "./tracingContext.js"; export function createDefaultTracingSpan(): TracingSpan { return { diff --git a/sdk/core/ts-http-runtime/src/tracing/tracingClient.ts b/sdk/core/ts-http-runtime/src/tracing/tracingClient.ts index 3e8f5917e265..810d11da9dc1 100644 --- a/sdk/core/ts-http-runtime/src/tracing/tracingClient.ts +++ b/sdk/core/ts-http-runtime/src/tracing/tracingClient.ts @@ -10,9 +10,9 @@ import { TracingContext, TracingSpan, TracingSpanOptions, -} from "./interfaces"; -import { getInstrumenter } from "./instrumenter"; -import { knownContextKeys } from "./tracingContext"; +} from "./interfaces.js"; +import { getInstrumenter } from "./instrumenter.js"; +import { knownContextKeys } from "./tracingContext.js"; /** * Creates a new tracing client. diff --git a/sdk/core/ts-http-runtime/src/tracing/tracingContext.ts b/sdk/core/ts-http-runtime/src/tracing/tracingContext.ts index a6aacf8c2d87..c775a50cfef4 100644 --- a/sdk/core/ts-http-runtime/src/tracing/tracingContext.ts +++ b/sdk/core/ts-http-runtime/src/tracing/tracingContext.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { TracingContext, TracingSpan } from "./interfaces"; +import { TracingContext, TracingSpan } from "./interfaces.js"; /** @internal */ export const knownContextKeys = { diff --git a/sdk/core/ts-http-runtime/src/util/aborterUtils.ts b/sdk/core/ts-http-runtime/src/util/aborterUtils.ts index 074274ec266c..a458007b414c 100644 --- a/sdk/core/ts-http-runtime/src/util/aborterUtils.ts +++ b/sdk/core/ts-http-runtime/src/util/aborterUtils.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortSignalLike } from "../abort-controller/AbortSignalLike"; +import { AbortSignalLike } from "../abort-controller/AbortSignalLike.js"; /** * Options related to abort controller. diff --git a/sdk/core/ts-http-runtime/src/util/bytesEncoding.browser.ts b/sdk/core/ts-http-runtime/src/util/bytesEncoding-browser.mts similarity index 100% rename from sdk/core/ts-http-runtime/src/util/bytesEncoding.browser.ts rename to sdk/core/ts-http-runtime/src/util/bytesEncoding-browser.mts diff --git a/sdk/core/ts-http-runtime/src/util/createAbortablePromise.ts b/sdk/core/ts-http-runtime/src/util/createAbortablePromise.ts index 13c301cf9c27..c6df50371290 100644 --- a/sdk/core/ts-http-runtime/src/util/createAbortablePromise.ts +++ b/sdk/core/ts-http-runtime/src/util/createAbortablePromise.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortError } from "../abort-controller/AbortError"; -import { AbortOptions } from "./aborterUtils"; +import { AbortError } from "../abort-controller/AbortError.js"; +import { AbortOptions } from "./aborterUtils.js"; /** * Options for the createAbortablePromise function. diff --git a/sdk/core/ts-http-runtime/src/util/delay.ts b/sdk/core/ts-http-runtime/src/util/delay.ts index 3ec8e6f86a62..307d6f025fec 100644 --- a/sdk/core/ts-http-runtime/src/util/delay.ts +++ b/sdk/core/ts-http-runtime/src/util/delay.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortOptions } from "./aborterUtils"; -import { createAbortablePromise } from "./createAbortablePromise"; +import { AbortOptions } from "./aborterUtils.js"; +import { createAbortablePromise } from "./createAbortablePromise.js"; const StandardAbortMessage = "The delay was aborted."; diff --git a/sdk/core/ts-http-runtime/src/util/error.ts b/sdk/core/ts-http-runtime/src/util/error.ts index c6bce37777a7..f876780d95a8 100644 --- a/sdk/core/ts-http-runtime/src/util/error.ts +++ b/sdk/core/ts-http-runtime/src/util/error.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isObject } from "./object"; +import { isObject } from "./object.js"; /** * Typeguard for an error object shape (has name and message) diff --git a/sdk/core/ts-http-runtime/src/util/file.ts b/sdk/core/ts-http-runtime/src/util/file.ts index a55eb25f479a..3ce76551d839 100644 --- a/sdk/core/ts-http-runtime/src/util/file.ts +++ b/sdk/core/ts-http-runtime/src/util/file.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { toWebStream } from "./stream"; +import { toWebStream } from "./stream.js"; /** * Options passed into createFile specifying metadata about the file. diff --git a/sdk/core/ts-http-runtime/src/util/helpers.ts b/sdk/core/ts-http-runtime/src/util/helpers.ts index 4ab9d65ed5d8..28eae15ce015 100644 --- a/sdk/core/ts-http-runtime/src/util/helpers.ts +++ b/sdk/core/ts-http-runtime/src/util/helpers.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortError } from "../abort-controller/AbortError"; -import { AbortSignalLike } from "../abort-controller/AbortSignalLike"; -import { PipelineResponse } from "../interfaces"; +import { AbortError } from "../abort-controller/AbortError.js"; +import { AbortSignalLike } from "../abort-controller/AbortSignalLike.js"; +import { PipelineResponse } from "../interfaces.js"; const StandardAbortMessage = "The operation was aborted."; diff --git a/sdk/core/ts-http-runtime/src/util/inspect.browser.ts b/sdk/core/ts-http-runtime/src/util/inspect-browser.mts similarity index 100% rename from sdk/core/ts-http-runtime/src/util/inspect.browser.ts rename to sdk/core/ts-http-runtime/src/util/inspect-browser.mts diff --git a/sdk/core/ts-http-runtime/src/util/inspect.ts b/sdk/core/ts-http-runtime/src/util/inspect.ts index 27613c3494f5..c69ad2d36fb1 100644 --- a/sdk/core/ts-http-runtime/src/util/inspect.ts +++ b/sdk/core/ts-http-runtime/src/util/inspect.ts @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { inspect } from "util"; +import { inspect } from "node:util"; export const custom = inspect.custom; diff --git a/sdk/core/ts-http-runtime/src/util/sanitizer.ts b/sdk/core/ts-http-runtime/src/util/sanitizer.ts index 69daa57722df..763a545ee4f9 100644 --- a/sdk/core/ts-http-runtime/src/util/sanitizer.ts +++ b/sdk/core/ts-http-runtime/src/util/sanitizer.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { UnknownObject, isObject } from "./object"; +import { UnknownObject, isObject } from "./object.js"; /** * @internal diff --git a/sdk/core/core-util/src/sha256.browser.ts b/sdk/core/ts-http-runtime/src/util/sha256-browser.mts similarity index 99% rename from sdk/core/core-util/src/sha256.browser.ts rename to sdk/core/ts-http-runtime/src/util/sha256-browser.mts index 6f6eb47aba68..5c466bd611bf 100644 --- a/sdk/core/core-util/src/sha256.browser.ts +++ b/sdk/core/ts-http-runtime/src/util/sha256-browser.mts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { stringToUint8Array, uint8ArrayToString } from "./bytesEncoding.browser"; +import { stringToUint8Array, uint8ArrayToString } from "./bytesEncoding.js"; // stubs for browser self.crypto interface JsonWebKey {} diff --git a/sdk/core/ts-http-runtime/src/util/sha256.ts b/sdk/core/ts-http-runtime/src/util/sha256.ts index 92bc5b575c4b..2e9814a6e2a8 100644 --- a/sdk/core/ts-http-runtime/src/util/sha256.ts +++ b/sdk/core/ts-http-runtime/src/util/sha256.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createHash, createHmac } from "crypto"; +import { createHash, createHmac } from "node:crypto"; /** * Generates a SHA-256 HMAC signature. diff --git a/sdk/core/ts-http-runtime/src/util/stream.browser.ts b/sdk/core/ts-http-runtime/src/util/stream-browser.mts similarity index 96% rename from sdk/core/ts-http-runtime/src/util/stream.browser.ts rename to sdk/core/ts-http-runtime/src/util/stream-browser.mts index 5fc831f1ea8e..d819eea71c6f 100644 --- a/sdk/core/ts-http-runtime/src/util/stream.browser.ts +++ b/sdk/core/ts-http-runtime/src/util/stream-browser.mts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isBlob, isWebReadableStream } from "./typeGuards"; +import { isBlob, isWebReadableStream } from "./typeGuards.js"; export function toStream( source: ReadableStream | NodeJS.ReadableStream | Uint8Array | Blob, diff --git a/sdk/core/ts-http-runtime/src/util/stream.ts b/sdk/core/ts-http-runtime/src/util/stream.ts index a5941aefe611..08aa66185609 100644 --- a/sdk/core/ts-http-runtime/src/util/stream.ts +++ b/sdk/core/ts-http-runtime/src/util/stream.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Readable } from "stream"; -import { ReadableStream as AsyncIterableReadableStream } from "stream/web"; -import { isBlob, isNodeReadableStream, isWebReadableStream } from "./typeGuards"; +import { Readable } from "node:stream"; +import { ReadableStream as AsyncIterableReadableStream } from "node:stream/web"; +import { isBlob, isNodeReadableStream, isWebReadableStream } from "./typeGuards.js"; async function* streamAsyncIterator( this: ReadableStream, diff --git a/sdk/core/ts-http-runtime/src/util/tokenCycler.ts b/sdk/core/ts-http-runtime/src/util/tokenCycler.ts index bf5afa2e6510..aad1f68d7967 100644 --- a/sdk/core/ts-http-runtime/src/util/tokenCycler.ts +++ b/sdk/core/ts-http-runtime/src/util/tokenCycler.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AccessToken, GetTokenOptions, TokenCredential } from "../auth/tokenCredential"; -import { delay } from "./helpers"; +import { AccessToken, GetTokenOptions, TokenCredential } from "../auth/tokenCredential.js"; +import { delay } from "./helpers.js"; /** * A function that gets a promise of an access token and allows providing diff --git a/sdk/core/ts-http-runtime/src/util/userAgent.ts b/sdk/core/ts-http-runtime/src/util/userAgent.ts index bee41e5c772b..70d3bd3634bb 100644 --- a/sdk/core/ts-http-runtime/src/util/userAgent.ts +++ b/sdk/core/ts-http-runtime/src/util/userAgent.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { getHeaderName, setPlatformSpecificData } from "./userAgentPlatform"; -import { SDK_VERSION } from "../constants"; +import { getHeaderName, setPlatformSpecificData } from "./userAgentPlatform.js"; +import { SDK_VERSION } from "../constants.js"; function getUserAgentString(telemetryInfo: Map): string { const parts: string[] = []; diff --git a/sdk/core/ts-http-runtime/src/util/userAgentPlatform.browser.ts b/sdk/core/ts-http-runtime/src/util/userAgentPlatform-browser.mts similarity index 100% rename from sdk/core/ts-http-runtime/src/util/userAgentPlatform.browser.ts rename to sdk/core/ts-http-runtime/src/util/userAgentPlatform-browser.mts diff --git a/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.native.ts b/sdk/core/ts-http-runtime/src/util/userAgentPlatform-react-native.mts similarity index 80% rename from sdk/core/core-rest-pipeline/src/util/userAgentPlatform.native.ts rename to sdk/core/ts-http-runtime/src/util/userAgentPlatform-react-native.mts index 66fd2d1e3a37..3233c2a2d5c4 100644 --- a/sdk/core/core-rest-pipeline/src/util/userAgentPlatform.native.ts +++ b/sdk/core/ts-http-runtime/src/util/userAgentPlatform-react-native.mts @@ -4,7 +4,9 @@ /* * NOTE: When moving this file, please update "react-native" section in package.json. */ -const { Platform } = require("react-native"); // eslint-disable-line import/no-extraneous-dependencies, @typescript-eslint/no-require-imports + +/* @ts-ignore */ +const { Platform } = await import("react-native"); /** * @internal diff --git a/sdk/core/ts-http-runtime/src/util/userAgentPlatform.ts b/sdk/core/ts-http-runtime/src/util/userAgentPlatform.ts index c1be64874b1c..a020aeeb9765 100644 --- a/sdk/core/ts-http-runtime/src/util/userAgentPlatform.ts +++ b/sdk/core/ts-http-runtime/src/util/userAgentPlatform.ts @@ -1,7 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as os from "os"; +import * as os from "node:os"; +import * as process from "node:process"; + +/** + * @internal + */ +interface ExtendedPlatformVersions extends NodeJS.ProcessVersions { + bun?: string; + deno?: string; +} /** * @internal @@ -14,6 +23,14 @@ export function getHeaderName(): string { * @internal */ export function setPlatformSpecificData(map: Map): void { - map.set("Node", process.version); + const versions = process.versions as ExtendedPlatformVersions; + if (versions.bun) { + map.set("Bun", versions.bun); + } else if (versions.deno) { + map.set("Deno", versions.deno); + } else if (versions.node) { + map.set("Node", versions.node); + } + map.set("OS", `(${os.arch()}-${os.type()}-${os.release()})`); } diff --git a/sdk/core/ts-http-runtime/src/util/uuidUtils.browser.ts b/sdk/core/ts-http-runtime/src/util/uuidUtils-browser.mts similarity index 90% rename from sdk/core/ts-http-runtime/src/util/uuidUtils.browser.ts rename to sdk/core/ts-http-runtime/src/util/uuidUtils-browser.mts index 69ff81071615..9452dcdd118c 100644 --- a/sdk/core/ts-http-runtime/src/util/uuidUtils.browser.ts +++ b/sdk/core/ts-http-runtime/src/util/uuidUtils-browser.mts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { generateUUID } from "./uuidUtils.native"; +import { generateUUID } from "./uuidUtils.common.js"; interface Crypto { randomUUID(): string; diff --git a/sdk/core/ts-http-runtime/src/util/uuidUtils-react-native.mts b/sdk/core/ts-http-runtime/src/util/uuidUtils-react-native.mts new file mode 100644 index 000000000000..bb681ec861b7 --- /dev/null +++ b/sdk/core/ts-http-runtime/src/util/uuidUtils-react-native.mts @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export { randomUUID } from "./uuidUtils.common.js"; diff --git a/sdk/core/core-util/src/uuidUtils.native.ts b/sdk/core/ts-http-runtime/src/util/uuidUtils.common.ts similarity index 100% rename from sdk/core/core-util/src/uuidUtils.native.ts rename to sdk/core/ts-http-runtime/src/util/uuidUtils.common.ts diff --git a/sdk/core/ts-http-runtime/src/util/uuidUtils.ts b/sdk/core/ts-http-runtime/src/util/uuidUtils.ts index 96d2bfa34980..2fdefce56496 100644 --- a/sdk/core/ts-http-runtime/src/util/uuidUtils.ts +++ b/sdk/core/ts-http-runtime/src/util/uuidUtils.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { randomUUID as v4RandomUUID } from "crypto"; -import { generateUUID } from "./uuidUtils.native"; +import { randomUUID as v4RandomUUID } from "node:crypto"; +import { generateUUID } from "./uuidUtils.common.js"; interface Crypto { randomUUID(): string; diff --git a/sdk/core/ts-http-runtime/src/xhrHttpClient.ts b/sdk/core/ts-http-runtime/src/xhrHttpClient.ts index b8f6001f390b..3540900aacfc 100644 --- a/sdk/core/ts-http-runtime/src/xhrHttpClient.ts +++ b/sdk/core/ts-http-runtime/src/xhrHttpClient.ts @@ -1,17 +1,17 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { AbortError } from "./abort-controller/AbortError"; +import { AbortError } from "./abort-controller/AbortError.js"; import { HttpClient, HttpHeaders, PipelineRequest, PipelineResponse, TransferProgressEvent, -} from "./interfaces"; -import { createHttpHeaders } from "./httpHeaders"; -import { RestError } from "./restError"; -import { isReadableStream } from "./util/typeGuards"; +} from "./interfaces.js"; +import { createHttpHeaders } from "./httpHeaders.js"; +import { RestError } from "./restError.js"; +import { isReadableStream } from "./util/typeGuards.js"; /** * A HttpClient implementation that uses XMLHttpRequest to send HTTP requests. diff --git a/sdk/core/ts-http-runtime/test/bearerTokenAuthenticationPolicy.spec.ts b/sdk/core/ts-http-runtime/test/bearerTokenAuthenticationPolicy.spec.ts index b61de3eadcd7..7e24435de19a 100644 --- a/sdk/core/ts-http-runtime/test/bearerTokenAuthenticationPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/bearerTokenAuthenticationPolicy.spec.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; -import { AccessToken, TokenCredential } from "../src/auth/tokenCredential"; +import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest"; +import { AccessToken, TokenCredential } from "../src/auth/tokenCredential.js"; import { PipelinePolicy, PipelineResponse, @@ -11,27 +10,26 @@ import { bearerTokenAuthenticationPolicy, createHttpHeaders, createPipelineRequest, -} from "../src"; -import { DEFAULT_CYCLER_OPTIONS } from "../src/util/tokenCycler"; +} from "../src/index.js"; +import { DEFAULT_CYCLER_OPTIONS } from "../src/util/tokenCycler.js"; const { refreshWindowInMs: defaultRefreshWindow } = DEFAULT_CYCLER_OPTIONS; describe("BearerTokenAuthenticationPolicy", function () { - let clock: sinon.SinonFakeTimers; - beforeEach(() => { - clock = sinon.useFakeTimers(Date.now()); + vi.useFakeTimers({ now: Date.now() }); }); + afterEach(() => { - clock.restore(); + vi.useRealTimers(); }); it("correctly adds an Authentication header with the Bearer token", async function () { const mockToken = "token"; const tokenScopes = ["scope1", "scope2"]; - const fakeGetToken = sinon.fake.returns( - Promise.resolve({ token: mockToken, expiresOnTimestamp: new Date().getTime() }), - ); + const fakeGetToken = vi + .fn() + .mockResolvedValue({ token: mockToken, expiresOnTimestamp: new Date().getTime() }); const mockCredential: TokenCredential = { getToken: fakeGetToken, }; @@ -42,25 +40,22 @@ describe("BearerTokenAuthenticationPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const bearerTokenAuthPolicy = createBearerTokenPolicy(tokenScopes, mockCredential); await bearerTokenAuthPolicy.sendRequest(request, next); - assert( - fakeGetToken.calledWith(tokenScopes, { - abortSignal: undefined, - tracingOptions: undefined, - }), - "fakeGetToken called incorrectly.", - ); + expect(fakeGetToken).toHaveBeenCalledWith(tokenScopes, { + abortSignal: undefined, + tracingOptions: undefined, + }); assert.strictEqual(request.headers.get("Authorization"), `Bearer ${mockToken}`); }); it("refreshes the token on initial request", async () => { const expiresOn = Date.now() + 1000 * 60; // One minute later. - const credential = new MockRefreshCredential(expiresOn); + const credential = new MockRefreshAzureCredential(expiresOn); const request = createPipelineRequest({ url: "https://example.com" }); const successResponse: PipelineResponse = { @@ -68,8 +63,8 @@ describe("BearerTokenAuthenticationPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = createBearerTokenPolicy("test-scope", credential); @@ -80,7 +75,7 @@ describe("BearerTokenAuthenticationPolicy", function () { it("refreshes the token during the refresh window", async () => { const expireDelayMs = defaultRefreshWindow + 5000; let tokenExpiration = Date.now() + expireDelayMs; - const credential = new MockRefreshCredential(tokenExpiration); + const credential = new MockRefreshAzureCredential(tokenExpiration); const request = createPipelineRequest({ url: "https://example.com" }); const successResponse: PipelineResponse = { @@ -88,8 +83,8 @@ describe("BearerTokenAuthenticationPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = createBearerTokenPolicy("test-scope", credential); @@ -101,7 +96,7 @@ describe("BearerTokenAuthenticationPolicy", function () { // The token will remain cached until tokenExpiration - testTokenRefreshBufferMs, so in (5000 - 1000) milliseconds. // For safe measure, we test the token is still cached a second earlier than the forced refresh expectation. - clock.tick(expireDelayMs - defaultRefreshWindow - 1000); + vi.advanceTimersByTime(expireDelayMs - defaultRefreshWindow - 1000); await policy.sendRequest(request, next); assert.strictEqual(credential.authCount, 1); @@ -110,7 +105,7 @@ describe("BearerTokenAuthenticationPolicy", function () { credential.expiresOnTimestamp = tokenExpiration; // Now we wait until it expires: - clock.tick(expireDelayMs + 1000); + vi.advanceTimersByTime(expireDelayMs + 1000); await policy.sendRequest(request, next); assert.strictEqual(credential.authCount, 2); }); @@ -120,7 +115,7 @@ describe("BearerTokenAuthenticationPolicy", function () { const startTime = Date.now(); const tokenExpiration = startTime + expireDelayMs; const getTokenDelay = 100; - const credential = new MockRefreshCredential(tokenExpiration, getTokenDelay, clock); + const credential = new MockRefreshAzureCredential(tokenExpiration, getTokenDelay); const request = createPipelineRequest({ url: "https://example.com" }); const successResponse: PipelineResponse = { @@ -128,8 +123,8 @@ describe("BearerTokenAuthenticationPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = createBearerTokenPolicy("test-scope", credential); @@ -151,7 +146,7 @@ describe("BearerTokenAuthenticationPolicy", function () { const startTime = Date.now(); const tokenExpiration = startTime + expireDelayMs; const getTokenDelay = 100; - const credential = new MockRefreshCredential(tokenExpiration, getTokenDelay, clock); + const credential = new MockRefreshAzureCredential(tokenExpiration, getTokenDelay); const request = createPipelineRequest({ url: "https://example.com" }); const successResponse: PipelineResponse = { @@ -159,8 +154,8 @@ describe("BearerTokenAuthenticationPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = createBearerTokenPolicy("test-scope", credential); @@ -186,7 +181,7 @@ describe("BearerTokenAuthenticationPolicy", function () { const startTime = Date.now(); const tokenExpiration = startTime + defaultRefreshWindow + expireDelayMs; const getTokenDelay = 100; - const credential = new MockRefreshCredential(tokenExpiration, getTokenDelay, clock); + const credential = new MockRefreshAzureCredential(tokenExpiration, getTokenDelay); const request = createPipelineRequest({ url: "https://example.com" }); const successResponse: PipelineResponse = { @@ -194,15 +189,15 @@ describe("BearerTokenAuthenticationPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = createBearerTokenPolicy("test-scope", credential); await policy.sendRequest(request, next); assert.strictEqual(credential.authCount, 1, "The first authentication should have happened"); - clock.tick(tokenExpiration - startTime - defaultRefreshWindow); // Until we start refreshing the token + vi.advanceTimersByTime(tokenExpiration - startTime - defaultRefreshWindow); // Until we start refreshing the token // Now we wait until some requests are all resolved. await Promise.all([ @@ -226,11 +221,11 @@ describe("BearerTokenAuthenticationPolicy", function () { it("throws if the target URI doesn't start with 'https'", async () => { const expireDelayMs = defaultRefreshWindow + 5000; const tokenExpiration = Date.now() + expireDelayMs; - const credential = new MockRefreshCredential(tokenExpiration); + const credential = new MockRefreshAzureCredential(tokenExpiration); const request = createPipelineRequest({ url: "http://example.com" }); const policy = createBearerTokenPolicy("test-scope", credential); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); let error: Error | undefined; try { @@ -256,14 +251,13 @@ describe("BearerTokenAuthenticationPolicy", function () { } }); -class MockRefreshCredential implements TokenCredential { +class MockRefreshAzureCredential implements TokenCredential { public authCount = 0; public shouldThrow: boolean = false; constructor( public expiresOnTimestamp: number, public getTokenDelay?: number, - public clock?: sinon.SinonFakeTimers, ) {} public async getToken(): Promise { @@ -274,8 +268,8 @@ class MockRefreshCredential implements TokenCredential { } // Allowing getToken to take a while - if (this.getTokenDelay && this.clock) { - this.clock.tick(this.getTokenDelay); + if (this.getTokenDelay && vi.isFakeTimers()) { + vi.advanceTimersByTime(this.getTokenDelay); } return { token: "mock-token", expiresOnTimestamp: this.expiresOnTimestamp }; diff --git a/sdk/core/ts-http-runtime/test/browser/checkEnvironment.spec.ts b/sdk/core/ts-http-runtime/test/browser/checkEnvironment.spec.ts index 5f5e7c7bf376..41fa19aeae24 100644 --- a/sdk/core/ts-http-runtime/test/browser/checkEnvironment.spec.ts +++ b/sdk/core/ts-http-runtime/test/browser/checkEnvironment.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isBrowser, isBun, isDeno, isNode, isReactNative, isWebWorker } from "../../src"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { isBrowser, isBun, isDeno, isNode, isReactNative, isWebWorker } from "../../src/index.js"; describe("checkEnvironment (browser)", function () { describe("isBun (browser)", function () { diff --git a/sdk/core/ts-http-runtime/test/browser/decompressResponsePolicy.ts b/sdk/core/ts-http-runtime/test/browser/decompressResponsePolicy.ts index 719f7a2a7817..03356ca29d1d 100644 --- a/sdk/core/ts-http-runtime/test/browser/decompressResponsePolicy.ts +++ b/sdk/core/ts-http-runtime/test/browser/decompressResponsePolicy.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { decompressResponsePolicy } from "../../src"; +import { describe, it, assert } from "vitest"; +import { decompressResponsePolicy } from "../../src/index.js"; describe("decompressResponsePolicy (browser)", function () { it("Throws on creation", function () { diff --git a/sdk/core/ts-http-runtime/test/browser/fetchHttpClient.spec.ts b/sdk/core/ts-http-runtime/test/browser/fetchHttpClient.spec.ts index a8f35bee3a8b..895ca7d4dfc9 100644 --- a/sdk/core/ts-http-runtime/test/browser/fetchHttpClient.spec.ts +++ b/sdk/core/ts-http-runtime/test/browser/fetchHttpClient.spec.ts @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { createFetchHttpClient } from "../../src/fetchHttpClient"; -import { createPipelineRequest } from "../../src/pipelineRequest"; -import { png } from "./mocks/encodedPng"; -import sinon from "sinon"; -import { createHttpHeaders } from "../../src/httpHeaders"; -import { AbortError } from "../../src/abort-controller/AbortError"; -import { AbortSignalLike } from "../../src/abort-controller/AbortSignalLike"; -import { delay } from "../../src/util/helpers"; +import { describe, it, assert, vi, beforeEach, afterEach } from "vitest"; +import { createFetchHttpClient } from "../../src/fetchHttpClient.js"; +import { createPipelineRequest } from "../../src/pipelineRequest.js"; +import { png } from "./mocks/encodedPng.js"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; +import { AbortError } from "../../src/abort-controller/AbortError.js"; +import { AbortSignalLike } from "../../src/abort-controller/AbortSignalLike.js"; +import { delay } from "../../src/util/helpers.js"; const streamBody = new ReadableStream({ async start(controller) { @@ -55,23 +54,21 @@ function createResponse( } describe("FetchHttpClient", function () { - let fetchMock: sinon.SinonStub; - let clock: sinon.SinonFakeTimers; beforeEach(() => { - fetchMock = sinon.stub(self, "fetch"); + vi.stubGlobal("fetch", vi.fn()); }); afterEach(() => { - sinon.restore(); - fetchMock.restore(); - if (clock) { - clock.restore(); + vi.clearAllMocks(); + vi.unstubAllGlobals(); + if (vi.isFakeTimers()) { + vi.useRealTimers(); } }); it("shouldn't throw on 404", async function () { const mockedResponse = createResponse(404); - fetchMock.returns(mockedResponse); + vi.mocked(fetch).mockResolvedValue(mockedResponse); const client = createFetchHttpClient(); @@ -83,12 +80,11 @@ describe("FetchHttpClient", function () { it("should allow canceling of requests", async function () { const mockedResponse = createResponse(404); const timeoutLength = 2000; - clock = sinon.useFakeTimers(); - fetchMock.callsFake(async (_url, options) => { + vi.useFakeTimers(); + vi.mocked(fetch).mockImplementation(async (_url, options) => { await delay(timeoutLength); - if (options.signal) { + if (options?.signal) { const signal: AbortSignalLike = options.signal; - console.log(`${signal.aborted}`); if (signal.aborted) { throw new AbortError(); @@ -110,9 +106,9 @@ describe("FetchHttpClient", function () { }, }); const promise = client.sendRequest(request); - clock.tick(timeoutLength - 1); + vi.advanceTimersByTime(timeoutLength - 1); controller.abort(); - clock.tick(1); + vi.advanceTimersByTime(1); try { await promise; @@ -123,10 +119,10 @@ describe("FetchHttpClient", function () { }); it("should return AbortError while reading stream", async function () { - clock = sinon.useFakeTimers(); + vi.useFakeTimers(); const body = "This is an example text for abort test"; - fetchMock.callsFake(async (_url, options) => { - if (!options.signal) { + vi.mocked(fetch).mockImplementation(async (_url, options) => { + if (!options?.signal) { throw new Error("Abort signal is not received"); } return createResponse(200, body, 0, 20, options.signal); @@ -143,9 +139,9 @@ describe("FetchHttpClient", function () { streamResponseStatusCodes: new Set([200]), }); const promise = client.sendRequest(request); - clock.tick(100); + vi.advanceTimersByTime(100); controller.abort(); - clock.tick(1); + vi.advanceTimersByTime(1); try { const response = await promise; const reader = response.browserStreamBody!.getReader(); @@ -165,7 +161,7 @@ describe("FetchHttpClient", function () { it("shouldn't be affected by requests cancelled late", async function () { const blob = new Blob(); const mockedResponse = new Response(blob, { status: 200 }); - fetchMock.returns(mockedResponse); + vi.mocked(fetch).mockResolvedValue(mockedResponse); const client = createFetchHttpClient(); const controller = new AbortController(); @@ -183,7 +179,7 @@ describe("FetchHttpClient", function () { it("should allow canceling of requests before the request is made", async function () { const blob = new Blob(); const mockedResponse = new Response(blob, { status: 200 }); - fetchMock.returns(mockedResponse); + vi.mocked(fetch).mockResolvedValue(mockedResponse); const client = createFetchHttpClient(); const controller = new AbortController(); @@ -204,10 +200,10 @@ describe("FetchHttpClient", function () { it("should load chunk by chunk", async function () { const client = createFetchHttpClient(); const responseText = "An appropriate response."; - clock = sinon.useFakeTimers(); + vi.useFakeTimers(); // Mocking fetch to send the first chunk right away but delay the next // chunk one second (1000ms). - fetchMock.returns(createResponse(200, responseText, 1000)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText, 1000)); const url = `http://localhost:3000/files/stream/nonempty`; let downloadCalled = 0; const request = createPipelineRequest({ @@ -228,7 +224,7 @@ describe("FetchHttpClient", function () { const chunk = await reader.read(); // Advance the mocked clock 1000ms so that the mock response // enqueues the second chunk - clock.tick(1000); + vi.advanceTimersByTime(1000); // Verify that only one chunk was loaded assert.equal(downloadCalled, 1); @@ -238,7 +234,7 @@ describe("FetchHttpClient", function () { it("should report download progress and decode chunks", async function () { const client = createFetchHttpClient(); const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText)); const url = `http://localhost:3000/files/stream/nonempty`; let downloadCalled = false; const request = createPipelineRequest({ @@ -257,11 +253,11 @@ describe("FetchHttpClient", function () { it("should report download progress and decode chunks without TransformStream", async function () { // Make TransformStream undefined to simulate Firefox where it is not available - const transformStub = sinon.stub(self, "TransformStream").value(undefined); + vi.stubGlobal("TransformStream", undefined); const client = createFetchHttpClient(); const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText)); const url = `http://localhost:3000/files/stream/nonempty`; let downloadCalled = false; const request = createPipelineRequest({ @@ -274,7 +270,7 @@ describe("FetchHttpClient", function () { }, }); const response = await client.sendRequest(request); - transformStub.restore(); + assert.isDefined(response.bodyAsText); assert.isTrue(downloadCalled, "no download progress"); }); @@ -282,7 +278,7 @@ describe("FetchHttpClient", function () { it("should report download progress when handling blob", async function () { const client = createFetchHttpClient(); const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText)); const url = `http://localhost:3000/files/stream/nonempty`; let downloadCalled = false; const request = createPipelineRequest({ @@ -306,7 +302,7 @@ describe("FetchHttpClient", function () { it("should stream response body when status code matches", async function () { const client = createFetchHttpClient(); const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText)); const url = `http://localhost:3000/files/stream/nonempty`; let downloadCalled = false; const request = createPipelineRequest({ @@ -330,7 +326,7 @@ describe("FetchHttpClient", function () { it("should not stream response body when status code doesn't match", async function () { const client = createFetchHttpClient(); const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText)); const url = `http://localhost:3000/files/stream/nonempty`; let downloadCalled = false; const request = createPipelineRequest({ @@ -352,7 +348,7 @@ describe("FetchHttpClient", function () { it("should report upload progress with TransformStream", async () => { const client = createFetchHttpClient(); const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + vi.mocked(fetch).mockResolvedValue(createResponse(200, responseText)); const url = `http://localhost:3000/formdata/stream/uploadfile`; let downloadCalled = false; @@ -388,21 +384,23 @@ describe("FetchHttpClient", function () { controller.close(); }, }); - fetchMock.callsFake(async (_url, options) => { - const body = options.body; - assert.isTrue( - body && - typeof (body as ReadableStream).getReader === "function" && - typeof (body as ReadableStream).tee === "function", - "expecting ReadableStream request body", - ); - assert.strictEqual(options.duplex, "half"); - const reader = (body as ReadableStream).getReader(); - const data = await reader.read(); - assert.equal(data.value, requestText, "unexpected request text"); - bodySent = true; - return new Response(undefined, { status: 200 }); - }); + vi.mocked(fetch).mockImplementation( + async (_url, options: (RequestInit & { duplex?: string }) | undefined) => { + const body = options?.body; + assert.isTrue( + body && + typeof (body as ReadableStream).getReader === "function" && + typeof (body as ReadableStream).tee === "function", + "expecting ReadableStream request body", + ); + assert.strictEqual(options?.duplex, "half"); + const reader = (body as ReadableStream).getReader(); + const data = await reader.read(); + assert.equal(data.value, requestText, "unexpected request text"); + bodySent = true; + return new Response(undefined, { status: 200 }); + }, + ); const request = createPipelineRequest({ url, method: "PUT", @@ -421,7 +419,7 @@ describe("FetchHttpClient", function () { const url = `http://localhost:3000/formdata/stream/uploadfile`; let bodySent = false; - const factoryMethod = () => { + const factoryMethod = (): ReadableStream => { return new ReadableStream({ start(controller) { controller.enqueue(requestText); @@ -429,8 +427,8 @@ describe("FetchHttpClient", function () { }, }); }; - fetchMock.callsFake(async (_url, options) => { - const body = options.body; + vi.mocked(fetch).mockImplementation(async (_url, options) => { + const body = options?.body; assert.isTrue( body && typeof (body as ReadableStream).getReader === "function" && @@ -458,13 +456,12 @@ describe("FetchHttpClient", function () { it("should honor timeout", async function () { const timeoutLength = 2000; const mockedResponse = createResponse(404); - clock = sinon.useFakeTimers(); - fetchMock.callsFake(async (_url, options) => { + vi.useFakeTimers(); + vi.mocked(fetch).mockImplementation(async (_url, options) => { await delay(timeoutLength); - if (options.signal) { + if (options?.signal) { const signal: AbortSignalLike = options.signal; - console.log(`${signal.aborted}`); if (signal.aborted) { throw new AbortError(); @@ -483,7 +480,7 @@ describe("FetchHttpClient", function () { method: "GET", }); const promise = client.sendRequest(request); - clock.tick(timeoutLength); + vi.advanceTimersByTime(timeoutLength); try { await promise; @@ -508,7 +505,7 @@ describe("FetchHttpClient", function () { it("shouldn't throw when accessing HTTP and allowInsecureConnection is true", async function () { const mockedResponse = createResponse(200); - fetchMock.returns(mockedResponse); + vi.mocked(fetch).mockResolvedValue(mockedResponse); const client = createFetchHttpClient(); const request = createPipelineRequest({ diff --git a/sdk/core/ts-http-runtime/test/browser/logger.spec.ts b/sdk/core/ts-http-runtime/test/browser/logger.spec.ts index 11ddff1a884d..54234ed4b243 100644 --- a/sdk/core/ts-http-runtime/test/browser/logger.spec.ts +++ b/sdk/core/ts-http-runtime/test/browser/logger.spec.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as Logger from "../../src/logger/logger"; -import * as sinon from "sinon"; -import { assert } from "chai"; +import { describe, it, expect, vi, afterEach } from "vitest"; +import * as Logger from "../../src/logger/logger.js"; const testLogger = Logger.createClientLogger("test"); @@ -14,40 +13,40 @@ describe("TypeSpecRuntimeLogger (browser)", function () { afterEach(() => { Logger.setLogLevel(undefined); - sinon.restore(); + vi.restoreAllMocks(); }); it("logs to the correct console function", () => { Logger.setLogLevel("verbose"); - const debugStub = sinon.stub(console, "debug"); + const debugStub = vi.spyOn(console, "debug"); testLogger.verbose("verbose"); - assert.isTrue(debugStub.calledOnce, "console.debug called"); - assert.strictEqual( - debugStub.firstCall.args[0], + expect(debugStub).toHaveBeenCalledOnce(); + expect(debugStub).toHaveBeenCalledWith( expectedTestMessage("typeSpecRuntime:test:verbose", "verbose"), ); - debugStub.restore(); + debugStub.mockClear(); - const infoStub = sinon.stub(console, "info"); + const infoStub = vi.spyOn(console, "info"); testLogger.info("info"); - assert.isTrue( - infoStub.calledOnceWith(expectedTestMessage("typeSpecRuntime:test:info", "info")), - ); - infoStub.restore(); + expect(infoStub).toHaveBeenCalledOnce(); + expect(infoStub).toHaveBeenCalledWith(expectedTestMessage("typeSpecRuntime:test:info", "info")); + infoStub.mockClear(); - const warningStub = sinon.stub(console, "warn"); + const warningStub = vi.spyOn(console, "warn"); testLogger.warning("warning"); - assert.isTrue( - warningStub.calledOnceWith(expectedTestMessage("typeSpecRuntime:test:warning", "warning")), + expect(warningStub).toHaveBeenCalledOnce(); + expect(warningStub).toHaveBeenCalledWith( + expectedTestMessage("typeSpecRuntime:test:warning", "warning"), ); - warningStub.restore(); + warningStub.mockClear(); - const errorStub = sinon.stub(console, "error"); + const errorStub = vi.spyOn(console, "error"); testLogger.error("error"); - assert.isTrue( - errorStub.calledOnceWith(expectedTestMessage("typeSpecRuntime:test:error", "error")), + expect(errorStub).toHaveBeenCalledOnce(); + expect(errorStub).toHaveBeenCalledWith( + expectedTestMessage("typeSpecRuntime:test:error", "error"), ); - errorStub.restore(); + errorStub.mockClear(); }); }); diff --git a/sdk/core/ts-http-runtime/test/browser/proxyPolicy.spec.ts b/sdk/core/ts-http-runtime/test/browser/proxyPolicy.spec.ts index 0b47135417cd..56cb24ad7d75 100644 --- a/sdk/core/ts-http-runtime/test/browser/proxyPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/browser/proxyPolicy.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { proxyPolicy } from "../../src"; +import { describe, it, assert } from "vitest"; +import { proxyPolicy } from "../../src/index.js"; describe("proxyPolicy (browser)", function () { it("Throws on creation", function () { diff --git a/sdk/core/ts-http-runtime/test/browser/streams.spec.ts b/sdk/core/ts-http-runtime/test/browser/streams.spec.ts index 843cf4c8043e..cf5a1ebcda16 100644 --- a/sdk/core/ts-http-runtime/test/browser/streams.spec.ts +++ b/sdk/core/ts-http-runtime/test/browser/streams.spec.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { getClient } from "../../src/client/getClient"; -import sinon from "sinon"; +import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest"; +import { getClient } from "../../src/client/getClient.js"; function createResponse(statusCode: number, body = ""): Response { const stream = new ReadableStream({ @@ -29,18 +28,20 @@ function createResponse(statusCode: number, body = ""): Response { const mockBaseUrl = "https://example.org"; describe("[Browser] Streams", () => { - let fetchMock: sinon.SinonStub; beforeEach(() => { - fetchMock = sinon.stub(self, "fetch"); + vi.stubGlobal("fetch", vi.fn()); }); afterEach(() => { - sinon.restore(); + vi.clearAllMocks(); + vi.unstubAllGlobals(); }); it("should get a JSON body response as a stream", async () => { const responseText = "An appropriate response."; - fetchMock.returns(createResponse(200, responseText)); + + const fetchMock = vi.mocked(fetch); + fetchMock.mockResolvedValue(createResponse(200, responseText)); const client = getClient(mockBaseUrl); const result = await client.pathUnchecked("/foo").get().asBrowserStream(); @@ -48,24 +49,26 @@ describe("[Browser] Streams", () => { // Read the first chunk const chunk = await reader.read(); assert.equal(chunk.done, false); - assert.isTrue(fetchMock.calledOnce); + expect(fetchMock).toHaveBeenCalledOnce(); }); it("should get a JSON body response", async () => { const responseText = "An appropriate response."; + const fetchMock = vi.mocked(fetch); const client = getClient(mockBaseUrl); - fetchMock.returns(createResponse(200, responseText)); + fetchMock.mockResolvedValue(createResponse(200, responseText)); const result = await client.pathUnchecked("/foo").get(); assert.deepEqual(result.body, responseText); - assert.isTrue(fetchMock.calledOnce); + expect(fetchMock).toHaveBeenCalledOnce(); }); it("should be able to handle errors on normal response", async () => { + const fetchMock = vi.mocked(fetch); const client = getClient(mockBaseUrl); - fetchMock.throwsException(new Error("ExpectedException")); + fetchMock.mockRejectedValue(new Error("ExpectedException")); try { await client.pathUnchecked("/foo").get(); } catch (e: any) { @@ -74,8 +77,9 @@ describe("[Browser] Streams", () => { }); it("should be able to handle errors on streamed response", async () => { + const fetchMock = vi.mocked(fetch); const client = getClient(mockBaseUrl); - fetchMock.throwsException(new Error("ExpectedException")); + fetchMock.mockRejectedValue(new Error("ExpectedException")); try { await client.pathUnchecked("/foo").get().asNodeStream(); } catch (e: any) { diff --git a/sdk/core/ts-http-runtime/test/bytesEncoding.spec.ts b/sdk/core/ts-http-runtime/test/bytesEncoding.spec.ts index 7054538f6f2a..339f5eb76226 100644 --- a/sdk/core/ts-http-runtime/test/bytesEncoding.spec.ts +++ b/sdk/core/ts-http-runtime/test/bytesEncoding.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { stringToUint8Array, uint8ArrayToString } from "../src/util/bytesEncoding"; -import { assert } from "chai"; +import { stringToUint8Array, uint8ArrayToString } from "../src/util/bytesEncoding.js"; +import { describe, it, assert } from "vitest"; describe("bytesEncoding", function () { describe("base64ToBytes", function () { diff --git a/sdk/core/ts-http-runtime/test/client/clientHelpers.spec.ts b/sdk/core/ts-http-runtime/test/client/clientHelpers.spec.ts index 6f106b0088a1..514f105d1b39 100644 --- a/sdk/core/ts-http-runtime/test/client/clientHelpers.spec.ts +++ b/sdk/core/ts-http-runtime/test/client/clientHelpers.spec.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createDefaultPipeline } from "../../src/client/clientHelpers"; -import { assert } from "chai"; -import { bearerTokenAuthenticationPolicyName } from "../../src/policies/bearerTokenAuthenticationPolicy"; -import { keyCredentialAuthenticationPolicyName } from "../../src/client/keyCredentialAuthenticationPolicy"; -import { TokenCredential } from "../../src/auth/tokenCredential"; -import { fail } from "assert"; -import { apiVersionPolicyName } from "../../src/client/apiVersionPolicy"; +import { describe, it, assert } from "vitest"; +import { createDefaultPipeline } from "../../src/client/clientHelpers.js"; +import { bearerTokenAuthenticationPolicyName } from "../../src/policies/bearerTokenAuthenticationPolicy.js"; +import { keyCredentialAuthenticationPolicyName } from "../../src/client/keyCredentialAuthenticationPolicy.js"; +import { TokenCredential } from "../../src/auth/tokenCredential.js"; +import { apiVersionPolicyName } from "../../src/client/apiVersionPolicy.js"; + describe("clientHelpers", () => { const mockBaseUrl = "https://example.org"; it("should create a default pipeline with no credentials", () => { @@ -42,7 +42,7 @@ describe("clientHelpers", () => { it("should throw if key credentials but no Api Header Name", () => { try { createDefaultPipeline(mockBaseUrl, { key: "mockKey" }); - fail("Expected to throw an error"); + assert.fail("Expected to throw an error"); } catch (error: any) { assert.equal((error as Error).message, "Missing API Key Header Name"); } diff --git a/sdk/core/ts-http-runtime/test/client/createRestError.spec.ts b/sdk/core/ts-http-runtime/test/client/createRestError.spec.ts index 3e672eaf250b..4e69f9769619 100644 --- a/sdk/core/ts-http-runtime/test/client/createRestError.spec.ts +++ b/sdk/core/ts-http-runtime/test/client/createRestError.spec.ts @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { createRestError } from "../../src/client/restError"; -import { PipelineRequest } from "../../src/interfaces"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { createRestError } from "../../src/client/restError.js"; +import { PipelineRequest } from "../../src/interfaces.js"; describe("createRestError", () => { it("should create a rest error from a PathUnchecked response with standard error", () => { diff --git a/sdk/core/ts-http-runtime/test/client/getBinaryBody.spec.ts b/sdk/core/ts-http-runtime/test/client/getBinaryBody.spec.ts index 3c7844ec2e49..edf077bd6cff 100644 --- a/sdk/core/ts-http-runtime/test/client/getBinaryBody.spec.ts +++ b/sdk/core/ts-http-runtime/test/client/getBinaryBody.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { binaryArrayToString } from "../../src/client/helpers/getBinaryBody"; +import { describe, it, assert } from "vitest"; +import { binaryArrayToString } from "../../src/client/helpers/getBinaryBody.js"; describe("getBinaryBody", () => { describe("decodeBinaryContent", () => { diff --git a/sdk/core/ts-http-runtime/test/client/getClient.spec.ts b/sdk/core/ts-http-runtime/test/client/getClient.spec.ts index 3f6522773f93..7534f7fa931e 100644 --- a/sdk/core/ts-http-runtime/test/client/getClient.spec.ts +++ b/sdk/core/ts-http-runtime/test/client/getClient.spec.ts @@ -1,23 +1,27 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { getCachedDefaultHttpsClient } from "../../src/client/clientHelpers"; -import { getClient } from "../../src/client/getClient"; -import sinon from "sinon"; -import { HttpClient, PipelineRequest, PipelineResponse, SendRequest } from "../../src/interfaces"; -import { PipelinePolicy } from "../../src/pipeline"; -import { createHttpHeaders } from "../../src/httpHeaders"; +import { describe, it, assert, vi, afterEach } from "vitest"; +import { getCachedDefaultHttpsClient } from "../../src/client/clientHelpers.js"; +import { getClient } from "../../src/client/getClient.js"; +import { + HttpClient, + PipelineRequest, + PipelineResponse, + SendRequest, +} from "../../src/interfaces.js"; +import { PipelinePolicy } from "../../src/pipeline.js"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; describe("getClient", () => { afterEach(() => { - sinon.restore(); + vi.restoreAllMocks(); }); describe("#apiVersionPolicy", () => { it("should add apiVersion to requests if apiVersion is absent", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, request: req } as PipelineResponse; }); @@ -37,7 +41,7 @@ describe("getClient", () => { it("should use operation-level apiVersion even if we config the client one", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, request: req } as PipelineResponse; }); @@ -65,7 +69,7 @@ describe("getClient", () => { it("should use apiVersion in url directly even if we config the client one", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, request: req } as PipelineResponse; }); @@ -89,7 +93,7 @@ describe("getClient", () => { it("should not encode url when skip query parameter encoding and api version parameter exists", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, @@ -118,7 +122,7 @@ describe("getClient", () => { it("should encode url when not skip query parameter encoding and api version parameter exists", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, @@ -147,7 +151,7 @@ describe("getClient", () => { it("should append api version correctly", async () => { const defaultHttpClient = getCachedDefaultHttpsClient(); - sinon.stub(defaultHttpClient, "sendRequest").callsFake(async (req) => { + vi.spyOn(defaultHttpClient, "sendRequest").mockImplementation(async (req) => { return { headers: createHttpHeaders(), status: 200, @@ -170,7 +174,8 @@ describe("getClient", () => { }); it("should insert policies in the correct pipeline position", async function () { - const sendRequest = (request: PipelineRequest, next: SendRequest) => next(request); + const sendRequest = (request: PipelineRequest, next: SendRequest): Promise => + next(request); const retryPolicy: PipelinePolicy = { name: "retry", sendRequest, diff --git a/sdk/core/ts-http-runtime/test/client/sendRequest.spec.ts b/sdk/core/ts-http-runtime/test/client/sendRequest.spec.ts index e776e2cb886f..6804b3e524c5 100644 --- a/sdk/core/ts-http-runtime/test/client/sendRequest.spec.ts +++ b/sdk/core/ts-http-runtime/test/client/sendRequest.spec.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { sendRequest } from "../../src/client/sendRequest"; -import { assert } from "chai"; -import { RestError } from "../../src/restError"; -import { PipelineResponse } from "../../src/interfaces"; -import { Pipeline, createEmptyPipeline } from "../../src/pipeline"; -import { createHttpHeaders } from "../../src/httpHeaders"; +import { describe, it, assert } from "vitest"; +import { sendRequest } from "../../src/client/sendRequest.js"; +import { RestError } from "../../src/restError.js"; +import { PipelineResponse } from "../../src/interfaces.js"; +import { Pipeline, createEmptyPipeline } from "../../src/pipeline.js"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; describe("sendRequest", () => { const foo = new Uint8Array([0x66, 0x6f, 0x6f]); diff --git a/sdk/core/ts-http-runtime/test/client/urlHelpers.spec.ts b/sdk/core/ts-http-runtime/test/client/urlHelpers.spec.ts index 1adf5b426e00..69148ef617a9 100644 --- a/sdk/core/ts-http-runtime/test/client/urlHelpers.spec.ts +++ b/sdk/core/ts-http-runtime/test/client/urlHelpers.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { buildBaseUrl, buildRequestUrl } from "../../src/client/urlHelpers"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { buildBaseUrl, buildRequestUrl } from "../../src/client/urlHelpers.js"; describe("urlHelpers", () => { const mockBaseUrl = "https://example.org"; diff --git a/sdk/core/ts-http-runtime/test/defaultLogPolicy.spec.ts b/sdk/core/ts-http-runtime/test/defaultLogPolicy.spec.ts index eb2e6e1a3e6e..7a5b45017442 100644 --- a/sdk/core/ts-http-runtime/test/defaultLogPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/defaultLogPolicy.spec.ts @@ -1,14 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; -import { PipelinePolicy } from "../src/pipeline"; -import { assert } from "chai"; -import { createHttpHeaders } from "../src/httpHeaders"; -import { createPipelineFromOptions } from "../src/createPipelineFromOptions"; -import { createPipelineRequest } from "../src/pipelineRequest"; -import { isNode } from "../src/util/checkEnvironment"; -import sinon from "sinon"; +import { describe, it, assert, vi } from "vitest"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; +import { PipelinePolicy } from "../src/pipeline.js"; +import { createHttpHeaders } from "../src/httpHeaders.js"; +import { createPipelineFromOptions } from "../src/createPipelineFromOptions.js"; +import { createPipelineRequest } from "../src/pipelineRequest.js"; +import { isNode } from "../src/util/checkEnvironment.js"; describe("defaultLogPolicy", function () { it("should be invoked on every retry", async function () { @@ -50,9 +49,10 @@ describe("defaultLogPolicy", function () { const order: string[] = []; for (const policy of orderedPolicies) { - const stub = sinon.stub(policy, "sendRequest").callsFake(async function (req, next) { + const originalSendRequest = policy.sendRequest; + vi.spyOn(policy, "sendRequest").mockImplementation(async function (req, next) { order.push(policy.name); - return stub.wrappedMethod(req, next); + return originalSendRequest(req, next); }); } diff --git a/sdk/core/ts-http-runtime/test/defaultRetryPolicy.spec.ts b/sdk/core/ts-http-runtime/test/defaultRetryPolicy.spec.ts index 10673f38604d..4e56ef3d9568 100644 --- a/sdk/core/ts-http-runtime/test/defaultRetryPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/defaultRetryPolicy.spec.ts @@ -1,14 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; -import { RestError, SendRequest, createPipelineRequest, defaultRetryPolicy } from "../src"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +import { describe, it, assert, expect, vi, afterEach } from "vitest"; +import { RestError, SendRequest, createPipelineRequest, defaultRetryPolicy } from "../src/index.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("defaultRetryPolicy", function () { afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); it("It should throw immediately if the response or error doesn't match anything we were expecting", async () => { @@ -18,10 +17,10 @@ describe("defaultRetryPolicy", function () { const testError = new RestError("Test Error!", { code: "UNEXPECTED" }); const policy = defaultRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -29,9 +28,9 @@ describe("defaultRetryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, 1); + expect(next).toHaveBeenCalledOnce(); assert.isTrue(catchCalled); }); @@ -41,12 +40,12 @@ describe("defaultRetryPolicy", function () { url: "https://bing.com", }); const policy = defaultRetryPolicy(); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); const testError = new RestError("Test Error!", { code: errorCode }); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -54,8 +53,8 @@ describe("defaultRetryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + await vi.runAllTimersAsync(); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); assert.isTrue(catchCalled); }); }); @@ -67,10 +66,10 @@ describe("defaultRetryPolicy", function () { const testError = new RestError("Test Error!", { statusCode: 416 }); const policy = defaultRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - await assert.isRejected(policy.sendRequest(request, next), /Test Error/); - assert.strictEqual(next.callCount, 1); + await expect(policy.sendRequest(request, next)).rejects.toThrow(/Test Error/); + expect(next).toHaveBeenCalledOnce(); }); }); diff --git a/sdk/core/ts-http-runtime/test/exponentialRetryPolicy.spec.ts b/sdk/core/ts-http-runtime/test/exponentialRetryPolicy.spec.ts index 04f7a100ed51..d814bfc782ff 100644 --- a/sdk/core/ts-http-runtime/test/exponentialRetryPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/exponentialRetryPolicy.spec.ts @@ -1,21 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; +import { describe, it, expect, vi, afterEach } from "vitest"; import { PipelineResponse, RestError, SendRequest, createHttpHeaders, createPipelineRequest, -} from "../src"; -import { exponentialRetryPolicy } from "../src/policies/exponentialRetryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +} from "../src/index.js"; +import { exponentialRetryPolicy } from "../src/policies/exponentialRetryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("exponentialRetryPolicy", function () { afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); it("It should throw immediately if we get a 416 response", async () => { @@ -30,11 +29,11 @@ describe("exponentialRetryPolicy", function () { const testError = new RestError("Test Error!", { statusCode: 416, response }); const policy = exponentialRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - await assert.isRejected(policy.sendRequest(request, next), /Test Error/); - assert.strictEqual(next.callCount, 1); + await expect(policy.sendRequest(request, next)).rejects.toThrow(/Test Error/); + expect(next).toHaveBeenCalledOnce(); }); it("It should retry with a 503 response", async () => { @@ -49,14 +48,14 @@ describe("exponentialRetryPolicy", function () { const testError = new RestError("Test Error!", { statusCode: 503, response }); const policy = exponentialRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); - const promise = assert.isRejected(policy.sendRequest(request, next), /Test Error/); - await clock.runAllAsync(); + const promise = expect(policy.sendRequest(request, next)).rejects.toThrow(/Test Error/); + await vi.runAllTimersAsync(); await promise; - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); }); }); diff --git a/sdk/core/ts-http-runtime/test/formDataPolicy.spec.ts b/sdk/core/ts-http-runtime/test/formDataPolicy.spec.ts index b6cb8f16d650..4cdb93eb168a 100644 --- a/sdk/core/ts-http-runtime/test/formDataPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/formDataPolicy.spec.ts @@ -1,17 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; +import { describe, it, assert, vi } from "vitest"; import { PipelineResponse, SendRequest, createHttpHeaders, createPipelineRequest, formDataPolicy, -} from "../src"; -import { BodyPart, FormDataMap, MultipartRequestBody } from "../src/interfaces"; -import { createFile } from "../src/util/file"; +} from "../src/index.js"; +import { FormDataMap } from "../src/interfaces.js"; export async function performRequest(formData: FormDataMap): Promise { const request = createPipelineRequest({ @@ -26,8 +24,8 @@ export async function performRequest(formData: FormDataMap): Promise, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = formDataPolicy(); @@ -35,10 +33,6 @@ export async function performRequest(formData: FormDataMap): Promise, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = formDataPolicy(); @@ -82,8 +76,8 @@ describe("formDataPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); const policy = formDataPolicy(); @@ -92,133 +86,4 @@ describe("formDataPolicy", function () { assert.isUndefined(result.request.formData); assert.strictEqual(result.request.body, `a=va&b=vb&c=vc1&c=vc2`); }); - - describe("multipart/form-data", function () { - it("throws if request.body is already present", async function () { - const request = createPipelineRequest({ - url: "https://bing.com", - headers: createHttpHeaders({ - "Content-Type": "multipart/form-data", - }), - formData: {}, - body: "AAAAAAAAAAAA", - }); - const successResponse: PipelineResponse = { - headers: createHttpHeaders(), - request, - status: 200, - }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); - - const policy = formDataPolicy(); - - assert.isRejected( - policy.sendRequest(request, next), - /multipart\/form-data request must not have a request body already specified/, - ); - }); - - it("prepares a form with multiple fields correctly", async function () { - // add field with spooky unicode characters to ensure encoding is working - const result = await performRequest({ a: "va", b: "vb", c: "👻👻" }); - assert.isUndefined(result.request.formData); - const multipartBody = result.request.multipartBody as any; - assert.ok(multipartBody, "expecting multipartBody to be defined"); - const parts = (multipartBody as any).parts as BodyPart[]; - const enc = new TextEncoder(); - assert.ok(parts.length === 3, "need 3 parts"); - assert.deepEqual(parts[0], { - headers: createHttpHeaders({ - "Content-Disposition": `form-data; name="a"`, - }), - body: enc.encode("va"), - }); - assert.deepEqual(parts[1], { - headers: createHttpHeaders({ - "Content-Disposition": `form-data; name="b"`, - }), - body: enc.encode("vb"), - }); - assert.deepEqual(parts[2], { - headers: createHttpHeaders({ - "Content-Disposition": `form-data; name="c"`, - }), - body: enc.encode("👻👻"), - }); - }); - - describe("file uploads", function () { - it("can upload a File object", async function () { - if (typeof File === "undefined") { - this.skip(); - } - - const result = await performRequest({ - file: new File([new Uint8Array([1, 2, 3])], "file.bin", { - type: "application/octet-stream", - }), - }); - - const parts = (result.request.multipartBody as MultipartRequestBody).parts; - assert.ok(parts.length === 1, "expected 1 part"); - assert.deepEqual( - parts[0].headers, - createHttpHeaders({ - "Content-Type": "application/octet-stream", - "Content-Disposition": `form-data; name="file"; filename="file.bin"`, - }), - ); - const buf = new Uint8Array( - await new Response((parts[0].body as any).stream()).arrayBuffer(), - ); - assert.deepEqual([...buf], [1, 2, 3]); - }); - - it("can upload a Blob object", async function () { - if (typeof Blob === "undefined") { - this.skip(); - } - - const result = await performRequest({ - file: new Blob([new Uint8Array([1, 2, 3])]), - }); - - const parts = (result.request.multipartBody as MultipartRequestBody).parts; - assert.ok(parts.length === 1, "expected 1 part"); - assert.deepEqual( - parts[0].headers, - createHttpHeaders({ - // Content-Type should not be inferred - "Content-Disposition": `form-data; name="file"; filename="blob"`, - }), - ); - const buf = new Uint8Array( - await new Response((parts[0].body as any).stream()).arrayBuffer(), - ); - assert.deepEqual([...buf], [1, 2, 3]); - }); - - it("can upload a Uint8Array using createFile", async function () { - const result = await performRequest({ - file: createFile(new Uint8Array([0x01, 0x02, 0x03]), "file.bin", { - type: "text/plain", - }), - }); - - const parts = (result.request.multipartBody as MultipartRequestBody).parts; - assert.ok(parts.length === 1, "expected 1 part"); - assert.deepEqual( - parts[0].headers, - createHttpHeaders({ - "Content-Type": "text/plain", - "Content-Disposition": `form-data; name="file"; filename="file.bin"`, - }), - ); - - const content = new Uint8Array(await (parts[0].body as Blob).arrayBuffer()); - assert.deepEqual([...content], [0x01, 0x02, 0x03]); - }); - }); - }); }); diff --git a/sdk/core/ts-http-runtime/test/httpHeaders.spec.ts b/sdk/core/ts-http-runtime/test/httpHeaders.spec.ts index f78686234846..1660c88b789a 100644 --- a/sdk/core/ts-http-runtime/test/httpHeaders.spec.ts +++ b/sdk/core/ts-http-runtime/test/httpHeaders.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { createHttpHeaders } from "../src/httpHeaders"; +import { describe, it, assert } from "vitest"; +import { createHttpHeaders } from "../src/httpHeaders.js"; describe("HttpHeaders", () => { it("toJSON() should use normalized header names", () => { diff --git a/sdk/core/ts-http-runtime/test/logger/debug.spec.ts b/sdk/core/ts-http-runtime/test/logger/debug.spec.ts index 9bf30399743e..a7668cd16211 100644 --- a/sdk/core/ts-http-runtime/test/logger/debug.spec.ts +++ b/sdk/core/ts-http-runtime/test/logger/debug.spec.ts @@ -1,13 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import debug, { Debugger } from "../../src/logger/debug"; -import { assert } from "chai"; -import { stub } from "sinon"; +import { describe, it, assert, expect, vi, beforeEach, afterEach, type MockInstance } from "vitest"; +import debug, { Debugger } from "../../src/logger/debug.js"; describe("debug", function () { let logger: Debugger; - let logStub: sinon.SinonStub; + let logStub: MockInstance; function expectedTestMessage(namespace: string, message: string): string { return `${namespace} ${message}`; @@ -15,32 +14,35 @@ describe("debug", function () { beforeEach(() => { logger = debug("test"); - logStub = stub(logger, "log"); + logStub = vi.spyOn(logger, "log"); }); afterEach(() => { - logStub.restore(); + logStub.mockReset(); logger.destroy(); debug.disable(); }); + it("logs when enabled", () => { debug.enable("test"); assert.isTrue(logger.enabled); const testMessage = "hello world!"; logger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test", testMessage)); }); + it("does not log when not enabled", () => { const testMessage = "hello world!"; logger(testMessage); - assert.isTrue(logStub.notCalled); + expect(logStub).not.toHaveBeenCalled(); }); + it("stops logging after being disabled", () => { debug.enable("test"); assert.isTrue(logger.enabled); const testMessage = "hello world!"; logger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test", testMessage)); assert.strictEqual( debug.disable(), "test", @@ -48,8 +50,9 @@ describe("debug", function () { ); assert.isFalse(logger.enabled); logger(testMessage); - assert.isTrue(logStub.calledOnce, "Logger should not have been called a second time."); + expect(logStub).toHaveBeenCalledTimes(1); }); + it("extend() creates a new namespace", () => { const subLogger = logger.extend("foo"); assert.strictEqual(subLogger.namespace, "test:foo"); @@ -57,31 +60,36 @@ describe("debug", function () { const testMessage = "hello world!"; logger(testMessage); subLogger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test:foo", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test:foo", testMessage)); }); + it("enable() handles a csv list", () => { debug.enable("test,test2"); assert.isTrue(debug.enabled("test")); assert.isTrue(debug.enabled("test2")); }); + it("enable() supports wildcards", () => { const subLogger = logger.extend("foo"); debug.enable("test:*"); assert.isTrue(subLogger.enabled); const testMessage = "hello world!"; subLogger(testMessage); - assert.isTrue(logStub.calledOnceWith(expectedTestMessage("test:foo", testMessage))); + expect(logStub).toHaveBeenCalledWith(expectedTestMessage("test:foo", testMessage)); }); + it("enable() supports the global wildcard", () => { debug.enable("*"); assert.isTrue(debug.enabled("test")); assert.isTrue(debug.enabled("bar")); }); + it("enable() supports skips", () => { debug.enable("*,-test:*"); assert.isTrue(debug.enabled("bar")); assert.isFalse(debug.enabled("test:foo")); }); + it("names ending in * are always enabled", () => { assert.isTrue(debug.enabled("foo*")); }); diff --git a/sdk/core/ts-http-runtime/test/logger/logger.spec.ts b/sdk/core/ts-http-runtime/test/logger/logger.spec.ts index ac1f3ea53967..fac680e8555e 100644 --- a/sdk/core/ts-http-runtime/test/logger/logger.spec.ts +++ b/sdk/core/ts-http-runtime/test/logger/logger.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as Logger from "../../src/logger/logger"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import * as Logger from "../../src/logger/logger.js"; const testLogger = Logger.createClientLogger("test"); diff --git a/sdk/core/ts-http-runtime/test/multipartPolicy.spec.ts b/sdk/core/ts-http-runtime/test/multipartPolicy.spec.ts index dc9b551af6a8..64e5861c0747 100644 --- a/sdk/core/ts-http-runtime/test/multipartPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/multipartPolicy.spec.ts @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import sinon from "sinon"; -import { createHttpHeaders } from "../src/httpHeaders"; -import { PipelineRequest, PipelineResponse, SendRequest } from "../src/interfaces"; -import { createPipelineRequest } from "../src/pipelineRequest"; -import { multipartPolicy } from "../src/policies/multipartPolicy"; -import { assert } from "chai"; -import { PipelineRequestOptions } from "../src/pipelineRequest"; -import { stringToUint8Array } from "../src/util/bytesEncoding"; -import { assertBodyMatches } from "./util"; +import { describe, it, assert, vi, expect } from "vitest"; +import { createHttpHeaders } from "../src/httpHeaders.js"; +import { PipelineRequest, PipelineResponse, SendRequest } from "../src/interfaces.js"; +import { createPipelineRequest } from "../src/pipelineRequest.js"; +import { multipartPolicy } from "../src/policies/multipartPolicy.js"; +import { PipelineRequestOptions } from "../src/pipelineRequest.js"; +import { stringToUint8Array } from "../src/util/bytesEncoding.js"; +import { assertBodyMatches } from "./util.js"; export async function performRequest( requestOptions: Omit, @@ -26,8 +25,8 @@ export async function performRequest( request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); await policy.sendRequest(request, next); return request; @@ -56,8 +55,8 @@ describe("multipartPolicy", function () { request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(successResponse); await policy.sendRequest(request, next); @@ -86,7 +85,7 @@ describe("multipartPolicy", function () { }); it("throws when multipart request body present but content-type is not multipart", async function () { - await assert.isRejected( + await expect( performRequest({ headers: createHttpHeaders({ "content-type": "application/json", @@ -95,12 +94,13 @@ describe("multipartPolicy", function () { parts: [], }, }), + ).rejects.toThrow( /Got multipart request body, but content-type header was not multipart: application\/json/, ); }); it("throws when invalid boundary is set in content-type header", async function () { - await assert.isRejected( + await expect( performRequest({ headers: createHttpHeaders({ "content-type": "multipart/form-data; boundary=%%%%%%%", @@ -109,20 +109,18 @@ describe("multipartPolicy", function () { parts: [], }, }), - /Multipart boundary "%%%%%%%" contains invalid characters/, - ); + ).rejects.toThrow(/Multipart boundary "%%%%%%%" contains invalid characters/); }); it("throws when invalid boundary is set in body", async function () { - await assert.isRejected( + await expect( performRequest({ multipartBody: { boundary: "%%%%%%%", parts: [], }, }), - /Multipart boundary "%%%%%%%" contains invalid characters/, - ); + ).rejects.toThrow(/Multipart boundary "%%%%%%%" contains invalid characters/); }); it("generates boundary when none specified in existing header", async function () { diff --git a/sdk/core/ts-http-runtime/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts b/sdk/core/ts-http-runtime/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts index 2bfac5628ce9..535c8f13189c 100644 --- a/sdk/core/ts-http-runtime/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/bearerTokenAuthenticationPolicyChallenge.spec.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; -import { AccessToken, GetTokenOptions, TokenCredential } from "../../src/auth/tokenCredential"; +import { describe, it, assert, vi, beforeEach, afterEach } from "vitest"; +import { AccessToken, GetTokenOptions, TokenCredential } from "../../src/auth/tokenCredential.js"; import { AuthorizeRequestOnChallengeOptions, HttpClient, @@ -12,8 +11,8 @@ import { createEmptyPipeline, createHttpHeaders, createPipelineRequest, -} from "../../src"; -import { TextDecoder } from "util"; +} from "../../src/index.js"; +import { TextDecoder } from "node:util"; export interface TestChallenge { scope: string; @@ -124,13 +123,12 @@ class MockRefreshCredential implements TokenCredential { } describe("bearerTokenAuthenticationPolicy with challenge", function () { - let clock: sinon.SinonFakeTimers; - beforeEach(() => { - clock = sinon.useFakeTimers(Date.now()); + vi.useFakeTimers({ now: Date.now() }); }); + afterEach(() => { - clock.restore(); + vi.useRealTimers(); }); it("tests that the scope and the claim have been passed through to getToken correctly", async function () { @@ -319,7 +317,7 @@ describe("bearerTokenAuthenticationPolicy with challenge", function () { // Will refresh token once as the first time token is empty await pipeline.sendRequest(testHttpsClient, pipelineRequest); - clock.tick(5000); + vi.advanceTimersByTime(5000); // Will refresh token twice // - 1st refreshing because the token is epxired // - 2nd refreshing because the response with old token has 401 error and claim details so we need refresh token again @@ -428,7 +426,7 @@ describe("bearerTokenAuthenticationPolicy with challenge", function () { // - 2nd refreshing to handle challenge process await pipeline.sendRequest(testHttpsClient, pipelineRequest); assert.equal(credential.authCount, 2); - clock.tick(5000); + vi.advanceTimersByTime(5000); // Will not refresh the token because the previous one is still valid await pipeline.sendRequest(testHttpsClient, pipelineRequest); await pipeline.sendRequest(testHttpsClient, pipelineRequest); diff --git a/sdk/core/ts-http-runtime/test/node/checkEnvironment.spec.ts b/sdk/core/ts-http-runtime/test/node/checkEnvironment.spec.ts index 8de2b01e2704..91c251822eb3 100644 --- a/sdk/core/ts-http-runtime/test/node/checkEnvironment.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/checkEnvironment.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isBrowser, isBun, isDeno, isNode, isReactNative, isWebWorker } from "../../src"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { isBrowser, isBun, isDeno, isNode, isReactNative, isWebWorker } from "../../src/index.js"; describe("checkEnvironment (node)", function () { describe("isBun (node)", function () { diff --git a/sdk/core/ts-http-runtime/test/node/decompressResponsePolicy.ts b/sdk/core/ts-http-runtime/test/node/decompressResponsePolicy.ts index 587bb3203278..8b2f312f0072 100644 --- a/sdk/core/ts-http-runtime/test/node/decompressResponsePolicy.ts +++ b/sdk/core/ts-http-runtime/test/node/decompressResponsePolicy.ts @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; -import { SendRequest, createPipelineRequest, decompressResponsePolicy } from "../../src"; +import { describe, it, assert, expect, vi } from "vitest"; +import { SendRequest, createPipelineRequest, decompressResponsePolicy } from "../../src/index.js"; describe("decompressResponsePolicy (node)", function () { it("Sets the expected flag on the request", function () { @@ -15,11 +14,10 @@ describe("decompressResponsePolicy (node)", function () { assert.isFalse(request.headers.has("Accept-Encoding"), "acceptEncoding is set."); - const next = sinon.stub, ReturnType>(); - + const next = vi.fn, ReturnType>(); policy.sendRequest(request, next); - assert.isTrue(next.calledOnceWith(request), "next called with request"); + expect(next).toBeCalledWith(request); assert.strictEqual(request.headers.get("Accept-Encoding"), "gzip,deflate"); }); }); diff --git a/sdk/core/ts-http-runtime/test/node/formDataPolicy.spec.ts b/sdk/core/ts-http-runtime/test/node/formDataPolicy.spec.ts index 82268c032ebf..d0a9a2dcd064 100644 --- a/sdk/core/ts-http-runtime/test/node/formDataPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/formDataPolicy.spec.ts @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { createHttpHeaders } from "../../src/httpHeaders"; -import { MultipartRequestBody } from "../../src/interfaces"; -import { isBlob } from "../../src/util/typeGuards"; -import { Readable } from "stream"; -import { performRequest } from "../formDataPolicy.spec"; -import { createFileFromStream } from "../../src/util/file"; -import { ReadableStream } from "stream/web"; +import { describe, it, assert } from "vitest"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; +import { MultipartRequestBody } from "../../src/interfaces.js"; +import { isBlob } from "../../src/util/typeGuards.js"; +import { Readable } from "node:stream"; +import { performRequest } from "../formDataPolicy.spec.js"; +import { createFileFromStream } from "../../src/util/file.js"; +import { ReadableStream } from "node:stream/web"; describe("formDataPolicy (node-only)", function () { it("can upload a Node ReadableStream", async function () { diff --git a/sdk/core/ts-http-runtime/test/node/getBodyLength.spec.ts b/sdk/core/ts-http-runtime/test/node/getBodyLength.spec.ts index 97801776f559..1b170ce4024c 100644 --- a/sdk/core/ts-http-runtime/test/node/getBodyLength.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/getBodyLength.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { getBodyLength } from "../../src/nodeHttpClient"; +import { describe, it, assert } from "vitest"; +import { getBodyLength } from "../../src/nodeHttpClient.js"; describe("Get Body Length", function () { it("Gets the length of the ASCII string correctly", function () { diff --git a/sdk/core/ts-http-runtime/test/node/nodeHttpClient.spec.ts b/sdk/core/ts-http-runtime/test/node/nodeHttpClient.spec.ts index 489d65fc443c..7fb059c07df0 100644 --- a/sdk/core/ts-http-runtime/test/node/nodeHttpClient.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/nodeHttpClient.spec.ts @@ -1,13 +1,29 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; -import { PassThrough, Writable } from "stream"; +import { describe, it, assert, vi, beforeEach, afterEach } from "vitest"; +import { PassThrough, Writable } from "node:stream"; import { ClientRequest, IncomingHttpHeaders, IncomingMessage } from "http"; -import https from "https"; -import http from "http"; -import { createDefaultHttpClient, createPipelineRequest } from "../../src"; +import { createDefaultHttpClient, createPipelineRequest } from "../../src/index.js"; + +vi.mock("https", async () => { + const actual = await vi.importActual("https"); + return { + ...actual, + request: vi.fn(), + }; +}); + +vi.mock("http", async () => { + const actual = await vi.importActual("http"); + return { + ...actual, + request: vi.fn(), + }; +}); + +import * as https from "https"; +import * as http from "http"; class FakeResponse extends PassThrough { public statusCode?: number; @@ -23,7 +39,7 @@ class FakeRequest extends PassThrough {} * * This fake asserts we have only passed the correct types. */ -const httpRequestChecker = { +const httpRequestChecker: ClientRequest = { on() { /* no op */ }, @@ -34,7 +50,7 @@ const httpRequestChecker = { const isString = typeof chunk === "string"; assert(isString || Buffer.isBuffer(chunk), "Expected either string or Buffer"); }, -}; +} as unknown as ClientRequest; function createResponse(statusCode: number, body = ""): IncomingMessage { const response = new FakeResponse(); @@ -50,29 +66,58 @@ function createRequest(): ClientRequest { return request as unknown as ClientRequest; } -describe("NodeHttpClient", function () { - let stubbedHttpsRequest: sinon.SinonStub; - let stubbedHttpRequest: sinon.SinonStub; - let clock: sinon.SinonFakeTimers; +function yieldHttpsResponse(response: IncomingMessage): void { + const lastCall = vi.mocked<{ + ( + options: string | https.RequestOptions | URL, + callback?: ((res: IncomingMessage) => void) | undefined, + ): ClientRequest; + }>(https.request).mock.lastCall; + if (!lastCall) { + throw new Error("Cannot yield response because mock has not been called"); + } + + if (!lastCall[1]) { + throw new Error("Mock was not called with a callback in the second parameter"); + } + lastCall[1](response); +} + +function yieldHttpResponse(response: IncomingMessage): void { + const lastCall = vi.mocked<{ + ( + options: string | http.RequestOptions | URL, + callback?: ((res: IncomingMessage) => void) | undefined, + ): ClientRequest; + }>(http.request).mock.lastCall; + if (!lastCall) { + throw new Error("Cannot yield response because mock has not been called"); + } + + if (!lastCall[1]) { + throw new Error("Mock was not called with a callback in the second parameter"); + } + lastCall[1](response); +} +describe("NodeHttpClient", function () { beforeEach(function () { - stubbedHttpsRequest = sinon.stub(https, "request"); - stubbedHttpRequest = sinon.stub(http, "request"); - clock = sinon.useFakeTimers(); + vi.useFakeTimers(); + const clientRequest = createRequest(); + vi.mocked(https.request).mockReturnValue(clientRequest); + vi.mocked(http.request).mockReturnValue(clientRequest); }); afterEach(function () { - clock.restore(); - sinon.restore(); + vi.useRealTimers(); + vi.clearAllMocks(); }); it("shouldn't throw on 404", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com" }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(404)); + yieldHttpsResponse(createResponse(404)); const response = await promise; assert.strictEqual(response.status, 404); }); @@ -80,8 +125,6 @@ describe("NodeHttpClient", function () { it("should allow canceling of requests", async function () { const client = createDefaultHttpClient(); const controller = new AbortController(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", abortSignal: controller.signal, @@ -99,14 +142,12 @@ describe("NodeHttpClient", function () { it("shouldn't be affected by requests cancelled late", async function () { const client = createDefaultHttpClient(); const controller = new AbortController(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", abortSignal: controller.signal, }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); const response = await promise; controller.abort(); assert.strictEqual(response.status, 200); @@ -116,8 +157,6 @@ describe("NodeHttpClient", function () { const client = createDefaultHttpClient(); const controller = new AbortController(); controller.abort(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", abortSignal: controller.signal, @@ -133,8 +172,6 @@ describe("NodeHttpClient", function () { it("should report upload and download progress", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); let downloadCalled = false; let uploadCalled = false; const request = createPipelineRequest({ @@ -151,7 +188,7 @@ describe("NodeHttpClient", function () { }); const promise = client.sendRequest(request); const responseText = "An appropriate response."; - stubbedHttpsRequest.yield(createResponse(200, responseText)); + yieldHttpsResponse(createResponse(200, responseText)); const response = await promise; assert.strictEqual(response.bodyAsText, responseText); assert.isTrue(downloadCalled, "no download progress"); @@ -162,14 +199,12 @@ describe("NodeHttpClient", function () { const client = createDefaultHttpClient(); const timeoutLength = 2000; - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", timeout: timeoutLength, }); const promise = client.sendRequest(request); - clock.tick(timeoutLength); + vi.advanceTimersByTime(timeoutLength); try { await promise; assert.fail("Expected await to throw"); @@ -180,14 +215,12 @@ describe("NodeHttpClient", function () { it("should stream response body on matching status code", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", streamResponseStatusCodes: new Set([200]), }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200, "body")); + yieldHttpsResponse(createResponse(200, "body")); const response = await promise; assert.equal(response.bodyAsText, undefined); assert.ok(response.readableStreamBody); @@ -195,14 +228,12 @@ describe("NodeHttpClient", function () { it("should stream response body on any status code", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", streamResponseStatusCodes: new Set([Number.POSITIVE_INFINITY]), }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(201, "body")); + yieldHttpsResponse(createResponse(201, "body")); const response = await promise; assert.equal(response.bodyAsText, undefined); assert.ok(response.readableStreamBody); @@ -210,14 +241,12 @@ describe("NodeHttpClient", function () { it("should not stream response body on non-matching status code", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", streamResponseStatusCodes: new Set([200]), }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(400, "body")); + yieldHttpsResponse(createResponse(400, "body")); const response = await promise; assert.equal(response.bodyAsText, "body"); assert.strictEqual(response.readableStreamBody, undefined); @@ -239,22 +268,18 @@ describe("NodeHttpClient", function () { it("shouldn't throw when accessing HTTP and allowInsecureConnection is true", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpRequest.returns(clientRequest); const request = createPipelineRequest({ allowInsecureConnection: true, url: "http://example.com", }); const promise = client.sendRequest(request); - stubbedHttpRequest.yield(createResponse(200, "body")); + yieldHttpResponse(createResponse(200, "body")); const response = await promise; assert.strictEqual(response.status, 200); }); it("Should decode chunked responses properly", async function () { const client = createDefaultHttpClient(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", }); @@ -272,7 +297,7 @@ describe("NodeHttpClient", function () { buffer.copy(buffer2, 0, 4); streamResponse.write(buffer2); streamResponse.end(); - stubbedHttpsRequest.yield(streamResponse); + yieldHttpsResponse(streamResponse as unknown as IncomingMessage); const response = await promise; assert.strictEqual(response.status, 200); assert.strictEqual(response.bodyAsText, inputString); @@ -280,7 +305,7 @@ describe("NodeHttpClient", function () { it("should handle typed array bodies correctly", async function () { const client = createDefaultHttpClient(); - stubbedHttpsRequest.returns(httpRequestChecker); + vi.mocked(https.request).mockReturnValueOnce(httpRequestChecker); const data = new Uint8Array(10); for (let i = 0; i < 10; i++) { @@ -292,14 +317,14 @@ describe("NodeHttpClient", function () { body: data, }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); const response = await promise; assert.strictEqual(response.status, 200); }); it("should handle ArrayBuffer bodies correctly", async function () { const client = createDefaultHttpClient(); - stubbedHttpsRequest.returns(httpRequestChecker); + vi.mocked(https.request).mockReturnValueOnce(httpRequestChecker); const data = new Uint8Array(10); for (let i = 0; i < 10; i++) { @@ -311,14 +336,14 @@ describe("NodeHttpClient", function () { body: data.buffer, }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); const response = await promise; assert.strictEqual(response.status, 200); }); it("should handle Buffer bodies correctly", async function () { const client = createDefaultHttpClient(); - stubbedHttpsRequest.returns(httpRequestChecker); + vi.mocked(https.request).mockReturnValueOnce(httpRequestChecker); const data = Buffer.from("example text"); @@ -327,18 +352,18 @@ describe("NodeHttpClient", function () { body: data, }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); const response = await promise; assert.strictEqual(response.status, 200); }); it("should handle string bodies correctly", async function () { const client = createDefaultHttpClient(); - stubbedHttpsRequest.returns(httpRequestChecker); + vi.mocked(https.request).mockReturnValueOnce(httpRequestChecker); const request = createPipelineRequest({ url: "https://example.com", body: "test data" }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); const response = await promise; assert.strictEqual(response.status, 200); }); @@ -353,8 +378,8 @@ describe("NodeHttpClient", function () { assert.equal(chunk.toString(), requestText, "Unexpected body"); next(); }, - }); - stubbedHttpsRequest.returns(writable); + }) as unknown as ClientRequest; + vi.mocked(https.request).mockReturnValueOnce(writable); const stream = new PassThrough(); stream.write(requestText); @@ -362,7 +387,7 @@ describe("NodeHttpClient", function () { const body = stream; const request = createPipelineRequest({ url: "https://example.com", body }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); await promise; assert.isTrue(bodySent, "body should have been piped to request"); }); @@ -377,10 +402,10 @@ describe("NodeHttpClient", function () { assert.equal(chunk.toString(), requestText, "Unexpected body"); next(); }, - }); - stubbedHttpsRequest.returns(writable); + }) as unknown as ClientRequest; + vi.mocked(https.request).mockReturnValueOnce(writable); - const body = () => { + const body = (): PassThrough => { const stream = new PassThrough(); stream.write(requestText); stream.end(); @@ -388,26 +413,23 @@ describe("NodeHttpClient", function () { }; const request = createPipelineRequest({ url: "https://example.com", body }); const promise = client.sendRequest(request); - stubbedHttpsRequest.yield(createResponse(200)); + yieldHttpsResponse(createResponse(200)); await promise; assert.isTrue(bodySent, "body should have been piped to request"); }); it("should return an AbortError when aborted while reading the HTTP response", async function () { - clock.restore(); + vi.useRealTimers(); const client = createDefaultHttpClient(); const controller = new AbortController(); - const clientRequest = createRequest(); - stubbedHttpsRequest.returns(clientRequest); const request = createPipelineRequest({ url: "https://example.com", abortSignal: controller.signal, }); - const promise = client.sendRequest(request); const streamResponse = new FakeResponse(); - + const clientRequest = createRequest(); clientRequest.destroy = function (this: FakeRequest, e: Error) { // give it some time to attach listeners and read from the stream setTimeout(() => { @@ -415,11 +437,13 @@ describe("NodeHttpClient", function () { }, 0); return clientRequest; }; + vi.mocked(https.request).mockReturnValueOnce(clientRequest); + const promise = client.sendRequest(request); streamResponse.headers = {}; streamResponse.statusCode = 200; const buffer = Buffer.from("The start of an HTTP body"); streamResponse.write(buffer); - stubbedHttpsRequest.yield(streamResponse); + yieldHttpsResponse(streamResponse as unknown as IncomingMessage); controller.abort(); try { diff --git a/sdk/core/ts-http-runtime/test/node/pipeline.spec.ts b/sdk/core/ts-http-runtime/test/node/pipeline.spec.ts index da722b306378..6307463f405c 100644 --- a/sdk/core/ts-http-runtime/test/node/pipeline.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/pipeline.spec.ts @@ -1,26 +1,31 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import http from "https"; -import https from "https"; +import { describe, it, assert, vi, afterEach } from "vitest"; +import { proxyPolicy, proxyPolicyName } from "../../src/policies/proxyPolicy.js"; +import { tlsPolicy, tlsPolicyName } from "../../src/policies/tlsPolicy.js"; +import { HttpClient } from "../../src/interfaces.js"; +import { HttpsProxyAgent } from "https-proxy-agent"; +import { createEmptyPipeline } from "../../src/pipeline.js"; +import { createHttpHeaders } from "../../src/httpHeaders.js"; +import { createNodeHttpClient } from "../../src/nodeHttpClient.js"; +import { createPipelineFromOptions } from "../../src/createPipelineFromOptions.js"; -import { proxyPolicy, proxyPolicyName } from "../../src/policies/proxyPolicy"; -import { tlsPolicy, tlsPolicyName } from "../../src/policies/tlsPolicy"; +vi.mock("https", async () => { + const actual = await vi.importActual("https"); + return { + ...actual, + request: vi.fn(), + }; +}); -import { HttpClient } from "../../src/interfaces"; -import { HttpsProxyAgent } from "https-proxy-agent"; -import { assert } from "chai"; -import { createEmptyPipeline } from "../../src/pipeline"; -import { createHttpHeaders } from "../../src/httpHeaders"; -import { createNodeHttpClient } from "../../src/nodeHttpClient"; -import { createPipelineFromOptions } from "../../src/createPipelineFromOptions"; -import sinon from "sinon"; +import type { Agent } from "node:http"; +import * as https from "node:https"; describe("HttpsPipeline", function () { describe("Agent creation", function () { afterEach(() => { - sinon.restore(); - sinon.reset(); + vi.clearAllMocks(); }); it("should create a proxy agent", async function () { @@ -81,7 +86,7 @@ describe("HttpsPipeline", function () { const pipeline = createEmptyPipeline(); const fakePfx = "fakecert"; const httpClient: HttpClient = createNodeHttpClient(); - sinon.stub(https, "request").callsFake((request: any) => { + vi.mocked(https.request).mockImplementation((request: any) => { assert.equal(request.agent.options.pfx, fakePfx); throw new Error("ok"); }); @@ -106,7 +111,7 @@ describe("HttpsPipeline", function () { const pipeline = createEmptyPipeline(); const fakePfx = "fakecert"; const httpClient: HttpClient = createNodeHttpClient(); - sinon.stub(https, "request").callsFake((request: any) => { + vi.mocked(https.request).mockImplementation((request: any) => { assert.equal(request.agent.options.pfx, "requestPfx"); throw new Error("ok"); }); @@ -132,7 +137,7 @@ describe("HttpsPipeline", function () { const pipeline = createEmptyPipeline(); const fakePfx = "fakecert"; const httpClient: HttpClient = createNodeHttpClient(); - sinon.stub(https, "request").callsFake((request: any) => { + vi.mocked(https.request).mockImplementation((request: any) => { assert.equal(request.agent.options.pfx, fakePfx); throw new Error("ok"); }); @@ -158,8 +163,8 @@ describe("HttpsPipeline", function () { const pipeline = createEmptyPipeline(); const fakePfx = "fakecert"; const httpClient: HttpClient = createNodeHttpClient(); - let cachedAgent: http.Agent; - sinon.stub(https, "request").callsFake((request: any) => { + let cachedAgent: Agent; + vi.mocked(https.request).mockImplementation((request: any) => { assert.equal(request.agent.options.pfx, fakePfx); if (cachedAgent) { // Should cache Agent @@ -204,8 +209,8 @@ describe("HttpsPipeline", function () { const newFakePfx = "newFakeCert"; const httpClient: HttpClient = createNodeHttpClient(); - let cachedAgent: http.Agent; - sinon.stub(https, "request").callsFake((request: any) => { + let cachedAgent: Agent; + vi.mocked(https.request).mockImplementation((request: any) => { if (cachedAgent) { assert.equal(request.agent.options.pfx, newFakePfx); // Should cache Agent diff --git a/sdk/core/ts-http-runtime/test/node/proxyPolicy.spec.ts b/sdk/core/ts-http-runtime/test/node/proxyPolicy.spec.ts index 347fd18ee797..f399cca54acc 100644 --- a/sdk/core/ts-http-runtime/test/node/proxyPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/proxyPolicy.spec.ts @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; +import * as process from "node:process"; +import { describe, it, assert, vi, afterEach } from "vitest"; import { ProxySettings, SendRequest, createPipelineRequest, getDefaultProxySettings, proxyPolicy, -} from "../../src"; +} from "../../src/index.js"; import { getProxyAgentOptions, globalNoProxyList, loadNoProxy, -} from "../../src/policies/proxyPolicy"; +} from "../../src/policies/proxyPolicy.js"; describe("proxyPolicy (node)", function () { it("Sets proxy settings on the request", function () { @@ -28,11 +28,11 @@ describe("proxyPolicy (node)", function () { url: "https://bing.com", }); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); policy.sendRequest(request, next); - assert.isTrue(next.calledOnceWith(request), "next called with request"); + assert.deepStrictEqual(next.mock.calls, [[request]], "next called with request"); assert.strictEqual(request.proxySettings, proxySettings); }); @@ -53,11 +53,11 @@ describe("proxyPolicy (node)", function () { proxySettings: requestProxySettings, }); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); policy.sendRequest(request, next); - assert.isTrue(next.calledOnceWith(request), "next called with request"); + assert.deepStrictEqual(next.mock.calls, [[request]], "next called with request"); assert.strictEqual(request.proxySettings, requestProxySettings); }); @@ -78,11 +78,11 @@ describe("proxyPolicy (node)", function () { url: "https://proxytest.com", }); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); policy.sendRequest(request, next); - assert.isTrue(next.calledOnceWith(request), "next called with request"); + assert.deepStrictEqual(next.mock.calls, [[request]], "next called with request"); assert.strictEqual(request.proxySettings, undefined); request.url = "https://www.proxytest.com"; @@ -133,13 +133,13 @@ describe("proxyPolicy (node)", function () { }; const policy1 = proxyPolicy(proxySettings, { customNoProxyList: ["test.com"] }); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); const request = createPipelineRequest({ url: "https://proxytest.om", }); policy1.sendRequest(request, next); - assert.isTrue(next.calledOnceWith(request), "next called with request"); + assert.deepStrictEqual(next.mock.calls, [[request]], "next called with request"); assert.strictEqual(request.proxySettings, proxySettings); request.url = "https://test.com"; diff --git a/sdk/core/ts-http-runtime/test/node/restError.spec.ts b/sdk/core/ts-http-runtime/test/node/restError.spec.ts index f316919ae176..92fc20c67982 100644 --- a/sdk/core/ts-http-runtime/test/node/restError.spec.ts +++ b/sdk/core/ts-http-runtime/test/node/restError.spec.ts @@ -1,9 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { PipelineResponse, RestError, createHttpHeaders, createPipelineRequest } from "../../src"; -import { inspect } from "util"; +import { describe, it, assert } from "vitest"; +import { + PipelineResponse, + RestError, + createHttpHeaders, + createPipelineRequest, +} from "../../src/index.js"; +import { inspect } from "node:util"; describe("RestError", function () { it("serializes properly in node", function () { diff --git a/sdk/core/ts-http-runtime/test/pipeline.spec.ts b/sdk/core/ts-http-runtime/test/pipeline.spec.ts index 601534f6c2e4..7202023b5574 100644 --- a/sdk/core/ts-http-runtime/test/pipeline.spec.ts +++ b/sdk/core/ts-http-runtime/test/pipeline.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; import { HttpClient, PipelinePolicy, @@ -9,7 +9,7 @@ import { createHttpHeaders, createPipelineFromOptions, createPipelineRequest, -} from "../src"; +} from "../src/index.js"; describe("HttpsPipeline", function () { it("Newly created pipeline has no policies", function () { diff --git a/sdk/core/ts-http-runtime/test/redirectPolicy.spec.ts b/sdk/core/ts-http-runtime/test/redirectPolicy.spec.ts index 8f608cabec9f..15959b0fa581 100644 --- a/sdk/core/ts-http-runtime/test/redirectPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/redirectPolicy.spec.ts @@ -1,10 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { redirectPolicy } from "../src/policies/redirectPolicy"; -import * as sinon from "sinon"; -import { PipelineResponse, SendRequest, createHttpHeaders, createPipelineRequest } from "../src"; +import { describe, it, assert, expect, vi } from "vitest"; +import { redirectPolicy } from "../src/policies/redirectPolicy.js"; +import { + PipelineResponse, + SendRequest, + createHttpHeaders, + createPipelineRequest, +} from "../src/index.js"; describe("RedirectPolicy", () => { it("should not follow redirect if no location header", async () => { @@ -22,9 +26,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, 301); @@ -46,9 +50,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -70,9 +74,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); }); @@ -93,9 +97,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); }); @@ -116,9 +120,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -140,9 +144,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -164,9 +168,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -188,13 +192,13 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); - assert.strictEqual(next.lastCall.args[0].method, "GET"); - assert.isUndefined(next.lastCall.args[0].body); + assert.strictEqual(next.mock.lastCall?.[0].method, "GET"); + assert.isUndefined(next.mock.lastCall?.[0].body); assert.strictEqual(result.status, expectedStatusCode); }); @@ -214,9 +218,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -238,9 +242,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -262,9 +266,9 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -287,10 +291,10 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy({ maxRetries }); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(redirectResponse); - next.onThirdCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); @@ -306,13 +310,13 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.resolves(redirectResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(redirectResponse); const result = await policy.sendRequest(request, next); assert.strictEqual(result.status, expectedStatusCode); - assert.strictEqual(next.callCount, 21); + expect(next).toHaveBeenCalledTimes(21); }); it("should remove Authorization header on redirected request", async function () { @@ -336,11 +340,11 @@ describe("RedirectPolicy", () => { }; const policy = redirectPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(redirectResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(redirectResponse); + next.mockResolvedValueOnce(successResponse); await policy.sendRequest(request, next); - assert.isFalse(next.args[1][0].headers.has("Authorization")); + assert.isFalse(next.mock.calls[1][0].headers.has("Authorization")); }); }); diff --git a/sdk/core/ts-http-runtime/test/retryPolicy.spec.ts b/sdk/core/ts-http-runtime/test/retryPolicy.spec.ts index 0186c6289b21..c311cf9eae66 100644 --- a/sdk/core/ts-http-runtime/test/retryPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/retryPolicy.spec.ts @@ -1,21 +1,21 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as sinon from "sinon"; + +import { describe, it, assert, expect, vi, afterEach } from "vitest"; import { PipelineResponse, RestError, SendRequest, createHttpHeaders, createPipelineRequest, -} from "../src"; -import { retryPolicy } from "../src/policies/retryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; -import { assert } from "chai"; -import { makeTestLogger } from "./util"; +} from "../src/index.js"; +import { retryPolicy } from "../src/policies/retryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; +import { makeTestLogger } from "./util.js"; describe("retryPolicy", function () { afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); it("It should allow passing custom retry strategies", async () => { @@ -42,20 +42,21 @@ describe("retryPolicy", function () { }, }, ]); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().rejects(testError); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockRejectedValueOnce(testError); + next.mockResolvedValueOnce(successResponse); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); const promise = policy.sendRequest(request, next); - assert.isTrue(next.calledOnce); + expect(next).toHaveBeenCalledOnce(); + const beforeTime = Date.now(); // allow the delay to occur - const time = await clock.nextAsync(); + await vi.advanceTimersToNextTimerAsync(); // should be at least the standard delay - assert.isAtLeast(time, 100); - assert.isTrue(next.calledTwice); + assert.isAtLeast(Date.now() - beforeTime, 100); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; assert.strictEqual(result, successResponse); @@ -80,10 +81,10 @@ describe("retryPolicy", function () { }, }, ]); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -91,9 +92,9 @@ describe("retryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); assert.isTrue(catchCalled); }); @@ -122,10 +123,10 @@ describe("retryPolicy", function () { }, ); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -133,9 +134,9 @@ describe("retryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, 11); + expect(next).toHaveBeenCalledTimes(11); assert.isTrue(catchCalled); }); @@ -159,10 +160,10 @@ describe("retryPolicy", function () { }, ]); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -170,9 +171,9 @@ describe("retryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); assert.isTrue(catchCalled); assert.strictEqual(request.url, "https://not-bing.com"); }); @@ -198,10 +199,10 @@ describe("retryPolicy", function () { }, ]); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -209,9 +210,9 @@ describe("retryPolicy", function () { catchCalled = true; assert.strictEqual(e, retryError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, 1); + expect(next).toHaveBeenCalledTimes(1); assert.isTrue(catchCalled); }); @@ -243,10 +244,10 @@ describe("retryPolicy", function () { }, ); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -254,9 +255,9 @@ describe("retryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); assert.isTrue(catchCalled); assert.deepEqual( @@ -324,10 +325,10 @@ describe("retryPolicy", function () { }, ); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -335,9 +336,9 @@ describe("retryPolicy", function () { catchCalled = true; assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, 1); + expect(next).toHaveBeenCalledTimes(1); assert.isTrue(catchCalled); assert.deepEqual( @@ -388,8 +389,8 @@ describe("retryPolicy", function () { }, ); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); abortController.abort(); @@ -401,7 +402,7 @@ describe("retryPolicy", function () { }); // should be one more than the default retry count - assert.strictEqual(next.callCount, 1); + expect(next).toHaveBeenCalledTimes(1); assert.isTrue(catchCalled); assert.deepEqual( @@ -449,10 +450,10 @@ describe("retryPolicy", function () { }, ); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -461,10 +462,10 @@ describe("retryPolicy", function () { assert.strictEqual(e, retryError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, 1); + expect(next).toHaveBeenCalledTimes(1); assert.isTrue(catchCalled); assert.deepEqual( @@ -516,10 +517,10 @@ describe("retryPolicy", function () { }, ); - const next = sinon.stub, ReturnType>(); - next.rejects(testError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(testError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -528,10 +529,10 @@ describe("retryPolicy", function () { assert.strictEqual(e, testError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); assert.isTrue(catchCalled); assert.strictEqual(request.url, "https://not-bing.com"); diff --git a/sdk/core/ts-http-runtime/test/sanitizer.spec.ts b/sdk/core/ts-http-runtime/test/sanitizer.spec.ts index a00d261f1ec9..c68817376b01 100644 --- a/sdk/core/ts-http-runtime/test/sanitizer.spec.ts +++ b/sdk/core/ts-http-runtime/test/sanitizer.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { Sanitizer } from "../src/util/sanitizer"; +import { describe, it, assert } from "vitest"; +import { Sanitizer } from "../src/util/sanitizer.js"; describe("Sanitizer", function () { it("Redacts query parameters in url properties", function () { diff --git a/sdk/core/ts-http-runtime/test/systemErrorRetryPolicy.spec.ts b/sdk/core/ts-http-runtime/test/systemErrorRetryPolicy.spec.ts index 785e70bf76e6..9ea85d60fd9b 100644 --- a/sdk/core/ts-http-runtime/test/systemErrorRetryPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/systemErrorRetryPolicy.spec.ts @@ -1,21 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; +import { describe, it, assert, expect, vi, afterEach } from "vitest"; import { PipelineResponse, RestError, SendRequest, createHttpHeaders, createPipelineRequest, -} from "../src"; -import { systemErrorRetryPolicy } from "../src/policies/systemErrorRetryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +} from "../src/index.js"; +import { systemErrorRetryPolicy } from "../src/policies/systemErrorRetryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("systemErrorRetryPolicy", function () { afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); it("It should retry after a system error", async () => { @@ -30,20 +29,21 @@ describe("systemErrorRetryPolicy", function () { }; const policy = systemErrorRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().rejects(systemError); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockRejectedValueOnce(systemError); + next.mockResolvedValueOnce(successResponse); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); const promise = policy.sendRequest(request, next); - assert.isTrue(next.calledOnce); + expect(next).toHaveBeenCalledOnce(); // allow the delay to occur - const time = await clock.nextAsync(); + const before = Date.now(); + await vi.advanceTimersToNextTimerAsync(); // should be at least the standard delay - assert.isAtLeast(time, 500); - assert.isTrue(next.calledTwice); + assert.isAtLeast(Date.now() - before, 500); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; @@ -57,10 +57,10 @@ describe("systemErrorRetryPolicy", function () { const systemError = new RestError("Test Error!", { code: "ENOENT" }); const policy = systemErrorRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.rejects(systemError); + const next = vi.fn, ReturnType>(); + next.mockRejectedValue(systemError); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); let catchCalled = false; const promise = policy.sendRequest(request, next); @@ -68,9 +68,9 @@ describe("systemErrorRetryPolicy", function () { catchCalled = true; assert.strictEqual(e, systemError); }); - await clock.runAllAsync(); + await vi.runAllTimersAsync(); // should be one more than the default retry count - assert.strictEqual(next.callCount, DEFAULT_RETRY_POLICY_COUNT + 1); + expect(next).toHaveBeenCalledTimes(DEFAULT_RETRY_POLICY_COUNT + 1); assert.isTrue(catchCalled); }); }); diff --git a/sdk/core/ts-http-runtime/test/throttlingRetryPolicy.spec.ts b/sdk/core/ts-http-runtime/test/throttlingRetryPolicy.spec.ts index 11df268a9d4a..6804f3e4114c 100644 --- a/sdk/core/ts-http-runtime/test/throttlingRetryPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/throttlingRetryPolicy.spec.ts @@ -1,18 +1,19 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert, use as chaiUse } from "chai"; -import chaiPromises from "chai-as-promised"; -chaiUse(chaiPromises); -import { Context } from "mocha"; -import * as sinon from "sinon"; -import { PipelineResponse, SendRequest, createHttpHeaders, createPipelineRequest } from "../src"; -import { throttlingRetryPolicy } from "../src/policies/throttlingRetryPolicy"; -import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants"; +import { describe, it, assert, expect, vi, afterEach } from "vitest"; +import { + PipelineResponse, + SendRequest, + createHttpHeaders, + createPipelineRequest, +} from "../src/index.js"; +import { throttlingRetryPolicy } from "../src/policies/throttlingRetryPolicy.js"; +import { DEFAULT_RETRY_POLICY_COUNT } from "../src/constants.js"; describe("throttlingRetryPolicy", function () { afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); const defaultDurations = [0, 10 * 1000]; // milliseconds @@ -48,24 +49,23 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(retryResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(retryResponse); + next.mockResolvedValueOnce(successResponse); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers({ now: 0 }); const promise = policy.sendRequest(request, next); - assert.isTrue(next.calledOnce, "next wasn't called once"); + expect(next).toHaveBeenCalledOnce(); // allow the delay to occur - const time = await clock.nextAsync(); - assert.strictEqual(time, defaultDuration); - assert.isTrue(next.calledTwice, "next wasn't called twice"); + await vi.advanceTimersToNextTimerAsync(); + assert.strictEqual(Date.now(), defaultDuration); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; assert.strictEqual(result, successResponse); - clock.restore(); }); }); }); @@ -88,28 +88,27 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(retryResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(retryResponse); + next.mockResolvedValueOnce(successResponse); - const clock = sinon.useFakeTimers(new Date("Wed, 21 Oct 2015 07:20:00 GMT")); + vi.useFakeTimers({ now: new Date("Wed, 21 Oct 2015 07:20:00 GMT") }); const promise = policy.sendRequest(request, next); - assert.isTrue(next.calledOnce); + expect(next).toHaveBeenCalledOnce(); // allow the delay to occur - const time = await clock.nextAsync(); + await vi.advanceTimersToNextTimerAsync(); assert.strictEqual( - time, + Date.now(), new Date("Wed, 21 Oct 2015 07:28:00 GMT").getTime(), "It should now be the time from the header.", ); - assert.isTrue(next.calledTwice); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; assert.strictEqual(result, successResponse); - clock.restore(); }); it("It should retry after a given number of seconds on a response with status code 503", async () => { @@ -130,24 +129,23 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(retryResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(retryResponse); + next.mockResolvedValueOnce(successResponse); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers({ now: 0 }); const promise = policy.sendRequest(request, next); - assert.isTrue(next.calledOnce); + expect(next).toHaveBeenCalledOnce(); // allow the delay to occur - const time = await clock.nextAsync(); - assert.strictEqual(time, 10 * 1000); - assert.isTrue(next.calledTwice); + await vi.advanceTimersToNextTimerAsync(); + assert.strictEqual(Date.now(), 10 * 1000); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; assert.strictEqual(result, successResponse); - clock.restore(); }); it("It should retry after a given date occurs on a response with status code 503", async () => { @@ -168,28 +166,27 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(retryResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(retryResponse); + next.mockResolvedValueOnce(successResponse); - const clock = sinon.useFakeTimers(new Date("Wed, 21 Oct 2015 07:20:00 GMT")); + vi.useFakeTimers({ now: new Date("Wed, 21 Oct 2015 07:20:00 GMT") }); const promise = policy.sendRequest(request, next); - assert.isTrue(next.calledOnce); + expect(next).toHaveBeenCalledOnce(); // allow the delay to occur - const time = await clock.nextAsync(); + await vi.advanceTimersToNextTimerAsync(); assert.strictEqual( - time, + Date.now(), new Date("Wed, 21 Oct 2015 07:28:00 GMT").getTime(), "It should now be the time from the header.", ); - assert.isTrue(next.calledTwice); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; assert.strictEqual(result, successResponse); - clock.restore(); }); it("It should retry after 0 seconds with status code 503 for a past date", async () => { @@ -210,25 +207,24 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(retryResponse); - next.onSecondCall().resolves(successResponse); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(retryResponse); + next.mockResolvedValueOnce(successResponse); const promise = policy.sendRequest(request, next); - const clock = sinon.useFakeTimers(); + vi.useFakeTimers(); - assert.isTrue(next.calledOnce, "next wasn't called once"); - await clock.nextAsync(); - assert.isTrue(next.calledTwice, "next wasn't called twice"); + expect(next).toHaveBeenCalledOnce(); + await vi.advanceTimersToNextTimerAsync(); + expect(next).toHaveBeenCalledTimes(2); const result = await promise; assert.strictEqual(result, successResponse); - clock.restore(); }); - it("It should retry up to the default max retries", async function (this: Context) { - const clock = sinon.useFakeTimers(); + it("It should retry up to the default max retries", async function () { + vi.useFakeTimers(); const request = createPipelineRequest({ url: "https://bing.com", @@ -242,13 +238,13 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); let i = 0; for (; i < DEFAULT_RETRY_POLICY_COUNT; ++i) { - next.onCall(i).resolves(retryResponse); + next.mockResolvedValueOnce(retryResponse); } // This one should be returned - next.onCall(i).resolves({ + next.mockResolvedValueOnce({ headers: createHttpHeaders({ "Retry-After": "1", "final-response": "final-response", @@ -258,12 +254,10 @@ describe("throttlingRetryPolicy", function () { }); const promise = policy.sendRequest(request, next); - await clock.tickAsync(i * 1000); + await vi.advanceTimersByTimeAsync(i * 1000); const response = await promise; assert.equal(response.status, 503); assert.equal(response.headers.get("final-response"), "final-response"); - - clock.restore(); }); it("throttlingRetryPolicy should honor abort signal", async () => { @@ -285,17 +279,11 @@ describe("throttlingRetryPolicy", function () { }; const policy = throttlingRetryPolicy(); - const next = sinon.stub, ReturnType>(); - next.onFirstCall().resolves(retryResponse); - next.onSecondCall().resolves(successResponse); - - await assert.isRejected( - policy.sendRequest(request, next), - "The operation was aborted.", - "Unexpected error thrown", - ); + const next = vi.fn, ReturnType>(); + next.mockResolvedValueOnce(retryResponse); + next.mockResolvedValueOnce(successResponse); - assert.isTrue(next.calledOnce); - assert.isFalse(next.calledTwice); + await expect(policy.sendRequest(request, next)).rejects.toThrow("The operation was aborted."); + expect(next).toHaveBeenCalledOnce(); }); }); diff --git a/sdk/core/ts-http-runtime/test/tracing/instrumenter.spec.ts b/sdk/core/ts-http-runtime/test/tracing/instrumenter.spec.ts index f59f2f304543..f467b5a764d5 100644 --- a/sdk/core/ts-http-runtime/test/tracing/instrumenter.spec.ts +++ b/sdk/core/ts-http-runtime/test/tracing/instrumenter.spec.ts @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Instrumenter, TracingSpan } from "../../src/tracing/interfaces"; +import { Instrumenter, TracingSpan } from "../../src/tracing/interfaces.js"; import { createDefaultInstrumenter, createDefaultTracingSpan, getInstrumenter, useInstrumenter, -} from "../../src/tracing/instrumenter"; -import { createTracingContext, knownContextKeys } from "../../src/tracing/tracingContext"; -import { assert } from "chai"; +} from "../../src/tracing/instrumenter.js"; +import { createTracingContext, knownContextKeys } from "../../src/tracing/tracingContext.js"; +import { describe, it, assert, beforeEach } from "vitest"; describe("Instrumenter", () => { describe("NoOpInstrumenter", () => { diff --git a/sdk/core/ts-http-runtime/test/tracing/interfaces.spec.ts b/sdk/core/ts-http-runtime/test/tracing/interfaces.spec.ts index c4db865c6f9f..d2523f5d081b 100644 --- a/sdk/core/ts-http-runtime/test/tracing/interfaces.spec.ts +++ b/sdk/core/ts-http-runtime/test/tracing/interfaces.spec.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { GetTokenOptions } from "../../src/auth/tokenCredential"; -import { OperationTracingOptions } from "../../src/tracing/interfaces"; -import { assert } from "chai"; -import { createTracingContext } from "../../src/tracing/tracingContext"; +import { describe, it, assert } from "vitest"; +import { GetTokenOptions } from "../../src/auth/tokenCredential.js"; +import { OperationTracingOptions } from "../../src/tracing/interfaces.js"; +import { createTracingContext } from "../../src/tracing/tracingContext.js"; describe("Interface compatibility", () => { describe("OperationTracingOptions", () => { diff --git a/sdk/core/ts-http-runtime/test/tracing/tracingClient.spec.ts b/sdk/core/ts-http-runtime/test/tracing/tracingClient.spec.ts index c1ce28a02eaa..d8f87120d923 100644 --- a/sdk/core/ts-http-runtime/test/tracing/tracingClient.spec.ts +++ b/sdk/core/ts-http-runtime/test/tracing/tracingClient.spec.ts @@ -1,21 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest"; import { Instrumenter, TracingClient, TracingContext, TracingSpan, -} from "../../src/tracing/interfaces"; +} from "../../src/tracing/interfaces.js"; import { createDefaultInstrumenter, createDefaultTracingSpan, useInstrumenter, -} from "../../src/tracing/instrumenter"; -import { createTracingContext, knownContextKeys } from "../../src/tracing/tracingContext"; -import { assert } from "chai"; -import { createTracingClient } from "../../src/tracing/tracingClient"; -import sinon from "sinon"; +} from "../../src/tracing/instrumenter.js"; +import { createTracingContext, knownContextKeys } from "../../src/tracing/tracingContext.js"; +import { createTracingClient } from "../../src/tracing/tracingClient.js"; describe("TracingClient", () => { let instrumenter: Instrumenter; @@ -38,7 +37,7 @@ describe("TracingClient", () => { }); afterEach(() => { - sinon.restore(); + vi.restoreAllMocks(); }); describe("#startSpan", () => { @@ -51,23 +50,20 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setAttributeSpy = sinon.spy(span, "setAttribute"); + const setAttributeSpy = vi.spyOn(span, "setAttribute"); client.startSpan("test", {}); - assert.isTrue( - setAttributeSpy.calledWith("az.namespace", expectedNamespace), - `expected span.setAttribute("az.namespace", "${expectedNamespace}") to have been called`, - ); + expect(setAttributeSpy).toBeCalledWith("az.namespace", expectedNamespace); }); it("passes package information to instrumenter", () => { - const instrumenterStartSpanSpy = sinon.spy(instrumenter, "startSpan"); + const instrumenterStartSpanSpy = vi.spyOn(instrumenter, "startSpan"); client.startSpan("test", {}); - assert.isTrue(instrumenterStartSpanSpy.called); - const args = instrumenterStartSpanSpy.getCall(0).args; - - assert.equal(args[0], "test"); - assert.equal(args[1]?.packageName, "test-package"); - assert.equal(args[1]?.packageVersion, "1.0.0"); + expect(instrumenterStartSpanSpy).toHaveBeenCalledOnce(); + expect(instrumenterStartSpanSpy).toHaveBeenCalledWith("test", { + packageName: "test-package", + packageVersion: "1.0.0", + tracingContext: undefined, + }); }); it("sets namespace on context", () => { @@ -117,14 +113,11 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setAttributeSpy = sinon.spy(span, "setAttribute"); + const setAttributeSpy = vi.spyOn(span, "setAttribute"); await client.withSpan(spanName, {}, async () => { // no op }); - assert.isTrue( - setAttributeSpy.calledWith("az.namespace", expectedNamespace), - `expected span.setAttribute("az.namespace", "${expectedNamespace}") to have been called`, - ); + expect(setAttributeSpy).toBeCalledWith("az.namespace", expectedNamespace); }); it("passes options and span to callback", async () => { @@ -177,10 +170,10 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setStatusSpy = sinon.spy(span, "setStatus"); + const setStatusSpy = vi.spyOn(span, "setStatus"); await client.withSpan(spanName, {}, () => Promise.resolve(42)); - assert.isTrue(setStatusSpy.calledWith(sinon.match({ status: "success" }))); + expect(setStatusSpy).toHaveBeenCalledWith({ status: "success" }); }); }); @@ -194,13 +187,13 @@ describe("TracingClient", () => { tracingContext: context, }; }; - const setStatusSpy = sinon.spy(span, "setStatus"); + const setStatusSpy = vi.spyOn(span, "setStatus"); let errorThrown = false; try { await client.withSpan(spanName, {}, () => Promise.reject(new Error("test"))); } catch (err: any) { errorThrown = true; - assert.isTrue(setStatusSpy.calledWith(sinon.match({ status: "error", error: err }))); + expect(setStatusSpy).toHaveBeenCalledWith({ status: "error", error: err }); } assert.isTrue(errorThrown); diff --git a/sdk/core/ts-http-runtime/test/tracing/tracingContext.spec.ts b/sdk/core/ts-http-runtime/test/tracing/tracingContext.spec.ts index 01135a01e8ea..e1166c119059 100644 --- a/sdk/core/ts-http-runtime/test/tracing/tracingContext.spec.ts +++ b/sdk/core/ts-http-runtime/test/tracing/tracingContext.spec.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { describe, it, assert, beforeEach } from "vitest"; import { TracingContextImpl, createTracingContext, knownContextKeys, -} from "../../src/tracing/tracingContext"; -import { assert } from "chai"; -import { createDefaultTracingSpan } from "../../src/tracing/instrumenter"; +} from "../../src/tracing/tracingContext.js"; +import { createDefaultTracingSpan } from "../../src/tracing/instrumenter.js"; describe("TracingContext", () => { describe("TracingContextImpl", () => { diff --git a/sdk/core/ts-http-runtime/test/tracingPolicy.spec.ts b/sdk/core/ts-http-runtime/test/tracingPolicy.spec.ts index 29721ae78dd0..402256d76f00 100644 --- a/sdk/core/ts-http-runtime/test/tracingPolicy.spec.ts +++ b/sdk/core/ts-http-runtime/test/tracingPolicy.spec.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import * as sinon from "sinon"; +import { describe, it, assert, expect, vi, beforeEach, afterEach, type Mock } from "vitest"; import { PipelineRequest, PipelineResponse, @@ -11,7 +10,7 @@ import { createHttpHeaders, createPipelineRequest, tracingPolicy, -} from "../src"; +} from "../src/index.js"; import { Instrumenter, InstrumenterSpanOptions, @@ -19,8 +18,8 @@ import { TracingContext, TracingSpan, TracingSpanOptions, -} from "../src/tracing/interfaces"; -import { useInstrumenter } from "../src/tracing/instrumenter"; +} from "../src/tracing/interfaces.js"; +import { useInstrumenter } from "../src/tracing/instrumenter.js"; class MockSpan implements TracingSpan { spanAttributes: Record = {}; @@ -121,7 +120,7 @@ describe("tracingPolicy", function () { function createTestRequest({ noContext = false } = {}): { request: PipelineRequest; - next: sinon.SinonStub; + next: Mock, ReturnType>; } { const request = createPipelineRequest({ url: "https://bing.com", @@ -134,20 +133,20 @@ describe("tracingPolicy", function () { request: request, status: 200, }; - const next = sinon.stub, ReturnType>(); - next.resolves(response); + const next = vi.fn, ReturnType>(); + next.mockResolvedValue(response); return { request, next }; } - afterEach(() => { - sinon.restore(); - }); - beforeEach(() => { activeInstrumenter = new MockInstrumenter(); useInstrumenter(activeInstrumenter); }); + afterEach(() => { + vi.restoreAllMocks(); + }); + it("will create a span with the correct data", async () => { const policy = tracingPolicy(); const { request, next } = createTestRequest(); @@ -165,7 +164,7 @@ describe("tracingPolicy", function () { }); it("will set request headers correctly", async () => { - sinon.stub(activeInstrumenter, "createRequestHeaders").returns({ + vi.spyOn(activeInstrumenter, "createRequestHeaders").mockReturnValue({ testheader: "testvalue", }); const { request, next } = createTestRequest(); @@ -184,11 +183,11 @@ describe("tracingPolicy", function () { }); const policy = tracingPolicy(); - const next = sinon.stub, ReturnType>(); + const next = vi.fn, ReturnType>(); const requestError = new RestError("Bad Request.", { statusCode: 400 }); - next.rejects(requestError); + next.mockRejectedValue(requestError); - await assert.isRejected(policy.sendRequest(request, next), requestError); + await expect(policy.sendRequest(request, next)).rejects.toThrow(requestError); const createdSpan = activeInstrumenter.lastSpanCreated; assert.exists(createdSpan); const mockSpan = createdSpan!; @@ -211,33 +210,39 @@ describe("tracingPolicy", function () { describe("span errors", () => { it("will not fail the request when creating a span throws", async () => { - sinon.stub(activeInstrumenter, "startSpan").throws("boom"); + vi.spyOn(activeInstrumenter, "startSpan").mockImplementation(() => { + throw "boom"; + }); const { request, next } = createTestRequest(); const policy = tracingPolicy(); - await assert.isFulfilled(policy.sendRequest(request, next)); + await expect(policy.sendRequest(request, next)).resolves; }); it("will not fail the request when post-processing success fails", async () => { - const mockSpan = sinon.createStubInstance(MockSpan); - mockSpan.end.throws(new Error("end is not a function")); + const mockSpan = new MockSpan("mock"); + vi.spyOn(mockSpan, "end").mockImplementation(() => { + throw new Error("end is not a function"); + }); activeInstrumenter.setStaticSpan(mockSpan); const { request, next } = createTestRequest(); const policy = tracingPolicy(); - await assert.isFulfilled(policy.sendRequest(request, next)); + await expect(policy.sendRequest(request, next)).resolves; }); it("will not fail the request when post-processing error fails", async () => { - const mockSpan = sinon.createStubInstance(MockSpan); - mockSpan.end.throws(new Error("end is not a function")); + const mockSpan = new MockSpan("mock"); + vi.spyOn(mockSpan, "end").mockImplementation(() => { + throw new Error("end is not a function"); + }); const { request, next } = createTestRequest(); const policy = tracingPolicy(); const expectedError = new RestError("Bad Request.", { statusCode: 400 }); - next.rejects(expectedError); + next.mockRejectedValue(expectedError); // Expect the pipeline request error, _not_ the error that is thrown when ending a span. - await assert.isRejected(policy.sendRequest(request, next), expectedError); + await expect(policy.sendRequest(request, next)).rejects.toThrow(expectedError); }); }); }); diff --git a/sdk/core/ts-http-runtime/test/util.ts b/sdk/core/ts-http-runtime/test/util.ts index a1bd31223cf5..c42fd42c446a 100644 --- a/sdk/core/ts-http-runtime/test/util.ts +++ b/sdk/core/ts-http-runtime/test/util.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { TypeSpecRuntimeLogger } from "../src/logger/logger"; -import { RequestBodyType } from "../src/interfaces"; -import { isNodeReadableStream, isWebReadableStream } from "../src/util/typeGuards"; +import { assert } from "vitest"; +import { TypeSpecRuntimeLogger } from "../src/logger/logger.js"; +import { RequestBodyType } from "../src/interfaces.js"; +import { isNodeReadableStream, isWebReadableStream } from "../src/util/typeGuards.js"; export function makeTestLogger(): { logger: TypeSpecRuntimeLogger; diff --git a/sdk/core/ts-http-runtime/test/util/aborterUtils.spec.ts b/sdk/core/ts-http-runtime/test/util/aborterUtils.spec.ts index 6cd2d073ea54..3f33b4fd92b5 100644 --- a/sdk/core/ts-http-runtime/test/util/aborterUtils.spec.ts +++ b/sdk/core/ts-http-runtime/test/util/aborterUtils.spec.ts @@ -1,14 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as sinon from "sinon"; -import { AbortSignalLike } from "../../src/abort-controller/AbortSignalLike"; -import chai from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { cancelablePromiseRace, createAbortablePromise } from "../../src"; - -chai.use(chaiAsPromised); -const { assert } = chai; +import { describe, it, assert, expect, vi, afterEach } from "vitest"; +import { AbortSignalLike } from "../../src/abort-controller/AbortSignalLike.js"; +import { cancelablePromiseRace, createAbortablePromise } from "../../src/index.js"; describe("createAbortablePromise", function () { let token: ReturnType; @@ -28,16 +23,16 @@ describe("createAbortablePromise", function () { }, ); afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); it("should resolve if not aborted nor rejected", async function () { - const clock = sinon.useFakeTimers(); + const clock = vi.useFakeTimers(); const promise = createPromise(); - const time = await clock.nextAsync(); - clock.restore(); - assert.strictEqual(time, delayTime); - await assert.isFulfilled(promise); + await clock.advanceTimersToNextTimerAsync(); + assert.strictEqual(clock.getTimerCount(), 0); + clock.useRealTimers(); + await expect(promise).resolves.toBeUndefined(); }); it("should reject when aborted", async function () { @@ -48,7 +43,7 @@ describe("createAbortablePromise", function () { abortErrorMsg, }); aborter.abort(); - await assert.isRejected(promise, abortErrorMsg); + await expect(promise).rejects.toThrowError(abortErrorMsg); }); }); diff --git a/sdk/core/ts-http-runtime/test/util/delay.spec.ts b/sdk/core/ts-http-runtime/test/util/delay.spec.ts index 8e589f8e3c34..58cdca118631 100644 --- a/sdk/core/ts-http-runtime/test/util/delay.spec.ts +++ b/sdk/core/ts-http-runtime/test/util/delay.spec.ts @@ -1,22 +1,21 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as sinon from "sinon"; -import { assert } from "chai"; -import { delay } from "../../src"; +import { describe, it, assert, vi, afterEach } from "vitest"; +import { delay } from "../../src/index.js"; describe("delay", function () { afterEach(function () { - sinon.restore(); + vi.useRealTimers(); }); it("should resolve after the given number of ms", async function () { - const clock = sinon.useFakeTimers(); + const clock = vi.useFakeTimers(); const delayTime = 2500; const delayPromise = delay(delayTime); - const time = await clock.nextAsync(); - clock.restore(); - assert.strictEqual(time, delayTime); + await clock.advanceTimersByTimeAsync(delayTime); + assert.strictEqual(clock.getTimerCount(), 0); + clock.useRealTimers(); // should be resolved, so we can await it and it will resolve next tick await delayPromise; }); diff --git a/sdk/core/ts-http-runtime/test/util/sha256.spec.ts b/sdk/core/ts-http-runtime/test/util/sha256.spec.ts index a94014dd6219..3861a6026b52 100644 --- a/sdk/core/ts-http-runtime/test/util/sha256.spec.ts +++ b/sdk/core/ts-http-runtime/test/util/sha256.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { computeSha256Hash, computeSha256Hmac } from "../../src/index"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { computeSha256Hash, computeSha256Hmac } from "../../src/index.js"; describe("SHA-256", function () { describe("Hash", function () { diff --git a/sdk/core/ts-http-runtime/test/util/typeGuards.spec.ts b/sdk/core/ts-http-runtime/test/util/typeGuards.spec.ts index 8fbac859746a..ec1657bea21b 100644 --- a/sdk/core/ts-http-runtime/test/util/typeGuards.spec.ts +++ b/sdk/core/ts-http-runtime/test/util/typeGuards.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { isDefined, isObjectWithProperties, objectHasProperty } from "../../src/index"; -import { assert } from "chai"; +import { describe, it, assert } from "vitest"; +import { isDefined, isObjectWithProperties, objectHasProperty } from "../../src/index.js"; describe("Type guards", function () { describe("isDefined", function () { diff --git a/sdk/core/ts-http-runtime/test/util/uuidUtils.spec.ts b/sdk/core/ts-http-runtime/test/util/uuidUtils.spec.ts index 554b8c9f0690..d31d3250c366 100644 --- a/sdk/core/ts-http-runtime/test/util/uuidUtils.spec.ts +++ b/sdk/core/ts-http-runtime/test/util/uuidUtils.spec.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { assert } from "chai"; -import { randomUUID } from "../../src/util/uuidUtils"; +import { describe, it, assert } from "vitest"; +import { randomUUID } from "../../src/util/uuidUtils.js"; describe("randomUUID", function () { it("should be a valid v4 UUID", function () { diff --git a/sdk/core/ts-http-runtime/ts-http-runtime.shims.d.ts b/sdk/core/ts-http-runtime/ts-http-runtime.shims.d.ts deleted file mode 100644 index 4275edc40123..000000000000 --- a/sdk/core/ts-http-runtime/ts-http-runtime.shims.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -declare global { - interface FormData {} - interface Blob {} - interface File {} - interface ReadableStream {} - interface TransformStream {} -} - -export * from "./types/ts-http-runtime"; diff --git a/sdk/core/ts-http-runtime/tsconfig.browser.config.json b/sdk/core/ts-http-runtime/tsconfig.browser.config.json new file mode 100644 index 000000000000..1b37aebc5457 --- /dev/null +++ b/sdk/core/ts-http-runtime/tsconfig.browser.config.json @@ -0,0 +1,10 @@ +{ + "extends": "./.tshy/build.json", + "include": ["./src/**/*.ts", "./src/**/*.mts", "./test/**/*.spec.ts"], + "exclude": ["./test/**/node/**/*.ts"], + "compilerOptions": { + "outDir": "./dist-test/browser", + "rootDir": ".", + "skipLibCheck": true + } +} diff --git a/sdk/core/ts-http-runtime/tsconfig.json b/sdk/core/ts-http-runtime/tsconfig.json index d918ed0873a1..6fe171774dcf 100644 --- a/sdk/core/ts-http-runtime/tsconfig.json +++ b/sdk/core/ts-http-runtime/tsconfig.json @@ -1,12 +1,13 @@ { "extends": "../../../tsconfig.package", "compilerOptions": { - "outDir": "./dist-esm", - "declarationDir": "./types", "paths": { - "@typespec/ts-http-runtime": ["./src/index"] + "@typespec/ts-http-runtime": ["./src/index.ts"] }, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": ".", "lib": ["dom", "dom.iterable"] }, - "include": ["src/**/*.ts", "test/**/*.ts"] + "include": ["./src/**/*.ts", "./src/**/*.mts", "test/**/*.ts"] } diff --git a/sdk/core/ts-http-runtime/vitest.browser.config.ts b/sdk/core/ts-http-runtime/vitest.browser.config.ts new file mode 100644 index 000000000000..0b05437f23ac --- /dev/null +++ b/sdk/core/ts-http-runtime/vitest.browser.config.ts @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; +import browserMap from "@azure-tools/vite-plugin-browser-test-map"; + +export default defineConfig({ + define: { + "process.env": process.env, + }, + plugins: [browserMap()], + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + browser: { + enabled: true, + headless: true, + name: "chromium", + provider: "playwright", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["dist-test/browser/**/*.spec.js"], + coverage: { + include: ["dist-test/browser/**/*.js"], + exclude: [ + "dist-test/browser/**/*./*-browser.mjs", + "dist-test/browser/**/*./*-react-native.mjs", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage-browser", + }, + }, +}); diff --git a/sdk/core/ts-http-runtime/vitest.config.ts b/sdk/core/ts-http-runtime/vitest.config.ts new file mode 100644 index 000000000000..7c014c00af62 --- /dev/null +++ b/sdk/core/ts-http-runtime/vitest.config.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + reporters: ["basic", "junit"], + outputFile: { + junit: "test-results.browser.xml", + }, + fakeTimers: { + toFake: ["setTimeout", "Date"], + }, + watch: false, + include: ["test/**/*.spec.ts"], + exclude: ["test/**/browser/*.spec.ts"], + coverage: { + include: ["src/**/*.ts"], + exclude: [ + "src/**/*-browser.mts", + "src/**/*-react-native.mts", + "vitest*.config.ts", + "samples-dev/**/*.ts", + ], + provider: "istanbul", + reporter: ["text", "json", "html"], + reportsDirectory: "coverage", + }, + }, +}); diff --git a/sdk/eventhub/event-hubs/perf-tests.yml b/sdk/eventhub/event-hubs/perf-tests.yml index f65e222ef81f..d7617edb39d6 100644 --- a/sdk/eventhub/event-hubs/perf-tests.yml +++ b/sdk/eventhub/event-hubs/perf-tests.yml @@ -5,15 +5,15 @@ Project: sdk/eventhub/perf-tests/event-hubs PrimaryPackage: '@azure/event-hubs' PackageVersions: -- '@azure/event-hubs': 5.8.0 - '@azure/core-amqp': 3.2.0 - '@azure/core-auth': 1.4.0 - '@azure/core-http': 2.3.1 - '@azure/core-rest-pipeline': 1.10.0 +- '@azure/event-hubs': 5.11.3 + '@azure/core-amqp': 4.2.0 + '@azure/core-auth': 1.6.0 + '@azure/core-http': 3.0.4 + '@azure/core-rest-pipeline': 1.14.0 '@azure/core-tracing': 1.0.1 - '@azure/core-util': 1.1.1 - '@azure/abort-controller': 1.1.0 - '@azure/logger': 1.0.3 + '@azure/core-util': 1.7.0 + '@azure/abort-controller': 2.0.0 + '@azure/logger': 1.0.4 - '@azure/event-hubs': source '@azure/core-amqp': source '@azure/core-auth': source diff --git a/sdk/monitor/monitor-opentelemetry/perf-tests.yml b/sdk/monitor/monitor-opentelemetry/perf-tests.yml index acad9c4ae71d..69ac1b243e14 100644 --- a/sdk/monitor/monitor-opentelemetry/perf-tests.yml +++ b/sdk/monitor/monitor-opentelemetry/perf-tests.yml @@ -5,9 +5,9 @@ Project: sdk/monitor/perf-tests/monitor-opentelemetry PrimaryPackage: '@azure/monitor-opentelemetry' PackageVersions: -- '@azure/monitor-opentelemetry': 1.1.1 - "@azure/functions": 3.2.0 - "@azure/monitor-opentelemetry-exporter": 1.0.0-beta.18 +- '@azure/monitor-opentelemetry': 1.2.0 + "@azure/functions": 3.5.1 + "@azure/monitor-opentelemetry-exporter": 1.0.0-beta.19 "@azure/opentelemetry-instrumentation-azure-sdk": 1.0.0-beta.5 - '@azure/monitor-opentelemetry': source "@azure/core-client": source diff --git a/sdk/servicebus/service-bus/perf-tests.yml b/sdk/servicebus/service-bus/perf-tests.yml index 7634a7bf4817..7cc00c4c92b1 100644 --- a/sdk/servicebus/service-bus/perf-tests.yml +++ b/sdk/servicebus/service-bus/perf-tests.yml @@ -5,18 +5,18 @@ Project: sdk/servicebus/perf-tests/service-bus PrimaryPackage: '@azure/service-bus' PackageVersions: -- '@azure/service-bus': 7.7.3 - '@azure/core-amqp': 3.2.1 - '@azure/core-auth': 1.4.0 - '@azure/core-client': 1.6.1 - '@azure/core-http': 2.3.1 - '@azure/core-paging': 1.4.0 - '@azure/core-rest-pipeline': 1.10.0 +- '@azure/service-bus': 7.9.4 + '@azure/core-amqp': 4.2.0 + '@azure/core-auth': 1.6.0 + '@azure/core-client': 1.8.0 + '@azure/core-http': 3.0.4 + '@azure/core-paging': 1.5.0 + '@azure/core-rest-pipeline': 1.14.0 '@azure/core-tracing': 1.0.1 - '@azure/core-util': 1.1.1 - '@azure/core-xml': 1.3.0 - '@azure/abort-controller': 1.1.0 - '@azure/logger': 1.0.3 + '@azure/core-util': 1.7.0 + '@azure/core-xml': 1.3.4 + '@azure/abort-controller': 2.0.0 + '@azure/logger': 1.0.4 - '@azure/service-bus': source '@azure/core-amqp': source '@azure/core-auth': source diff --git a/sdk/storage/perf-tests/storage-blob/test/storageTest.spec.ts b/sdk/storage/perf-tests/storage-blob/test/storageTest.spec.ts index ae2c02aa0d95..811e14b93dee 100644 --- a/sdk/storage/perf-tests/storage-blob/test/storageTest.spec.ts +++ b/sdk/storage/perf-tests/storage-blob/test/storageTest.spec.ts @@ -28,12 +28,13 @@ export abstract class StorageBlobTest extends PerfTest { getValueInConnString(connectionString, "AccountKey"), ); this.blobServiceClient = BlobServiceClient.fromConnectionString(connectionString); - const options = this.configureClientOptions({ additionalPolicies: [] }); + // only meant for core v2, commenting out for now + // const options = this.configureClientOptions({ additionalPolicies: [] }); - const pipeline = this.blobServiceClient["storageClientContext"].pipeline; - for (const { policy } of options.additionalPolicies ?? []) { - pipeline.addPolicy(policy, { afterPhase: "Sign" }); - } + // const pipeline = this.blobServiceClient["storageClientContext"].pipeline; + // for (const { policy } of options.additionalPolicies ?? []) { + // pipeline.addPolicy(policy, { afterPhase: "Sign" }); + // } this.containerClient = this.blobServiceClient.getContainerClient(StorageBlobTest.containerName); } diff --git a/sdk/storage/storage-blob/perf-tests.yml b/sdk/storage/storage-blob/perf-tests.yml index 917511217431..a6aa251ec21d 100644 --- a/sdk/storage/storage-blob/perf-tests.yml +++ b/sdk/storage/storage-blob/perf-tests.yml @@ -5,16 +5,16 @@ Project: sdk/storage/perf-tests/storage-blob PrimaryPackage: '@azure/storage-blob' PackageVersions: -- '@azure/storage-blob': 12.12.0 - '@azure/core-auth': 1.4.0 - '@azure/core-http': 2.3.1 - '@azure/core-lro': 2.4.0 - '@azure/core-paging': 1.4.0 - '@azure/core-rest-pipeline': 1.10.0 +- '@azure/storage-blob': 12.17.0 + '@azure/core-auth': 1.6.0 + '@azure/core-http': 3.0.4 + '@azure/core-lro': 2.6.0 + '@azure/core-paging': 1.5.0 + '@azure/core-rest-pipeline': 1.14.0 '@azure/core-tracing': 1.0.1 - '@azure/core-util': 1.1.1 + '@azure/core-util': 1.7.0 '@azure/abort-controller': 1.1.0 - '@azure/logger': 1.0.3 + '@azure/logger': 1.0.4 - '@azure/storage-blob': source '@azure/core-auth': source '@azure/core-lro': source diff --git a/sdk/storage/storage-file-datalake/perf-tests.yml b/sdk/storage/storage-file-datalake/perf-tests.yml index f522e9986a3e..2d910aeaeda9 100644 --- a/sdk/storage/storage-file-datalake/perf-tests.yml +++ b/sdk/storage/storage-file-datalake/perf-tests.yml @@ -5,17 +5,17 @@ Project: sdk/storage/perf-tests/storage-file-datalake PrimaryPackage: '@azure/storage-file-datalake' PackageVersions: -- '@azure/storage-file-datalake': 12.11.0 - '@azure/storage-blob': 12.12.0 - '@azure/core-auth': 1.4.0 - '@azure/core-http': 2.3.1 - '@azure/core-lro': 2.4.0 - '@azure/core-paging': 1.3.0 - '@azure/core-rest-pipeline': 1.10.0 +- '@azure/storage-file-datalake': 12.16.0 + '@azure/storage-blob': 12.17.0 + '@azure/core-auth': 1.6.0 + '@azure/core-http': 3.0.4 + '@azure/core-lro': 2.6.0 + '@azure/core-paging': 1.5.0 + '@azure/core-rest-pipeline': 1.14.0 '@azure/core-tracing': 1.0.1 - '@azure/core-util': 1.1.1 + '@azure/core-util': 1.7.0 '@azure/abort-controller': 1.1.0 - '@azure/logger': 1.0.3 + '@azure/logger': 1.0.4 - '@azure/storage-file-datalake': source '@azure/storage-blob': source '@azure/core-auth': source diff --git a/sdk/storage/storage-file-share/perf-tests.yml b/sdk/storage/storage-file-share/perf-tests.yml index 6143ad789a0d..0716ba953821 100644 --- a/sdk/storage/storage-file-share/perf-tests.yml +++ b/sdk/storage/storage-file-share/perf-tests.yml @@ -5,15 +5,16 @@ Project: sdk/storage/perf-tests/storage-file-share PrimaryPackage: '@azure/storage-file-share' PackageVersions: -- '@azure/storage-file-share': 12.12.0 - '@azure/core-auth': 1.4.0 - '@azure/core-http': 2.3.1 - '@azure/core-paging': 1.4.0 - '@azure/core-rest-pipeline': 1.10.0 +- '@azure/storage-file-share': 12.17.0 + '@azure/core-auth': 1.6.0 + '@azure/core-http': 3.0.4 + '@azure/core-lro': 2.6.0 + '@azure/core-paging': 1.5.0 + '@azure/core-rest-pipeline': 1.14.0 '@azure/core-tracing': 1.0.1 - '@azure/core-util': 1.1.1 + '@azure/core-util': 1.7.0 '@azure/abort-controller': 1.1.0 - '@azure/logger': 1.0.3 + '@azure/logger': 1.0.4 - '@azure/storage-file-share': source '@azure/core-auth': source '@azure/core-paging': source