diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0f8304009278..c4ce90f55935 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,6 +40,9 @@ # PRLabel: %Batch /sdk/batch/ @xingwu1 @matthchr @bgklein @deyaaeldeen +# PRLabel: %Communication +/sdk/communication/ @RezaJooyandeh @DominikMe @0rland0Wats0n + # PRLabel: %Cosmos /sdk/cosmosdb/ @southpolesteve @zfoster diff --git a/README.md b/README.md index 5fe9bb3d6414..e1f8f7355575 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Packages](https://img.shields.io/badge/packages-latest-blue.svg)](https://azure.github.io/azure-sdk/releases/latest/js.html) [![Dependencies](https://img.shields.io/badge/dependency-report-blue.svg)](https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-js/dependencies/dependencies.html) [![DependencyGraph](https://img.shields.io/badge/dependency-graph-blue.svg)](https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-js/dependencies/InterdependencyGraph.html) -This repository is for active development of the Azure SDK for JavaScript (NodeJS & Browser). For consumers of the SDK we recommend visiting our [public developer docs](https://docs.microsoft.com/en-us/javascript/azure/) or our versioned [developer docs](https://azure.github.io/azure-sdk-for-js). +This repository is for active development of the Azure SDK for JavaScript (NodeJS & Browser). For consumers of the SDK we recommend visiting our [public developer docs](https://docs.microsoft.com/javascript/azure/) or our versioned [developer docs](https://azure.github.io/azure-sdk-for-js). ## Getting started @@ -41,7 +41,7 @@ Libraries which enable you to provision specific resources. They are responsible Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) . You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://www.microsoft.com/msrc/faqs-report-an-issue). ## Contributing -For details on contributing to this repository, see the [contributing guide](CONTRIBUTING.md). +For details on contributing to this repository, see the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md). This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. diff --git a/SECURITY.md b/SECURITY.md index 926b8ae4059a..dec3d3b7013b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. ## Reporting Security Issues @@ -12,7 +12,7 @@ If you believe you have found a security vulnerability in any Microsoft-owned re Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/msrc/pgp-key-msrc). You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). @@ -36,6 +36,6 @@ We prefer all communications to be in English. ## Policy -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/msrc/cvd). diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 0b425bc4d9bb..5885a8121800 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -4,6 +4,10 @@ dependencies: '@rush-temp/ai-form-recognizer': 'file:projects/ai-form-recognizer.tgz' '@rush-temp/ai-text-analytics': 'file:projects/ai-text-analytics.tgz' '@rush-temp/app-configuration': 'file:projects/app-configuration.tgz' + '@rush-temp/communication-administration': 'file:projects/communication-administration.tgz' + '@rush-temp/communication-chat': 'file:projects/communication-chat.tgz' + '@rush-temp/communication-common': 'file:projects/communication-common.tgz' + '@rush-temp/communication-sms': 'file:projects/communication-sms.tgz' '@rush-temp/core-amqp': 'file:projects/core-amqp.tgz' '@rush-temp/core-arm': 'file:projects/core-arm.tgz' '@rush-temp/core-asynciterator-polyfill': 'file:projects/core-asynciterator-polyfill.tgz' @@ -75,6 +79,18 @@ packages: dev: false resolution: integrity: sha512-RVG1Ad3Afv9gwFFmpeCXQAm+Sa0L8KEZRJJAAZEGoYDb6EoO1iQDVmoBz720h8mdrGpi0D60xNU/KhriIwuZfQ== + /@azure/communication-signaling/1.0.0-beta.1: + dependencies: + '@azure/core-http': 1.1.7 + '@azure/logger': 1.0.0 + '@opentelemetry/api': 0.6.1 + events: 3.1.0 + tslib: 1.13.0 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-xxlGwbbTkEZAline8wrP75FLaOsT23nMukzIg5X/Cs6cQSQ/JKj7Uxq5Idxp9GgAYT+g+PAj+BJ929/jaselBQ== /@azure/core-amqp/1.1.4: dependencies: '@azure/abort-controller': 1.0.1 @@ -453,6 +469,19 @@ packages: node: '>=8' resolution: integrity: sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + /@microsoft/api-documenter/7.8.55: + dependencies: + '@microsoft/api-extractor-model': 7.9.6 + '@microsoft/tsdoc': 0.12.19 + '@rushstack/node-core-library': 3.33.5 + '@rushstack/ts-command-line': 4.6.9 + colors: 1.2.5 + js-yaml: 3.13.1 + resolve: 1.17.0 + dev: false + hasBin: true + resolution: + integrity: sha512-NhRc45gUhwZiUzdyA9U5x3A3Ql3nKhu2iBsk5CrguOAtEw/rJ0rGJ9Ufj52V4J+dQ3/itI+sFicReZrXs90Tjg== /@microsoft/api-extractor-model/7.7.10: dependencies: '@microsoft/tsdoc': 0.12.19 @@ -460,6 +489,13 @@ packages: dev: false resolution: integrity: sha512-gMFDXwUgoQYz9TgatyNPALDdZN4xBC3Un3fGwlzME+vM13PoJ26pGuqI7kv/OlK9+q2sgrEdxWns8D3UnLf2TA== + /@microsoft/api-extractor-model/7.9.6: + dependencies: + '@microsoft/tsdoc': 0.12.19 + '@rushstack/node-core-library': 3.33.5 + dev: false + resolution: + integrity: sha512-npGZSgOk1iDre5DbmIZpxAeppsYDCwaRmxNZy8afVOKh0PPiOmnZEUzEyvGCNIQBdHC8B7f8L7qLgLlkm2dq8A== /@microsoft/api-extractor/7.7.11: dependencies: '@microsoft/api-extractor-model': 7.7.10 @@ -646,6 +682,20 @@ packages: dev: false resolution: integrity: sha512-1+FoymIdr9W9k0D8fdZBBPwi5YcMwh/RyESuL5bY29rLICFxSLOPK+ImVZ1OcWj9GEMsvDx5pNpJ311mHQk+MA== + /@rushstack/node-core-library/3.33.5: + dependencies: + '@types/node': 10.17.13 + colors: 1.2.5 + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.17.0 + semver: 7.3.2 + timsort: 0.3.0 + z-schema: 3.18.4 + dev: false + resolution: + integrity: sha512-eUTjIbXuWctD5hULyHn2tIm/SqXNagjqlMfGg28ZeQkcPx4gpNTvJSv2Cau8b8Nco+yblbWVOi/BNCh3+ai3bA== /@rushstack/ts-command-line/4.3.13: dependencies: '@types/argparse': 1.0.33 @@ -654,6 +704,15 @@ packages: dev: false resolution: integrity: sha512-BUBbjYu67NJGQkpHu8aYm7kDoMFizL1qx78+72XE3mX/vDdXYJzw/FWS7TPcMJmY4kNlYs979v2B0Q0qa2wRiw== + /@rushstack/ts-command-line/4.6.9: + dependencies: + '@types/argparse': 1.0.38 + argparse: 1.0.10 + colors: 1.2.5 + string-argv: 0.3.1 + dev: false + resolution: + integrity: sha512-HrwXkKAHMj14ZTH/70AbrR7vpA5CMiE1oKC1F+hDnnyi94bvOGKLRf3mpiynHKWMPJAJrwREP1Lcf3/UBfGWGg== /@sinonjs/commons/1.8.0: dependencies: type-detect: 4.0.8 @@ -689,6 +748,10 @@ packages: dev: false resolution: integrity: sha512-VQgHxyPMTj3hIlq9SY1mctqx+Jj8kpQfoLvDlVSDNOyuYs8JYfkuY3OW/4+dO657yPmNhHpePRx0/Tje5ImNVQ== + /@types/argparse/1.0.38: + dev: false + resolution: + integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== /@types/async-lock/1.1.2: dev: false resolution: @@ -822,6 +885,10 @@ packages: dev: false resolution: integrity: sha512-S0ohSSX8ioT65zu8KbG99xKyFV3InIjbM3c8roYqWy4+5HpYPyUHLYykfhM6MEI5B/3s7KSZPGFyCzCrZ2TOZA== + /@types/jwt-decode/2.2.1: + dev: false + resolution: + integrity: sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A== /@types/long/4.0.1: dev: false resolution: @@ -2651,6 +2718,14 @@ packages: eslint: '>=5.16.0' resolution: integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + /eslint-plugin-prefer-arrow/1.2.2_eslint@6.8.0: + dependencies: + eslint: 6.8.0 + dev: false + peerDependencies: + eslint: '>=2.0.0' + resolution: + integrity: sha512-C8YMhL+r8RMeMdYAw/rQtE6xNdMulj+zGWud/qIGnlmomiPRaLDGLMeskZ3alN6uMBojmooRimtdrXebLN4svQ== /eslint-plugin-prettier/3.1.4_eslint@6.8.0+prettier@1.19.1: dependencies: eslint: 6.8.0 @@ -3793,6 +3868,12 @@ packages: node: '>=6' resolution: integrity: sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + /import-lazy/4.0.0: + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== /imurmurhash/0.1.4: dev: false engines: @@ -4413,6 +4494,10 @@ packages: dev: false resolution: integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + /jwt-decode/2.2.0: + dev: false + resolution: + integrity: sha1-fYa9VmefWM5qhHBKZX3TkruoGnk= /karma-chai/0.1.0_chai@4.2.0+karma@5.1.1: dependencies: chai: 4.2.0 @@ -6918,6 +7003,12 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + /string-argv/0.3.1: + dev: false + engines: + node: '>=0.6.19' + resolution: + integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== /string-width/1.0.2: dependencies: code-point-at: 1.1.0 @@ -8029,7 +8120,7 @@ packages: dev: false name: '@rush-temp/abort-controller' resolution: - integrity: sha512-78SPLuZydRyhpdf4wO9uWQf4g8Ebuk5OZWFKmLKTPk42QJtMJpH9l7X1UXW3nh58BUHYairnIHJ0jamYTC6unw== + integrity: sha512-xM5W0taJ/3c/Rxugc3E+Q0HfRb+CE4yhobdPYaNA2OufzCZMO5OZguDr+cvM52AdLUvNP/M7UUwEljKPJznLeQ== tarball: 'file:projects/abort-controller.tgz' version: 0.0.0 'file:projects/ai-anomaly-detector.tgz': @@ -8268,6 +8359,242 @@ packages: integrity: sha512-o3zyWd0p+Th710h7qEQs8+0UstbL9Vf+kgUNP5amLJDfYh2qfzVA0msroRHAhaM0sRO7BDGXfpkFnU/GUa9PPw== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 + 'file:projects/communication-administration.tgz': + dependencies: + '@azure/core-tracing': 1.0.0-preview.9 + '@microsoft/api-documenter': 7.8.55 + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + cross-env: 7.0.2 + dotenv: 8.2.0 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-prefer-arrow: 1.2.2_eslint@6.8.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-json-preprocessor: 0.3.3_karma@5.1.1 + karma-json-to-file-reporter: 1.0.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + node-fetch: 2.6.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + dev: false + name: '@rush-temp/communication-administration' + resolution: + integrity: sha512-7R+ATtNKPhFhlmIncfs+zLaZOT8K8gYG4OZQxeU4Q1w6upb6D3hLROYRHj7peUOkJ1uqr3/Kq+JetTCzG1uRnQ== + tarball: 'file:projects/communication-administration.tgz' + version: 0.0.0 + 'file:projects/communication-chat.tgz': + dependencies: + '@azure/communication-signaling': 1.0.0-beta.1 + '@azure/core-tracing': 1.0.0-preview.9 + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + cross-env: 7.0.2 + dotenv: 8.2.0 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-json-preprocessor: 0.3.3_karma@5.1.1 + karma-json-to-file-reporter: 1.0.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + util: 0.12.3 + dev: false + name: '@rush-temp/communication-chat' + resolution: + integrity: sha512-GqsE5L/Y6v/ZUWjHu/1cEqSgdbVOwyH7bq3Bc1MFtaTz5hYyE1MlXTgMkKijZqUzJR8ETbPtv6YhCM8oISqHgw== + tarball: 'file:projects/communication-chat.tgz' + version: 0.0.0 + 'file:projects/communication-common.tgz': + dependencies: + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/chai-as-promised': 7.1.3 + '@types/jwt-decode': 2.2.1 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + chai-as-promised: 7.1.1_chai@4.2.0 + cross-env: 7.0.2 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + jwt-decode: 2.2.0 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + util: 0.12.3 + dev: false + name: '@rush-temp/communication-common' + resolution: + integrity: sha512-zDlM6WQ2IuIfgNEtzboy0XkFyD/iq/sroDDE7ZoSjUeUvd1NC6r4gf9Sie4IhaNZDDD5iwICBuq2AsNOvogtLw== + tarball: 'file:projects/communication-common.tgz' + version: 0.0.0 + 'file:projects/communication-sms.tgz': + dependencies: + '@azure/core-tracing': 1.0.0-preview.9 + '@microsoft/api-extractor': 7.7.11 + '@opentelemetry/api': 0.10.2 + '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 + '@rollup/plugin-json': 4.1.0_rollup@1.32.1 + '@rollup/plugin-multi-entry': 3.0.1_rollup@1.32.1 + '@rollup/plugin-node-resolve': 8.1.0_rollup@1.32.1 + '@rollup/plugin-replace': 2.3.3_rollup@1.32.1 + '@types/chai': 4.2.11 + '@types/mocha': 7.0.2 + '@types/node': 8.10.61 + '@types/sinon': 9.0.4 + '@typescript-eslint/eslint-plugin': 2.34.0_3787943315ebc5ea524d5c102dc9e452 + '@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.6 + assert: 1.5.0 + chai: 4.2.0 + cross-env: 7.0.2 + dotenv: 8.2.0 + eslint: 6.8.0 + eslint-config-prettier: 6.11.0_eslint@6.8.0 + eslint-plugin-no-null: 1.0.2_eslint@6.8.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 + events: 3.1.0 + inherits: 2.0.4 + karma: 5.1.1 + karma-chrome-launcher: 3.1.0 + karma-coverage: 2.0.2 + karma-edge-launcher: 0.4.2_karma@5.1.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-ie-launcher: 1.0.0_karma@5.1.1 + karma-junit-reporter: 2.0.1_karma@5.1.1 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@5.1.1 + karma-remap-istanbul: 0.6.0_karma@5.1.1 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + prettier: 1.19.1 + rimraf: 3.0.2 + rollup: 1.32.1 + rollup-plugin-shim: 1.0.0 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.32.1 + rollup-plugin-terser: 5.3.0_rollup@1.32.1 + rollup-plugin-visualizer: 4.0.4_rollup@1.32.1 + sinon: 9.0.2 + tslib: 2.0.0 + typescript: 3.9.6 + util: 0.12.3 + dev: false + name: '@rush-temp/communication-sms' + resolution: + integrity: sha512-lQoSU2BOticoPyB2JTgjCp7Mxe34Y/0wDBPBcgyxB42A/YM0R0ZoMuELN7AFJ/XEMzCWLIIqVMDMLPCQtgNbxQ== + tarball: 'file:projects/communication-sms.tgz' + version: 0.0.0 'file:projects/core-amqp.tgz': dependencies: '@azure/identity': 1.1.0 @@ -8836,7 +9163,7 @@ packages: dev: false name: '@rush-temp/cosmos' resolution: - integrity: sha512-n2thQR98RdP6LVfeW9NbiW787UK+JJjZEe7JbgMqbrehiMCBynmPkEY38rgYhlklxwpQDPS8nUir1NFNZlx/fQ== + integrity: sha512-tkGeW5NMFi/1REwH/01mOKnzGUXyCBs8Zjq28esn6R0pA1vUhoNjVp4bqojqGogYme0SHdqNnWgDjFh+y0OLqQ== tarball: 'file:projects/cosmos.tgz' version: 0.0.0 'file:projects/data-tables.tgz': @@ -10493,6 +10820,10 @@ specifiers: '@rush-temp/ai-form-recognizer': 'file:./projects/ai-form-recognizer.tgz' '@rush-temp/ai-text-analytics': 'file:./projects/ai-text-analytics.tgz' '@rush-temp/app-configuration': 'file:./projects/app-configuration.tgz' + '@rush-temp/communication-administration': 'file:./projects/communication-administration.tgz' + '@rush-temp/communication-chat': 'file:./projects/communication-chat.tgz' + '@rush-temp/communication-common': 'file:./projects/communication-common.tgz' + '@rush-temp/communication-sms': 'file:./projects/communication-sms.tgz' '@rush-temp/core-amqp': 'file:./projects/core-amqp.tgz' '@rush-temp/core-arm': 'file:./projects/core-arm.tgz' '@rush-temp/core-asynciterator-polyfill': 'file:./projects/core-asynciterator-polyfill.tgz' diff --git a/common/smoke-test/README.md b/common/smoke-test/README.md index f38e97f4b10d..4d4136d5fe97 100644 --- a/common/smoke-test/README.md +++ b/common/smoke-test/README.md @@ -5,7 +5,7 @@ uses package dependencies, loads all packages into a single process, and executes code samples to ensure basic end to end scenarios work as expected. Smoke Tests are meant to be run periodically in an Azure DevOps pipeline. See -[`smoke-tests.yml`](./smoke-tests.yml) to configure Smoke Tests in an Azure +[`smoke-tests.yml`](https://github.com/Azure/azure-sdk-for-js/blob/master/common/smoke-test/smoke-tests.yml) to configure Smoke Tests in an Azure DevOps pipeline. When run in an Azure DevOps pipeline specify the `-CI` flag to ensure environment variables are properly set and error/warning messages are properly surfaced during the execution. @@ -23,7 +23,7 @@ package. - AAD Application with `Owner` permissions to an Azure subscription - PowerShell 7 - Node 12.x -- Azure SDK for JS [`dev-tool`](../tools/dev-tool) +- Azure SDK for JS [`dev-tool`](https://github.com/Azure/azure-sdk-for-js/blob/master/common/tools/dev-tool) ## Configuring Samples diff --git a/common/tools/eslint-plugin-azure-sdk/package.json b/common/tools/eslint-plugin-azure-sdk/package.json index 44bd6d4b2183..7127890b56db 100644 --- a/common/tools/eslint-plugin-azure-sdk/package.json +++ b/common/tools/eslint-plugin-azure-sdk/package.json @@ -21,14 +21,14 @@ } ], "license": "MIT", - "homepage": "https://github.com/Azure/azure-sdk-tools/tree/master/tools/eslint-plugin-azure-sdk", + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/common/tools/eslint-plugin-azure-sdk", "repository": { "type": "git", - "url": "https://github.com/Azure/azure-sdk-tools.git", - "directory": "tools/eslint-plugin-azure-sdk" + "url": "https://github.com/Azure/azure-sdk-for-js.git", + "directory": "common/tools/eslint-plugin-azure-sdk" }, "bugs": { - "url": "https://github.com/Azure/azure-sdk-tools/issues" + "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, "main": "dist/index.js", "files": [ diff --git a/common/tools/eslint-plugin-azure-sdk/src/utils/metadata.ts b/common/tools/eslint-plugin-azure-sdk/src/utils/metadata.ts index f849aa75f257..e4e67fd677da 100644 --- a/common/tools/eslint-plugin-azure-sdk/src/utils/metadata.ts +++ b/common/tools/eslint-plugin-azure-sdk/src/utils/metadata.ts @@ -19,7 +19,7 @@ export const getRuleMetaData = ( description: ruleDescription, category: "Best Practices", recommended: true, - url: `https://github.com/Azure/azure-sdk-tools/blob/master/tools/eslint-plugin-azure-sdk/docs/rules/${ruleName}.md` + url: `https://github.com/Azure/azure-sdk-for-js/tree/master/common/tools/eslint-plugin-azure-sdk/docs/rules/${ruleName}.md` }, schema: [] }; diff --git a/documentation/Bundling.md b/documentation/Bundling.md index af10e646ab15..a521dacbb853 100644 --- a/documentation/Bundling.md +++ b/documentation/Bundling.md @@ -365,7 +365,7 @@ Once this is done, you can use parcel by configuring your project in the way tha ### Parcel with Javascript -Parcel uses [browserslist](https://github.com/browserslist/browserslist) to configure what polyfills are needed when bundling. Azure SDK libraries generally target the ES2015 version of JavaScript and use some modern features of JavaScript, including [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*), so let's edit `package.json` to target the latest version of three popular browsers: +Parcel uses [browserslist](https://github.com/browserslist/browserslist) to configure what polyfills are needed when bundling. Azure SDK libraries generally target the ES2015 version of JavaScript and use some modern features of JavaScript, including [generators](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function*), so let's edit `package.json` to target the latest version of three popular browsers: ```json "browserslist": [ @@ -413,7 +413,7 @@ This will emit a compiled version of `index.html`, as well as any included scrip ### Parcel with TypeScript -Parcel uses [browserslist](https://github.com/browserslist/browserslist) to configure what polyfills are needed when bundling. The Azure SDK uses some modern features of JavaScript, including [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function), so let's edit `package.json` to target the latest version of three popular browsers: +Parcel uses [browserslist](https://github.com/browserslist/browserslist) to configure what polyfills are needed when bundling. The Azure SDK uses some modern features of JavaScript, including [async functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function), so let's edit `package.json` to target the latest version of three popular browsers: ```json "browserslist": [ diff --git a/documentation/using-azure-identity.md b/documentation/using-azure-identity.md index 46a5c364e1b9..b32edfe0b715 100644 --- a/documentation/using-azure-identity.md +++ b/documentation/using-azure-identity.md @@ -2,10 +2,10 @@ This document intends to demystify the configuration and use of [Microsoft identity -platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/), +platform](https://docs.microsoft.com/azure/active-directory/develop/), also known as Azure Active Directory v2, with the Azure SDK libraries. Microsoft identity platform implements the [OAuth 2.0 and OpenID Connect -standards](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols) +standards](https://docs.microsoft.com/azure/active-directory/develop/active-directory-v2-protocols) to provide authentication for users and services who may be granted access to Azure services. @@ -26,12 +26,12 @@ tenant. A "tenant" is basically instance of Azure Active Directory associated with your Azure account. You can follow the instructions on [this quick start guide for setting up a -tenant](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-create-new-tenant) +tenant](https://docs.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant) to check if you have AAD tenant already or, if not, create one. Once you have a tenant, you can create an app registration by following [this quickstart guide for app -registrations](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). +registrations](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app). Your app registration holds the configuration for how your application will authenticate users and services, so it's very important to it set up correctly before using any of the credential types below. The section on each credential @@ -47,7 +47,7 @@ inside of your AAD tenant or if you'd like other organizations and individuals to use it. The [app registration quickstart -guide](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app#register-a-new-application-using-the-azure-portal) +guide](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app#register-a-new-application-using-the-azure-portal) gives a helpful breakdown for the various tenancy options in the "Supported account types" documentation. @@ -62,7 +62,7 @@ serve different use cases and application types. A primary differentiator between these flows is whether the "client" that initiates the flow is running on a user device or on a system managed by the application developer (like a web server). The [Microsoft Authentication -Library](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-client-applications) +Library](https://docs.microsoft.com/azure/active-directory/develop/msal-client-applications) documentation describes this distinction as _public_ versus _confidential_ clients. @@ -70,7 +70,7 @@ Most of the credential types are strictly public or confidential as they serve a specific purpose, like authenticating a backend service for use with storage APIs. Some credentials may be both public or confidential depending on how you configure them. For example, the [authorization code -flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) +flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) can be initiated from a mobile application _or_ from within a web application running in a server. @@ -106,7 +106,7 @@ environment?** The identity platform provides an authorization model for Azure services with [two types of -permissions](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#troubleshooting-permissions-and-consent): +permissions](https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#troubleshooting-permissions-and-consent): - **Application permissions** authorize an application to access resources directly. Administrator consent must be granted to your application. @@ -120,7 +120,7 @@ with a _public credential_, you must configure API permissions for the Azure service you need to access (Key Vault, Storage, etc) so that user accounts can be authorized to use them through your application. The [quick start guide for configuring API -permissions](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis) +permissions](https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-access-web-apis) explains how to do this in detail. ### User-Granted Consent @@ -130,19 +130,19 @@ delegated permissions, they may be presented with a consent screen that asks whether they want to grant your application permission to access resources on their behalf. An example of this consent flow can be found in the [consent framework documentation -page](https://docs.microsoft.com/en-us/azure/active-directory/develop/consent-framework). +page](https://docs.microsoft.com/azure/active-directory/develop/consent-framework). An administrator can also grant consent for your application on behalf of all users. In this case, users may never see a consent screen. If you'd like to make it easy for an administrator to grant access to all users, follow the instructions in the [admin consent endpoint request -documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#request-the-permissions-from-a-directory-admin). +documentation](https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#request-the-permissions-from-a-directory-admin). There are some cases where a user may not be allowed to grant consent to an application. When this occurs, the user may have to speak with an administrator to have the permissions granted on their behalf. The [user consent troubleshooting -page](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-sign-in-unexpected-user-consent-error) +page](https://docs.microsoft.com/azure/active-directory/manage-apps/application-sign-in-unexpected-user-consent-error) provides more details on the consent errors a user might encounter. ## Credential Types in @azure/identity @@ -150,7 +150,7 @@ provides more details on the consent errors a user might encounter. ### ClientSecretCredential and ClientCertificateCredential The `ClientSecretCredential` implements the [client credentials -flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) +flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) to enable confidential clients, like web services, to access Azure resources. To use this credential, you will need to create a client secret using the "Certificates & secrets" page for your app registration. @@ -159,7 +159,7 @@ The `ClientCertificateCredential` implements the same client credentials flow, but instead uses a certificate as the means to authenticate the client. You must must generate your own PEM-formatted certificate for use in this flow and then [register -it](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad) +it](https://docs.microsoft.com/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad) in the "Certificates & secrets" page for your app registration. Using a certificate to authenticate is recommended as it is generally more secure than using a client secret. @@ -174,7 +174,7 @@ on which credential you are using. ### UsernamePasswordCredential The `UsernamePasswordCredential` follows the [resource owner password credential -flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc) +flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth-ropc) to authenticate public or confidential clients. To use this credential, you will need the `tenantId` and `clientId` of your app and a `username` and `password` of the user you are authenticating. @@ -193,7 +193,7 @@ directly is a major security risk. > NOTE: This credential type does not work with personal Microsoft accounts or > multi-factor authentication at this time. See the -> [documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc) +> [documentation](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth-ropc) > for more information. ### EnvironmentCredential @@ -228,7 +228,7 @@ application to learn how to configure environment variables for your deployment. The `ManagedIdentityCredential` takes advantage of authentication endpoints that are hosted within the virtual network of applications deployed to Azure virtual machines, App Services, Functions, Container Services, [and -more](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities). +more](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities). One important distinction of this credential compared to the others is that it _does not require an app registration_. This authentication scheme relates to @@ -240,10 +240,10 @@ to grant one of two types of managed identity to the resource that runs your code: - A [system-assigned - identity](https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity#adding-a-system-assigned-identity) + identity](https://docs.microsoft.com/azure/app-service/overview-managed-identity#adding-a-system-assigned-identity) which uniquely identifies your resource - A [user-assigned - identity](https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity#adding-a-user-assigned-identity) + identity](https://docs.microsoft.com/azure/app-service/overview-managed-identity#adding-a-user-assigned-identity) which can be assigned to your resource (and others) Once your resource has an identity assigned, that identity can be granted access @@ -256,15 +256,15 @@ the managed identity you wish to use for authentication. More information on configuring and using managed identities can be found in the [Managed identities for Azure -resources](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) +resources](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview) documentation. There is also a [list of Azure -services](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities#azure-services-that-support-azure-ad-authentication) +services](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities#azure-services-that-support-azure-ad-authentication) that have been tested to confirm support for managed identity authentication. ### InteractiveBrowserCredential The `InteractiveBrowserCredential` follows the [implicit grant -flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow) +flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-implicit-grant-flow) which enables authentication for clients that run completely in the browser. It is primarily useful for single-page web applications (SPAs) which need to authenticate to access Azure resources and APIs directly. @@ -285,7 +285,7 @@ creating an `InteractiveBrowserCredential`. ### DeviceCodeCredential The `DeviceCodeCredential` follows the [device code authorization -flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code) +flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-device-code) which enables input-constrained devices, like TVs or IoT devices, to authenticate by having the user enter a provided "device code" into an authorization site that the user visits on another device. @@ -297,7 +297,7 @@ section of the **Authentication** page of your app registration. ### AuthorizationCodeCredential The `AuthorizationCodeCredential` follows the [authorization code -flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) +flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) which enables server-hosted web applications, native desktop and mobile applications, and web APIs to access resources on the user's behalf. diff --git a/eng/.docsettings.yml b/eng/.docsettings.yml index 586305ee5d71..2a61957e3f61 100644 --- a/eng/.docsettings.yml +++ b/eng/.docsettings.yml @@ -3,6 +3,7 @@ omitted_paths: - eng/* - sdk/*/arm-* - sdk/cognitiveservices/* + - sdk/communication/*/test/README.md - sdk/identity/identity/test/manual/* - sdk/identity/identity/test/manual-integration/* - sdk/test-utils/perfstress/README.md diff --git a/eng/common/pipelines/templates/steps/create-pull-request.yml b/eng/common/pipelines/templates/steps/create-pull-request.yml index a60d26c8fe98..836ad4b3604b 100644 --- a/eng/common/pipelines/templates/steps/create-pull-request.yml +++ b/eng/common/pipelines/templates/steps/create-pull-request.yml @@ -15,6 +15,7 @@ parameters: ScriptDirectory: eng/common/scripts GHReviewersVariable: '' GHTeamReviewersVariable: '' + GHAssignessVariable: '' # Multiple labels seperated by comma, e.g. "bug, APIView" PRLabels: '' @@ -75,19 +76,6 @@ steps: -PRTitle "${{ parameters.PRTitle }}" -PRBody "${{ coalesce(parameters.PRBody, parameters.CommitMsg, parameters.PRTitle) }}" -PRLabels "${{ parameters.PRLabels}}" - -- task: PowerShell@2 - displayName: Tag a Reviewer on PR - condition: and(succeeded(), eq(variables['HasChanges'], 'true')) - continueOnError: true - inputs: - pwsh: true - workingDirectory: ${{ parameters.WorkingDirectory }} - filePath: ${{ parameters.ScriptDirectory }}/add-pullrequest-reviewers.ps1 - arguments: > - -RepoOwner "${{ parameters.RepoOwner }}" - -RepoName "$(RepoNameWithoutOwner)" - -AuthToken "$(azuresdk-github-pat)" - -GitHubUsers "$(${{ parameters.GHReviewersVariable }})" - -GitHubTeams "$(${{ parameters.GHTeamReviewersVariable }})" - -PRNumber "$(Submitted.PullRequest.Number)" + -UserReviewers "$(${{ parameters.GHReviewersVariable }})" + -TeamReviewers "$(${{ parameters.GHTeamReviewersVariable }})" + -Assignees "$(${{ parameters.GHAssignessVariable }})" \ No newline at end of file diff --git a/eng/common/scripts/Submit-PullRequest.ps1 b/eng/common/scripts/Submit-PullRequest.ps1 index 7f3f0a544e9a..c5eb19b3ca45 100644 --- a/eng/common/scripts/Submit-PullRequest.ps1 +++ b/eng/common/scripts/Submit-PullRequest.ps1 @@ -49,40 +49,64 @@ param( [string]$PRBody = $PRTitle, [Parameter(Mandatory = $false)] - [string]$PRLabels + [string]$PRLabels, + + [Parameter(Mandatory = $false)] + [string]$UserReviewers, + + [Parameter(Mandatory = $false)] + [string]$TeamReviewers, + + [Parameter(Mandatory = $false)] + [string]$Assignees ) $headers = @{ Authorization = "bearer $AuthToken" } +$baseURI = "https://api.github.com/repos" +function SplitMembers ($membersString) +{ + return @($membersString.Split(",") | % { $_.Trim() } | ? { return $_ }) +} -$query = "state=open&head=${PROwner}:${PRBranch}&base=${BaseBranch}" +function InvokeGitHubAPI($apiURI, $method, $body) { + $resp = Invoke-RestMethod -Method $method -Headers $headers -Body ($body | ConvertTo-Json) -Uri $apiURI -MaximumRetryCount 3 + Write-Host -f green "These members have been added to: https://github.com/$RepoOwner/$RepoName/pull/$prNumber" + ($body | Format-List | Write-Output) + $resp | Write-Verbose +} -function AddLabels([int] $prNumber, [string] $prLabelString) -{ - # Adding labels to the pr. - if (-not $prLabelString) { - Write-Verbose "There are no labels added to the PR." - return +function AddReviewers ($prNumber, $users, $teams) { + $uri = "$baseURI/$RepoOwner/$RepoName/pulls/$prNumber/requested_reviewers" + $userAdditions = SplitMembers -membersString $users + $teamAdditions = SplitMembers -membersString $teams + $postResp = @{} + if ($userAdditions) { + $postResp["reviewers"] = @($userAdditions) } - - # Parse the labels from string to array - $prLabelArray = @($prLabelString.Split(",") | % { $_.Trim() } | ? { return $_ }) - $prLabelUri = "https://api.github.com/repos/$RepoOwner/$RepoName/issues/$prNumber" - $labelRequestData = @{ - labels = $prLabelArray + if ($teamAdditions) { + $postResp["team_reviewers"] = @($teamAdditions) } - try { - $resp = Invoke-RestMethod -Method PATCH -Headers $headers $prLabelUri -Body ($labelRequestData | ConvertTo-Json) + return InvokeGitHubAPI -apiURI $uri -method 'Post' -body $postResp +} + +function AddLabelsAndOrAssignees ($prNumber, $labels, $assignees) { + $uri = "$baseURI/$RepoOwner/$RepoName/issues/$prNumber" + $labelAdditions = SplitMembers -membersString $labels + $assigneeAdditions = SplitMembers -membersString $assignees + $postResp = @{} + if ($assigneeAdditions) { + $postResp["assignees"] = @($assigneeAdditions) } - catch { - Write-Error "Invoke-RestMethod $prLabelUri failed with exception:`n$_" + if ($labelAdditions) { + $postResp["labels"] = @($labelAdditions) } - - $resp | Write-Verbose - Write-Host -f green "Label(s) [$prLabelArray] added to pull request: https://github.com/$RepoOwner/$RepoName/pull/$prNumber" + return InvokeGitHubAPI -apiURI $uri -method 'Post' -body $postResp } +$query = "state=open&head=${PROwner}:${PRBranch}&base=${BaseBranch}" + try { $resp = Invoke-RestMethod -Headers $headers "https://api.github.com/repos/$RepoOwner/$RepoName/pulls?$query" } @@ -93,11 +117,18 @@ catch { $resp | Write-Verbose if ($resp.Count -gt 0) { + try { Write-Host -f green "Pull request already exists $($resp[0].html_url)" # setting variable to reference the pull request by number Write-Host "##vso[task.setvariable variable=Submitted.PullRequest.Number]$($resp[0].number)" - AddLabels $resp[0].number $PRLabels + AddReviewers -prNumber $resp[0].number -users $UserReviewers -teams $TeamReviewers + AddLabelsAndOrAssignees -prNumber $resp[0].number -labels $PRLabels -assignees $Assignees + } + catch { + Write-Error "Call to GitHub API failed with exception:`n$_" + exit 1 + } } else { $data = @{ @@ -112,17 +143,17 @@ else { $resp = Invoke-RestMethod -Method POST -Headers $headers ` "https://api.github.com/repos/$RepoOwner/$RepoName/pulls" ` -Body ($data | ConvertTo-Json) + + $resp | Write-Verbose + Write-Host -f green "Pull request created https://github.com/$RepoOwner/$RepoName/pull/$($resp.number)" + + # setting variable to reference the pull request by number + Write-Host "##vso[task.setvariable variable=Submitted.PullRequest.Number]$($resp.number)" + AddReviewers -prNumber $resp.number -users $UserReviewers -teams $TeamReviewers + AddLabelsAndOrAssignees -prNumber $resp.number -labels $PRLabels -assignees $Assignees } catch { - Write-Error "Invoke-RestMethod [https://api.github.com/repos/$RepoOwner/$RepoName/pulls] failed with exception:`n$_" + Write-Error "Call to GitHub API failed with exception:`n$_" exit 1 } - - $resp | Write-Verbose - Write-Host -f green "Pull request created https://github.com/$RepoOwner/$RepoName/pull/$($resp.number)" - - # setting variable to reference the pull request by number - Write-Host "##vso[task.setvariable variable=Submitted.PullRequest.Number]$($resp.number)" - - AddLabels $resp.number $PRLabels -} +} \ No newline at end of file diff --git a/eng/common/scripts/add-pullrequest-reviewers.ps1 b/eng/common/scripts/add-pullrequest-reviewers.ps1 deleted file mode 100644 index 3198dcb40d2c..000000000000 --- a/eng/common/scripts/add-pullrequest-reviewers.ps1 +++ /dev/null @@ -1,61 +0,0 @@ -param( - [Parameter(Mandatory = $true)] - $RepoOwner, - - [Parameter(Mandatory = $true)] - $RepoName, - - [Parameter(Mandatory = $false)] - $GitHubUsers = "", - - [Parameter(Mandatory = $false)] - $GitHubTeams = "", - - [Parameter(Mandatory = $true)] - $PRNumber, - - [Parameter(Mandatory = $true)] - $AuthToken -) - -function AddMembers($memberName, $additionSet) { - $headers = @{ - Authorization = "bearer $AuthToken" - } - $uri = "https://api.github.com/repos/$RepoOwner/$RepoName/pulls/$PRNumber/requested_reviewers" - $errorOccurred = $false - - foreach ($id in $additionSet) { - try { - $postResp = @{} - $postResp[$memberName] = @($id) - $postResp = $postResp | ConvertTo-Json - - Write-Host $postResp - $resp = Invoke-RestMethod -Method Post -Headers $headers -Body $postResp -Uri $uri -MaximumRetryCount 3 - $resp | Write-Verbose - } - catch { - Write-Host "Error attempting to add $user `n$_" - $errorOccurred = $true - } - } - - return $errorOccurred -} - -# at least one of these needs to be populated -if (-not $GitHubUsers -and -not $GitHubTeams) { - Write-Host "No user provided for addition, exiting." - exit 0 -} - -$userAdditions = @($GitHubUsers.Split(",") | % { $_.Trim() } | ? { return $_ }) -$teamAdditions = @($GitHubTeams.Split(",") | % { $_.Trim() } | ? { return $_ }) - -$errorsOccurredAddingUsers = AddMembers -memberName "reviewers" -additionSet $userAdditions -$errorsOccurredAddingTeams = AddMembers -memberName "team_reviewers" -additionSet $teamAdditions - -if ($errorsOccurredAddingUsers -or $errorsOccurredAddingTeams) { - exit 1 -} diff --git a/eng/common/scripts/copy-docs-to-blobstorage.ps1 b/eng/common/scripts/copy-docs-to-blobstorage.ps1 index 9b7dea48b1d5..64bfab444411 100644 --- a/eng/common/scripts/copy-docs-to-blobstorage.ps1 +++ b/eng/common/scripts/copy-docs-to-blobstorage.ps1 @@ -257,30 +257,31 @@ if ($Language -eq "javascript") if ($Language -eq "dotnet") { - $PublishedPkgs = Get-ChildItem "$($DocLocation)/packages" | Where-Object -FilterScript {$_.Name.EndsWith(".nupkg") -and -not $_.Name.EndsWith(".symbols.nupkg")} - $PublishedDocs = Get-ChildItem "$($DocLocation)" | Where-Object -FilterScript {$_.Name.StartsWith("Docs.")} + $PublishedPkgs = Get-ChildItem "$($DocLocation)" | Where-Object -FilterScript {$_.Name.EndsWith(".nupkg") -and -not $_.Name.EndsWith(".symbols.nupkg")} + $PublishedDocs = Get-ChildItem "$($DocLocation)" | Where-Object -FilterScript {$_.Name.EndsWith("docs.zip")} - foreach ($Item in $PublishedDocs) { - $PkgName = $Item.Name.Remove(0, 5) - $PkgFullName = $PublishedPkgs | Where-Object -FilterScript {$_.Name -match "$($PkgName).\d"} - - if (($PkgFullName | Measure-Object).count -eq 1) - { - $DocVersion = $PkgFullName[0].BaseName.Remove(0, $PkgName.Length + 1) - - Write-Host "Start Upload for $($PkgName)/$($DocVersion)" - Write-Host "DocDir $($Item)" - Write-Host "PkgName $($PkgName)" - Write-Host "DocVersion $($DocVersion)" - $releaseTag = RetrieveReleaseTag "Nuget" $PublicArtifactLocation - Upload-Blobs -DocDir "$($Item)" -PkgName $PkgName -DocVersion $DocVersion -ReleaseTag $releaseTag - } - else - { - Write-Host "Package with the same name Exists. Upload Skipped" - continue - } + if (($PublishedPkgs.Count -gt 1) -or ($PublishedDoc.Count -gt 1)) + { + Write-Host "$($DocLocation) should contain only one (1) published package and docs" + Write-Host "No of Packages $($PublishedPkgs.Count)" + Write-Host "No of Docs $($PublishedDoc.Count)" + exit 1 } + + $DocsStagingDir = "$WorkingDirectory/docstaging" + $TempDir = "$WorkingDirectory/temp" + + New-Item -ItemType directory -Path $DocsStagingDir + New-Item -ItemType directory -Path $TempDir + + Expand-Archive -LiteralPath $PublishedDocs[0].FullName -DestinationPath $DocsStagingDir + $pkgProperties = ParseNugetPackage -pkg $PublishedPkgs[0].FullName -workingDirectory $TempDir + + Write-Host "Start Upload for $($pkgProperties.ReleaseTag)" + Write-Host "DocDir $($DocsStagingDir)" + Write-Host "PkgName $($pkgProperties.PackageId)" + Write-Host "DocVersion $($pkgProperties.PackageVersion)" + Upload-Blobs -DocDir "$($DocsStagingDir)" -PkgName $pkgProperties.PackageId -DocVersion $pkgProperties.PackageVersion -ReleaseTag $pkgProperties.ReleaseTag } if ($Language -eq "python") diff --git a/eng/common/scripts/get-pr-creator.ps1 b/eng/common/scripts/get-pr-creator.ps1 new file mode 100644 index 000000000000..23a1f28c6e21 --- /dev/null +++ b/eng/common/scripts/get-pr-creator.ps1 @@ -0,0 +1,37 @@ +param ( + [Parameter(Mandatory = $true)] + [string]$RepoOwner, + + [Parameter(Mandatory = $true)] + [string]$RepoName, + + [Parameter(Mandatory = $true)] + $PullRequestNumber, + + [Parameter(Mandatory = $true)] + $VsoPRCreatorVariable, + + [Parameter(Mandatory = $false)] + $AuthToken +) + +$headers = @{ } + +if ($AuthToken) { + $headers = @{ + Authorization = "bearer $AuthToken" + } +} + +try +{ + $prApiUrl = "https://api.github.com/repos/$RepoOwner/$RepoName/pulls/${PullRequestNumber}" + $response = Invoke-RestMethod -Headers $headers $prApiUrl + Write-Host "##vso[task.setvariable variable=$VsoPRCreatorVariable;]$($response.user.login)" +} +catch +{ + Write-Error "Invoke-RestMethod ${prApiUrl} failed with exception:`n$_" + exit 1 +} + diff --git a/eng/pipelines/aggregate-reports.yml b/eng/pipelines/aggregate-reports.yml index 947dcc40c871..294712a62d55 100644 --- a/eng/pipelines/aggregate-reports.yml +++ b/eng/pipelines/aggregate-reports.yml @@ -23,7 +23,8 @@ jobs: - template: ../common/pipelines/templates/steps/verify-links.yml parameters: Directory: "" - + CheckLinkGuidance: $true + - script: 'npm ci' workingDirectory: '$(Build.SourcesDirectory)/eng/tools/analyze-deps' displayName: 'Install tool dependencies' diff --git a/eng/pipelines/templates/steps/analyze.yml b/eng/pipelines/templates/steps/analyze.yml index 2e274370299f..3a3ff719c5a1 100644 --- a/eng/pipelines/templates/steps/analyze.yml +++ b/eng/pipelines/templates/steps/analyze.yml @@ -23,6 +23,7 @@ steps: - template: ../../../common/pipelines/templates/steps/verify-links.yml parameters: Directory: sdk/${{ parameters.ServiceDirectory }} + CheckLinkGuidance: $true - script: | npm ci @@ -49,11 +50,11 @@ steps: displayName: "Audit libraries" - ${{ each artifact in parameters.Artifacts }}: - - template: /eng/common/pipelines/templates/steps/verify-changelog.yml - parameters: - PackageName: ${{artifact.name}} - ServiceName: ${{parameters.ServiceDirectory}} - ForRelease: false + - template: /eng/common/pipelines/templates/steps/verify-changelog.yml + parameters: + PackageName: ${{artifact.name}} + ServiceName: ${{parameters.ServiceDirectory}} + ForRelease: false - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 # ComponentGovernance is currently unable to run on pull requests of public projects. Running on non-PR diff --git a/eng/pipelines/templates/steps/build.yml b/eng/pipelines/templates/steps/build.yml index 54ef9c530112..3fc74e6d0f1b 100644 --- a/eng/pipelines/templates/steps/build.yml +++ b/eng/pipelines/templates/steps/build.yml @@ -23,13 +23,6 @@ steps: condition: and(succeeded(),ne(variables['SetDevVersion'],'true')) displayName: "Install dependencies" - - template: /eng/common/pipelines/templates/steps/replace-relative-links.yml - parameters: - TargetFolder: $(Build.SourcesDirectory)/sdk/$(folder) - RootFolder: $(Build.SourcesDirectory) - BuildSHA: $(Build.SourceVersion) - RepoId: "Azure/azure-sdk-for-js" - # Option "-p max" ensures parallelism is set to the number of cores on all platforms, which improves build times. # The default on Windows is "cores - 1" (microsoft/rushstack#436). - script: | @@ -37,7 +30,7 @@ steps: displayName: "Build libraries" - pwsh: | - eng/tools/check-api-warning.ps1 + eng/tools/check-api-warning.ps1 displayName: "Check api extractor output changes" - script: | diff --git a/eng/pipelines/templates/steps/test.yml b/eng/pipelines/templates/steps/test.yml index 4ba60e080cd2..0e1b1b857d73 100644 --- a/eng/pipelines/templates/steps/test.yml +++ b/eng/pipelines/templates/steps/test.yml @@ -1,7 +1,7 @@ parameters: Artifacts: [] ServiceDirectory: not-specified - + steps: - script: | node common/scripts/install-run-rush.js install @@ -27,7 +27,7 @@ steps: node eng/tools/rush-runner.js unit-test:node "${{parameters.ServiceDirectory}}" --verbose -p max displayName: "Test libraries" condition: and(succeeded(),eq(variables['TestType'], 'node')) - + # Option "-p max" ensures parallelism is set to the number of cores on all platforms, which improves build times. # The default on Windows is "cores - 1" (microsoft/rushstack#436). - script: | @@ -56,7 +56,7 @@ steps: # PublishTestResults.searchFolder only supports absolute paths, not relative. - task: PublishTestResults@2 inputs: - searchFolder: '$(System.DefaultWorkingDirectory)/sdk' + searchFolder: "$(System.DefaultWorkingDirectory)/sdk" testResultsFiles: "**/test-results.xml" testRunTitle: "$(OSName) - NodeJS - Unit Tests - [Node $(NodeTestVersion)]" condition: and(always(),eq(variables['TestType'], 'node')) @@ -66,7 +66,7 @@ steps: # PublishTestResults.searchFolder only supports absolute paths, not relative. - task: PublishTestResults@2 inputs: - searchFolder: '$(System.DefaultWorkingDirectory)/sdk' + searchFolder: "$(System.DefaultWorkingDirectory)/sdk" testResultsFiles: "**/test-results.browser.xml" testRunTitle: "$(OSName) - Browser - Unit Tests - [Node $(NodeTestVersion)]" condition: and(always(),eq(variables['TestType'], 'browser')) diff --git a/eng/tools/generate-static-index/service-mapper.json b/eng/tools/generate-static-index/service-mapper.json index 6eea5e2ab086..4df0efc39f34 100644 --- a/eng/tools/generate-static-index/service-mapper.json +++ b/eng/tools/generate-static-index/service-mapper.json @@ -14,6 +14,7 @@ "botservice": "Bot Service", "cdn": "CDN", "cognitiveservices": "Cognitive Services", + "communication": "Communication", "commerce": "Commerce", "compute": "Compute", "consumption": "Consumption", diff --git a/rush.json b/rush.json index c816a9e34d11..299959b1616c 100644 --- a/rush.json +++ b/rush.json @@ -352,6 +352,26 @@ "projectFolder": "sdk/search/search-documents", "versionPolicyName": "client" }, + { + "packageName": "@azure/communication-administration", + "projectFolder": "sdk/communication/communication-administration", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/communication-chat", + "projectFolder": "sdk/communication/communication-chat", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/communication-common", + "projectFolder": "sdk/communication/communication-common", + "versionPolicyName": "client" + }, + { + "packageName": "@azure/communication-sms", + "projectFolder": "sdk/communication/communication-sms", + "versionPolicyName": "client" + }, { "packageName": "@azure/core-amqp", "projectFolder": "sdk/core/core-amqp", diff --git a/sdk/anomalydetector/ai-anomaly-detector/CHANGELOG.md b/sdk/anomalydetector/ai-anomaly-detector/CHANGELOG.md index c4d90d152ed9..150c86f2d487 100644 --- a/sdk/anomalydetector/ai-anomaly-detector/CHANGELOG.md +++ b/sdk/anomalydetector/ai-anomaly-detector/CHANGELOG.md @@ -1,8 +1,12 @@ # Release History -## 3.0.0-preview.2 (Unreleased) +## 3.0.0-beta.3 (Unreleased) +## 3.0.0-beta.2 (2020-09-18) + +- Fix missing types in package [#10916](https://github.com/Azure/azure-sdk-for-js/pull/10916) + ## 3.0.0-preview.1 (2020-08-27) - This release is a preview of our efforts to create a client library that is user friendly and diff --git a/sdk/anomalydetector/ai-anomaly-detector/README.md b/sdk/anomalydetector/ai-anomaly-detector/README.md index 9173e3d1e8be..be8219e991d0 100644 --- a/sdk/anomalydetector/ai-anomaly-detector/README.md +++ b/sdk/anomalydetector/ai-anomaly-detector/README.md @@ -5,12 +5,16 @@ [Source code](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/anomalydetector/ai-anomaly-detector/) | [Package (NPM)](https://www.npmjs.com/package/@azure/ai-anomaly-detector) | [API reference documentation](https://aka.ms/azsdk/net/docs/ref/anomalydetector) | -[Product documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/anomaly-detector/) |[Samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/anomalydetector/ai-anomaly-detector/samples) +[Product documentation](https://docs.microsoft.com/azure/cognitive-services/anomaly-detector/) | [Samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/anomalydetector/ai-anomaly-detector/samples) ## Key concepts -Coming soon (#10865) +The `AnomalyDetectorClient` provides methods for anomaly detection: + +- `detectEntireSeries` - Detects anomalies on an entire data set +- `detectLastPoint` - Detects anomalies in the latest data point +- `detectChangePoint` - Evaluates change point score of every series point ## Getting started @@ -20,8 +24,8 @@ Coming soon (#10865) ### Prerequisites -- An [Azure subscription][azure_sub]. -- An existing [Cognitive Services][cognitive_resource] or Anomaly Detector resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. +- An [Azure subscription](https://azure.microsoft.com/free/). +- An existing Anomaly Detector resource. If you use the Azure CLI, replace `` and `` with your own unique names: @@ -41,7 +45,7 @@ npm install @azure/ai-anomaly-detector To create a client object to access the Anomaly Detector API, you will need the `endpoint` of your Anomaly Detector resource and a `credential`. The Anomaly Detector client can use either Azure Active Directory credentials or an API key credential to authenticate. -You can find the endpoint for your Anomaly Detector resource either in the [Azure Portal][azure_portal] or by using the [Azure CLI][azure_cli] snippet below: +You can find the endpoint for your Anomaly Detector resource in the Azure Portal by clicking `Keys and Endpoint` under Resource Management in the menu or by using the Azure CLI snippet below: ```bash az cognitiveservices account show --name --resource-group --query "endpoint" @@ -49,7 +53,7 @@ az cognitiveservices account show --name --resource-group < #### Using an API Key -Use the [Azure Portal][azure_portal] to browse to your Anomaly Detector resource and retrieve an API key, or use the [Azure CLI][azure_cli] snippet below: +Use the Azure Portal to browse to your Anomaly Detector resource and retrieve an API key by clicking `Keys and Endpoint` under Resource Management, or use the Azure CLI snippet below: **Note:** Sometimes the API key is referred to as a "subscription key" or "subscription API key." @@ -67,14 +71,14 @@ const client = new AnomalyDetectorClient("", new AzureKeyCredential("< #### Using an Azure Active Directory Credential -Client API key authentication is used in most of the examples, but you can also authenticate with Azure Active Directory using the [Azure Identity library][azure_identity]. To use the [DefaultAzureCredential][defaultazurecredential] provider shown below, +Client API key authentication is used in most of the examples, but you can also authenticate with Azure Active Directory using the [Azure Identity library]. To use the DefaultAzureCredential provider shown below, or other credential providers provided with the Azure SDK, please install the `@azure/identity` package: ```bash npm install @azure/identity ``` -You will also need to [register a new AAD application][register_aad_app] and grant access to Anomaly Detector by assigning the `"Cognitive Services User"` role to your service principal (note: other roles such as `"Owner"` will not grant the necessary permissions, only `"Cognitive Services User"` will suffice to run the examples and the sample code). +You will also need to register a new AAD application and grant access to Anomaly Detector by assigning the `"Cognitive Services User"` role to your service principal (note: other roles such as `"Owner"` will not grant the necessary permissions, only `"Cognitive Services User"` will suffice to run the examples and the sample code). Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET`. @@ -87,7 +91,69 @@ const client = new AnomalyDetectorClient("", new DefaultAzureCredentia ## Examples -Coming soon (#10865) +### Detect Change Points + +This sample demonstrates how to detect change points on entire series. + +```javascript +const { AnomalyDetectorClient, TimeGranularity } = require("@azure/ai-anomaly-detector"); +const { AzureKeyCredential } = require("@azure/core-auth"); + +// You will need to set this environment variables in .env file or edit the following values +const apiKey = process.env["API_KEY"] || ""; +const endpoint = process.env["ENDPOINT"] || ""; + +async function main() { + // create client + const client = new AnomalyDetectorClient(endpoint, new AzureKeyCredential(apiKey)); + + // construct request + const request = { + series: [ + { timestamp: new Date("2018-03-01T00:00:00Z"), value: 32858923 }, + { timestamp: new Date("2018-03-02T00:00:00Z"), value: 29615278 }, + { timestamp: new Date("2018-03-03T00:00:00Z"), value: 22839355 }, + { timestamp: new Date("2018-03-04T00:00:00Z"), value: 25948736 }, + { timestamp: new Date("2018-03-05T00:00:00Z"), value: 34139159 }, + { timestamp: new Date("2018-03-06T00:00:00Z"), value: 33843985 }, + { timestamp: new Date("2018-03-07T00:00:00Z"), value: 33637661 }, + { timestamp: new Date("2018-03-08T00:00:00Z"), value: 32627350 }, + { timestamp: new Date("2018-03-09T00:00:00Z"), value: 29881076 }, + { timestamp: new Date("2018-03-10T00:00:00Z"), value: 22681575 }, + { timestamp: new Date("2018-03-11T00:00:00Z"), value: 24629393 }, + { timestamp: new Date("2018-03-12T00:00:00Z"), value: 34010679 }, + { timestamp: new Date("2018-03-13T00:00:00Z"), value: 33893888 }, + { timestamp: new Date("2018-03-14T00:00:00Z"), value: 33760076 }, + { timestamp: new Date("2018-03-15T00:00:00Z"), value: 33093515 } + ], + granularity: TimeGranularity.daily + }; + + // get change point detect results + const result = await client.detectChangePoint(request); + const isChangePointDetected = result.isChangePoint.some((changePoint) => changePoint); + + if (isChangePointDetected) { + console.log("Change points were detected from the series at index:"); + result.isChangePoint.forEach((changePoint, index) => { + if (changePoint === true) { + console.log(index); + } + }); + } else { + console.log("There is no change point detected from the series."); + } + // output: + // Change points were detected from the series at index: + // 9 +} + +main().catch((err) => { + console.error("The sample encountered an error:", err); +}); +``` + +More Samples can be found [here](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/anomalydetector/ai-anomaly-detector/samples) ## Troubleshooting diff --git a/sdk/anomalydetector/ai-anomaly-detector/package.json b/sdk/anomalydetector/ai-anomaly-detector/package.json index 59c6e9048bab..9297043552f3 100644 --- a/sdk/anomalydetector/ai-anomaly-detector/package.json +++ b/sdk/anomalydetector/ai-anomaly-detector/package.json @@ -1,6 +1,6 @@ { "name": "@azure/ai-anomaly-detector", - "version": "3.0.0-preview.2", + "version": "3.0.0-beta.3", "description": "An isomorphic client library for the Azure Anomaly Detector service.", "sdk-type": "client", "main": "dist/index.js", diff --git a/sdk/anomalydetector/ai-anomaly-detector/src/constants.ts b/sdk/anomalydetector/ai-anomaly-detector/src/constants.ts index f2775bb63784..6641e5d73063 100644 --- a/sdk/anomalydetector/ai-anomaly-detector/src/constants.ts +++ b/sdk/anomalydetector/ai-anomaly-detector/src/constants.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export const SDK_VERSION: string = "3.0.0-preview.2"; +export const SDK_VERSION: string = "3.0.0-beta.3"; export const DEFAULT_COGNITIVE_SCOPE = "https://cognitiveservices.azure.com/.default"; diff --git a/sdk/anomalydetector/ai-anomaly-detector/src/generated/generatedClientContext.ts b/sdk/anomalydetector/ai-anomaly-detector/src/generated/generatedClientContext.ts index 9c8416d5dd9a..a14774cead09 100644 --- a/sdk/anomalydetector/ai-anomaly-detector/src/generated/generatedClientContext.ts +++ b/sdk/anomalydetector/ai-anomaly-detector/src/generated/generatedClientContext.ts @@ -10,7 +10,7 @@ import * as coreHttp from "@azure/core-http"; import { GeneratedClientOptionalParams } from "./models"; const packageName = "@azure/ai-form-recognizer"; -const packageVersion = "3.0.0-preview.2"; +const packageVersion = "3.0.0-beta.3"; export class GeneratedClientContext extends coreHttp.ServiceClient { endpoint: string; diff --git a/sdk/appconfiguration/app-configuration/README.md b/sdk/appconfiguration/app-configuration/README.md index 0fbe9d7c3645..2e9e3e4de436 100644 --- a/sdk/appconfiguration/app-configuration/README.md +++ b/sdk/appconfiguration/app-configuration/README.md @@ -1,6 +1,6 @@ # App Configuration client library for JavaScript -[Azure App Configuration](https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview) is a managed service that helps developers centralize their application and feature settings simply and securely. +[Azure App Configuration](https://docs.microsoft.com/azure/azure-app-configuration/overview) is a managed service that helps developers centralize their application and feature settings simply and securely. Use the client library for App Configuration to: @@ -11,7 +11,7 @@ Use the client library for App Configuration to: [Source code](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/appconfiguration/app-configuration/) | [Package (NPM)](https://www.npmjs.com/package/@azure/app-configuration) | [API reference documentation](https://docs.microsoft.com/javascript/api/@azure/app-configuration) | -[Product documentation](https://docs.microsoft.com/en-us/azure/azure-app-configuration/) | +[Product documentation](https://docs.microsoft.com/azure/azure-app-configuration/) | [Samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples) ## Getting started @@ -24,7 +24,7 @@ npm install @azure/app-configuration ### Prerequisites -- You must have an [Azure Subscription](https://azure.microsoft.com) and an [App Configuration](https://docs.microsoft.com/en-us/azure/azure-app-configuration/) resource to use this package. +- You must have an [Azure Subscription](https://azure.microsoft.com) and an [App Configuration](https://docs.microsoft.com/azure/azure-app-configuration/) resource to use this package. - Node.js version 8.x.x or higher ### Create an App Configuration resource @@ -134,7 +134,7 @@ async function run() { value: "testvalue", // Labels allow you to create variants of a key tailored // for specific use-cases like supporting multiple environments. - // https://docs.microsoft.com/en-us/azure/azure-app-configuration/concept-key-value#label-keys + // https://docs.microsoft.com/azure/azure-app-configuration/concept-key-value#label-keys label: "optional-label" }); @@ -181,6 +181,6 @@ folder for more details. ## Related projects - [Microsoft Azure SDK for JavaScript](https://github.com/Azure/azure-sdk-for-js) -- [Azure App Configuration](https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview) +- [Azure App Configuration](https://docs.microsoft.com/azure/azure-app-configuration/overview) ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fappconfiguration%2Fapp-configuration%2FREADME.png) diff --git a/sdk/appconfiguration/app-configuration/test/README.md b/sdk/appconfiguration/app-configuration/test/README.md index 36f4b682f04b..326060770fb5 100644 --- a/sdk/appconfiguration/app-configuration/test/README.md +++ b/sdk/appconfiguration/app-configuration/test/README.md @@ -6,7 +6,7 @@ You can use existing Azure resources for the live tests, or generate new ones by The Azure resource that is used by the tests in this project is: -- An [Azure App Configuration](https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview). Your Azure application needs to be assigned as the **owner** of this Azure App Configuration resource. The steps are provided [below](#AAD-based-authentication). +- An [Azure App Configuration](https://docs.microsoft.com/azure/azure-app-configuration/overview). Your Azure application needs to be assigned as the **owner** of this Azure App Configuration resource. The steps are provided [below](#AAD-based-authentication). To run the live tests, you will also need to set the below environment variables: @@ -25,7 +25,7 @@ The following steps will help you setup the AAD credentials. ### Register a new application in AAD -- Follow [Documentation to register a new application](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) in the Azure Active Directory (in the Azure portal). +- Follow [Documentation to register a new application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app) in the Azure Active Directory (in the Azure portal). - Note down the `CLIENT_ID` and `TENANT_ID`. - In the "Certificates & Secrets" tab, create a secret and note that down. @@ -34,6 +34,6 @@ The following steps will help you setup the AAD credentials. - In the Azure portal, go to your Azure App Configuration and assign the **Owner** role to the registered application. - This can be done from `Role assignment` section of `Access control (IAM)` tab (in the left-side-navbar of your Azure App Configuration in the Azure portal)
_Doing this would allow the registered application manage the resource, i.e., entity creation, deletion, etc.,_
-- For more information on securing your Azure App Configuration: [Learn more](https://docs.microsoft.com/en-us/azure/event-hubs/authorize-access-event-hubs) +- For more information on securing your Azure App Configuration: [Learn more](https://docs.microsoft.com/azure/event-hubs/authorize-access-event-hubs) ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fappconfiguration%2Fapp-configuration%2Ftest%2FREADME.png) diff --git a/sdk/cognitiveservices/cognitiveservices-anomalydetector/README.md b/sdk/cognitiveservices/cognitiveservices-anomalydetector/README.md index ab8ee82f328d..324f5088e7b0 100644 --- a/sdk/cognitiveservices/cognitiveservices-anomalydetector/README.md +++ b/sdk/cognitiveservices/cognitiveservices-anomalydetector/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample determines anamolies with the given time series. To know more, refer to the [Azure Documentation on Anomaly Detectors](https://docs.microsoft.com/en-us/azure/cognitive-services/anomaly-detector/) +The following sample determines anamolies with the given time series. To know more, refer to the [Azure Documentation on Anomaly Detectors](https://docs.microsoft.com/azure/cognitive-services/anomaly-detector/) ```javascript const { AnomalyDetectorClient } = require("@azure/cognitiveservices-anomalydetector"); diff --git a/sdk/cognitiveservices/cognitiveservices-autosuggest/README.md b/sdk/cognitiveservices/cognitiveservices-autosuggest/README.md index fcaa3fdd2575..a89833079014 100644 --- a/sdk/cognitiveservices/cognitiveservices-autosuggest/README.md +++ b/sdk/cognitiveservices/cognitiveservices-autosuggest/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample gets suggestions from Bing for the given query **Microsoft Azure**. To know more, refer to the [Azure Documentation on Bing Auto Suggest](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-autosuggest/) +The following sample gets suggestions from Bing for the given query **Microsoft Azure**. To know more, refer to the [Azure Documentation on Bing Auto Suggest](https://docs.microsoft.com/azure/cognitive-services/bing-autosuggest/) ```javascript const { AutoSuggestClient } = require("@azure/cognitiveservices-autosuggest"); diff --git a/sdk/cognitiveservices/cognitiveservices-computervision/README.md b/sdk/cognitiveservices/cognitiveservices-computervision/README.md index ac8de3afbaff..e4067518d8f2 100644 --- a/sdk/cognitiveservices/cognitiveservices-computervision/README.md +++ b/sdk/cognitiveservices/cognitiveservices-computervision/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample describes a given image using Computer Vision. To know more, refer to the [Azure Documentation on Computer Vision](https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/home) +The following sample describes a given image using Computer Vision. To know more, refer to the [Azure Documentation on Computer Vision](https://docs.microsoft.com/azure/cognitive-services/computer-vision/home) ```javascript const { ComputerVisionClient } = require("@azure/cognitiveservices-computervision"); @@ -38,7 +38,7 @@ async function main() { const client = new ComputerVisionClient(cognitiveServiceCredentials, computerVisionEndPoint); const url = - "https://docs.microsoft.com/en-us/azure/includes/media/shared-image-galleries/shared-image-gallery.png"; + "https://docs.microsoft.com/azure/includes/media/shared-image-galleries/shared-image-gallery.png"; const options = { maxCandidates: 5, language: "en" @@ -85,7 +85,7 @@ main(); ); const url = - "https://docs.microsoft.com/en-us/azure/includes/media/shared-image-galleries/shared-image-gallery.png"; + "https://docs.microsoft.com/azure/includes/media/shared-image-galleries/shared-image-gallery.png"; const options = { maxCandidates: 5, language: "en" diff --git a/sdk/cognitiveservices/cognitiveservices-contentmoderator/README.md b/sdk/cognitiveservices/cognitiveservices-contentmoderator/README.md index 66686180ab95..675c7e9e6cbc 100644 --- a/sdk/cognitiveservices/cognitiveservices-contentmoderator/README.md +++ b/sdk/cognitiveservices/cognitiveservices-contentmoderator/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample detects the langauge of text provided using text moderator APIs. To know more, refer to the [Azure Documentation on Content Moderator](https://docs.microsoft.com/en-us/azure/cognitive-services/content-moderator/overview) +The following sample detects the langauge of text provided using text moderator APIs. To know more, refer to the [Azure Documentation on Content Moderator](https://docs.microsoft.com/azure/cognitive-services/content-moderator/overview) ```javascript const { ContentModeratorClient } = require("@azure/cognitiveservices-contentmoderator"); diff --git a/sdk/cognitiveservices/cognitiveservices-customimagesearch/README.md b/sdk/cognitiveservices/cognitiveservices-customimagesearch/README.md index 9f7975ddcc49..fa09f23ffd87 100644 --- a/sdk/cognitiveservices/cognitiveservices-customimagesearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-customimagesearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs an image search for given query on a custom configuration. The custom configuration can be setup using the Custom search portal. To know more, refer to the [Azure Documentation on Bing Custom Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-custom-search/) +The following sample performs an image search for given query on a custom configuration. The custom configuration can be setup using the Custom search portal. To know more, refer to the [Azure Documentation on Bing Custom Search](https://docs.microsoft.com/azure/cognitive-services/bing-custom-search/) ```javascript const { CustomImageSearchClient } = require("@azure/cognitiveservices-customimagesearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-customsearch/README.md b/sdk/cognitiveservices/cognitiveservices-customsearch/README.md index e9ba05319682..b0279049acc4 100644 --- a/sdk/cognitiveservices/cognitiveservices-customsearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-customsearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a search for given query on a custom configuration. The custom configuration can be setup using the Custom search portal. To know more, refer to the [Azure Documentation Bing Custom Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-custom-search/) +The following sample performs a search for given query on a custom configuration. The custom configuration can be setup using the Custom search portal. To know more, refer to the [Azure Documentation Bing Custom Search](https://docs.microsoft.com/azure/cognitive-services/bing-custom-search/) ```javascript const { CustomSearchClient } = require("@azure/cognitiveservices-customsearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-customvision-prediction/README.md b/sdk/cognitiveservices/cognitiveservices-customvision-prediction/README.md index 8c5f3297f711..c77450f79c73 100644 --- a/sdk/cognitiveservices/cognitiveservices-customvision-prediction/README.md +++ b/sdk/cognitiveservices/cognitiveservices-customvision-prediction/README.md @@ -18,7 +18,7 @@ npm install @azure/cognitiveservices-customvision-prediction #### nodejs - Authentication, client creation and classifyImageUrl as an example written in TypeScript. ##### Sample code -The following sample predicts and classifies the given image based on your custom vision training. To know more, refer to the [Azure Documentation on Custom Vision Services](https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/home). +The following sample predicts and classifies the given image based on your custom vision training. To know more, refer to the [Azure Documentation on Custom Vision Services](https://docs.microsoft.com/azure/cognitive-services/custom-vision-service/home). ```javascript const { PredictionAPIClient } = require("@azure/cognitiveservices-customvision-prediction"); diff --git a/sdk/cognitiveservices/cognitiveservices-customvision-training/README.md b/sdk/cognitiveservices/cognitiveservices-customvision-training/README.md index ad6fd5500992..b80ad980a2c9 100644 --- a/sdk/cognitiveservices/cognitiveservices-customvision-training/README.md +++ b/sdk/cognitiveservices/cognitiveservices-customvision-training/README.md @@ -18,7 +18,7 @@ npm install @azure/cognitiveservices-customvision-training #### nodejs - Authentication, client creation and getDomains as an example written in TypeScript. ##### Sample code -The following sample performs a quick test of the given image based on your custom vision training. To know more, refer to the [Azure Documentation on Custom Vision Services](https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/home). +The following sample performs a quick test of the given image based on your custom vision training. To know more, refer to the [Azure Documentation on Custom Vision Services](https://docs.microsoft.com/azure/cognitive-services/custom-vision-service/home). ```javascript const { TrainingAPIClient } = require("@azure/cognitiveservices-customvision-training"); diff --git a/sdk/cognitiveservices/cognitiveservices-entitysearch/README.md b/sdk/cognitiveservices/cognitiveservices-entitysearch/README.md index 239d2dd110ef..0ff80a675085 100644 --- a/sdk/cognitiveservices/cognitiveservices-entitysearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-entitysearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a Bing entity search on the query 'Microsoft Azure'. To know more, refer to the [Azure Documentation on Bing Entities Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-entities-search/). +The following sample performs a Bing entity search on the query 'Microsoft Azure'. To know more, refer to the [Azure Documentation on Bing Entities Search](https://docs.microsoft.com/azure/cognitive-services/bing-entities-search/). ```javascript const { EntitySearchClient } = require("@azure/cognitiveservices-entitysearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-face/README.md b/sdk/cognitiveservices/cognitiveservices-face/README.md index 70aa7c627b16..343c6a481fcb 100644 --- a/sdk/cognitiveservices/cognitiveservices-face/README.md +++ b/sdk/cognitiveservices/cognitiveservices-face/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample detects the facial features on the given image. To know more, refer to the [Azure Documentation on Face APIs](https://docs.microsoft.com/en-us/azure/cognitive-services/face/overview) +The following sample detects the facial features on the given image. To know more, refer to the [Azure Documentation on Face APIs](https://docs.microsoft.com/azure/cognitive-services/face/overview) ```javascript const { FaceClient, FaceModels } = require("@azure/cognitiveservices-face"); diff --git a/sdk/cognitiveservices/cognitiveservices-formrecognizer/README.md b/sdk/cognitiveservices/cognitiveservices-formrecognizer/README.md index c5733dce02a3..34713e316ae2 100644 --- a/sdk/cognitiveservices/cognitiveservices-formrecognizer/README.md +++ b/sdk/cognitiveservices/cognitiveservices-formrecognizer/README.md @@ -25,7 +25,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample reads the scanned copy of a sample receipt. To know more, refer to the [Azure Documentation on Form Recognizer](https://docs.microsoft.com/en-us/azure/cognitive-services/form-recognizer/overview) +The following sample reads the scanned copy of a sample receipt. To know more, refer to the [Azure Documentation on Form Recognizer](https://docs.microsoft.com/azure/cognitive-services/form-recognizer/overview) ```javascript const { FormRecognizerClient } = require("@azure/cognitiveservices-formrecognizer"); diff --git a/sdk/cognitiveservices/cognitiveservices-imagesearch/README.md b/sdk/cognitiveservices/cognitiveservices-imagesearch/README.md index b057feeb6bd8..4cca4e181aa7 100644 --- a/sdk/cognitiveservices/cognitiveservices-imagesearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-imagesearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs an image search for 'Microsoft Azure' with conditions such as the color has to be 'Monochrome', etc. To know more, refer to the [Azure Documentation on Bing Image Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-image-search/) +The following sample performs an image search for 'Microsoft Azure' with conditions such as the color has to be 'Monochrome', etc. To know more, refer to the [Azure Documentation on Bing Image Search](https://docs.microsoft.com/azure/cognitive-services/bing-image-search/) ```javascript const { ImageSearchClient } = require("@azure/cognitiveservices-imagesearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-localsearch/README.md b/sdk/cognitiveservices/cognitiveservices-localsearch/README.md index 6efb2cc4c7ca..1807e8d9e6d3 100644 --- a/sdk/cognitiveservices/cognitiveservices-localsearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-localsearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs an local business search with the query 'Coffee 98052'. To know more, refer to the [Azure Documentation on Bing Local Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-local-business-search/) +The following sample performs an local business search with the query 'Coffee 98052'. To know more, refer to the [Azure Documentation on Bing Local Search](https://docs.microsoft.com/azure/cognitive-services/bing-local-business-search/) ```javascript const { LocalSearchClient } = require("@azure/cognitiveservices-localsearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-luis-authoring/README.md b/sdk/cognitiveservices/cognitiveservices-luis-authoring/README.md index 73d1087aeca6..7c5bfb93e503 100644 --- a/sdk/cognitiveservices/cognitiveservices-luis-authoring/README.md +++ b/sdk/cognitiveservices/cognitiveservices-luis-authoring/README.md @@ -38,7 +38,7 @@ let authoringKey = process.env["luis-authoring-key"]; const creds = new CognitiveServicesCredentials(authoringKey); // check the following link to find your region -// https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-regions +// https://docs.microsoft.com/azure/cognitive-services/luis/luis-reference-regions const region = ""; const client = new LUISAuthoringClient( creds, diff --git a/sdk/cognitiveservices/cognitiveservices-luis-runtime/README.md b/sdk/cognitiveservices/cognitiveservices-luis-runtime/README.md index 79401dd898b8..9e49103ae3a1 100644 --- a/sdk/cognitiveservices/cognitiveservices-luis-runtime/README.md +++ b/sdk/cognitiveservices/cognitiveservices-luis-runtime/README.md @@ -33,7 +33,7 @@ let authoringKey = process.env["luis-authoring-key"]; const creds = new CognitiveServicesCredentials(authoringKey); // check the following link to find your region -// https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-regions +// https://docs.microsoft.com/azure/cognitive-services/luis/luis-reference-regions const region = ""; const client = new LUISRuntimeClient(creds, "https://" + region + ".api.cognitive.microsoft.com/"); @@ -103,7 +103,7 @@ client.prediction // check the following link to find your region - // https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-regions + // https://docs.microsoft.com/azure/cognitive-services/luis/luis-reference-regions const region = ""; const client = new Azure.CognitiveservicesLuisRuntime.LUISRuntimeClient( creds, diff --git a/sdk/cognitiveservices/cognitiveservices-newssearch/README.md b/sdk/cognitiveservices/cognitiveservices-newssearch/README.md index edfd67088a2b..4fdb76150b9f 100644 --- a/sdk/cognitiveservices/cognitiveservices-newssearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-newssearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a news search on 'Microsoft Azure' with conditions such as the freshness must be within a Month, etc. To know more, refer to the [Azure Documentation on Bing News Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-news-search/) +The following sample performs a news search on 'Microsoft Azure' with conditions such as the freshness must be within a Month, etc. To know more, refer to the [Azure Documentation on Bing News Search](https://docs.microsoft.com/azure/cognitive-services/bing-news-search/) ```javascript const { NewsSearchClient } = require("@azure/cognitiveservices-newssearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-personalizer/README.md b/sdk/cognitiveservices/cognitiveservices-personalizer/README.md index 751a43fe9d7e..f96361cdb7d1 100644 --- a/sdk/cognitiveservices/cognitiveservices-personalizer/README.md +++ b/sdk/cognitiveservices/cognitiveservices-personalizer/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample ranks a personalized request object. To know more, refer to the [Azure Documentation on Personalizer](https://docs.microsoft.com/en-us/azure/cognitive-services/personalizer/) +The following sample ranks a personalized request object. To know more, refer to the [Azure Documentation on Personalizer](https://docs.microsoft.com/azure/cognitive-services/personalizer/) ```javascript const { PersonalizerClient } = require("@azure/cognitiveservices-personalizer"); diff --git a/sdk/cognitiveservices/cognitiveservices-spellcheck/README.md b/sdk/cognitiveservices/cognitiveservices-spellcheck/README.md index 2c03234aaf84..5d27845f565a 100644 --- a/sdk/cognitiveservices/cognitiveservices-spellcheck/README.md +++ b/sdk/cognitiveservices/cognitiveservices-spellcheck/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a spell check on the text - 'Bill Gatos'. The result will return a suggestion of 'Gates'. To know more, refer to the [Azure Documentation on Spell Check](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-spell-check/) +The following sample performs a spell check on the text - 'Bill Gatos'. The result will return a suggestion of 'Gates'. To know more, refer to the [Azure Documentation on Spell Check](https://docs.microsoft.com/azure/cognitive-services/bing-spell-check/) ```javascript const { SpellCheckClient } = require("@azure/cognitiveservices-spellcheck"); diff --git a/sdk/cognitiveservices/cognitiveservices-textanalytics/README.md b/sdk/cognitiveservices/cognitiveservices-textanalytics/README.md index 5420a1c3de5d..905442972f0d 100644 --- a/sdk/cognitiveservices/cognitiveservices-textanalytics/README.md +++ b/sdk/cognitiveservices/cognitiveservices-textanalytics/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample detects the langauge in the provided text. In addition, it provides data such as Characters count, transaction count, etc. To know more, refer to the [Azure Documentation on Text Analytics](https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview) +The following sample detects the langauge in the provided text. In addition, it provides data such as Characters count, transaction count, etc. To know more, refer to the [Azure Documentation on Text Analytics](https://docs.microsoft.com/azure/cognitive-services/text-analytics/overview) ```javascript const { TextAnalyticsClient } = require("@azure/cognitiveservices-textanalytics"); diff --git a/sdk/cognitiveservices/cognitiveservices-translatortext/README.md b/sdk/cognitiveservices/cognitiveservices-translatortext/README.md index 4fa7533bb4bd..ca96ca922c45 100644 --- a/sdk/cognitiveservices/cognitiveservices-translatortext/README.md +++ b/sdk/cognitiveservices/cognitiveservices-translatortext/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample translates the given text which is in Chinese to English. To know more, refer to the [Azure Documentation on Translator](https://docs.microsoft.com/en-us/azure/cognitive-services/translator/) +The following sample translates the given text which is in Chinese to English. To know more, refer to the [Azure Documentation on Translator](https://docs.microsoft.com/azure/cognitive-services/translator/) ```javascript const { TranslatorTextClient } = require("@azure/cognitiveservices-translatortext"); diff --git a/sdk/cognitiveservices/cognitiveservices-videosearch/README.md b/sdk/cognitiveservices/cognitiveservices-videosearch/README.md index dcd67e5871dd..443f4626ce92 100644 --- a/sdk/cognitiveservices/cognitiveservices-videosearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-videosearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a video search on 'Microsoft Azure' with conditions such as the length must be Short, pricing must be Free, etc. To know more, refer to the [Azure Documentation on Bing Video Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-video-search/) +The following sample performs a video search on 'Microsoft Azure' with conditions such as the length must be Short, pricing must be Free, etc. To know more, refer to the [Azure Documentation on Bing Video Search](https://docs.microsoft.com/azure/cognitive-services/bing-video-search/) ```javascript const { VideoSearchClient } = require("@azure/cognitiveservices-videosearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-visualsearch/README.md b/sdk/cognitiveservices/cognitiveservices-visualsearch/README.md index 95527ab6761e..a19902674acc 100644 --- a/sdk/cognitiveservices/cognitiveservices-visualsearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-visualsearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a visual search, i.e. perform a search with a image. To know more, refer to the [Azure Documentation on Bing Visual Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-visual-search/). +The following sample performs a visual search, i.e. perform a search with a image. To know more, refer to the [Azure Documentation on Bing Visual Search](https://docs.microsoft.com/azure/cognitive-services/bing-visual-search/). ```javascript const { VisualSearchClient } = require("@azure/cognitiveservices-visualsearch"); diff --git a/sdk/cognitiveservices/cognitiveservices-websearch/README.md b/sdk/cognitiveservices/cognitiveservices-websearch/README.md index 7ff651d1d7a3..dcca110c07d1 100644 --- a/sdk/cognitiveservices/cognitiveservices-websearch/README.md +++ b/sdk/cognitiveservices/cognitiveservices-websearch/README.md @@ -24,7 +24,7 @@ npm install @azure/ms-rest-azure-js ``` ##### Sample code -The following sample performs a web search on the text 'Microsoft Azure'. To know more, refer to the [Azure Documentation on Bing Web Search](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-web-search/) +The following sample performs a web search on the text 'Microsoft Azure'. To know more, refer to the [Azure Documentation on Bing Web Search](https://docs.microsoft.com/azure/cognitive-services/bing-web-search/) ```javascript const { WebSearchClient } = require("@azure/cognitiveservices-websearch"); diff --git a/sdk/communication/ci.yml b/sdk/communication/ci.yml new file mode 100644 index 000000000000..07fa45913f7a --- /dev/null +++ b/sdk/communication/ci.yml @@ -0,0 +1,36 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. + +trigger: + branches: + include: + - master + - release/* + - hotfix/* + paths: + include: + - sdk/communication/ + +pr: + branches: + include: + - master + - feature/* + - release/* + - hotfix/* + paths: + include: + - sdk/communication/ + +extends: + template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml + parameters: + ServiceDirectory: communication + Artifacts: + - name: azure-communication-common + safeName: azurecommunicationcommon + - name: azure-communication-administration + safeName: azurecommunicationadministration + - name: azure-communication-sms + safeName: azurecommunicationsms + - name: azure-communication-chat + safeName: azurecommunicationchat diff --git a/sdk/communication/communication-administration/.eslintrc.json b/sdk/communication/communication-administration/.eslintrc.json new file mode 100644 index 000000000000..9bd67fdc87a5 --- /dev/null +++ b/sdk/communication/communication-administration/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-naming-options": "off" + // "@azure/azure-sdk/ts-config-declaration": "off", + // "@azure/azure-sdk/ts-config-allowsyntheticdefaultimports": "off", + // "@azure/azure-sdk/ts-config-esmoduleinterop": "off", + // "@azure/azure-sdk/ts-config-forceconsistentcasinginfilenames": "off", + // "@azure/azure-sdk/ts-config-importhelpers": "off", + // "@azure/azure-sdk/ts-config-module": "off", + // "@azure/azure-sdk/ts-config-moduleresolution": "off", + // "@azure/azure-sdk/ts-config-sourcemap": "off", + // "@azure/azure-sdk/ts-config-strict": "off", + // "@azure/azure-sdk/ts-config-target": "off", + // "@azure/azure-sdk/ts-config-lib": "off" + } +} diff --git a/sdk/communication/communication-administration/.gitignore b/sdk/communication/communication-administration/.gitignore new file mode 100644 index 000000000000..5480375639b4 --- /dev/null +++ b/sdk/communication/communication-administration/.gitignore @@ -0,0 +1,2 @@ +/**/code-model-v* +/docGen \ No newline at end of file diff --git a/sdk/communication/communication-administration/.vscode/launch.json b/sdk/communication/communication-administration/.vscode/launch.json new file mode 100644 index 000000000000..0838e97b6317 --- /dev/null +++ b/sdk/communication/communication-administration/.vscode/launch.json @@ -0,0 +1,42 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Mocha Test [Without Rollup]", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-r", + "ts-node/register", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/*.spec.ts" + ], + "env": { "TS_NODE_COMPILER_OPTIONS": "{\"module\": \"commonjs\"}" }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "protocol": "inspector" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Unit Tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-u", + "tdd", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/dist-test/index.node.js" + ], + "internalConsoleOptions": "openOnSessionStart", + "preLaunchTask": "npm: build:test" + } + ] +} diff --git a/sdk/communication/communication-administration/CHANGELOG.md b/sdk/communication/communication-administration/CHANGELOG.md new file mode 100644 index 000000000000..88388cb04159 --- /dev/null +++ b/sdk/communication/communication-administration/CHANGELOG.md @@ -0,0 +1,5 @@ +# Release History + +## 1.0.0-beta.1 (2020-09-22) + +The Azure Communication Administration Client library contains code which facilitates user token administration. diff --git a/sdk/communication/communication-administration/LICENSE b/sdk/communication/communication-administration/LICENSE new file mode 100644 index 000000000000..ea8fb1516028 --- /dev/null +++ b/sdk/communication/communication-administration/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/communication/communication-administration/README.md b/sdk/communication/communication-administration/README.md new file mode 100644 index 000000000000..4b8b55f1d73a --- /dev/null +++ b/sdk/communication/communication-administration/README.md @@ -0,0 +1,83 @@ +# Azure Communication Administration client library for JavaScript + +The Azure Communication Administration library lets the developer create/delete users and issue tokens for Communication Services. Users and tokens can then be used when adding Chat or Calling to an app. + +## Getting started + +### Prerequisites + +- An [Azure subscription][azure_sub]. +- An existing Communication Services resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. + +### Installing + +```bash +npm install @azure/communication-administration +``` + +## Key concepts + +### CommunicationIdentityClient + +`CommunicationIdentityClient` provides methods to manage users and their tokens. + +## Examples + +## Authentication + +You can get a key and/or connection string from your Communication Services resource in [Azure Portal][azure_portal]. Once you have a key, you may authenticate with any of the following methods: + +### Create `KeyCredential` with `AzureKeyCredential` before initializing CommunicationIdentityClient + +```typescript +import { AzureKeyCredential } from "@azure/core-auth"; +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +const credential = new AzureKeyCredential(KEY); +const client = new CommunicationIdentityClient(HOST, credential); +``` + +### Using a connection string + +```typescript +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +const connectionString = `endpoint=HOST;accessKey=KEY`; +const client = new CommunicationIdentityClient(connectionString); +``` + +## Usage + +### Create a user and token + +Here we create an instance of the `CommunicationIdentityClient` class, create a user, then issue a chat scoped token for the user. + +```typescript +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +const client = new CommunicationIdentityClient(CONNECTION_STRING); +const user = await client.createUser(); +const { token } = await client.issueToken(user, ["chat"]); +``` + +## Troubleshooting + +## Next steps + +Please take a look at the +[samples] +directory for detailed examples on how to use this library. + +## Contributing + +If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md) to learn more about how to build and test the code. + +## Related projects + +- [Microsoft Azure SDK for Javascript](https://github.com/Azure/azure-sdk-for-js) + +[azure_cli]: https://docs.microsoft.com/cli/azure +[azure_sub]: https://azure.microsoft.com/free/ +[azure_portal]: https://portal.azure.com + +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fcommunication%2Fcommunication-administration%2FREADME.png) diff --git a/sdk/communication/communication-administration/api-extractor.json b/sdk/communication/communication-administration/api-extractor.json new file mode 100644 index 000000000000..641582682b45 --- /dev/null +++ b/sdk/communication/communication-administration/api-extractor.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "types/src/index.d.ts", + "docModel": { + "enabled": true + }, + "apiReport": { + "enabled": true, + "reportFolder": "./review" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "", + "publicTrimmedFilePath": "./types/communication-administration.d.ts" + }, + "messages": { + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, + "extractorMessageReporting": { + "ae-forgotten-export": { + "logLevel": "error", + "addToApiReportFile": false + }, + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "error" + } + } + } +} diff --git a/sdk/communication/communication-administration/karma.conf.js b/sdk/communication/communication-administration/karma.conf.js new file mode 100644 index 000000000000..8e53409cf259 --- /dev/null +++ b/sdk/communication/communication-administration/karma.conf.js @@ -0,0 +1,144 @@ +// https://github.com/karma-runner/karma-chrome-launcher +process.env.CHROME_BIN = require("puppeteer").executablePath(); +require("dotenv").config(); +const { + jsonRecordingFilterFunction, + isPlaybackMode, + isSoftRecordMode, + isRecordMode +} = require("@azure/test-utils-recorder"); + +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-edge-launcher", + "karma-firefox-launcher", + "karma-ie-launcher", + "karma-env-preprocessor", + "karma-coverage", + "karma-remap-istanbul", + "karma-junit-reporter", + "karma-json-to-file-reporter", + "karma-json-preprocessor" + ], + + // list of files / patterns to load in the browser + files: [ + // Uncomment the cdn link below for the polyfill service to support IE11 missing features + // Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys + // "https://cdn.polyfill.io/v2/polyfill.js?features=Symbol,Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys|always", + "dist-test/index.browser.js" + ].concat(isPlaybackMode() || isSoftRecordMode() ? ["recordings/browsers/**/*.json"] : []), + + // 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"], + "recordings/browsers/**/*.json": ["json"] + // 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 + //"test-browser/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_MODE", "COMMUNICATION_CONNECTION_STRING"], + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["mocha", "coverage", "karma-remap-istanbul", "junit", "json-to-file"], + + coverageReporter: { + // specify a common output directory + dir: "coverage-browser/", + reporters: [ + { + type: "json", + subdir: ".", + file: "coverage.json" + } + ] + }, + + remapIstanbulReporter: { + src: "coverage-browser/coverage.json", + reports: { + lcovonly: "coverage-browser/lcov.info", + html: "coverage-browser/html/report", + "text-summary": null, + cobertura: "./coverage-browser/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 + }, + + jsonToFileReporter: { + filter: jsonRecordingFilterFunction, + outputPath: "." + }, + + // 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, + browserConsoleLogOptions: { + terminal: !isRecordMode() + }, + + client: { + mocha: { + // change Karma's debug.html to the mocha web reporter + reporter: "html", + timeout: "600000" + } + } + }); +}; diff --git a/sdk/communication/communication-administration/package.json b/sdk/communication/communication-administration/package.json new file mode 100644 index 000000000000..c90eaac76870 --- /dev/null +++ b/sdk/communication/communication-administration/package.json @@ -0,0 +1,125 @@ +{ + "name": "@azure/communication-administration", + "version": "1.0.0-beta.1", + "description": "SDK for Azure Communication service which facilitates user token administration.", + "sdk-type": "client", + "main": "dist/index.js", + "module": "dist-esm/src/index.js", + "types": "types/communication-administration.d.ts", + "scripts": { + "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", + "build": "tsc -p . && rollup -c 2>&1 && api-extractor run --local", + "build:autorest": "autorest --typescript --v3 ./swagger/CommunicationIdentity.md && rushx format", + "build:clean": "rush update --recheck && rush rebuild && npm run build", + "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", + "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1", + "build:samples": "dev-tool samples prep && cd dist-samples && tsc -p .", + "build:test": "tsc -p . && rollup -c rollup.test.config.js 2>&1", + "check-format": "prettier --list-different \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "clean": "rimraf dist dist-* types *.tgz *.log", + "execute:samples": "npm run build:samples && dev-tool samples run dist-samples/javascript dist-samples/typescript/dist/dist-samples/typescript/src/", + "extract-api": "tsc -p . && api-extractor run --local", + "format": "prettier --write \"recordings/**/*.{js,json}\" \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "generate-doc": "api-documenter markdown -i temp -o docGen", + "integration-test:browser": "echo integration-test:browser skipped", + "integration-test:node": "echo integration-test:node skipped", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json tsconfig.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json tsconfig.json api-extractor.json src test --ext .ts -f html -o communication-administration-lintReport.html || exit 0", + "pack": "npm pack 2>&1", + "prebuild": "npm run clean", + "test": "npm run build:test && npm run unit-test && npm run integration-test", + "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:watch": "npm run test -- --watch --reporter min", + "unit-test:browser": "karma start --single-run", + "unit-test:node": "mocha --reporter ../../../common/tools/mocha-multi-reporter.js dist-test/index.node.js", + "unit-test": "npm run unit-test:node && npm run unit-test:browser" + }, + "files": [ + "dist/", + "dist-browser/", + "dist-esm/src/", + "types/communication-administration.d.ts", + "README.md", + "LICENSE" + ], + "keywords": [ + "Azure", + "cloud", + "communication" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/", + "sideEffects": false, + "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", + "dependencies": { + "@azure/communication-common": "1.0.0-beta.1", + "@azure/core-auth": "^1.1.3", + "@azure/core-http": "^1.1.6", + "@azure/core-paging": "^1.1.1", + "@azure/logger": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.9", + "@opentelemetry/api": "^0.10.2", + "events": "^3.0.0", + "tslib": "^2.0.0" + }, + "devDependencies": { + "@azure/dev-tool": "^1.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure/test-utils-recorder": "^1.0.0", + "@microsoft/api-documenter": "~7.8.17", + "@microsoft/api-extractor": "7.7.11", + "@rollup/plugin-commonjs": "11.0.2", + "@rollup/plugin-json": "^4.0.0", + "@rollup/plugin-multi-entry": "^3.0.0", + "@rollup/plugin-node-resolve": "^8.0.0", + "@rollup/plugin-replace": "^2.2.0", + "@types/chai": "^4.1.6", + "@types/mocha": "^7.0.2", + "@types/sinon": "^9.0.4", + "@types/node": "^8.0.0", + "@typescript-eslint/eslint-plugin": "^2.0.0", + "@typescript-eslint/parser": "^2.0.0", + "assert": "^1.4.1", + "chai": "^4.2.0", + "cross-env": "^7.0.2", + "dotenv": "^8.2.0", + "eslint-config-prettier": "^6.0.0", + "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-no-only-tests": "^2.3.0", + "eslint-plugin-prefer-arrow": "~1.2.0", + "eslint-plugin-promise": "^4.1.1", + "eslint": "^6.1.0", + "inherits": "^2.0.3", + "karma-chrome-launcher": "^3.0.0", + "karma-coverage": "^2.0.0", + "karma-edge-launcher": "^0.4.2", + "karma-env-preprocessor": "^0.1.1", + "karma-firefox-launcher": "^1.1.0", + "karma-ie-launcher": "^1.0.0", + "karma-json-preprocessor": "^0.3.3", + "karma-json-to-file-reporter": "^1.0.1", + "karma-junit-reporter": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "karma-mocha": "^2.0.1", + "karma-remap-istanbul": "^0.6.0", + "karma": "^5.1.0", + "mocha-junit-reporter": "^1.18.0", + "mocha": "^7.1.1", + "node-fetch": "^2.6.0", + "prettier": "^1.16.4", + "rimraf": "^3.0.0", + "rollup-plugin-sourcemaps": "^0.4.2", + "rollup-plugin-terser": "^5.1.1", + "rollup-plugin-visualizer": "^4.0.4", + "rollup-plugin-shim": "^1.0.0", + "rollup": "^1.16.3", + "sinon": "^9.0.2", + "typescript": "~3.9.3" + } +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json new file mode 100644 index 000000000000..f44b55201cf3 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.json @@ -0,0 +1,22 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://endpoint/identities", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": null, + "status": 200, + "response": "{\"id\":\"sanitized\"}", + "responseHeaders": { + "content-type": "application/json; charset=utf-8" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "27d09bb5f8e19a5b9a886691bbe0c28c" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json new file mode 100644 index 000000000000..6544834afeac --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.json @@ -0,0 +1,20 @@ +{ + "recordings": [ + { + "method": "DELETE", + "url": "https://endpoint/identities/sanitized", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": null, + "status": 204, + "response": "", + "responseHeaders": {} + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "23307718ae010385eb18d4ce84eb95c9" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json new file mode 100644 index 000000000000..c95b86bb589e --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.json @@ -0,0 +1,22 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://endpoint/identities/sanitized/token", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": "{\"scopes\":[\"chat\",\"pstn\"]}", + "status": 200, + "response": "{\"id\":\"sanitized\",\"token\":\"sanitized\",\"expiresOn\":\"2020-09-18T17:57:51.2773604+00:00\"}", + "responseHeaders": { + "content-type": "application/json; charset=utf-8" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "4fcce8a4b300bc164dbce1708fc9ef13" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json new file mode 100644 index 000000000000..1a91970393b5 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.json @@ -0,0 +1,22 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://endpoint/identities/sanitized/token", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": "{\"scopes\":[\"chat\"]}", + "status": 200, + "response": "{\"id\":\"sanitized\",\"token\":\"sanitized\",\"expiresOn\":\"2020-09-18T17:57:51.218834+00:00\"}", + "responseHeaders": { + "content-type": "application/json; charset=utf-8" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "778874dd07d653a79561fb2d94cb0b86" +} diff --git a/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json new file mode 100644 index 000000000000..7b52bb71a782 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/browsers/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.json @@ -0,0 +1,20 @@ +{ + "recordings": [ + { + "method": "PATCH", + "url": "https://endpoint/identities/sanitized", + "query": { + "api-version": "2020-07-20-preview2" + }, + "requestBody": "{\"tokensValidFrom\":\"2020-10-10T00:00:00.000Z\"}", + "status": 204, + "response": "", + "responseHeaders": {} + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "568db7fa8e03c8fc44cc0f90faaa974f" +} diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js new file mode 100644 index 000000000000..43503a3a7da2 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_creates_a_user.js @@ -0,0 +1,29 @@ +let nock = require("nock"); + +module.exports.hash = "71dd63e8f90b2c2eb44bc15618466368"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .post("/identities") + .query(true) + .reply(200, { id: "sanitized" }, [ + "Transfer-Encoding", + "chunked", + "Content-Type", + "application/json; charset=utf-8", + "MS-CV", + "U+/c6yzuBkqKSc0+kh37Lg.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "e3ea5380-0244-42b9-b0a4-a2d63066ad98", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "82ms", + "X-Azure-Ref", + "0mqNjXwAAAADmbwVtRUg1QoQQ/bHqCd5SWVZSMzBFREdFMDQxMwA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:45 GMT" + ]); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js new file mode 100644 index 000000000000..5d62b3949ae2 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_deletes_a_user.js @@ -0,0 +1,25 @@ +let nock = require("nock"); + +module.exports.hash = "c32f7ebc5af64d902e3e080cc228e00f"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .delete("/identities/sanitized") + .query(true) + .reply(204, "", [ + "MS-CV", + "xeaIdBb7TEe5cvxIpes+5A.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "5314f3f9-ab0d-4d3c-8373-98e2743d89cd", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "445ms", + "X-Azure-Ref", + "0vDBhXwAAAABiUEnMD06IS60LcrViuM6+WVZSMzBFREdFMDQxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Tue, 15 Sep 2020 21:23:08 GMT" + ]); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js new file mode 100644 index 000000000000..46d1f356d450 --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_multiple_scopes.js @@ -0,0 +1,33 @@ +let nock = require("nock"); + +module.exports.hash = "f30fde667c7b7a14ab32826e4d83a221"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .post("/identities/sanitized/token", { scopes: ["chat", "pstn"] }) + .query(true) + .reply( + 200, + { id: "sanitized", token: "sanitized", expiresOn: "2020-09-18T17:57:45.5545875+00:00" }, + [ + "Transfer-Encoding", + "chunked", + "Content-Type", + "application/json; charset=utf-8", + "MS-CV", + "E+sS3wKjfUSheriVQSe2QA.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "9f35ed20-f1ac-46a2-bc6d-0af9b4e06c78", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "120ms", + "X-Azure-Ref", + "0mqNjXwAAAABMcDEBNfteQKjGaHEc+xytWVZSMzBFREdFMDQwOAA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:46 GMT" + ] + ); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js new file mode 100644 index 000000000000..86dfce393e0b --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_issues_a_token_for_a_user_single_scope.js @@ -0,0 +1,33 @@ +let nock = require("nock"); + +module.exports.hash = "1c880cc35f2f3b240445a35a012e7bab"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .post("/identities/sanitized/token", { scopes: ["chat"] }) + .query(true) + .reply( + 200, + { id: "sanitized", token: "sanitized", expiresOn: "2020-09-18T17:57:45.3830734+00:00" }, + [ + "Transfer-Encoding", + "chunked", + "Content-Type", + "application/json; charset=utf-8", + "MS-CV", + "f94y+F9y70yOnKIRo9ewAA.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "76b35c64-7a2c-4876-81a0-0396f8f65f32", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "70ms", + "X-Azure-Ref", + "0mqNjXwAAAAD+AWsEKavdTbytYp800w86WVZSMzBFREdFMDMwOQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:46 GMT" + ] + ); diff --git a/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js new file mode 100644 index 000000000000..a12a8c76093a --- /dev/null +++ b/sdk/communication/communication-administration/recordings/node/communicationidentityclient_playbacklive/recording_successfully_revokes_tokens_issued_for_a_user.js @@ -0,0 +1,25 @@ +let nock = require("nock"); + +module.exports.hash = "e10098ac22e2857510889e9c31a45559"; + +module.exports.testInfo = { uniqueName: {}, newDate: {} }; + +nock("https://endpoint", { encodedQueryParams: true }) + .patch("/identities/sanitized", { tokensValidFrom: "2020-10-10T00:00:00.000Z" }) + .query(true) + .reply(204, "", [ + "MS-CV", + "KhF9I7PNKEmPXCM8o/2rzg.0", + "Strict-Transport-Security", + "max-age=2592000", + "x-ms-client-request-id", + "c8722972-96df-49bd-80f3-956313c647b7", + "api-supported-versions", + "2020-07-20-preview1, 2020-07-20-preview2", + "X-Processing-Time", + "645ms", + "X-Azure-Ref", + "0mqNjXwAAAAD2aqka/gd+TYiOFoj9xCZrWVZSMzBFREdFMDMwNwA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "Date", + "Thu, 17 Sep 2020 17:57:46 GMT" + ]); diff --git a/sdk/communication/communication-administration/review/communication-administration.api.md b/sdk/communication/communication-administration/review/communication-administration.api.md new file mode 100644 index 000000000000..7e9329a433a2 --- /dev/null +++ b/sdk/communication/communication-administration/review/communication-administration.api.md @@ -0,0 +1,64 @@ +## API Report File for "@azure/communication-administration" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { CommunicationUser } from '@azure/communication-common'; +import { HttpResponse } from '@azure/core-http'; +import { KeyCredential } from '@azure/core-auth'; +import { OperationOptions } from '@azure/core-http'; +import { PipelineOptions } from '@azure/core-http'; + +// @public +export class CommunicationIdentityClient { + constructor(connectionString: string, options?: CommunicationIdentityOptions); + constructor(url: string, credential: KeyCredential, options?: CommunicationIdentityOptions); + createUser(options?: OperationOptions): Promise; + deleteUser(user: CommunicationUser, options?: OperationOptions): Promise; + issueToken(user: CommunicationUser, scopes: TokenScope[], options?: OperationOptions): Promise; + revokeTokens(user: CommunicationUser, tokensValidFrom?: Date, options?: OperationOptions): Promise; +} + +// @public +export interface CommunicationIdentityOptions extends PipelineOptions { +} + +// @public +export interface CommunicationIdentityToken { + expiresOn: Date; + id: string; + token: string; +} + +// @public +export interface CommunicationTokenRequest { + scopes: string[]; +} + +// @public +export interface CommunicationUserToken extends Pick { + user: CommunicationUser; +} + +// @public +export type CreateUserResponse = WithResponse; + +// @public +export type IssueTokenResponse = WithResponse; + +// @public +export type TokenScope = "chat" | "voip" | "pstn"; + +// @public +export type VoidResponse = WithResponse<{}>; + +// @public +export type WithResponse = T & { + _response: HttpResponse; +}; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/sdk/communication/communication-administration/rollup.base.config.js b/sdk/communication/communication-administration/rollup.base.config.js new file mode 100644 index 000000000000..0e556ce1f12e --- /dev/null +++ b/sdk/communication/communication-administration/rollup.base.config.js @@ -0,0 +1,131 @@ +import path from "path"; +import nodeResolve from "@rollup/plugin-node-resolve"; +import multiEntry from "@rollup/plugin-multi-entry"; +import cjs from "@rollup/plugin-commonjs"; +import replace from "@rollup/plugin-replace"; +import { terser } from "rollup-plugin-terser"; +import sourcemaps from "rollup-plugin-sourcemaps"; +import viz from "rollup-plugin-visualizer"; +import shim from "rollup-plugin-shim"; + +const pkg = require("./package.json"); +const depNames = Object.keys(pkg.dependencies); +const devDepNames = Object.keys(pkg.devDependencies); +const input = "dist-esm/src/index.js"; +const production = process.env.NODE_ENV === "production"; + +export function nodeConfig(test = false) { + const externalNodeBuiltins = ["events", "crypto"]; + const baseConfig = { + input: input, + external: depNames.concat(externalNodeBuiltins), + output: { file: "dist/index.js", format: "cjs", sourcemap: true }, + preserveSymlinks: false, + plugins: [ + sourcemaps(), + replace({ + delimiters: ["", ""], + values: { + // replace dynamic checks with if (true) since this is for node only. + // Allows rollup's dead code elimination to be more aggressive. + "if (isNode)": "if (true)" + } + }), + nodeResolve({ preferBuiltins: true }), + cjs() + ] + }; + + if (test) { + // Entry points - test files under the `test` folder(common for both browser and node), node specific test files + baseConfig.input = ["dist-esm/test/*.spec.js", "dist-esm/test/node/*.spec.js"]; + baseConfig.plugins.unshift(multiEntry({ exports: false })); + + // different output file + baseConfig.output.file = "dist-test/index.node.js"; + + // mark assert as external + baseConfig.external.push("assert", ...devDepNames); + + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting + // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also + // applies to test code, which causes all tests to be removed by tree-shaking. + baseConfig.treeshake = false; + } else if (production) { + baseConfig.plugins.push(terser()); + } + + return baseConfig; +} + +export function browserConfig(test = false) { + const baseConfig = { + input: input, + external: ["crypto", "fs-extra"], + output: { + file: "dist-browser/azure-communication-administration.js", + format: "umd", + name: "Azure.Communication.Administration", + sourcemap: true, + globals: { "@azure/core-http": "Azure.Core.HTTP" } + }, + preserveSymlinks: false, + plugins: [ + sourcemaps(), + replace({ + delimiters: ["", ""], + values: { + // replace dynamic checks with if (false) since this is for + // browser only. Rollup's dead code elimination will remove + // any code guarded by if (isNode) { ... } + "if (isNode)": "if (false)" + } + }), + shim({ + constants: `export default {}`, + fs: `export default {}`, + os: `export default {}`, + dotenv: `export function config() { }`, + path: `export default {}` + }), + nodeResolve({ + mainFields: ["module", "browser"], + preferBuiltins: false + }), + cjs({ + namedExports: { + chai: ["assert"], + events: ["EventEmitter"], + "@opentelemetry/api": ["CanonicalCode", "SpanKind", "TraceFlags"] + } + }), + viz({ filename: "dist-browser/browser-stats.html", sourcemap: false }) + ] + }; + + if (test) { + // Entry points - test files under the `test` folder(common for both browser and node), browser specific test files + baseConfig.input = ["dist-esm/test/*.spec.js", "dist-esm/test/browser/*.spec.js"]; + baseConfig.plugins.unshift(multiEntry({ exports: false })); + baseConfig.output.file = "dist-test/index.browser.js"; + + baseConfig.onwarn = (warning) => { + if ( + warning.code === "CIRCULAR_DEPENDENCY" && + warning.importer.indexOf(path.normalize("node_modules/chai/lib") === 0) + ) { + // Chai contains circular references, but they are not fatal and can be ignored. + return; + } + + console.error(`(!) ${warning.message}`); + }; + + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting + // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also + // applies to test code, which causes all tests to be removed by tree-shaking. + baseConfig.treeshake = false; + } + + return baseConfig; +} diff --git a/sdk/communication/communication-administration/rollup.config.js b/sdk/communication/communication-administration/rollup.config.js new file mode 100644 index 000000000000..14652aa67ed8 --- /dev/null +++ b/sdk/communication/communication-administration/rollup.config.js @@ -0,0 +1,13 @@ +import * as base from "./rollup.base.config"; + +const inputs = []; + +if (!process.env.ONLY_BROWSER) { + inputs.push(base.nodeConfig()); +} + +if (!process.env.ONLY_NODE) { + inputs.push(base.browserConfig()); +} + +export default inputs; diff --git a/sdk/communication/communication-administration/rollup.test.config.js b/sdk/communication/communication-administration/rollup.test.config.js new file mode 100644 index 000000000000..925a4421a53e --- /dev/null +++ b/sdk/communication/communication-administration/rollup.test.config.js @@ -0,0 +1,3 @@ +import * as base from "./rollup.base.config"; + +export default [base.nodeConfig(true), base.browserConfig(true)]; diff --git a/sdk/communication/communication-administration/sample.env b/sdk/communication/communication-administration/sample.env new file mode 100644 index 000000000000..587c69bb3fdf --- /dev/null +++ b/sdk/communication/communication-administration/sample.env @@ -0,0 +1,7 @@ +# Used in most samples. Retrieve these values from a Communication Services resource +# in the Azure Portal. +COMMUNICATION_CONNECTION_STRING="endpoint=;accessKey=" + +# Our tests assume that TEST_MODE is "playback" by default. You can +# change it to "record" to generate new recordings, or "live" to bypass the recorder entirely. +# TEST_MODE=playback diff --git a/sdk/communication/communication-administration/samples/.gitignore b/sdk/communication/communication-administration/samples/.gitignore new file mode 100644 index 000000000000..0c348f50aebf --- /dev/null +++ b/sdk/communication/communication-administration/samples/.gitignore @@ -0,0 +1 @@ +.npmrc \ No newline at end of file diff --git a/sdk/communication/communication-administration/samples/javascript/README.md b/sdk/communication/communication-administration/samples/javascript/README.md new file mode 100644 index 000000000000..f1dc1eb76834 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/README.md @@ -0,0 +1,67 @@ +--- +page_type: sample +languages: + - javascript +products: + - azure + - azure-communication-service + - azure-communication-administration +urlFragment: communication-administration-identity-javascript +--- + +# Azure Communication Service Administration Identity client library sample for JavaScript + +These sample programs show how to use the JavaScript client libraries for Azure Communication Service Administration Identity to issue and refresh tokens. + +| **File Name** | **Description** | +| --------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| [issueToken.js] | uses the CommunicationIdentityClient to create a user and issue a token for this user | +| [revokeTokens.js] | uses the CommunicationIdentityClient to create a user, issue tokens for this user, and revoke these tokens | + +## Prerequisites + +The sample is compatible with Node.js >= 8.0.0. + +You need [an Azure subscription][freesub] and [an Azure Communication Service Instance][azcomsvc] to run these sample program. + +Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README]. + +## Setup + +To run the sample using the published version of the package: + +1. Install the dependencies using `npm`: + +```bash +npm install +``` + +2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically. + +3. Run whichever samples you like (note that some samples may require additional setup, see the table above): + +```bash +node issueToken.js +``` + +Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform): + +```bash +npx cross-env CONNECTION_STRING="" node issueToken.js +``` + +## Next Steps + +Take a look at our [API Documentation] for more information about the APIs that are available in the clients. + +[issuetoken]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/javascript/issueToken.js +[revoketokens]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/javascript/revokeTokens.js +[apiref]: https://docs.microsoft.com/javascript/api/@azure/communication-administration +[azcomsvc]: https://docs.microsoft.com/azure +[freesub]: https://azure.microsoft.com/free/ +[package]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/README.md + +## ! TODO + +- Get correct url for azcomsvc +- Uncomment urls when merged and apirefs available diff --git a/sdk/communication/communication-administration/samples/javascript/issueToken.js b/sdk/communication/communication-administration/samples/javascript/issueToken.js new file mode 100644 index 000000000000..db295a7913c7 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/issueToken.js @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * issue a user token. + */ + +const { CommunicationIdentityClient } = require("@azure/communication-administration"); + +// Load the .env file if it exists +const dotenv = require("dotenv"); +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +async function main() { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + const scopes = ["chat"]; + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + console.log("Issuing Token"); + + // Issue token and get token from response + const { token } = await client.issueToken(user, scopes); + + console.log(`Issued token: ${token}`); +} + +main().catch((error) => { + console.error("Encountered an error while issuing token: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/javascript/package.json b/sdk/communication/communication-administration/samples/javascript/package.json new file mode 100644 index 000000000000..268ddee07c85 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/package.json @@ -0,0 +1,29 @@ +{ + "name": "azure-communication-configuration-user-token-samples-js", + "version": "0.1.0", + "description": "Azure Communication Service User Token Management client library samples for JavaScript", + "engine": { + "node": ">=8.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Azure/azure-sdk-for-js.git" + }, + "keywords": [ + "Azure", + "Communication", + "Node.js", + "JavaScript" + ], + "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/master/sdk/communication/communication-configuration", + "sideEffects": false, + "dependencies": { + "@azure/communication-administration": "latest", + "dotenv": "^8.2.0" + } +} diff --git a/sdk/communication/communication-administration/samples/javascript/revokeTokens.js b/sdk/communication/communication-administration/samples/javascript/revokeTokens.js new file mode 100644 index 000000000000..13dabb722451 --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/revokeTokens.js @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * revoke a user's tokens. + */ + +const { CommunicationIdentityClient } = require("@azure/communication-administration"); + +// Load the .env file if it exists +const dotenv = require("dotenv"); +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +async function main() { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + const scopes = ["chat"]; + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + + console.log("Issuing Tokens"); + + // Issue tokens + const { token: token1 } = await client.issueToken(user, scopes); + const { token: token2 } = await client.issueToken(user, scopes); + const { token: token3 } = await client.issueToken(user, scopes); + + console.log("Issued tokens:"); + console.log(token1); + console.log(token2); + console.log(token3); + + // Revoke tokens + console.log("Revoking Tokens"); + + await client.revokeTokens(user, new Date()); + + console.log("Tokens Revoked"); +} + +main().catch((error) => { + console.error("Encountered an error while revoking tokens: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/javascript/sample.env b/sdk/communication/communication-administration/samples/javascript/sample.env new file mode 100644 index 000000000000..1ba7d7b92f1f --- /dev/null +++ b/sdk/communication/communication-administration/samples/javascript/sample.env @@ -0,0 +1,3 @@ +# Used in most samples. Retrieve these values from a Communication Service instance +# in the Azure Portal. +CONNECTION_STRING="endpoint=https://.communication.azure.net/;accessKey=" \ No newline at end of file diff --git a/sdk/communication/communication-administration/samples/tsconfig.json b/sdk/communication/communication-administration/samples/tsconfig.json new file mode 100644 index 000000000000..8c89eac7173a --- /dev/null +++ b/sdk/communication/communication-administration/samples/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "typescript/dist", + "lib": ["DOM", "ES6"] + }, + "include": ["typescript/src/**.ts"], + "exclude": ["typescript/*.json", "**/node_modules/", "../node_modules", "../typings"] +} diff --git a/sdk/communication/communication-administration/samples/typescript/README.md b/sdk/communication/communication-administration/samples/typescript/README.md new file mode 100644 index 000000000000..cc996d2c6b8e --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/README.md @@ -0,0 +1,73 @@ +--- +page_type: sample +languages: + - typescript +products: + - azure + - azure-communication-service + - azure-communication-administration +urlFragment: communication-administration-identity-typescript +--- + +# Azure Communication Service Communication Identity client library sample for TypeScript + +These sample programs show how to use the TypeScript client libraries for Azure Communication Service Communication Identity to issue and refresh tokens. + +| **File Name** | **Description** | +| -------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| [issueToken.ts] | uses the CommunicationIdentityClient to create a user and issue a token for this user | +| [revokeTokens.ts] | uses the CommunicationIdentityClient to create a user, issue tokens for this user, and revoke these tokens | + +## Prerequisites + +The sample is compatible with Node.js >= 8.0.0. + +You need [an Azure subscription][freesub] and [an Azure Communication Service Instance][azcomsvc] to run these sample program. + +Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README]. + +## Setup + +To run the sample using the published version of the package: + +1. Install the dependencies using `npm`: + +```bash +npm install +``` + +2. Compile the sample + +```bash +npm run build +``` + +3. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically. + +4. Run whichever samples you like (note that some samples may require additional setup, see the table above): + +```bash +node dist/issueToken.js +``` + +Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform): + +```bash +npx cross-env CONNECTION_STRING="" node dist/issueToken.js +``` + +## Next Steps + +Take a look at our [API Documentation] for more information about the APIs that are available in the clients. + +[issuetoken]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts +[revoketokens]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts +[apiref]: https://docs.microsoft.com/javascript/api/@azure/communication-administration +[azcomsvc]: https://docs.microsoft.com/azure +[freesub]: https://azure.microsoft.com/free/ +[package]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/communication/communication-administration/README.md + +## ! TODO + +- Get correct url for azcomsvc +- Uncomment urls when merged and apirefs available diff --git a/sdk/communication/communication-administration/samples/typescript/package.json b/sdk/communication/communication-administration/samples/typescript/package.json new file mode 100644 index 000000000000..a2a3941de76d --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/package.json @@ -0,0 +1,38 @@ +{ + "name": "azure-communication-configuration-user-token-samples-ts", + "version": "0.1.0", + "description": "Azure Communication Service User Token Management client library samples for TypeScript", + "engine": { + "node": ">=8.0.0" + }, + "scripts": { + "build": "tsc", + "prebuild": "rimraf dist/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Azure/azure-sdk-for-js.git" + }, + "keywords": [ + "Azure", + "Communication", + "Node.js", + "JavaScript" + ], + "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/master/sdk/communication/communication-configuration", + "sideEffects": false, + "dependencies": { + "@azure/communication-administration": "latest", + "dotenv": "^8.2.0" + }, + "devDependencies": { + "@types/node": "^8.0.0", + "rimraf": "^3.0.0", + "typescript": "~3.6.4" + } +} diff --git a/sdk/communication/communication-administration/samples/typescript/sample.env b/sdk/communication/communication-administration/samples/typescript/sample.env new file mode 100644 index 000000000000..1ba7d7b92f1f --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/sample.env @@ -0,0 +1,3 @@ +# Used in most samples. Retrieve these values from a Communication Service instance +# in the Azure Portal. +CONNECTION_STRING="endpoint=https://.communication.azure.net/;accessKey=" \ No newline at end of file diff --git a/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts b/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts new file mode 100644 index 000000000000..a185e04adfd5 --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/src/issueToken.ts @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * issue a new user token. + */ + +import { CommunicationIdentityClient, TokenScope } from "@azure/communication-administration"; + +// Load the .env file if it exists +import * as dotenv from "dotenv"; +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +export const main = async () => { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + const scopes: TokenScope[] = ["chat"]; + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + console.log("Issuing Token"); + + // Issue token and get token from response + const { token } = await client.issueToken(user, scopes); + + console.log(`Issued token: ${token}`); +}; + +main().catch((error) => { + console.error("Encountered an error while issuing token: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts b/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts new file mode 100644 index 000000000000..4e4e6cbf0255 --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/src/revokeTokens.ts @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates how to use the CommunicationIdentityClient to + * issue a new user token. + */ + +import { CommunicationIdentityClient } from "@azure/communication-administration"; + +// Load the .env file if it exists +import * as dotenv from "dotenv"; +dotenv.config(); + +// You will need to set this environment variables or edit the following values +const connectionString = + process.env["CONNECTION_STRING"] || ""; + +export const main = async () => { + console.log("== Issue Token Sample =="); + + const client = new CommunicationIdentityClient(connectionString); + + // Create user + console.log("Creating User"); + + const user = await client.createUser(); + + console.log(`Created user with id: ${user.communicationUserId}`); + + console.log("Issuing Tokens"); + + // Issue tokens + const { token: token1 } = await client.issueToken(user, ["chat"]); + const { token: token2 } = await client.issueToken(user, ["pstn"]); + const { token: token3 } = await client.issueToken(user, ["voip"]); + + console.log("Issued tokens:"); + console.log(token1); + console.log(token2); + console.log(token3); + + // Revoke tokens + console.log("Revoking Tokens"); + + await client.revokeTokens(user, new Date()); + + console.log("Tokens Revoked"); +}; + +main().catch((error) => { + console.error("Encountered an error while issuing/refreshing token: "); + console.error("Request: \n", error.request); + console.error("\nResponse: \n", error.response); + console.error(error); +}); diff --git a/sdk/communication/communication-administration/samples/typescript/tsconfig.json b/sdk/communication/communication-administration/samples/typescript/tsconfig.json new file mode 100644 index 000000000000..9e7ca6c9974b --- /dev/null +++ b/sdk/communication/communication-administration/samples/typescript/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "commonjs", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "strict": true, + "alwaysStrict": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**.ts"], + "exclude": ["node_modules"] +} diff --git a/sdk/communication/communication-administration/src/common/logger.ts b/sdk/communication/communication-administration/src/common/logger.ts new file mode 100644 index 000000000000..ea6fd2a63671 --- /dev/null +++ b/sdk/communication/communication-administration/src/common/logger.ts @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { createClientLogger } from "@azure/logger"; + +/** + * The @azure/logger configuration for this package. + */ +export const logger = createClientLogger("communication-administration"); diff --git a/sdk/communication/communication-administration/src/common/mappers.ts b/sdk/communication/communication-administration/src/common/mappers.ts new file mode 100644 index 000000000000..52c5be668df3 --- /dev/null +++ b/sdk/communication/communication-administration/src/common/mappers.ts @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { HttpOperationResponse, HttpResponse } from "@azure/core-http"; +import { WithResponse } from ".."; + +/** + * Attach http response to a model + */ +export const attachHttpResponse = ( + model: T, + httpResponse: (HttpResponse & { bodyAsText: string; parsedBody: any }) | HttpOperationResponse +): WithResponse => { + const { parsedBody, bodyAsText, ...r } = httpResponse; + return Object.defineProperty(model, "_response", { + value: r + }); +}; diff --git a/sdk/communication/communication-administration/src/common/tracing.ts b/sdk/communication/communication-administration/src/common/tracing.ts new file mode 100644 index 000000000000..bd42a3471fb5 --- /dev/null +++ b/sdk/communication/communication-administration/src/common/tracing.ts @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { OperationOptions } from "@azure/core-http"; +import { getTracer } from "@azure/core-tracing"; +import { Span, SpanOptions, SpanKind } from "@opentelemetry/api"; + +type OperationTracingOptions = OperationOptions["tracingOptions"]; + +/** + * Creates a span using the global tracer. + * @ignore + * @param name The name of the operation being performed. + * @param tracingOptions The options for the underlying http request. + */ +export function createSpan( + operationName: string, + operationOptions: T +): { span: Span; updatedOptions: T } { + const tracer = getTracer(); + const tracingOptions = operationOptions.tracingOptions || {}; + const spanOptions: SpanOptions = { + ...tracingOptions.spanOptions, + kind: SpanKind.INTERNAL + }; + + const span = tracer.startSpan(`Azure.Communication.${operationName}`, spanOptions); + + span.setAttribute("az.namespace", "Microsoft.Communication"); + + let newSpanOptions = tracingOptions.spanOptions || {}; + if (span.isRecording()) { + newSpanOptions = { + ...tracingOptions.spanOptions, + parent: span.context(), + attributes: { + ...spanOptions.attributes, + "az.namespace": "Microsoft.Communication" + } + }; + } + + const newTracingOptions: OperationTracingOptions = { + ...tracingOptions, + spanOptions: newSpanOptions + }; + + const newOperationOptions: T = { + ...operationOptions, + tracingOptions: newTracingOptions + }; + + return { + span, + updatedOptions: newOperationOptions + }; +} diff --git a/sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts b/sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts new file mode 100644 index 000000000000..29952d7d2f14 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/communicationIdentityClient.ts @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + createCommunicationAccessKeyCredentialPolicy, + parseClientArguments, + isKeyCredential, + CommunicationUser +} from "@azure/communication-common"; +import { KeyCredential } from "@azure/core-auth"; +import { + InternalPipelineOptions, + createPipelineFromOptions, + OperationOptions, + operationOptionsToRequestOptionsBase +} from "@azure/core-http"; +import { CanonicalCode } from "@opentelemetry/api"; +import { GeneratedCommunicationIdentityClient } from "./generated/src/generatedCommunicationIdentityClient"; +import { CommunicationIdentityOperations } from "./generated/src/operations/communicationIdentityOperations"; +import { SDK_VERSION } from "./constants"; +import { logger } from "../common/logger"; +import { createSpan } from "../common/tracing"; +import { + CommunicationIdentityOptions, + TokenScope, + IssueTokenResponse, + CreateUserResponse, + CommunicationUserToken, + VoidResponse +} from "./models"; +import { attachHttpResponse } from "../common/mappers"; + +const isCommunicationIdentityOptions = (options: any): options is CommunicationIdentityOptions => + options && !isKeyCredential(options); + +/** + * Client class for interacting with Azure Communication Services User Token Management. + */ +export class CommunicationIdentityClient { + /** + * A reference to the auto-generated UserToken HTTP client. + */ + private readonly client: CommunicationIdentityOperations; + + /** + * The base URL to which requests are made + */ + private readonly endpoint: string; + + /** + * Initializes a new instance of the CommunicationIdentity class. + * @param connectionString Connection string to connect to an Azure Communication Service resource. + * Example: "endpoint=https://contoso.eastus.communications.azure.net/;accesskey=secret"; + * @param options Optional. Options to configure the HTTP pipeline. + */ + public constructor(connectionString: string, options?: CommunicationIdentityOptions); + + /** + * Initializes a new instance of the CommunicationIdentity class using an Azure KeyCredential. + * @param url The endpoint of the service (ex: https://contoso.eastus.communications.azure.net). + * @param credential An object that is used to authenticate requests to the service. Use the AzureKeyCredential or `@azure/identity` to create a credential. + * @param options Optional. Options to configure the HTTP pipeline. + */ + public constructor( + url: string, + credential: KeyCredential, + options?: CommunicationIdentityOptions + ); + + /** + * Creates an instance of CommunicationIdentity. + * + * @param {string} url The endpoint to the service + * @param {KeyCredential} credential An object that is used to authenticate requests to the service. Use the AzureKeyCredential or `@azure/identity` to create a credential. + * @param {CommunicationIdentityOptions} [options={}] Options to configure the HTTP pipeline. + */ + public constructor( + connectionStringOrUrl: string, + credentialOrOptions?: KeyCredential | CommunicationIdentityOptions, + maybeOptions: CommunicationIdentityOptions = {} + ) { + const { url, credential } = parseClientArguments(connectionStringOrUrl, credentialOrOptions); + const options = isCommunicationIdentityOptions(credentialOrOptions) + ? credentialOrOptions + : maybeOptions; + const libInfo = `azsdk-js-communication-administration/${SDK_VERSION}`; + + if (!options.userAgentOptions) { + options.userAgentOptions = {}; + } + + if (options.userAgentOptions.userAgentPrefix) { + options.userAgentOptions.userAgentPrefix = `${options.userAgentOptions.userAgentPrefix} ${libInfo}`; + } else { + options.userAgentOptions.userAgentPrefix = libInfo; + } + + const internalPipelineOptions: InternalPipelineOptions = { + ...options, + ...{ + loggingOptions: { + logger: logger.info + } + } + }; + + const authPolicy = createCommunicationAccessKeyCredentialPolicy(credential); + const pipeline = createPipelineFromOptions(internalPipelineOptions, authPolicy); + + this.endpoint = url; + this.client = new GeneratedCommunicationIdentityClient(pipeline).communicationIdentity; + } + + /** + * Creates a scoped user token. + * + * @param {CommunicationUser} user The user whose tokens are being revoked. + * @param {TokenScope[]} scopes Scopes to include in the token. + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async issueToken( + user: CommunicationUser, + scopes: TokenScope[], + options: OperationOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-issueToken", options); + try { + const { token, id, expiresOn, _response } = await this.client.issueToken( + this.endpoint, + user.communicationUserId, + scopes, + { ...operationOptionsToRequestOptionsBase(updatedOptions) } + ); + const results: CommunicationUserToken = { + token, + expiresOn, + user: { communicationUserId: id } + }; + return attachHttpResponse(results, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Revokes all data and tokens created for a user. + * + * @param {CommunicationUser} user The user whose tokens are being revoked. + * @param {Date} tokensValidFrom Tokens issued before this time will be revoked. + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async revokeTokens( + user: CommunicationUser, + tokensValidFrom: Date = new Date(), + options: OperationOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-revokeTokens", options); + try { + const { _response } = await this.client.update(this.endpoint, user.communicationUserId, { + tokensValidFrom, + ...operationOptionsToRequestOptionsBase(updatedOptions) + }); + return attachHttpResponse({}, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a single user. + * + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async createUser(options: OperationOptions = {}): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-createUser", options); + try { + const { id, _response } = await this.client.create(this.endpoint, { + ...operationOptionsToRequestOptionsBase(updatedOptions) + }); + const user: CommunicationUser = { communicationUserId: id }; + return attachHttpResponse(user, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Triggers revocation event for user and deletes all its data. + * + * @param {CommunicationUser} user The user being deleted. + * @param {OperationOptions} [options={}] Additional options for the request. + */ + public async deleteUser( + user: CommunicationUser, + options: OperationOptions = {} + ): Promise { + const { span, updatedOptions } = createSpan("CommunicationIdentity-deleteUser", options); + try { + const { _response } = await this.client.deleteMethod( + this.endpoint, + user.communicationUserId, + { + ...operationOptionsToRequestOptionsBase(updatedOptions) + } + ); + return attachHttpResponse({}, _response); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } +} + +export { CommunicationTokenRequest, CommunicationIdentityToken } from "./generated/src/models"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/constants.ts b/sdk/communication/communication-administration/src/communicationIdentity/constants.ts new file mode 100644 index 000000000000..d95eaa576529 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/constants.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { apiVersion } from "./generated/src/models/parameters"; + +export const SDK_VERSION: string = apiVersion.mapper.defaultValue; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts new file mode 100644 index 000000000000..c359cfc5a5b5 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClient.ts @@ -0,0 +1,39 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; +import * as Models from "./models"; +import * as Mappers from "./models/mappers"; +import * as operations from "./operations"; +import { GeneratedCommunicationIdentityClientContext } from "./generatedCommunicationIdentityClientContext"; + +class GeneratedCommunicationIdentityClient extends GeneratedCommunicationIdentityClientContext { + // Operation groups + communicationIdentity: operations.CommunicationIdentityOperations; + + /** + * Initializes a new instance of the GeneratedCommunicationIdentityClient class. + * @param [options] The parameter options + */ + constructor(options?: coreHttp.ServiceClientOptions) { + super(options); + this.communicationIdentity = new operations.CommunicationIdentityOperations(this); + } +} + +// Operation Specifications + +export { + GeneratedCommunicationIdentityClient, + GeneratedCommunicationIdentityClientContext, + Models as GeneratedCommunicationIdentityModels, + Mappers as GeneratedCommunicationIdentityMappers +}; +export * from "./operations"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts new file mode 100644 index 000000000000..39ffe3f42ed3 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +const packageName = "azure-communication-administration-identity"; +const packageVersion = "1.0.0-beta.1"; + +export class GeneratedCommunicationIdentityClientContext extends coreHttp.ServiceClient { + /** + * Initializes a new instance of the GeneratedCommunicationIdentityClientContext class. + * @param [options] The parameter options + */ + constructor(options?: coreHttp.ServiceClientOptions) { + if (!options) { + options = {}; + } + + if (!options.userAgent) { + const defaultUserAgent = coreHttp.getDefaultUserAgentValue(); + options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`; + } + + super(undefined, options); + + this.baseUri = "{endpoint}"; + this.requestContentType = "application/json; charset=utf-8"; + } +} diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts new file mode 100644 index 000000000000..36b7cd50c0b3 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/communicationIdentityOperationsMappers.ts @@ -0,0 +1,14 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +export { + CommunicationIdentity, + CommunicationIdentityToken, + CommunicationIdentityUpdateRequest, + CommunicationTokenRequest +} from "../models/mappers"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts new file mode 100644 index 000000000000..86d8f18d964b --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/index.ts @@ -0,0 +1,107 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +/** + * A communication identity. + */ +export interface CommunicationIdentity { + /** + * Identifier of the identity. + */ + id: string; +} + +/** + * An interface representing CommunicationIdentityUpdateRequest. + */ +export interface CommunicationIdentityUpdateRequest { + /** + * All tokens that are issued prior to this time will be revoked. + */ + tokensValidFrom?: Date; +} + +/** + * An interface representing CommunicationTokenRequest. + */ +export interface CommunicationTokenRequest { + /** + * List of scopes attached to the token. + */ + scopes: string[]; +} + +/** + * An interface representing CommunicationIdentityToken. + */ +export interface CommunicationIdentityToken { + /** + * Identifier of the identity owning the token. + */ + id: string; + /** + * The token issued for the identity. + */ + token: string; + /** + * The expiry time of the token. + */ + expiresOn: Date; +} + +/** + * Optional Parameters. + */ +export interface CommunicationIdentityUpdateOptionalParams extends coreHttp.RequestOptionsBase { + /** + * All tokens that are issued prior to this time will be revoked. + */ + tokensValidFrom?: Date; +} + +/** + * Contains response data for the create operation. + */ +export type CommunicationIdentityCreateResponse = CommunicationIdentity & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: CommunicationIdentity; + }; +}; + +/** + * Contains response data for the issueToken operation. + */ +export type CommunicationIdentityIssueTokenResponse = CommunicationIdentityToken & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: CommunicationIdentityToken; + }; +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts new file mode 100644 index 000000000000..dbcc264adfac --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/mappers.ts @@ -0,0 +1,95 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +export const CommunicationIdentity: coreHttp.CompositeMapper = { + serializedName: "CommunicationIdentity", + type: { + name: "Composite", + className: "CommunicationIdentity", + modelProperties: { + id: { + required: true, + serializedName: "id", + type: { + name: "String" + } + } + } + } +}; + +export const CommunicationIdentityUpdateRequest: coreHttp.CompositeMapper = { + serializedName: "CommunicationIdentityUpdateRequest", + type: { + name: "Composite", + className: "CommunicationIdentityUpdateRequest", + modelProperties: { + tokensValidFrom: { + serializedName: "tokensValidFrom", + type: { + name: "DateTime" + } + } + } + } +}; + +export const CommunicationTokenRequest: coreHttp.CompositeMapper = { + serializedName: "CommunicationTokenRequest", + type: { + name: "Composite", + className: "CommunicationTokenRequest", + modelProperties: { + scopes: { + required: true, + serializedName: "scopes", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + } + } + } +}; + +export const CommunicationIdentityToken: coreHttp.CompositeMapper = { + serializedName: "CommunicationIdentityToken", + type: { + name: "Composite", + className: "CommunicationIdentityToken", + modelProperties: { + id: { + required: true, + serializedName: "id", + type: { + name: "String" + } + }, + token: { + required: true, + serializedName: "token", + type: { + name: "String" + } + }, + expiresOn: { + required: true, + serializedName: "expiresOn", + type: { + name: "DateTime" + } + } + } + } +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts new file mode 100644 index 000000000000..f7ac50fdfb24 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/models/parameters.ts @@ -0,0 +1,46 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; + +export const apiVersion: coreHttp.OperationQueryParameter = { + parameterPath: "apiVersion", + mapper: { + required: true, + isConstant: true, + serializedName: "api-version", + defaultValue: "2020-07-20-preview2", + type: { + name: "String" + } + } +}; +export const endpoint: coreHttp.OperationURLParameter = { + parameterPath: "endpoint", + mapper: { + required: true, + serializedName: "endpoint", + defaultValue: "", + type: { + name: "String" + } + }, + skipEncoding: true +}; +export const id: coreHttp.OperationURLParameter = { + parameterPath: "id", + mapper: { + required: true, + serializedName: "id", + type: { + name: "String" + } + } +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts new file mode 100644 index 000000000000..a033787129b6 --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/communicationIdentityOperations.ts @@ -0,0 +1,296 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import * as coreHttp from "@azure/core-http"; +import * as Models from "../models"; +import * as Mappers from "../models/communicationIdentityOperationsMappers"; +import * as Parameters from "../models/parameters"; +import { GeneratedCommunicationIdentityClientContext } from "../generatedCommunicationIdentityClientContext"; + +/** Class representing a CommunicationIdentityOperations. */ +export class CommunicationIdentityOperations { + private readonly client: GeneratedCommunicationIdentityClientContext; + + /** + * Create a CommunicationIdentityOperations. + * @param {GeneratedCommunicationIdentityClientContext} client Reference to the service client. + */ + constructor(client: GeneratedCommunicationIdentityClientContext) { + this.client = client; + } + + /** + * @summary Create a new identity. + * @param endpoint Auth and Identity endpoint + * @param [options] The optional parameters + * @returns Promise + */ + create( + endpoint: string, + options?: coreHttp.RequestOptionsBase + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param callback The callback + */ + create(endpoint: string, callback: coreHttp.ServiceCallback): void; + /** + * @param endpoint Auth and Identity endpoint + * @param options The optional parameters + * @param callback The callback + */ + create( + endpoint: string, + options: coreHttp.RequestOptionsBase, + callback: coreHttp.ServiceCallback + ): void; + create( + endpoint: string, + options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + options + }, + createOperationSpec, + callback + ) as Promise; + } + + /** + * @summary Delete the identity, revoke all tokens of the identity and delete all associated data. + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to be deleted. + * @param [options] The optional parameters + * @returns Promise + */ + deleteMethod( + endpoint: string, + id: string, + options?: coreHttp.RequestOptionsBase + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to be deleted. + * @param callback The callback + */ + deleteMethod(endpoint: string, id: string, callback: coreHttp.ServiceCallback): void; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to be deleted. + * @param options The optional parameters + * @param callback The callback + */ + deleteMethod( + endpoint: string, + id: string, + options: coreHttp.RequestOptionsBase, + callback: coreHttp.ServiceCallback + ): void; + deleteMethod( + endpoint: string, + id: string, + options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + id, + options + }, + deleteMethodOperationSpec, + callback + ); + } + + /** + * @summary Update an Identity. + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity. + * @param [options] The optional parameters + * @returns Promise + */ + update( + endpoint: string, + id: string, + options?: Models.CommunicationIdentityUpdateOptionalParams + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity. + * @param callback The callback + */ + update(endpoint: string, id: string, callback: coreHttp.ServiceCallback): void; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity. + * @param options The optional parameters + * @param callback The callback + */ + update( + endpoint: string, + id: string, + options: Models.CommunicationIdentityUpdateOptionalParams, + callback: coreHttp.ServiceCallback + ): void; + update( + endpoint: string, + id: string, + options?: Models.CommunicationIdentityUpdateOptionalParams | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + id, + options + }, + updateOperationSpec, + callback + ); + } + + /** + * @summary Generate a new token for an identity. + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to issue token for. + * @param scopes List of scopes attached to the token. + * @param [options] The optional parameters + * @returns Promise + */ + issueToken( + endpoint: string, + id: string, + scopes: string[], + options?: coreHttp.RequestOptionsBase + ): Promise; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to issue token for. + * @param scopes List of scopes attached to the token. + * @param callback The callback + */ + issueToken( + endpoint: string, + id: string, + scopes: string[], + callback: coreHttp.ServiceCallback + ): void; + /** + * @param endpoint Auth and Identity endpoint + * @param id Identifier of the identity to issue token for. + * @param scopes List of scopes attached to the token. + * @param options The optional parameters + * @param callback The callback + */ + issueToken( + endpoint: string, + id: string, + scopes: string[], + options: coreHttp.RequestOptionsBase, + callback: coreHttp.ServiceCallback + ): void; + issueToken( + endpoint: string, + id: string, + scopes: string[], + options?: + | coreHttp.RequestOptionsBase + | coreHttp.ServiceCallback, + callback?: coreHttp.ServiceCallback + ): Promise { + return this.client.sendOperationRequest( + { + endpoint, + id, + scopes, + options + }, + issueTokenOperationSpec, + callback + ) as Promise; + } +} + +// Operation Specifications +const serializer = new coreHttp.Serializer(Mappers); +const createOperationSpec: coreHttp.OperationSpec = { + httpMethod: "POST", + path: "identities", + urlParameters: [Parameters.endpoint], + queryParameters: [Parameters.apiVersion], + responses: { + 200: { + bodyMapper: Mappers.CommunicationIdentity + }, + default: {} + }, + serializer +}; + +const deleteMethodOperationSpec: coreHttp.OperationSpec = { + httpMethod: "DELETE", + path: "identities/{id}", + urlParameters: [Parameters.endpoint, Parameters.id], + queryParameters: [Parameters.apiVersion], + responses: { + 204: {}, + default: {} + }, + serializer +}; + +const updateOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PATCH", + path: "identities/{id}", + urlParameters: [Parameters.endpoint, Parameters.id], + queryParameters: [Parameters.apiVersion], + requestBody: { + parameterPath: { + tokensValidFrom: ["options", "tokensValidFrom"] + }, + mapper: { + ...Mappers.CommunicationIdentityUpdateRequest, + required: true + } + }, + contentType: "application/merge-patch+json", + responses: { + 204: {}, + default: {} + }, + serializer +}; + +const issueTokenOperationSpec: coreHttp.OperationSpec = { + httpMethod: "POST", + path: "identities/{id}/token", + urlParameters: [Parameters.endpoint, Parameters.id], + queryParameters: [Parameters.apiVersion], + requestBody: { + parameterPath: { + scopes: "scopes" + }, + mapper: { + ...Mappers.CommunicationTokenRequest, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.CommunicationIdentityToken + }, + default: {} + }, + serializer +}; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts new file mode 100644 index 000000000000..bda865874f7c --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/operations/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +export * from "./communicationIdentityOperations"; diff --git a/sdk/communication/communication-administration/src/communicationIdentity/models.ts b/sdk/communication/communication-administration/src/communicationIdentity/models.ts new file mode 100644 index 000000000000..bef1654e887a --- /dev/null +++ b/sdk/communication/communication-administration/src/communicationIdentity/models.ts @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { HttpResponse, PipelineOptions } from "@azure/core-http"; +import { CommunicationUser } from "@azure/communication-common"; +import { CommunicationIdentityToken } from "./generated/src/models"; + +/** + * Represents the scope of the token. + */ +export type TokenScope = "chat" | "voip" | "pstn"; + +/** + * Client options used to configure the CommunicationIdentity API requests. + */ +export interface CommunicationIdentityOptions extends PipelineOptions {} + +/** + * Represents an object with a non-enumerable _response property which provides + * information about the HTTP response. + */ +export type WithResponse = T & { _response: HttpResponse }; + +/** + * Represents a generic HTTP response + */ +export type VoidResponse = WithResponse<{}>; + +/** + * The issued token and the user it was issued for. + */ +export interface CommunicationUserToken + extends Pick { + /** + * Represents the user the token was issued for + */ + user: CommunicationUser; +} + +/** + * Represents the response from creating a user + */ +export type CreateUserResponse = WithResponse; + +/** + * Represents the response from issuing a token + */ +export type IssueTokenResponse = WithResponse; diff --git a/sdk/communication/communication-administration/src/index.ts b/sdk/communication/communication-administration/src/index.ts new file mode 100644 index 000000000000..145213d3f1e5 --- /dev/null +++ b/sdk/communication/communication-administration/src/index.ts @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export * from "./communicationIdentity/communicationIdentityClient"; +export * from "./communicationIdentity/models"; diff --git a/sdk/communication/communication-administration/swagger/CommunicationIdentity.md b/sdk/communication/communication-administration/swagger/CommunicationIdentity.md new file mode 100644 index 000000000000..f82df99de6e7 --- /dev/null +++ b/sdk/communication/communication-administration/swagger/CommunicationIdentity.md @@ -0,0 +1,22 @@ +# Azure Communication Services Configuration Module + +> see https://aka.ms/autorest + +## Configuration + +```yaml +package-name: azure-communication-administration-identity +title: CommunicationIdentityConfigurationClient +override-client-name: GeneratedCommunicationIdentityClient +description: Communication identity configuration client +package-version: 1.0.0-beta.1 +generate-metadata: false +license-header: MICROSOFT_MIT_NO_VERSION +output-folder: ../src/communicationIdentity/generated +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/838c5092f11e8ca26e262b1f1099d5c5cdfedc3f/specification/communication/data-plane/Microsoft.CommunicationServicesIdentity/preview/2020-07-20-preview2/CommunicationIdentity.json +model-date-time-as-string: false +optional-response-headers: true +payload-flattening-threshold: 10 +use: "@microsoft.azure/autorest.typescript@5.0.1" +azure-arm: false +``` diff --git a/sdk/communication/communication-administration/test/README.md b/sdk/communication/communication-administration/test/README.md new file mode 100644 index 000000000000..219d112a3086 --- /dev/null +++ b/sdk/communication/communication-administration/test/README.md @@ -0,0 +1,19 @@ +# Testing + +To test this project, make sure to build it by following our [building instructions](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md#building), then follow the [testing instructions](https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md#testing). + +You can use existing Azure resources for the live tests, or generate new ones by using our [New-TestResources.ps1](https://github.com/Azure/azure-sdk-for-js/blob/master/eng/common/TestResources/New-TestResources.ps1) script, which will use an [ARM template](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/textanalytics/test-resources.json) that already has all of the the necessary configurations. + +The Azure resource that is used by the tests in this project is: + +- An existing Communication Services resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. + +To run the live tests, you will need to set the below environment variables: + +- `TEST_MODE`: Should have `live` assigned if you want to run live without recording. Assign `record` to run live with recording. +- `COMMUNICATION_CONNECTION_STRING`: The primary connection string of the Communication Services resource in your account. + +[azure_sub]: https://azure.microsoft.com/free/ +[azure_portal]: https://portal.azure.com + +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fcommunication%2Fcommunication-administration%2FREADME.png) diff --git a/sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts b/sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts new file mode 100644 index 000000000000..4d8f6dca3b27 --- /dev/null +++ b/sdk/communication/communication-administration/test/communicationIdentityClient.mocked.spec.ts @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { isNode } from "@azure/core-http"; +import { CommunicationUser, isCommunicationUser } from "@azure/communication-common"; +import { assert } from "chai"; +import sinon from "sinon"; +import { CommunicationIdentityClient } from "../src"; +import { TestCommunicationIdentityClient } from "./utils/testCommunicationIdentityClient"; +import { issueTokenHttpClient, revokeTokensHttpClient } from "./utils/mockHttpClients"; + +describe("CommunicationIdentityClient [Mocked]", () => { + const dateHeader = isNode ? "date" : "x-ms-date"; + const user: CommunicationUser = { communicationUserId: "ACS_ID" }; + + afterEach(() => { + sinon.restore(); + }); + + it("creates instance of CommunicationIdentityClient", () => { + const client = new CommunicationIdentityClient( + "endpoint=https://contoso.spool.azure.local;accesskey=banana" + ); + assert.instanceOf(client, CommunicationIdentityClient); + }); + + it("sets correct headers", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(issueTokenHttpClient, "sendRequest"); + + await client.issueTokenTest(user, ["chat"]); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + + if (isNode) { + assert.equal(request.headers.get("host"), "contoso.spool.azure.local"); + } + + assert.typeOf(request.headers.get(dateHeader), "string"); + assert.isDefined(request.headers.get("authorization")); + assert.match( + request.headers.get("authorization") as string, + /HMAC-SHA256 SignedHeaders=.+&Signature=.+/ + ); + }); + + it("sends scopes in issue token request", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(issueTokenHttpClient, "sendRequest"); + const response = await client.issueTokenTest(user, ["chat"]); + + assert.equal(response.user.communicationUserId, "identity"); + assert.equal(response.token, "token"); + assert.equal(response.expiresOn.toDateString(), new Date("2011/11/30").toDateString()); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + assert.deepEqual(JSON.parse(request.body), { scopes: ["chat"] }); + }); + + it("[issueToken] excludes _response from results when stringified", async () => { + const client = new TestCommunicationIdentityClient(); + const response = await client.issueTokenTest(user, ["chat"]); + + assert.isDefined(response._response); + assert.isTrue(JSON.stringify(response).indexOf("token") > -1); + assert.isFalse(JSON.stringify(response).indexOf("_response") > -1); + }); + + it("[createUser] excludes _response from results when stringified", async () => { + const client = new TestCommunicationIdentityClient(); + const user = await client.createUserTest(); + + assert.isTrue(isCommunicationUser(user)); + assert.equal(user.communicationUserId, "identity"); + assert.isDefined(user._response); + assert.isTrue(JSON.stringify(user).indexOf("id") > -1); + assert.isFalse(JSON.stringify(user).indexOf("_response") > -1); + }); + + it("sends current datetime as value of tokensValidFrom if not passed to revokeTokens", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(revokeTokensHttpClient, "sendRequest"); + + await client.revokeTokensTest(user); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + const { tokensValidFrom: received } = JSON.parse(request.body); + + assert.isNotNaN(Date.parse(received)); + }); + + it("sends tokensValidFrom in revoke tokens request", async () => { + const client = new TestCommunicationIdentityClient(); + const spy = sinon.spy(revokeTokensHttpClient, "sendRequest"); + const tokensValidFrom = new Date("2011/11/30"); + + await client.revokeTokensTest(user, tokensValidFrom); + sinon.assert.calledOnce(spy); + + const request = spy.getCall(0).args[0]; + const { tokensValidFrom: received } = JSON.parse(request.body); + const expected = tokensValidFrom.toISOString(); + + assert.equal(received, expected); + }); +}); diff --git a/sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts b/sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts new file mode 100644 index 000000000000..40e11d38bbaf --- /dev/null +++ b/sdk/communication/communication-administration/test/communicationIdentityClient.spec.ts @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { CommunicationUser } from "@azure/communication-common"; +import { assert } from "chai"; +import { isPlaybackMode, Recorder } from "@azure/test-utils-recorder"; +import { CommunicationIdentityClient } from "../src"; +import { createRecordedCommunicationIdentityClient } from "./utils/recordedClient"; + +describe("CommunicationIdentityClient [Playback/Live]", function() { + let user: CommunicationUser; + let recorder: Recorder; + let client: CommunicationIdentityClient; + + beforeEach(function() { + ({ client, recorder } = createRecordedCommunicationIdentityClient(this)); + }); + + afterEach(async function() { + if (!this.currentTest?.isPending()) { + await recorder.stop(); + } + }); + + it("successfully creates a user", async function() { + user = await client.createUser(); + assert.isString(user.communicationUserId); + }); + + it("successfully issues a token for a user [single scope]", async function() { + const { token, expiresOn, user: receivedUser } = await client.issueToken(user, ["chat"]); + assert.isString(token); + assert.instanceOf(expiresOn, Date); + assert.deepEqual(receivedUser, user); + }); + + it("successfully issues a token for a user [multiple scopes]", async function() { + const { token, expiresOn, user: receivedUser } = await client.issueToken(user, [ + "chat", + "pstn" + ]); + assert.isString(token); + assert.instanceOf(expiresOn, Date); + assert.deepEqual(receivedUser, user); + }); + + it("successfully revokes tokens issued for a user", async function() { + const { _response: response } = await client.revokeTokens( + user, + // Must set tokensValidFrom if in playback mode so date strings will match + // when Nock searches for requests + isPlaybackMode() ? new Date("2020-10-10T00:00:00.000Z") : undefined + ); + assert.equal(response.status, 204); + const { tokensValidFrom } = JSON.parse(response.request.body); + assert.isNotNaN(Date.parse(tokensValidFrom)); + }); + + it("successfully deletes a user", async function() { + const { _response: response } = await client.deleteUser(user); + assert.equal(response.status, 204); + }).timeout(20000); +}); diff --git a/sdk/communication/communication-administration/test/utils/mockHttpClients.ts b/sdk/communication/communication-administration/test/utils/mockHttpClients.ts new file mode 100644 index 000000000000..3a07f402b634 --- /dev/null +++ b/sdk/communication/communication-administration/test/utils/mockHttpClients.ts @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { HttpClient, WebResourceLike, HttpOperationResponse, HttpHeaders } from "@azure/core-http"; +import { CommunicationIdentityToken } from "../../src"; +import { CommunicationIdentity } from "../../src/communicationIdentity/generated/src/models"; + +export const createMockHttpClient = (status: number = 200, parsedBody?: T): HttpClient => { + return { + async sendRequest(httpRequest: WebResourceLike): Promise { + return { + status, + headers: new HttpHeaders(), + request: httpRequest, + parsedBody + }; + } + }; +}; + +const tokenResponse = { + id: "identity", + token: "token", + expiresOn: new Date("2011/11/30") +}; +export const issueTokenHttpClient: HttpClient = createMockHttpClient( + 200, + tokenResponse +); +export const revokeTokensHttpClient: HttpClient = createMockHttpClient(204); +export const createUserHttpClient: HttpClient = createMockHttpClient(200, { + id: "identity" +}); diff --git a/sdk/communication/communication-administration/test/utils/recordedClient.ts b/sdk/communication/communication-administration/test/utils/recordedClient.ts new file mode 100644 index 000000000000..48dde8b490b7 --- /dev/null +++ b/sdk/communication/communication-administration/test/utils/recordedClient.ts @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Context } from "mocha"; +import * as dotenv from "dotenv"; + +import { env, Recorder, record, RecorderEnvironmentSetup } from "@azure/test-utils-recorder"; +import { isNode } from "@azure/core-http"; +import { CommunicationIdentityClient } from "../../src"; + +if (isNode) { + dotenv.config(); +} + +export interface RecordedClient { + client: CommunicationIdentityClient; + recorder: Recorder; +} + +const replaceableVariables: { [k: string]: string } = { + COMMUNICATION_CONNECTION_STRING: "endpoint=https://endpoint/;accesskey=banana" +}; + +export const testEnv = new Proxy(replaceableVariables, { + get: (target, key: string) => { + return env[key] || target[key]; + } +}); + +export const environmentSetup: RecorderEnvironmentSetup = { + replaceableVariables, + customizationsOnRecordings: [ + (recording: string): string => + recording.replace(/"token"\s?:\s?"[^"]*"/g, `"token":"sanitized"`), + (recording: string): string => recording.replace(/(https:\/\/)([^\/',]*)/, "$1endpoint"), + /** + * Must replace date saved to tokensValidFrom as to not + * break playback tests. + */ + (recording: string): string => { + return recording.replace( + /"tokensValidFrom"\s?:\s?"[^"]*"/g, + `"tokensValidFrom":"2020-10-10T00:00:00.000Z"` + ); + }, + (recording: string): string => recording.replace(/"id"\s?:\s?"[^"]*"/g, `"id":"sanitized"`), + (recording: string): string => { + return recording.replace( + /(https:\/\/[^\/',]*\/identities\/)[^\/',]*(\/token)/, + "$1sanitized$2" + ); + }, + (recording: string): string => + recording.replace(/\/identities\/[^\/'",]*/, "/identities/sanitized") + ], + queryParametersToSkip: [] +}; + +export function createRecordedCommunicationIdentityClient( + context: Context, + connectionString: string = testEnv.COMMUNICATION_CONNECTION_STRING +): RecordedClient { + const recorder = record(context, environmentSetup); + + return { + client: new CommunicationIdentityClient(connectionString), + recorder + }; +} diff --git a/sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts b/sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts new file mode 100644 index 000000000000..73c08cfc9e99 --- /dev/null +++ b/sdk/communication/communication-administration/test/utils/testCommunicationIdentityClient.ts @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { OperationOptions, RestResponse } from "@azure/core-http"; +import { CommunicationUser } from "@azure/communication-common"; +import { + CommunicationIdentityClient, + TokenScope, + IssueTokenResponse, + CreateUserResponse +} from "../../src"; +import { + issueTokenHttpClient, + createUserHttpClient, + revokeTokensHttpClient +} from "./mockHttpClients"; + +export class TestCommunicationIdentityClient { + private connectionString: string = "endpoint=https://contoso.spool.azure.local;accesskey=banana"; + + public async issueTokenTest( + user: CommunicationUser, + scopes: TokenScope[], + options: OperationOptions = {} + ): Promise { + const client = new CommunicationIdentityClient(this.connectionString, { + httpClient: issueTokenHttpClient + }); + return client.issueToken(user, scopes, options); + } + + public async revokeTokensTest( + user: CommunicationUser, + revocationTime?: Date, + options: OperationOptions = {} + ): Promise { + const client = new CommunicationIdentityClient(this.connectionString, { + httpClient: revokeTokensHttpClient + }); + return client.revokeTokens(user, revocationTime, options); + } + + public async createUserTest(options: OperationOptions = {}): Promise { + const client = new CommunicationIdentityClient(this.connectionString, { + httpClient: createUserHttpClient + }); + return client.createUser(options); + } +} diff --git a/sdk/communication/communication-administration/tests.yml b/sdk/communication/communication-administration/tests.yml new file mode 100644 index 000000000000..b9277f1edcc7 --- /dev/null +++ b/sdk/communication/communication-administration/tests.yml @@ -0,0 +1,8 @@ +trigger: none + +extends: + template: ../../../eng/pipelines/templates/jobs/archetype-sdk-integration.yml + parameters: + PackageName: "@azure/communication-administration" + ResourceServiceDirectory: communication + \ No newline at end of file diff --git a/sdk/communication/communication-administration/tsconfig.json b/sdk/communication/communication-administration/tsconfig.json new file mode 100644 index 000000000000..01b339f5a963 --- /dev/null +++ b/sdk/communication/communication-administration/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../tsconfig.package", + "compilerOptions": { + "outDir": "./dist-esm", + "declarationDir": "./types" + }, + "exclude": [ + "node_modules", + "types", + "temp", + "browser", + "dist", + "dist-esm", + "dist-samples", + "./samples/**/*.ts" + ] +} diff --git a/sdk/communication/communication-chat/.eslintrc.json b/sdk/communication/communication-chat/.eslintrc.json new file mode 100644 index 000000000000..9bd67fdc87a5 --- /dev/null +++ b/sdk/communication/communication-chat/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-naming-options": "off" + // "@azure/azure-sdk/ts-config-declaration": "off", + // "@azure/azure-sdk/ts-config-allowsyntheticdefaultimports": "off", + // "@azure/azure-sdk/ts-config-esmoduleinterop": "off", + // "@azure/azure-sdk/ts-config-forceconsistentcasinginfilenames": "off", + // "@azure/azure-sdk/ts-config-importhelpers": "off", + // "@azure/azure-sdk/ts-config-module": "off", + // "@azure/azure-sdk/ts-config-moduleresolution": "off", + // "@azure/azure-sdk/ts-config-sourcemap": "off", + // "@azure/azure-sdk/ts-config-strict": "off", + // "@azure/azure-sdk/ts-config-target": "off", + // "@azure/azure-sdk/ts-config-lib": "off" + } +} diff --git a/sdk/communication/communication-chat/.gitignore b/sdk/communication/communication-chat/.gitignore new file mode 100644 index 000000000000..e35e6c4bbeb0 --- /dev/null +++ b/sdk/communication/communication-chat/.gitignore @@ -0,0 +1 @@ +/**/code-model-v* \ No newline at end of file diff --git a/sdk/communication/communication-chat/.vscode/launch.json b/sdk/communication/communication-chat/.vscode/launch.json new file mode 100644 index 000000000000..458b9b5c32c6 --- /dev/null +++ b/sdk/communication/communication-chat/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Mocha Test [Without Rollup]", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-r", + "ts-node/register", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/*.spec.ts", + "${workspaceFolder}/test/node/*.spec.ts" + ], + "env": { + "TS_NODE_COMPILER_OPTIONS": "{\"module\": \"commonjs\"}" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "protocol": "inspector" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Unit Tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-u", + "tdd", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/dist-test/index.node.js" + ], + "internalConsoleOptions": "openOnSessionStart", + "preLaunchTask": "npm: build:test" + } + ] +} diff --git a/sdk/communication/communication-chat/.vscode/tasks.json b/sdk/communication/communication-chat/.vscode/tasks.json new file mode 100644 index 000000000000..83bb44526db4 --- /dev/null +++ b/sdk/communication/communication-chat/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Node", + "type": "npm", + "script": "build:node", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/sdk/communication/communication-chat/CHANGELOG.md b/sdk/communication/communication-chat/CHANGELOG.md new file mode 100644 index 000000000000..b2c7e4ac4197 --- /dev/null +++ b/sdk/communication/communication-chat/CHANGELOG.md @@ -0,0 +1,13 @@ +# Release History + +## 1.0.0-beta.1 (2020-09-22) + +The first preview of the Azure Communication Chat Client has the following features: + +- create/get/update/delete a chat thread +- list all chat threads the user join +- create/get/update/delete a chat message +- list all chat messages in a chat thread +- add members in a chat thread +- delete a member in a chat thread +- list all members in a chat thread diff --git a/sdk/communication/communication-chat/LICENSE b/sdk/communication/communication-chat/LICENSE new file mode 100644 index 000000000000..ea8fb1516028 --- /dev/null +++ b/sdk/communication/communication-chat/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/communication/communication-chat/README.md b/sdk/communication/communication-chat/README.md new file mode 100644 index 000000000000..c4b112c92c77 --- /dev/null +++ b/sdk/communication/communication-chat/README.md @@ -0,0 +1,190 @@ +# Azure Communication Chat client library for JavaScript + +Azure Communication Services for Chat let developers add Chat capabilities to their app. Use this client library to manage chat threads and their users, and send and receive Chat messages. + +Read more about Azure Communication Services [here](https://review.docs.microsoft.com/azure/project-spool/overview?branch=pr-en-us-104477) + +## Getting started + +## Prerequisites + +- An [Azure subscription][azure_sub]. +- An existing Communication Services resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. +- [Node.js](https://nodejs.org) + +### Installing + +```bash +npm install @azure/communication-chat +``` + +## Key concepts + +A chat conversation is represented by a thread. Each user in the thread is called a thread member. Thread members can chat with one another privately in a 1:1 chat or huddle up in a 1:N group chat. Users also get near-real time updates for when others are typing and when they have read the messages. + +### ChatClient + +`ChatClient` is the primary interface for developers using this client library. It provides asynchronous methods to create and delete a thread. + +### ChatThreadClient + +`ChatThreadClient` provides asynchronous methods to do the message and chat thread members operations within the chat thread. + +## Examples + +### Initialize ChatClient + +Use resource url and user access token to initialize chat client. + +```JavaScript +import { ChatClient } from '@azure/communicationservices-chat'; +import { AzureCommunicationUserCredential } from "@azure/communication-common"; + +// Your unique Azure Communication service endpoint +let endpointUrl = ''; +let userAccessToken = ''; +let userCredential = new AzureCommunicationUserCredential(userAccessToken); +let chatClient = new ChatClient(endpointUrl, userCredential); + +``` + +### Create a thread with two users + +Use the `createThread` method to create a chat thread. + +`createThreadRequest` is used to describe the thread request: + +- Use `topic` to give a thread topic; +- Use `members` to list the thread members to be added to the thread; + +`chatThreadClient` is the response returned from creating a thread, it contains an `threadId` which is the unique ID of the thread. + +```Javascript +let createThreadRequest = +{ + topic: 'Preparation for London conference', + members: + [ + { + user: { communicationUserId: '' }, + displayName: 'Jack' + }, + { + user: { communicationUserId: '' }, + displayName: 'Geeta' + } + ] +}; +let chatThreadClient= await chatClient.createChatThread(createThreadRequest); +let threadId = chatThreadClient.threadId; +``` + +### Send a message to the thread + +Use `sendMessage` method to sends a message to a thread identified by threadId. + +`sendMessageRequest` is used to describe the message request: + +- Use `content` to provide the chat message content; + +`sendMessageOptions` is used to describe the operation optional params: + +- Use `priority` to specify the message priority level, such as 'Normal' or 'High' ; +- Use `senderDisplayName` to specify the display name of the sender; + +`sendChatMessageResult` is the response returned from sending a message, it contains an ID, which is the unique ID of the message. + +```JavaScript +let sendMessageRequest = +{ + content: 'Hello Geeta! Can you share the deck for the conference?' +}; +let sendMessageOptions = +{ + priority: 'Normal', + senderDisplayName : 'Jack' +}; +let sendChatMessageResult = await chatThreadClient.sendMessage(sendMessageRequest, sendMessageOptions); +let messageId = sendChatMessageResult.id; +``` + +### Receive messages from a thread + +With real-time signaling, you can subscribe to listen for new incoming messages and update the current messages in memory accordingly. + +```JavaScript + +// open notifications channel +await chatClient.startRealtimeNotifications(); +// subscribe to new notification +chatClient.on("chatMessageReceived", (e) => { + console.log("Notification chatMessageReceived!"); + // your code here +}); + +``` + +Alternatively you can retrieve chat messages by polling the `listMessages` method at specified intervals. + +```JavaScript +for await (const chatMessage of chatThreadClient.listMessages()) { + // your code here +} +``` + +### Add Users to a thread + +Once a thread is created, you can then add and remove users from that thread. By adding users, you give them access to be able to send messages to the thread. +You will need to start by getting a new access token and identity for that user. The user will need that access token in order to initialize their chat client. +More information on tokens here: [Authenticate to Azure Communication Services](https://review.docs.microsoft.com/azure/project-spool/concepts/authentication?branch=pr-en-us-104477&tabs=javascript) + +```JavaScript +// Get a new token created for the user. The token response will contain a token and an identity for the user. +let userTokenResponse = await myTokenFunction(); + +let addMembersRequest = +{ + members: [ + { + user: { communicationUserId: userTokenResponse.identity }, + displayName: '', + shareHistoryTime: '