From cdffa0805822ea1b572ac5ee1d23d3f08b0eb9e4 Mon Sep 17 00:00:00 2001 From: SDKAuto Date: Tue, 1 Aug 2023 18:10:51 +0000 Subject: [PATCH] CodeGen from PR 22310 in Azure/azure-rest-api-specs Initial version of the code-signing dataplane service (#22310) * Initial version of the code-signing dataplane service * Remove error objects since those come from the Azure Core namespace * fix: added azure.codesigning.json resulting file * fix: use newer version dependency syntax * Rolling back version change per PR feedback * fix: polling operation mapping per PR feedback * Adding x-ms-examples for example validation * fix: added custom-words per PR feedback * Renamed parameter definition to match open api json definition * fix: modified the api-version to synch up with the folder api-version * Adding details json cadl validation * refactor: moved from cadl to typespec * chore: attach azure.codesiging.json definition * chore: remove package-lock.json since its unneeded. * feat: adding get sign eku operation & example fix: sign long running operation * chore: removed unused swagger.json generated * chore: removing data-plane swagger generated, keeping just the typespec project * Readding the swagger information for dataplane service * fix: ci issues pointed examples are not referenced on the swagger file resources should not be read only * added examples to typespec definition * fix: examples * more fixes for example.json operations * even more fixes for example.json operations * fix: minor Remove optional parameter from region. since its required. Added description to namespace definition Removed optional parameter from operation status, since the id is required. Added suppression of warning * Added fixes to azure.codesigning.json generation * Added required property of id to examples * Switched property to a more descriptive naming for the eku response * fix: moved examples to a non version specific folder * fix: the compiler didnt liked not using the preview folder, rolling back * feat: added oauth2 security definition * fix: removed api-version from example path * style: change casing of operations to camel case fix: per guidance modified the getsignEku operation into listSignEku * Update azure.codesigning.json generated by tsp compiler * fix: modified ResourceAction to LongRunningResourceAction per feedback * docs: added enum descriptions to each value on hash algorithms * fix: pinned to current versions to avoid ci errors by using latest dependency * Added prefix of StandardResourceOperations interface to Resource operations * fix: sign operation should return 202 Accepted on example * fix: sign operation should return 202 Accepted on example * style: tsp format result * refactor: removed unused mapping to parent resource * refactor: removing typespec-python emitter * Adding get sign root certificate operation * fix: adding custom word rootcert * fix: adding api version parameter * Added resource provider folder per ci finding * chore: removing package.json per PR feedback * Renaming folder to remove "Microsoft." path per feedback from PR see: https://github.com/Azure/azure-rest-api-specs/blob/main/documentation/typespec-structure-guidelines.md for guidelines * feat: expanded the typespec options to include the lang generation * Fix: Based on review from API stewardship team Added more detailed information for docs and summary of operations Refactored getSignRootCertificate operation to use RpcOperation instead of custom operation Pluralized the listSignEkus operation Renamed models to provide more detailed description of their purposed Eliminated the custom enum in favor of the typespec enum provided * refactor: moved version to 2023-06-15 based on feedback of ACS Eng team * refactor: renamed models following azure team feedback * Update tspconfig.yaml Applied latest schema of emitter options and parameters. * fix: adding back missing custom words, fixing coffeelake casing * docs: updated samples to include varied hashes to represent a more familiar request for customers * docs: updated the docs clauses of the typespec file to avoid repetitions on the docs generated. * fix: update README.md of data-plane generation to include the correct tag * Regenerated azure.codesigning.json file * Based on pr build feedback, updated custom words definition * docs: per compiler feedback, adding doc definition for versioning * fix: outdated examples of data-plane swagger * fix: per PR feedback, using T payload for Foundations.OperationStatus * chore: updated Azure.CodeSigning swagger generated using tsp v0.46.0 * fix: removed autorest from the dependencies per feedback fix: added suppression for custom RPC operation * Removing json examples for compliance with avocado pipeline * fix: Adding examples to tsp directory * Corrected samples --------- Co-authored-by: Ray Chen --- common/config/rush/pnpm-lock.yaml | 113 ++++--- rush.json | 9 +- .../azurecodesigning-rest/.eslintrc.json | 11 + .../azurecodesigning-rest/CHANGELOG.md | 3 + .../azurecodesigning-rest/README.md | 59 ++++ .../azurecodesigning-rest/api-extractor.json | 31 ++ .../azurecodesigning-rest/karma.conf.js | 133 +++++++++ .../azurecodesigning-rest/package.json | 119 ++++++++ .../review/azure-codesigning-rest.api.md | 281 ++++++++++++++++++ .../src/clientDefinitions.ts | 84 ++++++ .../src/codeSigningClient.ts | 49 +++ .../azurecodesigning-rest/src/index.ts | 16 + .../azurecodesigning-rest/src/isUnexpected.ts | 145 +++++++++ .../azurecodesigning-rest/src/logger.ts | 5 + .../azurecodesigning-rest/src/models.ts | 18 ++ .../azurecodesigning-rest/src/outputModels.ts | 67 +++++ .../src/paginateHelper.ts | 154 ++++++++++ .../azurecodesigning-rest/src/parameters.ts | 15 + .../src/pollingHelper.ts | 101 +++++++ .../azurecodesigning-rest/src/responses.ts | 97 ++++++ .../test/public/sampleTest.spec.ts | 23 ++ .../test/public/utils/env.browser.ts | 2 + .../test/public/utils/env.ts | 6 + .../test/public/utils/recordedClient.ts | 29 ++ .../azurecodesigning-rest/tsconfig.json | 11 + .../azurecodesigning-rest/tsp-location.yaml | 5 + sdk/codesigning/ci.yml | 33 ++ 27 files changed, 1582 insertions(+), 37 deletions(-) create mode 100644 sdk/codesigning/azurecodesigning-rest/.eslintrc.json create mode 100644 sdk/codesigning/azurecodesigning-rest/CHANGELOG.md create mode 100644 sdk/codesigning/azurecodesigning-rest/README.md create mode 100644 sdk/codesigning/azurecodesigning-rest/api-extractor.json create mode 100644 sdk/codesigning/azurecodesigning-rest/karma.conf.js create mode 100644 sdk/codesigning/azurecodesigning-rest/package.json create mode 100644 sdk/codesigning/azurecodesigning-rest/review/azure-codesigning-rest.api.md create mode 100644 sdk/codesigning/azurecodesigning-rest/src/clientDefinitions.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/codeSigningClient.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/index.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/isUnexpected.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/logger.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/models.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/outputModels.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/paginateHelper.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/parameters.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/pollingHelper.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/src/responses.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/test/public/sampleTest.spec.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/test/public/utils/env.browser.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/test/public/utils/env.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/test/public/utils/recordedClient.ts create mode 100644 sdk/codesigning/azurecodesigning-rest/tsconfig.json create mode 100644 sdk/codesigning/azurecodesigning-rest/tsp-location.yaml create mode 100644 sdk/codesigning/ci.yml diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 80db0d33996f..f1698b664620 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -229,6 +229,7 @@ specifiers: '@rush-temp/arm-workloads': file:./projects/arm-workloads.tgz '@rush-temp/arm-workspaces': file:./projects/arm-workspaces.tgz '@rush-temp/attestation': file:./projects/attestation.tgz + '@rush-temp/azure-codesigning-rest': file:./projects/azure-codesigning-rest.tgz '@rush-temp/communication-alpha-ids': file:./projects/communication-alpha-ids.tgz '@rush-temp/communication-call-automation': file:./projects/communication-call-automation.tgz '@rush-temp/communication-chat': file:./projects/communication-chat.tgz @@ -582,6 +583,7 @@ dependencies: '@rush-temp/arm-workloads': file:projects/arm-workloads.tgz '@rush-temp/arm-workspaces': file:projects/arm-workspaces.tgz '@rush-temp/attestation': file:projects/attestation.tgz + '@rush-temp/azure-codesigning-rest': file:projects/azure-codesigning-rest.tgz '@rush-temp/communication-alpha-ids': file:projects/communication-alpha-ids.tgz '@rush-temp/communication-call-automation': file:projects/communication-call-automation.tgz '@rush-temp/communication-chat': file:projects/communication-chat.tgz @@ -2844,7 +2846,7 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/chai-as-promised/7.1.5: @@ -2866,7 +2868,7 @@ packages: /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/cookie/0.4.1: @@ -2876,7 +2878,7 @@ packages: /@types/cors/2.8.13: resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/debug/4.1.8: @@ -2888,7 +2890,7 @@ packages: /@types/decompress/4.2.4: resolution: {integrity: sha512-/C8kTMRTNiNuWGl5nEyKbPiMv6HA+0RbEXzFhFBEzASM6+oa4tJro9b8nj7eRlOFfuLdzUU+DS/GPDlvvzMOhA==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/eslint/8.4.10: @@ -2909,7 +2911,7 @@ packages: /@types/express-serve-static-core/4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -2927,13 +2929,13 @@ packages: /@types/fs-extra/8.1.2: resolution: {integrity: sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/fs-extra/9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/http-errors/2.0.1: @@ -2950,7 +2952,7 @@ packages: /@types/is-buffer/2.0.0: resolution: {integrity: sha512-0f7N/e3BAz32qDYvgB4d2cqv1DqUwvGxHkXsrucICn8la1Vb6Yl6Eg8mPScGwUiqHJeE7diXlzaK+QMA9m4Gxw==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/json-schema/7.0.12: @@ -2964,13 +2966,13 @@ packages: /@types/jsonwebtoken/9.0.2: resolution: {integrity: sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/jws/3.2.5: resolution: {integrity: sha512-xGTxZH34xOryaTN8CMsvhh9lfNqFuHiMoRvsLYWQdBJHqiECyfInXVl2eK8Jz2emxZWMIn5RBlmr3oDVPeWujw==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/linkify-it/3.0.2: @@ -3029,20 +3031,20 @@ packages: /@types/mysql/2.15.19: resolution: {integrity: sha512-wSRg2QZv14CWcZXkgdvHbbV2ACufNy5EgI8mBBxnJIptchv7DBy/h53VMa2jDhyo0C9MO4iowE6z9vF8Ja1DkQ==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/node-fetch/2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 form-data: 3.0.1 dev: false /@types/node-fetch/2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 form-data: 3.0.1 dev: false @@ -3075,7 +3077,7 @@ packages: /@types/pg/8.6.1: resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 pg-protocol: 1.6.0 pg-types: 2.2.0 dev: false @@ -3103,7 +3105,7 @@ packages: /@types/resolve/1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/resolve/1.20.2: @@ -3126,7 +3128,7 @@ packages: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/serve-static/1.15.2: @@ -3134,7 +3136,7 @@ packages: dependencies: '@types/http-errors': 2.0.1 '@types/mime': 3.0.1 - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/shimmer/1.0.2: @@ -3154,13 +3156,13 @@ packages: /@types/stoppable/1.1.1: resolution: {integrity: sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/through/0.0.30: resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/tough-cookie/4.0.2: @@ -3174,7 +3176,7 @@ packages: /@types/tunnel/0.0.3: resolution: {integrity: sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/underscore/1.11.6: @@ -3192,19 +3194,19 @@ packages: /@types/ws/7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/ws/8.5.5: resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/xml2js/0.4.11: resolution: {integrity: sha512-JdigeAKmCyoJUiQljjr7tQG3if9NkqGUgwEUqBvV0N7LM4HyQk7UXCnusRa1lnvXAEYJ8mw8GtZWioagNztOwA==} dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false /@types/yargs-parser/21.0.0: @@ -3221,7 +3223,7 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 14.18.54 + '@types/node': 16.18.39 dev: false optional: true @@ -4498,7 +4500,7 @@ packages: resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) dependencies: - ms: 2.1.1 + ms: 2.1.3 dev: false /debug/3.2.7: @@ -4677,7 +4679,7 @@ packages: cosmiconfig: 7.1.0 debug: 4.3.4 deps-regex: 0.1.4 - ignore: 5.1.9 + ignore: 5.2.4 is-core-module: 2.12.1 js-yaml: 3.14.1 json5: 2.2.3 @@ -4818,7 +4820,7 @@ packages: dependencies: semver: 7.5.4 shelljs: 0.8.5 - typescript: 5.2.0-dev.20230731 + typescript: 5.2.0-dev.20230801 dev: false /duplexer3/0.1.5: @@ -4880,7 +4882,7 @@ packages: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.13 - '@types/node': 14.18.54 + '@types/node': 16.18.39 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -5050,7 +5052,7 @@ packages: dependencies: debug: 3.2.7 is-core-module: 2.12.1 - resolve: 1.22.3 + resolve: 1.22.2 dev: false /eslint-module-utils/2.8.0_eslint@8.46.0: @@ -5869,7 +5871,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.0.4 + minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 dev: false @@ -6194,7 +6196,7 @@ packages: /ignore-walk/3.0.4: resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} dependencies: - minimatch: 3.0.8 + minimatch: 3.1.2 dev: false /ignore/5.1.9: @@ -6287,7 +6289,7 @@ packages: cli-cursor: 3.1.0 cli-width: 3.0.0 external-editor: 3.1.0 - figures: 3.0.0 + figures: 3.2.0 lodash: 4.17.21 mute-stream: 0.0.8 run-async: 2.4.1 @@ -8762,7 +8764,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 14.18.54 + '@types/node': 16.18.39 long: 5.2.3 dev: false @@ -10335,8 +10337,8 @@ packages: hasBin: true dev: false - /typescript/5.2.0-dev.20230731: - resolution: {integrity: sha512-RJVLgnDgu67ZrohYy0aBea+5TICfRod36+24zw0bR/KJDQJO9mlIjTC0k+/PKw87fXP5JuUHqepEk15PvFya7A==} + /typescript/5.2.0-dev.20230801: + resolution: {integrity: sha512-f8FmzL+1+agawPPUzsd38vTiZD/z+RtGax/3+tzxsBP15O/4lMsliTEXRXF7ESC7a1s/f9HsNNRMne438PPZsw==} engines: {node: '>=14.17'} hasBin: true dev: false @@ -17565,6 +17567,47 @@ packages: - utf-8-validate dev: false + file:projects/azure-codesigning-rest.tgz: + resolution: {integrity: sha512-yNnPC3Ql+DfDdcIWAZpXtamkaG3JK+eYzKG+Osg+mzFG6W6sGFjyosCg3iABtfAbqFNugFRB0Zz3pIG6R6rHsg==, tarball: file:projects/azure-codesigning-rest.tgz} + name: '@rush-temp/azure-codesigning-rest' + version: 0.0.0 + dependencies: + '@azure/identity': 2.1.0 + '@microsoft/api-extractor': 7.36.3_@types+node@14.18.54 + '@types/chai': 4.3.5 + '@types/mocha': 7.0.2 + '@types/node': 14.18.54 + autorest: 3.6.3 + chai: 4.3.7 + cross-env: 7.0.3 + dotenv: 16.3.1 + eslint: 8.46.0 + karma: 6.4.2 + karma-chrome-launcher: 3.2.0 + karma-coverage: 2.2.1 + karma-env-preprocessor: 0.1.1 + karma-firefox-launcher: 1.3.0 + karma-junit-reporter: 2.0.1_karma@6.4.2 + karma-mocha: 2.0.1 + karma-mocha-reporter: 2.2.5_karma@6.4.2 + karma-source-map-support: 1.4.0 + karma-sourcemap-loader: 0.3.8 + mkdirp: 2.1.6 + mocha: 7.2.0 + mocha-junit-reporter: 1.23.3_mocha@7.2.0 + nyc: 15.1.0 + prettier: 2.8.8 + rimraf: 3.0.2 + source-map-support: 0.5.21 + tslib: 2.6.1 + typescript: 5.0.4 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + dev: false + file:projects/communication-alpha-ids.tgz: resolution: {integrity: sha512-Z5UKcnMA79I3zXDvLr02SA8y89FbXoR+Dtoqcqv0NBj3FJd4vvZMyrIc6tgdkAxBNKj0RqU85YIo0QUct8REsQ==, tarball: file:projects/communication-alpha-ids.tgz} name: '@rush-temp/communication-alpha-ids' diff --git a/rush.json b/rush.json index 8efa6dffdc9d..7d4e54f7493a 100644 --- a/rush.json +++ b/rush.json @@ -1,7 +1,7 @@ /** * This is the main configuration file for Rush. * For full documentation, please see https://rushjs.io - */ { + */{ "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json", /** * (Required) This specifies the version of the Rush engine to be used in this repo. @@ -2044,6 +2044,11 @@ "packageName": "@azure/arm-sphere", "projectFolder": "sdk/sphere/arm-sphere", "versionPolicyName": "management" + }, + { + "packageName": "@azure-rest/azure-codesigning-rest", + "projectFolder": "sdk/codesigning/azurecodesigning-rest", + "versionPolicyName": "client" } ] -} +} \ No newline at end of file diff --git a/sdk/codesigning/azurecodesigning-rest/.eslintrc.json b/sdk/codesigning/azurecodesigning-rest/.eslintrc.json new file mode 100644 index 000000000000..619797ac39b6 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "plugins": ["@azure/azure-sdk"], + "extends": ["plugin:@azure/azure-sdk/azure-sdk-base"], + "rules": { + "@azure/azure-sdk/ts-modules-only-named": "warn", + "@azure/azure-sdk/ts-apiextractor-json-types": "warn", + "@azure/azure-sdk/ts-package-json-types": "warn", + "@azure/azure-sdk/ts-package-json-engine-is-present": "warn", + "tsdoc/syntax": "warn" + } +} diff --git a/sdk/codesigning/azurecodesigning-rest/CHANGELOG.md b/sdk/codesigning/azurecodesigning-rest/CHANGELOG.md new file mode 100644 index 000000000000..95121a616909 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0-beta.1 (2023-08-01) + + - Initial Release diff --git a/sdk/codesigning/azurecodesigning-rest/README.md b/sdk/codesigning/azurecodesigning-rest/README.md new file mode 100644 index 000000000000..0025b62590f4 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/README.md @@ -0,0 +1,59 @@ +# Azure CodeSigning REST client library for JavaScript + +Azure CodeSigning is a service that provides managed code signing for all. + +**Please rely heavily on our [REST client docs](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/rest-clients.md) to use this library** + +Key links: + +- [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/codesigning/azurecodesigning-rest) +- [Package (NPM)](https://www.npmjs.com/package/@azure-rest/azure-codesigning-rest) +- [API reference documentation](https://docs.microsoft.com/javascript/api/@azure-rest/azure-codesigning-rest?view=azure-node-preview) +- [Samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/codesigning/azurecodesigning-rest/samples) + +## Getting started + +### Currently supported environments + +- LTS versions of Node.js + +### Prerequisites + +- You must have an [Azure subscription](https://azure.microsoft.com/free/) to use this package. + +### Install the `@azure-rest/azure-codesigning-rest` package + +Install the Azure CodeSigning REST client REST client library for JavaScript with `npm`: + +```bash +npm install @azure-rest/azure-codesigning-rest +``` + +### Create and authenticate a `CodeSigningClient` + +To use an [Azure Active Directory (AAD) token credential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token), +provide an instance of the desired credential type obtained from the +[@azure/identity](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) library. + +To authenticate with AAD, you must first `npm` install [`@azure/identity`](https://www.npmjs.com/package/@azure/identity) + +After setup, you can choose which type of [credential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) from `@azure/identity` to use. +As an example, [DefaultAzureCredential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#defaultazurecredential) +can be used to authenticate the client. + +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 + +## Troubleshooting + +### Logging + +Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`: + +```javascript +const { setLogLevel } = require("@azure/logger"); + +setLogLevel("info"); +``` + +For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger). diff --git a/sdk/codesigning/azurecodesigning-rest/api-extractor.json b/sdk/codesigning/azurecodesigning-rest/api-extractor.json new file mode 100644 index 000000000000..ff8dc21ce7eb --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/api-extractor.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "./types/src/index.d.ts", + "docModel": { + "enabled": true + }, + "apiReport": { + "enabled": true, + "reportFolder": "./review" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "", + "publicTrimmedFilePath": "./types/azure-codesigning-rest.d.ts" + }, + "messages": { + "tsdocMessageReporting": { + "default": { + "logLevel": "none" + } + }, + "extractorMessageReporting": { + "ae-missing-release-tag": { + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "none" + } + } + } +} \ No newline at end of file diff --git a/sdk/codesigning/azurecodesigning-rest/karma.conf.js b/sdk/codesigning/azurecodesigning-rest/karma.conf.js new file mode 100644 index 000000000000..a9d5f1b5fc59 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/karma.conf.js @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// https://github.com/karma-runner/karma-chrome-launcher +process.env.CHROME_BIN = require("puppeteer").executablePath(); +require("dotenv").config(); +const { relativeRecordingsPath } = require("@azure-tools/test-recorder"); +process.env.RECORDINGS_RELATIVE_PATH = relativeRecordingsPath(); + +module.exports = function (config) { + config.set({ + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: "./", + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ["source-map-support", "mocha"], + + plugins: [ + "karma-mocha", + "karma-mocha-reporter", + "karma-chrome-launcher", + "karma-firefox-launcher", + "karma-env-preprocessor", + "karma-coverage", + "karma-sourcemap-loader", + "karma-junit-reporter", + "karma-source-map-support", + ], + + // list of files / patterns to load in the browser + files: [ + "dist-test/index.browser.js", + { + pattern: "dist-test/index.browser.js.map", + type: "html", + included: false, + served: true, + }, + ], + + // list of files / patterns to exclude + exclude: [], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + "**/*.js": ["sourcemap", "env"], + // IMPORTANT: COMMENT following line if you want to debug in your browsers!! + // Preprocess source file to calculate code coverage, however this will make source file unreadable + // "dist-test/index.js": ["coverage"] + }, + + envPreprocessor: [ + "TEST_MODE", + "ENDPOINT", + "AZURE_CLIENT_SECRET", + "AZURE_CLIENT_ID", + "AZURE_TENANT_ID", + "SUBSCRIPTION_ID", + "RECORDINGS_RELATIVE_PATH", + ], + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["mocha", "coverage", "junit"], + + coverageReporter: { + // specify a common output directory + dir: "coverage-browser/", + reporters: [ + { type: "json", subdir: ".", file: "coverage.json" }, + { type: "lcovonly", subdir: ".", file: "lcov.info" }, + { type: "html", subdir: "html" }, + { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" }, + ], + }, + + junitReporter: { + outputDir: "", // results will be saved as $outputDir/$browserName.xml + outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile + suite: "", // suite will become the package name attribute in xml testsuite element + useBrowserName: false, // add browser name to report and classes names + nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element + classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element + properties: {}, // key value pair of properties to add to the section of the report + }, + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // --no-sandbox allows our tests to run in Linux without having to change the system. + // --disable-web-security allows us to authenticate from the browser without having to write tests using interactive auth, which would be far more complex. + browsers: ["ChromeHeadlessNoSandbox"], + customLaunchers: { + ChromeHeadlessNoSandbox: { + base: "ChromeHeadless", + flags: ["--no-sandbox", "--disable-web-security"], + }, + }, + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: 1, + + browserNoActivityTimeout: 60000000, + browserDisconnectTimeout: 10000, + browserDisconnectTolerance: 3, + + client: { + mocha: { + // change Karma's debug.html to the mocha web reporter + reporter: "html", + timeout: "600000", + }, + }, + }); +}; diff --git a/sdk/codesigning/azurecodesigning-rest/package.json b/sdk/codesigning/azurecodesigning-rest/package.json new file mode 100644 index 000000000000..8cd8ef80cf76 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/package.json @@ -0,0 +1,119 @@ +{ + "name": "@azure-rest/azure-codesigning-rest", + "sdk-type": "client", + "author": "Microsoft Corporation", + "version": "1.0.0-beta.1", + "description": "Azure Codesigning Service", + "keywords": [ + "node", + "azure", + "cloud", + "typescript", + "browser", + "isomorphic" + ], + "license": "MIT", + "main": "dist/index.js", + "module": "./dist-esm/src/index.js", + "types": "./types/azure-codesigning-rest.d.ts", + "repository": "github:Azure/azure-sdk-for-js", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "files": [ + "dist/", + "dist-esm/src/", + "types/azure-codesigning-rest.d.ts", + "README.md", + "LICENSE", + "review/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "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", + "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1", + "build:samples": "echo skipped.", + "build:test": "tsc -p . && dev-tool run bundle", + "build:debug": "tsc -p . && dev-tool run bundle && api-extractor run --local", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"*.{js,json}\" \"test/**/*.ts\"", + "clean": "rimraf dist dist-browser dist-esm test-dist temp types *.tgz *.log", + "execute:samples": "echo skipped", + "extract-api": "rimraf review && mkdirp ./review && api-extractor run --local", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"*.{js,json}\" \"test/**/*.ts\"", + "generate:client": "echo skipped", + "integration-test:browser": "dev-tool run test:browser", + "integration-test:node": "dev-tool run test:node-js-input -- --timeout 5000000 'dist-esm/test/**/*.spec.js'", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", + "lint": "eslint package.json api-extractor.json src test --ext .ts", + "pack": "npm pack 2>&1", + "test:browser": "npm run clean && npm run build:test && npm run unit-test:browser", + "test:node": "npm run clean && npm run build:test && npm run unit-test:node", + "test": "npm run clean && npm run build:test && npm run unit-test", + "unit-test": "npm run unit-test:node && npm run unit-test:browser", + "unit-test:node": "dev-tool run test:node-ts-input -- --timeout 1200000 --exclude 'test/**/browser/*.spec.ts' 'test/**/*.spec.ts'", + "unit-test:browser": "dev-tool run test:browser", + "build": "npm run clean && tsc -p . && dev-tool run bundle && mkdirp ./review && api-extractor run --local" + }, + "sideEffects": false, + "autoPublish": false, + "dependencies": { + "@azure/core-auth": "^1.3.0", + "@azure-rest/core-client": "^1.1.4", + "@azure/core-rest-pipeline": "^1.8.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0", + "@azure/core-paging": "^1.5.0", + "@azure/core-lro": "^2.5.4", + "@azure/abort-controller": "^1.0.0" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.31.1", + "autorest": "latest", + "@types/node": "^14.0.0", + "dotenv": "^16.0.0", + "eslint": "^8.0.0", + "mkdirp": "^2.1.2", + "prettier": "^2.5.1", + "rimraf": "^3.0.0", + "source-map-support": "^0.5.9", + "typescript": "~5.0.0", + "@azure/dev-tool": "^1.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure-tools/test-credential": "^1.0.0", + "@azure/identity": "^2.0.1", + "@azure-tools/test-recorder": "^3.0.0", + "mocha": "^7.1.1", + "@types/mocha": "^7.0.2", + "mocha-junit-reporter": "^1.18.0", + "cross-env": "^7.0.2", + "@types/chai": "^4.2.8", + "chai": "^4.2.0", + "karma-chrome-launcher": "^3.0.0", + "karma-coverage": "^2.0.0", + "karma-env-preprocessor": "^0.1.1", + "karma-firefox-launcher": "^1.1.0", + "karma-junit-reporter": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "karma-mocha": "^2.0.1", + "karma-source-map-support": "~1.4.0", + "karma-sourcemap-loader": "^0.3.8", + "karma": "^6.2.0", + "nyc": "^15.0.0" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/codesigning/azurecodesigning-rest/README.md", + "//metadata": { + "constantPaths": [ + { + "path": "src/codeSigningClient.ts", + "prefix": "userAgentInfo" + } + ] + }, + "browser": { + "./dist-esm/test/public/utils/env.js": "./dist-esm/test/public/utils/env.browser.js" + } +} \ No newline at end of file diff --git a/sdk/codesigning/azurecodesigning-rest/review/azure-codesigning-rest.api.md b/sdk/codesigning/azurecodesigning-rest/review/azure-codesigning-rest.api.md new file mode 100644 index 000000000000..f0068a8a5954 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/review/azure-codesigning-rest.api.md @@ -0,0 +1,281 @@ +## API Report File for "@azure-rest/azure-codesigning-rest" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Client } from '@azure-rest/core-client'; +import { ClientOptions } from '@azure-rest/core-client'; +import { CreateHttpPollerOptions } from '@azure/core-lro'; +import { ErrorModel } from '@azure-rest/core-client'; +import { ErrorResponse } from '@azure-rest/core-client'; +import { HttpResponse } from '@azure-rest/core-client'; +import { OperationState } from '@azure/core-lro'; +import { Paged } from '@azure/core-paging'; +import { PagedAsyncIterableIterator } from '@azure/core-paging'; +import { PathUncheckedResponse } from '@azure-rest/core-client'; +import { RawHttpHeaders } from '@azure/core-rest-pipeline'; +import { RequestParameters } from '@azure-rest/core-client'; +import { SimplePollerLike } from '@azure/core-lro'; +import { StreamableMethod } from '@azure-rest/core-client'; +import { TokenCredential } from '@azure/core-auth'; + +// @public (undocumented) +export type CodeSigningClient = Client & { + path: Routes; +}; + +// @public +export interface CodeSigningSubmissionOptions { + authenticodeHashList?: string[]; + digest: string; + fileHashList?: string[]; + signatureAlgorithm: string; +} + +// @public +export interface CodeSignOperationStatusOutput { + id: string; + signResult?: CodeSignResultOutput; +} + +// @public +export interface CodeSignResultOutput { + operationId: string; + signature?: string; + signingCertificate?: string; +} + +// @public +function createClient(region: string, credentials: TokenCredential, options?: ClientOptions): CodeSigningClient; +export default createClient; + +// @public +export type ExtendedKeyUsageListOutput = Paged; + +// @public +export interface ExtendedKeyUsageOutput { + ekus: string[]; +} + +// @public +export type GetArrayType = T extends Array ? TData : never; + +// @public (undocumented) +export interface GetCodeSigningStatus { + get(options?: GetCodeSigningStatusParameters): StreamableMethod; +} + +// @public +export interface GetCodeSigningStatus200Response extends HttpResponse { + // (undocumented) + body: OperationStatusOutput; + // (undocumented) + status: "200"; +} + +// @public (undocumented) +export interface GetCodeSigningStatusDefaultHeaders { + "x-ms-error-code"?: string; +} + +// @public (undocumented) +export interface GetCodeSigningStatusDefaultResponse extends HttpResponse { + // (undocumented) + body: ErrorResponse; + // (undocumented) + headers: RawHttpHeaders & GetCodeSigningStatusDefaultHeaders; + // (undocumented) + status: string; +} + +// @public +export interface GetCodeSigningStatusLogicalResponse extends HttpResponse { + // (undocumented) + body: OperationStatusOutput; + // (undocumented) + status: "200"; +} + +// @public (undocumented) +export type GetCodeSigningStatusParameters = RequestParameters; + +// @public +export function getLongRunningPoller(client: Client, initialResponse: Sign202Response | SignDefaultResponse, options?: CreateHttpPollerOptions>): Promise, TResult>>; + +// @public (undocumented) +export function getLongRunningPoller(client: Client, initialResponse: GetCodeSigningStatus200Response | GetCodeSigningStatusDefaultResponse, options?: CreateHttpPollerOptions>): Promise, TResult>>; + +// @public +export type GetPage = (pageLink: string, maxPageSize?: number) => Promise<{ + page: TPage; + nextPageLink?: string; +}>; + +// @public (undocumented) +export interface GetSignRootCertificate { + get(options?: GetSignRootCertificateParameters): StreamableMethod; +} + +// @public +export interface GetSignRootCertificate200Response extends HttpResponse { + body: Uint8Array; + // (undocumented) + status: "200"; +} + +// @public (undocumented) +export interface GetSignRootCertificateDefaultHeaders { + "x-ms-error-code"?: string; +} + +// @public (undocumented) +export interface GetSignRootCertificateDefaultResponse extends HttpResponse { + // (undocumented) + body: ErrorResponse; + // (undocumented) + headers: RawHttpHeaders & GetSignRootCertificateDefaultHeaders; + // (undocumented) + status: string; +} + +// @public (undocumented) +export type GetSignRootCertificateParameters = RequestParameters; + +// @public (undocumented) +export function isUnexpected(response: GetCodeSigningStatus200Response | GetCodeSigningStatusLogicalResponse | GetCodeSigningStatusDefaultResponse): response is GetCodeSigningStatusDefaultResponse; + +// @public (undocumented) +export function isUnexpected(response: GetSignRootCertificate200Response | GetSignRootCertificateDefaultResponse): response is GetSignRootCertificateDefaultResponse; + +// @public (undocumented) +export function isUnexpected(response: ListSignEkus200Response | ListSignEkusDefaultResponse): response is ListSignEkusDefaultResponse; + +// @public (undocumented) +export function isUnexpected(response: Sign202Response | SignLogicalResponse | SignDefaultResponse): response is SignDefaultResponse; + +// @public (undocumented) +export interface ListSignEkus { + get(options?: ListSignEkusParameters): StreamableMethod; +} + +// @public +export interface ListSignEkus200Response extends HttpResponse { + // (undocumented) + body: ExtendedKeyUsageListOutput; + // (undocumented) + status: "200"; +} + +// @public (undocumented) +export interface ListSignEkusDefaultHeaders { + "x-ms-error-code"?: string; +} + +// @public (undocumented) +export interface ListSignEkusDefaultResponse extends HttpResponse { + // (undocumented) + body: ErrorResponse; + // (undocumented) + headers: RawHttpHeaders & ListSignEkusDefaultHeaders; + // (undocumented) + status: string; +} + +// @public (undocumented) +export type ListSignEkusParameters = RequestParameters; + +// @public +export interface OperationStatusOutput { + error?: ErrorModel; + id: string; + result?: CodeSignResultOutput; + status: string; +} + +// @public +export function paginate(client: Client, initialResponse: TResponse, options?: PagingOptions): PagedAsyncIterableIterator>; + +// @public +export type PaginateReturn = TResult extends { + body: { + value?: infer TPage; + }; +} ? GetArrayType : Array; + +// @public +export interface PagingOptions { + customGetPage?: GetPage[]>; +} + +// @public +export interface ResourceOperationStatusOutput { + error?: ErrorModel; + id: string; + result?: CodeSignOperationStatusOutput; + status: string; +} + +// @public (undocumented) +export interface Routes { + (path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/{operationId}", operationId: string, codeSigningAccountName: string, certificateProfileName: string): GetCodeSigningStatus; + (path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/rootcert", codeSigningAccountName: string, certificateProfileName: string): GetSignRootCertificate; + (path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/eku", codeSigningAccountName: string, certificateProfileName: string): ListSignEkus; + (path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}:sign", codeSigningAccountName: string, certificateProfileName: string): Sign; +} + +// @public (undocumented) +export interface Sign { + post(options?: SignParameters): StreamableMethod; +} + +// @public (undocumented) +export interface Sign202Headers { + "operation-location": string; +} + +// @public +export interface Sign202Response extends HttpResponse { + // (undocumented) + body: ResourceOperationStatusOutput; + // (undocumented) + headers: RawHttpHeaders & Sign202Headers; + // (undocumented) + status: "202"; +} + +// @public (undocumented) +export interface SignBodyParam { + // (undocumented) + body?: CodeSigningSubmissionOptions; +} + +// @public (undocumented) +export interface SignDefaultHeaders { + "x-ms-error-code"?: string; +} + +// @public (undocumented) +export interface SignDefaultResponse extends HttpResponse { + // (undocumented) + body: ErrorResponse; + // (undocumented) + headers: RawHttpHeaders & SignDefaultHeaders; + // (undocumented) + status: string; +} + +// @public +export interface SignLogicalResponse extends HttpResponse { + // (undocumented) + body: ResourceOperationStatusOutput; + // (undocumented) + status: "200"; +} + +// @public (undocumented) +export type SignParameters = SignBodyParam & RequestParameters; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/sdk/codesigning/azurecodesigning-rest/src/clientDefinitions.ts b/sdk/codesigning/azurecodesigning-rest/src/clientDefinitions.ts new file mode 100644 index 000000000000..355e650dfa1e --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/clientDefinitions.ts @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + GetCodeSigningStatusParameters, + GetSignRootCertificateParameters, + ListSignEkusParameters, + SignParameters, +} from "./parameters"; +import { + GetCodeSigningStatus200Response, + GetCodeSigningStatusDefaultResponse, + GetSignRootCertificate200Response, + GetSignRootCertificateDefaultResponse, + ListSignEkus200Response, + ListSignEkusDefaultResponse, + Sign202Response, + SignDefaultResponse, +} from "./responses"; +import { Client, StreamableMethod } from "@azure-rest/core-client"; + +export interface GetCodeSigningStatus { + /** This status operation requires that a Sign request has been submitted and the operationId is known. */ + get( + options?: GetCodeSigningStatusParameters + ): StreamableMethod< + GetCodeSigningStatus200Response | GetCodeSigningStatusDefaultResponse + >; +} + +export interface GetSignRootCertificate { + /** The root certificate is generated as part of the initial account creation and it is used to sign the bits for the profile provided. */ + get( + options?: GetSignRootCertificateParameters + ): StreamableMethod< + GetSignRootCertificate200Response | GetSignRootCertificateDefaultResponse + >; +} + +export interface ListSignEkus { + /** The list of extended key usages are used to determine the purpose of the certificate usage as part of the codesigning operation. */ + get( + options?: ListSignEkusParameters + ): StreamableMethod; +} + +export interface Sign { + /** Submit a codesign operation under the created codesign account and profile name provided. */ + post( + options?: SignParameters + ): StreamableMethod; +} + +export interface Routes { + /** Resource for '/codesigningaccounts/\{codeSigningAccountName\}/certificateprofiles/\{certificateProfileName\}/sign/\{operationId\}' has methods for the following verbs: get */ + ( + path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/{operationId}", + operationId: string, + codeSigningAccountName: string, + certificateProfileName: string + ): GetCodeSigningStatus; + /** Resource for '/codesigningaccounts/\{codeSigningAccountName\}/certificateprofiles/\{certificateProfileName\}/sign/rootcert' has methods for the following verbs: get */ + ( + path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/rootcert", + codeSigningAccountName: string, + certificateProfileName: string + ): GetSignRootCertificate; + /** Resource for '/codesigningaccounts/\{codeSigningAccountName\}/certificateprofiles/\{certificateProfileName\}/sign/eku' has methods for the following verbs: get */ + ( + path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/eku", + codeSigningAccountName: string, + certificateProfileName: string + ): ListSignEkus; + /** Resource for '/codesigningaccounts/\{codeSigningAccountName\}/certificateprofiles/\{certificateProfileName\}:sign' has methods for the following verbs: post */ + ( + path: "/codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}:sign", + codeSigningAccountName: string, + certificateProfileName: string + ): Sign; +} + +export type CodeSigningClient = Client & { + path: Routes; +}; diff --git a/sdk/codesigning/azurecodesigning-rest/src/codeSigningClient.ts b/sdk/codesigning/azurecodesigning-rest/src/codeSigningClient.ts new file mode 100644 index 000000000000..03a0e0780284 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/codeSigningClient.ts @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { getClient, ClientOptions } from "@azure-rest/core-client"; +import { logger } from "./logger"; +import { TokenCredential } from "@azure/core-auth"; +import { CodeSigningClient } from "./clientDefinitions"; + +/** + * Initialize a new instance of `CodeSigningClient` + * @param region - The Azure region wherein requests for signing will be sent. + * @param credentials - uniquely identify client credential + * @param options - the parameter for all optional parameters + */ +export default function createClient( + region: string, + credentials: TokenCredential, + options: ClientOptions = {} +): CodeSigningClient { + const baseUrl = options.baseUrl ?? `https://${region}.codesigning.azure.net/`; + options.apiVersion = options.apiVersion ?? "2023-06-15-preview"; + options = { + ...options, + credentials: { + scopes: options.credentials?.scopes ?? [ + "https://codesigning.azure.net/.default", + ], + }, + }; + + const userAgentInfo = `azsdk-js-azure-codesigning-rest/1.0.0-beta.1`; + const userAgentPrefix = + options.userAgentOptions && options.userAgentOptions.userAgentPrefix + ? `${options.userAgentOptions.userAgentPrefix} ${userAgentInfo}` + : `${userAgentInfo}`; + options = { + ...options, + userAgentOptions: { + userAgentPrefix, + }, + loggingOptions: { + logger: options.loggingOptions?.logger ?? logger.info, + }, + }; + + const client = getClient(baseUrl, credentials, options) as CodeSigningClient; + + return client; +} diff --git a/sdk/codesigning/azurecodesigning-rest/src/index.ts b/sdk/codesigning/azurecodesigning-rest/src/index.ts new file mode 100644 index 000000000000..2b8048ad81ed --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/index.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import CodeSigningClient from "./codeSigningClient"; + +export * from "./codeSigningClient"; +export * from "./parameters"; +export * from "./responses"; +export * from "./clientDefinitions"; +export * from "./isUnexpected"; +export * from "./models"; +export * from "./outputModels"; +export * from "./paginateHelper"; +export * from "./pollingHelper"; + +export default CodeSigningClient; diff --git a/sdk/codesigning/azurecodesigning-rest/src/isUnexpected.ts b/sdk/codesigning/azurecodesigning-rest/src/isUnexpected.ts new file mode 100644 index 000000000000..69e95239b29e --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/isUnexpected.ts @@ -0,0 +1,145 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + GetCodeSigningStatus200Response, + GetCodeSigningStatusLogicalResponse, + GetCodeSigningStatusDefaultResponse, + GetSignRootCertificate200Response, + GetSignRootCertificateDefaultResponse, + ListSignEkus200Response, + ListSignEkusDefaultResponse, + Sign202Response, + SignLogicalResponse, + SignDefaultResponse, +} from "./responses"; + +const responseMap: Record = { + "GET /codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/{operationId}": + ["200"], + "GET /codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/rootcert": + ["200"], + "GET /codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}/sign/eku": + ["200"], + "POST /codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}:sign": + ["202"], + "GET /codesigningaccounts/{codeSigningAccountName}/certificateprofiles/{certificateProfileName}:sign": + ["200", "202"], +}; + +export function isUnexpected( + response: + | GetCodeSigningStatus200Response + | GetCodeSigningStatusLogicalResponse + | GetCodeSigningStatusDefaultResponse +): response is GetCodeSigningStatusDefaultResponse; +export function isUnexpected( + response: + | GetSignRootCertificate200Response + | GetSignRootCertificateDefaultResponse +): response is GetSignRootCertificateDefaultResponse; +export function isUnexpected( + response: ListSignEkus200Response | ListSignEkusDefaultResponse +): response is ListSignEkusDefaultResponse; +export function isUnexpected( + response: Sign202Response | SignLogicalResponse | SignDefaultResponse +): response is SignDefaultResponse; +export function isUnexpected( + response: + | GetCodeSigningStatus200Response + | GetCodeSigningStatusLogicalResponse + | GetCodeSigningStatusDefaultResponse + | GetSignRootCertificate200Response + | GetSignRootCertificateDefaultResponse + | ListSignEkus200Response + | ListSignEkusDefaultResponse + | Sign202Response + | SignLogicalResponse + | SignDefaultResponse +): response is + | GetCodeSigningStatusDefaultResponse + | GetSignRootCertificateDefaultResponse + | ListSignEkusDefaultResponse + | SignDefaultResponse { + const lroOriginal = response.headers["x-ms-original-url"]; + const url = new URL(lroOriginal ?? response.request.url); + const method = response.request.method; + let pathDetails = responseMap[`${method} ${url.pathname}`]; + if (!pathDetails) { + pathDetails = getParametrizedPathSuccess(method, url.pathname); + } + return !pathDetails.includes(response.status); +} + +function getParametrizedPathSuccess(method: string, path: string): string[] { + const pathParts = path.split("/"); + + // Traverse list to match the longest candidate + // matchedLen: the length of candidate path + // matchedValue: the matched status code array + let matchedLen = -1, + matchedValue: string[] = []; + + // Iterate the responseMap to find a match + for (const [key, value] of Object.entries(responseMap)) { + // Extracting the path from the map key which is in format + // GET /path/foo + if (!key.startsWith(method)) { + continue; + } + const candidatePath = getPathFromMapKey(key); + // Get each part of the url path + const candidateParts = candidatePath.split("/"); + + // track if we have found a match to return the values found. + let found = true; + for ( + let i = candidateParts.length - 1, j = pathParts.length - 1; + i >= 1 && j >= 1; + i--, j-- + ) { + if ( + candidateParts[i]?.startsWith("{") && + candidateParts[i]?.indexOf("}") !== -1 + ) { + const start = candidateParts[i]!.indexOf("}") + 1, + end = candidateParts[i]?.length; + // If the current part of the candidate is a "template" part + // Try to use the suffix of pattern to match the path + // {guid} ==> $ + // {guid}:export ==> :export$ + const isMatched = new RegExp( + `${candidateParts[i]?.slice(start, end)}` + ).test(pathParts[j] || ""); + + if (!isMatched) { + found = false; + break; + } + continue; + } + + // If the candidate part is not a template and + // the parts don't match mark the candidate as not found + // to move on with the next candidate path. + if (candidateParts[i] !== pathParts[j]) { + found = false; + break; + } + } + + // We finished evaluating the current candidate parts + // Update the matched value if and only if we found the longer pattern + if (found && candidatePath.length > matchedLen) { + matchedLen = candidatePath.length; + matchedValue = value; + } + } + + return matchedValue; +} + +function getPathFromMapKey(mapKey: string): string { + const pathStart = mapKey.indexOf("/"); + return mapKey.slice(pathStart); +} diff --git a/sdk/codesigning/azurecodesigning-rest/src/logger.ts b/sdk/codesigning/azurecodesigning-rest/src/logger.ts new file mode 100644 index 000000000000..f90ae0e72a91 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/logger.ts @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { createClientLogger } from "@azure/logger"; +export const logger = createClientLogger("azure-codesigning-rest"); diff --git a/sdk/codesigning/azurecodesigning-rest/src/models.ts b/sdk/codesigning/azurecodesigning-rest/src/models.ts new file mode 100644 index 000000000000..2e81f6c03d31 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/models.ts @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/** The codesign request information to be signed by the service. */ +export interface CodeSigningSubmissionOptions { + /** + * The supported signature algorithm identifiers. + * + * Possible values: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, ES256K + */ + signatureAlgorithm: string; + /** Content digest to codesign. */ + digest: string; + /** List of full file digital signatures. */ + fileHashList?: string[]; + /** List of authenticode digital signatures. */ + authenticodeHashList?: string[]; +} diff --git a/sdk/codesigning/azurecodesigning-rest/src/outputModels.ts b/sdk/codesigning/azurecodesigning-rest/src/outputModels.ts new file mode 100644 index 000000000000..b8e8c38d4fae --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/outputModels.ts @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Paged } from "@azure/core-paging"; +import { ErrorModel } from "@azure-rest/core-client"; + +/** The sign status model. */ +export interface CodeSignResultOutput { + /** Response Id of the codesign operation. */ + operationId: string; + /** Digital signature of the requested content digest. */ + signature?: string; + /** + * Signing certificate corresponding to the private key used to codesign the requested + * digest. + */ + signingCertificate?: string; +} + +/** Provides status details for long running operations. */ +export interface OperationStatusOutput { + /** The unique ID of the operation. */ + id: string; + /** + * The status of the operation + * + * Possible values: InProgress, Succeeded, Failed, Canceled + */ + status: string; + /** Error object that describes the error when status is "Failed". */ + error?: ErrorModel; + /** The result of the operation. */ + result?: CodeSignResultOutput; +} + +/** Extended key usage object identifier that are allowed. */ +export interface ExtendedKeyUsageOutput { + /** An element of ekus. */ + ekus: string[]; +} + +/** Provides status details for long running operations. */ +export interface ResourceOperationStatusOutput { + /** The unique ID of the operation. */ + id: string; + /** + * The status of the operation + * + * Possible values: InProgress, Succeeded, Failed, Canceled + */ + status: string; + /** Error object that describes the error when status is "Failed". */ + error?: ErrorModel; + /** The result of the operation. */ + result?: CodeSignOperationStatusOutput; +} + +/** The codesign operation status response. */ +export interface CodeSignOperationStatusOutput { + /** Unique Id of the operation. */ + id: string; + /** The result of the codesign operation including the signature and signing certificate. */ + signResult?: CodeSignResultOutput; +} + +/** Paged collection of ExtendedKeyUsage items */ +export type ExtendedKeyUsageListOutput = Paged; diff --git a/sdk/codesigning/azurecodesigning-rest/src/paginateHelper.ts b/sdk/codesigning/azurecodesigning-rest/src/paginateHelper.ts new file mode 100644 index 000000000000..1c9af35b1efd --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/paginateHelper.ts @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + getPagedAsyncIterator, + PagedAsyncIterableIterator, + PagedResult, +} from "@azure/core-paging"; +import { + Client, + createRestError, + PathUncheckedResponse, +} from "@azure-rest/core-client"; + +/** + * Helper type to extract the type of an array + */ +export type GetArrayType = T extends Array ? TData : never; + +/** + * The type of a custom function that defines how to get a page and a link to the next one if any. + */ +export type GetPage = ( + pageLink: string, + maxPageSize?: number +) => Promise<{ + page: TPage; + nextPageLink?: string; +}>; + +/** + * Options for the paging helper + */ +export interface PagingOptions { + /** + * Custom function to extract pagination details for crating the PagedAsyncIterableIterator + */ + customGetPage?: GetPage[]>; +} + +/** + * Helper type to infer the Type of the paged elements from the response type + * This type is generated based on the swagger information for x-ms-pageable + * specifically on the itemName property which indicates the property of the response + * where the page items are found. The default value is `value`. + * This type will allow us to provide strongly typed Iterator based on the response we get as second parameter + */ +export type PaginateReturn = TResult extends { + body: { value?: infer TPage }; +} + ? GetArrayType + : Array; + +/** + * Helper to paginate results from an initial response that follows the specification of Autorest `x-ms-pageable` extension + * @param client - Client to use for sending the next page requests + * @param initialResponse - Initial response containing the nextLink and current page of elements + * @param customGetPage - Optional - Function to define how to extract the page and next link to be used to paginate the results + * @returns - PagedAsyncIterableIterator to iterate the elements + */ +export function paginate( + client: Client, + initialResponse: TResponse, + options: PagingOptions = {} +): PagedAsyncIterableIterator> { + // Extract element type from initial response + type TElement = PaginateReturn; + let firstRun = true; + const itemName = "value"; + const nextLinkName = "nextLink"; + const { customGetPage } = options; + const pagedResult: PagedResult = { + firstPageLink: "", + getPage: + typeof customGetPage === "function" + ? customGetPage + : async (pageLink: string) => { + const result = firstRun + ? initialResponse + : await client.pathUnchecked(pageLink).get(); + firstRun = false; + checkPagingRequest(result); + const nextLink = getNextLink(result.body, nextLinkName); + const values = getElements(result.body, itemName); + return { + page: values, + nextPageLink: nextLink, + }; + }, + }; + + return getPagedAsyncIterator(pagedResult); +} + +/** + * Gets for the value of nextLink in the body + */ +function getNextLink(body: unknown, nextLinkName?: string): string | undefined { + if (!nextLinkName) { + return undefined; + } + + const nextLink = (body as Record)[nextLinkName]; + + if (typeof nextLink !== "string" && typeof nextLink !== "undefined") { + throw new Error( + `Body Property ${nextLinkName} should be a string or undefined` + ); + } + + return nextLink; +} + +/** + * Gets the elements of the current request in the body. + */ +function getElements(body: unknown, itemName: string): T[] { + const value = (body as Record)[itemName] as T[]; + + // value has to be an array according to the x-ms-pageable extension. + // The fact that this must be an array is used above to calculate the + // type of elements in the page in PaginateReturn + if (!Array.isArray(value)) { + throw new Error( + `Couldn't paginate response\n Body doesn't contain an array property with name: ${itemName}` + ); + } + + return value ?? []; +} + +/** + * Checks if a request failed + */ +function checkPagingRequest(response: PathUncheckedResponse): void { + const Http2xxStatusCodes = [ + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "226", + ]; + if (!Http2xxStatusCodes.includes(response.status)) { + throw createRestError( + `Pagination failed with unexpected statusCode ${response.status}`, + response + ); + } +} diff --git a/sdk/codesigning/azurecodesigning-rest/src/parameters.ts b/sdk/codesigning/azurecodesigning-rest/src/parameters.ts new file mode 100644 index 000000000000..a0c45e683f24 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/parameters.ts @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { RequestParameters } from "@azure-rest/core-client"; +import { CodeSigningSubmissionOptions } from "./models"; + +export type GetCodeSigningStatusParameters = RequestParameters; +export type GetSignRootCertificateParameters = RequestParameters; +export type ListSignEkusParameters = RequestParameters; + +export interface SignBodyParam { + body?: CodeSigningSubmissionOptions; +} + +export type SignParameters = SignBodyParam & RequestParameters; diff --git a/sdk/codesigning/azurecodesigning-rest/src/pollingHelper.ts b/sdk/codesigning/azurecodesigning-rest/src/pollingHelper.ts new file mode 100644 index 000000000000..dbfe4ea5b5c0 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/pollingHelper.ts @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Client, HttpResponse } from "@azure-rest/core-client"; +import { + CreateHttpPollerOptions, + LongRunningOperation, + LroResponse, + OperationState, + SimplePollerLike, + createHttpPoller, +} from "@azure/core-lro"; +import { + GetCodeSigningStatus200Response, + GetCodeSigningStatusDefaultResponse, + GetCodeSigningStatusLogicalResponse, + Sign202Response, + SignDefaultResponse, + SignLogicalResponse, +} from "./responses"; +/** + * Helper function that builds a Poller object to help polling a long running operation. + * @param client - Client to use for sending the request to get additional pages. + * @param initialResponse - The initial response. + * @param options - Options to set a resume state or custom polling interval. + * @returns - A poller object to poll for operation state updates and eventually get the final response. + */ +export async function getLongRunningPoller< + TResult extends SignLogicalResponse | SignDefaultResponse +>( + client: Client, + initialResponse: Sign202Response | SignDefaultResponse, + options?: CreateHttpPollerOptions> +): Promise, TResult>>; +export async function getLongRunningPoller< + TResult extends + | GetCodeSigningStatusLogicalResponse + | GetCodeSigningStatusDefaultResponse +>( + client: Client, + initialResponse: + | GetCodeSigningStatus200Response + | GetCodeSigningStatusDefaultResponse, + options?: CreateHttpPollerOptions> +): Promise, TResult>>; +export async function getLongRunningPoller( + client: Client, + initialResponse: TResult, + options: CreateHttpPollerOptions> = {} +): Promise, TResult>> { + const poller: LongRunningOperation = { + requestMethod: initialResponse.request.method, + requestPath: initialResponse.request.url, + sendInitialRequest: async () => { + // In the case of Rest Clients we are building the LRO poller object from a response that's the reason + // we are not triggering the initial request here, just extracting the information from the + // response we were provided. + return getLroResponse(initialResponse); + }, + sendPollRequest: async (path) => { + // This is the callback that is going to be called to poll the service + // to get the latest status. We use the client provided and the polling path + // which is an opaque URL provided by caller, the service sends this in one of the following headers: operation-location, azure-asyncoperation or location + // depending on the lro pattern that the service implements. If non is provided we default to the initial path. + const response = await client + .pathUnchecked(path ?? initialResponse.request.url) + .get(); + const lroResponse = getLroResponse(response as TResult); + lroResponse.rawResponse.headers["x-ms-original-url"] = + initialResponse.request.url; + return lroResponse; + }, + }; + + options.resolveOnUnsuccessful = options.resolveOnUnsuccessful ?? true; + return await createHttpPoller(poller, options); +} + +/** + * Converts a Rest Client response to a response that the LRO implementation understands + * @param response - a rest client http response + * @returns - An LRO response that the LRO implementation understands + */ +function getLroResponse( + response: TResult +): LroResponse { + if (Number.isNaN(response.status)) { + throw new TypeError( + `Status code of the response is not a number. Value: ${response.status}` + ); + } + + return { + flatResponse: response, + rawResponse: { + ...response, + statusCode: Number.parseInt(response.status), + body: response.body, + }, + }; +} diff --git a/sdk/codesigning/azurecodesigning-rest/src/responses.ts b/sdk/codesigning/azurecodesigning-rest/src/responses.ts new file mode 100644 index 000000000000..5b886b911df5 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/src/responses.ts @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { RawHttpHeaders } from "@azure/core-rest-pipeline"; +import { HttpResponse, ErrorResponse } from "@azure-rest/core-client"; +import { + OperationStatusOutput, + ExtendedKeyUsageListOutput, + ResourceOperationStatusOutput, +} from "./outputModels"; + +/** The request has succeeded. */ +export interface GetCodeSigningStatus200Response extends HttpResponse { + status: "200"; + body: OperationStatusOutput; +} + +export interface GetCodeSigningStatusDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetCodeSigningStatusDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetCodeSigningStatusDefaultHeaders; +} + +/** The final response for long-running getCodeSigningStatus operation */ +export interface GetCodeSigningStatusLogicalResponse extends HttpResponse { + status: "200"; + body: OperationStatusOutput; +} + +/** The request has succeeded. */ +export interface GetSignRootCertificate200Response extends HttpResponse { + status: "200"; + /** Value may contain any sequence of octets */ + body: Uint8Array; +} + +export interface GetSignRootCertificateDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface GetSignRootCertificateDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & GetSignRootCertificateDefaultHeaders; +} + +/** The request has succeeded. */ +export interface ListSignEkus200Response extends HttpResponse { + status: "200"; + body: ExtendedKeyUsageListOutput; +} + +export interface ListSignEkusDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface ListSignEkusDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & ListSignEkusDefaultHeaders; +} + +export interface Sign202Headers { + /** The location for monitoring the operation state. */ + "operation-location": string; +} + +/** The request has been accepted for processing, but processing has not yet completed. */ +export interface Sign202Response extends HttpResponse { + status: "202"; + body: ResourceOperationStatusOutput; + headers: RawHttpHeaders & Sign202Headers; +} + +export interface SignDefaultHeaders { + /** String error code indicating what went wrong. */ + "x-ms-error-code"?: string; +} + +export interface SignDefaultResponse extends HttpResponse { + status: string; + body: ErrorResponse; + headers: RawHttpHeaders & SignDefaultHeaders; +} + +/** The final response for long-running sign operation */ +export interface SignLogicalResponse extends HttpResponse { + status: "200"; + body: ResourceOperationStatusOutput; +} diff --git a/sdk/codesigning/azurecodesigning-rest/test/public/sampleTest.spec.ts b/sdk/codesigning/azurecodesigning-rest/test/public/sampleTest.spec.ts new file mode 100644 index 000000000000..bce68e428645 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/test/public/sampleTest.spec.ts @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Recorder } from "@azure-tools/test-recorder"; +import { assert } from "chai"; +import { createRecorder } from "./utils/recordedClient"; +import { Context } from "mocha"; + +describe("My test", () => { + let recorder: Recorder; + + beforeEach(async function (this: Context) { + recorder = await createRecorder(this); + }); + + afterEach(async function () { + await recorder.stop(); + }); + + it("sample test", async function () { + assert.equal(1, 1); + }); +}); diff --git a/sdk/codesigning/azurecodesigning-rest/test/public/utils/env.browser.ts b/sdk/codesigning/azurecodesigning-rest/test/public/utils/env.browser.ts new file mode 100644 index 000000000000..fd2aca680c7b --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/test/public/utils/env.browser.ts @@ -0,0 +1,2 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. diff --git a/sdk/codesigning/azurecodesigning-rest/test/public/utils/env.ts b/sdk/codesigning/azurecodesigning-rest/test/public/utils/env.ts new file mode 100644 index 000000000000..0e06855b73ae --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/test/public/utils/env.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as dotenv from "dotenv"; + +dotenv.config(); diff --git a/sdk/codesigning/azurecodesigning-rest/test/public/utils/recordedClient.ts b/sdk/codesigning/azurecodesigning-rest/test/public/utils/recordedClient.ts new file mode 100644 index 000000000000..6cc58bc15e11 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/test/public/utils/recordedClient.ts @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Context } from "mocha"; +import { Recorder, RecorderStartOptions } from "@azure-tools/test-recorder"; +import "./env"; + +const envSetupForPlayback: Record = { + ENDPOINT: "https://endpoint", + AZURE_CLIENT_ID: "azure_client_id", + AZURE_CLIENT_SECRET: "azure_client_secret", + AZURE_TENANT_ID: "88888888-8888-8888-8888-888888888888", + SUBSCRIPTION_ID: "azure_subscription_id", +}; + +const recorderEnvSetup: RecorderStartOptions = { + envSetupForPlayback, +}; + +/** + * creates the recorder and reads the environment variables from the `.env` file. + * Should be called first in the test suite to make sure environment variables are + * read before they are being used. + */ +export async function createRecorder(context: Context): Promise { + const recorder = new Recorder(context.currentTest); + await recorder.start(recorderEnvSetup); + return recorder; +} diff --git a/sdk/codesigning/azurecodesigning-rest/tsconfig.json b/sdk/codesigning/azurecodesigning-rest/tsconfig.json new file mode 100644 index 000000000000..d5bf593423c9 --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.package", + "compilerOptions": { + "outDir": "./dist-esm", + "declarationDir": "./types" + }, + "include": [ + "src/**/*.ts", + "./test/**/*.ts" + ] +} \ No newline at end of file diff --git a/sdk/codesigning/azurecodesigning-rest/tsp-location.yaml b/sdk/codesigning/azurecodesigning-rest/tsp-location.yaml new file mode 100644 index 000000000000..f70c0bccc3ff --- /dev/null +++ b/sdk/codesigning/azurecodesigning-rest/tsp-location.yaml @@ -0,0 +1,5 @@ +directory: specification/codesigning/CodeSigning +repo: Azure/azure-rest-api-specs +additionalDirectories: [] +commit: 80c5b33a4334eed1df2547e775e187b9e58d2a19 + diff --git a/sdk/codesigning/ci.yml b/sdk/codesigning/ci.yml new file mode 100644 index 000000000000..11504489c66d --- /dev/null +++ b/sdk/codesigning/ci.yml @@ -0,0 +1,33 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. + +trigger: + branches: + include: + - main + - feature/* + - release/* + - hotfix/* + exclude: + - feature/v4 + paths: + include: + - sdk/codesigning/ +pr: + branches: + include: + - main + - feature/* + - release/* + - hotfix/* + exclude: + - feature/v4 + paths: + include: + - sdk/codesigning/ +extends: + template: /eng/pipelines/templates/stages/archetype-sdk-client.yml + parameters: + ServiceDirectory: codesigning + Artifacts: + - name: azure-rest-azure-codesigning-rest + safeName: azurerestazurecodesigningrest