From dfb933d938ec547b3e054ee8a505d79774c2b0eb Mon Sep 17 00:00:00 2001 From: Will Temple <77019085+witemple-msft@users.noreply.github.com> Date: Thu, 4 Feb 2021 17:24:15 -0500 Subject: [PATCH] [template] Replace existing template package with tutorial client (#13467) * [template] Replaced template with tutorial appconfig SDK * Retained old changelog and version information. * Lint * Fixed recordings to use stable values * Remove unnecessary getEnv function * Addressed some feedback items * Added some docs * Renamed an env var, added some docs to sample README * Added live testing configuration for template * Fixed some sample links * Improved samples * Fixed missing docs command, renamed smokeTestConfiguration * Added missing typedoc dependency * Final feedback items * Regenerate API.md * Use createSpanFunction instead of defining the span function manually. * Removed extra deps * Fixed readme issues, use App Config README for example instead of TA. * Karma single run --- common/config/rush/pnpm-lock.yaml | 222 +-- sdk/template/template/CHANGELOG.md | 17 +- sdk/template/template/README-EXAMPLE.md | 188 +++ sdk/template/template/README-TEMPLATE.md | 424 ------ sdk/template/template/README.md | 79 +- sdk/template/template/karma.conf.js | 44 +- sdk/template/template/package.json | 39 +- ...determined_setting_has_expected_value.json | 56 + ...redetermined_setting_has_expected_value.js | 72 + sdk/template/template/review/template.api.md | 41 +- sdk/template/template/sample.env | 33 +- .../template/samples/javascript/README.md | 43 +- .../javascript/getConfigurationSetting.js | 25 + .../template/samples/javascript/package.json | 2 +- .../template/samples/javascript/sample.env | 7 +- .../samples/javascript/sampleTemplate.js | 27 - sdk/template/template/samples/tsconfig.json | 2 +- .../template/samples/typescript/README.md | 43 +- .../template/samples/typescript/package.json | 2 +- .../template/samples/typescript/sample.env | 5 +- .../typescript/src/getConfigurationSetting.ts | 25 + .../samples/typescript/src/sampleTemplate.ts | 27 - .../template/samples/typescript/tsconfig.json | 31 +- .../template/src/configurationClient.ts | 182 +++ .../template/src/{print.ts => constants.ts} | 4 +- .../template/src/generated/generatedClient.ts | 794 ++++++++++ .../src/generated/generatedClientContext.ts | 53 + sdk/template/template/src/generated/index.ts | 11 + .../template/src/generated/models/index.ts | 704 +++++++++ .../template/src/generated/models/mappers.ts | 538 +++++++ .../src/generated/models/parameters.ts | 255 ++++ sdk/template/template/src/index.ts | 32 +- sdk/template/template/src/logger.ts | 11 + sdk/template/template/src/print.browser.ts | 13 - sdk/template/template/src/tracing.ts | 17 + sdk/template/template/src/util.ts | 29 + sdk/template/template/swagger/README.md | 43 + .../template/swagger/appconfiguration.json | 1351 +++++++++++++++++ .../test/browser/sampleBrowser.spec.ts | 14 - .../template/test/internal/basic.spec.ts | 42 + sdk/template/template/test/node/index.spec.ts | 19 - .../test/public/configurationClient.spec.ts | 103 ++ sdk/template/template/tests.yml | 12 + sdk/template/test-resources.json | 73 + 44 files changed, 4972 insertions(+), 782 deletions(-) create mode 100644 sdk/template/template/README-EXAMPLE.md delete mode 100644 sdk/template/template/README-TEMPLATE.md create mode 100644 sdk/template/template/recordings/browsers/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.json create mode 100644 sdk/template/template/recordings/node/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.js create mode 100644 sdk/template/template/samples/javascript/getConfigurationSetting.js delete mode 100644 sdk/template/template/samples/javascript/sampleTemplate.js create mode 100644 sdk/template/template/samples/typescript/src/getConfigurationSetting.ts delete mode 100644 sdk/template/template/samples/typescript/src/sampleTemplate.ts create mode 100644 sdk/template/template/src/configurationClient.ts rename sdk/template/template/src/{print.ts => constants.ts} (53%) create mode 100644 sdk/template/template/src/generated/generatedClient.ts create mode 100644 sdk/template/template/src/generated/generatedClientContext.ts create mode 100644 sdk/template/template/src/generated/index.ts create mode 100644 sdk/template/template/src/generated/models/index.ts create mode 100644 sdk/template/template/src/generated/models/mappers.ts create mode 100644 sdk/template/template/src/generated/models/parameters.ts create mode 100644 sdk/template/template/src/logger.ts delete mode 100644 sdk/template/template/src/print.browser.ts create mode 100644 sdk/template/template/src/tracing.ts create mode 100644 sdk/template/template/src/util.ts create mode 100644 sdk/template/template/swagger/README.md create mode 100644 sdk/template/template/swagger/appconfiguration.json delete mode 100644 sdk/template/template/test/browser/sampleBrowser.spec.ts create mode 100644 sdk/template/template/test/internal/basic.spec.ts delete mode 100644 sdk/template/template/test/node/index.spec.ts create mode 100644 sdk/template/template/test/public/configurationClient.spec.ts create mode 100644 sdk/template/template/tests.yml create mode 100644 sdk/template/test-resources.json diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index d07284670ac0..1168f3c0a88e 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -1020,12 +1020,12 @@ packages: dev: false resolution: integrity: sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== - /@types/yargs/15.0.12: + /@types/yargs/15.0.13: dependencies: '@types/yargs-parser': 20.2.0 dev: false resolution: - integrity: sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== + integrity: sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== /@types/yauzl/2.9.1: dependencies: '@types/node': 10.17.51 @@ -1616,14 +1616,14 @@ packages: node: '>=8' resolution: integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - /bl/4.0.3: + /bl/4.0.4: dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.0 dev: false resolution: - integrity: sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== + integrity: sha512-7tdr4EpSd7jJ6tuQ21vu2ke8w7pNEstzj1O8wwq6sNNzO3UDi5MA8Gny/gquCj7r2C6fHudg8tKRGyjRgmvNxQ== /blob/0.0.5: dev: false resolution: @@ -1751,33 +1751,33 @@ packages: dev: false resolution: integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - /chai-as-promised/7.1.1_chai@4.2.0: + /chai-as-promised/7.1.1_chai@4.3.0: dependencies: - chai: 4.2.0 + chai: 4.3.0 check-error: 1.0.2 dev: false peerDependencies: chai: '>= 2.1.2 < 5' resolution: integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - /chai-exclude/2.0.2_chai@4.2.0: + /chai-exclude/2.0.2_chai@4.3.0: dependencies: - chai: 4.2.0 + chai: 4.3.0 fclone: 1.0.11 dev: false peerDependencies: chai: '>= 4.0.0 < 5' resolution: integrity: sha512-QmNVnvdSw8Huccdjm49mKu3HtoHxvjdavgYkY0KPQ5MI5UWfbc9sX1YqRgaMPf2GGtDXPoF2ram3AeNS4945Xw== - /chai-string/1.5.0_chai@4.2.0: + /chai-string/1.5.0_chai@4.3.0: dependencies: - chai: 4.2.0 + chai: 4.3.0 dev: false peerDependencies: chai: ^4.1.2 resolution: integrity: sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw== - /chai/4.2.0: + /chai/4.3.0: dependencies: assertion-error: 1.1.0 check-error: 1.0.2 @@ -1787,9 +1787,9 @@ packages: type-detect: 4.0.8 dev: false engines: - node: '>=4' + node: '>=8' resolution: - integrity: sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + integrity: sha512-/BFd2J30EcOwmdOgXvVsmM48l0Br0nmZPlO0uOW4XKh6kpsUumRXBgPV+IlaqFaqr9cYbeoZAM1Npx0i4A+aiA== /chalk/1.1.3: dependencies: ansi-styles: 2.2.1 @@ -2590,6 +2590,16 @@ packages: eslint: '>=4.19.1' resolution: integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + /eslint-plugin-no-null/1.0.2_eslint@7.19.0: + dependencies: + eslint: 7.19.0 + dev: false + engines: + node: '>=5.0.0' + peerDependencies: + eslint: '>=3.0.0' + resolution: + integrity: sha1-EjaoEjkTkKGHetQAfCbnRTQclR8= /eslint-plugin-no-only-tests/2.4.0: dev: false engines: @@ -4216,9 +4226,9 @@ packages: dev: false resolution: integrity: sha1-fYa9VmefWM5qhHBKZX3TkruoGnk= - /karma-chai/0.1.0_chai@4.2.0+karma@5.2.3: + /karma-chai/0.1.0_chai@4.3.0+karma@5.2.3: dependencies: - chai: 4.2.0 + chai: 4.3.0 karma: 5.2.3 dev: false peerDependencies: @@ -4406,15 +4416,15 @@ packages: debug: '*' resolution: integrity: sha512-tHdyFADhVVPBorIKCX8A37iLHxc6RBRphkSoQ+MLKdAtFn1k97tD8WUGi1KlEtDZKL3hui0qhsY9HXUfSNDYPQ== - /keytar/5.6.0: + /keytar/7.3.0: dependencies: - nan: 2.14.1 - prebuild-install: 5.3.3 + node-addon-api: 3.1.0 + prebuild-install: 6.0.0 dev: false optional: true requiresBuild: true resolution: - integrity: sha512-ueulhshHSGoryfRXaIvTj0BV1yB0KddBGhGoqCxSN9LR1Ks1GKuuCdVhF+2/YOs5fMl6MlTI9On1a4DHDXoTow== + integrity: sha512-t8YD0ETO5AeRxCaaN4N/hzj3JusIH0ugjVooE724+ozaVG9+l16Mau62T+U8tEhCv7SozY/g69BWF1U+o47qJg== /lazy-ass/1.6.0: dev: false engines: @@ -4842,11 +4852,6 @@ packages: node: '>=0.8.0' resolution: integrity: sha512-tKn7j7QXfH5GHtOQ2edbFmylN8z8g2bfBWU3tmZ/b09fXDQt+pelfQ0NKNu1hso83sLXjEKHF1XIbjAqVGYSsA== - /nan/2.14.1: - dev: false - optional: true - resolution: - integrity: sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== /nanoid/3.1.20: dev: false engines: @@ -4919,6 +4924,11 @@ packages: dev: false resolution: integrity: sha512-dEYmUqjtbivotqjraOe8UvhT/poFfog1BQRNsZm/MSEDDESk2cQ1tvD8kGyuN07TM/zoW+n42odL8zTeJupYdQ== + /node-addon-api/3.1.0: + dev: false + optional: true + resolution: + integrity: sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== /node-environment-flags/1.0.6: dependencies: object.getownpropertydescriptors: 2.1.1 @@ -5374,13 +5384,13 @@ packages: node: '>=4' resolution: integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== - /prebuild-install/5.3.3: + /prebuild-install/6.0.0: dependencies: detect-libc: 1.0.3 expand-template: 2.0.3 github-from-package: 0.0.0 minimist: 1.2.5 - mkdirp: 0.5.5 + mkdirp-classic: 0.5.3 napi-build-utils: 1.0.2 node-abi: 2.19.3 noop-logger: 0.1.1 @@ -5397,7 +5407,7 @@ packages: hasBin: true optional: true resolution: - integrity: sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g== + integrity: sha512-h2ZJ1PXHKWZpp1caLw0oX9sagVpL2YTk+ZwInQbQ3QqNd4J03O6MpFNmMTJlkfgPENWqe5kP0WjQLqz5OjLfsw== /prelude-ls/1.1.2: dev: false engines: @@ -6597,7 +6607,7 @@ packages: integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== /tar-stream/2.2.0: dependencies: - bl: 4.0.3 + bl: 4.0.4 end-of-stream: 1.4.4 fs-constants: 1.0.0 inherits: 2.0.4 @@ -7410,7 +7420,7 @@ packages: '@types/chai': 4.2.14 '@types/mocha': 7.0.2 '@types/node': 8.10.66 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 csv-parse: 4.15.1 dotenv: 8.2.0 @@ -7456,8 +7466,8 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.10 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7500,8 +7510,8 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.10 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7546,8 +7556,8 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.10 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7599,7 +7609,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7647,8 +7657,8 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 buffer: 5.7.1 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 dotenv: 8.2.0 eslint: 7.19.0 jsrsasign: 10.1.5 @@ -7700,7 +7710,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7755,7 +7765,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7811,8 +7821,8 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 eslint: 7.19.0 events: 3.2.0 @@ -7865,7 +7875,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7919,7 +7929,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -7977,8 +7987,8 @@ packages: assert: 1.5.0 async-lock: 1.2.8 buffer: 5.7.1 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 debug: 4.3.1 dotenv: 8.2.0 @@ -8077,7 +8087,7 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.10 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 downlevel-dts: 0.4.0 eslint: 7.19.0 @@ -8125,7 +8135,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 downlevel-dts: 0.4.0 eslint: 7.19.0 @@ -8179,7 +8189,7 @@ packages: '@types/uuid': 8.3.0 '@types/xml2js': 0.4.8 babel-runtime: 6.26.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 downlevel-dts: 0.4.0 eslint: 7.19.0 @@ -8188,7 +8198,7 @@ packages: form-data: 3.0.0 glob: 7.1.6 karma: 5.2.3 - karma-chai: 0.1.0_chai@4.2.0+karma@5.2.3 + karma-chai: 0.1.0_chai@4.3.0+karma@5.2.3 karma-chrome-launcher: 3.1.0 karma-edge-launcher: 0.4.2_karma@5.2.3 karma-firefox-launcher: 1.3.0 @@ -8241,7 +8251,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 '@types/uuid': 8.3.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 downlevel-dts: 0.4.0 eslint: 7.19.0 @@ -8292,7 +8302,7 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 eslint: 7.19.0 events: 3.2.0 karma: 5.2.3 @@ -8389,7 +8399,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 '@types/xml2js': 0.4.8 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 downlevel-dts: 0.4.0 eslint: 7.19.0 @@ -8496,7 +8506,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 '@types/uuid': 8.3.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 downlevel-dts: 0.4.0 @@ -8551,8 +8561,8 @@ packages: '@types/node': 8.10.66 '@types/prettier': 2.0.2 builtin-modules: 3.1.0 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 chalk: 3.0.0 eslint: 7.19.0 fs-extra: 8.1.0 @@ -8586,7 +8596,7 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.10 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -8638,7 +8648,7 @@ packages: '@typescript-eslint/experimental-utils': 4.13.0_eslint@7.19.0+typescript@4.1.2 '@typescript-eslint/parser': 4.13.0_eslint@7.19.0+typescript@4.1.2 '@typescript-eslint/typescript-estree': 4.13.0_typescript@4.1.2 - chai: 4.2.0 + chai: 4.3.0 eslint: 7.19.0 eslint-config-prettier: 7.2.0_eslint@7.19.0 eslint-plugin-no-only-tests: 2.4.0 @@ -8684,9 +8694,9 @@ packages: '@types/ws': 7.4.0 assert: 1.5.0 buffer: 5.7.1 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 - chai-string: 1.5.0_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 + chai-string: 1.5.0_chai@4.3.0 cross-env: 7.0.3 debug: 4.3.1 dotenv: 8.2.0 @@ -8754,9 +8764,9 @@ packages: '@types/ws': 7.4.0 async-lock: 1.2.8 azure-storage: 2.10.3 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 - chai-string: 1.5.0_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 + chai-string: 1.5.0_chai@4.3.0 cross-env: 7.0.3 debug: 4.3.1 dotenv: 8.2.0 @@ -8799,8 +8809,8 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 '@types/uuid': 8.3.0 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -8856,9 +8866,9 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 assert: 1.5.0 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 - chai-string: 1.5.0_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 + chai-string: 1.5.0_chai@4.3.0 cross-env: 7.0.3 debug: 4.3.1 dotenv: 8.2.0 @@ -8955,9 +8965,9 @@ packages: dev: false name: '@rush-temp/identity' optionalDependencies: - keytar: 5.6.0 + keytar: 7.3.0 resolution: - integrity: sha512-QtPXzTEtOsTApcZ/bzkdCsoygqD5EKCEo+E2zmSY1jOPSI6VkJUWJTzy919QR9msCP7G/+dte+il4emxRgynzQ== + integrity: sha512-DI6V3LwBVB+UVC00ACz81o8AQ4mwfC/0svNRmi1dmWF7prsm8FrB4Htlr9MFyN4fd3U8Gzy0L4yHkhIz60YCZg== tarball: file:projects/identity.tgz version: 0.0.0 file:projects/keyvault-admin.tgz: @@ -8977,8 +8987,8 @@ packages: '@types/sinon': 9.0.10 '@types/uuid': 8.3.0 assert: 1.5.0 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9021,7 +9031,7 @@ packages: '@types/query-string': 6.2.0 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9089,12 +9099,14 @@ packages: '@rollup/plugin-node-resolve': 8.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.3.4_rollup@1.32.1 '@types/chai': 4.2.14 + '@types/chai-as-promised': 7.1.3 '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/query-string': 6.2.0 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9133,7 +9145,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-FBv4UmvUcBH10v1TQRJfbHSFUUn+nrnjceC4jClIpp2QrEUbN5YXKuI9uOU2J1RYXLWY4CaV2rSWd20b3xVw4g== + integrity: sha512-2T3z2w3gA8WLmpZNCAXxQPEkyE3yiO6cOBHKt/UEXwCris9pvqpkfbMcEmkaX+gWwiNt0ptXJlnysziiiB7Auw== tarball: file:projects/keyvault-keys.tgz version: 0.0.0 file:projects/keyvault-secrets.tgz: @@ -9152,7 +9164,7 @@ packages: '@types/query-string': 6.2.0 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9206,7 +9218,7 @@ packages: '@types/node': 8.10.66 '@types/sinon': 9.0.10 assert: 1.5.0 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 delay: 4.4.1 dotenv: 8.2.0 @@ -9285,11 +9297,12 @@ packages: '@types/mocha': 7.0.2 '@types/node': 10.17.51 '@types/sinon': 9.0.10 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 - esm: 3.2.25 + events: 3.2.0 + inherits: 2.0.4 karma: 5.2.3 karma-chrome-launcher: 3.1.0 karma-coverage: 2.0.3 @@ -9317,11 +9330,11 @@ packages: tslib: 2.1.0 typedoc: 0.15.2 typescript: 4.1.2 - uglify-js: 3.12.6 + util: 0.12.3 dev: false name: '@rush-temp/quantum-jobs' resolution: - integrity: sha512-XPouSBvla9KRgRxU/dQ/8mJ+L5B+rLucQvMFp0BahqpAHFMmZ625YWEMThQ9GuNhoOQvNC5hpIuiQV+CSON4tQ== + integrity: sha512-7vaErqG6JWDYUBBD/kum3Ckp5k0OCRyWtFWzZQPGlGEKQpTXtbuujjcK184m8CMLQxNlGD8+azVUhEy4Pj0DoQ== tarball: file:projects/quantum-jobs.tgz version: 0.0.0 file:projects/schema-registry-avro.tgz: @@ -9330,6 +9343,7 @@ packages: '@opentelemetry/api': 0.10.2 '@rollup/plugin-commonjs': 11.0.2_rollup@1.32.1 '@rollup/plugin-inject': 4.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.4.0_rollup@1.32.1 '@rollup/plugin-replace': 2.3.4_rollup@1.32.1 @@ -9339,8 +9353,8 @@ packages: '@types/node': 8.10.66 avsc: 5.5.3 buffer: 5.7.1 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9375,7 +9389,7 @@ packages: dev: false name: '@rush-temp/schema-registry-avro' resolution: - integrity: sha512-FSKWxjelU6wX3uFeBZ/WaAfaCTHjfhqwEIZ5a4OhgDlktjor3xjdcZgc+UEx9Sga6xfwE9+cM2QxMnFIoSkPYg== + integrity: sha512-WIat3YB9zIgvgNyg7brxLCN7gCiDyhVx2iFgF5Is+4y/MNTOf1cDxmq2rAdJLVD+2+H3d0+S0XylwmSLykRBTg== tarball: file:projects/schema-registry-avro.tgz version: 0.0.0 file:projects/schema-registry.tgz: @@ -9391,8 +9405,8 @@ packages: '@types/chai-as-promised': 7.1.3 '@types/mocha': 7.0.2 '@types/node': 8.10.66 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9443,7 +9457,7 @@ packages: '@types/mocha': 7.0.2 '@types/node': 8.10.66 '@types/sinon': 9.0.10 - chai: 4.2.0 + chai: 4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 @@ -9507,9 +9521,9 @@ packages: '@types/ws': 7.4.0 assert: 1.5.0 buffer: 5.7.1 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 - chai-exclude: 2.0.2_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 + chai-exclude: 2.0.2_chai@4.3.0 cross-env: 7.0.3 debug: 4.3.1 delay: 4.4.1 @@ -9557,7 +9571,7 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-WzR4R9h7IwmBSij3j7ToynpbAFvjcHMt669AvyVEaTLYqbWXjx1zK+kfOO8t/S5ZVhYBBdNj4U1PDt8UWBfj3Q== + integrity: sha512-kkDyNrEU+rumWnaczL6uTraDLrhTEI2V5atnyevxiUjGjPYR+jJ1mgXFTuBQdwO+bMgM/1u11N7zJUc6lrByWw== tarball: file:projects/service-bus.tgz version: 0.0.0 file:projects/storage-blob-changefeed.tgz: @@ -10008,12 +10022,17 @@ packages: '@types/chai-as-promised': 7.1.3 '@types/mocha': 7.0.2 '@types/node': 8.10.66 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + '@typescript-eslint/eslint-plugin': 4.13.0_85649cb1d193687858ee685cdd7abf38 + '@typescript-eslint/parser': 4.13.0_eslint@7.19.0+typescript@4.1.2 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 cross-env: 7.0.3 dotenv: 8.2.0 eslint: 7.19.0 - events: 3.2.0 + eslint-config-prettier: 7.2.0_eslint@7.19.0 + eslint-plugin-no-null: 1.0.2_eslint@7.19.0 + eslint-plugin-no-only-tests: 2.4.0 + eslint-plugin-promise: 4.2.1 inherits: 2.0.4 karma: 5.2.3 karma-chrome-launcher: 3.1.0 @@ -10022,10 +10041,11 @@ packages: karma-env-preprocessor: 0.1.1 karma-firefox-launcher: 1.3.0 karma-ie-launcher: 1.0.0_karma@5.2.3 + karma-json-preprocessor: 0.3.3_karma@5.2.3 + karma-json-to-file-reporter: 1.0.1 karma-junit-reporter: 2.0.1_karma@5.2.3 karma-mocha: 2.0.1 karma-mocha-reporter: 2.2.5_karma@5.2.3 - karma-sourcemap-loader: 0.3.8 mocha: 7.2.0 mocha-junit-reporter: 1.23.3_mocha@7.2.0 nyc: 14.1.1 @@ -10039,7 +10059,7 @@ packages: dev: false name: '@rush-temp/template' resolution: - integrity: sha512-M26tlOJgHjSJ/kRfg/xxZFuJxV1aAG7V0RY79FopzVxBxUwA2Ca/+HJDzb5QiSmTbKjJUruBd8YjwMvl79WprA== + integrity: sha512-7vYHfS2+EcYRylnk5SStmqNPqVsLPsiTiPE8kw2iSGR2+euWvPBxdL8WY75tYH8f+Q75d9wVqjodMJfMJL2o3g== tarball: file:projects/template.tgz version: 0.0.0 file:projects/test-utils-multi-version.tgz: @@ -10048,8 +10068,8 @@ packages: '@types/chai': 4.2.14 '@types/mocha': 7.0.2 '@types/node': 8.10.66 - chai: 4.2.0 - chai-as-promised: 7.1.1_chai@4.2.0 + chai: 4.3.0 + chai-as-promised: 7.1.1_chai@4.3.0 eslint: 7.19.0 karma: 5.2.3 karma-chrome-launcher: 3.1.0 @@ -10105,7 +10125,7 @@ packages: '@types/mock-require': 2.0.0 '@types/nise': 1.4.0 '@types/node': 8.10.66 - chai: 4.2.0 + chai: 4.3.0 dotenv: 8.2.0 eslint: 7.19.0 fs-extra: 8.1.0 @@ -10152,7 +10172,7 @@ packages: '@azure/event-hubs': 2.1.4 '@types/node': 8.10.66 '@types/uuid': 8.3.0 - '@types/yargs': 15.0.12 + '@types/yargs': 15.0.13 async-lock: 1.2.8 death: 1.1.0 debug: 4.3.1 diff --git a/sdk/template/template/CHANGELOG.md b/sdk/template/template/CHANGELOG.md index ccb34798ad39..6a7473963bfe 100644 --- a/sdk/template/template/CHANGELOG.md +++ b/sdk/template/template/CHANGELOG.md @@ -1,17 +1,27 @@ # Release History + +## 1.0.11-beta.1 (Unreleased) + +- Restructured the template package to use the Client SDK developer training materials. + ## 1.0.10-beta.1 (2020-11-16) + - Test Release Pipeline ## 1.0.9-beta.13 (2020-10-13) + - Test Release Pipeline ## 1.0.9-beta.3 (2020-09-05) + - Test Release Pipeline ## 1.0.9-beta.2 (2020-09-04) + - Testing release tag replacement ## 1.0.9-beta.1 (2020-08-27) + - Testing prerelease versioning changes ## 1.0.8 (Unreleased) @@ -19,20 +29,25 @@ ## 1.0.7 (2020-04-01) ## 1.0.6 (2020-03-26) + - Test Release Pipeline ## 1.0.5 (2020-03-25) + - Test Release Pipeline ## 1.0.4 (2020-03-245 + - Test Release Pipeline ## 1.0.3 (2020-03-24) + - Test Release Pipeline ## 1.0.2 (2020-03-24) -- Test Release Pipeline +- Test Release Pipeline ## 1.0.1 (2020-03-24) + - Test Release Pipeline diff --git a/sdk/template/template/README-EXAMPLE.md b/sdk/template/template/README-EXAMPLE.md new file mode 100644 index 000000000000..f22df945d438 --- /dev/null +++ b/sdk/template/template/README-EXAMPLE.md @@ -0,0 +1,188 @@ +# App Configuration client library for JavaScript + + + +[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: + +- Create flexible key representations and mappings +- Tag keys with labels +- Replay settings from any point in time + +[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/azure/azure-app-configuration/) | +[Samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples) + +## Getting started + +### Install the package + +```bash +npm install @azure/app-configuration +``` + +### Prerequisites + +- 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 + +You can use the [Azure Portal](https://portal.azure.com) or the [Azure CLI](https://docs.microsoft.com/cli/azure) to create an Azure App Configuration resource. + +Example (Azure CLI): + +``` +az appconfig create --name --resource-group --location eastus +``` + +### Authenticate the client + +AppConfigurationClient can authenticate using a [service principal](#authenticating-with-a-service-principal) or using a [connection string](#authenticating-with-a-connection-string). + +#### Authenticating with a service principal + +Authentication via service principal is done by: + +- Creating a credential using the `@azure/identity` package. +- Setting appropriate RBAC rules on your AppConfiguration resource. + More information on App Configuration roles can be found [here](https://docs.microsoft.com/azure/azure-app-configuration/concept-enable-rbac#azure-built-in-roles-for-azure-app-configuration). + +Using [DefaultAzureCredential](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/README.md#defaultazurecredential) + +```javascript +const azureIdentity = require("@azure/identity"); +const appConfig = require("@azure/app-configuration"); + +const credential = new azureIdentity.DefaultAzureCredential(); +const client = new appConfig.AppConfigurationClient( + endpoint, // ex: .azconfig.io> + credential +); +``` + +More information about `@azure/identity` can be found [here](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/README.md) + +#### Authenticating with a connection string + +To get the Primary **connection string** for an App Configuration resource you can use this Azure CLI command: + +``` +az appconfig credential list -g -n --query "([?name=='Primary'].connectionString)[0]" +``` + +And in code you can now create your App Configuration client with the **connection string** you got from the Azure CLI: + +```typescript +const client = new AppConfigurationClient(""); +``` + +## Key concepts + +The [`AppConfigurationClient`](https://docs.microsoft.com/javascript/api/@azure/app-configuration/appconfigurationclient) has some terminology changes from App Configuration in the portal. + +- Key/Value pairs are represented as [`ConfigurationSetting`](https://docs.microsoft.com/javascript/api/@azure/app-configuration/configurationsetting) objects +- Locking and unlocking a setting is represented in the `isReadOnly` field, which you can toggle using `setReadOnly`. + +The client follows a simple design methodology - [`ConfigurationSetting`](https://docs.microsoft.com/javascript/api/@azure/app-configuration/configurationsetting) can be passed into any method that takes a [`ConfigurationSettingParam`](https://docs.microsoft.com/javascript/api/@azure/app-configuration/configurationsettingparam) or [`ConfigurationSettingId`](https://docs.microsoft.com/javascript/api/@azure/app-configuration/configurationsettingid). + +This means this pattern works: + +```typescript +const setting = await client.getConfigurationSetting({ + key: "hello" +}); + +setting.value = "new value!"; +await client.setConfigurationSetting(setting); + +// fields unrelated to just identifying the setting are simply +// ignored (for instance, the `value` field) +await client.setReadOnly(setting, true); + +// delete just needs to identify the setting so other fields are +// just ignored +await client.deleteConfigurationSetting(setting); +``` + +or, for example, re-getting a setting: + +```typescript +let setting = await client.getConfigurationSetting({ + key: "hello" +}); + +// re-get the setting +setting = await.getConfigurationSetting(setting); +``` + +## Examples + +#### Create and get a setting + +```javascript +const appConfig = require("@azure/app-configuration"); + +const client = new appConfig.AppConfigurationClient( + "" +); + +async function run() { + const newSetting = await client.setConfigurationSetting({ + key: "testkey", + value: "testvalue", + // Labels allow you to create variants of a key tailored + // for specific use-cases like supporting multiple environments. + // https://docs.microsoft.com/azure/azure-app-configuration/concept-key-value#label-keys + label: "optional-label" + }); + + let retrievedSetting = await client.getConfigurationSetting({ + key: "testkey", + label: "optional-label" + }); + + console.log("Retrieved value:", retrievedSetting.value); +} + +run().catch((err) => console.log("ERROR:", err)); +``` + +## Next steps + +The following samples show you the various ways you can interact with App Configuration: + +- [`helloworld.ts`](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples/typescript/src/helloworld.ts) - Get, set, and delete configuration values. +- [`helloworldWithLabels.ts`](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples/typescript/src/helloworldWithLabels.ts) - Use labels to add additional dimensions to your settings for scenarios like beta vs production. +- [`optimisticConcurrencyViaEtag.ts`](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples/typescript/src/optimisticConcurrencyViaEtag.ts) - Set values using etags to prevent accidental overwrites. +- [`setReadOnlySample.ts`](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples/typescript/src/setReadOnlySample.ts) - Marking settings as read-only to prevent modification. +- [`getSettingOnlyIfChanged.ts`](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples/typescript/src/getSettingOnlyIfChanged.ts) - Get a setting only if it changed from the last time you got it. +- [`listRevisions.ts`](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples/typescript/src/listRevisions.ts) - List the revisions of a key, allowing you to see previous values and when they were set. + +More in-depth examples can be found in the [samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration/samples) folder on GitHub. + +## 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. + +This module's tests are a mixture of live and unit tests, which require you to have an Azure App Configuration instance. To execute the tests you'll need to run: + +1. `rush update` +2. `rush build -t @azure/app-configuration` +3. Create a .env file with these contents in the `sdk\appconfiguration\app-configuration` folder: + `APPCONFIG_CONNECTION_STRING=connection string for your App Configuration instance` +4. `cd sdk\appconfiguration\app-configuration` +5. `npm run test`. + +View our [tests](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/appconfiguration/app-configuration/test) +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/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/template/template/README-TEMPLATE.md b/sdk/template/template/README-TEMPLATE.md deleted file mode 100644 index d27c4a6706d6..000000000000 --- a/sdk/template/template/README-TEMPLATE.md +++ /dev/null @@ -1,424 +0,0 @@ -# Azure Text Analytics client library for JavaScript - -[Azure TextAnalytics](https://azure.microsoft.com/services/cognitive-services/text-analytics/) is a cloud-based service that provides advanced natural language processing over raw text, and includes six main functions: - -- Language Detection -- Sentiment Analysis -- Key Phrase Extraction -- Named Entity Recognition -- Linked Entity Recognition - -Use the client library to: - -- Detect what language input text is written in. -- Determine what customers think of your brand or topic by analyzing raw text for clues about positive or negative sentiment. -- Automatically extract key phrases to quickly identify the main points. -- Identify and categorize entities in your text as people, places, organizations, date/time, quantities, percentages, currencies, and more. - -[Source code](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/textanalytics/ai-text-analytics/) | -[Package (NPM)](https://www.npmjs.com/package/@azure/ai-text-analytics) | -[API reference documentation](https://aka.ms/azsdk/js/textanalytics/docs) | -[Product documentation](https://docs.microsoft.com/azure/cognitive-services/text-analytics/) | -[Samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/textanalytics/ai-text-analytics/samples) - -## Getting started - -### Currently supported environments - -- Node.js version 8.x.x or higher - -### Prerequisites - -- An [Azure subscription][azure_sub]. -- An existing [Cognitive Services][cognitive_resource] or Text Analytics resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli]. - -If you use the Azure CLI, replace `` and `` with your own unique names: - -```PowerShell -az cognitiveservices account create --kind TextAnalytics --resource-group --name -``` - -### Install the `@azure/ai-text-analytics` package - -Install the Azure Text Analytics client library for JavaScript with `npm`: - -```bash -npm install @azure/ai-text-analytics -``` - -### Create and authenticate a `TextAnalyticsClient` - -To create a client object to access the Text Analytics API, you will need the `endpoint` of your Text Analytics resource and a `credential`. The Text Analytics client can use either Azure Active Directory credentials or an API key credential to authenticate. - -You can find the endpoint for your text analytics resource either in the [Azure Portal][azure_portal] or by using the [Azure CLI][azure_cli] snippet below: - -```bash -az cognitiveservices account show --name --resource-group --query "endpoint" -``` - -#### Using an API Key - -Use the [Azure Portal][azure_portal] to browse to your Text Analytics resource and retrieve an API key, or use the [Azure CLI][azure_cli] snippet below: - -**Note:** Sometimes the API key is referred to as a "subscription key" or "subscription API key." - -```PowerShell -az cognitiveservices account keys list --resource-group --name -``` - -Once you have an API key and endpoint, you can use the `AzureKeyCredential` class to authenticate the client as follows: - -```js -const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics"); - -const client = new TextAnalyticsClient( - "", - 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, -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 Text Analytics 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`. - -```js -const { TextAnalyticsClient } = require("@azure/ai-text-analytics"); -const { DefaultAzureCredential } = require("@azure/identity"); - -const client = new TextAnalyticsClient("", new DefaultAzureCredential()); -``` - -### JavaScript Bundle - -To use this client library in the browser, first you need to use a bundler. For details on how to do this, please refer to our [bundling documentation](https://aka.ms/AzureSDKBundling). - -### CORS - -> note to package authors: If the service supports CORS please use this section to describe how to enable CORS, otherwise delete this section. See an example below from Azure Storage: - -You need to set up [Cross-Origin Resource Sharing (CORS)](https://docs.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services) rules for your storage account if you need to develop for browsers. Go to Azure portal and Azure Storage Explorer, find your storage account, create new CORS rules for blob/queue/file/table service(s). - -For example, you can create the following CORS settings for local development. But please customize the settings carefully according to your requirements in a production environment. - -- Allowed origins: \* -- Allowed verbs: DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT -- Allowed headers: \* -- Exposed headers: \* -- Maximum age (seconds): 86400 - -## Key concepts - -### TextAnalyticsClient - -`TextAnalyticsClient` is the primary interface for developers using the Text Analytics client library. It provides asynchronous methods to access a specific use of Text Analytics, such as language detection or key phrase extraction. - -### Input - -A **document** represents a single unit of input to be analyzed by the predictive models in the Text Analytics service. Operations on `TextAnalyticsClient` take a collection of inputs to be analyzed as a batch. The operation methods have overloads that allow the inputs to be represented as strings, or as objects with attached metadata. - -For example, each document can be passed as a string in an array, e.g. - -```typescript -const documents = [ - "I hated the movie. It was so slow!", - "The movie made it into my top ten favorites.", - "What a great movie!" -]; -``` - -or, if you wish to pass in a per-item document `id` or `language`/`countryHint`, they can be given as a list of `TextDocumentInput` or `DetectLanguageInput` depending on the operation; - -```javascript -const textDocumentInputs = [ - { id: "1", language: "en", text: "I hated the movie. It was so slow!" }, - { id: "2", language: "en", text: "The movie made it into my top ten favorites." }, - { id: "3", language: "en", text: "What a great movie!" }, -]; -``` - -See [service limiations][data_limits] for the input, including document length limits, maximum batch size, and supported text encodings. - -### Return Value - -The return value corresponding to a single document is either a successful result or an error object. Each `TextAnalyticsClient` method returns a heterogeneous array of results and errors that correspond to the inputs by index. A text input and its result will have the same index in the input and result collections. The collection may also optionally include information about the input batch and how it was processed in the `statistics` field. - -An __result__, such as `AnalyzeSentimentResult`, is the result of a Text Analytics operation, containing a prediction or predictions about a single text input. An operation's result type also may optionally include information about the input document and how it was processed. - -The __error__ object, `TextAnalyticsErrorResult`, indicates that the service encountered an error while processing the document and contains information about the error. - -### Document Error Handling - -In the collection returned by an operation, errors are distinguished from successful responses by the presence of the `error` property, which contains the inner `TextAnalyticsError` object if an error was encountered. For successful result objects, this property is _always_ `undefined`. - -For example, to filter out all errors, you could use the following `filter`: - -```javascript -const results = await client.analyzeSentiment(documents); -const onlySuccessful = results.filter((result) => result.error === undefined); -``` - -__Note__: TypeScript users can benefit from better type-checking of result and error objects if `compilerOptions.strictNullChecks` is set to `true` in their `tsconfig.json` configuration. For example: - -```typescript -const [result] = await client.analyzeSentiment(["Hello world!"]); - -if (result.error !== undefined) { - // In this if block, TypeScript will be sure that the type of `result` is - // `TextAnalyticsError` if compilerOptions.strictNullChecks is enabled in - // the tsconfig.json - - console.log(result.error); -} -``` - -## Examples - -### Analyze Sentiment - -Analyze sentiment of text to determine if it is positive, negative, neutral, or mixed, including per-sentence sentiment analysis and confidence scores. - -```javascript -const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics"); - -const client = new TextAnalyticsClient( - "", - new AzureKeyCredential("") -); - -const documents = [ - "I did not like the restaurant. The food was too spicy.", - "The restaurant was decorated beautifully. The atmosphere was unlike any other restaurant I've been to.", - "The food was yummy. :)" -] - -async function main() { - const results = await client.analyzeSentiment(documents); - - for (const result of results) { - if (result.error === undefined) { - console.log("Overall sentiment:", result.sentiment); - console.log("Scores:", result.confidenceScores); - } else { - console.error("Encountered an error:", result.error); - } - } -} - -main(); -``` - -### Recognize Entities - -Recognize and categorize entities in text as people, places, organizations, dates/times, quantities, currencies, etc. - -The `language` parameter is optional. If it is not specified, the default English model will be used. - -```javascript -const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics"); - -const client = new TextAnalyticsClient( - "", - new AzureKeyCredential("") -); - -const documents = [ - "Microsoft was founded by Bill Gates and Paul Allen.", - "Redmond is a city in King County, Washington, United States, located 15 miles east of Seattle.", - "Jeff bought three dozen eggs because there was a 50% discount." -]; - -async function main() { - const results = await client.recognizeEntities(documents, "en"); - - for (const result of results) { - if (result.error === undefined) { - console.log(" -- Recognized entities for input", result.id, "--"); - for (const entity of result.entities) { - console.log(entity.text, ":", entity.category, "(Score:", entity.score, ")"); - } - } else { - console.error("Encountered an error:", result.error); - } - } -} - -main(); -``` - -### Recognize Linked Entities - -A "Linked" entity is one that exists in a knowledge base (such as Wikipedia). The `recognizeLinkedEntities` operation can disambiguate entities by determining which entry in a knowledge base they likely refer to (for example, in a piece of text, does the word "Mars" refer to the planet, or to the Roman god of war). Linked entities contain associated URLs to the knowledge base that provides the definition of the entity. - -```javascript -const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics"); - -const client = new TextAnalyticsClient( - "", - new AzureKeyCredential("") -); - -const documents = [ - "Microsoft was founded by Bill Gates and Paul Allen.", - "Easter Island, a Chilean territory, is a remote volcanic island in Polynesia.", - "I use Azure Functions to develop my product." -]; - -async function main() { - const results = await client.recognizeLinkedEntities(documents, "en"); - - for (const result of results) { - if (result.error === undefined) { - console.log(" -- Recognized linked entities for input", result.id, "--"); - for (const entity of result.entities) { - console.log(entity.name, "(URL:", entity.url, ", Source:", entity.dataSource, ")"); - for (const match of entity.matches) { - console.log(" Occurrence:", "\"" + match.text + "\"", "(Score:", match.score, ")"); - } - } - } else { - console.error("Encountered an error:", result.error); - } - } -} - -main(); -``` - -### Extract Key Phrases - -Key Phrase extraction identifies the main talking points in a document. For example, given input text "The food was delicious and there were wonderful staff", the service returns "food" and "wonderful staff". - -```javascript -const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics"); - -const client = new TextAnalyticsClient( - "", - new AzureKeyCredential("") -); - -const documents = [ - "Redmond is a city in King County, Washington, United States, located 15 miles east of Seattle.", - "I need to take my cat to the veterinarian.", - "I will travel to South America in the summer." -]; - -async function main() { - const results = await client.extractKeyPhrases(documents, "en"); - - for (const result of results) { - if (result.error === undefined) { - console.log(" -- Extracted key phrases for input", result.id, "--"); - console.log(result.keyPhrases) - } else { - console.error("Encountered an error:", result.error); - } - } -} - -main(); -``` - -### Detect Language - -Determine the language of a piece of text. - -The `countryHint` parameter is optional, but can assist the service in providing correct output if the country of origin is known. If provided, it should be set to an ISO-3166 Alpha-2 two-letter country code (such as "us" for the United States or "jp" for Japan) or to the value `"none"`. If the parameter is not provided, then the default `"us"` (United States) model will be used. If you do not know the country of origin of the document, then the parameter `"none"` should be used, and the Text Analytics service will apply a model that is tuned for an unknown country of origin. - -```javascript -const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics"); - -const client = new TextAnalyticsClient( - "", - new AzureKeyCredential("") -); - -const documents = [ - "This is written in English.", - "Il documento scritto in italiano.", - "Dies ist in englischer Sprache verfasst." -]; - -async function main() { - const results = await client.detectLanguage(documents, "none"); - - for (const result of results) { - const { primaryLanguage } = result; - if (result.error === undefined) { - console.log( - "Input #", - result.id, - "identified as", - primaryLanguage.name, - "( ISO6391:", - primaryLanguage.iso6391Name, - ", Score:", - primaryLanguage.score, - ")" - ); - } else { - console.error("Encountered an error:", result.error); - } - } -} - -main(); -``` - -## Troubleshooting - -### Enable logs - -You can set the following environment variable to see debug logs when using this library. - -- Getting debug logs from the Azure TextAnalytics client library - -```bash -export DEBUG=azure* -``` - -## Next steps - -Please take a look at the -[samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/textanalytics/ai-text-analytics/samples) -directory for detailed examples on how to use this library. - -## Contributing - -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.microsoft.com. - -When you submit a pull request, a CLA-bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -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) - -![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Ftextanalytics%2Fai-text-analytics%2FREADME.png) - -[azure_cli]: https://docs.microsoft.com/cli/azure -[azure_sub]: https://azure.microsoft.com/free/ -[cognitive_resource]: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account -[azure_portal]: https://portal.azure.com -[azure_identity]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/identity/identity -[cognitive_auth]: https://docs.microsoft.com/azure/cognitive-services/authentication -[register_aad_app]: https://docs.microsoft.com/azure/cognitive-services/authentication#assign-a-role-to-a-service-principal -[defaultazurecredential]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/identity/identity#defaultazurecredential -[data_limits]: https://docs.microsoft.com/azure/cognitive-services/text-analytics/overview#data-limits diff --git a/sdk/template/template/README.md b/sdk/template/template/README.md index a44b124f0ae2..147c20b65e65 100644 --- a/sdk/template/template/README.md +++ b/sdk/template/template/README.md @@ -1,27 +1,76 @@ -## Azure Template client library for JavaScript +# Azure Template client library for JavaScript -This template serves as a starting point for JavaScript libraries targeting both Node and the Browser and implemented in TypeScript. + -**Note:** -For a more complete example of README.md file, please see [README template][readme_template]. Also see the [Azure SDK Document Guidelines][azsdk_doc_guidelines] for more information. +This project is used as a template package for the Azure SDK for JavaScript. It is intended to help Azure SDK developers bootstrap new packages, and it provides an example of how to organize the code and documentation of a client library for an Azure service. -## Building the Template +## Getting started -Please refer to the [Contributing Guide][contributing_guide] for information on how to build projects in this repository. +### Currently supported environments -## Implementation Details +- Node.js version 8.x or higher -The overall build pipeline looks like the following: +### Prerequisites -1. TypeScript builds all source files under `./src` to ECMAScript Modules (ESM) under `./dist-esm`. -2. Rollup builds `./dist-esm` to an optimized single file at `./dist/index.js` as the Node entry point. -3. Rollup builds `./dist-esm` to an optimized browser bundle under `./browser/azure-template.js`. +- An [Azure subscription][azure_sub]. -Tests follow a similar pipeline, however test output is under `dist-test` folder. +Usually you'd put a shell command for provisioning the necessary Azure services here. +### Install the `@azure/template` package + +Install the Template client library for JavaScript with `npm`: + +```bash +npm install @azure/template +``` + +### Further examples + +Top-level examples usually include things like creating and authenticating the main Client. If your service supports multiple means of authenticating (e.g. key-based and Azure Active Directory) you can give a separate example of each. + +## Key concepts + +### ConfigurationClient + +Describe your primary client here. Talk about what operations it can do and when a developer would want to use it. + +### Additional Examples + +Create a section for each top-level service concept you want to explain. + +## Examples + +### First Example + + + +Create several code examples for how someone would use your library to accomplish a common task with the service. + +## Troubleshooting + +### Enable logs + +You can set the following environment variable to see debug logs when using this library. + +- Getting debug logs from the Azure TextAnalytics client library + +```bash +export DEBUG=azure* +``` + +## Next steps + +Please take a look at the [samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template/samples) directory for detailed examples that demonstrate how to use the client libraries. + +## 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) ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Ftemplate%2Ftemplate%2FREADME.png) -[readme_template]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/template/template/README-TEMPLATE.md -[azsdk_doc_guidelines]: https://review.docs.microsoft.com/help/contribute-ref/contribute-ref-how-to-document-sdk?branch=master#readme -[contributing_guide]: https://github.com/Azure/azure-sdk-for-js/blob/master/CONTRIBUTING.md +[azure_cli]: https://docs.microsoft.com/cli/azure +[azure_sub]: https://azure.microsoft.com/free/ diff --git a/sdk/template/template/karma.conf.js b/sdk/template/template/karma.conf.js index d88149705d76..9bca108da550 100644 --- a/sdk/template/template/karma.conf.js +++ b/sdk/template/template/karma.conf.js @@ -1,6 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + // https://github.com/karma-runner/karma-chrome-launcher process.env.CHROME_BIN = require("puppeteer").executablePath(); require("dotenv").config(); +const { + jsonRecordingFilterFunction, + isPlaybackMode, + isSoftRecordMode, + isRecordMode +} = require("@azure/test-utils-recorder"); module.exports = function(config) { config.set({ @@ -20,15 +29,16 @@ module.exports = function(config) { "karma-ie-launcher", "karma-env-preprocessor", "karma-coverage", - "karma-sourcemap-loader", - "karma-junit-reporter" + "karma-junit-reporter", + "karma-json-to-file-reporter", + "karma-json-preprocessor" ], // list of files / patterns to load in the browser files: [ "dist-test/index.browser.js", { pattern: "dist-test/index.browser.js.map", type: "html", included: false, served: true } - ], + ].concat(isPlaybackMode() || isSoftRecordMode() ? ["recordings/browsers/**/*.json"] : []), // list of files / patterns to exclude exclude: [], @@ -36,17 +46,18 @@ module.exports = function(config) { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - "**/*.js": ["env"] + "**/*.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 - // "dist-test/index.js": ["coverage"] + "test-browser/index.js": ["coverage"] }, envPreprocessor: [ "TEST_MODE", - "ENDPOINT", - "API_KEY", - "API_KEY_ALT", + "APPCONFIG_ENDPOINT", + "APPCONFIG_TEST_SETTING_KEY", + "APPCONFIG_TEST_SETTING_EXPECTED_VALUE", "AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_TENANT_ID" @@ -55,17 +66,12 @@ module.exports = function(config) { // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["mocha", "coverage", "junit"], + reporters: ["mocha", "coverage", "junit", "json-to-file"], coverageReporter: { // specify a common output directory dir: "coverage-browser/", - reporters: [ - { type: "json", subdir: ".", file: "coverage.json" }, - { type: "lcovonly", subdir: ".", file: "lcov.info" }, - { type: "html", subdir: "html" }, - { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" } - ] + reporters: [{ type: "json", subdir: ".", file: "coverage.json" }] }, junitReporter: { @@ -78,6 +84,11 @@ module.exports = function(config) { properties: {} // key value pair of properties to add to the section of the report }, + jsonToFileReporter: { + filter: jsonRecordingFilterFunction, + outputPath: "." + }, + // web server port port: 9876, @@ -112,6 +123,9 @@ module.exports = function(config) { browserNoActivityTimeout: 600000, browserDisconnectTimeout: 10000, browserDisconnectTolerance: 3, + browserConsoleLogOptions: { + terminal: !isRecordMode() + }, client: { mocha: { diff --git a/sdk/template/template/package.json b/sdk/template/template/package.json index 7a8980159a8f..ace110816058 100644 --- a/sdk/template/template/package.json +++ b/sdk/template/template/package.json @@ -1,14 +1,24 @@ { "name": "@azure/template", - "version": "1.0.10-beta.1", - "description": "Template Library with typescript type definitions for node.js and browser.", + "version": "1.0.11-beta.1", + "description": "Example project for learning how to build a client library", "sdk-type": "client", "main": "dist/index.js", "module": "dist-esm/src/index.js", - "browser": { - "./dist-esm/src/print.js": "./dist-esm/src/print.browser.js" - }, + "browser": {}, "types": "types/template.d.ts", + "//metadata": { + "constantPaths": [ + { + "path": "src/generated/generatedClientContext.ts", + "prefix": "packageVersion" + }, + { + "path": "src/constants.ts", + "prefix": "SDK_VERSION" + } + ] + }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", @@ -18,9 +28,11 @@ "build": "tsc -p . && rollup -c 2>&1 && api-extractor run --local", "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "clean": "rimraf dist dist-* test-dist temp types *.tgz *.log", + "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src", "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 --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "generate:client": "autorest --typescript --v3 swagger", "integration-test:browser": "karma start --single-run", "integration-test:node": "nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 5000000 --full-trace \"dist-esm/test/{,!(browser)/**/}/*.spec.js\"", "integration-test": "npm run integration-test:node && npm run integration-test:browser", @@ -33,8 +45,7 @@ "test": "npm run build:test && npm run unit-test && npm run integration-test", "unit-test:browser": "karma start --single-run", "unit-test:node": "mocha -r esm --require ts-node/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 1200000 --full-trace \"test/{,!(browser)/**/}/*.spec.ts\"", - "unit-test": "npm run unit-test:node && npm run unit-test:browser", - "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src" + "unit-test": "npm run unit-test:node && npm run unit-test:browser" }, "files": [ "dist/", @@ -57,7 +68,7 @@ "bugs": { "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, - "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/template/template/", + "homepage": "https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/template/template/README.md", "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", "dependencies": { @@ -66,12 +77,13 @@ "@azure/core-tracing": "1.0.0-preview.9", "@azure/logger": "^1.0.0", "@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/identity": "^1.1.0", + "@azure/test-utils-recorder": "^1.0.0", "@microsoft/api-extractor": "7.7.11", "@types/chai": "^4.1.6", "@types/chai-as-promised": "^7.1.0", @@ -90,21 +102,22 @@ "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": "^2.0.1", "karma-mocha-reporter": "^2.2.5", - "karma-sourcemap-loader": "^0.3.8", "mocha": "^7.1.1", "mocha-junit-reporter": "^1.18.0", "nyc": "^14.0.0", "prettier": "^1.16.4", "rimraf": "^3.0.0", "rollup": "^1.16.3", + "typedoc": "0.15.2", "typescript": "4.1.2", - "util": "^0.12.1", - "typedoc": "0.15.2" + "util": "^0.12.1" }, "//sampleConfiguration": { - "skipFolder": true + "skipFolder": false } } diff --git a/sdk/template/template/recordings/browsers/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.json b/sdk/template/template/recordings/browsers/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.json new file mode 100644 index 000000000000..2994f728b5be --- /dev/null +++ b/sdk/template/template/recordings/browsers/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.json @@ -0,0 +1,56 @@ +{ + "recordings": [ + { + "method": "POST", + "url": "https://login.microsoftonline.com/azure_tenant_id/oauth2/v2.0/token", + "query": {}, + "requestBody": "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Fmyappconfig.azconfig.io%2F.default", + "status": 200, + "response": "{\"token_type\":\"Bearer\",\"expires_in\":3599,\"ext_expires_in\":3599,\"access_token\":\"access_token\"}", + "responseHeaders": { + "cache-control": "no-store, no-cache", + "content-length": "1491", + "content-type": "application/json; charset=utf-8", + "date": "Mon, 26 Oct 2020 21:18:44 GMT", + "expires": "-1", + "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", + "pragma": "no-cache", + "referrer-policy": "strict-origin-when-cross-origin", + "strict-transport-security": "max-age=31536000; includeSubDomains", + "x-content-type-options": "nosniff", + "x-ms-ests-server": "2.1.11169.11 - SCUS ProdSlices", + "x-ms-request-id": "a05c2f53-347b-43be-8e75-8adac3e40101" + } + }, + { + "method": "GET", + "url": "https://myappconfig.azconfig.io/kv/test-key", + "query": { + "api-version": "1.0" + }, + "requestBody": null, + "status": 200, + "response": "{\"etag\":\"cbARBFLodwGLL3qktvCwmLa1vet\",\"key\":\"test-key\",\"label\":null,\"content_type\":\"\",\"value\":\"test-value\",\"tags\":{},\"locked\":false,\"last_modified\":\"2020-10-16T00:08:12+00:00\"}", + "responseHeaders": { + "access-control-allow-credentials": "true", + "access-control-allow-origin": "*", + "access-control-expose-headers": "DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Authorization, x-ms-client-request-id, x-ms-useragent, x-ms-content-sha256, x-ms-date, host, Accept, Accept-Datetime, Date, If-Match, If-None-Match, Sync-Token, x-ms-return-client-request-id, ETag, Last-Modified, Link, Memento-Datetime, retry-after-ms, x-ms-request-id, WWW-Authenticate", + "content-type": "application/vnd.microsoft.appconfig.kv+json; charset=utf-8", + "date": "Mon, 26 Oct 2020 21:18:45 GMT", + "etag": "\"cbARBFLodwGLL3qktvCwmLa1vet\"", + "last-modified": "Fri, 16 Oct 2020 00:08:12 GMT", + "server": "openresty/1.17.8.2", + "status": "200", + "strict-transport-security": "max-age=15724800; includeSubDomains", + "sync-token": "zAJw6V16=MDozIzUxNTAyNjY=;sn=5150266", + "x-ms-correlation-request-id": "764e6e56-1dac-4c11-94b7-8a45c90d3bb9", + "x-ms-request-id": "764e6e56-1dac-4c11-94b7-8a45c90d3bb9" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "dbff5419a75940fa5401dd76cca9de72" +} \ No newline at end of file diff --git a/sdk/template/template/recordings/node/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.js b/sdk/template/template/recordings/node/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.js new file mode 100644 index 000000000000..5ae0a3376925 --- /dev/null +++ b/sdk/template/template/recordings/node/aad_configurationclient_functional_tests/recording_predetermined_setting_has_expected_value.js @@ -0,0 +1,72 @@ +let nock = require('nock'); + +module.exports.hash = "4396ae23de09111d66f4ad1027657096"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/azure_tenant_id/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Fmyappconfig.azconfig.io%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '12c6bd6d-e57d-40c2-921a-bb61e1d57d00', + 'x-ms-ests-server', + '2.1.11140.11 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=Ao37r96OlpdEqDng7XQpw6iqBNuqAQAAAGjdG9cOAAAA; expires=Sun, 15-Nov-2020 18:28:56 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Fri, 16 Oct 2020 18:28:56 GMT', + 'Content-Length', + '1491' +]); + +nock('https://myappconfig.azconfig.io:443', {"encodedQueryParams":true}) + .get('/kv/test-key') + .query(true) + .reply(200, {"etag":"cbARBFLodwGLL3qktvCwmLa1vet","key":"test-key","label":null,"content_type":"","value":"test-value","tags":{},"locked":false,"last_modified":"2020-10-16T00:08:12+00:00"}, [ + 'Server', + 'openresty/1.17.8.2', + 'Date', + 'Fri, 16 Oct 2020 18:28:57 GMT', + 'Content-Type', + 'application/vnd.microsoft.appconfig.kv+json; charset=utf-8', + 'Transfer-Encoding', + 'chunked', + 'Connection', + 'keep-alive', + 'Last-Modified', + 'Fri, 16 Oct 2020 00:08:12 GMT', + 'ETag', + '"cbARBFLodwGLL3qktvCwmLa1vet"', + 'Sync-Token', + 'zAJw6V16=MDoyIzUwMDA4MTgjNj0tMQ==;sn=5000818', + 'x-ms-request-id', + 'c216d2fc-a04f-40d6-aa9b-5eb170434239', + 'x-ms-correlation-request-id', + 'c216d2fc-a04f-40d6-aa9b-5eb170434239', + 'Access-Control-Allow-Origin', + '*', + 'Access-Control-Allow-Credentials', + 'true', + 'Access-Control-Expose-Headers', + 'DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Authorization, x-ms-client-request-id, x-ms-useragent, x-ms-content-sha256, x-ms-date, host, Accept, Accept-Datetime, Date, If-Match, If-None-Match, Sync-Token, x-ms-return-client-request-id, ETag, Last-Modified, Link, Memento-Datetime, retry-after-ms, x-ms-request-id, WWW-Authenticate', + 'Strict-Transport-Security', + 'max-age=15724800; includeSubDomains' +]); diff --git a/sdk/template/template/review/template.api.md b/sdk/template/template/review/template.api.md index 5a15e14e384d..3ee61bc94c0a 100644 --- a/sdk/template/template/review/template.api.md +++ b/sdk/template/template/review/template.api.md @@ -4,22 +4,39 @@ ```ts -import { AzureKeyCredential } from '@azure/core-auth'; -import EventEmitter from 'events'; -import { KeyCredential } from '@azure/core-auth'; -import { URLBuilder } from '@azure/core-http'; +import { OperationOptions } from '@azure/core-http'; +import { PipelineOptions } from '@azure/core-http'; +import { TokenCredential } from '@azure/core-http'; -export { AzureKeyCredential } +// @public +export class ConfigurationClient { + constructor(endpointUrl: string, credential: TokenCredential, options?: ConfigurationClientOptions); + getConfigurationSetting(key: string, options?: GetConfigurationSettingOptions): Promise; + getConfigurationSetting(setting: ConfigurationSetting, options?: GetConfigurationSettingOptions): Promise; +} -// @public (undocumented) -export function createEventEmitter(): EventEmitter; - -export { KeyCredential } +// @public +export interface ConfigurationClientOptions extends PipelineOptions { +} // @public (undocumented) -export function (str: string): void; - -export { URLBuilder } +export interface ConfigurationSetting { + contentType?: string; + etag?: string; + isReadOnly?: boolean; + key: string; + label?: string; + lastModified?: Date; + tags?: { + [propertyName: string]: string; + }; + value?: string; +} + +// @public +export interface GetConfigurationSettingOptions extends OperationOptions { + onlyIfChanged?: boolean; +} // (No @packageDocumentation comment for this package) diff --git a/sdk/template/template/sample.env b/sdk/template/template/sample.env index c231c9804b0b..63d2520e7232 100644 --- a/sdk/template/template/sample.env +++ b/sdk/template/template/sample.env @@ -1,17 +1,26 @@ -# Used in most samples. Retrieve these values from a Cognitive Services instance -# in the Azure Portal. -ENDPOINT="Your Endpoint URL" -API_KEY="Your API key" +# Used in most samples. Retrieve these values from an instance in the Azure +# Portal. -# Used to authenticate using Azure AD as a service principal for role-based authentication -# in the tokenAuth sample. +APPCONFIG_ENDPOINT: "https://.azconfig.io", + +# Used in the tests to indicate the key to use when retrieving a setting from +# the App Configuration and the expected value of that setting. + +APPCONFIG_TEST_SETTING_KEY="" +APPCONFIG_TEST_SETTING_EXPECTED_VALUE="" + +# Used to authenticate using Azure AD as a service principal for role-based +# authentication in the tokenAuth sample. # # See the documentation for `EnvironmentCredential` at the following link: # https://docs.microsoft.com/javascript/api/@azure/identity/environmentcredential -AZURE_TENANT_ID= -AZURE_CLIENT_ID= -AZURE_CLIENT_SECRET= -# 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 \ No newline at end of file +AZURE_TENANT_ID="" +AZURE_CLIENT_ID="" +AZURE_CLIENT_SECRET="" + +# 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/template/template/samples/javascript/README.md b/sdk/template/template/samples/javascript/README.md index a7404651589a..e44eee2f819a 100644 --- a/sdk/template/template/samples/javascript/README.md +++ b/sdk/template/template/samples/javascript/README.md @@ -1,22 +1,39 @@ - + +- javascript + products: + +# NOTE: You MUST use valid product slugs from the docs.microsoft.com taxonomy + +# in this array. Please check to make sure that the items you enter into this + +# list are valid! For example, "azure-template" is NOT a valid product slug + +# and is provided here as an example only. + +- azure +- azure-template + +# For urlFragment, use the base name of the package (not including the namespace) + +# and append "-typescript" or "-javascript" + +## urlFragment: template-javascript + +--> # Azure Template client library samples for JavaScript These sample programs show how to use the JavaScript client libraries for Azure Template in some common scenarios. -| **File Name** | **Description** | -| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -| [sampleTemplate.js][sampleTemplate] | sample template | +| **File Name** | **Description** | +| ----------------------------------------------------- | -------------------------------------------------------------------------- | +| [getConfigurationSetting.js][getconfigurationsetting] | Demonstrates the use of a ConfigurationClient to retrieve a setting value. | ## Prerequisites @@ -41,20 +58,20 @@ npm install 3. Run whichever samples you like (note that some samples may require additional setup, see the table above): ```bash -node sampleTemplate.js +node getConfigurationSetting.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 ENDPOINT="" API_KEY="" node sampleTemplate.js +npx cross-env ENDPOINT="" API_KEY="" node getConfigurationSetting.js ``` ## Next Steps Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients. -[sampleTemplate]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/template/template/samples/javascript/sampleTemplate.js +[getconfigurationsetting]: https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/template/template/samples/javascript/getConfigurationSetting.js [apiref]: https://docs.microsoft.com/javascript/api [freesub]: https://azure.microsoft.com/free/ [package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template/README.md diff --git a/sdk/template/template/samples/javascript/getConfigurationSetting.js b/sdk/template/template/samples/javascript/getConfigurationSetting.js new file mode 100644 index 000000000000..3cd2c503a314 --- /dev/null +++ b/sdk/template/template/samples/javascript/getConfigurationSetting.js @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates the use of a ConfigurationClient to retrieve a setting value. + */ + +const { ConfigurationClient } = require("@azure/template"); +const { DefaultAzureCredential } = require("@azure/identity"); + +async function main() { + const endpoint = process.env.APPCONFIG_ENDPOINT || ""; + const key = process.env.APPCONFIG_TEST_SETTING_KEY || "test-key"; + + const client = new ConfigurationClient(endpoint, new DefaultAzureCredential()); + + const setting = await client.getConfigurationSetting(key); + + console.log("The setting has a value of:", setting.value); + console.log("Details:", setting); +} + +main().catch((err) => { + console.error("The sample encountered an error:", err); +}); diff --git a/sdk/template/template/samples/javascript/package.json b/sdk/template/template/samples/javascript/package.json index 2d754a9ea424..b1eb849e9ad4 100644 --- a/sdk/template/template/samples/javascript/package.json +++ b/sdk/template/template/samples/javascript/package.json @@ -24,7 +24,7 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template", "sideEffects": false, "dependencies": { - "@azure/template": "latest", + "@azure/identity": "latest", "dotenv": "^8.2.0" } } diff --git a/sdk/template/template/samples/javascript/sample.env b/sdk/template/template/samples/javascript/sample.env index bec0f536a952..c65006b76b34 100644 --- a/sdk/template/template/samples/javascript/sample.env +++ b/sdk/template/template/samples/javascript/sample.env @@ -1,10 +1,7 @@ -# Used in most samples. Retrieve these values from a Cognitive Services instance -# in the Azure Portal. -ENDPOINT="" -API_KEY="" +# Retrieve this value from an AppConfig instance in the Azure Portal. +ENDPOINT="Your Endpoint URL" # Used to authenticate using Azure AD as a service principal for role-based authentication -# in the tokenAuth sample. # # See the documentation for `EnvironmentCredential` at the following link: # https://docs.microsoft.com/javascript/api/@azure/identity/environmentcredential diff --git a/sdk/template/template/samples/javascript/sampleTemplate.js b/sdk/template/template/samples/javascript/sampleTemplate.js deleted file mode 100644 index 7b7ed9f1847a..000000000000 --- a/sdk/template/template/samples/javascript/sampleTemplate.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * Demonstrates something - */ - -const { AzureKeyCredential } = require("@azure/template"); - -// 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 endpoint = process.env["ENDPOINT"] || ""; -const apiKey = process.env["API_KEY"] || ""; - -async function main() { - console.log("== Sample Template =="); - new AzureKeyCredential(apiKey); - - // TODO -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/template/template/samples/tsconfig.json b/sdk/template/template/samples/tsconfig.json index 8c89eac7173a..0e83d1fd597c 100644 --- a/sdk/template/template/samples/tsconfig.json +++ b/sdk/template/template/samples/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "module": "commonjs", "outDir": "typescript/dist", - "lib": ["DOM", "ES6"] + "lib": ["ES6"] }, "include": ["typescript/src/**.ts"], "exclude": ["typescript/*.json", "**/node_modules/", "../node_modules", "../typings"] diff --git a/sdk/template/template/samples/typescript/README.md b/sdk/template/template/samples/typescript/README.md index d11c37245121..58f05e5082cf 100644 --- a/sdk/template/template/samples/typescript/README.md +++ b/sdk/template/template/samples/typescript/README.md @@ -1,22 +1,37 @@ - + + +## + +- typescript + products: + +# NOTE: You MUST use valid product slugs from the docs.microsoft.com taxonomy + +# in this array. Please check to make sure that the items you enter into this + +# list are valid! + +- azure +- azure-template + +# For urlFragment, use the base name of the package (not including the namespace) + +# and append "-typescript" or "-javascript" + +## urlFragment: template-typescript + +--> # Azure Template client library samples for TypeScript These sample programs show how to use the TypeScript client libraries for Azure Template in some common scenarios. -| **File Name** | **Description** | -| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -| [sampleTemplate.ts][sampleTemplate] | sample template | +| **File Name** | **Description** | +| ----------------------------------------------------- | -------------------------------------------------------------------------- | +| [getConfigurationSetting.ts][getconfigurationsetting] | Demonstrates the use of a ConfigurationClient to retrieve a setting value. | ## Prerequisites @@ -53,20 +68,20 @@ npm run build 4. Run whichever samples you like (note that some samples may require additional setup, see the table above): ```bash -node dist/sampleTemplate.js +node dist/getConfigurationSetting.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 ENDPOINT="" API_KEY="" node dist/sampleTemplate.js +npx cross-env ENDPOINT="" API_KEY="" node dist/getConfigurationSetting.js ``` ## Next Steps Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients. -[sampleTemplate]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template/samples/typescript/src/sampleTemplate.ts +[getconfigurationsetting]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template/samples/typescript/src/getConfigurationSetting.ts [apiref]: https://docs.microsoft.com/javascript/api [freesub]: https://azure.microsoft.com/free/ [package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template/README.md diff --git a/sdk/template/template/samples/typescript/package.json b/sdk/template/template/samples/typescript/package.json index af0e194a10aa..60065b8aa546 100644 --- a/sdk/template/template/samples/typescript/package.json +++ b/sdk/template/template/samples/typescript/package.json @@ -28,7 +28,7 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/template/template", "sideEffects": false, "dependencies": { - "@azure/template": "latest", + "@azure/identity": "latest", "dotenv": "^8.2.0" }, "devDependencies": { diff --git a/sdk/template/template/samples/typescript/sample.env b/sdk/template/template/samples/typescript/sample.env index 472c7b5448be..c65006b76b34 100644 --- a/sdk/template/template/samples/typescript/sample.env +++ b/sdk/template/template/samples/typescript/sample.env @@ -1,10 +1,7 @@ -# Used in most samples. Retrieve these values from a Cognitive Services instance -# in the Azure Portal. +# Retrieve this value from an AppConfig instance in the Azure Portal. ENDPOINT="Your Endpoint URL" -API_KEY="" # Used to authenticate using Azure AD as a service principal for role-based authentication -# in the tokenAuth sample. # # See the documentation for `EnvironmentCredential` at the following link: # https://docs.microsoft.com/javascript/api/@azure/identity/environmentcredential diff --git a/sdk/template/template/samples/typescript/src/getConfigurationSetting.ts b/sdk/template/template/samples/typescript/src/getConfigurationSetting.ts new file mode 100644 index 000000000000..9c32cf8b46cc --- /dev/null +++ b/sdk/template/template/samples/typescript/src/getConfigurationSetting.ts @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Demonstrates the use of a ConfigurationClient to retrieve a setting value. + */ + +import { ConfigurationClient } from "@azure/template"; +import { DefaultAzureCredential } from "@azure/identity"; + +export async function main() { + const endpoint = process.env.APPCONFIG_ENDPOINT ?? ""; + const key = process.env.APPCONFIG_TEST_SETTING_KEY ?? "test-key"; + + const client = new ConfigurationClient(endpoint, new DefaultAzureCredential()); + + const setting = await client.getConfigurationSetting(key); + + console.log("The setting has a value of:", setting.value); + console.log("Details:", setting); +} + +main().catch((err) => { + console.error("The sample encountered an error:", err); +}); diff --git a/sdk/template/template/samples/typescript/src/sampleTemplate.ts b/sdk/template/template/samples/typescript/src/sampleTemplate.ts deleted file mode 100644 index 04164882a01e..000000000000 --- a/sdk/template/template/samples/typescript/src/sampleTemplate.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** - * Demonstrates something - */ - -import { AzureKeyCredential } from "@azure/template"; - -// 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 endpoint = process.env["ENDPOINT"] || ""; -const apiKey = process.env["API_KEY"] || ""; - -export async function main() { - console.log("== Sample Template =="); - new AzureKeyCredential(apiKey); - - // TODO -} - -main().catch((err) => { - console.error("The sample encountered an error:", err); -}); diff --git a/sdk/template/template/samples/typescript/tsconfig.json b/sdk/template/template/samples/typescript/tsconfig.json index bcc3352ff11d..5ed056486b40 100644 --- a/sdk/template/template/samples/typescript/tsconfig.json +++ b/sdk/template/template/samples/typescript/tsconfig.json @@ -1,17 +1,16 @@ { - "compilerOptions": { - "module": "commonjs", - "moduleResolution": "node", - - "allowSyntheticDefaultImports": true, - - "strict": true, - "alwaysStrict": true, - - "outDir": "dist", - "rootDir": "src" - }, - "include": ["src/**.ts"], - "exclude": ["node_modules"] - } - \ No newline at end of file + "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/template/template/src/configurationClient.ts b/sdk/template/template/src/configurationClient.ts new file mode 100644 index 000000000000..8197d523b2ed --- /dev/null +++ b/sdk/template/template/src/configurationClient.ts @@ -0,0 +1,182 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + PipelineOptions, + TokenCredential, + OperationOptions, + bearerTokenAuthenticationPolicy, + createPipelineFromOptions, + InternalPipelineOptions +} from "@azure/core-http"; +import { CanonicalCode } from "@opentelemetry/api"; + +import { SDK_VERSION } from "./constants"; +import { logger } from "./logger"; +import { ConfigurationSetting, GeneratedClient } from "./generated"; +import { createSpan } from "./tracing"; +import { quoteETag } from "./util"; + +// re-export generated types that are used as public interfaces. +export { ConfigurationSetting }; + +/** + * Options for the `getConfigurationSetting` method of `ConfigurationClient`. + */ +export interface GetConfigurationSettingOptions extends OperationOptions { + /** + * If set to `true`, the method will use entity tags to instruct the service + * to send an updated value only if the value has changed. + * + * NOTE: This option is only supported if passing a full + * `ConfigurationSetting` object with an `etag` as the first parameter to + * `getConfigurationSetting`. + */ + onlyIfChanged?: boolean; +} + +/** + * Client options used to configure App Configuration API requests. + */ +export interface ConfigurationClientOptions extends PipelineOptions { + // Any custom options configured at the client level go here. +} + +/** + * The client class used to interact with the App Configuration service. + */ +export class ConfigurationClient { + private client: GeneratedClient; + + /** + * Creates an instance of a ConfigurationClient. + * + * Example usage: + * ```ts + * import { ConfigurationClient} from "@azure/ai-text-analytics"; + * import { DefaultAzureCredential} from "@azure/identity"; + * + * const client = new ConfigurationClient( + * "", + * new DefaultAzureCredential() + * ); + * ``` + * @param endpointUrl - the URL to the App Configuration endpoint + * @param credential - used to authenticate requests to the service + * @param options - optional configuration used to send requests to the service + */ + constructor( + endpointUrl: string, + credential: TokenCredential, + options: ConfigurationClientOptions = {} + ) { + // The below code helps us set a proper User-Agent header on all requests + const libInfo = `azsdk-js-template-template/${SDK_VERSION}`; + if (!options.userAgentOptions) { + options.userAgentOptions = {}; + } + if (options.userAgentOptions.userAgentPrefix) { + options.userAgentOptions.userAgentPrefix = `${options.userAgentOptions.userAgentPrefix} ${libInfo}`; + } else { + options.userAgentOptions.userAgentPrefix = libInfo; + } + + // The AAD scope for an API is usually the baseUri + "/.default", but it + // may be different for your service. + const authPolicy = bearerTokenAuthenticationPolicy(credential, `${endpointUrl}/.default`); + + const internalPipelineOptions: InternalPipelineOptions = { + ...options, + deserializationOptions: { + expectedContentTypes: { + json: [ + "application/vnd.microsoft.appconfig.kvset+json", + "application/vnd.microsoft.appconfig.kv+json", + "application/vnd.microsoft.appconfig.kvs+json", + "application/vnd.microsoft.appconfig.keyset+json", + "application/vnd.microsoft.appconfig.revs+json" + ] + } + }, + ...{ + loggingOptions: { + logger: logger.info, + // This array contains header names we want to log that are not already + // included as safe. Unknown/unsafe headers are logged as "". + allowedHeaderNames: ["x-ms-correlation-request-id"] + } + } + }; + const pipeline = createPipelineFromOptions(internalPipelineOptions, authPolicy); + + this.client = new GeneratedClient(endpointUrl, pipeline); + } + + /** + * Retrieve the contents of an App Configuration setting by name (key). + * + * @param key - the unique name of the setting to get + * @param options - optional configuration for the operation + */ + public async getConfigurationSetting( + key: string, + options?: GetConfigurationSettingOptions + ): Promise; + + /** + * Retrieve an updated value of an App Configuration setting, allowing for + * the use of entity tags to request the new value only if it has changed. + * + * @param setting - the setting to retrieve from the service + * @param options - optional configuration for the operation + */ + public async getConfigurationSetting( + setting: ConfigurationSetting, + options?: GetConfigurationSettingOptions + ): Promise; + + public async getConfigurationSetting( + keyOrSetting: string | ConfigurationSetting, + options: GetConfigurationSettingOptions = {} + ): Promise { + let key: string; + let ifNoneMatch: string | undefined; + + if (typeof keyOrSetting === "string") { + key = keyOrSetting; + if (options.onlyIfChanged) { + throw new RangeError( + "You must pass a ConfigurationSetting instead of a key to perform a conditional fetch." + ); + } + } else { + key = keyOrSetting.key; + const etag = keyOrSetting.etag; + if (options.onlyIfChanged) { + ifNoneMatch = quoteETag(etag); + } + } + + const { span, updatedOptions } = createSpan( + // Here you set the name of the span, usually clientName-operationName + "ConfigurationClient-getConfigurationSetting", + options + ); + + try { + const result = await this.client.getKeyValue(key, { + ...updatedOptions, + ifNoneMatch + }); + return result; + } catch (e) { + // There are different standard codes available for different errors: + // https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#status + span.setStatus({ code: CanonicalCode.UNKNOWN, message: e.message }); + + throw e; + } finally { + span.end(); + } + } +} diff --git a/sdk/template/template/src/print.ts b/sdk/template/template/src/constants.ts similarity index 53% rename from sdk/template/template/src/print.ts rename to sdk/template/template/src/constants.ts index d717040cbbc3..dbe3c3cdbae7 100644 --- a/sdk/template/template/src/print.ts +++ b/sdk/template/template/src/constants.ts @@ -1,6 +1,4 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export default function(str: string): void { - console.log(str); -} +export const SDK_VERSION: string = "1.0.11-beta.1"; diff --git a/sdk/template/template/src/generated/generatedClient.ts b/sdk/template/template/src/generated/generatedClient.ts new file mode 100644 index 000000000000..471a997d1718 --- /dev/null +++ b/sdk/template/template/src/generated/generatedClient.ts @@ -0,0 +1,794 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * 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 Parameters from "./models/parameters"; +import * as Mappers from "./models/mappers"; +import { GeneratedClientContext } from "./generatedClientContext"; +import { + GeneratedClientOptionalParams, + GeneratedClientGetKeysOptionalParams, + GeneratedClientGetKeysResponse, + GeneratedClientCheckKeysOptionalParams, + GeneratedClientCheckKeysResponse, + GeneratedClientGetKeyValuesOptionalParams, + GeneratedClientGetKeyValuesResponse, + GeneratedClientCheckKeyValuesOptionalParams, + GeneratedClientCheckKeyValuesResponse, + GeneratedClientGetKeyValueOptionalParams, + GeneratedClientGetKeyValueResponse, + GeneratedClientPutKeyValueOptionalParams, + GeneratedClientPutKeyValueResponse, + GeneratedClientDeleteKeyValueOptionalParams, + GeneratedClientDeleteKeyValueResponse, + GeneratedClientCheckKeyValueOptionalParams, + GeneratedClientCheckKeyValueResponse, + GeneratedClientGetLabelsOptionalParams, + GeneratedClientGetLabelsResponse, + GeneratedClientCheckLabelsOptionalParams, + GeneratedClientCheckLabelsResponse, + GeneratedClientPutLockOptionalParams, + GeneratedClientPutLockResponse, + GeneratedClientDeleteLockOptionalParams, + GeneratedClientDeleteLockResponse, + GeneratedClientGetRevisionsOptionalParams, + GeneratedClientGetRevisionsResponse, + GeneratedClientCheckRevisionsOptionalParams, + GeneratedClientCheckRevisionsResponse, + GeneratedClientGetKeysNextOptionalParams, + GeneratedClientGetKeysNextResponse, + GeneratedClientGetKeyValuesNextOptionalParams, + GeneratedClientGetKeyValuesNextResponse, + GeneratedClientGetLabelsNextOptionalParams, + GeneratedClientGetLabelsNextResponse, + GeneratedClientGetRevisionsNextOptionalParams, + GeneratedClientGetRevisionsNextResponse +} from "./models"; + +/** @hidden */ +export class GeneratedClient extends GeneratedClientContext { + /** + * Initializes a new instance of the GeneratedClient class. + * @param endpoint The endpoint of the App Configuration instance to send requests to. + * @param options The parameter options + */ + constructor(endpoint: string, options?: GeneratedClientOptionalParams) { + super(endpoint, options); + } + + /** + * Gets a list of keys. + * @param options The options parameters. + */ + getKeys( + options?: GeneratedClientGetKeysOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getKeysOperationSpec + ) as Promise; + } + + /** + * Requests the headers and status of the given resource. + * @param options The options parameters. + */ + checkKeys( + options?: GeneratedClientCheckKeysOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + checkKeysOperationSpec + ) as Promise; + } + + /** + * Gets a list of key-values. + * @param options The options parameters. + */ + getKeyValues( + options?: GeneratedClientGetKeyValuesOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getKeyValuesOperationSpec + ) as Promise; + } + + /** + * Requests the headers and status of the given resource. + * @param options The options parameters. + */ + checkKeyValues( + options?: GeneratedClientCheckKeyValuesOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + checkKeyValuesOperationSpec + ) as Promise; + } + + /** + * Gets a single key-value. + * @param key The key of the key-value to retrieve. + * @param options The options parameters. + */ + getKeyValue( + key: string, + options?: GeneratedClientGetKeyValueOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + key, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getKeyValueOperationSpec + ) as Promise; + } + + /** + * Creates a key-value. + * @param key The key of the key-value to create. + * @param options The options parameters. + */ + putKeyValue( + key: string, + options?: GeneratedClientPutKeyValueOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + key, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + putKeyValueOperationSpec + ) as Promise; + } + + /** + * Deletes a key-value. + * @param key The key of the key-value to delete. + * @param options The options parameters. + */ + deleteKeyValue( + key: string, + options?: GeneratedClientDeleteKeyValueOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + key, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + deleteKeyValueOperationSpec + ) as Promise; + } + + /** + * Requests the headers and status of the given resource. + * @param key The key of the key-value to retrieve. + * @param options The options parameters. + */ + checkKeyValue( + key: string, + options?: GeneratedClientCheckKeyValueOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + key, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + checkKeyValueOperationSpec + ) as Promise; + } + + /** + * Gets a list of labels. + * @param options The options parameters. + */ + getLabels( + options?: GeneratedClientGetLabelsOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getLabelsOperationSpec + ) as Promise; + } + + /** + * Requests the headers and status of the given resource. + * @param options The options parameters. + */ + checkLabels( + options?: GeneratedClientCheckLabelsOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + checkLabelsOperationSpec + ) as Promise; + } + + /** + * Locks a key-value. + * @param key The key of the key-value to lock. + * @param options The options parameters. + */ + putLock( + key: string, + options?: GeneratedClientPutLockOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + key, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + putLockOperationSpec + ) as Promise; + } + + /** + * Unlocks a key-value. + * @param key The key of the key-value to unlock. + * @param options The options parameters. + */ + deleteLock( + key: string, + options?: GeneratedClientDeleteLockOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + key, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + deleteLockOperationSpec + ) as Promise; + } + + /** + * Gets a list of key-value revisions. + * @param options The options parameters. + */ + getRevisions( + options?: GeneratedClientGetRevisionsOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getRevisionsOperationSpec + ) as Promise; + } + + /** + * Requests the headers and status of the given resource. + * @param options The options parameters. + */ + checkRevisions( + options?: GeneratedClientCheckRevisionsOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + checkRevisionsOperationSpec + ) as Promise; + } + + /** + * GetKeysNext + * @param nextLink The nextLink from the previous successful call to the GetKeys method. + * @param options The options parameters. + */ + getKeysNext( + nextLink: string, + options?: GeneratedClientGetKeysNextOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + nextLink, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getKeysNextOperationSpec + ) as Promise; + } + + /** + * GetKeyValuesNext + * @param nextLink The nextLink from the previous successful call to the GetKeyValues method. + * @param options The options parameters. + */ + getKeyValuesNext( + nextLink: string, + options?: GeneratedClientGetKeyValuesNextOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + nextLink, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getKeyValuesNextOperationSpec + ) as Promise; + } + + /** + * GetLabelsNext + * @param nextLink The nextLink from the previous successful call to the GetLabels method. + * @param options The options parameters. + */ + getLabelsNext( + nextLink: string, + options?: GeneratedClientGetLabelsNextOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + nextLink, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getLabelsNextOperationSpec + ) as Promise; + } + + /** + * GetRevisionsNext + * @param nextLink The nextLink from the previous successful call to the GetRevisions method. + * @param options The options parameters. + */ + getRevisionsNext( + nextLink: string, + options?: GeneratedClientGetRevisionsNextOptionalParams + ): Promise { + const operationArguments: coreHttp.OperationArguments = { + nextLink, + options: coreHttp.operationOptionsToRequestOptionsBase(options || {}) + }; + return this.sendOperationRequest( + operationArguments, + getRevisionsNextOperationSpec + ) as Promise; + } +} +// Operation Specifications +const serializer = new coreHttp.Serializer(Mappers, /* isXml */ false); + +const getKeysOperationSpec: coreHttp.OperationSpec = { + path: "/keys", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.KeyListResult, + headersMapper: Mappers.GeneratedClientGetKeysHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [Parameters.name, Parameters.apiVersion, Parameters.after], + urlParameters: [Parameters.endpoint], + headerParameters: [ + Parameters.accept, + Parameters.syncToken, + Parameters.acceptDatetime + ], + serializer +}; +const checkKeysOperationSpec: coreHttp.OperationSpec = { + path: "/keys", + httpMethod: "HEAD", + responses: { + 200: { + headersMapper: Mappers.GeneratedClientCheckKeysHeaders + }, + default: {} + }, + queryParameters: [Parameters.name, Parameters.apiVersion, Parameters.after], + urlParameters: [Parameters.endpoint], + headerParameters: [Parameters.syncToken, Parameters.acceptDatetime], + serializer +}; +const getKeyValuesOperationSpec: coreHttp.OperationSpec = { + path: "/kv", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.KeyValueListResult, + headersMapper: Mappers.GeneratedClientGetKeyValuesHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [ + Parameters.apiVersion, + Parameters.after, + Parameters.key, + Parameters.label, + Parameters.select + ], + urlParameters: [Parameters.endpoint], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept1 + ], + serializer +}; +const checkKeyValuesOperationSpec: coreHttp.OperationSpec = { + path: "/kv", + httpMethod: "HEAD", + responses: { + 200: { + headersMapper: Mappers.GeneratedClientCheckKeyValuesHeaders + }, + default: {} + }, + queryParameters: [ + Parameters.apiVersion, + Parameters.after, + Parameters.key, + Parameters.label, + Parameters.select + ], + urlParameters: [Parameters.endpoint], + headerParameters: [Parameters.syncToken, Parameters.acceptDatetime], + serializer +}; +const getKeyValueOperationSpec: coreHttp.OperationSpec = { + path: "/kv/{key}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.ConfigurationSetting, + headersMapper: Mappers.GeneratedClientGetKeyValueHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [Parameters.apiVersion, Parameters.label, Parameters.select], + urlParameters: [Parameters.endpoint, Parameters.key1], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept2, + Parameters.ifMatch, + Parameters.ifNoneMatch + ], + serializer +}; +const putKeyValueOperationSpec: coreHttp.OperationSpec = { + path: "/kv/{key}", + httpMethod: "PUT", + responses: { + 200: { + bodyMapper: Mappers.ConfigurationSetting, + headersMapper: Mappers.GeneratedClientPutKeyValueHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + requestBody: Parameters.entity, + queryParameters: [Parameters.apiVersion, Parameters.label], + urlParameters: [Parameters.endpoint, Parameters.key1], + headerParameters: [ + Parameters.syncToken, + Parameters.accept2, + Parameters.ifMatch, + Parameters.ifNoneMatch, + Parameters.contentType + ], + mediaType: "json", + serializer +}; +const deleteKeyValueOperationSpec: coreHttp.OperationSpec = { + path: "/kv/{key}", + httpMethod: "DELETE", + responses: { + 200: { + bodyMapper: Mappers.ConfigurationSetting, + headersMapper: Mappers.GeneratedClientDeleteKeyValueHeaders + }, + 204: { + headersMapper: Mappers.GeneratedClientDeleteKeyValueHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [Parameters.apiVersion, Parameters.label], + urlParameters: [Parameters.endpoint, Parameters.key1], + headerParameters: [ + Parameters.syncToken, + Parameters.accept2, + Parameters.ifMatch + ], + serializer +}; +const checkKeyValueOperationSpec: coreHttp.OperationSpec = { + path: "/kv/{key}", + httpMethod: "HEAD", + responses: { + 200: { + headersMapper: Mappers.GeneratedClientCheckKeyValueHeaders + }, + default: {} + }, + queryParameters: [Parameters.apiVersion, Parameters.label, Parameters.select], + urlParameters: [Parameters.endpoint, Parameters.key1], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.ifMatch, + Parameters.ifNoneMatch + ], + serializer +}; +const getLabelsOperationSpec: coreHttp.OperationSpec = { + path: "/labels", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.LabelListResult, + headersMapper: Mappers.GeneratedClientGetLabelsHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [ + Parameters.name, + Parameters.apiVersion, + Parameters.after, + Parameters.select1 + ], + urlParameters: [Parameters.endpoint], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept3 + ], + serializer +}; +const checkLabelsOperationSpec: coreHttp.OperationSpec = { + path: "/labels", + httpMethod: "HEAD", + responses: { + 200: { + headersMapper: Mappers.GeneratedClientCheckLabelsHeaders + }, + default: {} + }, + queryParameters: [ + Parameters.name, + Parameters.apiVersion, + Parameters.after, + Parameters.select1 + ], + urlParameters: [Parameters.endpoint], + headerParameters: [Parameters.syncToken, Parameters.acceptDatetime], + serializer +}; +const putLockOperationSpec: coreHttp.OperationSpec = { + path: "/locks/{key}", + httpMethod: "PUT", + responses: { + 200: { + bodyMapper: Mappers.ConfigurationSetting, + headersMapper: Mappers.GeneratedClientPutLockHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [Parameters.apiVersion, Parameters.label], + urlParameters: [Parameters.endpoint, Parameters.key1], + headerParameters: [ + Parameters.syncToken, + Parameters.accept2, + Parameters.ifMatch, + Parameters.ifNoneMatch + ], + serializer +}; +const deleteLockOperationSpec: coreHttp.OperationSpec = { + path: "/locks/{key}", + httpMethod: "DELETE", + responses: { + 200: { + bodyMapper: Mappers.ConfigurationSetting, + headersMapper: Mappers.GeneratedClientDeleteLockHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [Parameters.apiVersion, Parameters.label], + urlParameters: [Parameters.endpoint, Parameters.key1], + headerParameters: [ + Parameters.syncToken, + Parameters.accept2, + Parameters.ifMatch, + Parameters.ifNoneMatch + ], + serializer +}; +const getRevisionsOperationSpec: coreHttp.OperationSpec = { + path: "/revisions", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.KeyValueListResult, + headersMapper: Mappers.GeneratedClientGetRevisionsHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [ + Parameters.apiVersion, + Parameters.after, + Parameters.key, + Parameters.label, + Parameters.select + ], + urlParameters: [Parameters.endpoint], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept1 + ], + serializer +}; +const checkRevisionsOperationSpec: coreHttp.OperationSpec = { + path: "/revisions", + httpMethod: "HEAD", + responses: { + 200: { + headersMapper: Mappers.GeneratedClientCheckRevisionsHeaders + }, + default: {} + }, + queryParameters: [ + Parameters.apiVersion, + Parameters.after, + Parameters.key, + Parameters.label, + Parameters.select + ], + urlParameters: [Parameters.endpoint], + headerParameters: [Parameters.syncToken, Parameters.acceptDatetime], + serializer +}; +const getKeysNextOperationSpec: coreHttp.OperationSpec = { + path: "{nextLink}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.KeyListResult, + headersMapper: Mappers.GeneratedClientGetKeysNextHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [Parameters.name, Parameters.apiVersion, Parameters.after], + urlParameters: [Parameters.endpoint, Parameters.nextLink], + headerParameters: [ + Parameters.accept, + Parameters.syncToken, + Parameters.acceptDatetime + ], + serializer +}; +const getKeyValuesNextOperationSpec: coreHttp.OperationSpec = { + path: "{nextLink}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.KeyValueListResult, + headersMapper: Mappers.GeneratedClientGetKeyValuesNextHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [ + Parameters.apiVersion, + Parameters.after, + Parameters.key, + Parameters.label, + Parameters.select + ], + urlParameters: [Parameters.endpoint, Parameters.nextLink], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept1 + ], + serializer +}; +const getLabelsNextOperationSpec: coreHttp.OperationSpec = { + path: "{nextLink}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.LabelListResult, + headersMapper: Mappers.GeneratedClientGetLabelsNextHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [ + Parameters.name, + Parameters.apiVersion, + Parameters.after, + Parameters.select1 + ], + urlParameters: [Parameters.endpoint, Parameters.nextLink], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept3 + ], + serializer +}; +const getRevisionsNextOperationSpec: coreHttp.OperationSpec = { + path: "{nextLink}", + httpMethod: "GET", + responses: { + 200: { + bodyMapper: Mappers.KeyValueListResult, + headersMapper: Mappers.GeneratedClientGetRevisionsNextHeaders + }, + default: { + bodyMapper: Mappers.ErrorModel + } + }, + queryParameters: [ + Parameters.apiVersion, + Parameters.after, + Parameters.key, + Parameters.label, + Parameters.select + ], + urlParameters: [Parameters.endpoint, Parameters.nextLink], + headerParameters: [ + Parameters.syncToken, + Parameters.acceptDatetime, + Parameters.accept1 + ], + serializer +}; diff --git a/sdk/template/template/src/generated/generatedClientContext.ts b/sdk/template/template/src/generated/generatedClientContext.ts new file mode 100644 index 000000000000..57791271cc84 --- /dev/null +++ b/sdk/template/template/src/generated/generatedClientContext.ts @@ -0,0 +1,53 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * 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 { GeneratedClientOptionalParams } from "./models"; + +const packageName = "@azure/template"; +const packageVersion = "1.0.11-beta.1"; + +/** @hidden */ +export class GeneratedClientContext extends coreHttp.ServiceClient { + endpoint: string; + syncToken?: string; + apiVersion: string; + + /** + * Initializes a new instance of the GeneratedClientContext class. + * @param endpoint The endpoint of the App Configuration instance to send requests to. + * @param options The parameter options + */ + constructor(endpoint: string, options?: GeneratedClientOptionalParams) { + if (endpoint === undefined) { + throw new Error("'endpoint' cannot be null"); + } + + // Initializing default values for options + if (!options) { + options = {}; + } + + if (!options.userAgent) { + const defaultUserAgent = coreHttp.getDefaultUserAgentValue(); + options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`; + } + + super(undefined, options); + + this.requestContentType = "application/json; charset=utf-8"; + + this.baseUri = options.endpoint || "{endpoint}"; + + // Parameter assignments + this.endpoint = endpoint; + + // Assigning values to Constant parameters + this.apiVersion = options.apiVersion || "1.0"; + } +} diff --git a/sdk/template/template/src/generated/index.ts b/sdk/template/template/src/generated/index.ts new file mode 100644 index 000000000000..3aebf3c9a56c --- /dev/null +++ b/sdk/template/template/src/generated/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +export * from "./models"; +export { GeneratedClient } from "./generatedClient"; +export { GeneratedClientContext } from "./generatedClientContext"; diff --git a/sdk/template/template/src/generated/models/index.ts b/sdk/template/template/src/generated/models/index.ts new file mode 100644 index 000000000000..961b02122bdd --- /dev/null +++ b/sdk/template/template/src/generated/models/index.ts @@ -0,0 +1,704 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * 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"; + +/** The result of a list request. */ +export interface KeyListResult { + /** The collection value. */ + items?: Key[]; + /** The URI that can be used to request the next set of paged results. */ + nextLink?: string; +} + +export interface Key { + /** + * The name of the key. + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly name?: string; +} + +/** Azure App Configuration error object. */ +export interface ErrorModel { + /** The type of the error. */ + type?: string; + /** A brief summary of the error. */ + title?: string; + /** The name of the parameter that resulted in the error. */ + name?: string; + /** A detailed description of the error. */ + detail?: string; + /** The HTTP status code that the error maps to. */ + status?: number; +} + +/** The result of a list request. */ +export interface KeyValueListResult { + /** The collection value. */ + items?: ConfigurationSetting[]; + /** The URI that can be used to request the next set of paged results. */ + nextLink?: string; +} + +export interface ConfigurationSetting { + /** The unique name of the key-value. */ + key: string; + /** The label of the key-value. */ + label?: string; + /** The content type of the key-value. */ + contentType?: string; + /** The value of the key-value. */ + value?: string; + /** The time the key-value was last modified. */ + lastModified?: Date; + /** Dictionary of */ + tags?: { [propertyName: string]: string }; + /** Indicates whether or not this key-value is readonly. */ + isReadOnly?: boolean; + /** The entity-tag of the key-value. */ + etag?: string; +} + +/** The result of a list request. */ +export interface LabelListResult { + /** The collection value. */ + items?: Label[]; + /** The URI that can be used to request the next set of paged results. */ + nextLink?: string; +} + +export interface Label { + /** + * The name of the label. + * NOTE: This property will not be serialized. It can only be populated by the server. + */ + readonly name?: string; +} + +/** Defines headers for GeneratedClient_getKeys operation. */ +export interface GeneratedClientGetKeysHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_checkKeys operation. */ +export interface GeneratedClientCheckKeysHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_getKeyValues operation. */ +export interface GeneratedClientGetKeyValuesHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_checkKeyValues operation. */ +export interface GeneratedClientCheckKeyValuesHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_getKeyValue operation. */ +export interface GeneratedClientGetKeyValueHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; + /** An identifier representing the returned state of the resource. */ + eTag?: string; + /** A UTC datetime that specifies the last time the resource was modified. */ + lastModified?: string; +} + +/** Defines headers for GeneratedClient_putKeyValue operation. */ +export interface GeneratedClientPutKeyValueHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; + /** An identifier representing the returned state of the resource. */ + eTag?: string; +} + +/** Defines headers for GeneratedClient_deleteKeyValue operation. */ +export interface GeneratedClientDeleteKeyValueHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; + /** An identifier representing the returned state of the resource. */ + eTag?: string; +} + +/** Defines headers for GeneratedClient_checkKeyValue operation. */ +export interface GeneratedClientCheckKeyValueHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; + /** An identifier representing the returned state of the resource. */ + eTag?: string; + /** A UTC datetime that specifies the last time the resource was modified. */ + lastModified?: string; +} + +/** Defines headers for GeneratedClient_getLabels operation. */ +export interface GeneratedClientGetLabelsHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_checkLabels operation. */ +export interface GeneratedClientCheckLabelsHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_putLock operation. */ +export interface GeneratedClientPutLockHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; + /** An identifier representing the returned state of the resource. */ + eTag?: string; +} + +/** Defines headers for GeneratedClient_deleteLock operation. */ +export interface GeneratedClientDeleteLockHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; + /** An identifier representing the returned state of the resource. */ + eTag?: string; +} + +/** Defines headers for GeneratedClient_getRevisions operation. */ +export interface GeneratedClientGetRevisionsHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_checkRevisions operation. */ +export interface GeneratedClientCheckRevisionsHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_getKeysNext operation. */ +export interface GeneratedClientGetKeysNextHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_getKeyValuesNext operation. */ +export interface GeneratedClientGetKeyValuesNextHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_getLabelsNext operation. */ +export interface GeneratedClientGetLabelsNextHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines headers for GeneratedClient_getRevisionsNext operation. */ +export interface GeneratedClientGetRevisionsNextHeaders { + /** Enables real-time consistency between requests by providing the returned value in the next request made to the server. */ + syncToken?: string; +} + +/** Defines values for SettingFields. */ +export type SettingFields = + | "key" + | "label" + | "content_type" + | "value" + | "last_modified" + | "tags" + | "locked" + | "etag"; + +/** Optional parameters. */ +export interface GeneratedClientGetKeysOptionalParams + extends coreHttp.OperationOptions { + /** A filter for the name of the returned keys. */ + name?: string; + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; +} + +/** Contains response data for the getKeys operation. */ +export type GeneratedClientGetKeysResponse = GeneratedClientGetKeysHeaders & + KeyListResult & { + /** 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: KeyListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetKeysHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientCheckKeysOptionalParams + extends coreHttp.OperationOptions { + /** A filter for the name of the returned keys. */ + name?: string; + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; +} + +/** Contains response data for the checkKeys operation. */ +export type GeneratedClientCheckKeysResponse = GeneratedClientCheckKeysHeaders & { + /** The underlying HTTP response. */ + _response: coreHttp.HttpResponse & { + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientCheckKeysHeaders; + }; +}; + +/** Optional parameters. */ +export interface GeneratedClientGetKeyValuesOptionalParams + extends coreHttp.OperationOptions { + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** A filter used to match keys. */ + key?: string; + /** A filter used to match labels */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; +} + +/** Contains response data for the getKeyValues operation. */ +export type GeneratedClientGetKeyValuesResponse = GeneratedClientGetKeyValuesHeaders & + KeyValueListResult & { + /** 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: KeyValueListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetKeyValuesHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientCheckKeyValuesOptionalParams + extends coreHttp.OperationOptions { + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** A filter used to match keys. */ + key?: string; + /** A filter used to match labels */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; +} + +/** Contains response data for the checkKeyValues operation. */ +export type GeneratedClientCheckKeyValuesResponse = GeneratedClientCheckKeyValuesHeaders & { + /** The underlying HTTP response. */ + _response: coreHttp.HttpResponse & { + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientCheckKeyValuesHeaders; + }; +}; + +/** Optional parameters. */ +export interface GeneratedClientGetKeyValueOptionalParams + extends coreHttp.OperationOptions { + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** The label of the key-value to retrieve. */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; + /** Used to perform an operation only if the targeted resource's etag matches the value provided. */ + ifMatch?: string; + /** Used to perform an operation only if the targeted resource's etag does not match the value provided. */ + ifNoneMatch?: string; +} + +/** Contains response data for the getKeyValue operation. */ +export type GeneratedClientGetKeyValueResponse = GeneratedClientGetKeyValueHeaders & + ConfigurationSetting & { + /** 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: ConfigurationSetting; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetKeyValueHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientPutKeyValueOptionalParams + extends coreHttp.OperationOptions { + /** The label of the key-value to create. */ + label?: string; + /** Used to perform an operation only if the targeted resource's etag matches the value provided. */ + ifMatch?: string; + /** Used to perform an operation only if the targeted resource's etag does not match the value provided. */ + ifNoneMatch?: string; + /** The key-value to create. */ + entity?: ConfigurationSetting; +} + +/** Contains response data for the putKeyValue operation. */ +export type GeneratedClientPutKeyValueResponse = GeneratedClientPutKeyValueHeaders & + ConfigurationSetting & { + /** 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: ConfigurationSetting; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientPutKeyValueHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientDeleteKeyValueOptionalParams + extends coreHttp.OperationOptions { + /** The label of the key-value to delete. */ + label?: string; + /** Used to perform an operation only if the targeted resource's etag matches the value provided. */ + ifMatch?: string; +} + +/** Contains response data for the deleteKeyValue operation. */ +export type GeneratedClientDeleteKeyValueResponse = GeneratedClientDeleteKeyValueHeaders & + ConfigurationSetting & { + /** 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: ConfigurationSetting; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientDeleteKeyValueHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientCheckKeyValueOptionalParams + extends coreHttp.OperationOptions { + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** The label of the key-value to retrieve. */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; + /** Used to perform an operation only if the targeted resource's etag matches the value provided. */ + ifMatch?: string; + /** Used to perform an operation only if the targeted resource's etag does not match the value provided. */ + ifNoneMatch?: string; +} + +/** Contains response data for the checkKeyValue operation. */ +export type GeneratedClientCheckKeyValueResponse = GeneratedClientCheckKeyValueHeaders & { + /** The underlying HTTP response. */ + _response: coreHttp.HttpResponse & { + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientCheckKeyValueHeaders; + }; +}; + +/** Optional parameters. */ +export interface GeneratedClientGetLabelsOptionalParams + extends coreHttp.OperationOptions { + /** A filter for the name of the returned labels. */ + name?: string; + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: string[]; +} + +/** Contains response data for the getLabels operation. */ +export type GeneratedClientGetLabelsResponse = GeneratedClientGetLabelsHeaders & + LabelListResult & { + /** 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: LabelListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetLabelsHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientCheckLabelsOptionalParams + extends coreHttp.OperationOptions { + /** A filter for the name of the returned labels. */ + name?: string; + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: string[]; +} + +/** Contains response data for the checkLabels operation. */ +export type GeneratedClientCheckLabelsResponse = GeneratedClientCheckLabelsHeaders & { + /** The underlying HTTP response. */ + _response: coreHttp.HttpResponse & { + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientCheckLabelsHeaders; + }; +}; + +/** Optional parameters. */ +export interface GeneratedClientPutLockOptionalParams + extends coreHttp.OperationOptions { + /** The label, if any, of the key-value to lock. */ + label?: string; + /** Used to perform an operation only if the targeted resource's etag matches the value provided. */ + ifMatch?: string; + /** Used to perform an operation only if the targeted resource's etag does not match the value provided. */ + ifNoneMatch?: string; +} + +/** Contains response data for the putLock operation. */ +export type GeneratedClientPutLockResponse = GeneratedClientPutLockHeaders & + ConfigurationSetting & { + /** 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: ConfigurationSetting; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientPutLockHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientDeleteLockOptionalParams + extends coreHttp.OperationOptions { + /** The label, if any, of the key-value to unlock. */ + label?: string; + /** Used to perform an operation only if the targeted resource's etag matches the value provided. */ + ifMatch?: string; + /** Used to perform an operation only if the targeted resource's etag does not match the value provided. */ + ifNoneMatch?: string; +} + +/** Contains response data for the deleteLock operation. */ +export type GeneratedClientDeleteLockResponse = GeneratedClientDeleteLockHeaders & + ConfigurationSetting & { + /** 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: ConfigurationSetting; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientDeleteLockHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientGetRevisionsOptionalParams + extends coreHttp.OperationOptions { + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** A filter used to match keys. */ + key?: string; + /** A filter used to match labels */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; +} + +/** Contains response data for the getRevisions operation. */ +export type GeneratedClientGetRevisionsResponse = GeneratedClientGetRevisionsHeaders & + KeyValueListResult & { + /** 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: KeyValueListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetRevisionsHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientCheckRevisionsOptionalParams + extends coreHttp.OperationOptions { + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** A filter used to match keys. */ + key?: string; + /** A filter used to match labels */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; +} + +/** Contains response data for the checkRevisions operation. */ +export type GeneratedClientCheckRevisionsResponse = GeneratedClientCheckRevisionsHeaders & { + /** The underlying HTTP response. */ + _response: coreHttp.HttpResponse & { + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientCheckRevisionsHeaders; + }; +}; + +/** Optional parameters. */ +export interface GeneratedClientGetKeysNextOptionalParams + extends coreHttp.OperationOptions { + /** A filter for the name of the returned keys. */ + name?: string; + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; +} + +/** Contains response data for the getKeysNext operation. */ +export type GeneratedClientGetKeysNextResponse = GeneratedClientGetKeysNextHeaders & + KeyListResult & { + /** 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: KeyListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetKeysNextHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientGetKeyValuesNextOptionalParams + extends coreHttp.OperationOptions { + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** A filter used to match keys. */ + key?: string; + /** A filter used to match labels */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; +} + +/** Contains response data for the getKeyValuesNext operation. */ +export type GeneratedClientGetKeyValuesNextResponse = GeneratedClientGetKeyValuesNextHeaders & + KeyValueListResult & { + /** 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: KeyValueListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetKeyValuesNextHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientGetLabelsNextOptionalParams + extends coreHttp.OperationOptions { + /** A filter for the name of the returned labels. */ + name?: string; + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: string[]; +} + +/** Contains response data for the getLabelsNext operation. */ +export type GeneratedClientGetLabelsNextResponse = GeneratedClientGetLabelsNextHeaders & + LabelListResult & { + /** 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: LabelListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetLabelsNextHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientGetRevisionsNextOptionalParams + extends coreHttp.OperationOptions { + /** Instructs the server to return elements that appear after the element referred to by the specified token. */ + after?: string; + /** Requests the server to respond with the state of the resource at the specified time. */ + acceptDatetime?: string; + /** A filter used to match keys. */ + key?: string; + /** A filter used to match labels */ + label?: string; + /** Used to select what fields are present in the returned resource(s). */ + select?: SettingFields[]; +} + +/** Contains response data for the getRevisionsNext operation. */ +export type GeneratedClientGetRevisionsNextResponse = GeneratedClientGetRevisionsNextHeaders & + KeyValueListResult & { + /** 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: KeyValueListResult; + /** The parsed HTTP response headers. */ + parsedHeaders: GeneratedClientGetRevisionsNextHeaders; + }; + }; + +/** Optional parameters. */ +export interface GeneratedClientOptionalParams + extends coreHttp.ServiceClientOptions { + /** Used to guarantee real-time consistency between requests. */ + syncToken?: string; + /** Api Version */ + apiVersion?: string; + /** Overrides client endpoint. */ + endpoint?: string; +} diff --git a/sdk/template/template/src/generated/models/mappers.ts b/sdk/template/template/src/generated/models/mappers.ts new file mode 100644 index 000000000000..23323a8184e4 --- /dev/null +++ b/sdk/template/template/src/generated/models/mappers.ts @@ -0,0 +1,538 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * 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 KeyListResult: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "KeyListResult", + modelProperties: { + items: { + serializedName: "items", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Key" + } + } + } + }, + nextLink: { + serializedName: "@nextLink", + type: { + name: "String" + } + } + } + } +}; + +export const Key: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "Key", + modelProperties: { + name: { + serializedName: "name", + readOnly: true, + type: { + name: "String" + } + } + } + } +}; + +export const ErrorModel: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "ErrorModel", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + title: { + serializedName: "title", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + detail: { + serializedName: "detail", + type: { + name: "String" + } + }, + status: { + serializedName: "status", + type: { + name: "Number" + } + } + } + } +}; + +export const KeyValueListResult: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "KeyValueListResult", + modelProperties: { + items: { + serializedName: "items", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ConfigurationSetting" + } + } + } + }, + nextLink: { + serializedName: "@nextLink", + type: { + name: "String" + } + } + } + } +}; + +export const ConfigurationSetting: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "ConfigurationSetting", + modelProperties: { + key: { + serializedName: "key", + required: true, + type: { + name: "String" + } + }, + label: { + serializedName: "label", + type: { + name: "String" + } + }, + contentType: { + serializedName: "content_type", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last_modified", + type: { + name: "DateTime" + } + }, + tags: { + serializedName: "tags", + type: { + name: "Dictionary", + value: { type: { name: "String" } } + } + }, + isReadOnly: { + serializedName: "locked", + type: { + name: "Boolean" + } + }, + etag: { + serializedName: "etag", + type: { + name: "String" + } + } + } + } +}; + +export const LabelListResult: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "LabelListResult", + modelProperties: { + items: { + serializedName: "items", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Label" + } + } + } + }, + nextLink: { + serializedName: "@nextLink", + type: { + name: "String" + } + } + } + } +}; + +export const Label: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "Label", + modelProperties: { + name: { + serializedName: "name", + readOnly: true, + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetKeysHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetKeysHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientCheckKeysHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientCheckKeysHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetKeyValuesHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetKeyValuesHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientCheckKeyValuesHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientCheckKeyValuesHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetKeyValueHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetKeyValueHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + }, + eTag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientPutKeyValueHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientPutKeyValueHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + }, + eTag: { + serializedName: "etag", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientDeleteKeyValueHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientDeleteKeyValueHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + }, + eTag: { + serializedName: "etag", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientCheckKeyValueHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientCheckKeyValueHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + }, + eTag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetLabelsHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetLabelsHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientCheckLabelsHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientCheckLabelsHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientPutLockHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientPutLockHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + }, + eTag: { + serializedName: "etag", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientDeleteLockHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientDeleteLockHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + }, + eTag: { + serializedName: "etag", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetRevisionsHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetRevisionsHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientCheckRevisionsHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientCheckRevisionsHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetKeysNextHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetKeysNextHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetKeyValuesNextHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetKeyValuesNextHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetLabelsNextHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetLabelsNextHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; + +export const GeneratedClientGetRevisionsNextHeaders: coreHttp.CompositeMapper = { + type: { + name: "Composite", + className: "GeneratedClientGetRevisionsNextHeaders", + modelProperties: { + syncToken: { + serializedName: "sync-token", + type: { + name: "String" + } + } + } + } +}; diff --git a/sdk/template/template/src/generated/models/parameters.ts b/sdk/template/template/src/generated/models/parameters.ts new file mode 100644 index 000000000000..1537fcd84ef6 --- /dev/null +++ b/sdk/template/template/src/generated/models/parameters.ts @@ -0,0 +1,255 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +import { + OperationParameter, + OperationURLParameter, + OperationQueryParameter, + QueryCollectionFormat +} from "@azure/core-http"; +import { ConfigurationSetting as ConfigurationSettingMapper } from "../models/mappers"; + +export const accept: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: + "application/vnd.microsoft.appconfig.keyset+json, application/json, application/problem+json", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + +export const endpoint: OperationURLParameter = { + parameterPath: "endpoint", + mapper: { + serializedName: "endpoint", + required: true, + type: { + name: "String" + } + }, + skipEncoding: true +}; + +export const name: OperationQueryParameter = { + parameterPath: ["options", "name"], + mapper: { + serializedName: "name", + type: { + name: "String" + } + } +}; + +export const syncToken: OperationParameter = { + parameterPath: "syncToken", + mapper: { + serializedName: "Sync-Token", + type: { + name: "String" + } + } +}; + +export const apiVersion: OperationQueryParameter = { + parameterPath: "apiVersion", + mapper: { + defaultValue: "1.0", + isConstant: true, + serializedName: "api-version", + type: { + name: "String" + } + } +}; + +export const after: OperationQueryParameter = { + parameterPath: ["options", "after"], + mapper: { + serializedName: "After", + type: { + name: "String" + } + } +}; + +export const acceptDatetime: OperationParameter = { + parameterPath: ["options", "acceptDatetime"], + mapper: { + serializedName: "Accept-Datetime", + type: { + name: "String" + } + } +}; + +export const accept1: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: + "application/vnd.microsoft.appconfig.kvset+json, application/json, application/problem+json", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + +export const key: OperationQueryParameter = { + parameterPath: ["options", "key"], + mapper: { + serializedName: "key", + type: { + name: "String" + } + } +}; + +export const label: OperationQueryParameter = { + parameterPath: ["options", "label"], + mapper: { + serializedName: "label", + type: { + name: "String" + } + } +}; + +export const select: OperationQueryParameter = { + parameterPath: ["options", "select"], + mapper: { + serializedName: "$Select", + type: { + name: "Sequence", + element: { + type: { + name: "Enum", + allowedValues: [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ] + } + } + } + }, + collectionFormat: QueryCollectionFormat.Csv +}; + +export const accept2: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: + "application/vnd.microsoft.appconfig.kv+json, application/json, application/problem+json", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + +export const key1: OperationURLParameter = { + parameterPath: "key", + mapper: { + serializedName: "key", + required: true, + type: { + name: "String" + } + } +}; + +export const ifMatch: OperationParameter = { + parameterPath: ["options", "ifMatch"], + mapper: { + serializedName: "If-Match", + type: { + name: "String" + } + } +}; + +export const ifNoneMatch: OperationParameter = { + parameterPath: ["options", "ifNoneMatch"], + mapper: { + serializedName: "If-None-Match", + type: { + name: "String" + } + } +}; + +export const contentType: OperationParameter = { + parameterPath: ["options", "contentType"], + mapper: { + defaultValue: "application/vnd.microsoft.appconfig.kv+json", + isConstant: true, + serializedName: "Content-Type", + type: { + name: "String" + } + } +}; + +export const entity: OperationParameter = { + parameterPath: ["options", "entity"], + mapper: ConfigurationSettingMapper +}; + +export const accept3: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: + "application/vnd.microsoft.appconfig.labelset+json, application/json, application/problem+json", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + +export const select1: OperationQueryParameter = { + parameterPath: ["options", "select"], + mapper: { + serializedName: "$Select", + type: { + name: "Sequence", + element: { + defaultValue: "name", + isConstant: true, + type: { + name: "String" + } + } + } + }, + collectionFormat: QueryCollectionFormat.Csv +}; + +export const nextLink: OperationURLParameter = { + parameterPath: "nextLink", + mapper: { + serializedName: "nextLink", + required: true, + type: { + name: "String" + } + }, + skipEncoding: true +}; diff --git a/sdk/template/template/src/index.ts b/sdk/template/template/src/index.ts index ffd1cf262fb9..698da7975a01 100644 --- a/sdk/template/template/src/index.ts +++ b/sdk/template/template/src/index.ts @@ -1,34 +1,4 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -// This node built-in must be shimmed for the browser. -import EventEmitter from "events"; -// This is a node dependency that needs to be replaced with a -// different implementation in the browser. -import print from "./print"; -export { print }; - -export { AzureKeyCredential, KeyCredential } from "@azure/core-auth"; - -// this is a utility function from a library that should be external -// for both node and web -import { isNode } from "@azure/core-http"; - -// exporting some value from a dependency -export { URLBuilder } from "@azure/core-http"; - -export function createEventEmitter(): EventEmitter { - // use event emitter - const e = new EventEmitter(); - - // Dynamic Node and browser-specific code - if (isNode) { - console.log("Node 👊"); - } else { - console.log("Browser ❤"); - } - - print("Created event emitter"); - - return e; -} +export * from "./configurationClient"; diff --git a/sdk/template/template/src/logger.ts b/sdk/template/template/src/logger.ts new file mode 100644 index 000000000000..f98322638ff0 --- /dev/null +++ b/sdk/template/template/src/logger.ts @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { createClientLogger } from "@azure/logger"; + +/** + * The \@azure/logger configuration for this package. + * + * @internal + */ +export const logger = createClientLogger("template"); diff --git a/sdk/template/template/src/print.browser.ts b/sdk/template/template/src/print.browser.ts deleted file mode 100644 index 594dc6cd615f..000000000000 --- a/sdk/template/template/src/print.browser.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -// This shim just declares "document" to be defined in this scope. -// If you really need access to browser features with strong -// type-checking, extend the shim to the extent you require or use: -// -// /// -declare const document: any; - -export default function(str: string): void { - document.write(str); -} diff --git a/sdk/template/template/src/tracing.ts b/sdk/template/template/src/tracing.ts new file mode 100644 index 000000000000..6281d205232e --- /dev/null +++ b/sdk/template/template/src/tracing.ts @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +import { createSpanFunction } from "@azure/core-http"; + +/** + * Creates a span using the global tracer. + * + * @param name - The name of the operation being performed. + * @param tracingOptions - The options for the underlying http request. + * + * @internal + */ +export const createSpan = createSpanFunction({ + namespace: "Microsoft.Learn", + packagePrefix: "Azure.Learn.ApiLearn" +}); diff --git a/sdk/template/template/src/util.ts b/sdk/template/template/src/util.ts new file mode 100644 index 000000000000..ff9373d6f939 --- /dev/null +++ b/sdk/template/template/src/util.ts @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** + * Handles etag quoting in AppConfig response objects. + * + * This is important because the etag inside the body of the configuration + * object isn't quoted, even though the header is. + * + * @param etag - the tag to quote, if it isn't quoted already + * + * @internal + */ +export function quoteETag(etag: string | undefined): string | undefined { + // https://tools.ietf.org/html/rfc7232#section-3.1 + if (etag === undefined || etag === "*") { + return etag; + } + + if (etag.startsWith('"') && etag.endsWith('"')) { + return etag; + } + + if (etag.startsWith("'") && etag.endsWith("'")) { + return etag; + } + + return `"${etag}"`; +} diff --git a/sdk/template/template/swagger/README.md b/sdk/template/template/swagger/README.md new file mode 100644 index 000000000000..994dc7b24710 --- /dev/null +++ b/sdk/template/template/swagger/README.md @@ -0,0 +1,43 @@ +# Azure Example TypeScript Protocol Layer + +> see https://aka.ms/autorest + +## Configuration + +```yaml +v3: true +package-name: "@azure/template" +title: GeneratedClient +description: Example Client +generate-metadata: false +license-header: MICROSOFT_MIT_NO_VERSION +output-folder: ../ +source-code-folder-path: ./src/generated +input-file: ./appconfiguration.json +add-credentials: false +package-version: 1.0.11-beta.1 +disable-async-iterators: true +hide-clients: true +use-extension: + "@autorest/typescript": "6.0.0-dev.20210121.2" +``` + +### Rename KeyValue to ConfigurationSetting + +```yaml +directive: + - from: swagger-document + where: $.definitions.KeyValue + transform: > + $["x-ms-client-name"] = "ConfigurationSetting"; +``` + +### Rename locked to isReadOnly + +```yaml +directive: + - from: swagger-document + where: $.definitions.KeyValue.properties.locked + transform: > + $["x-ms-client-name"] = "isReadOnly"; +``` diff --git a/sdk/template/template/swagger/appconfiguration.json b/sdk/template/template/swagger/appconfiguration.json new file mode 100644 index 000000000000..45a715db28cf --- /dev/null +++ b/sdk/template/template/swagger/appconfiguration.json @@ -0,0 +1,1351 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0", + "title": "Azure App Configuration" + }, + "schemes": ["https"], + "paths": { + "/keys": { + "get": { + "tags": ["Keys"], + "summary": "Gets a list of keys.", + "operationId": "GetKeys", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.keyset+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "A filter for the name of the returned keys.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyListResult" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "GetKeys": { + "$ref": "./examples/GetKeys.json" + } + }, + "x-ms-pageable": { + "itemName": "items", + "nextLinkName": "@nextLink" + } + }, + "head": { + "tags": ["Keys"], + "summary": "Requests the headers and status of the given resource.", + "operationId": "CheckKeys", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "A filter for the name of the returned keys.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed" + } + }, + "x-ms-examples": { + "CheckKeys": { + "$ref": "./examples/CheckKeys.json" + } + } + } + }, + "/kv": { + "get": { + "tags": ["KeyValues"], + "summary": "Gets a list of key-values.", + "operationId": "GetKeyValues", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.kvset+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "A filter used to match keys.", + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "A filter used to match labels", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ], + "x-ms-enum": { + "name": "SettingFields", + "modelAsString": false + } + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValueListResult" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "GetKeyValues": { + "$ref": "./examples/GetKeyValues.json" + } + }, + "x-ms-pageable": { + "itemName": "items", + "nextLinkName": "@nextLink" + } + }, + "head": { + "tags": ["KeyValues"], + "summary": "Requests the headers and status of the given resource.", + "operationId": "CheckKeyValues", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "A filter used to match keys.", + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "A filter used to match labels", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ], + "x-ms-enum": { + "name": "SettingFields", + "modelAsString": false + } + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed" + } + }, + "x-ms-examples": { + "CheckKeyValues": { + "$ref": "./examples/CheckKeyValues.json" + } + } + } + }, + "/kv/{key}": { + "get": { + "tags": ["KeyValues"], + "summary": "Gets a single key-value.", + "operationId": "GetKeyValue", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.kv+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "path", + "description": "The key of the key-value to retrieve.", + "required": true, + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "The label of the key-value to retrieve.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "If-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag matches the value provided.", + "type": "string" + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag does not match the value provided.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ], + "x-ms-enum": { + "name": "SettingFields", + "modelAsString": false + } + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValue" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + }, + "Last-Modified": { + "description": "A UTC datetime that specifies the last time the resource was modified.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "GetKeyValue": { + "$ref": "./examples/GetKeyValue.json" + }, + "GetKeyValue_IfMatch": { + "$ref": "./examples/GetKeyValue_IfMatch.json" + }, + "GetKeyValue_IfNoneMatch": { + "$ref": "./examples/GetKeyValue_IfNoneMatch.json" + } + } + }, + "put": { + "tags": ["KeyValues"], + "summary": "Creates a key-value.", + "operationId": "PutKeyValue", + "consumes": [ + "application/vnd.microsoft.appconfig.kv+json", + "application/vnd.microsoft.appconfig.kvset+json", + "application/json", + "text/json", + "application/*+json", + "application/json-patch+json" + ], + "produces": [ + "application/vnd.microsoft.appconfig.kv+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "path", + "description": "The key of the key-value to create.", + "required": true, + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "The label of the key-value to create.", + "type": "string" + }, + { + "name": "entity", + "in": "body", + "description": "The key-value to create.", + "schema": { + "$ref": "#/definitions/KeyValue" + } + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "If-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag matches the value provided.", + "type": "string" + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag does not match the value provided.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValue" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "PutKeyValue": { + "$ref": "./examples/PutKeyValue.json" + }, + "PutKeyValue_IfMatch": { + "$ref": "./examples/PutKeyValue_IfMatch.json" + } + } + }, + "delete": { + "tags": ["KeyValues"], + "summary": "Deletes a key-value.", + "operationId": "DeleteKeyValue", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.kv+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "path", + "description": "The key of the key-value to delete.", + "required": true, + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "The label of the key-value to delete.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "If-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag matches the value provided.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValue" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + } + } + }, + "204": { + "description": "Success", + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "DeleteKeyValue": { + "$ref": "./examples/DeleteKeyValue.json" + }, + "DeleteKeyValue_IfMatch": { + "$ref": "./examples/DeleteKeyValue_IfMatch.json" + } + } + }, + "head": { + "tags": ["KeyValues"], + "summary": "Requests the headers and status of the given resource.", + "operationId": "CheckKeyValue", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "key", + "in": "path", + "description": "The key of the key-value to retrieve.", + "required": true, + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "The label of the key-value to retrieve.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "If-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag matches the value provided.", + "type": "string" + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag does not match the value provided.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ], + "x-ms-enum": { + "name": "SettingFields", + "modelAsString": false + } + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + }, + "Last-Modified": { + "description": "A UTC datetime that specifies the last time the resource was modified.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed" + } + }, + "x-ms-examples": { + "CheckKeyValue": { + "$ref": "./examples/CheckKeyValue.json" + }, + "CheckKeyValue_IfMatch": { + "$ref": "./examples/CheckKeyValue_IfMatch.json" + }, + "CheckKeyValue_IfNoneMatch": { + "$ref": "./examples/CheckKeyValue_IfNoneMatch.json" + } + } + } + }, + "/labels": { + "get": { + "tags": ["Labels"], + "summary": "Gets a list of labels.", + "operationId": "GetLabels", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.labelset+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "A filter for the name of the returned labels.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": ["name"] + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/LabelListResult" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "GetLabels": { + "$ref": "./examples/GetLabels.json" + } + }, + "x-ms-pageable": { + "itemName": "items", + "nextLinkName": "@nextLink" + } + }, + "head": { + "tags": ["Labels"], + "summary": "Requests the headers and status of the given resource.", + "operationId": "CheckLabels", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "A filter for the name of the returned labels.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": ["name"] + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed" + } + }, + "x-ms-examples": { + "CheckLabels": { + "$ref": "./examples/CheckLabels.json" + } + } + } + }, + "/locks/{key}": { + "put": { + "tags": ["Locks"], + "summary": "Locks a key-value.", + "operationId": "PutLock", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.kv+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "path", + "description": "The key of the key-value to lock.", + "required": true, + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "The label, if any, of the key-value to lock.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "If-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag matches the value provided.", + "type": "string" + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag does not match the value provided.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValue" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "PutLock": { + "$ref": "./examples/PutLock.json" + }, + "PutLock_IfMatch": { + "$ref": "./examples/PutLock_IfMatch.json" + } + } + }, + "delete": { + "tags": ["Locks"], + "summary": "Unlocks a key-value.", + "operationId": "DeleteLock", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.kv+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "path", + "description": "The key of the key-value to unlock.", + "required": true, + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "The label, if any, of the key-value to unlock.", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "If-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag matches the value provided.", + "type": "string" + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Used to perform an operation only if the targeted resource's etag does not match the value provided.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValue" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + }, + "ETag": { + "description": "An identifier representing the returned state of the resource.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "DeleteLock": { + "$ref": "./examples/DeleteLock.json" + }, + "DeleteLock_IfMatch": { + "$ref": "./examples/DeleteLock_IfMatch.json" + } + } + } + }, + "/revisions": { + "get": { + "tags": ["Revisions"], + "summary": "Gets a list of key-value revisions.", + "operationId": "GetRevisions", + "consumes": [], + "produces": [ + "application/vnd.microsoft.appconfig.kvset+json", + "application/json", + "application/problem+json" + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "A filter used to match keys.", + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "A filter used to match labels", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ], + "x-ms-enum": { + "name": "SettingFields", + "modelAsString": false + } + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/KeyValueListResult" + }, + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-ms-examples": { + "GetRevisions": { + "$ref": "./examples/GetRevisions.json" + } + }, + "x-ms-pageable": { + "itemName": "items", + "nextLinkName": "@nextLink" + } + }, + "head": { + "tags": ["Revisions"], + "summary": "Requests the headers and status of the given resource.", + "operationId": "CheckRevisions", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "A filter used to match keys.", + "type": "string" + }, + { + "name": "label", + "in": "query", + "description": "A filter used to match labels", + "type": "string" + }, + { + "$ref": "#/parameters/SyncTokens" + }, + { + "$ref": "#/parameters/ApiVersion" + }, + { + "name": "After", + "in": "query", + "description": "Instructs the server to return elements that appear after the element referred to by the specified token.", + "type": "string" + }, + { + "name": "Accept-Datetime", + "in": "header", + "description": "Requests the server to respond with the state of the resource at the specified time.", + "type": "string" + }, + { + "name": "$Select", + "in": "query", + "description": "Used to select what fields are present in the returned resource(s).", + "type": "array", + "items": { + "type": "string", + "enum": [ + "key", + "label", + "content_type", + "value", + "last_modified", + "tags", + "locked", + "etag" + ], + "x-ms-enum": { + "name": "SettingFields", + "modelAsString": false + } + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "Success", + "headers": { + "Sync-Token": { + "description": "Enables real-time consistency between requests by providing the returned value in the next request made to the server.", + "type": "string" + } + } + }, + "default": { + "description": "Error response describing why the operation failed" + } + }, + "x-ms-examples": { + "CheckRevisions": { + "$ref": "./examples/CheckRevisions.json" + } + } + } + } + }, + "definitions": { + "Key": { + "type": "object", + "properties": { + "name": { + "description": "The name of the key.", + "type": "string", + "readOnly": true + } + } + }, + "KeyValue": { + "type": "object", + "required": ["key"], + "properties": { + "key": { + "description": "The unique name of the key-value.", + "type": "string" + }, + "label": { + "description": "The label of the key-value.", + "type": "string" + }, + "content_type": { + "description": "The content type of the key-value.", + "type": "string" + }, + "value": { + "description": "The value of the key-value.", + "type": "string" + }, + "last_modified": { + "description": "The time the key-value was last modified.", + "format": "date-time", + "type": "string" + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "locked": { + "description": "Indicates whether or not this key-value is readonly.", + "type": "boolean" + }, + "etag": { + "description": "The entity-tag of the key-value.", + "type": "string" + } + } + }, + "Label": { + "type": "object", + "properties": { + "name": { + "description": "The name of the label.", + "type": "string", + "readOnly": true + } + } + }, + "Error": { + "description": "Azure App Configuration error object.", + "properties": { + "type": { + "description": "The type of the error.", + "type": "string" + }, + "title": { + "description": "A brief summary of the error.", + "type": "string" + }, + "name": { + "description": "The name of the parameter that resulted in the error.", + "type": "string" + }, + "detail": { + "description": "A detailed description of the error.", + "type": "string" + }, + "status": { + "description": "The HTTP status code that the error maps to.", + "type": "integer" + } + }, + "readOnly": true + }, + "KeyListResult": { + "description": "The result of a list request.", + "type": "object", + "properties": { + "items": { + "description": "The collection value.", + "type": "array", + "items": { + "$ref": "#/definitions/Key" + } + }, + "@nextLink": { + "description": "The URI that can be used to request the next set of paged results.", + "type": "string" + } + } + }, + "KeyValueListResult": { + "description": "The result of a list request.", + "type": "object", + "properties": { + "items": { + "description": "The collection value.", + "type": "array", + "items": { + "$ref": "#/definitions/KeyValue" + } + }, + "@nextLink": { + "description": "The URI that can be used to request the next set of paged results.", + "type": "string" + } + } + }, + "LabelListResult": { + "description": "The result of a list request.", + "type": "object", + "properties": { + "items": { + "description": "The collection value.", + "type": "array", + "items": { + "$ref": "#/definitions/Label" + } + }, + "@nextLink": { + "description": "The URI that can be used to request the next set of paged results.", + "type": "string" + } + } + } + }, + "parameters": { + "SyncTokens": { + "name": "Sync-Token", + "in": "header", + "description": "Used to guarantee real-time consistency between requests.", + "type": "string" + }, + "ApiVersion": { + "name": "api-version", + "in": "query", + "description": "The API version to be used with the HTTP request.", + "required": true, + "type": "string" + }, + "Endpoint": { + "name": "endpoint", + "in": "path", + "description": "The endpoint of the App Configuration instance to send requests to.", + "required": true, + "type": "string", + "x-ms-skip-url-encoding": true, + "x-ms-parameter-location": "client" + } + }, + "x-ms-parameterized-host": { + "hostTemplate": "{endpoint}", + "useSchemePrefix": false, + "parameters": [ + { + "$ref": "#/parameters/Endpoint" + } + ] + } +} diff --git a/sdk/template/template/test/browser/sampleBrowser.spec.ts b/sdk/template/template/test/browser/sampleBrowser.spec.ts deleted file mode 100644 index bac0de0e6e50..000000000000 --- a/sdk/template/template/test/browser/sampleBrowser.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import * as lib from "../../src"; -import EventEmitter from "events"; - -describe("Hello function - browser", () => { - it("should create an event emitter", () => { - const result = lib.createEventEmitter(); - if (!(result instanceof EventEmitter)) { - throw new Error("Error occurred while creating an event emitter"); - } - }); -}); diff --git a/sdk/template/template/test/internal/basic.spec.ts b/sdk/template/template/test/internal/basic.spec.ts new file mode 100644 index 000000000000..66a878d6d84c --- /dev/null +++ b/sdk/template/template/test/internal/basic.spec.ts @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Chai is the Azure SDK Team's preferred assertion library, and it is included +// as part of our template project. +import { assert } from "chai"; + +// Import the internal function to be tested using the normal relative import +// syntax. +import { quoteETag } from "../../src/util"; + +// Unit tests SHOULD appear inside of a `describe` block. The hierarchical +// oranization of tests within `describe` blocks will be reflected in our +// pipeline analytics and metrics. +describe("basic internal unit tests", async function() { + // `it` declares a unit test. The test passes if it does not throw an `Error` + it("basic assertion", () => { + assert.equal(1, 1); + }); + + // Add the following test to the existing "describe" block + it("quoteETag", () => { + // undefined and "*" are handled specially + assert.equal(quoteETag(undefined), undefined); + assert.equal(quoteETag("*"), "*"); + + // already-quoted strings should not be re-quoted + assert.equal(quoteETag(`"xyz"`), `"xyz"`); + assert.equal(quoteETag(`'xyz'`), `'xyz'`); + + // unquoted strings should be quoted + assert.equal(quoteETag("abc"), `"abc"`); + + // strings with unmatched quotes should be quoted + assert.equal(quoteETag(`'abc"`), `"'abc""`); + assert.equal(quoteETag(`"abc'`), `""abc'"`); + assert.equal(quoteETag(`'abc`), `"'abc"`); + assert.equal(quoteETag(`"abc`), `""abc"`); + assert.equal(quoteETag(`abc"`), `"abc""`); + assert.equal(quoteETag(`abc'`), `"abc'"`); + }); +}); diff --git a/sdk/template/template/test/node/index.spec.ts b/sdk/template/template/test/node/index.spec.ts deleted file mode 100644 index 6302a5a43638..000000000000 --- a/sdk/template/template/test/node/index.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import * as lib from "../../src/index"; -import EventEmitter from "events"; - -// another node built-in that has to be shimmed for the browser -import assert from "assert"; - -describe("Hello function - node", () => { - it("should create an event emitter", () => { - const result = lib.createEventEmitter(); - assert(result instanceof EventEmitter); - }); - - it("should create a digest", () => { - assert(lib.URLBuilder instanceof Object); - }); -}); diff --git a/sdk/template/template/test/public/configurationClient.spec.ts b/sdk/template/template/test/public/configurationClient.spec.ts new file mode 100644 index 000000000000..e56752424e2a --- /dev/null +++ b/sdk/template/template/test/public/configurationClient.spec.ts @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { assert } from "chai"; +import { Context } from "mocha"; + +import { ConfigurationClient } from "../../src"; + +import { ClientSecretCredential } from "@azure/identity"; +import { env, record, Recorder } from "@azure/test-utils-recorder"; + +// When the recorder observes the values of these environment variables in any +// recorded HTTP request or response, it will replace them with the values they +// are mapped to below. +const replaceableVariables: Record = { + APPCONFIG_ENDPOINT: "https://myappconfig.azconfig.io", + APPCONFIG_TEST_SETTING_KEY: "test-key", + APPCONFIG_TEST_SETTING_EXPECTED_VALUE: "test-value", + AZURE_TENANT_ID: "azure_tenant_id", + AZURE_CLIENT_ID: "azure_client_id", + AZURE_CLIENT_SECRET: "azure_client_secret" +}; + +function createConfigurationClient(): ConfigurationClient { + // Retrieve the endpoint from the environment variable + // we saved to the .env file earlier + const endpoint = env.APPCONFIG_ENDPOINT; + + // We use ClientSecretCredential instead of DefaultAzureCredential in order + // to ensure that the requests made to the AAD server are always the same. If + // we used DefaultAzureCredential, they might be different on some machines + // than on others, depending on which credentials are available (such as + // Managed Identity or developer credentials). + const credential = new ClientSecretCredential( + env.AZURE_TENANT_ID, + env.AZURE_CLIENT_ID, + env.AZURE_CLIENT_SECRET + ); + + return new ConfigurationClient(endpoint, credential); +} + +// You want to give the test suite a descriptive name. Here, I add [AAD] to +// indicate that the tests are authenticating with the service using Azure +// Active Directory. +describe("[AAD] ConfigurationClient functional tests", function() { + // Declare the client and recorder instances. We will set them using the + // beforeEach hook. + let client: ConfigurationClient; + let recorder: Recorder; + + // NOTE: use of "function" and not ES6 arrow-style functions with the + // beforeEach hook is IMPORTANT due to the use of `this` in the function + // body. + beforeEach(function(this: Context) { + // The recorder has some convenience methods, and we need to store a + // reference to it so that we can `stop()` the recorder later in the + // `afterEach` hook. + // eslint-disable-next-line no-invalid-this + recorder = record(this, { + // == Recorder Environment Setup == Add the replaceable variables from + // above + replaceableVariables, + + // We don't use this in the template, but if we had any query parameters + // we wished to discard, we could add them here + queryParametersToSkip: [], + + // Finally, we need to remove the AAD `access_token` from any requests. + // This is very important, as it cannot be removed using environment + // variable or query parameter replacement. The + // `customizationsOnRecordings` field allows us to make arbitrary + // replacements within recordings. + customizationsOnRecordings: [ + (recording: any): any => + recording.replace(/"access_token":"[^"]*"/g, `"access_token":"access_token"`) + ] + }); + + // We'll be able to refer to the instantiated `client` in tests, since we + // initialize it before each test + client = createConfigurationClient(); + }); + + // After each test, we need to stop the recording. + afterEach(async function() { + await recorder.stop(); + }); + + it("predetermined setting has expected value", async () => { + const key = env.APPCONFIG_TEST_SETTING_KEY; + const expectedValue = env.APPCONFIG_TEST_SETTING_EXPECTED_VALUE; + + const setting = await client.getConfigurationSetting(key); + + // Make sure the key returned is the same as the key we asked for + assert.equal(key, setting.key); + + // Make sure the value of the setting is the same as the value we entered + // on the environment + assert.equal(expectedValue, setting.value); + }); +}); diff --git a/sdk/template/template/tests.yml b/sdk/template/template/tests.yml new file mode 100644 index 000000000000..8ee6aca1536a --- /dev/null +++ b/sdk/template/template/tests.yml @@ -0,0 +1,12 @@ +trigger: none + +extends: + template: ../../../eng/pipelines/templates/jobs/archetype-sdk-integration.yml + parameters: + PackageName: "@azure/template" + ResourceServiceDirectory: template + TestMinMax: true + EnvVars: + AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) + AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) + AZURE_CLIENT_SECRET: $(aad-azure-sdk-test-client-secret) diff --git a/sdk/template/test-resources.json b/sdk/template/test-resources.json new file mode 100644 index 000000000000..4393d5cfa6d7 --- /dev/null +++ b/sdk/template/test-resources.json @@ -0,0 +1,73 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "baseName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "The base resource name." + } + }, + "sku": { + "defaultValue": "Standard", + "type": "string" + }, + "uniqueString": { + "defaultValue": "[newGuid()]", + "type": "string" + } + }, + "variables": { + "configurationApiVersion": "2020-07-01-preview", + "accountName": "[parameters('baseName')]", + "endpoint": "[concat('https://', parameters('baseName'), '.azconfig.io')]", + "testKeyName": "test-key" + }, + "resources": [ + { + "type": "Microsoft.AppConfiguration/configurationStores", + "apiVersion": "[variables('configurationApiVersion')]", + "name": "[variables('accountName')]", + "location": "[resourceGroup().location]", + "sku": { + "name": "[parameters('sku')]" + }, + "properties": { + "endpoint": "[variables('endpoint')]" + } + }, + { + "type": "Microsoft.AppConfiguration/configurationStores/keyValues", + "apiVersion": "[variables('configurationApiVersion')]", + "name": "[concat(variables('accountName'), '/', variables('testKeyName'))]", + "copy": { + "name": "keyValueCopy", + "count": 1 + }, + "dependsOn": ["[variables('accountName')]"], + "properties": { + "value": "[parameters('uniqueString')]", + "contentType": "text/plain" + } + } + ], + "outputs": { + "APPCONFIG_CONNECTION_STRING": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.AppConfiguration/configurationStores', variables('accountName')), variables('configurationApiVersion')).value[0].connectionString]" + }, + "APPCONFIG_ENDPOINT": { + "type": "string", + "value": "[variables('endpoint')]" + }, + "APPCONFIG_TEST_SETTING_KEY": { + "type": "string", + "value": "[variables('testKeyName')]" + }, + "APPCONFIG_TEST_SETTING_EXPECTED_VALUE": { + "type": "string", + "value": "[parameters('uniqueString')]" + } + } +}