├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ └── main.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── action.yml ├── dist └── index.js ├── images └── extension-icon.png ├── lib ├── azure_devops_task.js ├── azure_devops_task.js.map ├── github_action.js ├── github_action.js.map ├── store_apis.js └── store_apis.js.map ├── package-lock.json ├── package.json ├── src ├── azure_devops_task.ts ├── github_action.ts └── store_apis.ts ├── submission-task ├── icon.png ├── index.js └── task.json ├── tsconfig.json └── vss-extension.json /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | lib -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: "@typescript-eslint/parser", 4 | plugins: ["@typescript-eslint"], 5 | extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 6 | }; 7 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - '**/README.md' 9 | pull_request: 10 | branches: 11 | - main 12 | paths-ignore: 13 | - '**/README.md' 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v3 20 | - uses: actions/setup-node@v3 21 | with: 22 | node-version: 16.x 23 | - name: Install dependencies 24 | run: npm ci 25 | - name: Install TFX 26 | run: npm install -g tfx-cli 27 | - name: Build 28 | run: npm run build 29 | - name: Package ADO Task 30 | run: npm run package 31 | - name: Publish ADO Task 32 | uses: actions/upload-artifact@v3 33 | with: 34 | name: ado-task 35 | path: Microsoft.microsoft-store-win32-release-task-*.vsix -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | 93 | # Gatsby files 94 | .cache/ 95 | # Comment in the public line in if your project uses Gatsby and not Next.js 96 | # https://nextjs.org/blog/next-9-1#public-directory-support 97 | # public 98 | 99 | # vuepress build output 100 | .vuepress/dist 101 | 102 | # vuepress v2.x temp and cache directory 103 | .temp 104 | .cache 105 | 106 | # Docusaurus cache and generated files 107 | .docusaurus 108 | 109 | # Serverless directories 110 | .serverless/ 111 | 112 | # FuseBox cache 113 | .fusebox/ 114 | 115 | # DynamoDB Local files 116 | .dynamodb/ 117 | 118 | # TernJS port file 119 | .tern-port 120 | 121 | # Stores VSCode versions used for testing VSCode extensions 122 | .vscode-test 123 | 124 | # yarn v2 125 | .yarn/cache 126 | .yarn/unplugged 127 | .yarn/build-state.yml 128 | .yarn/install-state.gz 129 | .pnp.* 130 | 131 | # act-cli 132 | .secrets 133 | 134 | # VSIXs 135 | *.vsix 136 | submission-task/exec-child.js 137 | submission-task/lib.json 138 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Store Submission 2 | 3 | This is a GitHub Action to update EXE and MSI apps in the Microsoft Store. 4 | 5 | ## Quick start 6 | 7 | 1. Ensure you meet the [prerequisites](#prerequisites). 8 | 9 | 2. [Install](https://aka.ms/store-submission) the extension. 10 | 11 | 3. [Obtain](#obtaining-your-credentials) and [configure](#configuring-your-credentials) your Partner Center credentials. 12 | 13 | 4. [Add tasks](#task-reference) to your release definitions. 14 | 15 | ## Prerequisites 16 | 17 | 1. You must have an Azure AD directory, and you must have [global administrator permission](https://azure.microsoft.com/documentation/articles/active-directory-assign-admin-roles/) for the directory. You can create a new Azure AD [from Partner Center](https://msdn.microsoft.com/windows/uwp/publish/manage-account-users). 18 | 19 | 2. You must associate your Azure AD directory with your Partner Center account to obtain the credentials to allow this extension to access your account and perform actions on your behalf. 20 | 21 | 3. The app you want to publish must already exist: this extension can only publish updates to existing applications. You can [create your app in Partner Center](https://msdn.microsoft.com/windows/uwp/publish/create-your-app-by-reserving-a-name). 22 | 23 | 4. You must have already [created at least one submission](https://msdn.microsoft.com/windows/uwp/publish/app-submissions) for your app before you can use the Publish task provided by this extension. If you have not created a submission, the task will fail. 24 | 25 | 5. More information and extra prerequisites specific to the API can be found [here](https://msdn.microsoft.com/windows/uwp/monetize/create-and-manage-submissions-using-windows-store-services). 26 | 27 | ## Obtaining your credentials 28 | 29 | Your credentials are comprised of three parts: the Azure **Tenant ID**, the **Client ID** and the **Client secret**. 30 | Follow these steps to obtain them: 31 | 32 | 1. In Partner Center, go to your **Account settings**, click **Manage users**, and associate your organization's Partner Center account with your organization's Azure AD directory. For detailed instructions, see [Manage account users](https://msdn.microsoft.com/windows/uwp/publish/manage-account-users). 33 | 34 | 2. In the **Manage users** page, click **Add Azure AD applications**, add the Azure AD application that represents the app or service that you will use to access submissions for your Partner Center account, and assign it the **Manager** role. If this application already exists in your Azure AD directory, you can select it on the **Add Azure AD applications** page to add it to your Partner Center account. Otherwise, you can create a new Azure AD application on the **Add Azure AD applications** page. For more information, see [Add and manage Azure AD applications](https://msdn.microsoft.com/windows/uwp/publish/manage-account-users#add-and-manage-azure-ad-applications). 35 | 36 | 3. Return to the **Manage users** page, click the name of your Azure AD application to go to the application settings, and copy the **Tenant ID** and **Client ID** values. 37 | 38 | 4. Click **Add new key**. On the following screen, copy the **Key** value, which corresponds to the **Client secret**. You *will not* be able to access this info again after you leave this page, so make sure to not lose it. For more information, see the information about managing keys in [Add and manage Azure AD applications](https://msdn.microsoft.com/windows/uwp/publish/manage-account-users#add-and-manage-azure-ad-applications). 39 | 40 | See more details on how to create a new Azure AD application account in your organizaiton's directory and add it to your Partner Center account [here](https://docs.microsoft.com/windows/uwp/publish/add-users-groups-and-azure-ad-applications#create-a-new-azure-ad-application-account-in-your-organizations-directory-and-add-it-to-your-partner-center-account). 41 | 42 | ## Obtaining App Metadata 43 | 44 | ### Seller ID 45 | 46 | The Seller ID can be found by clicking the gear icon in the upper right corner of the [Partner Center](https://partner.microsoft.com) and selecting `Account Settings`. You can find the Seller ID under [Legal info](https://partner.microsoft.com/dashboard/account/v3/organization/legalinfo) 47 | 48 | ### Product ID 49 | 50 | The Product ID can be found by navigating to the overview of your application in the [Partner Center](https://partner.microsoft.com) and copying the Partner Center ID. 51 | 52 | ## Task reference 53 | 54 | ### Microsoft Store Submission 55 | 56 | This action allows you to publish your app on the Store by creating a submission in Partner Center. 57 | 58 | ## Sample 59 | 60 | ```yml 61 | name: CI 62 | 63 | on: 64 | push: 65 | branches: [ main ] 66 | pull_request: 67 | branches: [ main ] 68 | 69 | jobs: 70 | start-store-submission: 71 | runs-on: ubuntu-latest 72 | steps: 73 | - name: Configure Store Credentials 74 | uses: microsoft/store-submission@v1 75 | with: 76 | command: configure 77 | type: win32 78 | seller-id: ${{ secrets.SELLER_ID }} 79 | product-id: ${{ secrets.PRODUCT_ID }} 80 | tenant-id: ${{ secrets.TENANT_ID }} 81 | client-id: ${{ secrets.CLIENT_ID }} 82 | client-secret: ${{ secrets.CLIENT_SECRET }} 83 | 84 | - name: Update Draft Submission 85 | uses: microsoft/store-submission@v1 86 | with: 87 | command: update 88 | product-update: '{"packages":[{"packageUrl":"https://cdn.contoso.us/prod/5.10.1.4420/ContosoIgniteInstallerFull.msi","languages":["en"],"architectures":["X64"],"isSilentInstall":true}]}' 89 | 90 | - name: Publish Submission 91 | uses: microsoft/store-submission@v1 92 | with: 93 | command: publish 94 | ``` 95 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Microsoft Store Publish' 2 | author: 'Microsoft' 3 | description: 'Submit a package to the Microsoft Store' 4 | branding: 5 | icon: 'upload-cloud' 6 | color: 'blue' 7 | inputs: 8 | type: 9 | description: 'The type of Store Application. Available options are: `packaged` or `win32`' 10 | required: false 11 | default: 'packaged' 12 | command: 13 | description: 'The command to execute. Available command: `configure`, `get`, `update`, `poll`, or `publish`.' 14 | required: false 15 | default: 'configure' 16 | seller-id: 17 | description: 'Seller Id' 18 | required: false 19 | product-id: 20 | description: 'Product Id' 21 | required: false 22 | tenant-id: 23 | description: 'AAD Tenant Id' 24 | required: false 25 | client-id: 26 | description: 'App Client Id' 27 | required: false 28 | client-secret: 29 | description: 'App Client secret' 30 | required: false 31 | module-name: 32 | description: 'Indicates which module should be queried from the current draft (listing, properties or availability)' 33 | required: false 34 | listing-language: 35 | description: 'Indicates which listing language should be queries from the current draft' 36 | required: false 37 | default: 'en' 38 | product-update: 39 | description: 'The Json payload that is used to update the package data' 40 | required: false 41 | metadata-update: 42 | description: 'The Json payload that is used to update the metadata data (listing, properties and/or availability)' 43 | required: false 44 | polling-submission-id: 45 | description: 'The Id of the active submission being processed' 46 | required: false 47 | outputs: 48 | draft-submission: 49 | description: 'The existing draft of the product specified' 50 | submission-status: 51 | description: 'The status of the submission' 52 | polling-submission-id: 53 | description: 'The Id of the active submission being processed' 54 | runs: 55 | using: 'node16' 56 | main: 'dist/index.js' -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | /******/ (() => { // webpackBootstrap 2 | /******/ var __webpack_modules__ = ({ 3 | 4 | /***/ 823: 5 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 6 | 7 | "use strict"; 8 | 9 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | var desc = Object.getOwnPropertyDescriptor(m, k); 12 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 13 | desc = { enumerable: true, get: function() { return m[k]; } }; 14 | } 15 | Object.defineProperty(o, k2, desc); 16 | }) : (function(o, m, k, k2) { 17 | if (k2 === undefined) k2 = k; 18 | o[k2] = m[k]; 19 | })); 20 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 21 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 22 | }) : function(o, v) { 23 | o["default"] = v; 24 | }); 25 | var __importStar = (this && this.__importStar) || function (mod) { 26 | if (mod && mod.__esModule) return mod; 27 | var result = {}; 28 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 29 | __setModuleDefault(result, mod); 30 | return result; 31 | }; 32 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 33 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 34 | return new (P || (P = Promise))(function (resolve, reject) { 35 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 36 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 37 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 38 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 39 | }); 40 | }; 41 | Object.defineProperty(exports, "__esModule", ({ value: true })); 42 | const core = __importStar(__nccwpck_require__(186)); 43 | const store_apis_1 = __nccwpck_require__(605); 44 | (function main() { 45 | return __awaiter(this, void 0, void 0, function* () { 46 | const storeApis = new store_apis_1.StoreApis(); 47 | try { 48 | const command = core.getInput("command"); 49 | switch (command) { 50 | case "configure": { 51 | storeApis.productId = core.getInput("product-id"); 52 | storeApis.sellerId = core.getInput("seller-id"); 53 | storeApis.tenantId = core.getInput("tenant-id"); 54 | storeApis.clientId = core.getInput("client-id"); 55 | storeApis.clientSecret = core.getInput("client-secret"); 56 | yield storeApis.InitAsync(); 57 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}product_id`, storeApis.productId); 58 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}seller_id`, storeApis.sellerId); 59 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}tenant_id`, storeApis.tenantId); 60 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}client_id`, storeApis.clientId); 61 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}client_secret`, storeApis.clientSecret); 62 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}access_token`, storeApis.accessToken); 63 | core.setSecret(storeApis.productId); 64 | core.setSecret(storeApis.sellerId); 65 | core.setSecret(storeApis.tenantId); 66 | core.setSecret(storeApis.clientId); 67 | core.setSecret(storeApis.clientSecret); 68 | core.setSecret(storeApis.accessToken); 69 | break; 70 | } 71 | case "get": { 72 | const moduleName = core.getInput("module-name"); 73 | const listingLanguage = core.getInput("listing-language"); 74 | const draftSubmission = yield storeApis.GetExistingDraft(moduleName, listingLanguage); 75 | core.setOutput("draft-submission", draftSubmission); 76 | break; 77 | } 78 | case "update": { 79 | const updatedMetadataString = core.getInput("metadata-update"); 80 | const updatedProductString = core.getInput("product-update"); 81 | if (!updatedMetadataString && !updatedProductString) { 82 | core.setFailed(`Nothing to update. Both product-update and metadata-update are null.`); 83 | return; 84 | } 85 | if (updatedMetadataString) { 86 | const updateSubmissionMetadata = yield storeApis.UpdateSubmissionMetadata(updatedMetadataString); 87 | console.log(updateSubmissionMetadata); 88 | } 89 | if (updatedProductString) { 90 | const updateSubmissionData = yield storeApis.UpdateProductPackages(updatedProductString); 91 | console.log(updateSubmissionData); 92 | } 93 | break; 94 | } 95 | case "poll": { 96 | const pollingSubmissionId = core.getInput("polling-submission-id"); 97 | if (!pollingSubmissionId) { 98 | core.setFailed(`polling-submission-id parameter cannot be empty.`); 99 | return; 100 | } 101 | const publishingStatus = yield storeApis.PollSubmissionStatus(pollingSubmissionId); 102 | core.setOutput("submission-status", publishingStatus); 103 | break; 104 | } 105 | case "publish": { 106 | const submissionId = yield storeApis.PublishSubmission(); 107 | core.setOutput("polling-submission-id", submissionId); 108 | break; 109 | } 110 | default: { 111 | core.setFailed(`Unknown command - ("${command}").`); 112 | break; 113 | } 114 | } 115 | } 116 | catch (error) { 117 | core.setFailed(error); 118 | } 119 | }); 120 | })(); 121 | //# sourceMappingURL=github_action.js.map 122 | 123 | /***/ }), 124 | 125 | /***/ 605: 126 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 127 | 128 | "use strict"; 129 | 130 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 131 | if (k2 === undefined) k2 = k; 132 | var desc = Object.getOwnPropertyDescriptor(m, k); 133 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 134 | desc = { enumerable: true, get: function() { return m[k]; } }; 135 | } 136 | Object.defineProperty(o, k2, desc); 137 | }) : (function(o, m, k, k2) { 138 | if (k2 === undefined) k2 = k; 139 | o[k2] = m[k]; 140 | })); 141 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 142 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 143 | }) : function(o, v) { 144 | o["default"] = v; 145 | }); 146 | var __importStar = (this && this.__importStar) || function (mod) { 147 | if (mod && mod.__esModule) return mod; 148 | var result = {}; 149 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 150 | __setModuleDefault(result, mod); 151 | return result; 152 | }; 153 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 154 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 155 | return new (P || (P = Promise))(function (resolve, reject) { 156 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 157 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 158 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 159 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 160 | }); 161 | }; 162 | Object.defineProperty(exports, "__esModule", ({ value: true })); 163 | exports.StoreApis = exports.EnvVariablePrefix = void 0; 164 | const https = __importStar(__nccwpck_require__(687)); 165 | exports.EnvVariablePrefix = "MICROSOFT_STORE_ACTION_"; 166 | class ResponseWrapper { 167 | constructor() { 168 | Object.defineProperty(this, "responseData", { 169 | enumerable: true, 170 | configurable: true, 171 | writable: true, 172 | value: void 0 173 | }); 174 | Object.defineProperty(this, "isSuccess", { 175 | enumerable: true, 176 | configurable: true, 177 | writable: true, 178 | value: void 0 179 | }); 180 | Object.defineProperty(this, "errors", { 181 | enumerable: true, 182 | configurable: true, 183 | writable: true, 184 | value: void 0 185 | }); 186 | } 187 | } 188 | class ErrorResponse { 189 | constructor() { 190 | Object.defineProperty(this, "statusCode", { 191 | enumerable: true, 192 | configurable: true, 193 | writable: true, 194 | value: void 0 195 | }); 196 | Object.defineProperty(this, "message", { 197 | enumerable: true, 198 | configurable: true, 199 | writable: true, 200 | value: void 0 201 | }); 202 | } 203 | } 204 | class Error { 205 | constructor() { 206 | Object.defineProperty(this, "code", { 207 | enumerable: true, 208 | configurable: true, 209 | writable: true, 210 | value: void 0 211 | }); 212 | Object.defineProperty(this, "message", { 213 | enumerable: true, 214 | configurable: true, 215 | writable: true, 216 | value: void 0 217 | }); 218 | Object.defineProperty(this, "target", { 219 | enumerable: true, 220 | configurable: true, 221 | writable: true, 222 | value: void 0 223 | }); 224 | } 225 | } 226 | class SubmissionResponse { 227 | constructor() { 228 | Object.defineProperty(this, "pollingUrl", { 229 | enumerable: true, 230 | configurable: true, 231 | writable: true, 232 | value: void 0 233 | }); 234 | Object.defineProperty(this, "submissionId", { 235 | enumerable: true, 236 | configurable: true, 237 | writable: true, 238 | value: void 0 239 | }); 240 | Object.defineProperty(this, "ongoingSubmissionId", { 241 | enumerable: true, 242 | configurable: true, 243 | writable: true, 244 | value: void 0 245 | }); 246 | } 247 | } 248 | var PublishingStatus; 249 | (function (PublishingStatus) { 250 | PublishingStatus["INPROGRESS"] = "INPROGRESS"; 251 | PublishingStatus["PUBLISHED"] = "PUBLISHED"; 252 | PublishingStatus["FAILED"] = "FAILED"; 253 | PublishingStatus["UNKNOWN"] = "UNKNOWN"; 254 | })(PublishingStatus || (PublishingStatus = {})); 255 | class ModuleStatus { 256 | constructor() { 257 | Object.defineProperty(this, "isReady", { 258 | enumerable: true, 259 | configurable: true, 260 | writable: true, 261 | value: void 0 262 | }); 263 | Object.defineProperty(this, "ongoingSubmissionId", { 264 | enumerable: true, 265 | configurable: true, 266 | writable: true, 267 | value: void 0 268 | }); 269 | } 270 | } 271 | class SubmissionStatus { 272 | constructor() { 273 | Object.defineProperty(this, "publishingStatus", { 274 | enumerable: true, 275 | configurable: true, 276 | writable: true, 277 | value: void 0 278 | }); 279 | Object.defineProperty(this, "hasFailed", { 280 | enumerable: true, 281 | configurable: true, 282 | writable: true, 283 | value: void 0 284 | }); 285 | } 286 | } 287 | class ListingAssetsResponse { 288 | constructor() { 289 | Object.defineProperty(this, "listingAssets", { 290 | enumerable: true, 291 | configurable: true, 292 | writable: true, 293 | value: void 0 294 | }); 295 | } 296 | } 297 | class ImageSize { 298 | constructor() { 299 | Object.defineProperty(this, "width", { 300 | enumerable: true, 301 | configurable: true, 302 | writable: true, 303 | value: void 0 304 | }); 305 | Object.defineProperty(this, "height", { 306 | enumerable: true, 307 | configurable: true, 308 | writable: true, 309 | value: void 0 310 | }); 311 | } 312 | } 313 | class ListingAsset { 314 | constructor() { 315 | Object.defineProperty(this, "language", { 316 | enumerable: true, 317 | configurable: true, 318 | writable: true, 319 | value: void 0 320 | }); 321 | Object.defineProperty(this, "storeLogos", { 322 | enumerable: true, 323 | configurable: true, 324 | writable: true, 325 | value: void 0 326 | }); 327 | Object.defineProperty(this, "screenshots", { 328 | enumerable: true, 329 | configurable: true, 330 | writable: true, 331 | value: void 0 332 | }); 333 | } 334 | } 335 | class Screenshot { 336 | constructor() { 337 | Object.defineProperty(this, "id", { 338 | enumerable: true, 339 | configurable: true, 340 | writable: true, 341 | value: void 0 342 | }); 343 | Object.defineProperty(this, "assetUrl", { 344 | enumerable: true, 345 | configurable: true, 346 | writable: true, 347 | value: void 0 348 | }); 349 | Object.defineProperty(this, "imageSize", { 350 | enumerable: true, 351 | configurable: true, 352 | writable: true, 353 | value: void 0 354 | }); 355 | } 356 | } 357 | class StoreLogo { 358 | constructor() { 359 | Object.defineProperty(this, "id", { 360 | enumerable: true, 361 | configurable: true, 362 | writable: true, 363 | value: void 0 364 | }); 365 | Object.defineProperty(this, "assetUrl", { 366 | enumerable: true, 367 | configurable: true, 368 | writable: true, 369 | value: void 0 370 | }); 371 | Object.defineProperty(this, "imageSize", { 372 | enumerable: true, 373 | configurable: true, 374 | writable: true, 375 | value: void 0 376 | }); 377 | } 378 | } 379 | class StoreApis { 380 | constructor() { 381 | Object.defineProperty(this, "accessToken", { 382 | enumerable: true, 383 | configurable: true, 384 | writable: true, 385 | value: void 0 386 | }); 387 | Object.defineProperty(this, "productId", { 388 | enumerable: true, 389 | configurable: true, 390 | writable: true, 391 | value: void 0 392 | }); 393 | Object.defineProperty(this, "sellerId", { 394 | enumerable: true, 395 | configurable: true, 396 | writable: true, 397 | value: void 0 398 | }); 399 | Object.defineProperty(this, "tenantId", { 400 | enumerable: true, 401 | configurable: true, 402 | writable: true, 403 | value: void 0 404 | }); 405 | Object.defineProperty(this, "clientId", { 406 | enumerable: true, 407 | configurable: true, 408 | writable: true, 409 | value: void 0 410 | }); 411 | Object.defineProperty(this, "clientSecret", { 412 | enumerable: true, 413 | configurable: true, 414 | writable: true, 415 | value: void 0 416 | }); 417 | this.LoadState(); 418 | } 419 | Delay(ms) { 420 | return new Promise((resolve) => setTimeout(resolve, ms)); 421 | } 422 | GetAccessToken() { 423 | return __awaiter(this, void 0, void 0, function* () { 424 | const requestParameters = { 425 | grant_type: "client_credentials", 426 | client_id: this.clientId, 427 | client_secret: this.clientSecret, 428 | scope: StoreApis.scope, 429 | }; 430 | const formBody = []; 431 | for (const property in requestParameters) { 432 | const encodedKey = encodeURIComponent(property); 433 | const encodedValue = encodeURIComponent(requestParameters[property]); 434 | formBody.push(encodedKey + "=" + encodedValue); 435 | } 436 | const dataString = formBody.join("\r\n&"); 437 | const options = { 438 | host: StoreApis.microsoftOnlineLoginHost, 439 | path: `/${this.tenantId}${StoreApis.authOAuth2TokenSuffix}`, 440 | method: "POST", 441 | headers: { 442 | "Content-Type": "application/x-www-form-urlencoded", 443 | "Content-Length": dataString.length, 444 | }, 445 | }; 446 | return new Promise((resolve, reject) => { 447 | const req = https.request(options, (res) => { 448 | let responseString = ""; 449 | res.on("data", (data) => { 450 | responseString += data; 451 | }); 452 | res.on("end", function () { 453 | const responseObject = JSON.parse(responseString); 454 | if (responseObject.error) 455 | reject(responseObject); 456 | else 457 | resolve(responseObject.access_token); 458 | }); 459 | }); 460 | req.on("error", (e) => { 461 | console.error(e); 462 | reject(e); 463 | }); 464 | req.write(dataString); 465 | req.end(); 466 | }); 467 | }); 468 | } 469 | GetCurrentDraftSubmissionPackagesData() { 470 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/packages`); 471 | } 472 | GetCurrentDraftSubmissionMetadata(moduleName, listingLanguages) { 473 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/metadata/${moduleName}?languages=${listingLanguages}`); 474 | } 475 | UpdateCurrentDraftSubmissionMetadata(submissionMetadata) { 476 | return this.CreateStoreHttpRequest(JSON.stringify(submissionMetadata), "PUT", `/submission/v1/product/${this.productId}/metadata`); 477 | } 478 | UpdateStoreSubmissionPackages(submission) { 479 | return __awaiter(this, void 0, void 0, function* () { 480 | return this.CreateStoreHttpRequest(JSON.stringify(submission), "PUT", `/submission/v1/product/${this.productId}/packages`); 481 | }); 482 | } 483 | CommitUpdateStoreSubmissionPackages() { 484 | return __awaiter(this, void 0, void 0, function* () { 485 | return this.CreateStoreHttpRequest("", "POST", `/submission/v1/product/${this.productId}/packages/commit`); 486 | }); 487 | } 488 | GetModuleStatus() { 489 | return __awaiter(this, void 0, void 0, function* () { 490 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/status`); 491 | }); 492 | } 493 | GetSubmissionStatus(submissionId) { 494 | return __awaiter(this, void 0, void 0, function* () { 495 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/submission/${submissionId}/status`); 496 | }); 497 | } 498 | SubmitSubmission() { 499 | return __awaiter(this, void 0, void 0, function* () { 500 | return this.CreateStoreHttpRequest("", "POST", `/submission/v1/product/${this.productId}/submit`); 501 | }); 502 | } 503 | GetCurrentDraftListingAssets(listingLanguages) { 504 | return __awaiter(this, void 0, void 0, function* () { 505 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/listings/assets?languages=${listingLanguages}`); 506 | }); 507 | } 508 | CreateStoreHttpRequest(requestParameters, method, path) { 509 | return __awaiter(this, void 0, void 0, function* () { 510 | const options = { 511 | host: StoreApis.storeApiUrl, 512 | path: path, 513 | method: method, 514 | headers: { 515 | "Content-Type": "application/json", 516 | "Content-Length": requestParameters.length, 517 | Authorization: "Bearer " + this.accessToken, 518 | "X-Seller-Account-Id": this.sellerId, 519 | }, 520 | }; 521 | return new Promise((resolve, reject) => { 522 | const req = https.request(options, (res) => { 523 | if (res.statusCode == 404) { 524 | const error = new ResponseWrapper(); 525 | error.isSuccess = false; 526 | error.errors = []; 527 | error.errors[0] = new Error(); 528 | error.errors[0].message = "Not found"; 529 | reject(error); 530 | return; 531 | } 532 | let responseString = ""; 533 | res.on("data", (data) => { 534 | responseString += data; 535 | }); 536 | res.on("end", function () { 537 | const responseObject = JSON.parse(responseString); 538 | resolve(responseObject); 539 | }); 540 | }); 541 | req.on("error", (e) => { 542 | console.error(e); 543 | reject(e); 544 | }); 545 | req.write(requestParameters); 546 | req.end(); 547 | }); 548 | }); 549 | } 550 | PollModuleStatus() { 551 | return __awaiter(this, void 0, void 0, function* () { 552 | let status = new ModuleStatus(); 553 | status.isReady = false; 554 | while (!status.isReady) { 555 | const moduleStatus = yield this.GetModuleStatus(); 556 | console.log(JSON.stringify(moduleStatus)); 557 | status = moduleStatus.responseData; 558 | if (!moduleStatus.isSuccess) { 559 | const errorResponse = moduleStatus; 560 | if (errorResponse.statusCode == 401) { 561 | console.log(`Access token expired. Requesting new one. (message='${errorResponse.message}')`); 562 | yield this.InitAsync(); 563 | status = new ModuleStatus(); 564 | status.isReady = false; 565 | continue; 566 | } 567 | console.log("Error"); 568 | break; 569 | } 570 | if (status.isReady) { 571 | console.log("Success!"); 572 | return true; 573 | } 574 | else { 575 | if (moduleStatus.errors && 576 | moduleStatus.errors.length > 0 && 577 | moduleStatus.errors.find((e) => e.target != "packages" || e.code == "packageuploaderror")) { 578 | console.log(moduleStatus.errors); 579 | return false; 580 | } 581 | } 582 | console.log("Waiting 10 seconds."); 583 | yield this.Delay(10000); 584 | } 585 | return false; 586 | }); 587 | } 588 | InitAsync() { 589 | return __awaiter(this, void 0, void 0, function* () { 590 | this.accessToken = yield this.GetAccessToken(); 591 | }); 592 | } 593 | GetExistingDraft(moduleName, listingLanguage) { 594 | return __awaiter(this, void 0, void 0, function* () { 595 | return new Promise((resolve, reject) => { 596 | if (moduleName && 597 | moduleName.toLowerCase() != "availability" && 598 | moduleName.toLowerCase() != "listings" && 599 | moduleName.toLowerCase() != "properties") { 600 | reject("Module name must be 'availability', 'listings' or 'properties'"); 601 | return; 602 | } 603 | (moduleName 604 | ? this.GetCurrentDraftSubmissionMetadata(moduleName, listingLanguage) 605 | : this.GetCurrentDraftSubmissionPackagesData()) 606 | .then((currentDraftResponse) => { 607 | if (!currentDraftResponse.isSuccess) { 608 | reject(`Failed to get the existing draft. - ${JSON.stringify(currentDraftResponse, null, 2)}`); 609 | } 610 | else { 611 | resolve(JSON.stringify(currentDraftResponse.responseData)); 612 | } 613 | }) 614 | .catch((error) => { 615 | reject(`Failed to get the existing draft. - ${error.errors}`); 616 | }); 617 | }); 618 | }); 619 | } 620 | PollSubmissionStatus(pollingSubmissionId) { 621 | return __awaiter(this, void 0, void 0, function* () { 622 | let status = new SubmissionStatus(); 623 | status.hasFailed = false; 624 | // eslint-disable-next-line no-async-promise-executor 625 | return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { 626 | while (!status.hasFailed) { 627 | const submissionStatus = yield this.GetSubmissionStatus(pollingSubmissionId); 628 | console.log(JSON.stringify(submissionStatus)); 629 | status = submissionStatus.responseData; 630 | if (!submissionStatus.isSuccess || status.hasFailed) { 631 | const errorResponse = submissionStatus; 632 | if (errorResponse.statusCode == 401) { 633 | console.log(`Access token expired. Requesting new one. (message='${errorResponse.message}')`); 634 | yield this.InitAsync(); 635 | status = new SubmissionStatus(); 636 | status.hasFailed = false; 637 | continue; 638 | } 639 | console.log("Error"); 640 | reject("Error"); 641 | return; 642 | } 643 | if (status.publishingStatus == PublishingStatus.PUBLISHED || 644 | status.publishingStatus == PublishingStatus.FAILED) { 645 | console.log(`PublishingStatus = ${status.publishingStatus}`); 646 | resolve(status.publishingStatus); 647 | return; 648 | } 649 | console.log("Waiting 10 seconds."); 650 | yield this.Delay(10000); 651 | } 652 | })); 653 | }); 654 | } 655 | UpdateSubmissionMetadata(submissionMetadataString) { 656 | return __awaiter(this, void 0, void 0, function* () { 657 | if (!(yield this.PollModuleStatus())) { 658 | // Wait until all modules are in the ready state 659 | return Promise.reject("Failed to poll module status."); 660 | } 661 | const submissionMetadata = JSON.parse(submissionMetadataString); 662 | console.log(submissionMetadata); 663 | const updateSubmissionData = yield this.UpdateCurrentDraftSubmissionMetadata(submissionMetadata); 664 | console.log(JSON.stringify(updateSubmissionData)); 665 | if (!updateSubmissionData.isSuccess) { 666 | return Promise.reject(`Failed to update submission metadata - ${JSON.stringify(updateSubmissionData.errors)}`); 667 | } 668 | if (!(yield this.PollModuleStatus())) { 669 | // Wait until all modules are in the ready state 670 | return Promise.reject("Failed to poll module status."); 671 | } 672 | return updateSubmissionData; 673 | }); 674 | } 675 | UpdateProductPackages(updatedProductString) { 676 | return __awaiter(this, void 0, void 0, function* () { 677 | if (!(yield this.PollModuleStatus())) { 678 | // Wait until all modules are in the ready state 679 | return Promise.reject("Failed to poll module status."); 680 | } 681 | const updatedProductPackages = JSON.parse(updatedProductString); 682 | console.log(updatedProductPackages); 683 | const updateSubmissionData = yield this.UpdateStoreSubmissionPackages(updatedProductPackages); 684 | console.log(JSON.stringify(updateSubmissionData)); 685 | if (!updateSubmissionData.isSuccess) { 686 | return Promise.reject(`Failed to update submission - ${JSON.stringify(updateSubmissionData.errors)}`); 687 | } 688 | console.log("Committing package changes..."); 689 | const commitResult = yield this.CommitUpdateStoreSubmissionPackages(); 690 | if (!commitResult.isSuccess) { 691 | return Promise.reject(`Failed to commit the updated submission - ${JSON.stringify(commitResult.errors)}`); 692 | } 693 | console.log(JSON.stringify(commitResult)); 694 | if (!(yield this.PollModuleStatus())) { 695 | // Wait until all modules are in the ready state 696 | return Promise.reject("Failed to poll module status."); 697 | } 698 | return updateSubmissionData; 699 | }); 700 | } 701 | PublishSubmission() { 702 | return __awaiter(this, void 0, void 0, function* () { 703 | const commitResult = yield this.CommitUpdateStoreSubmissionPackages(); 704 | if (!commitResult.isSuccess) { 705 | return Promise.reject(`Failed to commit the updated submission - ${JSON.stringify(commitResult.errors)}`); 706 | } 707 | console.log(JSON.stringify(commitResult)); 708 | if (!(yield this.PollModuleStatus())) { 709 | // Wait until all modules are in the ready state 710 | return Promise.reject("Failed to poll module status."); 711 | } 712 | let submissionId = null; 713 | const submitSubmissionResponse = yield this.SubmitSubmission(); 714 | console.log(JSON.stringify(submitSubmissionResponse)); 715 | if (submitSubmissionResponse.isSuccess) { 716 | if (submitSubmissionResponse.responseData.submissionId != null && 717 | submitSubmissionResponse.responseData.submissionId.length > 0) { 718 | submissionId = submitSubmissionResponse.responseData.submissionId; 719 | } 720 | else if (submitSubmissionResponse.responseData.ongoingSubmissionId != null && 721 | submitSubmissionResponse.responseData.ongoingSubmissionId.length > 0) { 722 | submissionId = 723 | submitSubmissionResponse.responseData.ongoingSubmissionId; 724 | } 725 | } 726 | return new Promise((resolve, reject) => { 727 | if (submissionId == null) { 728 | console.log("Failed to get submission ID"); 729 | reject("Failed to get submission ID"); 730 | } 731 | else { 732 | resolve(submissionId); 733 | } 734 | }); 735 | }); 736 | } 737 | GetExistingDraftListingAssets(listingLanguage) { 738 | return __awaiter(this, void 0, void 0, function* () { 739 | return new Promise((resolve, reject) => { 740 | this.GetCurrentDraftListingAssets(listingLanguage) 741 | .then((draftListingAssetsResponse) => { 742 | if (!draftListingAssetsResponse.isSuccess) { 743 | reject(`Failed to get the existing draft listing assets. - ${JSON.stringify(draftListingAssetsResponse, null, 2)}`); 744 | } 745 | else { 746 | resolve(JSON.stringify(draftListingAssetsResponse.responseData)); 747 | } 748 | }) 749 | .catch((error) => { 750 | reject(`Failed to get the existing draft listing assets. - ${error.errors}`); 751 | }); 752 | }); 753 | }); 754 | } 755 | LoadState() { 756 | var _a, _b, _c, _d, _e, _f; 757 | this.productId = (_a = process.env[`${exports.EnvVariablePrefix}product_id`]) !== null && _a !== void 0 ? _a : ""; 758 | this.sellerId = (_b = process.env[`${exports.EnvVariablePrefix}seller_id`]) !== null && _b !== void 0 ? _b : ""; 759 | this.tenantId = (_c = process.env[`${exports.EnvVariablePrefix}tenant_id`]) !== null && _c !== void 0 ? _c : ""; 760 | this.clientId = (_d = process.env[`${exports.EnvVariablePrefix}client_id`]) !== null && _d !== void 0 ? _d : ""; 761 | this.clientSecret = (_e = process.env[`${exports.EnvVariablePrefix}client_secret`]) !== null && _e !== void 0 ? _e : ""; 762 | this.accessToken = (_f = process.env[`${exports.EnvVariablePrefix}access_token`]) !== null && _f !== void 0 ? _f : ""; 763 | } 764 | } 765 | exports.StoreApis = StoreApis; 766 | Object.defineProperty(StoreApis, "microsoftOnlineLoginHost", { 767 | enumerable: true, 768 | configurable: true, 769 | writable: true, 770 | value: "login.microsoftonline.com" 771 | }); 772 | Object.defineProperty(StoreApis, "authOAuth2TokenSuffix", { 773 | enumerable: true, 774 | configurable: true, 775 | writable: true, 776 | value: "/oauth2/v2.0/token" 777 | }); 778 | Object.defineProperty(StoreApis, "scope", { 779 | enumerable: true, 780 | configurable: true, 781 | writable: true, 782 | value: "https://api.store.microsoft.com/.default" 783 | }); 784 | Object.defineProperty(StoreApis, "storeApiUrl", { 785 | enumerable: true, 786 | configurable: true, 787 | writable: true, 788 | value: "api.store.microsoft.com" 789 | }); 790 | //# sourceMappingURL=store_apis.js.map 791 | 792 | /***/ }), 793 | 794 | /***/ 351: 795 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 796 | 797 | "use strict"; 798 | 799 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 800 | if (k2 === undefined) k2 = k; 801 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 802 | }) : (function(o, m, k, k2) { 803 | if (k2 === undefined) k2 = k; 804 | o[k2] = m[k]; 805 | })); 806 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 807 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 808 | }) : function(o, v) { 809 | o["default"] = v; 810 | }); 811 | var __importStar = (this && this.__importStar) || function (mod) { 812 | if (mod && mod.__esModule) return mod; 813 | var result = {}; 814 | if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 815 | __setModuleDefault(result, mod); 816 | return result; 817 | }; 818 | Object.defineProperty(exports, "__esModule", ({ value: true })); 819 | exports.issue = exports.issueCommand = void 0; 820 | const os = __importStar(__nccwpck_require__(37)); 821 | const utils_1 = __nccwpck_require__(278); 822 | /** 823 | * Commands 824 | * 825 | * Command Format: 826 | * ::name key=value,key=value::message 827 | * 828 | * Examples: 829 | * ::warning::This is the message 830 | * ::set-env name=MY_VAR::some value 831 | */ 832 | function issueCommand(command, properties, message) { 833 | const cmd = new Command(command, properties, message); 834 | process.stdout.write(cmd.toString() + os.EOL); 835 | } 836 | exports.issueCommand = issueCommand; 837 | function issue(name, message = '') { 838 | issueCommand(name, {}, message); 839 | } 840 | exports.issue = issue; 841 | const CMD_STRING = '::'; 842 | class Command { 843 | constructor(command, properties, message) { 844 | if (!command) { 845 | command = 'missing.command'; 846 | } 847 | this.command = command; 848 | this.properties = properties; 849 | this.message = message; 850 | } 851 | toString() { 852 | let cmdStr = CMD_STRING + this.command; 853 | if (this.properties && Object.keys(this.properties).length > 0) { 854 | cmdStr += ' '; 855 | let first = true; 856 | for (const key in this.properties) { 857 | if (this.properties.hasOwnProperty(key)) { 858 | const val = this.properties[key]; 859 | if (val) { 860 | if (first) { 861 | first = false; 862 | } 863 | else { 864 | cmdStr += ','; 865 | } 866 | cmdStr += `${key}=${escapeProperty(val)}`; 867 | } 868 | } 869 | } 870 | } 871 | cmdStr += `${CMD_STRING}${escapeData(this.message)}`; 872 | return cmdStr; 873 | } 874 | } 875 | function escapeData(s) { 876 | return utils_1.toCommandValue(s) 877 | .replace(/%/g, '%25') 878 | .replace(/\r/g, '%0D') 879 | .replace(/\n/g, '%0A'); 880 | } 881 | function escapeProperty(s) { 882 | return utils_1.toCommandValue(s) 883 | .replace(/%/g, '%25') 884 | .replace(/\r/g, '%0D') 885 | .replace(/\n/g, '%0A') 886 | .replace(/:/g, '%3A') 887 | .replace(/,/g, '%2C'); 888 | } 889 | //# sourceMappingURL=command.js.map 890 | 891 | /***/ }), 892 | 893 | /***/ 186: 894 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 895 | 896 | "use strict"; 897 | 898 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 899 | if (k2 === undefined) k2 = k; 900 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 901 | }) : (function(o, m, k, k2) { 902 | if (k2 === undefined) k2 = k; 903 | o[k2] = m[k]; 904 | })); 905 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 906 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 907 | }) : function(o, v) { 908 | o["default"] = v; 909 | }); 910 | var __importStar = (this && this.__importStar) || function (mod) { 911 | if (mod && mod.__esModule) return mod; 912 | var result = {}; 913 | if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 914 | __setModuleDefault(result, mod); 915 | return result; 916 | }; 917 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 918 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 919 | return new (P || (P = Promise))(function (resolve, reject) { 920 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 921 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 922 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 923 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 924 | }); 925 | }; 926 | Object.defineProperty(exports, "__esModule", ({ value: true })); 927 | exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; 928 | const command_1 = __nccwpck_require__(351); 929 | const file_command_1 = __nccwpck_require__(717); 930 | const utils_1 = __nccwpck_require__(278); 931 | const os = __importStar(__nccwpck_require__(37)); 932 | const path = __importStar(__nccwpck_require__(17)); 933 | const oidc_utils_1 = __nccwpck_require__(41); 934 | /** 935 | * The code to exit an action 936 | */ 937 | var ExitCode; 938 | (function (ExitCode) { 939 | /** 940 | * A code indicating that the action was successful 941 | */ 942 | ExitCode[ExitCode["Success"] = 0] = "Success"; 943 | /** 944 | * A code indicating that the action was a failure 945 | */ 946 | ExitCode[ExitCode["Failure"] = 1] = "Failure"; 947 | })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); 948 | //----------------------------------------------------------------------- 949 | // Variables 950 | //----------------------------------------------------------------------- 951 | /** 952 | * Sets env variable for this action and future actions in the job 953 | * @param name the name of the variable to set 954 | * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify 955 | */ 956 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 957 | function exportVariable(name, val) { 958 | const convertedVal = utils_1.toCommandValue(val); 959 | process.env[name] = convertedVal; 960 | const filePath = process.env['GITHUB_ENV'] || ''; 961 | if (filePath) { 962 | const delimiter = '_GitHubActionsFileCommandDelimeter_'; 963 | const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; 964 | file_command_1.issueCommand('ENV', commandValue); 965 | } 966 | else { 967 | command_1.issueCommand('set-env', { name }, convertedVal); 968 | } 969 | } 970 | exports.exportVariable = exportVariable; 971 | /** 972 | * Registers a secret which will get masked from logs 973 | * @param secret value of the secret 974 | */ 975 | function setSecret(secret) { 976 | command_1.issueCommand('add-mask', {}, secret); 977 | } 978 | exports.setSecret = setSecret; 979 | /** 980 | * Prepends inputPath to the PATH (for this action and future actions) 981 | * @param inputPath 982 | */ 983 | function addPath(inputPath) { 984 | const filePath = process.env['GITHUB_PATH'] || ''; 985 | if (filePath) { 986 | file_command_1.issueCommand('PATH', inputPath); 987 | } 988 | else { 989 | command_1.issueCommand('add-path', {}, inputPath); 990 | } 991 | process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; 992 | } 993 | exports.addPath = addPath; 994 | /** 995 | * Gets the value of an input. 996 | * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. 997 | * Returns an empty string if the value is not defined. 998 | * 999 | * @param name name of the input to get 1000 | * @param options optional. See InputOptions. 1001 | * @returns string 1002 | */ 1003 | function getInput(name, options) { 1004 | const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; 1005 | if (options && options.required && !val) { 1006 | throw new Error(`Input required and not supplied: ${name}`); 1007 | } 1008 | if (options && options.trimWhitespace === false) { 1009 | return val; 1010 | } 1011 | return val.trim(); 1012 | } 1013 | exports.getInput = getInput; 1014 | /** 1015 | * Gets the values of an multiline input. Each value is also trimmed. 1016 | * 1017 | * @param name name of the input to get 1018 | * @param options optional. See InputOptions. 1019 | * @returns string[] 1020 | * 1021 | */ 1022 | function getMultilineInput(name, options) { 1023 | const inputs = getInput(name, options) 1024 | .split('\n') 1025 | .filter(x => x !== ''); 1026 | return inputs; 1027 | } 1028 | exports.getMultilineInput = getMultilineInput; 1029 | /** 1030 | * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. 1031 | * Support boolean input list: `true | True | TRUE | false | False | FALSE` . 1032 | * The return value is also in boolean type. 1033 | * ref: https://yaml.org/spec/1.2/spec.html#id2804923 1034 | * 1035 | * @param name name of the input to get 1036 | * @param options optional. See InputOptions. 1037 | * @returns boolean 1038 | */ 1039 | function getBooleanInput(name, options) { 1040 | const trueValue = ['true', 'True', 'TRUE']; 1041 | const falseValue = ['false', 'False', 'FALSE']; 1042 | const val = getInput(name, options); 1043 | if (trueValue.includes(val)) 1044 | return true; 1045 | if (falseValue.includes(val)) 1046 | return false; 1047 | throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + 1048 | `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); 1049 | } 1050 | exports.getBooleanInput = getBooleanInput; 1051 | /** 1052 | * Sets the value of an output. 1053 | * 1054 | * @param name name of the output to set 1055 | * @param value value to store. Non-string values will be converted to a string via JSON.stringify 1056 | */ 1057 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 1058 | function setOutput(name, value) { 1059 | process.stdout.write(os.EOL); 1060 | command_1.issueCommand('set-output', { name }, value); 1061 | } 1062 | exports.setOutput = setOutput; 1063 | /** 1064 | * Enables or disables the echoing of commands into stdout for the rest of the step. 1065 | * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. 1066 | * 1067 | */ 1068 | function setCommandEcho(enabled) { 1069 | command_1.issue('echo', enabled ? 'on' : 'off'); 1070 | } 1071 | exports.setCommandEcho = setCommandEcho; 1072 | //----------------------------------------------------------------------- 1073 | // Results 1074 | //----------------------------------------------------------------------- 1075 | /** 1076 | * Sets the action status to failed. 1077 | * When the action exits it will be with an exit code of 1 1078 | * @param message add error issue message 1079 | */ 1080 | function setFailed(message) { 1081 | process.exitCode = ExitCode.Failure; 1082 | error(message); 1083 | } 1084 | exports.setFailed = setFailed; 1085 | //----------------------------------------------------------------------- 1086 | // Logging Commands 1087 | //----------------------------------------------------------------------- 1088 | /** 1089 | * Gets whether Actions Step Debug is on or not 1090 | */ 1091 | function isDebug() { 1092 | return process.env['RUNNER_DEBUG'] === '1'; 1093 | } 1094 | exports.isDebug = isDebug; 1095 | /** 1096 | * Writes debug message to user log 1097 | * @param message debug message 1098 | */ 1099 | function debug(message) { 1100 | command_1.issueCommand('debug', {}, message); 1101 | } 1102 | exports.debug = debug; 1103 | /** 1104 | * Adds an error issue 1105 | * @param message error issue message. Errors will be converted to string via toString() 1106 | * @param properties optional properties to add to the annotation. 1107 | */ 1108 | function error(message, properties = {}) { 1109 | command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); 1110 | } 1111 | exports.error = error; 1112 | /** 1113 | * Adds a warning issue 1114 | * @param message warning issue message. Errors will be converted to string via toString() 1115 | * @param properties optional properties to add to the annotation. 1116 | */ 1117 | function warning(message, properties = {}) { 1118 | command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); 1119 | } 1120 | exports.warning = warning; 1121 | /** 1122 | * Adds a notice issue 1123 | * @param message notice issue message. Errors will be converted to string via toString() 1124 | * @param properties optional properties to add to the annotation. 1125 | */ 1126 | function notice(message, properties = {}) { 1127 | command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); 1128 | } 1129 | exports.notice = notice; 1130 | /** 1131 | * Writes info to log with console.log. 1132 | * @param message info message 1133 | */ 1134 | function info(message) { 1135 | process.stdout.write(message + os.EOL); 1136 | } 1137 | exports.info = info; 1138 | /** 1139 | * Begin an output group. 1140 | * 1141 | * Output until the next `groupEnd` will be foldable in this group 1142 | * 1143 | * @param name The name of the output group 1144 | */ 1145 | function startGroup(name) { 1146 | command_1.issue('group', name); 1147 | } 1148 | exports.startGroup = startGroup; 1149 | /** 1150 | * End an output group. 1151 | */ 1152 | function endGroup() { 1153 | command_1.issue('endgroup'); 1154 | } 1155 | exports.endGroup = endGroup; 1156 | /** 1157 | * Wrap an asynchronous function call in a group. 1158 | * 1159 | * Returns the same type as the function itself. 1160 | * 1161 | * @param name The name of the group 1162 | * @param fn The function to wrap in the group 1163 | */ 1164 | function group(name, fn) { 1165 | return __awaiter(this, void 0, void 0, function* () { 1166 | startGroup(name); 1167 | let result; 1168 | try { 1169 | result = yield fn(); 1170 | } 1171 | finally { 1172 | endGroup(); 1173 | } 1174 | return result; 1175 | }); 1176 | } 1177 | exports.group = group; 1178 | //----------------------------------------------------------------------- 1179 | // Wrapper action state 1180 | //----------------------------------------------------------------------- 1181 | /** 1182 | * Saves state for current action, the state can only be retrieved by this action's post job execution. 1183 | * 1184 | * @param name name of the state to store 1185 | * @param value value to store. Non-string values will be converted to a string via JSON.stringify 1186 | */ 1187 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 1188 | function saveState(name, value) { 1189 | command_1.issueCommand('save-state', { name }, value); 1190 | } 1191 | exports.saveState = saveState; 1192 | /** 1193 | * Gets the value of an state set by this action's main execution. 1194 | * 1195 | * @param name name of the state to get 1196 | * @returns string 1197 | */ 1198 | function getState(name) { 1199 | return process.env[`STATE_${name}`] || ''; 1200 | } 1201 | exports.getState = getState; 1202 | function getIDToken(aud) { 1203 | return __awaiter(this, void 0, void 0, function* () { 1204 | return yield oidc_utils_1.OidcClient.getIDToken(aud); 1205 | }); 1206 | } 1207 | exports.getIDToken = getIDToken; 1208 | /** 1209 | * Summary exports 1210 | */ 1211 | var summary_1 = __nccwpck_require__(327); 1212 | Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); 1213 | /** 1214 | * @deprecated use core.summary 1215 | */ 1216 | var summary_2 = __nccwpck_require__(327); 1217 | Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); 1218 | //# sourceMappingURL=core.js.map 1219 | 1220 | /***/ }), 1221 | 1222 | /***/ 717: 1223 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 1224 | 1225 | "use strict"; 1226 | 1227 | // For internal use, subject to change. 1228 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 1229 | if (k2 === undefined) k2 = k; 1230 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 1231 | }) : (function(o, m, k, k2) { 1232 | if (k2 === undefined) k2 = k; 1233 | o[k2] = m[k]; 1234 | })); 1235 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 1236 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 1237 | }) : function(o, v) { 1238 | o["default"] = v; 1239 | }); 1240 | var __importStar = (this && this.__importStar) || function (mod) { 1241 | if (mod && mod.__esModule) return mod; 1242 | var result = {}; 1243 | if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 1244 | __setModuleDefault(result, mod); 1245 | return result; 1246 | }; 1247 | Object.defineProperty(exports, "__esModule", ({ value: true })); 1248 | exports.issueCommand = void 0; 1249 | // We use any as a valid input type 1250 | /* eslint-disable @typescript-eslint/no-explicit-any */ 1251 | const fs = __importStar(__nccwpck_require__(147)); 1252 | const os = __importStar(__nccwpck_require__(37)); 1253 | const utils_1 = __nccwpck_require__(278); 1254 | function issueCommand(command, message) { 1255 | const filePath = process.env[`GITHUB_${command}`]; 1256 | if (!filePath) { 1257 | throw new Error(`Unable to find environment variable for file command ${command}`); 1258 | } 1259 | if (!fs.existsSync(filePath)) { 1260 | throw new Error(`Missing file at path: ${filePath}`); 1261 | } 1262 | fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { 1263 | encoding: 'utf8' 1264 | }); 1265 | } 1266 | exports.issueCommand = issueCommand; 1267 | //# sourceMappingURL=file-command.js.map 1268 | 1269 | /***/ }), 1270 | 1271 | /***/ 41: 1272 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 1273 | 1274 | "use strict"; 1275 | 1276 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 1277 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 1278 | return new (P || (P = Promise))(function (resolve, reject) { 1279 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 1280 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 1281 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 1282 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 1283 | }); 1284 | }; 1285 | Object.defineProperty(exports, "__esModule", ({ value: true })); 1286 | exports.OidcClient = void 0; 1287 | const http_client_1 = __nccwpck_require__(255); 1288 | const auth_1 = __nccwpck_require__(526); 1289 | const core_1 = __nccwpck_require__(186); 1290 | class OidcClient { 1291 | static createHttpClient(allowRetry = true, maxRetry = 10) { 1292 | const requestOptions = { 1293 | allowRetries: allowRetry, 1294 | maxRetries: maxRetry 1295 | }; 1296 | return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); 1297 | } 1298 | static getRequestToken() { 1299 | const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; 1300 | if (!token) { 1301 | throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); 1302 | } 1303 | return token; 1304 | } 1305 | static getIDTokenUrl() { 1306 | const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; 1307 | if (!runtimeUrl) { 1308 | throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); 1309 | } 1310 | return runtimeUrl; 1311 | } 1312 | static getCall(id_token_url) { 1313 | var _a; 1314 | return __awaiter(this, void 0, void 0, function* () { 1315 | const httpclient = OidcClient.createHttpClient(); 1316 | const res = yield httpclient 1317 | .getJson(id_token_url) 1318 | .catch(error => { 1319 | throw new Error(`Failed to get ID Token. \n 1320 | Error Code : ${error.statusCode}\n 1321 | Error Message: ${error.result.message}`); 1322 | }); 1323 | const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; 1324 | if (!id_token) { 1325 | throw new Error('Response json body do not have ID Token field'); 1326 | } 1327 | return id_token; 1328 | }); 1329 | } 1330 | static getIDToken(audience) { 1331 | return __awaiter(this, void 0, void 0, function* () { 1332 | try { 1333 | // New ID Token is requested from action service 1334 | let id_token_url = OidcClient.getIDTokenUrl(); 1335 | if (audience) { 1336 | const encodedAudience = encodeURIComponent(audience); 1337 | id_token_url = `${id_token_url}&audience=${encodedAudience}`; 1338 | } 1339 | core_1.debug(`ID token url is ${id_token_url}`); 1340 | const id_token = yield OidcClient.getCall(id_token_url); 1341 | core_1.setSecret(id_token); 1342 | return id_token; 1343 | } 1344 | catch (error) { 1345 | throw new Error(`Error message: ${error.message}`); 1346 | } 1347 | }); 1348 | } 1349 | } 1350 | exports.OidcClient = OidcClient; 1351 | //# sourceMappingURL=oidc-utils.js.map 1352 | 1353 | /***/ }), 1354 | 1355 | /***/ 327: 1356 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 1357 | 1358 | "use strict"; 1359 | 1360 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 1361 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 1362 | return new (P || (P = Promise))(function (resolve, reject) { 1363 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 1364 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 1365 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 1366 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 1367 | }); 1368 | }; 1369 | Object.defineProperty(exports, "__esModule", ({ value: true })); 1370 | exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; 1371 | const os_1 = __nccwpck_require__(37); 1372 | const fs_1 = __nccwpck_require__(147); 1373 | const { access, appendFile, writeFile } = fs_1.promises; 1374 | exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; 1375 | exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; 1376 | class Summary { 1377 | constructor() { 1378 | this._buffer = ''; 1379 | } 1380 | /** 1381 | * Finds the summary file path from the environment, rejects if env var is not found or file does not exist 1382 | * Also checks r/w permissions. 1383 | * 1384 | * @returns step summary file path 1385 | */ 1386 | filePath() { 1387 | return __awaiter(this, void 0, void 0, function* () { 1388 | if (this._filePath) { 1389 | return this._filePath; 1390 | } 1391 | const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; 1392 | if (!pathFromEnv) { 1393 | throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); 1394 | } 1395 | try { 1396 | yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); 1397 | } 1398 | catch (_a) { 1399 | throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); 1400 | } 1401 | this._filePath = pathFromEnv; 1402 | return this._filePath; 1403 | }); 1404 | } 1405 | /** 1406 | * Wraps content in an HTML tag, adding any HTML attributes 1407 | * 1408 | * @param {string} tag HTML tag to wrap 1409 | * @param {string | null} content content within the tag 1410 | * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add 1411 | * 1412 | * @returns {string} content wrapped in HTML element 1413 | */ 1414 | wrap(tag, content, attrs = {}) { 1415 | const htmlAttrs = Object.entries(attrs) 1416 | .map(([key, value]) => ` ${key}="${value}"`) 1417 | .join(''); 1418 | if (!content) { 1419 | return `<${tag}${htmlAttrs}>`; 1420 | } 1421 | return `<${tag}${htmlAttrs}>${content}`; 1422 | } 1423 | /** 1424 | * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. 1425 | * 1426 | * @param {SummaryWriteOptions} [options] (optional) options for write operation 1427 | * 1428 | * @returns {Promise} summary instance 1429 | */ 1430 | write(options) { 1431 | return __awaiter(this, void 0, void 0, function* () { 1432 | const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); 1433 | const filePath = yield this.filePath(); 1434 | const writeFunc = overwrite ? writeFile : appendFile; 1435 | yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); 1436 | return this.emptyBuffer(); 1437 | }); 1438 | } 1439 | /** 1440 | * Clears the summary buffer and wipes the summary file 1441 | * 1442 | * @returns {Summary} summary instance 1443 | */ 1444 | clear() { 1445 | return __awaiter(this, void 0, void 0, function* () { 1446 | return this.emptyBuffer().write({ overwrite: true }); 1447 | }); 1448 | } 1449 | /** 1450 | * Returns the current summary buffer as a string 1451 | * 1452 | * @returns {string} string of summary buffer 1453 | */ 1454 | stringify() { 1455 | return this._buffer; 1456 | } 1457 | /** 1458 | * If the summary buffer is empty 1459 | * 1460 | * @returns {boolen} true if the buffer is empty 1461 | */ 1462 | isEmptyBuffer() { 1463 | return this._buffer.length === 0; 1464 | } 1465 | /** 1466 | * Resets the summary buffer without writing to summary file 1467 | * 1468 | * @returns {Summary} summary instance 1469 | */ 1470 | emptyBuffer() { 1471 | this._buffer = ''; 1472 | return this; 1473 | } 1474 | /** 1475 | * Adds raw text to the summary buffer 1476 | * 1477 | * @param {string} text content to add 1478 | * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) 1479 | * 1480 | * @returns {Summary} summary instance 1481 | */ 1482 | addRaw(text, addEOL = false) { 1483 | this._buffer += text; 1484 | return addEOL ? this.addEOL() : this; 1485 | } 1486 | /** 1487 | * Adds the operating system-specific end-of-line marker to the buffer 1488 | * 1489 | * @returns {Summary} summary instance 1490 | */ 1491 | addEOL() { 1492 | return this.addRaw(os_1.EOL); 1493 | } 1494 | /** 1495 | * Adds an HTML codeblock to the summary buffer 1496 | * 1497 | * @param {string} code content to render within fenced code block 1498 | * @param {string} lang (optional) language to syntax highlight code 1499 | * 1500 | * @returns {Summary} summary instance 1501 | */ 1502 | addCodeBlock(code, lang) { 1503 | const attrs = Object.assign({}, (lang && { lang })); 1504 | const element = this.wrap('pre', this.wrap('code', code), attrs); 1505 | return this.addRaw(element).addEOL(); 1506 | } 1507 | /** 1508 | * Adds an HTML list to the summary buffer 1509 | * 1510 | * @param {string[]} items list of items to render 1511 | * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) 1512 | * 1513 | * @returns {Summary} summary instance 1514 | */ 1515 | addList(items, ordered = false) { 1516 | const tag = ordered ? 'ol' : 'ul'; 1517 | const listItems = items.map(item => this.wrap('li', item)).join(''); 1518 | const element = this.wrap(tag, listItems); 1519 | return this.addRaw(element).addEOL(); 1520 | } 1521 | /** 1522 | * Adds an HTML table to the summary buffer 1523 | * 1524 | * @param {SummaryTableCell[]} rows table rows 1525 | * 1526 | * @returns {Summary} summary instance 1527 | */ 1528 | addTable(rows) { 1529 | const tableBody = rows 1530 | .map(row => { 1531 | const cells = row 1532 | .map(cell => { 1533 | if (typeof cell === 'string') { 1534 | return this.wrap('td', cell); 1535 | } 1536 | const { header, data, colspan, rowspan } = cell; 1537 | const tag = header ? 'th' : 'td'; 1538 | const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); 1539 | return this.wrap(tag, data, attrs); 1540 | }) 1541 | .join(''); 1542 | return this.wrap('tr', cells); 1543 | }) 1544 | .join(''); 1545 | const element = this.wrap('table', tableBody); 1546 | return this.addRaw(element).addEOL(); 1547 | } 1548 | /** 1549 | * Adds a collapsable HTML details element to the summary buffer 1550 | * 1551 | * @param {string} label text for the closed state 1552 | * @param {string} content collapsable content 1553 | * 1554 | * @returns {Summary} summary instance 1555 | */ 1556 | addDetails(label, content) { 1557 | const element = this.wrap('details', this.wrap('summary', label) + content); 1558 | return this.addRaw(element).addEOL(); 1559 | } 1560 | /** 1561 | * Adds an HTML image tag to the summary buffer 1562 | * 1563 | * @param {string} src path to the image you to embed 1564 | * @param {string} alt text description of the image 1565 | * @param {SummaryImageOptions} options (optional) addition image attributes 1566 | * 1567 | * @returns {Summary} summary instance 1568 | */ 1569 | addImage(src, alt, options) { 1570 | const { width, height } = options || {}; 1571 | const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); 1572 | const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); 1573 | return this.addRaw(element).addEOL(); 1574 | } 1575 | /** 1576 | * Adds an HTML section heading element 1577 | * 1578 | * @param {string} text heading text 1579 | * @param {number | string} [level=1] (optional) the heading level, default: 1 1580 | * 1581 | * @returns {Summary} summary instance 1582 | */ 1583 | addHeading(text, level) { 1584 | const tag = `h${level}`; 1585 | const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) 1586 | ? tag 1587 | : 'h1'; 1588 | const element = this.wrap(allowedTag, text); 1589 | return this.addRaw(element).addEOL(); 1590 | } 1591 | /** 1592 | * Adds an HTML thematic break (
) to the summary buffer 1593 | * 1594 | * @returns {Summary} summary instance 1595 | */ 1596 | addSeparator() { 1597 | const element = this.wrap('hr', null); 1598 | return this.addRaw(element).addEOL(); 1599 | } 1600 | /** 1601 | * Adds an HTML line break (
) to the summary buffer 1602 | * 1603 | * @returns {Summary} summary instance 1604 | */ 1605 | addBreak() { 1606 | const element = this.wrap('br', null); 1607 | return this.addRaw(element).addEOL(); 1608 | } 1609 | /** 1610 | * Adds an HTML blockquote to the summary buffer 1611 | * 1612 | * @param {string} text quote text 1613 | * @param {string} cite (optional) citation url 1614 | * 1615 | * @returns {Summary} summary instance 1616 | */ 1617 | addQuote(text, cite) { 1618 | const attrs = Object.assign({}, (cite && { cite })); 1619 | const element = this.wrap('blockquote', text, attrs); 1620 | return this.addRaw(element).addEOL(); 1621 | } 1622 | /** 1623 | * Adds an HTML anchor tag to the summary buffer 1624 | * 1625 | * @param {string} text link text/content 1626 | * @param {string} href hyperlink 1627 | * 1628 | * @returns {Summary} summary instance 1629 | */ 1630 | addLink(text, href) { 1631 | const element = this.wrap('a', text, { href }); 1632 | return this.addRaw(element).addEOL(); 1633 | } 1634 | } 1635 | const _summary = new Summary(); 1636 | /** 1637 | * @deprecated use `core.summary` 1638 | */ 1639 | exports.markdownSummary = _summary; 1640 | exports.summary = _summary; 1641 | //# sourceMappingURL=summary.js.map 1642 | 1643 | /***/ }), 1644 | 1645 | /***/ 278: 1646 | /***/ ((__unused_webpack_module, exports) => { 1647 | 1648 | "use strict"; 1649 | 1650 | // We use any as a valid input type 1651 | /* eslint-disable @typescript-eslint/no-explicit-any */ 1652 | Object.defineProperty(exports, "__esModule", ({ value: true })); 1653 | exports.toCommandProperties = exports.toCommandValue = void 0; 1654 | /** 1655 | * Sanitizes an input into a string so it can be passed into issueCommand safely 1656 | * @param input input to sanitize into a string 1657 | */ 1658 | function toCommandValue(input) { 1659 | if (input === null || input === undefined) { 1660 | return ''; 1661 | } 1662 | else if (typeof input === 'string' || input instanceof String) { 1663 | return input; 1664 | } 1665 | return JSON.stringify(input); 1666 | } 1667 | exports.toCommandValue = toCommandValue; 1668 | /** 1669 | * 1670 | * @param annotationProperties 1671 | * @returns The command properties to send with the actual annotation command 1672 | * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 1673 | */ 1674 | function toCommandProperties(annotationProperties) { 1675 | if (!Object.keys(annotationProperties).length) { 1676 | return {}; 1677 | } 1678 | return { 1679 | title: annotationProperties.title, 1680 | file: annotationProperties.file, 1681 | line: annotationProperties.startLine, 1682 | endLine: annotationProperties.endLine, 1683 | col: annotationProperties.startColumn, 1684 | endColumn: annotationProperties.endColumn 1685 | }; 1686 | } 1687 | exports.toCommandProperties = toCommandProperties; 1688 | //# sourceMappingURL=utils.js.map 1689 | 1690 | /***/ }), 1691 | 1692 | /***/ 526: 1693 | /***/ (function(__unused_webpack_module, exports) { 1694 | 1695 | "use strict"; 1696 | 1697 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 1698 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 1699 | return new (P || (P = Promise))(function (resolve, reject) { 1700 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 1701 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 1702 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 1703 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 1704 | }); 1705 | }; 1706 | Object.defineProperty(exports, "__esModule", ({ value: true })); 1707 | exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; 1708 | class BasicCredentialHandler { 1709 | constructor(username, password) { 1710 | this.username = username; 1711 | this.password = password; 1712 | } 1713 | prepareRequest(options) { 1714 | if (!options.headers) { 1715 | throw Error('The request has no headers'); 1716 | } 1717 | options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; 1718 | } 1719 | // This handler cannot handle 401 1720 | canHandleAuthentication() { 1721 | return false; 1722 | } 1723 | handleAuthentication() { 1724 | return __awaiter(this, void 0, void 0, function* () { 1725 | throw new Error('not implemented'); 1726 | }); 1727 | } 1728 | } 1729 | exports.BasicCredentialHandler = BasicCredentialHandler; 1730 | class BearerCredentialHandler { 1731 | constructor(token) { 1732 | this.token = token; 1733 | } 1734 | // currently implements pre-authorization 1735 | // TODO: support preAuth = false where it hooks on 401 1736 | prepareRequest(options) { 1737 | if (!options.headers) { 1738 | throw Error('The request has no headers'); 1739 | } 1740 | options.headers['Authorization'] = `Bearer ${this.token}`; 1741 | } 1742 | // This handler cannot handle 401 1743 | canHandleAuthentication() { 1744 | return false; 1745 | } 1746 | handleAuthentication() { 1747 | return __awaiter(this, void 0, void 0, function* () { 1748 | throw new Error('not implemented'); 1749 | }); 1750 | } 1751 | } 1752 | exports.BearerCredentialHandler = BearerCredentialHandler; 1753 | class PersonalAccessTokenCredentialHandler { 1754 | constructor(token) { 1755 | this.token = token; 1756 | } 1757 | // currently implements pre-authorization 1758 | // TODO: support preAuth = false where it hooks on 401 1759 | prepareRequest(options) { 1760 | if (!options.headers) { 1761 | throw Error('The request has no headers'); 1762 | } 1763 | options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; 1764 | } 1765 | // This handler cannot handle 401 1766 | canHandleAuthentication() { 1767 | return false; 1768 | } 1769 | handleAuthentication() { 1770 | return __awaiter(this, void 0, void 0, function* () { 1771 | throw new Error('not implemented'); 1772 | }); 1773 | } 1774 | } 1775 | exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; 1776 | //# sourceMappingURL=auth.js.map 1777 | 1778 | /***/ }), 1779 | 1780 | /***/ 255: 1781 | /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { 1782 | 1783 | "use strict"; 1784 | 1785 | /* eslint-disable @typescript-eslint/no-explicit-any */ 1786 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 1787 | if (k2 === undefined) k2 = k; 1788 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 1789 | }) : (function(o, m, k, k2) { 1790 | if (k2 === undefined) k2 = k; 1791 | o[k2] = m[k]; 1792 | })); 1793 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 1794 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 1795 | }) : function(o, v) { 1796 | o["default"] = v; 1797 | }); 1798 | var __importStar = (this && this.__importStar) || function (mod) { 1799 | if (mod && mod.__esModule) return mod; 1800 | var result = {}; 1801 | if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 1802 | __setModuleDefault(result, mod); 1803 | return result; 1804 | }; 1805 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 1806 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 1807 | return new (P || (P = Promise))(function (resolve, reject) { 1808 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 1809 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 1810 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 1811 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 1812 | }); 1813 | }; 1814 | Object.defineProperty(exports, "__esModule", ({ value: true })); 1815 | exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; 1816 | const http = __importStar(__nccwpck_require__(685)); 1817 | const https = __importStar(__nccwpck_require__(687)); 1818 | const pm = __importStar(__nccwpck_require__(835)); 1819 | const tunnel = __importStar(__nccwpck_require__(294)); 1820 | var HttpCodes; 1821 | (function (HttpCodes) { 1822 | HttpCodes[HttpCodes["OK"] = 200] = "OK"; 1823 | HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; 1824 | HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; 1825 | HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; 1826 | HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; 1827 | HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; 1828 | HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; 1829 | HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; 1830 | HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; 1831 | HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; 1832 | HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; 1833 | HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; 1834 | HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; 1835 | HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; 1836 | HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; 1837 | HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; 1838 | HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; 1839 | HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; 1840 | HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; 1841 | HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; 1842 | HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; 1843 | HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; 1844 | HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; 1845 | HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; 1846 | HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; 1847 | HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; 1848 | HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; 1849 | })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); 1850 | var Headers; 1851 | (function (Headers) { 1852 | Headers["Accept"] = "accept"; 1853 | Headers["ContentType"] = "content-type"; 1854 | })(Headers = exports.Headers || (exports.Headers = {})); 1855 | var MediaTypes; 1856 | (function (MediaTypes) { 1857 | MediaTypes["ApplicationJson"] = "application/json"; 1858 | })(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); 1859 | /** 1860 | * Returns the proxy URL, depending upon the supplied url and proxy environment variables. 1861 | * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com 1862 | */ 1863 | function getProxyUrl(serverUrl) { 1864 | const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); 1865 | return proxyUrl ? proxyUrl.href : ''; 1866 | } 1867 | exports.getProxyUrl = getProxyUrl; 1868 | const HttpRedirectCodes = [ 1869 | HttpCodes.MovedPermanently, 1870 | HttpCodes.ResourceMoved, 1871 | HttpCodes.SeeOther, 1872 | HttpCodes.TemporaryRedirect, 1873 | HttpCodes.PermanentRedirect 1874 | ]; 1875 | const HttpResponseRetryCodes = [ 1876 | HttpCodes.BadGateway, 1877 | HttpCodes.ServiceUnavailable, 1878 | HttpCodes.GatewayTimeout 1879 | ]; 1880 | const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; 1881 | const ExponentialBackoffCeiling = 10; 1882 | const ExponentialBackoffTimeSlice = 5; 1883 | class HttpClientError extends Error { 1884 | constructor(message, statusCode) { 1885 | super(message); 1886 | this.name = 'HttpClientError'; 1887 | this.statusCode = statusCode; 1888 | Object.setPrototypeOf(this, HttpClientError.prototype); 1889 | } 1890 | } 1891 | exports.HttpClientError = HttpClientError; 1892 | class HttpClientResponse { 1893 | constructor(message) { 1894 | this.message = message; 1895 | } 1896 | readBody() { 1897 | return __awaiter(this, void 0, void 0, function* () { 1898 | return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { 1899 | let output = Buffer.alloc(0); 1900 | this.message.on('data', (chunk) => { 1901 | output = Buffer.concat([output, chunk]); 1902 | }); 1903 | this.message.on('end', () => { 1904 | resolve(output.toString()); 1905 | }); 1906 | })); 1907 | }); 1908 | } 1909 | } 1910 | exports.HttpClientResponse = HttpClientResponse; 1911 | function isHttps(requestUrl) { 1912 | const parsedUrl = new URL(requestUrl); 1913 | return parsedUrl.protocol === 'https:'; 1914 | } 1915 | exports.isHttps = isHttps; 1916 | class HttpClient { 1917 | constructor(userAgent, handlers, requestOptions) { 1918 | this._ignoreSslError = false; 1919 | this._allowRedirects = true; 1920 | this._allowRedirectDowngrade = false; 1921 | this._maxRedirects = 50; 1922 | this._allowRetries = false; 1923 | this._maxRetries = 1; 1924 | this._keepAlive = false; 1925 | this._disposed = false; 1926 | this.userAgent = userAgent; 1927 | this.handlers = handlers || []; 1928 | this.requestOptions = requestOptions; 1929 | if (requestOptions) { 1930 | if (requestOptions.ignoreSslError != null) { 1931 | this._ignoreSslError = requestOptions.ignoreSslError; 1932 | } 1933 | this._socketTimeout = requestOptions.socketTimeout; 1934 | if (requestOptions.allowRedirects != null) { 1935 | this._allowRedirects = requestOptions.allowRedirects; 1936 | } 1937 | if (requestOptions.allowRedirectDowngrade != null) { 1938 | this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; 1939 | } 1940 | if (requestOptions.maxRedirects != null) { 1941 | this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); 1942 | } 1943 | if (requestOptions.keepAlive != null) { 1944 | this._keepAlive = requestOptions.keepAlive; 1945 | } 1946 | if (requestOptions.allowRetries != null) { 1947 | this._allowRetries = requestOptions.allowRetries; 1948 | } 1949 | if (requestOptions.maxRetries != null) { 1950 | this._maxRetries = requestOptions.maxRetries; 1951 | } 1952 | } 1953 | } 1954 | options(requestUrl, additionalHeaders) { 1955 | return __awaiter(this, void 0, void 0, function* () { 1956 | return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); 1957 | }); 1958 | } 1959 | get(requestUrl, additionalHeaders) { 1960 | return __awaiter(this, void 0, void 0, function* () { 1961 | return this.request('GET', requestUrl, null, additionalHeaders || {}); 1962 | }); 1963 | } 1964 | del(requestUrl, additionalHeaders) { 1965 | return __awaiter(this, void 0, void 0, function* () { 1966 | return this.request('DELETE', requestUrl, null, additionalHeaders || {}); 1967 | }); 1968 | } 1969 | post(requestUrl, data, additionalHeaders) { 1970 | return __awaiter(this, void 0, void 0, function* () { 1971 | return this.request('POST', requestUrl, data, additionalHeaders || {}); 1972 | }); 1973 | } 1974 | patch(requestUrl, data, additionalHeaders) { 1975 | return __awaiter(this, void 0, void 0, function* () { 1976 | return this.request('PATCH', requestUrl, data, additionalHeaders || {}); 1977 | }); 1978 | } 1979 | put(requestUrl, data, additionalHeaders) { 1980 | return __awaiter(this, void 0, void 0, function* () { 1981 | return this.request('PUT', requestUrl, data, additionalHeaders || {}); 1982 | }); 1983 | } 1984 | head(requestUrl, additionalHeaders) { 1985 | return __awaiter(this, void 0, void 0, function* () { 1986 | return this.request('HEAD', requestUrl, null, additionalHeaders || {}); 1987 | }); 1988 | } 1989 | sendStream(verb, requestUrl, stream, additionalHeaders) { 1990 | return __awaiter(this, void 0, void 0, function* () { 1991 | return this.request(verb, requestUrl, stream, additionalHeaders); 1992 | }); 1993 | } 1994 | /** 1995 | * Gets a typed object from an endpoint 1996 | * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise 1997 | */ 1998 | getJson(requestUrl, additionalHeaders = {}) { 1999 | return __awaiter(this, void 0, void 0, function* () { 2000 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 2001 | const res = yield this.get(requestUrl, additionalHeaders); 2002 | return this._processResponse(res, this.requestOptions); 2003 | }); 2004 | } 2005 | postJson(requestUrl, obj, additionalHeaders = {}) { 2006 | return __awaiter(this, void 0, void 0, function* () { 2007 | const data = JSON.stringify(obj, null, 2); 2008 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 2009 | additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 2010 | const res = yield this.post(requestUrl, data, additionalHeaders); 2011 | return this._processResponse(res, this.requestOptions); 2012 | }); 2013 | } 2014 | putJson(requestUrl, obj, additionalHeaders = {}) { 2015 | return __awaiter(this, void 0, void 0, function* () { 2016 | const data = JSON.stringify(obj, null, 2); 2017 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 2018 | additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 2019 | const res = yield this.put(requestUrl, data, additionalHeaders); 2020 | return this._processResponse(res, this.requestOptions); 2021 | }); 2022 | } 2023 | patchJson(requestUrl, obj, additionalHeaders = {}) { 2024 | return __awaiter(this, void 0, void 0, function* () { 2025 | const data = JSON.stringify(obj, null, 2); 2026 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 2027 | additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 2028 | const res = yield this.patch(requestUrl, data, additionalHeaders); 2029 | return this._processResponse(res, this.requestOptions); 2030 | }); 2031 | } 2032 | /** 2033 | * Makes a raw http request. 2034 | * All other methods such as get, post, patch, and request ultimately call this. 2035 | * Prefer get, del, post and patch 2036 | */ 2037 | request(verb, requestUrl, data, headers) { 2038 | return __awaiter(this, void 0, void 0, function* () { 2039 | if (this._disposed) { 2040 | throw new Error('Client has already been disposed.'); 2041 | } 2042 | const parsedUrl = new URL(requestUrl); 2043 | let info = this._prepareRequest(verb, parsedUrl, headers); 2044 | // Only perform retries on reads since writes may not be idempotent. 2045 | const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) 2046 | ? this._maxRetries + 1 2047 | : 1; 2048 | let numTries = 0; 2049 | let response; 2050 | do { 2051 | response = yield this.requestRaw(info, data); 2052 | // Check if it's an authentication challenge 2053 | if (response && 2054 | response.message && 2055 | response.message.statusCode === HttpCodes.Unauthorized) { 2056 | let authenticationHandler; 2057 | for (const handler of this.handlers) { 2058 | if (handler.canHandleAuthentication(response)) { 2059 | authenticationHandler = handler; 2060 | break; 2061 | } 2062 | } 2063 | if (authenticationHandler) { 2064 | return authenticationHandler.handleAuthentication(this, info, data); 2065 | } 2066 | else { 2067 | // We have received an unauthorized response but have no handlers to handle it. 2068 | // Let the response return to the caller. 2069 | return response; 2070 | } 2071 | } 2072 | let redirectsRemaining = this._maxRedirects; 2073 | while (response.message.statusCode && 2074 | HttpRedirectCodes.includes(response.message.statusCode) && 2075 | this._allowRedirects && 2076 | redirectsRemaining > 0) { 2077 | const redirectUrl = response.message.headers['location']; 2078 | if (!redirectUrl) { 2079 | // if there's no location to redirect to, we won't 2080 | break; 2081 | } 2082 | const parsedRedirectUrl = new URL(redirectUrl); 2083 | if (parsedUrl.protocol === 'https:' && 2084 | parsedUrl.protocol !== parsedRedirectUrl.protocol && 2085 | !this._allowRedirectDowngrade) { 2086 | throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); 2087 | } 2088 | // we need to finish reading the response before reassigning response 2089 | // which will leak the open socket. 2090 | yield response.readBody(); 2091 | // strip authorization header if redirected to a different hostname 2092 | if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { 2093 | for (const header in headers) { 2094 | // header names are case insensitive 2095 | if (header.toLowerCase() === 'authorization') { 2096 | delete headers[header]; 2097 | } 2098 | } 2099 | } 2100 | // let's make the request with the new redirectUrl 2101 | info = this._prepareRequest(verb, parsedRedirectUrl, headers); 2102 | response = yield this.requestRaw(info, data); 2103 | redirectsRemaining--; 2104 | } 2105 | if (!response.message.statusCode || 2106 | !HttpResponseRetryCodes.includes(response.message.statusCode)) { 2107 | // If not a retry code, return immediately instead of retrying 2108 | return response; 2109 | } 2110 | numTries += 1; 2111 | if (numTries < maxTries) { 2112 | yield response.readBody(); 2113 | yield this._performExponentialBackoff(numTries); 2114 | } 2115 | } while (numTries < maxTries); 2116 | return response; 2117 | }); 2118 | } 2119 | /** 2120 | * Needs to be called if keepAlive is set to true in request options. 2121 | */ 2122 | dispose() { 2123 | if (this._agent) { 2124 | this._agent.destroy(); 2125 | } 2126 | this._disposed = true; 2127 | } 2128 | /** 2129 | * Raw request. 2130 | * @param info 2131 | * @param data 2132 | */ 2133 | requestRaw(info, data) { 2134 | return __awaiter(this, void 0, void 0, function* () { 2135 | return new Promise((resolve, reject) => { 2136 | function callbackForResult(err, res) { 2137 | if (err) { 2138 | reject(err); 2139 | } 2140 | else if (!res) { 2141 | // If `err` is not passed, then `res` must be passed. 2142 | reject(new Error('Unknown error')); 2143 | } 2144 | else { 2145 | resolve(res); 2146 | } 2147 | } 2148 | this.requestRawWithCallback(info, data, callbackForResult); 2149 | }); 2150 | }); 2151 | } 2152 | /** 2153 | * Raw request with callback. 2154 | * @param info 2155 | * @param data 2156 | * @param onResult 2157 | */ 2158 | requestRawWithCallback(info, data, onResult) { 2159 | if (typeof data === 'string') { 2160 | if (!info.options.headers) { 2161 | info.options.headers = {}; 2162 | } 2163 | info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); 2164 | } 2165 | let callbackCalled = false; 2166 | function handleResult(err, res) { 2167 | if (!callbackCalled) { 2168 | callbackCalled = true; 2169 | onResult(err, res); 2170 | } 2171 | } 2172 | const req = info.httpModule.request(info.options, (msg) => { 2173 | const res = new HttpClientResponse(msg); 2174 | handleResult(undefined, res); 2175 | }); 2176 | let socket; 2177 | req.on('socket', sock => { 2178 | socket = sock; 2179 | }); 2180 | // If we ever get disconnected, we want the socket to timeout eventually 2181 | req.setTimeout(this._socketTimeout || 3 * 60000, () => { 2182 | if (socket) { 2183 | socket.end(); 2184 | } 2185 | handleResult(new Error(`Request timeout: ${info.options.path}`)); 2186 | }); 2187 | req.on('error', function (err) { 2188 | // err has statusCode property 2189 | // res should have headers 2190 | handleResult(err); 2191 | }); 2192 | if (data && typeof data === 'string') { 2193 | req.write(data, 'utf8'); 2194 | } 2195 | if (data && typeof data !== 'string') { 2196 | data.on('close', function () { 2197 | req.end(); 2198 | }); 2199 | data.pipe(req); 2200 | } 2201 | else { 2202 | req.end(); 2203 | } 2204 | } 2205 | /** 2206 | * Gets an http agent. This function is useful when you need an http agent that handles 2207 | * routing through a proxy server - depending upon the url and proxy environment variables. 2208 | * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com 2209 | */ 2210 | getAgent(serverUrl) { 2211 | const parsedUrl = new URL(serverUrl); 2212 | return this._getAgent(parsedUrl); 2213 | } 2214 | _prepareRequest(method, requestUrl, headers) { 2215 | const info = {}; 2216 | info.parsedUrl = requestUrl; 2217 | const usingSsl = info.parsedUrl.protocol === 'https:'; 2218 | info.httpModule = usingSsl ? https : http; 2219 | const defaultPort = usingSsl ? 443 : 80; 2220 | info.options = {}; 2221 | info.options.host = info.parsedUrl.hostname; 2222 | info.options.port = info.parsedUrl.port 2223 | ? parseInt(info.parsedUrl.port) 2224 | : defaultPort; 2225 | info.options.path = 2226 | (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); 2227 | info.options.method = method; 2228 | info.options.headers = this._mergeHeaders(headers); 2229 | if (this.userAgent != null) { 2230 | info.options.headers['user-agent'] = this.userAgent; 2231 | } 2232 | info.options.agent = this._getAgent(info.parsedUrl); 2233 | // gives handlers an opportunity to participate 2234 | if (this.handlers) { 2235 | for (const handler of this.handlers) { 2236 | handler.prepareRequest(info.options); 2237 | } 2238 | } 2239 | return info; 2240 | } 2241 | _mergeHeaders(headers) { 2242 | if (this.requestOptions && this.requestOptions.headers) { 2243 | return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); 2244 | } 2245 | return lowercaseKeys(headers || {}); 2246 | } 2247 | _getExistingOrDefaultHeader(additionalHeaders, header, _default) { 2248 | let clientHeader; 2249 | if (this.requestOptions && this.requestOptions.headers) { 2250 | clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; 2251 | } 2252 | return additionalHeaders[header] || clientHeader || _default; 2253 | } 2254 | _getAgent(parsedUrl) { 2255 | let agent; 2256 | const proxyUrl = pm.getProxyUrl(parsedUrl); 2257 | const useProxy = proxyUrl && proxyUrl.hostname; 2258 | if (this._keepAlive && useProxy) { 2259 | agent = this._proxyAgent; 2260 | } 2261 | if (this._keepAlive && !useProxy) { 2262 | agent = this._agent; 2263 | } 2264 | // if agent is already assigned use that agent. 2265 | if (agent) { 2266 | return agent; 2267 | } 2268 | const usingSsl = parsedUrl.protocol === 'https:'; 2269 | let maxSockets = 100; 2270 | if (this.requestOptions) { 2271 | maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; 2272 | } 2273 | // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. 2274 | if (proxyUrl && proxyUrl.hostname) { 2275 | const agentOptions = { 2276 | maxSockets, 2277 | keepAlive: this._keepAlive, 2278 | proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { 2279 | proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` 2280 | })), { host: proxyUrl.hostname, port: proxyUrl.port }) 2281 | }; 2282 | let tunnelAgent; 2283 | const overHttps = proxyUrl.protocol === 'https:'; 2284 | if (usingSsl) { 2285 | tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; 2286 | } 2287 | else { 2288 | tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; 2289 | } 2290 | agent = tunnelAgent(agentOptions); 2291 | this._proxyAgent = agent; 2292 | } 2293 | // if reusing agent across request and tunneling agent isn't assigned create a new agent 2294 | if (this._keepAlive && !agent) { 2295 | const options = { keepAlive: this._keepAlive, maxSockets }; 2296 | agent = usingSsl ? new https.Agent(options) : new http.Agent(options); 2297 | this._agent = agent; 2298 | } 2299 | // if not using private agent and tunnel agent isn't setup then use global agent 2300 | if (!agent) { 2301 | agent = usingSsl ? https.globalAgent : http.globalAgent; 2302 | } 2303 | if (usingSsl && this._ignoreSslError) { 2304 | // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process 2305 | // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options 2306 | // we have to cast it to any and change it directly 2307 | agent.options = Object.assign(agent.options || {}, { 2308 | rejectUnauthorized: false 2309 | }); 2310 | } 2311 | return agent; 2312 | } 2313 | _performExponentialBackoff(retryNumber) { 2314 | return __awaiter(this, void 0, void 0, function* () { 2315 | retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); 2316 | const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); 2317 | return new Promise(resolve => setTimeout(() => resolve(), ms)); 2318 | }); 2319 | } 2320 | _processResponse(res, options) { 2321 | return __awaiter(this, void 0, void 0, function* () { 2322 | return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { 2323 | const statusCode = res.message.statusCode || 0; 2324 | const response = { 2325 | statusCode, 2326 | result: null, 2327 | headers: {} 2328 | }; 2329 | // not found leads to null obj returned 2330 | if (statusCode === HttpCodes.NotFound) { 2331 | resolve(response); 2332 | } 2333 | // get the result from the body 2334 | function dateTimeDeserializer(key, value) { 2335 | if (typeof value === 'string') { 2336 | const a = new Date(value); 2337 | if (!isNaN(a.valueOf())) { 2338 | return a; 2339 | } 2340 | } 2341 | return value; 2342 | } 2343 | let obj; 2344 | let contents; 2345 | try { 2346 | contents = yield res.readBody(); 2347 | if (contents && contents.length > 0) { 2348 | if (options && options.deserializeDates) { 2349 | obj = JSON.parse(contents, dateTimeDeserializer); 2350 | } 2351 | else { 2352 | obj = JSON.parse(contents); 2353 | } 2354 | response.result = obj; 2355 | } 2356 | response.headers = res.message.headers; 2357 | } 2358 | catch (err) { 2359 | // Invalid resource (contents not json); leaving result obj null 2360 | } 2361 | // note that 3xx redirects are handled by the http layer. 2362 | if (statusCode > 299) { 2363 | let msg; 2364 | // if exception/error in body, attempt to get better error 2365 | if (obj && obj.message) { 2366 | msg = obj.message; 2367 | } 2368 | else if (contents && contents.length > 0) { 2369 | // it may be the case that the exception is in the body message as string 2370 | msg = contents; 2371 | } 2372 | else { 2373 | msg = `Failed request: (${statusCode})`; 2374 | } 2375 | const err = new HttpClientError(msg, statusCode); 2376 | err.result = response.result; 2377 | reject(err); 2378 | } 2379 | else { 2380 | resolve(response); 2381 | } 2382 | })); 2383 | }); 2384 | } 2385 | } 2386 | exports.HttpClient = HttpClient; 2387 | const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); 2388 | //# sourceMappingURL=index.js.map 2389 | 2390 | /***/ }), 2391 | 2392 | /***/ 835: 2393 | /***/ ((__unused_webpack_module, exports) => { 2394 | 2395 | "use strict"; 2396 | 2397 | Object.defineProperty(exports, "__esModule", ({ value: true })); 2398 | exports.checkBypass = exports.getProxyUrl = void 0; 2399 | function getProxyUrl(reqUrl) { 2400 | const usingSsl = reqUrl.protocol === 'https:'; 2401 | if (checkBypass(reqUrl)) { 2402 | return undefined; 2403 | } 2404 | const proxyVar = (() => { 2405 | if (usingSsl) { 2406 | return process.env['https_proxy'] || process.env['HTTPS_PROXY']; 2407 | } 2408 | else { 2409 | return process.env['http_proxy'] || process.env['HTTP_PROXY']; 2410 | } 2411 | })(); 2412 | if (proxyVar) { 2413 | return new URL(proxyVar); 2414 | } 2415 | else { 2416 | return undefined; 2417 | } 2418 | } 2419 | exports.getProxyUrl = getProxyUrl; 2420 | function checkBypass(reqUrl) { 2421 | if (!reqUrl.hostname) { 2422 | return false; 2423 | } 2424 | const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; 2425 | if (!noProxy) { 2426 | return false; 2427 | } 2428 | // Determine the request port 2429 | let reqPort; 2430 | if (reqUrl.port) { 2431 | reqPort = Number(reqUrl.port); 2432 | } 2433 | else if (reqUrl.protocol === 'http:') { 2434 | reqPort = 80; 2435 | } 2436 | else if (reqUrl.protocol === 'https:') { 2437 | reqPort = 443; 2438 | } 2439 | // Format the request hostname and hostname with port 2440 | const upperReqHosts = [reqUrl.hostname.toUpperCase()]; 2441 | if (typeof reqPort === 'number') { 2442 | upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); 2443 | } 2444 | // Compare request host against noproxy 2445 | for (const upperNoProxyItem of noProxy 2446 | .split(',') 2447 | .map(x => x.trim().toUpperCase()) 2448 | .filter(x => x)) { 2449 | if (upperReqHosts.some(x => x === upperNoProxyItem)) { 2450 | return true; 2451 | } 2452 | } 2453 | return false; 2454 | } 2455 | exports.checkBypass = checkBypass; 2456 | //# sourceMappingURL=proxy.js.map 2457 | 2458 | /***/ }), 2459 | 2460 | /***/ 294: 2461 | /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { 2462 | 2463 | module.exports = __nccwpck_require__(219); 2464 | 2465 | 2466 | /***/ }), 2467 | 2468 | /***/ 219: 2469 | /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { 2470 | 2471 | "use strict"; 2472 | 2473 | 2474 | var net = __nccwpck_require__(808); 2475 | var tls = __nccwpck_require__(404); 2476 | var http = __nccwpck_require__(685); 2477 | var https = __nccwpck_require__(687); 2478 | var events = __nccwpck_require__(361); 2479 | var assert = __nccwpck_require__(491); 2480 | var util = __nccwpck_require__(837); 2481 | 2482 | 2483 | exports.httpOverHttp = httpOverHttp; 2484 | exports.httpsOverHttp = httpsOverHttp; 2485 | exports.httpOverHttps = httpOverHttps; 2486 | exports.httpsOverHttps = httpsOverHttps; 2487 | 2488 | 2489 | function httpOverHttp(options) { 2490 | var agent = new TunnelingAgent(options); 2491 | agent.request = http.request; 2492 | return agent; 2493 | } 2494 | 2495 | function httpsOverHttp(options) { 2496 | var agent = new TunnelingAgent(options); 2497 | agent.request = http.request; 2498 | agent.createSocket = createSecureSocket; 2499 | agent.defaultPort = 443; 2500 | return agent; 2501 | } 2502 | 2503 | function httpOverHttps(options) { 2504 | var agent = new TunnelingAgent(options); 2505 | agent.request = https.request; 2506 | return agent; 2507 | } 2508 | 2509 | function httpsOverHttps(options) { 2510 | var agent = new TunnelingAgent(options); 2511 | agent.request = https.request; 2512 | agent.createSocket = createSecureSocket; 2513 | agent.defaultPort = 443; 2514 | return agent; 2515 | } 2516 | 2517 | 2518 | function TunnelingAgent(options) { 2519 | var self = this; 2520 | self.options = options || {}; 2521 | self.proxyOptions = self.options.proxy || {}; 2522 | self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; 2523 | self.requests = []; 2524 | self.sockets = []; 2525 | 2526 | self.on('free', function onFree(socket, host, port, localAddress) { 2527 | var options = toOptions(host, port, localAddress); 2528 | for (var i = 0, len = self.requests.length; i < len; ++i) { 2529 | var pending = self.requests[i]; 2530 | if (pending.host === options.host && pending.port === options.port) { 2531 | // Detect the request to connect same origin server, 2532 | // reuse the connection. 2533 | self.requests.splice(i, 1); 2534 | pending.request.onSocket(socket); 2535 | return; 2536 | } 2537 | } 2538 | socket.destroy(); 2539 | self.removeSocket(socket); 2540 | }); 2541 | } 2542 | util.inherits(TunnelingAgent, events.EventEmitter); 2543 | 2544 | TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { 2545 | var self = this; 2546 | var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); 2547 | 2548 | if (self.sockets.length >= this.maxSockets) { 2549 | // We are over limit so we'll add it to the queue. 2550 | self.requests.push(options); 2551 | return; 2552 | } 2553 | 2554 | // If we are under maxSockets create a new one. 2555 | self.createSocket(options, function(socket) { 2556 | socket.on('free', onFree); 2557 | socket.on('close', onCloseOrRemove); 2558 | socket.on('agentRemove', onCloseOrRemove); 2559 | req.onSocket(socket); 2560 | 2561 | function onFree() { 2562 | self.emit('free', socket, options); 2563 | } 2564 | 2565 | function onCloseOrRemove(err) { 2566 | self.removeSocket(socket); 2567 | socket.removeListener('free', onFree); 2568 | socket.removeListener('close', onCloseOrRemove); 2569 | socket.removeListener('agentRemove', onCloseOrRemove); 2570 | } 2571 | }); 2572 | }; 2573 | 2574 | TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { 2575 | var self = this; 2576 | var placeholder = {}; 2577 | self.sockets.push(placeholder); 2578 | 2579 | var connectOptions = mergeOptions({}, self.proxyOptions, { 2580 | method: 'CONNECT', 2581 | path: options.host + ':' + options.port, 2582 | agent: false, 2583 | headers: { 2584 | host: options.host + ':' + options.port 2585 | } 2586 | }); 2587 | if (options.localAddress) { 2588 | connectOptions.localAddress = options.localAddress; 2589 | } 2590 | if (connectOptions.proxyAuth) { 2591 | connectOptions.headers = connectOptions.headers || {}; 2592 | connectOptions.headers['Proxy-Authorization'] = 'Basic ' + 2593 | new Buffer(connectOptions.proxyAuth).toString('base64'); 2594 | } 2595 | 2596 | debug('making CONNECT request'); 2597 | var connectReq = self.request(connectOptions); 2598 | connectReq.useChunkedEncodingByDefault = false; // for v0.6 2599 | connectReq.once('response', onResponse); // for v0.6 2600 | connectReq.once('upgrade', onUpgrade); // for v0.6 2601 | connectReq.once('connect', onConnect); // for v0.7 or later 2602 | connectReq.once('error', onError); 2603 | connectReq.end(); 2604 | 2605 | function onResponse(res) { 2606 | // Very hacky. This is necessary to avoid http-parser leaks. 2607 | res.upgrade = true; 2608 | } 2609 | 2610 | function onUpgrade(res, socket, head) { 2611 | // Hacky. 2612 | process.nextTick(function() { 2613 | onConnect(res, socket, head); 2614 | }); 2615 | } 2616 | 2617 | function onConnect(res, socket, head) { 2618 | connectReq.removeAllListeners(); 2619 | socket.removeAllListeners(); 2620 | 2621 | if (res.statusCode !== 200) { 2622 | debug('tunneling socket could not be established, statusCode=%d', 2623 | res.statusCode); 2624 | socket.destroy(); 2625 | var error = new Error('tunneling socket could not be established, ' + 2626 | 'statusCode=' + res.statusCode); 2627 | error.code = 'ECONNRESET'; 2628 | options.request.emit('error', error); 2629 | self.removeSocket(placeholder); 2630 | return; 2631 | } 2632 | if (head.length > 0) { 2633 | debug('got illegal response body from proxy'); 2634 | socket.destroy(); 2635 | var error = new Error('got illegal response body from proxy'); 2636 | error.code = 'ECONNRESET'; 2637 | options.request.emit('error', error); 2638 | self.removeSocket(placeholder); 2639 | return; 2640 | } 2641 | debug('tunneling connection has established'); 2642 | self.sockets[self.sockets.indexOf(placeholder)] = socket; 2643 | return cb(socket); 2644 | } 2645 | 2646 | function onError(cause) { 2647 | connectReq.removeAllListeners(); 2648 | 2649 | debug('tunneling socket could not be established, cause=%s\n', 2650 | cause.message, cause.stack); 2651 | var error = new Error('tunneling socket could not be established, ' + 2652 | 'cause=' + cause.message); 2653 | error.code = 'ECONNRESET'; 2654 | options.request.emit('error', error); 2655 | self.removeSocket(placeholder); 2656 | } 2657 | }; 2658 | 2659 | TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { 2660 | var pos = this.sockets.indexOf(socket) 2661 | if (pos === -1) { 2662 | return; 2663 | } 2664 | this.sockets.splice(pos, 1); 2665 | 2666 | var pending = this.requests.shift(); 2667 | if (pending) { 2668 | // If we have pending requests and a socket gets closed a new one 2669 | // needs to be created to take over in the pool for the one that closed. 2670 | this.createSocket(pending, function(socket) { 2671 | pending.request.onSocket(socket); 2672 | }); 2673 | } 2674 | }; 2675 | 2676 | function createSecureSocket(options, cb) { 2677 | var self = this; 2678 | TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { 2679 | var hostHeader = options.request.getHeader('host'); 2680 | var tlsOptions = mergeOptions({}, self.options, { 2681 | socket: socket, 2682 | servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host 2683 | }); 2684 | 2685 | // 0 is dummy port for v0.6 2686 | var secureSocket = tls.connect(0, tlsOptions); 2687 | self.sockets[self.sockets.indexOf(socket)] = secureSocket; 2688 | cb(secureSocket); 2689 | }); 2690 | } 2691 | 2692 | 2693 | function toOptions(host, port, localAddress) { 2694 | if (typeof host === 'string') { // since v0.10 2695 | return { 2696 | host: host, 2697 | port: port, 2698 | localAddress: localAddress 2699 | }; 2700 | } 2701 | return host; // for v0.11 or later 2702 | } 2703 | 2704 | function mergeOptions(target) { 2705 | for (var i = 1, len = arguments.length; i < len; ++i) { 2706 | var overrides = arguments[i]; 2707 | if (typeof overrides === 'object') { 2708 | var keys = Object.keys(overrides); 2709 | for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { 2710 | var k = keys[j]; 2711 | if (overrides[k] !== undefined) { 2712 | target[k] = overrides[k]; 2713 | } 2714 | } 2715 | } 2716 | } 2717 | return target; 2718 | } 2719 | 2720 | 2721 | var debug; 2722 | if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { 2723 | debug = function() { 2724 | var args = Array.prototype.slice.call(arguments); 2725 | if (typeof args[0] === 'string') { 2726 | args[0] = 'TUNNEL: ' + args[0]; 2727 | } else { 2728 | args.unshift('TUNNEL:'); 2729 | } 2730 | console.error.apply(console, args); 2731 | } 2732 | } else { 2733 | debug = function() {}; 2734 | } 2735 | exports.debug = debug; // for test 2736 | 2737 | 2738 | /***/ }), 2739 | 2740 | /***/ 491: 2741 | /***/ ((module) => { 2742 | 2743 | "use strict"; 2744 | module.exports = require("assert"); 2745 | 2746 | /***/ }), 2747 | 2748 | /***/ 361: 2749 | /***/ ((module) => { 2750 | 2751 | "use strict"; 2752 | module.exports = require("events"); 2753 | 2754 | /***/ }), 2755 | 2756 | /***/ 147: 2757 | /***/ ((module) => { 2758 | 2759 | "use strict"; 2760 | module.exports = require("fs"); 2761 | 2762 | /***/ }), 2763 | 2764 | /***/ 685: 2765 | /***/ ((module) => { 2766 | 2767 | "use strict"; 2768 | module.exports = require("http"); 2769 | 2770 | /***/ }), 2771 | 2772 | /***/ 687: 2773 | /***/ ((module) => { 2774 | 2775 | "use strict"; 2776 | module.exports = require("https"); 2777 | 2778 | /***/ }), 2779 | 2780 | /***/ 808: 2781 | /***/ ((module) => { 2782 | 2783 | "use strict"; 2784 | module.exports = require("net"); 2785 | 2786 | /***/ }), 2787 | 2788 | /***/ 37: 2789 | /***/ ((module) => { 2790 | 2791 | "use strict"; 2792 | module.exports = require("os"); 2793 | 2794 | /***/ }), 2795 | 2796 | /***/ 17: 2797 | /***/ ((module) => { 2798 | 2799 | "use strict"; 2800 | module.exports = require("path"); 2801 | 2802 | /***/ }), 2803 | 2804 | /***/ 404: 2805 | /***/ ((module) => { 2806 | 2807 | "use strict"; 2808 | module.exports = require("tls"); 2809 | 2810 | /***/ }), 2811 | 2812 | /***/ 837: 2813 | /***/ ((module) => { 2814 | 2815 | "use strict"; 2816 | module.exports = require("util"); 2817 | 2818 | /***/ }) 2819 | 2820 | /******/ }); 2821 | /************************************************************************/ 2822 | /******/ // The module cache 2823 | /******/ var __webpack_module_cache__ = {}; 2824 | /******/ 2825 | /******/ // The require function 2826 | /******/ function __nccwpck_require__(moduleId) { 2827 | /******/ // Check if module is in cache 2828 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 2829 | /******/ if (cachedModule !== undefined) { 2830 | /******/ return cachedModule.exports; 2831 | /******/ } 2832 | /******/ // Create a new module (and put it into the cache) 2833 | /******/ var module = __webpack_module_cache__[moduleId] = { 2834 | /******/ // no module.id needed 2835 | /******/ // no module.loaded needed 2836 | /******/ exports: {} 2837 | /******/ }; 2838 | /******/ 2839 | /******/ // Execute the module function 2840 | /******/ var threw = true; 2841 | /******/ try { 2842 | /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__); 2843 | /******/ threw = false; 2844 | /******/ } finally { 2845 | /******/ if(threw) delete __webpack_module_cache__[moduleId]; 2846 | /******/ } 2847 | /******/ 2848 | /******/ // Return the exports of the module 2849 | /******/ return module.exports; 2850 | /******/ } 2851 | /******/ 2852 | /************************************************************************/ 2853 | /******/ /* webpack/runtime/compat */ 2854 | /******/ 2855 | /******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/"; 2856 | /******/ 2857 | /************************************************************************/ 2858 | /******/ 2859 | /******/ // startup 2860 | /******/ // Load entry module and return exports 2861 | /******/ // This entry module is referenced by other modules so it can't be inlined 2862 | /******/ var __webpack_exports__ = __nccwpck_require__(823); 2863 | /******/ module.exports = __webpack_exports__; 2864 | /******/ 2865 | /******/ })() 2866 | ; -------------------------------------------------------------------------------- /images/extension-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/store-submission/4da7b7621e16b0b7584303180fbe27b009c6b213/images/extension-icon.png -------------------------------------------------------------------------------- /lib/azure_devops_task.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | const tl = require("azure-pipelines-task-lib/task"); 13 | const store_apis_1 = require("./store_apis"); 14 | (function main() { 15 | return __awaiter(this, void 0, void 0, function* () { 16 | const storeApis = new store_apis_1.StoreApis(); 17 | try { 18 | const command = tl.getInput("command"); 19 | switch (command) { 20 | case "configure": { 21 | storeApis.productId = tl.getInput("productId") || ""; 22 | storeApis.sellerId = tl.getInput("sellerId") || ""; 23 | storeApis.tenantId = tl.getInput("tenantId") || ""; 24 | storeApis.clientId = tl.getInput("clientId") || ""; 25 | storeApis.clientSecret = tl.getInput("clientSecret") || ""; 26 | yield storeApis.InitAsync(); 27 | tl.setVariable(`${store_apis_1.EnvVariablePrefix}product_id`, storeApis.productId, true, true); 28 | tl.setVariable(`${store_apis_1.EnvVariablePrefix}seller_id`, storeApis.sellerId, true, true); 29 | tl.setVariable(`${store_apis_1.EnvVariablePrefix}tenant_id`, storeApis.tenantId, true, true); 30 | tl.setVariable(`${store_apis_1.EnvVariablePrefix}client_id`, storeApis.clientId, true, true); 31 | tl.setVariable(`${store_apis_1.EnvVariablePrefix}client_secret`, storeApis.clientSecret, true, true); 32 | tl.setVariable(`${store_apis_1.EnvVariablePrefix}access_token`, storeApis.accessToken, true, true); 33 | break; 34 | } 35 | case "get": { 36 | const moduleName = tl.getInput("moduleName") || ""; 37 | const listingLanguage = tl.getInput("listingLanguage") || "en"; 38 | const draftSubmission = yield storeApis.GetExistingDraft(moduleName, listingLanguage); 39 | tl.setVariable("draftSubmission", draftSubmission.toString()); 40 | break; 41 | } 42 | case "update": { 43 | const updatedMetadataString = tl.getInput("metadataUpdate"); 44 | const updatedProductString = tl.getInput("productUpdate"); 45 | if (!updatedMetadataString && !updatedProductString) { 46 | tl.setResult(tl.TaskResult.Failed, `Nothing to update. Both product-update and metadata-update are null.`); 47 | return; 48 | } 49 | if (updatedMetadataString) { 50 | const updateSubmissionMetadata = yield storeApis.UpdateSubmissionMetadata(updatedMetadataString); 51 | console.log(updateSubmissionMetadata); 52 | } 53 | if (updatedProductString) { 54 | const updateSubmissionData = yield storeApis.UpdateProductPackages(updatedProductString); 55 | console.log(updateSubmissionData); 56 | } 57 | break; 58 | } 59 | case "poll": { 60 | const pollingSubmissionId = tl.getInput("pollingSubmissionId"); 61 | if (!pollingSubmissionId) { 62 | tl.setResult(tl.TaskResult.Failed, `pollingSubmissionId parameter cannot be empty.`); 63 | return; 64 | } 65 | const publishingStatus = yield storeApis.PollSubmissionStatus(pollingSubmissionId); 66 | tl.setVariable("submissionStatus", publishingStatus); 67 | break; 68 | } 69 | case "publish": { 70 | const submissionId = yield storeApis.PublishSubmission(); 71 | tl.setVariable("pollingSubmissionId", submissionId); 72 | break; 73 | } 74 | default: { 75 | tl.setResult(tl.TaskResult.Failed, `Unknown command - ("${command}").`); 76 | break; 77 | } 78 | } 79 | } 80 | catch (error) { 81 | tl.setResult(tl.TaskResult.Failed, error); 82 | } 83 | }); 84 | })(); 85 | //# sourceMappingURL=azure_devops_task.js.map -------------------------------------------------------------------------------- /lib/azure_devops_task.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"azure_devops_task.js","sourceRoot":"","sources":["../src/azure_devops_task.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/github_action.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 26 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 27 | return new (P || (P = Promise))(function (resolve, reject) { 28 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 29 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 30 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 31 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 32 | }); 33 | }; 34 | Object.defineProperty(exports, "__esModule", { value: true }); 35 | const core = __importStar(require("@actions/core")); 36 | const store_apis_1 = require("./store_apis"); 37 | (function main() { 38 | return __awaiter(this, void 0, void 0, function* () { 39 | const storeApis = new store_apis_1.StoreApis(); 40 | try { 41 | const command = core.getInput("command"); 42 | switch (command) { 43 | case "configure": { 44 | storeApis.productId = core.getInput("product-id"); 45 | storeApis.sellerId = core.getInput("seller-id"); 46 | storeApis.tenantId = core.getInput("tenant-id"); 47 | storeApis.clientId = core.getInput("client-id"); 48 | storeApis.clientSecret = core.getInput("client-secret"); 49 | yield storeApis.InitAsync(); 50 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}product_id`, storeApis.productId); 51 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}seller_id`, storeApis.sellerId); 52 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}tenant_id`, storeApis.tenantId); 53 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}client_id`, storeApis.clientId); 54 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}client_secret`, storeApis.clientSecret); 55 | core.exportVariable(`${store_apis_1.EnvVariablePrefix}access_token`, storeApis.accessToken); 56 | core.setSecret(storeApis.productId); 57 | core.setSecret(storeApis.sellerId); 58 | core.setSecret(storeApis.tenantId); 59 | core.setSecret(storeApis.clientId); 60 | core.setSecret(storeApis.clientSecret); 61 | core.setSecret(storeApis.accessToken); 62 | break; 63 | } 64 | case "get": { 65 | const moduleName = core.getInput("module-name"); 66 | const listingLanguage = core.getInput("listing-language"); 67 | const draftSubmission = yield storeApis.GetExistingDraft(moduleName, listingLanguage); 68 | core.setOutput("draft-submission", draftSubmission); 69 | break; 70 | } 71 | case "update": { 72 | const updatedMetadataString = core.getInput("metadata-update"); 73 | const updatedProductString = core.getInput("product-update"); 74 | if (!updatedMetadataString && !updatedProductString) { 75 | core.setFailed(`Nothing to update. Both product-update and metadata-update are null.`); 76 | return; 77 | } 78 | if (updatedMetadataString) { 79 | const updateSubmissionMetadata = yield storeApis.UpdateSubmissionMetadata(updatedMetadataString); 80 | console.log(updateSubmissionMetadata); 81 | } 82 | if (updatedProductString) { 83 | const updateSubmissionData = yield storeApis.UpdateProductPackages(updatedProductString); 84 | console.log(updateSubmissionData); 85 | } 86 | break; 87 | } 88 | case "poll": { 89 | const pollingSubmissionId = core.getInput("polling-submission-id"); 90 | if (!pollingSubmissionId) { 91 | core.setFailed(`polling-submission-id parameter cannot be empty.`); 92 | return; 93 | } 94 | const publishingStatus = yield storeApis.PollSubmissionStatus(pollingSubmissionId); 95 | core.setOutput("submission-status", publishingStatus); 96 | break; 97 | } 98 | case "publish": { 99 | const submissionId = yield storeApis.PublishSubmission(); 100 | core.setOutput("polling-submission-id", submissionId); 101 | break; 102 | } 103 | default: { 104 | core.setFailed(`Unknown command - ("${command}").`); 105 | break; 106 | } 107 | } 108 | } 109 | catch (error) { 110 | core.setFailed(error); 111 | } 112 | }); 113 | })(); 114 | //# sourceMappingURL=github_action.js.map -------------------------------------------------------------------------------- /lib/github_action.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"github_action.js","sourceRoot":"","sources":["../src/github_action.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/store_apis.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 26 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 27 | return new (P || (P = Promise))(function (resolve, reject) { 28 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 29 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 30 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 31 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 32 | }); 33 | }; 34 | Object.defineProperty(exports, "__esModule", { value: true }); 35 | exports.StoreApis = exports.EnvVariablePrefix = void 0; 36 | const https = __importStar(require("https")); 37 | exports.EnvVariablePrefix = "MICROSOFT_STORE_ACTION_"; 38 | class ResponseWrapper { 39 | constructor() { 40 | Object.defineProperty(this, "responseData", { 41 | enumerable: true, 42 | configurable: true, 43 | writable: true, 44 | value: void 0 45 | }); 46 | Object.defineProperty(this, "isSuccess", { 47 | enumerable: true, 48 | configurable: true, 49 | writable: true, 50 | value: void 0 51 | }); 52 | Object.defineProperty(this, "errors", { 53 | enumerable: true, 54 | configurable: true, 55 | writable: true, 56 | value: void 0 57 | }); 58 | } 59 | } 60 | class ErrorResponse { 61 | constructor() { 62 | Object.defineProperty(this, "statusCode", { 63 | enumerable: true, 64 | configurable: true, 65 | writable: true, 66 | value: void 0 67 | }); 68 | Object.defineProperty(this, "message", { 69 | enumerable: true, 70 | configurable: true, 71 | writable: true, 72 | value: void 0 73 | }); 74 | } 75 | } 76 | class Error { 77 | constructor() { 78 | Object.defineProperty(this, "code", { 79 | enumerable: true, 80 | configurable: true, 81 | writable: true, 82 | value: void 0 83 | }); 84 | Object.defineProperty(this, "message", { 85 | enumerable: true, 86 | configurable: true, 87 | writable: true, 88 | value: void 0 89 | }); 90 | Object.defineProperty(this, "target", { 91 | enumerable: true, 92 | configurable: true, 93 | writable: true, 94 | value: void 0 95 | }); 96 | } 97 | } 98 | class SubmissionResponse { 99 | constructor() { 100 | Object.defineProperty(this, "pollingUrl", { 101 | enumerable: true, 102 | configurable: true, 103 | writable: true, 104 | value: void 0 105 | }); 106 | Object.defineProperty(this, "submissionId", { 107 | enumerable: true, 108 | configurable: true, 109 | writable: true, 110 | value: void 0 111 | }); 112 | Object.defineProperty(this, "ongoingSubmissionId", { 113 | enumerable: true, 114 | configurable: true, 115 | writable: true, 116 | value: void 0 117 | }); 118 | } 119 | } 120 | var PublishingStatus; 121 | (function (PublishingStatus) { 122 | PublishingStatus["INPROGRESS"] = "INPROGRESS"; 123 | PublishingStatus["PUBLISHED"] = "PUBLISHED"; 124 | PublishingStatus["FAILED"] = "FAILED"; 125 | PublishingStatus["UNKNOWN"] = "UNKNOWN"; 126 | })(PublishingStatus || (PublishingStatus = {})); 127 | class ModuleStatus { 128 | constructor() { 129 | Object.defineProperty(this, "isReady", { 130 | enumerable: true, 131 | configurable: true, 132 | writable: true, 133 | value: void 0 134 | }); 135 | Object.defineProperty(this, "ongoingSubmissionId", { 136 | enumerable: true, 137 | configurable: true, 138 | writable: true, 139 | value: void 0 140 | }); 141 | } 142 | } 143 | class SubmissionStatus { 144 | constructor() { 145 | Object.defineProperty(this, "publishingStatus", { 146 | enumerable: true, 147 | configurable: true, 148 | writable: true, 149 | value: void 0 150 | }); 151 | Object.defineProperty(this, "hasFailed", { 152 | enumerable: true, 153 | configurable: true, 154 | writable: true, 155 | value: void 0 156 | }); 157 | } 158 | } 159 | class ListingAssetsResponse { 160 | constructor() { 161 | Object.defineProperty(this, "listingAssets", { 162 | enumerable: true, 163 | configurable: true, 164 | writable: true, 165 | value: void 0 166 | }); 167 | } 168 | } 169 | class ImageSize { 170 | constructor() { 171 | Object.defineProperty(this, "width", { 172 | enumerable: true, 173 | configurable: true, 174 | writable: true, 175 | value: void 0 176 | }); 177 | Object.defineProperty(this, "height", { 178 | enumerable: true, 179 | configurable: true, 180 | writable: true, 181 | value: void 0 182 | }); 183 | } 184 | } 185 | class ListingAsset { 186 | constructor() { 187 | Object.defineProperty(this, "language", { 188 | enumerable: true, 189 | configurable: true, 190 | writable: true, 191 | value: void 0 192 | }); 193 | Object.defineProperty(this, "storeLogos", { 194 | enumerable: true, 195 | configurable: true, 196 | writable: true, 197 | value: void 0 198 | }); 199 | Object.defineProperty(this, "screenshots", { 200 | enumerable: true, 201 | configurable: true, 202 | writable: true, 203 | value: void 0 204 | }); 205 | } 206 | } 207 | class Screenshot { 208 | constructor() { 209 | Object.defineProperty(this, "id", { 210 | enumerable: true, 211 | configurable: true, 212 | writable: true, 213 | value: void 0 214 | }); 215 | Object.defineProperty(this, "assetUrl", { 216 | enumerable: true, 217 | configurable: true, 218 | writable: true, 219 | value: void 0 220 | }); 221 | Object.defineProperty(this, "imageSize", { 222 | enumerable: true, 223 | configurable: true, 224 | writable: true, 225 | value: void 0 226 | }); 227 | } 228 | } 229 | class StoreLogo { 230 | constructor() { 231 | Object.defineProperty(this, "id", { 232 | enumerable: true, 233 | configurable: true, 234 | writable: true, 235 | value: void 0 236 | }); 237 | Object.defineProperty(this, "assetUrl", { 238 | enumerable: true, 239 | configurable: true, 240 | writable: true, 241 | value: void 0 242 | }); 243 | Object.defineProperty(this, "imageSize", { 244 | enumerable: true, 245 | configurable: true, 246 | writable: true, 247 | value: void 0 248 | }); 249 | } 250 | } 251 | class StoreApis { 252 | constructor() { 253 | Object.defineProperty(this, "accessToken", { 254 | enumerable: true, 255 | configurable: true, 256 | writable: true, 257 | value: void 0 258 | }); 259 | Object.defineProperty(this, "productId", { 260 | enumerable: true, 261 | configurable: true, 262 | writable: true, 263 | value: void 0 264 | }); 265 | Object.defineProperty(this, "sellerId", { 266 | enumerable: true, 267 | configurable: true, 268 | writable: true, 269 | value: void 0 270 | }); 271 | Object.defineProperty(this, "tenantId", { 272 | enumerable: true, 273 | configurable: true, 274 | writable: true, 275 | value: void 0 276 | }); 277 | Object.defineProperty(this, "clientId", { 278 | enumerable: true, 279 | configurable: true, 280 | writable: true, 281 | value: void 0 282 | }); 283 | Object.defineProperty(this, "clientSecret", { 284 | enumerable: true, 285 | configurable: true, 286 | writable: true, 287 | value: void 0 288 | }); 289 | this.LoadState(); 290 | } 291 | Delay(ms) { 292 | return new Promise((resolve) => setTimeout(resolve, ms)); 293 | } 294 | GetAccessToken() { 295 | return __awaiter(this, void 0, void 0, function* () { 296 | const requestParameters = { 297 | grant_type: "client_credentials", 298 | client_id: this.clientId, 299 | client_secret: this.clientSecret, 300 | scope: StoreApis.scope, 301 | }; 302 | const formBody = []; 303 | for (const property in requestParameters) { 304 | const encodedKey = encodeURIComponent(property); 305 | const encodedValue = encodeURIComponent(requestParameters[property]); 306 | formBody.push(encodedKey + "=" + encodedValue); 307 | } 308 | const dataString = formBody.join("\r\n&"); 309 | const options = { 310 | host: StoreApis.microsoftOnlineLoginHost, 311 | path: `/${this.tenantId}${StoreApis.authOAuth2TokenSuffix}`, 312 | method: "POST", 313 | headers: { 314 | "Content-Type": "application/x-www-form-urlencoded", 315 | "Content-Length": dataString.length, 316 | }, 317 | }; 318 | return new Promise((resolve, reject) => { 319 | const req = https.request(options, (res) => { 320 | let responseString = ""; 321 | res.on("data", (data) => { 322 | responseString += data; 323 | }); 324 | res.on("end", function () { 325 | const responseObject = JSON.parse(responseString); 326 | if (responseObject.error) 327 | reject(responseObject); 328 | else 329 | resolve(responseObject.access_token); 330 | }); 331 | }); 332 | req.on("error", (e) => { 333 | console.error(e); 334 | reject(e); 335 | }); 336 | req.write(dataString); 337 | req.end(); 338 | }); 339 | }); 340 | } 341 | GetCurrentDraftSubmissionPackagesData() { 342 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/packages`); 343 | } 344 | GetCurrentDraftSubmissionMetadata(moduleName, listingLanguages) { 345 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/metadata/${moduleName}?languages=${listingLanguages}`); 346 | } 347 | UpdateCurrentDraftSubmissionMetadata(submissionMetadata) { 348 | return this.CreateStoreHttpRequest(JSON.stringify(submissionMetadata), "PUT", `/submission/v1/product/${this.productId}/metadata`); 349 | } 350 | UpdateStoreSubmissionPackages(submission) { 351 | return __awaiter(this, void 0, void 0, function* () { 352 | return this.CreateStoreHttpRequest(JSON.stringify(submission), "PUT", `/submission/v1/product/${this.productId}/packages`); 353 | }); 354 | } 355 | CommitUpdateStoreSubmissionPackages() { 356 | return __awaiter(this, void 0, void 0, function* () { 357 | return this.CreateStoreHttpRequest("", "POST", `/submission/v1/product/${this.productId}/packages/commit`); 358 | }); 359 | } 360 | GetModuleStatus() { 361 | return __awaiter(this, void 0, void 0, function* () { 362 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/status`); 363 | }); 364 | } 365 | GetSubmissionStatus(submissionId) { 366 | return __awaiter(this, void 0, void 0, function* () { 367 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/submission/${submissionId}/status`); 368 | }); 369 | } 370 | SubmitSubmission() { 371 | return __awaiter(this, void 0, void 0, function* () { 372 | return this.CreateStoreHttpRequest("", "POST", `/submission/v1/product/${this.productId}/submit`); 373 | }); 374 | } 375 | GetCurrentDraftListingAssets(listingLanguages) { 376 | return __awaiter(this, void 0, void 0, function* () { 377 | return this.CreateStoreHttpRequest("", "GET", `/submission/v1/product/${this.productId}/listings/assets?languages=${listingLanguages}`); 378 | }); 379 | } 380 | CreateStoreHttpRequest(requestParameters, method, path) { 381 | return __awaiter(this, void 0, void 0, function* () { 382 | const options = { 383 | host: StoreApis.storeApiUrl, 384 | path: path, 385 | method: method, 386 | headers: { 387 | "Content-Type": "application/json", 388 | "Content-Length": requestParameters.length, 389 | Authorization: "Bearer " + this.accessToken, 390 | "X-Seller-Account-Id": this.sellerId, 391 | }, 392 | }; 393 | return new Promise((resolve, reject) => { 394 | const req = https.request(options, (res) => { 395 | if (res.statusCode == 404) { 396 | const error = new ResponseWrapper(); 397 | error.isSuccess = false; 398 | error.errors = []; 399 | error.errors[0] = new Error(); 400 | error.errors[0].message = "Not found"; 401 | reject(error); 402 | return; 403 | } 404 | let responseString = ""; 405 | res.on("data", (data) => { 406 | responseString += data; 407 | }); 408 | res.on("end", function () { 409 | const responseObject = JSON.parse(responseString); 410 | resolve(responseObject); 411 | }); 412 | }); 413 | req.on("error", (e) => { 414 | console.error(e); 415 | reject(e); 416 | }); 417 | req.write(requestParameters); 418 | req.end(); 419 | }); 420 | }); 421 | } 422 | PollModuleStatus() { 423 | return __awaiter(this, void 0, void 0, function* () { 424 | let status = new ModuleStatus(); 425 | status.isReady = false; 426 | while (!status.isReady) { 427 | const moduleStatus = yield this.GetModuleStatus(); 428 | console.log(JSON.stringify(moduleStatus)); 429 | status = moduleStatus.responseData; 430 | if (!moduleStatus.isSuccess) { 431 | const errorResponse = moduleStatus; 432 | if (errorResponse.statusCode == 401) { 433 | console.log(`Access token expired. Requesting new one. (message='${errorResponse.message}')`); 434 | yield this.InitAsync(); 435 | status = new ModuleStatus(); 436 | status.isReady = false; 437 | continue; 438 | } 439 | console.log("Error"); 440 | break; 441 | } 442 | if (status.isReady) { 443 | console.log("Success!"); 444 | return true; 445 | } 446 | else { 447 | if (moduleStatus.errors && 448 | moduleStatus.errors.length > 0 && 449 | moduleStatus.errors.find((e) => e.target != "packages" || e.code == "packageuploaderror")) { 450 | console.log(moduleStatus.errors); 451 | return false; 452 | } 453 | } 454 | console.log("Waiting 10 seconds."); 455 | yield this.Delay(10000); 456 | } 457 | return false; 458 | }); 459 | } 460 | InitAsync() { 461 | return __awaiter(this, void 0, void 0, function* () { 462 | this.accessToken = yield this.GetAccessToken(); 463 | }); 464 | } 465 | GetExistingDraft(moduleName, listingLanguage) { 466 | return __awaiter(this, void 0, void 0, function* () { 467 | return new Promise((resolve, reject) => { 468 | if (moduleName && 469 | moduleName.toLowerCase() != "availability" && 470 | moduleName.toLowerCase() != "listings" && 471 | moduleName.toLowerCase() != "properties") { 472 | reject("Module name must be 'availability', 'listings' or 'properties'"); 473 | return; 474 | } 475 | (moduleName 476 | ? this.GetCurrentDraftSubmissionMetadata(moduleName, listingLanguage) 477 | : this.GetCurrentDraftSubmissionPackagesData()) 478 | .then((currentDraftResponse) => { 479 | if (!currentDraftResponse.isSuccess) { 480 | reject(`Failed to get the existing draft. - ${JSON.stringify(currentDraftResponse, null, 2)}`); 481 | } 482 | else { 483 | resolve(JSON.stringify(currentDraftResponse.responseData)); 484 | } 485 | }) 486 | .catch((error) => { 487 | reject(`Failed to get the existing draft. - ${error.errors}`); 488 | }); 489 | }); 490 | }); 491 | } 492 | PollSubmissionStatus(pollingSubmissionId) { 493 | return __awaiter(this, void 0, void 0, function* () { 494 | let status = new SubmissionStatus(); 495 | status.hasFailed = false; 496 | // eslint-disable-next-line no-async-promise-executor 497 | return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { 498 | while (!status.hasFailed) { 499 | const submissionStatus = yield this.GetSubmissionStatus(pollingSubmissionId); 500 | console.log(JSON.stringify(submissionStatus)); 501 | status = submissionStatus.responseData; 502 | if (!submissionStatus.isSuccess || status.hasFailed) { 503 | const errorResponse = submissionStatus; 504 | if (errorResponse.statusCode == 401) { 505 | console.log(`Access token expired. Requesting new one. (message='${errorResponse.message}')`); 506 | yield this.InitAsync(); 507 | status = new SubmissionStatus(); 508 | status.hasFailed = false; 509 | continue; 510 | } 511 | console.log("Error"); 512 | reject("Error"); 513 | return; 514 | } 515 | if (status.publishingStatus == PublishingStatus.PUBLISHED || 516 | status.publishingStatus == PublishingStatus.FAILED) { 517 | console.log(`PublishingStatus = ${status.publishingStatus}`); 518 | resolve(status.publishingStatus); 519 | return; 520 | } 521 | console.log("Waiting 10 seconds."); 522 | yield this.Delay(10000); 523 | } 524 | })); 525 | }); 526 | } 527 | UpdateSubmissionMetadata(submissionMetadataString) { 528 | return __awaiter(this, void 0, void 0, function* () { 529 | if (!(yield this.PollModuleStatus())) { 530 | // Wait until all modules are in the ready state 531 | return Promise.reject("Failed to poll module status."); 532 | } 533 | const submissionMetadata = JSON.parse(submissionMetadataString); 534 | console.log(submissionMetadata); 535 | const updateSubmissionData = yield this.UpdateCurrentDraftSubmissionMetadata(submissionMetadata); 536 | console.log(JSON.stringify(updateSubmissionData)); 537 | if (!updateSubmissionData.isSuccess) { 538 | return Promise.reject(`Failed to update submission metadata - ${JSON.stringify(updateSubmissionData.errors)}`); 539 | } 540 | if (!(yield this.PollModuleStatus())) { 541 | // Wait until all modules are in the ready state 542 | return Promise.reject("Failed to poll module status."); 543 | } 544 | return updateSubmissionData; 545 | }); 546 | } 547 | UpdateProductPackages(updatedProductString) { 548 | return __awaiter(this, void 0, void 0, function* () { 549 | if (!(yield this.PollModuleStatus())) { 550 | // Wait until all modules are in the ready state 551 | return Promise.reject("Failed to poll module status."); 552 | } 553 | const updatedProductPackages = JSON.parse(updatedProductString); 554 | console.log(updatedProductPackages); 555 | const updateSubmissionData = yield this.UpdateStoreSubmissionPackages(updatedProductPackages); 556 | console.log(JSON.stringify(updateSubmissionData)); 557 | if (!updateSubmissionData.isSuccess) { 558 | return Promise.reject(`Failed to update submission - ${JSON.stringify(updateSubmissionData.errors)}`); 559 | } 560 | console.log("Committing package changes..."); 561 | const commitResult = yield this.CommitUpdateStoreSubmissionPackages(); 562 | if (!commitResult.isSuccess) { 563 | return Promise.reject(`Failed to commit the updated submission - ${JSON.stringify(commitResult.errors)}`); 564 | } 565 | console.log(JSON.stringify(commitResult)); 566 | if (!(yield this.PollModuleStatus())) { 567 | // Wait until all modules are in the ready state 568 | return Promise.reject("Failed to poll module status."); 569 | } 570 | return updateSubmissionData; 571 | }); 572 | } 573 | PublishSubmission() { 574 | return __awaiter(this, void 0, void 0, function* () { 575 | const commitResult = yield this.CommitUpdateStoreSubmissionPackages(); 576 | if (!commitResult.isSuccess) { 577 | return Promise.reject(`Failed to commit the updated submission - ${JSON.stringify(commitResult.errors)}`); 578 | } 579 | console.log(JSON.stringify(commitResult)); 580 | if (!(yield this.PollModuleStatus())) { 581 | // Wait until all modules are in the ready state 582 | return Promise.reject("Failed to poll module status."); 583 | } 584 | let submissionId = null; 585 | const submitSubmissionResponse = yield this.SubmitSubmission(); 586 | console.log(JSON.stringify(submitSubmissionResponse)); 587 | if (submitSubmissionResponse.isSuccess) { 588 | if (submitSubmissionResponse.responseData.submissionId != null && 589 | submitSubmissionResponse.responseData.submissionId.length > 0) { 590 | submissionId = submitSubmissionResponse.responseData.submissionId; 591 | } 592 | else if (submitSubmissionResponse.responseData.ongoingSubmissionId != null && 593 | submitSubmissionResponse.responseData.ongoingSubmissionId.length > 0) { 594 | submissionId = 595 | submitSubmissionResponse.responseData.ongoingSubmissionId; 596 | } 597 | } 598 | return new Promise((resolve, reject) => { 599 | if (submissionId == null) { 600 | console.log("Failed to get submission ID"); 601 | reject("Failed to get submission ID"); 602 | } 603 | else { 604 | resolve(submissionId); 605 | } 606 | }); 607 | }); 608 | } 609 | GetExistingDraftListingAssets(listingLanguage) { 610 | return __awaiter(this, void 0, void 0, function* () { 611 | return new Promise((resolve, reject) => { 612 | this.GetCurrentDraftListingAssets(listingLanguage) 613 | .then((draftListingAssetsResponse) => { 614 | if (!draftListingAssetsResponse.isSuccess) { 615 | reject(`Failed to get the existing draft listing assets. - ${JSON.stringify(draftListingAssetsResponse, null, 2)}`); 616 | } 617 | else { 618 | resolve(JSON.stringify(draftListingAssetsResponse.responseData)); 619 | } 620 | }) 621 | .catch((error) => { 622 | reject(`Failed to get the existing draft listing assets. - ${error.errors}`); 623 | }); 624 | }); 625 | }); 626 | } 627 | LoadState() { 628 | var _a, _b, _c, _d, _e, _f; 629 | this.productId = (_a = process.env[`${exports.EnvVariablePrefix}product_id`]) !== null && _a !== void 0 ? _a : ""; 630 | this.sellerId = (_b = process.env[`${exports.EnvVariablePrefix}seller_id`]) !== null && _b !== void 0 ? _b : ""; 631 | this.tenantId = (_c = process.env[`${exports.EnvVariablePrefix}tenant_id`]) !== null && _c !== void 0 ? _c : ""; 632 | this.clientId = (_d = process.env[`${exports.EnvVariablePrefix}client_id`]) !== null && _d !== void 0 ? _d : ""; 633 | this.clientSecret = (_e = process.env[`${exports.EnvVariablePrefix}client_secret`]) !== null && _e !== void 0 ? _e : ""; 634 | this.accessToken = (_f = process.env[`${exports.EnvVariablePrefix}access_token`]) !== null && _f !== void 0 ? _f : ""; 635 | } 636 | } 637 | exports.StoreApis = StoreApis; 638 | Object.defineProperty(StoreApis, "microsoftOnlineLoginHost", { 639 | enumerable: true, 640 | configurable: true, 641 | writable: true, 642 | value: "login.microsoftonline.com" 643 | }); 644 | Object.defineProperty(StoreApis, "authOAuth2TokenSuffix", { 645 | enumerable: true, 646 | configurable: true, 647 | writable: true, 648 | value: "/oauth2/v2.0/token" 649 | }); 650 | Object.defineProperty(StoreApis, "scope", { 651 | enumerable: true, 652 | configurable: true, 653 | writable: true, 654 | value: "https://api.store.microsoft.com/.default" 655 | }); 656 | Object.defineProperty(StoreApis, "storeApiUrl", { 657 | enumerable: true, 658 | configurable: true, 659 | writable: true, 660 | value: "api.store.microsoft.com" 661 | }); 662 | //# sourceMappingURL=store_apis.js.map -------------------------------------------------------------------------------- /lib/store_apis.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"store_apis.js","sourceRoot":"","sources":["../src/store_apis.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA+B;AAElB,QAAA,iBAAiB,GAAG,yBAAyB,CAAC;AAE3D,MAAM,eAAe;IAArB;QACE;;;;;WAAgB;QAChB;;;;;WAAmB;QACnB;;;;;WAAgB;IAClB,CAAC;CAAA;AAED,MAAM,aAAa;IAAnB;QACE;;;;;WAAmB;QACnB;;;;;WAAgB;IAClB,CAAC;CAAA;AAED,MAAM,KAAK;IAAX;QACE;;;;;WAAa;QACb;;;;;WAAgB;QAChB;;;;;WAAe;IACjB,CAAC;CAAA;AAED,MAAM,kBAAkB;IAAxB;QACE;;;;;WAAmB;QACnB;;;;;WAAqB;QACrB;;;;;WAA4B;IAC9B,CAAC;CAAA;AAED,IAAK,gBAKJ;AALD,WAAK,gBAAgB;IACnB,6CAAyB,CAAA;IACzB,2CAAuB,CAAA;IACvB,qCAAiB,CAAA;IACjB,uCAAmB,CAAA;AACrB,CAAC,EALI,gBAAgB,KAAhB,gBAAgB,QAKpB;AAED,MAAM,YAAY;IAAlB;QACE;;;;;WAAiB;QACjB;;;;;WAA4B;IAC9B,CAAC;CAAA;AAED,MAAM,gBAAgB;IAAtB;QACE;;;;;WAAmC;QACnC;;;;;WAAmB;IACrB,CAAC;CAAA;AAED,MAAM,qBAAqB;IAA3B;QACE;;;;;WAA8B;IAChC,CAAC;CAAA;AAED,MAAM,SAAS;IAAf;QACE;;;;;WAAc;QACd;;;;;WAAe;IACjB,CAAC;CAAA;AAED,MAAM,YAAY;IAAlB;QACE;;;;;WAAiB;QACjB;;;;;WAAwB;QACxB;;;;;WAA0B;IAC5B,CAAC;CAAA;AAED,MAAM,UAAU;IAAhB;QACE;;;;;WAAW;QACX;;;;;WAAiB;QACjB;;;;;WAAqB;IACvB,CAAC;CAAA;AAED,MAAM,SAAS;IAAf;QACE;;;;;WAAW;QACX;;;;;WAAiB;QACjB;;;;;WAAqB;IACvB,CAAC;CAAA;AAED,MAAa,SAAS;IAOpB;QAIA;;;;;WAA2B;QAC3B;;;;;WAAyB;QACzB;;;;;WAAwB;QACxB;;;;;WAAwB;QACxB;;;;;WAAwB;QACxB;;;;;WAA4B;QAR1B,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IASO,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAEa,cAAc;;YAC1B,MAAM,iBAAiB,GAA8B;gBACnD,UAAU,EAAE,oBAAoB;gBAChC,SAAS,EAAE,IAAI,CAAC,QAAQ;gBACxB,aAAa,EAAE,IAAI,CAAC,YAAY;gBAChC,KAAK,EAAE,SAAS,CAAC,KAAK;aACvB,CAAC;YAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;YACpB,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE;gBACxC,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;gBAChD,MAAM,YAAY,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACrE,QAAQ,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,GAAG,YAAY,CAAC,CAAC;aAChD;YAED,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE1C,MAAM,OAAO,GAAyB;gBACpC,IAAI,EAAE,SAAS,CAAC,wBAAwB;gBACxC,IAAI,EAAE,IAAI,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,qBAAqB,EAAE;gBAC3D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,mCAAmC;oBACnD,gBAAgB,EAAE,UAAU,CAAC,MAAM;iBACpC;aACF,CAAC;YAEF,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;oBACzC,IAAI,cAAc,GAAG,EAAE,CAAC;oBAExB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;wBACtB,cAAc,IAAI,IAAI,CAAC;oBACzB,CAAC,CAAC,CAAC;oBAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE;wBACZ,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;wBAClD,IAAI,cAAc,CAAC,KAAK;4BAAE,MAAM,CAAC,cAAc,CAAC,CAAC;;4BAC5C,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;oBAC5C,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;oBACpB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACjB,MAAM,CAAC,CAAC,CAAC,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACtB,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAEO,qCAAqC;QAG3C,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,WAAW,CACpD,CAAC;IACJ,CAAC;IAEO,iCAAiC,CACvC,UAAkB,EAClB,gBAAwB;QAExB,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,aAAa,UAAU,cAAc,gBAAgB,EAAE,CAChG,CAAC;IACJ,CAAC;IAEO,oCAAoC,CAC1C,kBAA0B;QAE1B,OAAO,IAAI,CAAC,sBAAsB,CAChC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAClC,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,WAAW,CACpD,CAAC;IACJ,CAAC;IAEa,6BAA6B,CACzC,UAAmB;;YAEnB,OAAO,IAAI,CAAC,sBAAsB,CAChC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAC1B,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,WAAW,CACpD,CAAC;QACJ,CAAC;KAAA;IAEa,mCAAmC;;YAG/C,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,MAAM,EACN,0BAA0B,IAAI,CAAC,SAAS,kBAAkB,CAC3D,CAAC;QACJ,CAAC;KAAA;IAEa,eAAe;;YAC3B,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,SAAS,CAClD,CAAC;QACJ,CAAC;KAAA;IAEa,mBAAmB,CAC/B,YAAoB;;YAEpB,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,eAAe,YAAY,SAAS,CAC7E,CAAC;QACJ,CAAC;KAAA;IAEa,gBAAgB;;YAG5B,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,MAAM,EACN,0BAA0B,IAAI,CAAC,SAAS,SAAS,CAClD,CAAC;QACJ,CAAC;KAAA;IAEa,4BAA4B,CACxC,gBAAwB;;YAExB,OAAO,IAAI,CAAC,sBAAsB,CAChC,EAAE,EACF,KAAK,EACL,0BAA0B,IAAI,CAAC,SAAS,8BAA8B,gBAAgB,EAAE,CACzF,CAAC;QACJ,CAAC;KAAA;IAEa,sBAAsB,CAClC,iBAAyB,EACzB,MAAc,EACd,IAAY;;YAEZ,MAAM,OAAO,GAAyB;gBACpC,IAAI,EAAE,SAAS,CAAC,WAAW;gBAC3B,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,gBAAgB,EAAE,iBAAiB,CAAC,MAAM;oBAC1C,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,WAAW;oBAC3C,qBAAqB,EAAE,IAAI,CAAC,QAAQ;iBACrC;aACF,CAAC;YAEF,OAAO,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACzD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;oBACzC,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,EAAE;wBACzB,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;wBACpC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;wBACxB,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;wBAClB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;wBAC9B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,WAAW,CAAC;wBACtC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACd,OAAO;qBACR;oBACD,IAAI,cAAc,GAAG,EAAE,CAAC;oBAExB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;wBACtB,cAAc,IAAI,IAAI,CAAC;oBACzB,CAAC,CAAC,CAAC;oBAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE;wBACZ,MAAM,cAAc,GAAuB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;wBACtE,OAAO,CAAC,cAAc,CAAC,CAAC;oBAC1B,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;oBACpB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACjB,MAAM,CAAC,CAAC,CAAC,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAC7B,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAEa,gBAAgB;;YAC5B,IAAI,MAAM,GAAiB,IAAI,YAAY,EAAE,CAAC;YAC9C,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YAEvB,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE;gBACtB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;gBAC1C,MAAM,GAAG,YAAY,CAAC,YAAY,CAAC;gBACnC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;oBAC3B,MAAM,aAAa,GAAG,YAAwC,CAAC;oBAC/D,IAAI,aAAa,CAAC,UAAU,IAAI,GAAG,EAAE;wBACnC,OAAO,CAAC,GAAG,CACT,uDAAuD,aAAa,CAAC,OAAO,IAAI,CACjF,CAAC;wBACF,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;wBACvB,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;wBAC5B,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;wBACvB,SAAS;qBACV;oBACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACrB,MAAM;iBACP;gBACD,IAAI,MAAM,CAAC,OAAO,EAAE;oBAClB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACxB,OAAO,IAAI,CAAC;iBACb;qBAAM;oBACL,IACE,YAAY,CAAC,MAAM;wBACnB,YAAY,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;wBAC9B,YAAY,CAAC,MAAM,CAAC,IAAI,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,UAAU,IAAI,CAAC,CAAC,IAAI,IAAI,oBAAoB,CAChE,EACD;wBACA,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;wBACjC,OAAO,KAAK,CAAC;qBACd;iBACF;gBAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACnC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;aACzB;YAED,OAAO,KAAK,CAAC;QACf,CAAC;KAAA;IAEY,SAAS;;YACpB,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QACjD,CAAC;KAAA;IAEY,gBAAgB,CAC3B,UAAkB,EAClB,eAAuB;;YAEvB,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC7C,IACE,UAAU;oBACV,UAAU,CAAC,WAAW,EAAE,IAAI,cAAc;oBAC1C,UAAU,CAAC,WAAW,EAAE,IAAI,UAAU;oBACtC,UAAU,CAAC,WAAW,EAAE,IAAI,YAAY,EACxC;oBACA,MAAM,CACJ,gEAAgE,CACjE,CAAC;oBACF,OAAO;iBACR;gBAED,CAAC,UAAU;oBACT,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,UAAU,EAAE,eAAe,CAAC;oBACrE,CAAC,CAAC,IAAI,CAAC,qCAAqC,EAAE,CAC/C;qBACE,IAAI,CAAC,CAAC,oBAAoB,EAAE,EAAE;oBAC7B,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE;wBACnC,MAAM,CACJ,uCAAuC,IAAI,CAAC,SAAS,CACnD,oBAAoB,EACpB,IAAI,EACJ,CAAC,CACF,EAAE,CACJ,CAAC;qBACH;yBAAM;wBACL,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,CAAC;qBAC5D;gBACH,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,MAAM,CAAC,uCAAuC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBAChE,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAEY,oBAAoB,CAC/B,mBAA2B;;YAE3B,IAAI,MAAM,GAAqB,IAAI,gBAAgB,EAAE,CAAC;YACtD,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC;YAEzB,qDAAqD;YACrD,OAAO,IAAI,OAAO,CAAmB,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC7D,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE;oBACxB,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CACrD,mBAAmB,CACpB,CAAC;oBACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC9C,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC;oBACvC,IAAI,CAAC,gBAAgB,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,EAAE;wBACnD,MAAM,aAAa,GAAG,gBAA4C,CAAC;wBACnE,IAAI,aAAa,CAAC,UAAU,IAAI,GAAG,EAAE;4BACnC,OAAO,CAAC,GAAG,CACT,uDAAuD,aAAa,CAAC,OAAO,IAAI,CACjF,CAAC;4BACF,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;4BACvB,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;4BAChC,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC;4BACzB,SAAS;yBACV;wBACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACrB,MAAM,CAAC,OAAO,CAAC,CAAC;wBAChB,OAAO;qBACR;oBACD,IACE,MAAM,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,SAAS;wBACrD,MAAM,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,EAClD;wBACA,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;wBAC7D,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;wBACjC,OAAO;qBACR;oBAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;oBACnC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;iBACzB;YACH,CAAC,CAAA,CAAC,CAAC;QACL,CAAC;KAAA;IAEY,wBAAwB,CACnC,wBAAgC;;YAEhC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;gBACpC,gDAAgD;gBAChD,OAAO,OAAO,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC;aACxD;YAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAEhE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAEhC,MAAM,oBAAoB,GACxB,MAAM,IAAI,CAAC,oCAAoC,CAAC,kBAAkB,CAAC,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAElD,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE;gBACnC,OAAO,OAAO,CAAC,MAAM,CACnB,0CAA0C,IAAI,CAAC,SAAS,CACtD,oBAAoB,CAAC,MAAM,CAC5B,EAAE,CACJ,CAAC;aACH;YAED,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;gBACpC,gDAAgD;gBAChD,OAAO,OAAO,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC;aACxD;YAED,OAAO,oBAAoB,CAAC;QAC9B,CAAC;KAAA;IAEY,qBAAqB,CAChC,oBAA4B;;YAE5B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;gBACpC,gDAAgD;gBAChD,OAAO,OAAO,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC;aACxD;YAED,MAAM,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAEhE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YAEpC,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,6BAA6B,CACnE,sBAAsB,CACvB,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAElD,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE;gBACnC,OAAO,OAAO,CAAC,MAAM,CACnB,iCAAiC,IAAI,CAAC,SAAS,CAC7C,oBAAoB,CAAC,MAAM,CAC5B,EAAE,CACJ,CAAC;aACH;YAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAE7C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mCAAmC,EAAE,CAAC;YACtE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;gBAC3B,OAAO,OAAO,CAAC,MAAM,CACnB,6CAA6C,IAAI,CAAC,SAAS,CACzD,YAAY,CAAC,MAAM,CACpB,EAAE,CACJ,CAAC;aACH;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;YAE1C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;gBACpC,gDAAgD;gBAChD,OAAO,OAAO,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC;aACxD;YAED,OAAO,oBAAoB,CAAC;QAC9B,CAAC;KAAA;IAEY,iBAAiB;;YAC5B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mCAAmC,EAAE,CAAC;YACtE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;gBAC3B,OAAO,OAAO,CAAC,MAAM,CACnB,6CAA6C,IAAI,CAAC,SAAS,CACzD,YAAY,CAAC,MAAM,CACpB,EAAE,CACJ,CAAC;aACH;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;YAE1C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;gBACpC,gDAAgD;gBAChD,OAAO,OAAO,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC;aACxD;YAED,IAAI,YAAY,GAAkB,IAAI,CAAC;YAEvC,MAAM,wBAAwB,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACtD,IAAI,wBAAwB,CAAC,SAAS,EAAE;gBACtC,IACE,wBAAwB,CAAC,YAAY,CAAC,YAAY,IAAI,IAAI;oBAC1D,wBAAwB,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAC7D;oBACA,YAAY,GAAG,wBAAwB,CAAC,YAAY,CAAC,YAAY,CAAC;iBACnE;qBAAM,IACL,wBAAwB,CAAC,YAAY,CAAC,mBAAmB,IAAI,IAAI;oBACjE,wBAAwB,CAAC,YAAY,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EACpE;oBACA,YAAY;wBACV,wBAAwB,CAAC,YAAY,CAAC,mBAAmB,CAAC;iBAC7D;aACF;YAED,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC7C,IAAI,YAAY,IAAI,IAAI,EAAE;oBACxB,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;oBAC3C,MAAM,CAAC,6BAA6B,CAAC,CAAC;iBACvC;qBAAM;oBACL,OAAO,CAAC,YAAY,CAAC,CAAC;iBACvB;YACH,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAEY,6BAA6B,CACxC,eAAuB;;YAEvB,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC7C,IAAI,CAAC,4BAA4B,CAAC,eAAe,CAAC;qBAC/C,IAAI,CAAC,CAAC,0BAA0B,EAAE,EAAE;oBACnC,IAAI,CAAC,0BAA0B,CAAC,SAAS,EAAE;wBACzC,MAAM,CACJ,sDAAsD,IAAI,CAAC,SAAS,CAClE,0BAA0B,EAC1B,IAAI,EACJ,CAAC,CACF,EAAE,CACJ,CAAC;qBACH;yBAAM;wBACL,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC,CAAC;qBAClE;gBACH,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,MAAM,CACJ,sDAAsD,KAAK,CAAC,MAAM,EAAE,CACrE,CAAC;gBACJ,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAEO,SAAS;;QACf,IAAI,CAAC,SAAS,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,GAAG,yBAAiB,YAAY,CAAC,mCAAI,EAAE,CAAC;QACrE,IAAI,CAAC,QAAQ,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,GAAG,yBAAiB,WAAW,CAAC,mCAAI,EAAE,CAAC;QACnE,IAAI,CAAC,QAAQ,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,GAAG,yBAAiB,WAAW,CAAC,mCAAI,EAAE,CAAC;QACnE,IAAI,CAAC,QAAQ,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,GAAG,yBAAiB,WAAW,CAAC,mCAAI,EAAE,CAAC;QACnE,IAAI,CAAC,YAAY,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,GAAG,yBAAiB,eAAe,CAAC,mCAAI,EAAE,CAAC;QAC3E,IAAI,CAAC,WAAW,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,GAAG,yBAAiB,cAAc,CAAC,mCAAI,EAAE,CAAC;IAC3E,CAAC;;AArfH,8BAsfC;AArfC;;;;WACE,2BAA2B;GAAC;AAC9B;;;;WAAgD,oBAAoB;GAAC;AACrE;;;;WAAgC,0CAA0C;GAAC;AAC3E;;;;WAAsC,yBAAyB;GAAC"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "win32submission", 3 | "version": "1.0.0", 4 | "description": "GitHub Action to update EXE and MSI apps in the Microsoft Store.", 5 | "main": "index.js", 6 | "keywords": [], 7 | "author": "Microsoft", 8 | "license": "MIT", 9 | "scripts": { 10 | "build": "tsc && ncc build lib/github_action.js && ncc build lib/azure_devops_task.js -o submission-task", 11 | "package": "tfx extension create --manifest-globs vss-extension.json", 12 | "eslint": "eslint . --ext .ts,.tsx", 13 | "format": "prettier --write **/*.ts" 14 | }, 15 | "devDependencies": { 16 | "@tsconfig/node17": "^1.0.0", 17 | "@types/node": "^17.0.35", 18 | "@typescript-eslint/eslint-plugin": "^5.25.0", 19 | "@typescript-eslint/parser": "^5.25.0", 20 | "eslint": "^8.16.0", 21 | "@vercel/ncc": "^0.33.4", 22 | "prettier": "^2.6.2", 23 | "ts-node": "^10.8.0", 24 | "typescript": "^4.6.4" 25 | }, 26 | "dependencies": { 27 | "@actions/core": "^1.9.1", 28 | "azure-pipelines-task-lib": "^3.2.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/azure_devops_task.ts: -------------------------------------------------------------------------------- 1 | import tl = require("azure-pipelines-task-lib/task"); 2 | import { StoreApis, EnvVariablePrefix } from "./store_apis"; 3 | 4 | (async function main() { 5 | const storeApis = new StoreApis(); 6 | 7 | try { 8 | const command = tl.getInput("command"); 9 | switch (command) { 10 | case "configure": { 11 | storeApis.productId = tl.getInput("productId") || ""; 12 | storeApis.sellerId = tl.getInput("sellerId") || ""; 13 | storeApis.tenantId = tl.getInput("tenantId") || ""; 14 | storeApis.clientId = tl.getInput("clientId") || ""; 15 | storeApis.clientSecret = tl.getInput("clientSecret") || ""; 16 | 17 | await storeApis.InitAsync(); 18 | 19 | tl.setVariable( 20 | `${EnvVariablePrefix}product_id`, 21 | storeApis.productId, 22 | true, 23 | true 24 | ); 25 | tl.setVariable( 26 | `${EnvVariablePrefix}seller_id`, 27 | storeApis.sellerId, 28 | true, 29 | true 30 | ); 31 | tl.setVariable( 32 | `${EnvVariablePrefix}tenant_id`, 33 | storeApis.tenantId, 34 | true, 35 | true 36 | ); 37 | tl.setVariable( 38 | `${EnvVariablePrefix}client_id`, 39 | storeApis.clientId, 40 | true, 41 | true 42 | ); 43 | tl.setVariable( 44 | `${EnvVariablePrefix}client_secret`, 45 | storeApis.clientSecret, 46 | true, 47 | true 48 | ); 49 | tl.setVariable( 50 | `${EnvVariablePrefix}access_token`, 51 | storeApis.accessToken, 52 | true, 53 | true 54 | ); 55 | 56 | break; 57 | } 58 | 59 | case "get": { 60 | const moduleName = tl.getInput("moduleName") || ""; 61 | const listingLanguage = tl.getInput("listingLanguage") || "en"; 62 | const draftSubmission = await storeApis.GetExistingDraft( 63 | moduleName, 64 | listingLanguage 65 | ); 66 | tl.setVariable("draftSubmission", draftSubmission.toString()); 67 | 68 | break; 69 | } 70 | 71 | case "update": { 72 | const updatedMetadataString = tl.getInput("metadataUpdate"); 73 | const updatedProductString = tl.getInput("productUpdate"); 74 | if (!updatedMetadataString && !updatedProductString) { 75 | tl.setResult( 76 | tl.TaskResult.Failed, 77 | `Nothing to update. Both product-update and metadata-update are null.` 78 | ); 79 | return; 80 | } 81 | 82 | if (updatedMetadataString) { 83 | const updateSubmissionMetadata = 84 | await storeApis.UpdateSubmissionMetadata(updatedMetadataString); 85 | console.log(updateSubmissionMetadata); 86 | } 87 | 88 | if (updatedProductString) { 89 | const updateSubmissionData = await storeApis.UpdateProductPackages( 90 | updatedProductString 91 | ); 92 | console.log(updateSubmissionData); 93 | } 94 | 95 | break; 96 | } 97 | 98 | case "poll": { 99 | const pollingSubmissionId = tl.getInput("pollingSubmissionId"); 100 | 101 | if (!pollingSubmissionId) { 102 | tl.setResult( 103 | tl.TaskResult.Failed, 104 | `pollingSubmissionId parameter cannot be empty.` 105 | ); 106 | return; 107 | } 108 | 109 | const publishingStatus = await storeApis.PollSubmissionStatus( 110 | pollingSubmissionId 111 | ); 112 | tl.setVariable("submissionStatus", publishingStatus); 113 | 114 | break; 115 | } 116 | 117 | case "publish": { 118 | const submissionId = await storeApis.PublishSubmission(); 119 | tl.setVariable("pollingSubmissionId", submissionId); 120 | 121 | break; 122 | } 123 | 124 | default: { 125 | tl.setResult(tl.TaskResult.Failed, `Unknown command - ("${command}").`); 126 | 127 | break; 128 | } 129 | } 130 | } catch (error: unknown) { 131 | tl.setResult(tl.TaskResult.Failed, error as string); 132 | } 133 | })(); 134 | -------------------------------------------------------------------------------- /src/github_action.ts: -------------------------------------------------------------------------------- 1 | import * as core from "@actions/core"; 2 | import { StoreApis, EnvVariablePrefix } from "./store_apis"; 3 | 4 | (async function main() { 5 | const storeApis = new StoreApis(); 6 | 7 | try { 8 | const command = core.getInput("command"); 9 | switch (command) { 10 | case "configure": { 11 | storeApis.productId = core.getInput("product-id"); 12 | storeApis.sellerId = core.getInput("seller-id"); 13 | storeApis.tenantId = core.getInput("tenant-id"); 14 | storeApis.clientId = core.getInput("client-id"); 15 | storeApis.clientSecret = core.getInput("client-secret"); 16 | 17 | await storeApis.InitAsync(); 18 | 19 | core.exportVariable( 20 | `${EnvVariablePrefix}product_id`, 21 | storeApis.productId 22 | ); 23 | core.exportVariable( 24 | `${EnvVariablePrefix}seller_id`, 25 | storeApis.sellerId 26 | ); 27 | core.exportVariable( 28 | `${EnvVariablePrefix}tenant_id`, 29 | storeApis.tenantId 30 | ); 31 | core.exportVariable( 32 | `${EnvVariablePrefix}client_id`, 33 | storeApis.clientId 34 | ); 35 | core.exportVariable( 36 | `${EnvVariablePrefix}client_secret`, 37 | storeApis.clientSecret 38 | ); 39 | core.exportVariable( 40 | `${EnvVariablePrefix}access_token`, 41 | storeApis.accessToken 42 | ); 43 | core.setSecret(storeApis.productId); 44 | core.setSecret(storeApis.sellerId); 45 | core.setSecret(storeApis.tenantId); 46 | core.setSecret(storeApis.clientId); 47 | core.setSecret(storeApis.clientSecret); 48 | core.setSecret(storeApis.accessToken); 49 | 50 | break; 51 | } 52 | 53 | case "get": { 54 | const moduleName = core.getInput("module-name"); 55 | const listingLanguage = core.getInput("listing-language"); 56 | const draftSubmission = await storeApis.GetExistingDraft( 57 | moduleName, 58 | listingLanguage 59 | ); 60 | core.setOutput("draft-submission", draftSubmission); 61 | 62 | break; 63 | } 64 | 65 | case "update": { 66 | const updatedMetadataString = core.getInput("metadata-update"); 67 | const updatedProductString = core.getInput("product-update"); 68 | if (!updatedMetadataString && !updatedProductString) { 69 | core.setFailed( 70 | `Nothing to update. Both product-update and metadata-update are null.` 71 | ); 72 | return; 73 | } 74 | 75 | if (updatedMetadataString) { 76 | const updateSubmissionMetadata = 77 | await storeApis.UpdateSubmissionMetadata(updatedMetadataString); 78 | console.log(updateSubmissionMetadata); 79 | } 80 | 81 | if (updatedProductString) { 82 | const updateSubmissionData = await storeApis.UpdateProductPackages( 83 | updatedProductString 84 | ); 85 | console.log(updateSubmissionData); 86 | } 87 | 88 | break; 89 | } 90 | 91 | case "poll": { 92 | const pollingSubmissionId = core.getInput("polling-submission-id"); 93 | 94 | if (!pollingSubmissionId) { 95 | core.setFailed(`polling-submission-id parameter cannot be empty.`); 96 | return; 97 | } 98 | 99 | const publishingStatus = await storeApis.PollSubmissionStatus( 100 | pollingSubmissionId 101 | ); 102 | core.setOutput("submission-status", publishingStatus); 103 | 104 | break; 105 | } 106 | 107 | case "publish": { 108 | const submissionId = await storeApis.PublishSubmission(); 109 | core.setOutput("polling-submission-id", submissionId); 110 | 111 | break; 112 | } 113 | 114 | default: { 115 | core.setFailed(`Unknown command - ("${command}").`); 116 | 117 | break; 118 | } 119 | } 120 | } catch (error: unknown) { 121 | core.setFailed(error as string); 122 | } 123 | })(); 124 | -------------------------------------------------------------------------------- /src/store_apis.ts: -------------------------------------------------------------------------------- 1 | import * as https from "https"; 2 | 3 | export const EnvVariablePrefix = "MICROSOFT_STORE_ACTION_"; 4 | 5 | class ResponseWrapper { 6 | responseData: T; 7 | isSuccess: boolean; 8 | errors: Error[]; 9 | } 10 | 11 | class ErrorResponse { 12 | statusCode: number; 13 | message: string; 14 | } 15 | 16 | class Error { 17 | code: string; 18 | message: string; 19 | target: string; 20 | } 21 | 22 | class SubmissionResponse { 23 | pollingUrl: string; 24 | submissionId: string; 25 | ongoingSubmissionId: string; 26 | } 27 | 28 | enum PublishingStatus { 29 | INPROGRESS = "INPROGRESS", 30 | PUBLISHED = "PUBLISHED", 31 | FAILED = "FAILED", 32 | UNKNOWN = "UNKNOWN", 33 | } 34 | 35 | class ModuleStatus { 36 | isReady: boolean; 37 | ongoingSubmissionId: string; 38 | } 39 | 40 | class SubmissionStatus { 41 | publishingStatus: PublishingStatus; 42 | hasFailed: boolean; 43 | } 44 | 45 | class ListingAssetsResponse { 46 | listingAssets: ListingAsset[]; 47 | } 48 | 49 | class ImageSize { 50 | width: number; 51 | height: number; 52 | } 53 | 54 | class ListingAsset { 55 | language: string; 56 | storeLogos: StoreLogo[]; 57 | screenshots: Screenshot[]; 58 | } 59 | 60 | class Screenshot { 61 | id: string; 62 | assetUrl: string; 63 | imageSize: ImageSize; 64 | } 65 | 66 | class StoreLogo { 67 | id: string; 68 | assetUrl: string; 69 | imageSize: ImageSize; 70 | } 71 | 72 | export class StoreApis { 73 | private static readonly microsoftOnlineLoginHost = 74 | "login.microsoftonline.com"; 75 | private static readonly authOAuth2TokenSuffix = "/oauth2/v2.0/token"; 76 | private static readonly scope = "https://api.store.microsoft.com/.default"; 77 | private static readonly storeApiUrl = "api.store.microsoft.com"; 78 | 79 | constructor() { 80 | this.LoadState(); 81 | } 82 | 83 | public accessToken: string; 84 | public productId: string; 85 | public sellerId: string; 86 | public tenantId: string; 87 | public clientId: string; 88 | public clientSecret: string; 89 | 90 | private Delay(ms: number): Promise { 91 | return new Promise((resolve) => setTimeout(resolve, ms)); 92 | } 93 | 94 | private async GetAccessToken(): Promise { 95 | const requestParameters: { [key: string]: string } = { 96 | grant_type: "client_credentials", 97 | client_id: this.clientId, 98 | client_secret: this.clientSecret, 99 | scope: StoreApis.scope, 100 | }; 101 | 102 | const formBody = []; 103 | for (const property in requestParameters) { 104 | const encodedKey = encodeURIComponent(property); 105 | const encodedValue = encodeURIComponent(requestParameters[property]); 106 | formBody.push(encodedKey + "=" + encodedValue); 107 | } 108 | 109 | const dataString = formBody.join("\r\n&"); 110 | 111 | const options: https.RequestOptions = { 112 | host: StoreApis.microsoftOnlineLoginHost, 113 | path: `/${this.tenantId}${StoreApis.authOAuth2TokenSuffix}`, 114 | method: "POST", 115 | headers: { 116 | "Content-Type": "application/x-www-form-urlencoded", 117 | "Content-Length": dataString.length, 118 | }, 119 | }; 120 | 121 | return new Promise((resolve, reject) => { 122 | const req = https.request(options, (res) => { 123 | let responseString = ""; 124 | 125 | res.on("data", (data) => { 126 | responseString += data; 127 | }); 128 | 129 | res.on("end", function () { 130 | const responseObject = JSON.parse(responseString); 131 | if (responseObject.error) reject(responseObject); 132 | else resolve(responseObject.access_token); 133 | }); 134 | }); 135 | 136 | req.on("error", (e) => { 137 | console.error(e); 138 | reject(e); 139 | }); 140 | 141 | req.write(dataString); 142 | req.end(); 143 | }); 144 | } 145 | 146 | private GetCurrentDraftSubmissionPackagesData(): Promise< 147 | ResponseWrapper 148 | > { 149 | return this.CreateStoreHttpRequest( 150 | "", 151 | "GET", 152 | `/submission/v1/product/${this.productId}/packages` 153 | ); 154 | } 155 | 156 | private GetCurrentDraftSubmissionMetadata( 157 | moduleName: string, 158 | listingLanguages: string 159 | ): Promise> { 160 | return this.CreateStoreHttpRequest( 161 | "", 162 | "GET", 163 | `/submission/v1/product/${this.productId}/metadata/${moduleName}?languages=${listingLanguages}` 164 | ); 165 | } 166 | 167 | private UpdateCurrentDraftSubmissionMetadata( 168 | submissionMetadata: string 169 | ): Promise> { 170 | return this.CreateStoreHttpRequest( 171 | JSON.stringify(submissionMetadata), 172 | "PUT", 173 | `/submission/v1/product/${this.productId}/metadata` 174 | ); 175 | } 176 | 177 | private async UpdateStoreSubmissionPackages( 178 | submission: unknown 179 | ): Promise> { 180 | return this.CreateStoreHttpRequest( 181 | JSON.stringify(submission), 182 | "PUT", 183 | `/submission/v1/product/${this.productId}/packages` 184 | ); 185 | } 186 | 187 | private async CommitUpdateStoreSubmissionPackages(): Promise< 188 | ResponseWrapper 189 | > { 190 | return this.CreateStoreHttpRequest( 191 | "", 192 | "POST", 193 | `/submission/v1/product/${this.productId}/packages/commit` 194 | ); 195 | } 196 | 197 | private async GetModuleStatus(): Promise> { 198 | return this.CreateStoreHttpRequest( 199 | "", 200 | "GET", 201 | `/submission/v1/product/${this.productId}/status` 202 | ); 203 | } 204 | 205 | private async GetSubmissionStatus( 206 | submissionId: string 207 | ): Promise> { 208 | return this.CreateStoreHttpRequest( 209 | "", 210 | "GET", 211 | `/submission/v1/product/${this.productId}/submission/${submissionId}/status` 212 | ); 213 | } 214 | 215 | private async SubmitSubmission(): Promise< 216 | ResponseWrapper 217 | > { 218 | return this.CreateStoreHttpRequest( 219 | "", 220 | "POST", 221 | `/submission/v1/product/${this.productId}/submit` 222 | ); 223 | } 224 | 225 | private async GetCurrentDraftListingAssets( 226 | listingLanguages: string 227 | ): Promise> { 228 | return this.CreateStoreHttpRequest( 229 | "", 230 | "GET", 231 | `/submission/v1/product/${this.productId}/listings/assets?languages=${listingLanguages}` 232 | ); 233 | } 234 | 235 | private async CreateStoreHttpRequest( 236 | requestParameters: string, 237 | method: string, 238 | path: string 239 | ): Promise> { 240 | const options: https.RequestOptions = { 241 | host: StoreApis.storeApiUrl, 242 | path: path, 243 | method: method, 244 | headers: { 245 | "Content-Type": "application/json", 246 | "Content-Length": requestParameters.length, 247 | Authorization: "Bearer " + this.accessToken, 248 | "X-Seller-Account-Id": this.sellerId, 249 | }, 250 | }; 251 | 252 | return new Promise>((resolve, reject) => { 253 | const req = https.request(options, (res) => { 254 | if (res.statusCode == 404) { 255 | const error = new ResponseWrapper(); 256 | error.isSuccess = false; 257 | error.errors = []; 258 | error.errors[0] = new Error(); 259 | error.errors[0].message = "Not found"; 260 | reject(error); 261 | return; 262 | } 263 | let responseString = ""; 264 | 265 | res.on("data", (data) => { 266 | responseString += data; 267 | }); 268 | 269 | res.on("end", function () { 270 | const responseObject = >JSON.parse(responseString); 271 | resolve(responseObject); 272 | }); 273 | }); 274 | 275 | req.on("error", (e) => { 276 | console.error(e); 277 | reject(e); 278 | }); 279 | 280 | req.write(requestParameters); 281 | req.end(); 282 | }); 283 | } 284 | 285 | private async PollModuleStatus(): Promise { 286 | let status: ModuleStatus = new ModuleStatus(); 287 | status.isReady = false; 288 | 289 | while (!status.isReady) { 290 | const moduleStatus = await this.GetModuleStatus(); 291 | console.log(JSON.stringify(moduleStatus)); 292 | status = moduleStatus.responseData; 293 | if (!moduleStatus.isSuccess) { 294 | const errorResponse = moduleStatus as unknown as ErrorResponse; 295 | if (errorResponse.statusCode == 401) { 296 | console.log( 297 | `Access token expired. Requesting new one. (message='${errorResponse.message}')` 298 | ); 299 | await this.InitAsync(); 300 | status = new ModuleStatus(); 301 | status.isReady = false; 302 | continue; 303 | } 304 | console.log("Error"); 305 | break; 306 | } 307 | if (status.isReady) { 308 | console.log("Success!"); 309 | return true; 310 | } else { 311 | if ( 312 | moduleStatus.errors && 313 | moduleStatus.errors.length > 0 && 314 | moduleStatus.errors.find( 315 | (e) => e.target != "packages" || e.code == "packageuploaderror" 316 | ) 317 | ) { 318 | console.log(moduleStatus.errors); 319 | return false; 320 | } 321 | } 322 | 323 | console.log("Waiting 10 seconds."); 324 | await this.Delay(10000); 325 | } 326 | 327 | return false; 328 | } 329 | 330 | public async InitAsync() { 331 | this.accessToken = await this.GetAccessToken(); 332 | } 333 | 334 | public async GetExistingDraft( 335 | moduleName: string, 336 | listingLanguage: string 337 | ): Promise { 338 | return new Promise((resolve, reject) => { 339 | if ( 340 | moduleName && 341 | moduleName.toLowerCase() != "availability" && 342 | moduleName.toLowerCase() != "listings" && 343 | moduleName.toLowerCase() != "properties" 344 | ) { 345 | reject( 346 | "Module name must be 'availability', 'listings' or 'properties'" 347 | ); 348 | return; 349 | } 350 | 351 | (moduleName 352 | ? this.GetCurrentDraftSubmissionMetadata(moduleName, listingLanguage) 353 | : this.GetCurrentDraftSubmissionPackagesData() 354 | ) 355 | .then((currentDraftResponse) => { 356 | if (!currentDraftResponse.isSuccess) { 357 | reject( 358 | `Failed to get the existing draft. - ${JSON.stringify( 359 | currentDraftResponse, 360 | null, 361 | 2 362 | )}` 363 | ); 364 | } else { 365 | resolve(JSON.stringify(currentDraftResponse.responseData)); 366 | } 367 | }) 368 | .catch((error) => { 369 | reject(`Failed to get the existing draft. - ${error.errors}`); 370 | }); 371 | }); 372 | } 373 | 374 | public async PollSubmissionStatus( 375 | pollingSubmissionId: string 376 | ): Promise { 377 | let status: SubmissionStatus = new SubmissionStatus(); 378 | status.hasFailed = false; 379 | 380 | // eslint-disable-next-line no-async-promise-executor 381 | return new Promise(async (resolve, reject) => { 382 | while (!status.hasFailed) { 383 | const submissionStatus = await this.GetSubmissionStatus( 384 | pollingSubmissionId 385 | ); 386 | console.log(JSON.stringify(submissionStatus)); 387 | status = submissionStatus.responseData; 388 | if (!submissionStatus.isSuccess || status.hasFailed) { 389 | const errorResponse = submissionStatus as unknown as ErrorResponse; 390 | if (errorResponse.statusCode == 401) { 391 | console.log( 392 | `Access token expired. Requesting new one. (message='${errorResponse.message}')` 393 | ); 394 | await this.InitAsync(); 395 | status = new SubmissionStatus(); 396 | status.hasFailed = false; 397 | continue; 398 | } 399 | console.log("Error"); 400 | reject("Error"); 401 | return; 402 | } 403 | if ( 404 | status.publishingStatus == PublishingStatus.PUBLISHED || 405 | status.publishingStatus == PublishingStatus.FAILED 406 | ) { 407 | console.log(`PublishingStatus = ${status.publishingStatus}`); 408 | resolve(status.publishingStatus); 409 | return; 410 | } 411 | 412 | console.log("Waiting 10 seconds."); 413 | await this.Delay(10000); 414 | } 415 | }); 416 | } 417 | 418 | public async UpdateSubmissionMetadata( 419 | submissionMetadataString: string 420 | ): Promise { 421 | if (!(await this.PollModuleStatus())) { 422 | // Wait until all modules are in the ready state 423 | return Promise.reject("Failed to poll module status."); 424 | } 425 | 426 | const submissionMetadata = JSON.parse(submissionMetadataString); 427 | 428 | console.log(submissionMetadata); 429 | 430 | const updateSubmissionData = 431 | await this.UpdateCurrentDraftSubmissionMetadata(submissionMetadata); 432 | console.log(JSON.stringify(updateSubmissionData)); 433 | 434 | if (!updateSubmissionData.isSuccess) { 435 | return Promise.reject( 436 | `Failed to update submission metadata - ${JSON.stringify( 437 | updateSubmissionData.errors 438 | )}` 439 | ); 440 | } 441 | 442 | if (!(await this.PollModuleStatus())) { 443 | // Wait until all modules are in the ready state 444 | return Promise.reject("Failed to poll module status."); 445 | } 446 | 447 | return updateSubmissionData; 448 | } 449 | 450 | public async UpdateProductPackages( 451 | updatedProductString: string 452 | ): Promise { 453 | if (!(await this.PollModuleStatus())) { 454 | // Wait until all modules are in the ready state 455 | return Promise.reject("Failed to poll module status."); 456 | } 457 | 458 | const updatedProductPackages = JSON.parse(updatedProductString); 459 | 460 | console.log(updatedProductPackages); 461 | 462 | const updateSubmissionData = await this.UpdateStoreSubmissionPackages( 463 | updatedProductPackages 464 | ); 465 | console.log(JSON.stringify(updateSubmissionData)); 466 | 467 | if (!updateSubmissionData.isSuccess) { 468 | return Promise.reject( 469 | `Failed to update submission - ${JSON.stringify( 470 | updateSubmissionData.errors 471 | )}` 472 | ); 473 | } 474 | 475 | console.log("Committing package changes..."); 476 | 477 | const commitResult = await this.CommitUpdateStoreSubmissionPackages(); 478 | if (!commitResult.isSuccess) { 479 | return Promise.reject( 480 | `Failed to commit the updated submission - ${JSON.stringify( 481 | commitResult.errors 482 | )}` 483 | ); 484 | } 485 | console.log(JSON.stringify(commitResult)); 486 | 487 | if (!(await this.PollModuleStatus())) { 488 | // Wait until all modules are in the ready state 489 | return Promise.reject("Failed to poll module status."); 490 | } 491 | 492 | return updateSubmissionData; 493 | } 494 | 495 | public async PublishSubmission(): Promise { 496 | const commitResult = await this.CommitUpdateStoreSubmissionPackages(); 497 | if (!commitResult.isSuccess) { 498 | return Promise.reject( 499 | `Failed to commit the updated submission - ${JSON.stringify( 500 | commitResult.errors 501 | )}` 502 | ); 503 | } 504 | console.log(JSON.stringify(commitResult)); 505 | 506 | if (!(await this.PollModuleStatus())) { 507 | // Wait until all modules are in the ready state 508 | return Promise.reject("Failed to poll module status."); 509 | } 510 | 511 | let submissionId: string | null = null; 512 | 513 | const submitSubmissionResponse = await this.SubmitSubmission(); 514 | console.log(JSON.stringify(submitSubmissionResponse)); 515 | if (submitSubmissionResponse.isSuccess) { 516 | if ( 517 | submitSubmissionResponse.responseData.submissionId != null && 518 | submitSubmissionResponse.responseData.submissionId.length > 0 519 | ) { 520 | submissionId = submitSubmissionResponse.responseData.submissionId; 521 | } else if ( 522 | submitSubmissionResponse.responseData.ongoingSubmissionId != null && 523 | submitSubmissionResponse.responseData.ongoingSubmissionId.length > 0 524 | ) { 525 | submissionId = 526 | submitSubmissionResponse.responseData.ongoingSubmissionId; 527 | } 528 | } 529 | 530 | return new Promise((resolve, reject) => { 531 | if (submissionId == null) { 532 | console.log("Failed to get submission ID"); 533 | reject("Failed to get submission ID"); 534 | } else { 535 | resolve(submissionId); 536 | } 537 | }); 538 | } 539 | 540 | public async GetExistingDraftListingAssets( 541 | listingLanguage: string 542 | ): Promise { 543 | return new Promise((resolve, reject) => { 544 | this.GetCurrentDraftListingAssets(listingLanguage) 545 | .then((draftListingAssetsResponse) => { 546 | if (!draftListingAssetsResponse.isSuccess) { 547 | reject( 548 | `Failed to get the existing draft listing assets. - ${JSON.stringify( 549 | draftListingAssetsResponse, 550 | null, 551 | 2 552 | )}` 553 | ); 554 | } else { 555 | resolve(JSON.stringify(draftListingAssetsResponse.responseData)); 556 | } 557 | }) 558 | .catch((error) => { 559 | reject( 560 | `Failed to get the existing draft listing assets. - ${error.errors}` 561 | ); 562 | }); 563 | }); 564 | } 565 | 566 | private LoadState() { 567 | this.productId = process.env[`${EnvVariablePrefix}product_id`] ?? ""; 568 | this.sellerId = process.env[`${EnvVariablePrefix}seller_id`] ?? ""; 569 | this.tenantId = process.env[`${EnvVariablePrefix}tenant_id`] ?? ""; 570 | this.clientId = process.env[`${EnvVariablePrefix}client_id`] ?? ""; 571 | this.clientSecret = process.env[`${EnvVariablePrefix}client_secret`] ?? ""; 572 | this.accessToken = process.env[`${EnvVariablePrefix}access_token`] ?? ""; 573 | } 574 | } 575 | -------------------------------------------------------------------------------- /submission-task/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/store-submission/4da7b7621e16b0b7584303180fbe27b009c6b213/submission-task/icon.png -------------------------------------------------------------------------------- /submission-task/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/Microsoft/azure-pipelines-task-lib/master/tasks.schema.json", 3 | "id": "dc557d64-6cdc-4687-86b3-af66d2120fb4", 4 | "name": "MicrosoftStoreWin32Submissions", 5 | "friendlyName": "MicrosoftStoreWin32Submissions", 6 | "description": "Microsoft Store Task for submitting updates to Win32 Apps", 7 | "helpMarkDown": "", 8 | "category": "Utility", 9 | "author": "Microsoft", 10 | "version": { 11 | "Major": 0, 12 | "Minor": 1, 13 | "Patch": 0 14 | }, 15 | "instanceNameFormat": "Microsoft Store Submission Task", 16 | "inputs": [ 17 | { 18 | "name": "type", 19 | "type": "pickList", 20 | "label": "The type of Store Application. Available options are: `packaged` or `win32`", 21 | "defaultValue": "packaged", 22 | "required": false, 23 | "helpMarkDown": "The type of Store Application. Available options are: `packaged` or `win32`", 24 | "options": { 25 | "packaged": "Packaged", 26 | "win32": "Win32" 27 | } 28 | }, 29 | { 30 | "name": "command", 31 | "type": "pickList", 32 | "label": "The command to execute. Available command: `configure`, `get`, `update`, `poll`, or `publish`.", 33 | "defaultValue": "configure", 34 | "required": false, 35 | "helpMarkDown": "The command to execute. Available command: `configure`, `get`, `update`, `poll`, or `publish`.", 36 | "options": { 37 | "configure": "Configure", 38 | "get": "Get", 39 | "update": "Update", 40 | "poll": "Poll", 41 | "publish": "Publish" 42 | } 43 | }, 44 | { 45 | "name": "sellerId", 46 | "type": "string", 47 | "label": "Seller Id", 48 | "defaultValue": "", 49 | "required": false, 50 | "visibleRule": "command = configure", 51 | "helpMarkDown": "Seller Id" 52 | }, 53 | { 54 | "name": "productId", 55 | "type": "string", 56 | "label": "Product Id", 57 | "defaultValue": "", 58 | "required": false, 59 | "visibleRule": "command = configure", 60 | "helpMarkDown": "Product Id" 61 | }, 62 | { 63 | "name": "tenantId", 64 | "type": "string", 65 | "label": "AAD Tenant Id", 66 | "defaultValue": "", 67 | "required": false, 68 | "visibleRule": "command = configure", 69 | "helpMarkDown": "AAD Tenant Id" 70 | }, 71 | { 72 | "name": "clientId", 73 | "type": "string", 74 | "label": "App Client Id", 75 | "defaultValue": "", 76 | "required": false, 77 | "visibleRule": "command = configure", 78 | "helpMarkDown": "App Client Id" 79 | }, 80 | { 81 | "name": "clientSecret", 82 | "type": "string", 83 | "label": "App Client secret", 84 | "defaultValue": "", 85 | "required": false, 86 | "visibleRule": "command = configure", 87 | "helpMarkDown": "App Client secret" 88 | }, 89 | { 90 | "name": "moduleName", 91 | "type": "pickList", 92 | "label": "Indicates which module should be queried from the current draft (listing, properties or availability)", 93 | "defaultValue": "", 94 | "required": false, 95 | "visibleRule": "command = get", 96 | "helpMarkDown": "Indicates which module should be queried from the current draft (listing, properties or availability)", 97 | "options": { 98 | "": "", 99 | "listing": "Listing", 100 | "properties": "Properties", 101 | "availability": "Availability" 102 | } 103 | }, 104 | { 105 | "name": "listingLanguage", 106 | "type": "string", 107 | "label": "Indicates which listing language should be queries from the current draft", 108 | "defaultValue": "en", 109 | "required": false, 110 | "visibleRule": "command = get", 111 | "helpMarkDown": "Indicates which listing language should be queries from the current draft" 112 | }, 113 | { 114 | "name": "productUpdate", 115 | "type": "string", 116 | "label": "The Json payload that is used to update the package data", 117 | "defaultValue": "", 118 | "required": false, 119 | "visibleRule": "command = update", 120 | "helpMarkDown": "The Json to upload the package data" 121 | }, 122 | { 123 | "name": "metadataUpdate", 124 | "type": "string", 125 | "label": "The Json payload that is used to update the metadata data (listing, properties and/or availability)", 126 | "defaultValue": "", 127 | "required": false, 128 | "visibleRule": "command = update", 129 | "helpMarkDown": "The Json payload that is used to update the metadata data (listing, properties and/or availability)" 130 | }, 131 | { 132 | "name": "pollingSubmissionId", 133 | "type": "string", 134 | "label": "The Id of the active submission being processed", 135 | "defaultValue": "", 136 | "required": false, 137 | "visibleRule": "command = poll", 138 | "helpMarkDown": "The Id of the active submission being processed" 139 | } 140 | ], 141 | "execution": { 142 | "Node10": { 143 | "target": "index.js" 144 | } 145 | } 146 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Node 16", 4 | "compilerOptions": { 5 | "lib": ["ES2021"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "useDefineForClassFields": true, 13 | "moduleResolution": "node", 14 | "sourceMap": true, 15 | "outDir": "./lib", 16 | "rootDir": "./src", 17 | "strictPropertyInitialization": false, 18 | "types": [ 19 | "node" 20 | ] 21 | }, 22 | "exclude": [ 23 | "node_modules", 24 | "dist", 25 | "lib", 26 | "submission-task" 27 | ] 28 | } -------------------------------------------------------------------------------- /vss-extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": 1, 3 | "id": "microsoft-store-win32-release-task", 4 | "name": "Microsoft Store Win32 Release Tasks", 5 | "version": "0.1.0", 6 | "publisher": "Microsoft", 7 | "public": false, 8 | "targets": [ 9 | { 10 | "id": "Microsoft.VisualStudio.Services" 11 | } 12 | ], 13 | "description": "Tools for managing and releasing updates for Win32 apps to the Microsoft Store.", 14 | "categories": [ 15 | "Azure Pipelines" 16 | ], 17 | "icons": { 18 | "default": "images/extension-icon.png" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "uri": "https://github.com/Microsoft/store-submission" 23 | }, 24 | "files": [ 25 | { 26 | "path": "submission-task" 27 | } 28 | ], 29 | "contributions": [ 30 | { 31 | "id": "microsoft-store-win32-submissions-task", 32 | "type": "ms.vss-distributed-task.task", 33 | "targets": [ 34 | "ms.vss-distributed-task.tasks" 35 | ], 36 | "properties": { 37 | "name": "submission-task" 38 | } 39 | } 40 | ] 41 | } --------------------------------------------------------------------------------