├── .editorconfig ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── build.yml │ └── test-report.yml ├── .gitignore ├── .pipelines ├── 35MSSharedLib1024.snk ├── CredScanSuppressions.json ├── build.yml ├── code-inspector.yaml ├── release-nuget.config ├── release.yml └── templates │ ├── build-cli.yaml │ ├── build-nuget.yaml │ └── pack-nuget.yaml ├── .runsettings ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Directory.Build.props ├── Directory.Build.targets ├── LICENSE ├── MSStore.API ├── IStoreAPI.cs ├── MSStore.API.csproj ├── MSStoreException.cs ├── MSStoreHttpException.cs ├── MSStoreWrappedErrorException.cs ├── Models │ ├── Availability.cs │ ├── AvailabilityMetadataResponse.cs │ ├── CreateSubmissionResponse.cs │ ├── ErrorDetail.cs │ ├── ErrorResponse.cs │ ├── ErrorScenarioDetail.cs │ ├── ImageSize.cs │ ├── IsSystemFeatureRequired.cs │ ├── Listing.cs │ ├── ListingAsset.cs │ ├── ListingAssetsResponse.cs │ ├── ListingsMetadataResponse.cs │ ├── ModuleStatus.cs │ ├── Package.cs │ ├── PackagesMetadataResponse.cs │ ├── ProductDeclarations.cs │ ├── Properties.cs │ ├── PropertiesMetadataResponse.cs │ ├── PublishingStatus.cs │ ├── ResponseError.cs │ ├── ResponseWrapper.cs │ ├── ResponseWrapper{T}.cs │ ├── Screenshot.cs │ ├── StoreConfigurations.cs │ ├── StoreLogo.cs │ ├── SubmissionStatus.cs │ ├── SystemRequirementDetail.cs │ ├── UpdateMetadataRequest.cs │ ├── UpdateMetadataResponse.cs │ └── UpdatePackagesRequest.cs ├── Packaged │ ├── IStorePackagedAPI.cs │ ├── Models │ │ ├── ApplicationPackage.cs │ │ ├── ApplicationSubmissionInfo.cs │ │ ├── BaseListing.cs │ │ ├── CertificationReport.cs │ │ ├── CodeAndDetail.cs │ │ ├── DevCenterApplication.cs │ │ ├── DevCenterApplicationCategory.cs │ │ ├── DevCenterCommitResponse.cs │ │ ├── DevCenterError.cs │ │ ├── DevCenterFlight.cs │ │ ├── DevCenterFlightSubmission.cs │ │ ├── DevCenterFlightSubmissionUpdate.cs │ │ ├── DevCenterListing.cs │ │ ├── DevCenterSubmission.cs │ │ ├── DevCenterSubmissionExtensions.cs │ │ ├── DevCenterSubmissionStatusResponse.cs │ │ ├── FileStatus.cs │ │ ├── FlightPackageUpdate.cs │ │ ├── GamingOption.cs │ │ ├── IDevCenterSubmission.cs │ │ ├── Image.cs │ │ ├── ImageResource.cs │ │ ├── PackageDeliveryOptions.cs │ │ ├── PackageRollout.cs │ │ ├── PagedResponse.cs │ │ ├── Pricing.cs │ │ ├── StatusDetails.cs │ │ ├── Trailer.cs │ │ ├── TrailerAsset.cs │ │ └── UpperCaseNamingPolicy.cs │ └── StorePackagedAPI.cs ├── SourceGenerationContext.cs ├── StoreAPI.cs └── SubmissionClient.cs ├── MSStore.CLI.MSIX ├── Assets │ ├── AppList.scale-100.png │ ├── AppList.scale-125.png │ ├── AppList.scale-150.png │ ├── AppList.scale-200.png │ ├── AppList.scale-400.png │ ├── AppList.targetsize-16.png │ ├── AppList.targetsize-16_altform-lightunplated.png │ ├── AppList.targetsize-16_altform-unplated.png │ ├── AppList.targetsize-20.png │ ├── AppList.targetsize-20_altform-lightunplated.png │ ├── AppList.targetsize-20_altform-unplated.png │ ├── AppList.targetsize-24.png │ ├── AppList.targetsize-24_altform-lightunplated.png │ ├── AppList.targetsize-24_altform-unplated.png │ ├── AppList.targetsize-256.png │ ├── AppList.targetsize-256_altform-lightunplated.png │ ├── AppList.targetsize-256_altform-unplated.png │ ├── AppList.targetsize-30.png │ ├── AppList.targetsize-30_altform-lightunplated.png │ ├── AppList.targetsize-30_altform-unplated.png │ ├── AppList.targetsize-32.png │ ├── AppList.targetsize-32_altform-lightunplated.png │ ├── AppList.targetsize-32_altform-unplated.png │ ├── AppList.targetsize-36.png │ ├── AppList.targetsize-36_altform-lightunplated.png │ ├── AppList.targetsize-36_altform-unplated.png │ ├── AppList.targetsize-40.png │ ├── AppList.targetsize-40_altform-lightunplated.png │ ├── AppList.targetsize-40_altform-unplated.png │ ├── AppList.targetsize-48.png │ ├── AppList.targetsize-48_altform-lightunplated.png │ ├── AppList.targetsize-48_altform-unplated.png │ ├── AppList.targetsize-56.png │ ├── AppList.targetsize-56_altform-lightunplated.png │ ├── AppList.targetsize-56_altform-unplated.png │ ├── AppList.targetsize-60.png │ ├── AppList.targetsize-60_altform-lightunplated.png │ ├── AppList.targetsize-60_altform-unplated.png │ ├── AppList.targetsize-64.png │ ├── AppList.targetsize-64_altform-lightunplated.png │ ├── AppList.targetsize-64_altform-unplated.png │ ├── AppList.targetsize-72.png │ ├── AppList.targetsize-72_altform-lightunplated.png │ ├── AppList.targetsize-72_altform-unplated.png │ ├── AppList.targetsize-80.png │ ├── AppList.targetsize-80_altform-lightunplated.png │ ├── AppList.targetsize-80_altform-unplated.png │ ├── AppList.targetsize-96.png │ ├── AppList.targetsize-96_altform-lightunplated.png │ ├── AppList.targetsize-96_altform-unplated.png │ ├── Square150x150Logo.scale-100.png │ ├── Square150x150Logo.scale-400.png │ ├── StoreLogo.scale-100.png │ ├── StoreLogo.scale-125.png │ ├── StoreLogo.scale-150.png │ ├── StoreLogo.scale-200.png │ └── StoreLogo.scale-400.png ├── MSStore.CLI.MSIX.proj ├── MSStore.CLI.MSIX_TemporaryKey.pfx ├── Package.Store.appxmanifest └── Package.appxmanifest ├── MSStore.CLI.UnitTests ├── AppsCommandUnitTests.cs ├── BaseCommandLineTest.cs ├── CredentialManagerUnixTests.cs ├── CredentialManagerWindowsTests.cs ├── EmptyCommandUnitTests.cs ├── ExternalCommandExecutorTests.cs ├── FlightsCommandUnitTests.cs ├── FlightsSubmissionCommandUnitTests.cs ├── FlightsSubmissionRolloutCommandsUnitTests.cs ├── GraphClientTests.cs ├── InitCommandUnitTests.cs ├── MSStore.CLI.UnitTests.csproj ├── PackageCommandUnitTests.cs ├── ProductTypeHelperTests.cs ├── ProjectConfiguratorFactoryTests.cs ├── ProjectConfiguratorTests.cs ├── PublishCommandUnitTests.cs ├── ReconfigureCommandUnitTests.cs ├── SetPublisherDisplayNameCommandUnitTests.cs ├── SettingsCommandUnitTests.cs ├── SubmissionCommandPackagedUnitTests.cs ├── SubmissionCommandUnpackagedUnitTests.cs ├── TelemetryUnitTests.cs ├── TestData │ ├── ElectronProject │ │ ├── Npm │ │ │ └── package.json │ │ └── Yarn │ │ │ ├── .yarnrc.yml │ │ │ ├── package.json │ │ │ └── yarn.lock │ ├── FlutterProject │ │ └── pubspec.yaml │ ├── MSIXProject │ │ ├── AppxManifest.xml │ │ └── test.msix.template │ ├── MauiProject │ │ ├── MauiApp.csproj.template │ │ └── Platforms │ │ │ └── Windows │ │ │ └── Package.appxmanifest │ ├── ReactNativeProject │ │ ├── Npm │ │ │ ├── package.json │ │ │ └── windows │ │ │ │ ├── react_native_win_app_with_npm.sln │ │ │ │ └── react_native_win_app_with_npm │ │ │ │ └── Package.appxmanifest │ │ └── Yarn │ │ │ ├── package.json │ │ │ ├── windows │ │ │ ├── react_native_win_app_with_yarn.sln │ │ │ └── react_native_win_app_with_yarn │ │ │ │ └── Package.appxmanifest │ │ │ └── yarn.lock │ ├── UWPProject │ │ └── Package.appxmanifest │ └── WinUIProject │ │ └── Package.appxmanifest ├── Usings.cs └── VersionExtensionsUnitTests.cs ├── MSStore.CLI.sln ├── MSStore.CLI ├── CommandExtensions.cs ├── Commands │ ├── Apps │ │ ├── GetCommand.cs │ │ └── ListCommand.cs │ ├── AppsCommand.cs │ ├── Flights │ │ ├── CreateCommand.cs │ │ ├── DeleteCommand.cs │ │ ├── FlightSubmissionCommand.cs │ │ ├── GetCommand.cs │ │ ├── ListCommand.cs │ │ └── Submission │ │ │ ├── DeleteCommand.cs │ │ │ ├── GetCommand.cs │ │ │ ├── PollCommand.cs │ │ │ ├── PublishCommand.cs │ │ │ ├── Rollout │ │ │ ├── FinalizeCommand.cs │ │ │ ├── GetCommand.cs │ │ │ ├── HaltCommand.cs │ │ │ └── UpdateCommand.cs │ │ │ ├── RolloutCommand.cs │ │ │ ├── StatusCommand.cs │ │ │ └── UpdateCommand.cs │ ├── FlightsCommand.cs │ ├── InfoCommand.cs │ ├── InitCommand.cs │ ├── PackageCommand.cs │ ├── PublishCommand.cs │ ├── ReconfigureCommand.cs │ ├── Settings │ │ └── SetPublisherDisplayNameCommand.cs │ ├── SettingsCommand.cs │ ├── Submission │ │ ├── DeleteCommand.cs │ │ ├── GetCommand.cs │ │ ├── GetListingAssetsCommand.cs │ │ ├── PollCommand.cs │ │ ├── PublishCommand.cs │ │ ├── Rollout │ │ │ ├── FinalizeCommand.cs │ │ │ ├── GetCommand.cs │ │ │ ├── HaltCommand.cs │ │ │ └── UpdateCommand.cs │ │ ├── RolloutCommand.cs │ │ ├── StatusCommand.cs │ │ ├── UpdateCommand.cs │ │ └── UpdateMetadataCommand.cs │ └── SubmissionCommand.cs ├── Helpers │ ├── CustomSpectreConsoleFormatter.cs │ ├── CustomSpectreConsoleLogger.cs │ ├── CustomSpectreConsoleLoggerProvider.cs │ ├── DevCenterApplicationExtensions.cs │ ├── DevCenterErrorExtensions.cs │ ├── DevCenterFlightExtensions.cs │ ├── IProjectConfiguratorExtensions.cs │ ├── IStoreAPIExtensions.cs │ ├── IStorePackagedAPIExtensions.cs │ ├── ListExtensions.cs │ ├── NativeMethods.cs │ ├── ParseResultExtensions.cs │ ├── ProductType.cs │ ├── ProductTypeHelper.cs │ ├── ProjectImagesHelper.cs │ ├── StatusDetailsExtensions.cs │ ├── TelemetryHelper.cs │ └── VersionExtensions.cs ├── MSStore.CLI.csproj ├── MicrosoftStoreCLI.cs ├── Program.cs ├── ProjectConfigurators │ ├── AllowTargetFutureDeviceFamily.cs │ ├── Arch.cs │ ├── ElectronProjectConfigurator.cs │ ├── FileProjectConfigurator.cs │ ├── FlutterProjectConfigurator.cs │ ├── IProjectConfigurator.cs │ ├── IProjectConfiguratorFactory.cs │ ├── IProjectPackager.cs │ ├── IProjectPublisher.cs │ ├── MSIXProjectPublisher.cs │ ├── MauiProjectConfigurator.cs │ ├── NodeBaseProjectConfigurator.cs │ ├── PWAProjectConfigurator.cs │ ├── ProjectConfiguratorFactory.cs │ ├── PublishFileSearchFilterStrategy.cs │ ├── ReactNativeProjectConfigurator.cs │ ├── SubmissionImage.cs │ ├── SubmissionImageType.cs │ ├── UWPProjectConfigurator.cs │ └── WinUIProjectConfigurator.cs ├── Properties │ └── PublishProfiles │ │ ├── linux-arm64.pubxml │ │ ├── linux-x64.pubxml │ │ ├── osx-arm64.pubxml │ │ ├── osx-x64.pubxml │ │ ├── win-arm64.pubxml │ │ └── win-x64.pubxml ├── Services │ ├── AppXManifestManager.cs │ ├── AzureBlobManager.cs │ ├── BrowserLauncher.cs │ ├── CLIConfigurator.cs │ ├── ConfigurationManager.cs │ ├── Configurations.cs │ ├── ConfigurationsSourceGenerationContext.cs │ ├── ConsoleReader.cs │ ├── CredentialManager │ │ ├── ICredentialManager.cs │ │ ├── Unix │ │ │ ├── CredentialManagerUnix.cs │ │ │ └── NativeMethods.cs │ │ └── Windows │ │ │ └── CredentialManagerWindows.cs │ ├── ElectronManager │ │ ├── ElectronManifest.cs │ │ ├── ElectronManifestBuild.cs │ │ ├── ElectronManifestBuildAppX.cs │ │ ├── ElectronManifestBuildDirectories.cs │ │ ├── ElectronManifestBuildWindows.cs │ │ ├── ElectronManifestManager.cs │ │ ├── ElectronManifestSourceGenerationContext.cs │ │ └── IElectronManifestManager.cs │ ├── EnvironmentInformationService.cs │ ├── ExternalCommandExecutionResult.cs │ ├── ExternalCommandExecutor.cs │ ├── FileDownloader.cs │ ├── Graph │ │ ├── AppPasswordRegistrationRequest.cs │ │ ├── AppRegistrationRequest.cs │ │ ├── AppUpdateRequest.cs │ │ ├── AzureApplication.cs │ │ ├── CreateAppSecretResponse.cs │ │ ├── CreatePrincipalRequest.cs │ │ ├── CreatePrincipalResponse.cs │ │ ├── GraphClient.cs │ │ ├── GraphSourceGenerationContext.cs │ │ ├── IGraphClient.cs │ │ ├── ListResponse.cs │ │ └── Organization.cs │ ├── IAppXManifestManager.cs │ ├── IAzureBlobManager.cs │ ├── IBrowserLauncher.cs │ ├── ICLIConfigurator.cs │ ├── IConfigurationManager.cs │ ├── IConsoleReader.cs │ ├── IEnvironmentInformationService.cs │ ├── IExternalCommandExecutor.cs │ ├── IFileDownloader.cs │ ├── IImageConverter.cs │ ├── INuGetPackageManager.cs │ ├── IPWAAppInfoManager.cs │ ├── IStoreAPIFactory.cs │ ├── IZipFileManager.cs │ ├── ImageConverter.cs │ ├── NuGetPackageManager.cs │ ├── PWAAppInfoManager.cs │ ├── PWABuilder │ │ ├── ClassicPackage.cs │ │ ├── GenerateZipRequest.cs │ │ ├── IPWABuilderClient.cs │ │ ├── Icon.cs │ │ ├── IconExtensions.cs │ │ ├── PWAAppInfo.cs │ │ ├── PWAAppInfoSourceGenerationContext.cs │ │ ├── PWABuilderClient.cs │ │ ├── PWASourceGenerationContext .cs │ │ ├── Publisher.cs │ │ ├── ScreenShot.cs │ │ ├── WebManifestFindContent.cs │ │ ├── WebManifestFindResponse.cs │ │ └── WebManifestJson.cs │ ├── PartnerCenter │ │ ├── AccountEnrollment.cs │ │ ├── AccountEnrollmentExtensions.cs │ │ ├── AccountEnrollments.cs │ │ ├── IPartnerCenterManager.cs │ │ ├── PartnerCenterGenerationContext.cs │ │ └── PartnerCenterManager.cs │ ├── StoreAPIFactory.cs │ ├── Telemetry │ │ ├── TelemetryConfigurations.cs │ │ ├── TelemetryConnectionStringProvider.cs │ │ └── TelemetrySourceGenerationContext.cs │ ├── TokenManager │ │ ├── ITokenManager.cs │ │ └── MSALTokenManager.cs │ └── ZipFileManager.cs ├── StatusContextExtensions.cs ├── StoreHostBuilderExtensions.cs └── config.json ├── NOTICE.md ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── nuget.config ├── privacy.md └── version.json /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.cs text diff=csharp 3 | *.csproj text eol=crlf 4 | *.sln text eol=crlf -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | # Check for updates to GitHub Actions every week 7 | interval: "weekly" 8 | -------------------------------------------------------------------------------- /.github/workflows/test-report.yml: -------------------------------------------------------------------------------- 1 | name: 'Test Report' 2 | on: 3 | workflow_run: 4 | workflows: ['CI'] # runs after CI workflow 5 | types: 6 | - completed 7 | permissions: 8 | contents: read 9 | actions: read 10 | checks: write 11 | jobs: 12 | report: 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | os: [ windows-latest, ubuntu-latest, macos-latest ] 17 | runs-on: ${{ matrix.os }} 18 | steps: 19 | - name: Display test results 20 | uses: dorny/test-reporter@v1 21 | with: 22 | artifact: test-results-${{ matrix.os }} 23 | name: Test - Results - ${{ matrix.os }} 24 | path: '*.trx' 25 | reporter: dotnet-trx -------------------------------------------------------------------------------- /.pipelines/35MSSharedLib1024.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/.pipelines/35MSSharedLib1024.snk -------------------------------------------------------------------------------- /.pipelines/CredScanSuppressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "tool": "Credential Scanner", 3 | "suppressions": [ 4 | { 5 | "hash": "ncVbunIptO+qkjV7bm9zYiMK0qP3bLPcjgmpEnuZdWw=", 6 | "_justification": "False positive, not a secret" 7 | }, 8 | { 9 | "file": "\\MSStore.CLI.MSIX\\MSStore.CLI.MSIX_TemporaryKey.pfx", 10 | "_justification": "Only for testing, not an issue" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /.pipelines/code-inspector.yaml: -------------------------------------------------------------------------------- 1 | name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr) 2 | 3 | resources: 4 | repositories: 5 | - repository: 1ESPipelineTemplates 6 | type: git 7 | name: 1ESPipelineTemplates/1ESPipelineTemplates 8 | ref: refs/tags/release 9 | 10 | schedules: 11 | - cron: "0 0 1 * *" 12 | displayName: Monthly check 13 | branches: 14 | include: 15 | - main 16 | 17 | pr: none 18 | 19 | extends: 20 | template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates 21 | parameters: 22 | customBuildTags: 23 | - ES365AIMigrationTooling 24 | pool: 25 | name: Azure-Pipelines-1ESPT-ExDShared 26 | image: windows-2022 27 | os: windows 28 | sdl: 29 | sourceAnalysisPool: 30 | name: Azure-Pipelines-1ESPT-ExDShared 31 | image: windows-2022 32 | os: windows 33 | componentgovernance: 34 | ignoreDirectories: $(Build.SourcesDirectory)/MSStore.CLI.UnitTests/TestData,$(Build.SourcesDirectory)/MSStore.CLI.UnitTests/bin 35 | credscan: 36 | suppressionsFile: '$(System.DefaultWorkingDirectory)/.pipelines/CredScanSuppressions.json' 37 | binSkim: 38 | AnalyzeTargetGlob: '$(System.DefaultWorkingDirectory)\MSStore.API\bin\**\net9.0\MSStore.API.dll' 39 | stages: 40 | - stage: codeInspector 41 | displayName: Code Inspector 42 | jobs: 43 | - job: CodeInspector 44 | displayName: Code Inspector 45 | steps: 46 | - checkout: self 47 | - task: CodeInspector@2 48 | inputs: 49 | ProductId: $(STPID) 50 | - task: ComponentGovernanceComponentDetection@0 51 | displayName: 'Component Governance Detection' 52 | inputs: 53 | ignoreDirectories: $(Build.SourcesDirectory)/MSStore.CLI.UnitTests/TestData,$(Build.SourcesDirectory)/MSStore.CLI.UnitTests/bin -------------------------------------------------------------------------------- /.pipelines/release-nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | False 5 | 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to 4 | agree to a Contributor License Agreement (CLA) declaring that you have the right to, 5 | and actually do, grant us the rights to use your contribution. For details, visit 6 | https://cla.microsoft.com. 7 | 8 | When you submit a pull request, a CLA-bot will automatically determine whether you need 9 | to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the 10 | instructions provided by the bot. You will only need to do this once across all repositories using our CLA. 11 | 12 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 13 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 14 | or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2025 Microsoft Corporation 5 | Microsoft Corp. 6 | Copyright (C) 2025 Microsoft Corporation 7 | MSStoreCLI 8 | Microsoft Corporation 9 | en-US 10 | true 11 | Recommended 12 | 13 | true 14 | 15 | 16 | true 17 | 18 | 19 | true 20 | 21 | 22 | $(MSBuildThisFileDirectory)\.runsettings 23 | enable 24 | true 25 | 27 | 28 | 29 | 30 | true 31 | 32 | 33 | 34 | all 35 | 3.7.115 36 | 37 | 38 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /MSStore.API/IStoreAPI.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using MSStore.API.Models; 7 | 8 | namespace MSStore.API 9 | { 10 | public interface IStoreAPI 11 | { 12 | Task GetDraftAsync(string productId, string? moduleName, string languages, CancellationToken ct = default); 13 | Task GetDraftListingAssetsAsync(string productId, string languages, CancellationToken ct = default); 14 | Task> GetModuleStatusAsync(string productId, CancellationToken ct = default); 15 | Task> GetSubmissionStatusPollingAsync(string productId, string submissionId, CancellationToken ct = default); 16 | Task PublishSubmissionAsync(string productId, CancellationToken ct = default); 17 | Task UpdateProductPackagesAsync(string productId, UpdatePackagesRequest updatedProductPackages, bool skipInitialPolling = false, CancellationToken ct = default); 18 | Task UpdateSubmissionMetadataAsync(string productId, UpdateMetadataRequest submissionMetadata, bool skipInitialPolling = false, CancellationToken ct = default); 19 | } 20 | } -------------------------------------------------------------------------------- /MSStore.API/MSStore.API.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | 6 | $(NoWarn);CS1591 7 | MIT 8 | true 9 | https://github.com/microsoft/msstore-cli 10 | https://github.com/microsoft/msstore-cli/releases 11 | Microsoft Store;MSStoreAPI;MSStore;API 12 | true 13 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb 14 | true 15 | 16 | 17 | 18 | True 19 | ..\.pipelines\35MSSharedLib1024.snk 20 | True 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /MSStore.API/MSStoreException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.API 7 | { 8 | public class MSStoreException : Exception 9 | { 10 | public MSStoreException() 11 | { 12 | } 13 | 14 | public MSStoreException(string? message) 15 | : base(message) 16 | { 17 | } 18 | 19 | public MSStoreException(string? message, Exception? innerException) 20 | : base(message, innerException) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MSStore.API/MSStoreHttpException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Net.Http; 5 | 6 | namespace MSStore.API 7 | { 8 | public class MSStoreHttpException(HttpResponseMessage response) : MSStoreException 9 | { 10 | public HttpResponseMessage Response { get; private set; } = response; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/MSStoreWrappedErrorException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using MSStore.API.Models; 7 | 8 | namespace MSStore.API 9 | { 10 | public class MSStoreWrappedErrorException : MSStoreException 11 | { 12 | public List ResponseErrors { get; } 13 | 14 | public MSStoreWrappedErrorException(string? message, List? responseErrors) 15 | : base(message) 16 | { 17 | ResponseErrors = responseErrors ?? []; 18 | } 19 | 20 | public MSStoreWrappedErrorException(string? message, List? responseErrors, Exception? innerException) 21 | : base(message, innerException) 22 | { 23 | ResponseErrors = responseErrors ?? []; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MSStore.API/Models/Availability.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class Availability 9 | { 10 | public List? Markets { get; set; } 11 | public string? Discoverability { get; set; } 12 | public bool EnableInFutureMarkets { get; set; } 13 | public string? Pricing { get; set; } 14 | public string? FreeTrial { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.API/Models/AvailabilityMetadataResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class AvailabilityMetadataResponse 7 | { 8 | public Availability? Availability { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.API/Models/CreateSubmissionResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class CreateSubmissionResponse 7 | { 8 | public string? PollingUrl { get; set; } 9 | public string? SubmissionId { get; set; } 10 | public string? OngoingSubmissionId { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /MSStore.API/Models/ErrorDetail.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class ErrorDetail 9 | { 10 | public string? ErrorScenario { get; set; } 11 | public List? ErrorScenarioDetails { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.API/Models/ErrorResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ErrorResponse 7 | { 8 | public int StatusCode { get; set; } 9 | public string? Message { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /MSStore.API/Models/ErrorScenarioDetail.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ErrorScenarioDetail 7 | { 8 | public string? ErrorValue { get; set; } 9 | public string? ErrorUrl { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Models/ImageSize.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ImageSize 7 | { 8 | public int Width { get; set; } 9 | public int Height { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Models/IsSystemFeatureRequired.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class IsSystemFeatureRequired 7 | { 8 | public bool IsRequired { get; set; } 9 | public bool IsRecommended { get; set; } 10 | public string? HardwareItemType { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/Listing.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class Listing 9 | { 10 | public string? Language { get; set; } 11 | public string? Description { get; set; } 12 | public List? ProductFeatures { get; set; } 13 | public List? SearchTerms { get; set; } 14 | public string? AdditionalLicenseTerms { get; set; } 15 | public List? Requirements { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MSStore.API/Models/ListingAsset.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class ListingAsset 9 | { 10 | public string? Language { get; set; } 11 | public List? StoreLogos { get; set; } 12 | public List? Screenshots { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.API/Models/ListingAssetsResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class ListingAssetsResponse 9 | { 10 | public List? ListingAssets { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/ListingsMetadataResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class ListingsMetadataResponse 9 | { 10 | public List? Listings { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/ModuleStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ModuleStatus 7 | { 8 | public bool IsReady { get; set; } 9 | public string? OngoingSubmissionId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Models/Package.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class Package 9 | { 10 | public string? PackageUrl { get; set; } 11 | public List? Languages { get; set; } 12 | public List? Architectures { get; set; } 13 | public string? InstallerParameters { get; set; } 14 | public bool IsSilentInstall { get; set; } 15 | public string? GenericDocUrl { get; set; } 16 | public List? ErrorDetails { get; set; } 17 | public string? PackageType { get; set; } 18 | public string? PackageId { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.API/Models/PackagesMetadataResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class PackagesMetadataResponse 9 | { 10 | public List? Packages { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/ProductDeclarations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ProductDeclarations 7 | { 8 | public bool DependsOnDriversOrNT { get; set; } 9 | public bool AccessibilitySupport { get; set; } 10 | public bool PenAndInkSupport { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/Properties.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class Properties 9 | { 10 | public bool IsPrivacyPolicyRequired { get; set; } 11 | public string? PrivacyPolicyUrl { get; set; } 12 | public string? WebSite { get; set; } 13 | public string? SupportContactInfo { get; set; } 14 | public string? CertificationNotes { get; set; } 15 | public string? Category { get; set; } 16 | public string? SubCategory { get; set; } 17 | public ProductDeclarations? ProductDeclarations { get; set; } 18 | public List? IsSystemFeatureRequired { get; set; } 19 | public List? SystemRequirementDetails { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MSStore.API/Models/PropertiesMetadataResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class PropertiesMetadataResponse 7 | { 8 | public Properties? Properties { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.API/Models/PublishingStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | [JsonConverter(typeof(JsonStringEnumConverter))] 9 | public enum PublishingStatus 10 | { 11 | INPROGRESS, 12 | PUBLISHED, 13 | FAILED, 14 | UNKNOWN 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.API/Models/ResponseError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ResponseError 7 | { 8 | public string? Code { get; set; } 9 | public string? Message { get; set; } 10 | public string? Target { get; set; } 11 | 12 | public override string ToString() 13 | { 14 | return $"{Code} - {Message}"; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /MSStore.API/Models/ResponseWrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class ResponseWrapper 9 | { 10 | public bool IsSuccess { get; set; } 11 | public List? Errors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.API/Models/ResponseWrapper{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class ResponseWrapper : ResponseWrapper 7 | { 8 | public T? ResponseData { get; set; } 9 | 10 | public static implicit operator ResponseWrapper(ResponseWrapper v) 11 | { 12 | return new() 13 | { 14 | Errors = v.Errors, 15 | IsSuccess = v.IsSuccess, 16 | ResponseData = v.ResponseData 17 | }; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.API/Models/Screenshot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class Screenshot 7 | { 8 | public string? Id { get; set; } 9 | public string? AssetUrl { get; set; } 10 | public ImageSize? ImageSize { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/StoreConfigurations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class StoreConfigurations 9 | { 10 | public int? SellerId { get; set; } 11 | public Guid? TenantId { get; set; } 12 | public Guid? ClientId { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.API/Models/StoreLogo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class StoreLogo 7 | { 8 | public string? Id { get; set; } 9 | public string? AssetUrl { get; set; } 10 | public ImageSize? ImageSize { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/SubmissionStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class SubmissionStatus 7 | { 8 | public PublishingStatus PublishingStatus { get; set; } 9 | public bool HasFailed { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Models/SystemRequirementDetail.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class SystemRequirementDetail 7 | { 8 | public string? MinimumRequirement { get; set; } 9 | public string? RecommendedRequirement { get; set; } 10 | public string? HardwareItemType { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Models/UpdateMetadataRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class UpdateMetadataRequest 9 | { 10 | public Availability? Availability { get; set; } 11 | public Properties? Properties { get; set; } 12 | public List? Listings { get; set; } 13 | public List? ListingsToAdd { get; set; } 14 | public List? ListingsToRemove { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.API/Models/UpdateMetadataResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Models 5 | { 6 | public class UpdateMetadataResponse 7 | { 8 | public string? PollingUrl { get; set; } 9 | public string? OngoingSubmissionId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Models/UpdatePackagesRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Models 7 | { 8 | public class UpdatePackagesRequest 9 | { 10 | public List? Packages { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/ApplicationPackage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class ApplicationPackage 9 | { 10 | public string? FileName { get; set; } 11 | public FileStatus? FileStatus { get; set; } 12 | public string? Id { get; set; } 13 | public string? Version { get; set; } 14 | public string? Architecture { get; set; } 15 | public List? Languages { get; set; } 16 | public List? Capabilities { get; set; } 17 | public string? MinimumDirectXVersion { get; set; } 18 | public string? MinimumSystemRam { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/ApplicationSubmissionInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class ApplicationSubmissionInfo 7 | { 8 | public string? Id { get; set; } 9 | public string? ResourceLocation { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/BaseListing.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class BaseListing 9 | { 10 | public List? Keywords { get; set; } 11 | public string? Description { get; set; } 12 | public List? Features { get; set; } 13 | public string? ReleaseNotes { get; set; } 14 | public List? Images { get; set; } 15 | public List? RecommendedHardware { get; set; } 16 | public List? MinimumHardware { get; set; } 17 | public string? Title { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/CertificationReport.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class CertificationReport 7 | { 8 | public string? Date { get; set; } 9 | public string? ReportUrl { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/CodeAndDetail.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class CodeAndDetail 7 | { 8 | public string? Code { get; set; } 9 | public string? Details { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterApplication.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class DevCenterApplication 9 | { 10 | public string? Id { get; set; } 11 | public string? PrimaryName { get; set; } 12 | public string? PackageFamilyName { get; set; } 13 | public string? PackageIdentityName { get; set; } 14 | public string? PublisherName { get; set; } 15 | public DateTime? FirstPublishedDate { get; set; } 16 | public ApplicationSubmissionInfo? PendingApplicationSubmission { get; set; } 17 | public bool HasAdvancedListingPermission { get; set; } 18 | public ApplicationSubmissionInfo? LastPublishedApplicationSubmission { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterCommitResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class DevCenterCommitResponse : DevCenterError 7 | { 8 | public string? Status { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class DevCenterError 9 | { 10 | public string? Code { get; set; } 11 | public List? Data { get; set; } 12 | public List? Details { get; set; } 13 | public string? Message { get; set; } 14 | public string? Source { get; set; } 15 | public string? Target { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterFlight.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class DevCenterFlight 9 | { 10 | public string? FlightId { get; set; } 11 | public string? FriendlyName { get; set; } 12 | public ApplicationSubmissionInfo? LastPublishedFlightSubmission { get; set; } 13 | public ApplicationSubmissionInfo? PendingFlightSubmission { get; set; } 14 | public List? GroupIds { get; set; } 15 | public string? RankHigherThan { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterFlightSubmission.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace MSStore.API.Packaged.Models 8 | { 9 | public class DevCenterFlightSubmission : IDevCenterSubmission 10 | { 11 | public string? Id { get; set; } 12 | public string? FlightId { get; set; } 13 | public string? Status { get; set; } 14 | public StatusDetails? StatusDetails { get; set; } 15 | public List? FlightPackages { get; set; } 16 | public PackageDeliveryOptions? PackageDeliveryOptions { get; set; } 17 | public string? FileUploadUrl { get; set; } 18 | public string? TargetPublishMode { get; set; } 19 | public DateTime? TargetPublishDate { get; set; } 20 | public string? NotesForCertification { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterFlightSubmissionUpdate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace MSStore.API.Packaged.Models 8 | { 9 | public class DevCenterFlightSubmissionUpdate 10 | { 11 | public List? FlightPackages { get; set; } 12 | public PackageDeliveryOptions? PackageDeliveryOptions { get; set; } 13 | public string? TargetPublishMode { get; set; } 14 | public DateTime? TargetPublishDate { get; set; } 15 | public string? NotesForCertification { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterListing.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Text.Json; 6 | 7 | namespace MSStore.API.Packaged.Models 8 | { 9 | public class DevCenterListing 10 | { 11 | public BaseListing? BaseListing { get; set; } 12 | public Dictionary? PlatformOverrides { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterSubmission.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace MSStore.API.Packaged.Models 8 | { 9 | public class DevCenterSubmission : IDevCenterSubmission 10 | { 11 | public string? Id { get; set; } 12 | public DevCenterApplicationCategory? ApplicationCategory { get; set; } 13 | public Pricing? Pricing { get; set; } 14 | public string? Visibility { get; set; } 15 | public string? TargetPublishMode { get; set; } 16 | public DateTime? TargetPublishDate { get; set; } 17 | public Dictionary? Listings { get; set; } 18 | public List? HardwarePreferences { get; set; } 19 | public bool AutomaticBackupEnabled { get; set; } 20 | public bool CanInstallOnRemovableMedia { get; set; } 21 | public bool IsGameDvrEnabled { get; set; } 22 | public List? GamingOptions { get; set; } 23 | public bool HasExternalInAppProducts { get; set; } 24 | public bool MeetAccessibilityGuidelines { get; set; } 25 | public string? NotesForCertification { get; set; } 26 | public string? Status { get; set; } 27 | public StatusDetails? StatusDetails { get; set; } 28 | public string? FileUploadUrl { get; set; } 29 | public List? ApplicationPackages { get; set; } 30 | public PackageDeliveryOptions? PackageDeliveryOptions { get; set; } 31 | public string? EnterpriseLicensing { get; set; } 32 | public bool AllowMicrosoftDecideAppAvailabilityToFutureDeviceFamilies { get; set; } 33 | public Dictionary? AllowTargetFutureDeviceFamilies { get; set; } 34 | public string? FriendlyName { get; set; } 35 | public List? Trailers { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterSubmissionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace MSStore.API.Packaged.Models 8 | { 9 | public static class DevCenterSubmissionExtensions 10 | { 11 | public static List FilterUnsupported(this List? applicationPackages) 12 | { 13 | if (applicationPackages == null) 14 | { 15 | return []; 16 | } 17 | 18 | return applicationPackages.Where(p => 19 | p.Capabilities == null || 20 | (!p.Capabilities.Contains("Microsoft.storeFilter.core.notSupported_8wekyb3d8bbwe") 21 | && !p.Capabilities.Contains("coreNotSupported"))) 22 | .ToList(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/DevCenterSubmissionStatusResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class DevCenterSubmissionStatusResponse 7 | { 8 | public string? Status { get; set; } 9 | public StatusDetails? StatusDetails { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/FileStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | [JsonConverter(typeof(JsonStringEnumConverter))] 9 | public enum FileStatus 10 | { 11 | None, 12 | PendingUpload, 13 | Uploaded, 14 | PendingDelete 15 | } 16 | } -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/FlightPackageUpdate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class FlightPackageUpdate 7 | { 8 | public string? Id { get; set; } 9 | public string? FileName { get; set; } 10 | public FileStatus? FileStatus { get; set; } 11 | public string? MinimumDirectXVersion { get; set; } 12 | public string? MinimumSystemRam { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/GamingOption.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class GamingOption 9 | { 10 | public List? Genres { get; set; } 11 | public bool IsLocalMultiplayer { get; set; } 12 | public bool IsLocalCooperative { get; set; } 13 | public bool IsOnlineMultiplayer { get; set; } 14 | public bool IsOnlineCooperative { get; set; } 15 | public bool IsBroadcastingPrivilegeGranted { get; set; } 16 | public bool IsCrossPlayEnabled { get; set; } 17 | public string? KinectDataForExternal { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/IDevCenterSubmission.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public interface IDevCenterSubmission 9 | { 10 | public string? Id { get; set; } 11 | public string? Status { get; set; } 12 | public StatusDetails? StatusDetails { get; set; } 13 | public PackageDeliveryOptions? PackageDeliveryOptions { get; set; } 14 | public string? FileUploadUrl { get; set; } 15 | public string? TargetPublishMode { get; set; } 16 | public DateTime? TargetPublishDate { get; set; } 17 | public string? NotesForCertification { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/Image.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class Image 7 | { 8 | public string? FileName { get; set; } 9 | public FileStatus? FileStatus { get; set; } 10 | public string? Id { get; set; } 11 | public string? ImageType { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/ImageResource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class ImageResource 7 | { 8 | public string? FileName { get; set; } 9 | public string? Id { get; set; } 10 | public string? Description { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/PackageDeliveryOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class PackageDeliveryOptions 9 | { 10 | public PackageRollout? PackageRollout { get; set; } 11 | public bool IsMandatoryUpdate { get; set; } 12 | public DateTime? MandatoryUpdateEffectiveDate { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/PackageRollout.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.API.Packaged.Models 5 | { 6 | public class PackageRollout 7 | { 8 | public bool IsPackageRollout { get; set; } 9 | public float PackageRolloutPercentage { get; set; } 10 | public string? PackageRolloutStatus { get; set; } 11 | public string? FallbackSubmissionId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/PagedResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class PagedResponse 9 | { 10 | public string? NextLink { get; set; } 11 | public List? Value { get; set; } 12 | public int TotalCount { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/Pricing.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class Pricing 9 | { 10 | public string? TrialPeriod { get; set; } 11 | public Dictionary? MarketSpecificPricings { get; set; } 12 | public string? PriceId { get; set; } 13 | public bool IsAdvancedPricingModel { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/StatusDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class StatusDetails 9 | { 10 | public List? Errors { get; set; } 11 | public List? Warnings { get; set; } 12 | public List? CertificationReports { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/Trailer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class Trailer 9 | { 10 | public string? Id { get; set; } 11 | public string? VideoFileName { get; set; } 12 | public string? VideoFileId { get; set; } 13 | public Dictionary? TrailerAssets { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/TrailerAsset.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.API.Packaged.Models 7 | { 8 | public class TrailerAsset 9 | { 10 | public string? Title { get; set; } 11 | public List? ImageList { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.API/Packaged/Models/UpperCaseNamingPolicy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Text.Json; 7 | 8 | namespace MSStore.API.Packaged.Models 9 | { 10 | public class UpperCaseNamingPolicy : JsonNamingPolicy 11 | { 12 | public override string ConvertName(string name) 13 | { 14 | // Forces 1st letter of enum to be capitalized (required by Store REST API) 15 | return name.Length >= 1 ? string.Concat(name[0].ToString().ToUpper(CultureInfo.InvariantCulture), name.AsSpan(1)) : name; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.scale-100.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.scale-125.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.scale-150.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.scale-200.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.scale-400.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-16.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-16_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-16_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-16_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-16_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-20.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-20_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-20_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-20_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-20_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-24.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-24_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-24_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-256.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-256_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-256_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-256_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-256_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-30.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-30_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-30_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-30_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-30_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-32.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-32_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-32_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-32_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-32_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-36.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-36_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-36_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-36_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-36_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-40.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-40_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-40_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-40_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-40_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-48.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-48_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-48_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-48_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-48_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-56.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-56_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-56_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-56_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-56_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-60.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-60_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-60_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-60_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-60_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-64.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-64_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-64_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-64_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-64_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-72.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-72_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-72_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-72_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-72_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-80.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-80_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-80_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-80_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-80_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-96.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-96_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-96_altform-lightunplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/AppList.targetsize-96_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/AppList.targetsize-96_altform-unplated.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/MSStore.CLI.MSIX_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.MSIX/MSStore.CLI.MSIX_TemporaryKey.pfx -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Package.Store.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 16 | 17 | 18 | Microsoft Store Developer CLI 19 | Microsoft Corporation 20 | Assets\StoreLogo.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /MSStore.CLI.MSIX/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 16 | 17 | 18 | Microsoft Store CLI 19 | MSStore CLI TEST CERT 20 | Assets\StoreLogo.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/AppsCommandUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.UnitTests 5 | { 6 | [TestClass] 7 | public class AppsCommandUnitTests : BaseCommandLineTest 8 | { 9 | [TestInitialize] 10 | public void Init() 11 | { 12 | FakeLogin(); 13 | AddDefaultFakeAccount(); 14 | AddFakeApps(); 15 | } 16 | 17 | [TestMethod] 18 | public async Task AppsListCommandShouldReturnZero() 19 | { 20 | var result = await ParseAndInvokeAsync( 21 | [ 22 | "apps", 23 | "list" 24 | ]); 25 | 26 | result.Output.Should().ContainAll(FakeApps.Select(a => a.Id)); 27 | result.Output.Should().ContainAll(FakeApps.Select(a => a.PrimaryName)); 28 | } 29 | 30 | [TestMethod] 31 | public async Task AppsGetCommandShouldReturnZeroIfExistingApp() 32 | { 33 | var appId = FakeApps[2].Id!; 34 | var result = await ParseAndInvokeAsync( 35 | [ 36 | "apps", 37 | "get", 38 | appId 39 | ]); 40 | 41 | result.Output.Should().Contain($"\"Id\": \"{appId}\","); 42 | } 43 | 44 | [TestMethod] 45 | public async Task AppsGetCommandIsNotSupportedForUnpackagedApps() 46 | { 47 | var result = await ParseAndInvokeAsync( 48 | [ 49 | "apps", 50 | "get", 51 | Guid.Empty.ToString() 52 | ], -1); 53 | 54 | result.Error.Should().Contain("This command is not supported for unpackaged applications."); 55 | } 56 | 57 | [TestMethod] 58 | public async Task AppsGetCommandShouldReturnErrorIfNonExistingApp() 59 | { 60 | var result = await ParseAndInvokeAsync( 61 | [ 62 | "apps", 63 | "get", 64 | "9PN3ABCDEFGD" 65 | ], 66 | -1); 67 | 68 | result.Error.Should().Contain("Error!"); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/CredentialManagerUnixTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.InteropServices; 5 | using MSStore.CLI.Services.CredentialManager.Unix; 6 | 7 | namespace MSStore.CLI.UnitTests 8 | { 9 | [TestClass] 10 | public class CredentialManagerUnixTests 11 | { 12 | private CredentialManagerUnix _credentialManagerUnix = null!; 13 | 14 | [TestInitialize] 15 | public void Initialize() 16 | { 17 | _credentialManagerUnix = new CredentialManagerUnix(); 18 | _credentialManagerUnix.ClearCredentials("testUserName"); 19 | } 20 | 21 | [TestCleanup] 22 | public void Cleanup() 23 | { 24 | _credentialManagerUnix.ClearCredentials("testUserName"); 25 | } 26 | 27 | [TestMethod] 28 | public void CredentialManagerUnix_ReadCredential_ShouldReturnEmpty() 29 | { 30 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 31 | { 32 | Assert.Inconclusive("This test is only valid on non-Windows platforms"); 33 | } 34 | 35 | var secret = _credentialManagerUnix.ReadCredential("testUserName"); 36 | 37 | secret.Should().BeEmpty(); 38 | } 39 | 40 | [TestMethod] 41 | public void CredentialManagerUnix_WriteCredential_ShouldPersist() 42 | { 43 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 44 | { 45 | Assert.Inconclusive("This test is only valid on non-Windows platforms"); 46 | } 47 | 48 | _credentialManagerUnix.WriteCredential("testUserName", "testSecret"); 49 | 50 | var secret = _credentialManagerUnix.ReadCredential("testUserName"); 51 | 52 | secret.Should().Be("testSecret"); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/CredentialManagerWindowsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.CLI.Services.CredentialManager.Windows; 5 | 6 | namespace MSStore.CLI.UnitTests 7 | { 8 | [TestClass] 9 | public class CredentialManagerWindowsTests 10 | { 11 | private const string TestApplicationName = "MicrosoftStoreCliUnitTests"; 12 | 13 | private CredentialManagerWindows _credentialManagerWindows = null!; 14 | 15 | [TestInitialize] 16 | public void Initialize() 17 | { 18 | _credentialManagerWindows = new CredentialManagerWindows 19 | { 20 | ApplicationName = TestApplicationName 21 | }; 22 | _credentialManagerWindows.ClearCredentials("testUserName"); 23 | } 24 | 25 | [TestCleanup] 26 | public void Cleanup() 27 | { 28 | _credentialManagerWindows.ClearCredentials("testUserName"); 29 | } 30 | 31 | [TestMethod] 32 | public void CredentialManagerWindows_ReadCredential_ShouldReturnEmpty() 33 | { 34 | var secret = _credentialManagerWindows.ReadCredential("testUserName"); 35 | 36 | secret.Should().BeEmpty(); 37 | } 38 | 39 | [TestMethod] 40 | public void CredentialManagerWindows_WriteCredential_ShouldPersist() 41 | { 42 | _credentialManagerWindows.WriteCredential("testUserName", "testSecret"); 43 | 44 | var secret = _credentialManagerWindows.ReadCredential("testUserName"); 45 | 46 | secret.Should().Be("testSecret"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/EmptyCommandUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.UnitTests 5 | { 6 | [TestClass] 7 | public class EmptyCommandUnitTests : BaseCommandLineTest 8 | { 9 | [TestMethod] 10 | public async Task EmptyCommandShouldReturnZeroIfLoggedIn() 11 | { 12 | FakeLogin(); 13 | 14 | var result = await ParseAndInvokeAsync([]); 15 | 16 | result.Error.Should().Contain("CLI tool to automate Microsoft Store Developer tasks."); 17 | } 18 | 19 | [TestMethod] 20 | public async Task EmptyCommandShouldReturnZeroIfNotSignedIn() 21 | { 22 | FakeConsole 23 | .Setup(x => x.YesNoConfirmationAsync(It.IsAny(), It.IsAny())) 24 | .ReturnsAsync(true); 25 | 26 | var clientId = "3F0BCAEF-6334-48CF-837F-81CB0F1F2C45"; 27 | var secret = "ClientSecret"; 28 | 29 | FakeConsole 30 | .SetupSequence(x => x.RequestStringAsync(It.IsAny(), It.IsAny(), It.IsAny())) 31 | .ReturnsAsync(clientId) 32 | .ReturnsAsync(secret); 33 | 34 | AddDefaultFakeAccount(); 35 | 36 | AddDefaultGraphOrg(); 37 | 38 | var result = await ParseAndInvokeAsync([]); 39 | 40 | result.Error.Should().Contain("Awesome! It seems to be working!"); 41 | } 42 | 43 | [TestMethod] 44 | public async Task InfoCommandShouldReturnZero() 45 | { 46 | FakeLogin(); 47 | 48 | var result = await ParseAndInvokeAsync(["info"]); 49 | 50 | result.Output.Should().Contain("Current Config"); 51 | } 52 | 53 | [TestMethod] 54 | public async Task InfoCommandShouldReturnZeroWithCert() 55 | { 56 | FakeLoginWithCert(); 57 | 58 | var result = await ParseAndInvokeAsync(["info"]); 59 | 60 | result.Output.Should().Contain("Current Config"); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/InitCommandUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.UnitTests 5 | { 6 | [TestClass] 7 | public class InitCommandUnitTests : BaseCommandLineTest 8 | { 9 | [TestInitialize] 10 | public void Init() 11 | { 12 | FakeLogin(); 13 | } 14 | 15 | [TestMethod] 16 | public async Task InitCommandShouldUseDefaultDirectoryIfNoArgument() 17 | { 18 | var result = await ParseAndInvokeAsync( 19 | [ 20 | "init" 21 | ], -1); 22 | 23 | result.Error.Should().Contain($"We could not find a project configurator for the project at '{Directory.GetCurrentDirectory()}'."); 24 | } 25 | 26 | [TestMethod] 27 | public async Task InitCommandShouldOpenBrowserIfNotRegistered() 28 | { 29 | AddFakeAccount(null); 30 | 31 | var result = await ParseAndInvokeAsync( 32 | [ 33 | "init", 34 | "https://www.microsoft.com/", 35 | "--publish", 36 | "--verbose" 37 | ], -2); 38 | 39 | result.Error.Should().Contain("I'll redirect you to the Microsoft Store Sign-up page."); 40 | 41 | BrowserLauncher.Verify(x => x.OpenBrowserAsync("https://partner.microsoft.com/dashboard/registration", true, It.IsAny()), Times.Once); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/MSStore.CLI.UnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0;net9.0-windows10.0.17763.0 5 | net9.0 6 | enable 7 | enable 8 | 9 | $(NoWarn);CA1001;CA1812;CS1591 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | all 52 | runtime; build; native; contentfiles; analyzers; buildtransitive 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/ProductTypeHelperTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.CLI.Helpers; 5 | 6 | namespace MSStore.CLI.UnitTests 7 | { 8 | [TestClass] 9 | public class ProductTypeHelperTests 10 | { 11 | [TestMethod] 12 | public void Test_ProductTypeHelper_Solve_Unpackaged() 13 | { 14 | var productId = "12345678-1234-1234-1234-123456789012"; 15 | var productType = ProductTypeHelper.Solve(productId); 16 | Assert.AreEqual(productType, ProductType.Unpackaged); 17 | } 18 | 19 | [TestMethod] 20 | [DataRow("12345678-1234-1234-1234-12345678901")] 21 | [DataRow("1")] 22 | [DataRow("1234567890")] 23 | public void Test_ProductTypeHelper_Solve_Packaged(string productId) 24 | { 25 | var productType = ProductTypeHelper.Solve(productId); 26 | Assert.AreEqual(productType, ProductType.Packaged); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/SetPublisherDisplayNameCommandUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.CLI.Services; 5 | using MSStore.CLI.Services.PWABuilder; 6 | 7 | namespace MSStore.CLI.UnitTests 8 | { 9 | [TestClass] 10 | public class SetPublisherDisplayNameCommandUnitTests : BaseCommandLineTest 11 | { 12 | [TestInitialize] 13 | public void Init() 14 | { 15 | FakeLogin("Test Publisher Display Name"); 16 | AddDefaultFakeAccount(); 17 | AddFakeApps(); 18 | 19 | PWAAppInfoManager 20 | .Setup(x => x.LoadAsync(It.IsAny(), It.IsAny())) 21 | .ReturnsAsync(new PWAAppInfo 22 | { 23 | AppId = FakeApps[0].Id, 24 | Uri = new Uri("https://www.microsoft.com") 25 | }); 26 | 27 | PartnerCenterManager 28 | .Setup(x => x.Enabled) 29 | .Returns(false); 30 | } 31 | 32 | [TestMethod] 33 | public async Task InitCommandUsesPublisherDisplayNameFromSettings() 34 | { 35 | var publisherDisplayName = "Test Publisher Display Name"; 36 | 37 | var initResult = await ParseAndInvokeAsync( 38 | [ 39 | "init", 40 | "https://microsoft.com", 41 | "--publish", 42 | "--verbose" 43 | ], -1); 44 | 45 | initResult.Error.Should().Contain($"Using PublisherDisplayName: {publisherDisplayName}"); 46 | } 47 | 48 | [TestMethod] 49 | public async Task SetPublisherDisplayNameCommandShouldSaveSettings() 50 | { 51 | var publisherDisplayName = "New Test Publisher Display Name"; 52 | 53 | await ParseAndInvokeAsync( 54 | [ 55 | "settings", 56 | "setpdn", 57 | publisherDisplayName 58 | ]); 59 | 60 | FakeConfigurationManager 61 | .Verify(x => x.SaveAsync(It.Is(c => c.PublisherDisplayName == publisherDisplayName), It.IsAny())); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/SettingsCommandUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.CLI.Services.Telemetry; 5 | 6 | namespace MSStore.CLI.UnitTests 7 | { 8 | [TestClass] 9 | public class SettingsCommandUnitTests : BaseCommandLineTest 10 | { 11 | [TestInitialize] 12 | public void Init() 13 | { 14 | FakeLogin(); 15 | } 16 | 17 | [TestMethod] 18 | public async Task SettingsCommandWithNoParametersShouldReturnZeroAndShowHelp() 19 | { 20 | AddDefaultFakeAccount(); 21 | 22 | var result = await ParseAndInvokeAsync( 23 | [ 24 | "settings" 25 | ]); 26 | 27 | result.Error.Should().Contain("Usage:"); 28 | result.Error.Should().Contain("settings [command] [options]"); 29 | } 30 | 31 | [TestMethod] 32 | public async Task SettingsCommandShouldSetTelemetrySettingToTrue() 33 | { 34 | AddDefaultFakeAccount(); 35 | 36 | var result = await ParseAndInvokeAsync( 37 | [ 38 | "settings", 39 | "-t" 40 | ]); 41 | 42 | FakeTelemetryConfigurationManager 43 | .Verify(x => x.SaveAsync(It.Is(tc => tc.TelemetryEnabled == true), It.IsAny())); 44 | } 45 | 46 | [TestMethod] 47 | public async Task SettingsCommandShouldSetTelemetrySettingToFalse() 48 | { 49 | AddDefaultFakeAccount(); 50 | 51 | var result = await ParseAndInvokeAsync( 52 | [ 53 | "settings", 54 | "-t", 55 | "false" 56 | ]); 57 | 58 | FakeTelemetryConfigurationManager 59 | .Verify(x => x.SaveAsync(It.Is(tc => tc.TelemetryEnabled == false), It.IsAny())); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TelemetryUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.CLI.Services.Telemetry; 5 | 6 | namespace MSStore.CLI.UnitTests 7 | { 8 | [TestClass] 9 | public class TelemetryUnitTests : BaseCommandLineTest 10 | { 11 | [TestMethod] 12 | public async Task TelemetryConfigurationLoadsAsync() 13 | { 14 | var telemetryConnectionStringProvider = await TelemetryConnectionStringProvider.LoadAsync(default); 15 | 16 | telemetryConnectionStringProvider.Should().NotBeNull(); 17 | 18 | telemetryConnectionStringProvider?.AIConnectionString.Should().NotBeNullOrEmpty(); 19 | } 20 | 21 | [TestMethod] 22 | public async Task EmptyCommandFirstRunShouldHavePrivacyLinkIfNotSignedIn() 23 | { 24 | AddDefaultGraphOrg(); 25 | 26 | FakeConsole 27 | .Setup(x => x.YesNoConfirmationAsync(It.IsAny(), It.IsAny())) 28 | .ReturnsAsync(true); 29 | 30 | var result = await ParseAndInvokeAsync([], null); 31 | 32 | result.Error.Should().Contain("https://aka.ms/privacy"); 33 | } 34 | 35 | [TestMethod] 36 | public async Task EmptyCommandFirstRunShouldHavePrivacyLinkIfSignedIn() 37 | { 38 | FakeLogin(); 39 | 40 | var result = await ParseAndInvokeAsync([], null); 41 | 42 | result.Error.Should().Contain("https://aka.ms/privacy"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ElectronProject/Npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ElectronProject/Yarn/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | yarnPath: .yarn/releases/yarn-3.3.0.cjs 2 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ElectronProject/Yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yarn", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "packageManager": "yarn@3.3.0" 7 | } 8 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ElectronProject/Yarn/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/FlutterProject/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: my_flutter_app 2 | description: A new Flutter project. 3 | publish_to: 'none' 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=2.17.6 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | cupertino_icons: ^1.0.2 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | 18 | flutter_lints: ^2.0.0 19 | 20 | flutter: 21 | uses-material-design: true -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/MSIXProject/AppxManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | MSIXApp1 6 | Microsoft 7 | Assets\StoreLogo.png 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/MSIXProject/test.msix.template: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/msstore-cli/3801a81b9a955b6af20e1ef695f73c952c57de58/MSStore.CLI.UnitTests/TestData/MSIXProject/test.msix.template -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/MauiProject/MauiApp.csproj.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0-android;net9.0-ios;net9.0-maccatalyst 4 | $(TargetFrameworks);net9.0-windows10.0.19041.0 5 | 00000000-0000-0000-0000-000000000000 6 | AppTitle 7 | true 8 | 9 | 10 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/MauiProject/Platforms/Windows/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | $placeholder$ 15 | Microsoft 16 | $placeholder$.png 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react_native_win_app_with_npm", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "react": "18.1.0", 7 | "react-native": "0.70.0", 8 | "react-native-windows": "0.70.10" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Npm/windows/react_native_win_app_with_npm.sln: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Npm/windows/react_native_win_app_with_npm/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | UWPApp1 18 | Microsoft 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react_native_win_app_with_yarn", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "react": "18.1.0", 7 | "react-native": "0.70.0", 8 | "react-native-windows": "0.70.10" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Yarn/windows/react_native_win_app_with_yarn.sln: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Yarn/windows/react_native_win_app_with_yarn/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | UWPApp1 18 | Microsoft 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/ReactNativeProject/Yarn/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/UWPProject/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | UWPApp1 18 | Microsoft 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/TestData/WinUIProject/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | WinUIApp1 13 | Microsoft 14 | Assets\StoreLogo.png 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/Usings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | global using FluentAssertions; 5 | global using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | global using Moq; -------------------------------------------------------------------------------- /MSStore.CLI.UnitTests/VersionExtensionsUnitTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.CLI.Helpers; 5 | 6 | namespace MSStore.CLI.UnitTests 7 | { 8 | [TestClass] 9 | public class VersionExtensionsUnitTests 10 | { 11 | [DataRow(1, 2, null, null, false, "1.2.0.0")] 12 | [DataRow(1, 2, 3, null, false, "1.2.3.0")] 13 | [DataRow(1, 2, 3, 4, false, "1.2.3.4")] 14 | [DataRow(1, 2, null, null, true, "1.2.0")] 15 | [DataRow(1, 2, 3, null, true, "1.2.3")] 16 | [DataRow(1, 2, 3, 4, true, "1.2.3")] 17 | [TestMethod] 18 | public void ToVersionStringTests(int major, int minor, int? build, int? revision, bool ignoreRevision, string expected) 19 | { 20 | Version version; 21 | if (build == null) 22 | { 23 | version = new Version(major, minor); 24 | } 25 | else if (revision == null) 26 | { 27 | version = new Version(major, minor, build!.Value); 28 | } 29 | else 30 | { 31 | version = new Version(major, minor, build!.Value, revision!.Value); 32 | } 33 | 34 | var actual = version.ToVersionString(ignoreRevision); 35 | 36 | Assert.AreEqual(expected, actual); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MSStore.CLI/CommandExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.CommandLine; 6 | using System.CommandLine.Help; 7 | 8 | namespace MSStore.CLI 9 | { 10 | internal static class CommandExtensions 11 | { 12 | public static void SetDefaultHelpHandler(this Command command) 13 | { 14 | command.SetHandler((context) => 15 | { 16 | HelpBuilder helpBuilder = new(LocalizationResources.Instance, GetBufferWidth()); 17 | helpBuilder.Write(command, Console.Out); 18 | }); 19 | } 20 | 21 | internal static int GetBufferWidth() 22 | { 23 | try 24 | { 25 | return Console.BufferWidth; 26 | } 27 | catch 28 | { 29 | // Default to 240 30 | return 240; 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MSStore.CLI/Commands/AppsCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine; 5 | using MSStore.CLI.Commands.Apps; 6 | 7 | namespace MSStore.CLI.Commands 8 | { 9 | internal class AppsCommand : Command 10 | { 11 | public AppsCommand() 12 | : base("apps", "Execute apps related tasks.") 13 | { 14 | AddCommand(new ListCommand()); 15 | AddCommand(new GetCommand()); 16 | this.SetDefaultHelpHandler(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.CLI/Commands/Flights/FlightSubmissionCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine; 5 | 6 | namespace MSStore.CLI.Commands.Flights 7 | { 8 | internal class FlightSubmissionCommand : Command 9 | { 10 | public FlightSubmissionCommand() 11 | : base("submission", "Execute flight submissions related tasks.") 12 | { 13 | AddCommand(new Submission.GetCommand()); 14 | AddCommand(new Submission.DeleteCommand()); 15 | AddCommand(new Submission.UpdateCommand()); 16 | AddCommand(new Submission.PublishCommand()); 17 | AddCommand(new Submission.PollCommand()); 18 | AddCommand(new Submission.StatusCommand()); 19 | AddCommand(new Submission.RolloutCommand()); 20 | this.SetDefaultHelpHandler(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MSStore.CLI/Commands/Flights/Submission/RolloutCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine; 5 | 6 | namespace MSStore.CLI.Commands.Flights.Submission 7 | { 8 | internal class RolloutCommand : Command 9 | { 10 | public RolloutCommand() 11 | : base("rollout", "Execute flight rollout related operations") 12 | { 13 | AddCommand(new Rollout.GetCommand()); 14 | AddCommand(new Rollout.UpdateCommand()); 15 | AddCommand(new Rollout.HaltCommand()); 16 | AddCommand(new Rollout.FinalizeCommand()); 17 | this.SetDefaultHelpHandler(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.CLI/Commands/FlightsCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine; 5 | using MSStore.CLI.Commands.Flights; 6 | 7 | namespace MSStore.CLI.Commands 8 | { 9 | internal class FlightsCommand : Command 10 | { 11 | public FlightsCommand() 12 | : base("flights", "Execute flights related tasks.") 13 | { 14 | AddCommand(new ListCommand()); 15 | AddCommand(new GetCommand()); 16 | AddCommand(new DeleteCommand()); 17 | AddCommand(new CreateCommand()); 18 | AddCommand(new FlightSubmissionCommand()); 19 | this.SetDefaultHelpHandler(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MSStore.CLI/Commands/Settings/SetPublisherDisplayNameCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.CommandLine; 6 | using System.CommandLine.Invocation; 7 | using System.Threading.Tasks; 8 | using Microsoft.ApplicationInsights; 9 | using MSStore.CLI.Helpers; 10 | using MSStore.CLI.Services; 11 | 12 | namespace MSStore.CLI.Commands.Settings 13 | { 14 | // To be removed when PartnerCenterManager.Enabled == true 15 | internal class SetPublisherDisplayNameCommand : Command 16 | { 17 | public SetPublisherDisplayNameCommand() 18 | : base("setpdn", "Set the Publisher Display Name property that is used by the init command.") 19 | { 20 | var publisherDisplayName = new Argument("publisherDisplayName", "The Publisher Display Name property that will be set globally."); 21 | AddArgument(publisherDisplayName); 22 | } 23 | 24 | public new class Handler( 25 | IConfigurationManager configurationManager, 26 | TelemetryClient telemetryClient) : ICommandHandler 27 | { 28 | private readonly IConfigurationManager _configurationManager = configurationManager ?? throw new ArgumentNullException(nameof(configurationManager)); 29 | private readonly TelemetryClient _telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient)); 30 | 31 | public string? PublisherDisplayName { get; set; } 32 | 33 | public int Invoke(InvocationContext context) 34 | { 35 | return -1001; 36 | } 37 | 38 | public async Task InvokeAsync(InvocationContext context) 39 | { 40 | var ct = context.GetCancellationToken(); 41 | 42 | try 43 | { 44 | var config = await _configurationManager.LoadAsync(ct: ct); 45 | config.PublisherDisplayName = PublisherDisplayName; 46 | await _configurationManager.SaveAsync(config, ct); 47 | 48 | return await _telemetryClient.TrackCommandEventAsync(0, ct); 49 | } 50 | catch 51 | { 52 | return await _telemetryClient.TrackCommandEventAsync(-1, ct); 53 | } 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /MSStore.CLI/Commands/Submission/RolloutCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine; 5 | 6 | namespace MSStore.CLI.Commands.Submission 7 | { 8 | internal class RolloutCommand : Command 9 | { 10 | public RolloutCommand() 11 | : base("rollout", "Execute rollout related operations") 12 | { 13 | AddCommand(new Rollout.GetCommand()); 14 | AddCommand(new Rollout.UpdateCommand()); 15 | AddCommand(new Rollout.HaltCommand()); 16 | AddCommand(new Rollout.FinalizeCommand()); 17 | this.SetDefaultHelpHandler(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.CLI/Commands/SubmissionCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine; 5 | using MSStore.CLI.Commands.Submission; 6 | 7 | namespace MSStore.CLI.Commands 8 | { 9 | internal class SubmissionCommand : Command 10 | { 11 | internal static readonly Option LanguageOption; 12 | internal static readonly Option SkipInitialPolling; 13 | internal static readonly Argument ProductIdArgument; 14 | 15 | static SubmissionCommand() 16 | { 17 | LanguageOption = new Option( 18 | aliases: ["--language", "-l"], 19 | getDefaultValue: () => "en", 20 | description: "Select which language you want to retrieve."); 21 | SkipInitialPolling = new Option( 22 | aliases: ["--skipInitialPolling", "-s"], 23 | getDefaultValue: () => false, 24 | description: "Skip the initial polling before executing the action."); 25 | ProductIdArgument = new Argument( 26 | name: "productId", 27 | description: "The product ID."); 28 | } 29 | 30 | public SubmissionCommand() 31 | : base("submission", "Executes commands to a store submission.") 32 | { 33 | AddCommand(new StatusCommand()); 34 | AddCommand(new GetCommand()); 35 | AddCommand(new GetListingAssetsCommand()); 36 | AddCommand(new UpdateMetadataCommand()); 37 | AddCommand(new UpdateCommand()); 38 | AddCommand(new PollCommand()); 39 | AddCommand(new Submission.PublishCommand()); 40 | AddCommand(new DeleteCommand()); 41 | AddCommand(new RolloutCommand()); 42 | this.SetDefaultHelpHandler(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/CustomSpectreConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.Extensions.Logging; 7 | using Microsoft.Extensions.Logging.Abstractions; 8 | using Microsoft.Extensions.Logging.Console; 9 | using Spectre.Console; 10 | 11 | namespace MSStore.CLI.Helpers 12 | { 13 | internal class CustomSpectreConsoleLogger(string name, ConsoleFormatter formatter, IExternalScopeProvider? scopeProvider, IAnsiConsole ansiConsole) : ILogger 14 | { 15 | internal ConsoleFormatter Formatter { get; set; } = formatter; 16 | internal IExternalScopeProvider? ScopeProvider { get; set; } = scopeProvider; 17 | 18 | [ThreadStatic] 19 | private static StringWriter? _stringWriter; 20 | 21 | public IDisposable? BeginScope(TState state) 22 | where TState : notnull 23 | { 24 | return ScopeProvider?.Push(state); 25 | } 26 | 27 | public bool IsEnabled(LogLevel logLevel) 28 | { 29 | return logLevel != LogLevel.None; 30 | } 31 | 32 | public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) 33 | { 34 | if (!IsEnabled(logLevel)) 35 | { 36 | return; 37 | } 38 | 39 | _stringWriter ??= new StringWriter(); 40 | LogEntry logEntry = new LogEntry(logLevel, name, eventId, state, exception, formatter); 41 | Formatter.Write(in logEntry, ScopeProvider, _stringWriter); 42 | 43 | var sb = _stringWriter.GetStringBuilder(); 44 | if (sb.Length == 0) 45 | { 46 | return; 47 | } 48 | 49 | string computedAnsiString = sb.ToString(); 50 | sb.Clear(); 51 | if (sb.Capacity > 1024) 52 | { 53 | sb.Capacity = 1024; 54 | } 55 | 56 | ansiConsole.Markup(computedAnsiString); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/CustomSpectreConsoleLoggerProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Concurrent; 5 | using Microsoft.Extensions.Logging; 6 | using Microsoft.Extensions.Logging.Console; 7 | using Spectre.Console; 8 | 9 | namespace MSStore.CLI.Helpers 10 | { 11 | internal class CustomSpectreConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope 12 | { 13 | private readonly ConcurrentDictionary _loggers = new(); 14 | private readonly IAnsiConsole _ansiConsole; 15 | private ConsoleFormatter _formatter; 16 | private IExternalScopeProvider? _scopeProvider; 17 | 18 | public CustomSpectreConsoleLoggerProvider(IAnsiConsole ansiConsole) 19 | { 20 | _formatter = new CustomSpectreConsoleFormatter 21 | { 22 | FormatterOptions = new SimpleConsoleFormatterOptions 23 | { 24 | ColorBehavior = LoggerColorBehavior.Enabled, 25 | IncludeScopes = true, 26 | TimestampFormat = "hh:mm:ss ", 27 | SingleLine = true 28 | } 29 | }; 30 | _ansiConsole = ansiConsole; 31 | } 32 | 33 | public ILogger CreateLogger(string name) 34 | { 35 | return _loggers.GetOrAdd(name, (name) => new CustomSpectreConsoleLogger(name, _formatter, _scopeProvider, _ansiConsole)); 36 | } 37 | 38 | public void Dispose() 39 | { 40 | _loggers.Clear(); 41 | } 42 | 43 | public void SetScopeProvider(IExternalScopeProvider scopeProvider) 44 | { 45 | _scopeProvider = scopeProvider; 46 | 47 | foreach (var logger in _loggers) 48 | { 49 | logger.Value.ScopeProvider = _scopeProvider; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/DevCenterApplicationExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.API.Packaged.Models; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class DevCenterApplicationExtensions 9 | { 10 | public static string? GetAnySubmissionId(this DevCenterApplication application) 11 | { 12 | if (application.Id == null) 13 | { 14 | return null; 15 | } 16 | 17 | if (application.PendingApplicationSubmission?.Id != null) 18 | { 19 | return application.PendingApplicationSubmission.Id; 20 | } 21 | else if (application.LastPublishedApplicationSubmission?.Id != null) 22 | { 23 | return application.LastPublishedApplicationSubmission.Id; 24 | } 25 | 26 | return null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/DevCenterErrorExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.API.Packaged.Models; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class DevCenterErrorExtensions 9 | { 10 | public static string ToErrorMessage(this DevCenterError error) 11 | { 12 | var message = $"Error Code: {error.Code}{System.Environment.NewLine}"; 13 | message += $"Error Message: {error.Message}{System.Environment.NewLine}"; 14 | message += $"Error Source: {error.Source}{System.Environment.NewLine}"; 15 | message += $"Error Target: {error.Target}{System.Environment.NewLine}"; 16 | 17 | message += $"Error Data:{System.Environment.NewLine}"; 18 | if (error.Data?.Count > 0) 19 | { 20 | foreach (var data in error.Data) 21 | { 22 | message += $" {data}{System.Environment.NewLine}"; 23 | } 24 | } 25 | else 26 | { 27 | message += $" No data{System.Environment.NewLine}"; 28 | } 29 | 30 | message += $"Error Details:{System.Environment.NewLine}"; 31 | 32 | if (error.Details?.Count > 0) 33 | { 34 | foreach (var detail in error.Details) 35 | { 36 | message += $" {detail}{System.Environment.NewLine}"; 37 | } 38 | } 39 | else 40 | { 41 | message += $" No details{System.Environment.NewLine}"; 42 | } 43 | 44 | return message; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/DevCenterFlightExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using MSStore.API.Packaged.Models; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class DevCenterFlightExtensions 9 | { 10 | public static string? GetAnyFlightSubmissionId(this DevCenterFlight flight) 11 | { 12 | if (flight.FlightId == null) 13 | { 14 | return null; 15 | } 16 | 17 | if (flight.PendingFlightSubmission?.Id != null) 18 | { 19 | return flight.PendingFlightSubmission.Id; 20 | } 21 | else if (flight.LastPublishedFlightSubmission?.Id != null) 22 | { 23 | return flight.LastPublishedFlightSubmission.Id; 24 | } 25 | 26 | return null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/IProjectConfiguratorExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Extensions.Logging; 7 | using MSStore.CLI.ProjectConfigurators; 8 | using MSStore.CLI.Services; 9 | using Spectre.Console; 10 | 11 | namespace MSStore.CLI.Helpers 12 | { 13 | internal static class IProjectConfiguratorExtensions 14 | { 15 | internal static async Task ValidateImagesAsync(this IProjectConfigurator configurator, IAnsiConsole ansiConsole, string pathOrUrl, IImageConverter imageConverter, ILogger logger, CancellationToken ct) 16 | { 17 | var appImages = await configurator.GetAppImagesAsync(pathOrUrl, ct); 18 | if (appImages?.Count > 0) 19 | { 20 | var projectSpecificDefaultImages = await configurator.GetDefaultImagesAsync(pathOrUrl, ct); 21 | var defaultImages = ProjectImagesHelper.GetDefaultImagesUsedByApp(ansiConsole, appImages, projectSpecificDefaultImages, imageConverter, logger); 22 | if (defaultImages.Count > 0) 23 | { 24 | AnsiConsole.MarkupLine($"[bold yellow]The following images are using the default values and should be updated:[/]"); 25 | foreach (var image in defaultImages) 26 | { 27 | AnsiConsole.MarkupLine($"[bold yellow] {image}[/]"); 28 | } 29 | } 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/ListExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class ListExtensions 9 | { 10 | public static bool IsNullOrEmpty(this List? list) 11 | { 12 | return list == null || list.Count == 0; 13 | } 14 | 15 | public static bool IsNullOrEmpty(this Dictionary? dict) 16 | where TKey : notnull 17 | { 18 | return dict == null || dict.Count == 0; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace MSStore.CLI.Helpers 8 | { 9 | internal static class NativeMethods 10 | { 11 | [DllImport("kernel32.dll")] 12 | internal static extern IntPtr GetConsoleWindow(); 13 | 14 | [DllImport("user32.dll", ExactSpelling = true)] 15 | internal static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestorFlags flags); 16 | 17 | internal enum GetAncestorFlags 18 | { 19 | GetParent = 1, 20 | GetRoot = 2, 21 | GetRootOwner = 3 22 | } 23 | 24 | internal static IntPtr GetConsoleOrTerminalWindow() 25 | { 26 | IntPtr consoleHandle = GetConsoleWindow(); 27 | IntPtr handle = GetAncestor(consoleHandle, GetAncestorFlags.GetRootOwner); 28 | 29 | return handle; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/ParseResultExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.CommandLine.Parsing; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class ParseResultExtensions 9 | { 10 | public static bool IsVerbose(this ParseResult parseResult) 11 | { 12 | return parseResult.RootCommandResult.Command is MicrosoftStoreCLI storeCLI && 13 | parseResult.GetValueForOption(storeCLI.VerboseOption); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/ProductType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Helpers 5 | { 6 | internal enum ProductType 7 | { 8 | Packaged, 9 | Unpackaged, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/ProductTypeHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class ProductTypeHelper 9 | { 10 | public static ProductType Solve(string productId) 11 | { 12 | if (Guid.TryParse(productId, out _)) 13 | { 14 | return ProductType.Unpackaged; 15 | } 16 | else 17 | { 18 | return ProductType.Packaged; 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MSStore.CLI/Helpers/VersionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Helpers 7 | { 8 | internal static class VersionExtensions 9 | { 10 | public static string ToVersionString(this Version version, bool ignoreRevision = false) 11 | { 12 | if (version.Revision != -1 && !ignoreRevision) 13 | { 14 | return version.ToString(4); 15 | } 16 | 17 | var sufix = ignoreRevision ? string.Empty : ".0"; 18 | 19 | if (version.Build != -1) 20 | { 21 | return version.ToString(3) + sufix; 22 | } 23 | 24 | return $"{version}.0" + sufix; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/AllowTargetFutureDeviceFamily.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.ProjectConfigurators 5 | { 6 | internal enum AllowTargetFutureDeviceFamily 7 | { 8 | Desktop, 9 | Mobile, 10 | Holographic, 11 | Xbox, 12 | Team 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/Arch.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.ProjectConfigurators 5 | { 6 | internal enum BuildArch 7 | { 8 | X86, 9 | X64, 10 | Arm64 11 | } 12 | } -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/IProjectConfigurator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using MSStore.API.Packaged; 10 | using MSStore.API.Packaged.Models; 11 | 12 | namespace MSStore.CLI.ProjectConfigurators 13 | { 14 | internal interface IProjectConfigurator 15 | { 16 | Task CanConfigureAsync(string pathOrUrl, CancellationToken ct); 17 | 18 | int? ValidateCommand(string pathOrUrl, DirectoryInfo? output, bool? commandPackage, bool? commandPublish); 19 | 20 | Task<(int returnCode, DirectoryInfo? outputDirectory)> ConfigureAsync(string pathOrUrl, DirectoryInfo? output, string publisherDisplayName, DevCenterApplication app, Version? version, IStorePackagedAPI storePackagedAPI, CancellationToken ct); 21 | 22 | Task?> GetAppImagesAsync(string pathOrUrl, CancellationToken ct); 23 | 24 | Task?> GetDefaultImagesAsync(string pathOrUrl, CancellationToken ct); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/IProjectConfiguratorFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.ProjectConfigurators 8 | { 9 | internal interface IProjectConfiguratorFactory 10 | { 11 | Task FindProjectConfiguratorAsync(string pathOrUrl, CancellationToken ct); 12 | Task FindProjectPublisherAsync(string pathOrUrl, CancellationToken ct); 13 | } 14 | } -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/IProjectPackager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using MSStore.API.Packaged; 10 | using MSStore.API.Packaged.Models; 11 | 12 | namespace MSStore.CLI.ProjectConfigurators 13 | { 14 | internal interface IProjectPackager 15 | { 16 | bool PackageOnlyOnWindows { get; } 17 | IEnumerable? DefaultBuildArchs { get; } 18 | Task<(int returnCode, DirectoryInfo? outputDirectory)> PackageAsync(string pathOrUrl, DevCenterApplication? app, IEnumerable? buildArchs, Version? version, DirectoryInfo? output, IStorePackagedAPI storePackagedAPI, CancellationToken ct); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/IProjectPublisher.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using MSStore.API.Packaged; 8 | using MSStore.API.Packaged.Models; 9 | 10 | namespace MSStore.CLI.ProjectConfigurators 11 | { 12 | internal interface IProjectPublisher 13 | { 14 | Task GetAppIdAsync(FileInfo? fileInfo, CancellationToken ct); 15 | string[] PackageFilesExtensionInclude { get; } 16 | string[]? PackageFilesExtensionExclude { get; } 17 | SearchOption PackageFilesSearchOption { get; } 18 | AllowTargetFutureDeviceFamily[] AllowTargetFutureDeviceFamilies { get; } 19 | Task CanPublishAsync(string pathOrUrl, CancellationToken ct); 20 | Task PublishAsync(string pathOrUrl, DevCenterApplication? app, string? flightId, DirectoryInfo? inputDirectory, bool noCommit, float? packageRolloutPercentage, IStorePackagedAPI storePackagedAPI, CancellationToken ct); 21 | } 22 | } -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/ProjectConfiguratorFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace MSStore.CLI.ProjectConfigurators 11 | { 12 | internal class ProjectConfiguratorFactory(IServiceProvider serviceProvider) : IProjectConfiguratorFactory 13 | { 14 | private IServiceProvider _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); 15 | 16 | public async Task FindProjectConfiguratorAsync(string pathOrUrl, CancellationToken ct) 17 | { 18 | var projectConfigurators = _serviceProvider.GetServices(); 19 | foreach (var projectConfigurator in projectConfigurators) 20 | { 21 | if (await projectConfigurator.CanConfigureAsync(pathOrUrl, ct)) 22 | { 23 | return projectConfigurator; 24 | } 25 | } 26 | 27 | return null; 28 | } 29 | 30 | public async Task FindProjectPublisherAsync(string pathOrUrl, CancellationToken ct) 31 | { 32 | var projectPublishers = _serviceProvider.GetServices().ToList(); 33 | projectPublishers.AddRange(_serviceProvider.GetServices() 34 | .Where(c => c is IProjectPublisher projectPublisher && 35 | !projectPublishers.Contains(projectPublisher)) 36 | .Cast()); 37 | foreach (var projectPublisher in projectPublishers) 38 | { 39 | if (await projectPublisher.CanPublishAsync(pathOrUrl, ct)) 40 | { 41 | return projectPublisher; 42 | } 43 | } 44 | 45 | return null; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/PublishFileSearchFilterStrategy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.ProjectConfigurators 5 | { 6 | internal enum PublishFileSearchFilterStrategy 7 | { 8 | All, 9 | Newest, 10 | OneLevelDown 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/SubmissionImage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.ProjectConfigurators 5 | { 6 | internal class SubmissionImage(string fileName, SubmissionImageType imageType) 7 | { 8 | public string FileName { get; private set; } = fileName; 9 | public SubmissionImageType ImageType { get; private set; } = imageType; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.CLI/ProjectConfigurators/SubmissionImageType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.ProjectConfigurators 5 | { 6 | internal enum SubmissionImageType 7 | { 8 | // Screenshot images 9 | Screenshot, 10 | MobileScreenshot, 11 | XboxScreenshot, 12 | SurfaceHubScreenshot, 13 | HoloLensScreenshot, 14 | 15 | // Store logos 16 | StoreLogo9x16, 17 | StoreLogoSquare, 18 | Icon, 19 | 20 | // Promotional images 21 | PromotionalArt16x9, 22 | PromotionalArtwork2400X1200, 23 | 24 | // Xbox images 25 | XboxBrandedKeyArt, 26 | XboxTitledHeroArt, 27 | XboxFeaturedPromotionalArt, 28 | 29 | // Optional promotional images: 30 | SquareIcon358X358, 31 | BackgroundImage1000X800, 32 | PromotionalArtwork414X180, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MSStore.CLI/Properties/PublishProfiles/linux-arm64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net9.0\linux-arm64\publish\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net9.0 13 | linux-arm64 14 | false 15 | true 16 | true 17 | 18 | -------------------------------------------------------------------------------- /MSStore.CLI/Properties/PublishProfiles/linux-x64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net9.0\linux-x64\publish\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net9.0 13 | linux-x64 14 | false 15 | true 16 | true 17 | 18 | -------------------------------------------------------------------------------- /MSStore.CLI/Properties/PublishProfiles/osx-arm64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net9.0\osx-arm64\publish\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net9.0 13 | osx-arm64 14 | false 15 | true 16 | true 17 | 18 | -------------------------------------------------------------------------------- /MSStore.CLI/Properties/PublishProfiles/osx-x64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net9.0\osx-x64\publish\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net9.0 13 | osx-x64 14 | false 15 | true 16 | true 17 | 18 | -------------------------------------------------------------------------------- /MSStore.CLI/Properties/PublishProfiles/win-arm64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net9.0-windows10.0.17763.0\win-arm64\publish\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net9.0-windows10.0.17763.0 13 | win-arm64 14 | false 15 | true 16 | false 17 | 18 | 19 | -------------------------------------------------------------------------------- /MSStore.CLI/Properties/PublishProfiles/win-x64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net9.0-windows10.0.17763.0\win-x64\publish\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net9.0-windows10.0.17763.0 13 | win-x64 14 | false 15 | true 16 | false 17 | 18 | 19 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/AzureBlobManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Azure.Core; 9 | using Azure.Core.Pipeline; 10 | using Azure.Storage.Blobs; 11 | using Azure.Storage.Blobs.Models; 12 | using Microsoft.ApplicationInsights; 13 | using MSStore.API; 14 | 15 | namespace MSStore.CLI.Services 16 | { 17 | internal class AzureBlobManager(TelemetryClient telemetryClient) : IAzureBlobManager 18 | { 19 | private readonly TelemetryClient _telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient)); 20 | 21 | public async Task UploadFileAsync(string blobUri, string localFilePath, IProgress progress, CancellationToken ct) 22 | { 23 | using var fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read); 24 | 25 | var blobClientOptions = new BlobClientOptions(); 26 | blobClientOptions.AddPolicy(new AddCorrelationIdHeaderPolicy(_telemetryClient), HttpPipelinePosition.PerCall); 27 | var blobClient = new BlobClient(new Uri(blobUri.Replace("+", "%2B")), blobClientOptions); 28 | var blobUploadOptions = new BlobUploadOptions 29 | { 30 | HttpHeaders = new BlobHttpHeaders 31 | { 32 | ContentType = "application/zip" 33 | }, 34 | ProgressHandler = new Progress(bytesTransferred => 35 | { 36 | progress.Report((double)bytesTransferred * 100 / fileStream.Length); 37 | }), 38 | }; 39 | 40 | var response = await blobClient.UploadAsync(fileStream, blobUploadOptions, ct); 41 | if (response.Value != null) 42 | { 43 | return response.Value.ETag.ToString(); 44 | } 45 | else 46 | { 47 | throw new MSStoreException(response.GetRawResponse().ReasonPhrase); 48 | } 49 | } 50 | 51 | public class AddCorrelationIdHeaderPolicy(TelemetryClient telemetryClient) : HttpPipelineSynchronousPolicy 52 | { 53 | public override void OnSendingRequest(HttpMessage message) 54 | { 55 | message.Request.Headers.Add("ms-correlationid", telemetryClient.Context.Session.Id); 56 | base.OnSendingRequest(message); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Configurations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Text.Json.Serialization; 6 | using MSStore.API.Models; 7 | 8 | namespace MSStore.CLI.Services 9 | { 10 | internal class Configurations 11 | { 12 | public int? SellerId { get; set; } 13 | public Guid? TenantId { get; set; } 14 | public Guid? ClientId { get; set; } 15 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 16 | public string? CertificateThumbprint { get; set; } 17 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 18 | public string? CertificateFilePath { get; set; } 19 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 20 | public string? StoreApiServiceUrl { get; set; } 21 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 22 | public string? StoreApiScope { get; set; } 23 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 24 | public string? DevCenterServiceUrl { get; set; } 25 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 26 | public string? DevCenterScope { get; set; } 27 | 28 | // To be removed when PartnerCenterManager.Enabled == true 29 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 30 | public string? PublisherDisplayName { get; set; } 31 | 32 | public StoreConfigurations GetStoreConfigurations() => new() 33 | { 34 | SellerId = SellerId, 35 | ClientId = ClientId, 36 | TenantId = TenantId 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ConfigurationsSourceGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace MSStore.CLI.Services 7 | { 8 | /// 9 | /// Source Generator Configuration for JSON Serialization/Deserialization of the CLI Configurations. 10 | /// 11 | [JsonSerializable(typeof(Configurations))] 12 | internal partial class ConfigurationsSourceGenerationContext : JsonSerializerContext 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/CredentialManager/ICredentialManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.CredentialManager 5 | { 6 | internal interface ICredentialManager 7 | { 8 | string? ReadCredential(string userName); 9 | void WriteCredential(string userName, string secret); 10 | void ClearCredentials(string userName); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/CredentialManager/Windows/CredentialManagerWindows.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Linq; 5 | using Meziantou.Framework.Win32; 6 | 7 | namespace MSStore.CLI.Services.CredentialManager.Windows 8 | { 9 | internal class CredentialManagerWindows : ICredentialManager 10 | { 11 | internal string ApplicationName { get; set; } = "MicrosoftStoreCli"; 12 | 13 | private string GetCredentialName(string userName) => $"{ApplicationName}:user={userName}"; 14 | 15 | public string? ReadCredential(string userName) 16 | { 17 | var clientCredential = Meziantou.Framework.Win32.CredentialManager.ReadCredential(GetCredentialName(userName)); 18 | 19 | if (clientCredential != null) 20 | { 21 | return clientCredential.Password; 22 | } 23 | 24 | return string.Empty; 25 | } 26 | 27 | public void WriteCredential(string userName, string secret) 28 | { 29 | Meziantou.Framework.Win32.CredentialManager.WriteCredential(GetCredentialName(userName), userName, secret, CredentialPersistence.LocalMachine); 30 | } 31 | 32 | public void ClearCredentials(string userName) 33 | { 34 | try 35 | { 36 | var credentialName = GetCredentialName(userName); 37 | if (Meziantou.Framework.Win32.CredentialManager.EnumerateCredentials(credentialName).Any()) 38 | { 39 | Meziantou.Framework.Win32.CredentialManager.DeleteCredential(credentialName); 40 | } 41 | } 42 | catch 43 | { 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Text.Json; 6 | using System.Text.Json.Serialization; 7 | 8 | namespace MSStore.CLI.Services.ElectronManager 9 | { 10 | internal class ElectronManifest 11 | { 12 | [JsonExtensionData] 13 | public Dictionary? ExtensionData { get; set; } 14 | 15 | [JsonPropertyName("build")] 16 | public ElectronManifestBuild? Build { get; set; } 17 | [JsonPropertyName("msstoreCliAppId")] 18 | [JsonPropertyOrder(int.MaxValue)] 19 | public string? MSStoreCLIAppID { get; set; } 20 | [JsonPropertyName("version")] 21 | public string? Version { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifestBuild.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Text.Json; 6 | using System.Text.Json.Serialization; 7 | 8 | namespace MSStore.CLI.Services.ElectronManager 9 | { 10 | internal class ElectronManifestBuild 11 | { 12 | [JsonPropertyName("appId")] 13 | public string? AppId { get; set; } 14 | [JsonPropertyName("productId")] 15 | public string? ProductId { get; set; } 16 | [JsonPropertyName("win")] 17 | public ElectronManifestBuildWindows? Windows { get; set; } 18 | [JsonPropertyName("appx")] 19 | public ElectronManifestBuildAppX? Appx { get; set; } 20 | [JsonPropertyName("directories")] 21 | public ElectronManifestBuildDirectories? Directories { get; set; } 22 | [JsonExtensionData] 23 | public Dictionary? ExtensionData { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifestBuildAppX.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Text.Json; 6 | using System.Text.Json.Serialization; 7 | 8 | namespace MSStore.CLI.Services.ElectronManager 9 | { 10 | internal class ElectronManifestBuildAppX 11 | { 12 | [JsonPropertyName("applicationId")] 13 | public string? ApplicationId { get; set; } 14 | [JsonPropertyName("displayName")] 15 | public string? DisplayName { get; set; } 16 | [JsonPropertyName("publisher")] 17 | public string? Publisher { get; set; } 18 | [JsonPropertyName("publisherDisplayName")] 19 | public string? PublisherDisplayName { get; set; } 20 | [JsonPropertyName("identityName")] 21 | public string? IdentityName { get; set; } 22 | [JsonExtensionData] 23 | public Dictionary? ExtensionData { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifestBuildDirectories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Text.Json; 6 | using System.Text.Json.Serialization; 7 | 8 | namespace MSStore.CLI.Services.ElectronManager 9 | { 10 | internal class ElectronManifestBuildDirectories 11 | { 12 | [JsonPropertyName("output")] 13 | public string? Output { get; set; } 14 | [JsonPropertyName("buildResources")] 15 | public string? BuildResources { get; set; } 16 | [JsonExtensionData] 17 | public Dictionary? ExtensionData { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifestBuildWindows.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Text.Json; 6 | using System.Text.Json.Nodes; 7 | using System.Text.Json.Serialization; 8 | 9 | namespace MSStore.CLI.Services.ElectronManager 10 | { 11 | internal class ElectronManifestBuildWindows 12 | { 13 | [JsonPropertyName("target")] 14 | public JsonNode? Targets { get; set; } 15 | [JsonExtensionData] 16 | public Dictionary? ExtensionData { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifestManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Text.Json; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace MSStore.CLI.Services.ElectronManager 10 | { 11 | internal class ElectronManifestManager : IElectronManifestManager 12 | { 13 | public async Task LoadAsync(FileInfo manifestFileInfo, CancellationToken ct) 14 | { 15 | try 16 | { 17 | using var file = manifestFileInfo.OpenRead(); 18 | 19 | return await JsonSerializer.DeserializeAsync(file, ElectronManifestSourceGenerationContext.GetCustom().ElectronManifest, ct) 20 | ?? new ElectronManifest(); 21 | } 22 | catch (FileNotFoundException) 23 | { 24 | return new ElectronManifest(); 25 | } 26 | } 27 | 28 | public async Task SaveAsync(ElectronManifest electronManifest, FileInfo manifestFileInfo, CancellationToken ct) 29 | { 30 | using var file = manifestFileInfo.Open(FileMode.OpenOrCreate); 31 | file.SetLength(0); 32 | file.Position = 0; 33 | 34 | await JsonSerializer.SerializeAsync( 35 | file, 36 | electronManifest, 37 | ElectronManifestSourceGenerationContext.GetCustom(true).ElectronManifest, 38 | ct); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/ElectronManifestSourceGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | 7 | namespace MSStore.CLI.Services.ElectronManager 8 | { 9 | /// 10 | /// Source Generator Configuration for JSON Serialization/Deserialization of the PWA Application Informations. 11 | /// 12 | [JsonSourceGenerationOptions] 13 | [JsonSerializable(typeof(ElectronManifest))] 14 | internal partial class ElectronManifestSourceGenerationContext : JsonSerializerContext 15 | { 16 | private static ElectronManifestSourceGenerationContext? _default; 17 | private static ElectronManifestSourceGenerationContext? _defaultPretty; 18 | 19 | public static ElectronManifestSourceGenerationContext GetCustom(bool writeIndented = false) 20 | { 21 | if (writeIndented) 22 | { 23 | return _defaultPretty ??= 24 | CreateCustom(writeIndented); 25 | } 26 | else 27 | { 28 | return _default ??= 29 | CreateCustom(writeIndented); 30 | } 31 | 32 | static ElectronManifestSourceGenerationContext CreateCustom(bool writeIndented) 33 | { 34 | return new ElectronManifestSourceGenerationContext(new JsonSerializerOptions 35 | { 36 | DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, 37 | PropertyNameCaseInsensitive = true, 38 | IgnoreReadOnlyFields = false, 39 | AllowTrailingCommas = true, 40 | IgnoreReadOnlyProperties = false, 41 | IncludeFields = false, 42 | WriteIndented = writeIndented, 43 | Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, 44 | }); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ElectronManager/IElectronManifestManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MSStore.CLI.Services.ElectronManager 9 | { 10 | internal interface IElectronManifestManager 11 | { 12 | Task LoadAsync(FileInfo manifestFileInfo, CancellationToken ct); 13 | Task SaveAsync(ElectronManifest electronManifest, FileInfo manifestFileInfo, CancellationToken ct); 14 | } 15 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/EnvironmentInformationService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Microsoft.Extensions.Logging; 6 | 7 | namespace MSStore.CLI.Services 8 | { 9 | internal class EnvironmentInformationService : IEnvironmentInformationService 10 | { 11 | private readonly bool _runningOnCI; 12 | 13 | public EnvironmentInformationService(ILogger logger) 14 | { 15 | _runningOnCI = false; 16 | var envVariablesTable = new (string EnvVariable, string Value)[] 17 | { 18 | ("CI", "true"), 19 | ("TF_BUILD", "true") 20 | }; 21 | 22 | try 23 | { 24 | foreach (var envVariable in envVariablesTable) 25 | { 26 | var value = Environment.GetEnvironmentVariable(envVariable.EnvVariable); 27 | if (value != null && value.Equals(envVariable.Value, StringComparison.OrdinalIgnoreCase)) 28 | { 29 | _runningOnCI = true; 30 | logger.LogInformation("Running on CI. {EnvVariable}={Value}", envVariable.EnvVariable, envVariable.Value); 31 | break; 32 | } 33 | } 34 | } 35 | catch (Exception ex) 36 | { 37 | logger.LogError(ex, "Error while checking if running on CI."); 38 | } 39 | } 40 | 41 | public bool IsRunningOnCI => _runningOnCI; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ExternalCommandExecutionResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services 5 | { 6 | internal struct ExternalCommandExecutionResult 7 | { 8 | public int ExitCode; 9 | public string StdOut; 10 | public string StdErr; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/FileDownloader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Net.Http; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace MSStore.CLI.Services 12 | { 13 | internal class FileDownloader(IHttpClientFactory httpClientFactory) : IFileDownloader 14 | { 15 | private readonly IHttpClientFactory _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); 16 | 17 | public async Task DownloadAsync(string url, string destinationFileName, IProgress progress, ILogger? logger, CancellationToken ct = default) 18 | { 19 | progress.Report(0); 20 | 21 | try 22 | { 23 | using var httpClient = _httpClientFactory.CreateClient("Default"); 24 | using var request = new HttpRequestMessage(HttpMethod.Get, url); 25 | 26 | using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, ct); 27 | 28 | response.EnsureSuccessStatusCode(); 29 | 30 | var contentLength = response.Content.Headers.ContentLength; 31 | 32 | using var stream = await response.Content.ReadAsStreamAsync(ct); 33 | 34 | const int bufferSize = 81920; 35 | 36 | using var file = File.OpenWrite(destinationFileName); 37 | var buffer = new byte[bufferSize]; 38 | long totalBytesRead = 0; 39 | int bytesRead; 40 | progress.Report(0.1); 41 | while ((bytesRead = await stream.ReadAsync(buffer, ct).ConfigureAwait(false)) != 0) 42 | { 43 | await file.WriteAsync(buffer.AsMemory(0, bytesRead), ct).ConfigureAwait(false); 44 | totalBytesRead += bytesRead; 45 | if (contentLength.HasValue) 46 | { 47 | progress.Report((float)totalBytesRead * 100 / contentLength.Value); 48 | } 49 | } 50 | 51 | progress.Report(100); 52 | 53 | return true; 54 | } 55 | catch (Exception ex) 56 | { 57 | logger?.LogError(ex, "Error downloading file from {Url}", url); 58 | } 59 | 60 | return false; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/AppPasswordRegistrationRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.Graph 5 | { 6 | internal class AppPasswordRegistrationRequest 7 | { 8 | public string? DisplayName { get; set; } 9 | public string? EndDateTime { get; set; } 10 | public string? StartDateTime { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/AppRegistrationRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.Graph 5 | { 6 | internal class AppRegistrationRequest 7 | { 8 | public string? DisplayName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/AppUpdateRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.CLI.Services.Graph 7 | { 8 | internal class AppUpdateRequest 9 | { 10 | public List? IdentifierUris { get; set; } 11 | public string? SignInAudience { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/AzureApplication.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Services.Graph 7 | { 8 | internal class AzureApplication 9 | { 10 | public string? Id { get; set; } 11 | public Guid? AppId { get; set; } 12 | public string? DisplayName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/CreateAppSecretResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Services.Graph 7 | { 8 | internal class CreateAppSecretResponse 9 | { 10 | public string? CustomKeyIdentifier { get; set; } 11 | public DateTime EndDateTime { get; set; } 12 | public string? KeyId { get; set; } 13 | public DateTime StartDateTime { get; set; } 14 | public string? SecretText { get; set; } 15 | public string? Hint { get; set; } 16 | public string? DisplayName { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/CreatePrincipalRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.Graph 5 | { 6 | internal class CreatePrincipalRequest 7 | { 8 | public string? AppId { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/CreatePrincipalResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Services.Graph 7 | { 8 | internal class CreatePrincipalResponse 9 | { 10 | public string? Id { get; set; } 11 | public Guid? AppId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/GraphSourceGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | 7 | namespace MSStore.CLI.Services.Graph 8 | { 9 | /// 10 | /// Source Generator Configuration for JSON Serialization/Deserialization of Microsoft Graph calls. 11 | /// 12 | [JsonSerializable(typeof(ListResponse))] 13 | [JsonSerializable(typeof(AppRegistrationRequest))] 14 | [JsonSerializable(typeof(AzureApplication))] 15 | [JsonSerializable(typeof(AppPasswordRegistrationRequest))] 16 | [JsonSerializable(typeof(CreateAppSecretResponse))] 17 | [JsonSerializable(typeof(AppUpdateRequest))] 18 | [JsonSerializable(typeof(CreatePrincipalRequest))] 19 | [JsonSerializable(typeof(CreatePrincipalResponse))] 20 | internal partial class GraphSourceGenerationContext : JsonSerializerContext 21 | { 22 | private static GraphSourceGenerationContext? _default; 23 | private static GraphSourceGenerationContext? _defaultPretty; 24 | 25 | public static GraphSourceGenerationContext GetCustom(bool writeIndented = false) 26 | { 27 | if (writeIndented) 28 | { 29 | return _defaultPretty ??= 30 | CreateCustom(writeIndented); 31 | } 32 | else 33 | { 34 | return _default ??= 35 | CreateCustom(writeIndented); 36 | } 37 | 38 | static GraphSourceGenerationContext CreateCustom(bool writeIndented) 39 | { 40 | return new GraphSourceGenerationContext(new JsonSerializerOptions 41 | { 42 | PropertyNamingPolicy = JsonNamingPolicy.CamelCase, 43 | DefaultIgnoreCondition = JsonIgnoreCondition.Never, 44 | PropertyNameCaseInsensitive = true, 45 | IgnoreReadOnlyFields = false, 46 | IgnoreReadOnlyProperties = false, 47 | IncludeFields = false, 48 | WriteIndented = writeIndented 49 | }); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/IGraphClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.Services.Graph 8 | { 9 | internal interface IGraphClient 10 | { 11 | bool Enabled { get; } 12 | Task> GetAppsByDisplayNameAsync(string displayName, CancellationToken ct); 13 | Task CreateAppAsync(string displayName, CancellationToken ct); 14 | Task CreatePrincipalAsync(string appId, CancellationToken ct); 15 | Task UpdateAppAsync(string id, AppUpdateRequest updatedApp, CancellationToken ct); 16 | Task CreateAppSecretAsync(string clientId, string displayName, CancellationToken ct); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/ListResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.CLI.Services.Graph 7 | { 8 | internal class ListResponse 9 | { 10 | public List? Value { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Graph/Organization.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Services.Graph 7 | { 8 | internal class Organization 9 | { 10 | public Guid? Id { get; set; } 11 | public string? Domain { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IAppXManifestManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using Microsoft.Extensions.Logging; 8 | using MSStore.API.Packaged.Models; 9 | 10 | namespace MSStore.CLI.Services 11 | { 12 | internal interface IAppXManifestManager 13 | { 14 | void UpdateManifest(string appxManifestPath, DevCenterApplication app, string publisherDisplayName, Version? version); 15 | void MinimalUpdateManifest(string appxManifestPath, DevCenterApplication app, string publisherDisplayName); 16 | Version UpdateManifestVersion(string appxManifestPath, Version? version); 17 | string? GetAppId(FileInfo fileInfo); 18 | List GetAllImagesFromManifest(FileInfo appxManifest, ILogger logger); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IAzureBlobManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MSStore.CLI.Services 9 | { 10 | internal interface IAzureBlobManager 11 | { 12 | Task UploadFileAsync(string blobUri, string localFilePath, IProgress progress, CancellationToken ct); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IBrowserLauncher.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.Services 8 | { 9 | internal interface IBrowserLauncher 10 | { 11 | Task OpenBrowserAsync(string url, bool askConfirmation, CancellationToken ct); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ICLIConfigurator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Spectre.Console; 8 | 9 | namespace MSStore.CLI.Services 10 | { 11 | internal interface ICLIConfigurator 12 | { 13 | Task ConfigureAsync(IAnsiConsole ansiConsole, bool askConfirmation, Guid? tenantId = null, string? sellerId = null, Guid? clientId = null, string? clientSecret = null, string? certificateThumbprint = null, string? certificateFilePath = null, string? certificatePassword = null, CancellationToken ct = default); 14 | Task ResetAsync(CancellationToken ct = default); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IConfigurationManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.Services 8 | { 9 | internal interface IConfigurationManager 10 | where T : new() 11 | { 12 | string ConfigPath { get; } 13 | Task LoadAsync(bool clearInvalidConfig = false, CancellationToken ct = default); 14 | Task ClearAsync(CancellationToken ct); 15 | Task SaveAsync(T config, CancellationToken ct); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IConsoleReader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace MSStore.CLI.Services 10 | { 11 | internal interface IConsoleReader 12 | { 13 | Task ReadNextAsync(bool hidden, CancellationToken ct); 14 | Task RequestStringAsync(string fieldName, bool hidden, CancellationToken ct); 15 | Task YesNoConfirmationAsync(string message, CancellationToken ct); 16 | Task SelectionPromptAsync(string title, IEnumerable choices, int pageSize = 10, Func? displaySelector = null, CancellationToken ct = default) 17 | where T : notnull; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IEnvironmentInformationService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services 5 | { 6 | internal interface IEnvironmentInformationService 7 | { 8 | bool IsRunningOnCI { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IExternalCommandExecutor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.Services 8 | { 9 | internal interface IExternalCommandExecutor 10 | { 11 | Task RunAsync(string command, string arguments, string workingDirectory, CancellationToken ct); 12 | Task FindToolAsync(string command, CancellationToken ct); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IFileDownloader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace MSStore.CLI.Services 10 | { 11 | internal interface IFileDownloader 12 | { 13 | Task DownloadAsync(string url, string destinationFileName, IProgress progress, ILogger? logger, CancellationToken ct = default); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IImageConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.Services 8 | { 9 | internal interface IImageConverter 10 | { 11 | Task ConvertIcoToPngAsync(string sourceFilePath, string destinationFilePath, int destinationWidth, int destinationHeight, int paddingX, int paddingY, CancellationToken ct); 12 | byte[]? ConvertToByteArray(string image); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/INuGetPackageManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MSStore.CLI.Services 9 | { 10 | internal interface INuGetPackageManager 11 | { 12 | Task IsPackageInstalledAsync(DirectoryInfo directory, string packageName, CancellationToken ct); 13 | bool IsMaui(FileInfo fileInfo); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IPWAAppInfoManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using MSStore.CLI.Services.PWABuilder; 7 | 8 | namespace MSStore.CLI.Services 9 | { 10 | internal interface IPWAAppInfoManager 11 | { 12 | Task SaveAsync(PWAAppInfo pwaAppInfo, string directoryPath, CancellationToken ct); 13 | Task LoadAsync(string directoryPath, CancellationToken ct); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IStoreAPIFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using MSStore.API; 7 | using MSStore.API.Packaged; 8 | 9 | namespace MSStore.CLI.Services 10 | { 11 | internal interface IStoreAPIFactory 12 | { 13 | Task CreateAsync(Configurations? config = null, CancellationToken ct = default); 14 | Task CreatePackagedAsync(Configurations? config = null, CancellationToken ct = default); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/IZipFileManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services 5 | { 6 | internal interface IZipFileManager 7 | { 8 | void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName); 9 | void ExtractZip(string sourceArchiveFileName, string destinationDirectoryName); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ImageConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Extensions.Logging; 9 | using SkiaSharp; 10 | 11 | namespace MSStore.CLI.Services 12 | { 13 | internal class ImageConverter(ILogger logger) : IImageConverter 14 | { 15 | private ILogger _logger = logger; 16 | 17 | public async Task ConvertIcoToPngAsync(string sourceFilePath, string destinationFilePath, int destinationWidth, int destinationHeight, int paddingX, int paddingY, CancellationToken ct) 18 | { 19 | try 20 | { 21 | using var image = SKImage.FromEncodedData(sourceFilePath); 22 | 23 | SKBitmap finalBitmap = new SKBitmap(destinationWidth, destinationHeight); 24 | SKRect dest = new SKRect(paddingX, paddingY, destinationWidth - paddingX, destinationHeight - paddingY); 25 | SKRect source = new SKRect(0, 0, image.Width, image.Height); 26 | 27 | using (SKCanvas canvas = new SKCanvas(finalBitmap)) 28 | { 29 | canvas.DrawImage(image, source, dest, new SKSamplingOptions(SKCubicResampler.Mitchell)); 30 | } 31 | 32 | using MemoryStream memStream = new MemoryStream(); 33 | using (SKManagedWStream wstream = new SKManagedWStream(memStream)) 34 | { 35 | finalBitmap.Encode(wstream, SKEncodedImageFormat.Png, 100); 36 | } 37 | 38 | memStream.Seek(0, SeekOrigin.Begin); 39 | 40 | using var fileStream = new FileStream(destinationFilePath, FileMode.Create); 41 | await memStream.CopyToAsync(fileStream, ct); 42 | 43 | return true; 44 | } 45 | catch (Exception ex) 46 | { 47 | _logger.LogCritical(ex, "Failed to convert ICO to PNG"); 48 | return false; 49 | } 50 | } 51 | 52 | public byte[]? ConvertToByteArray(string image) 53 | { 54 | using var bitmap = SKBitmap.Decode(image); 55 | return bitmap?.Bytes; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/NuGetPackageManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using System.Xml; 10 | using Microsoft.Extensions.Logging; 11 | 12 | namespace MSStore.CLI.Services 13 | { 14 | internal class NuGetPackageManager(ILogger logger) : INuGetPackageManager 15 | { 16 | private readonly ILogger _logger = logger; 17 | 18 | public virtual bool IsMaui(FileInfo fileInfo) 19 | { 20 | if (!fileInfo.Exists) 21 | { 22 | return false; 23 | } 24 | 25 | XmlDocument xmlDoc = new XmlDocument 26 | { 27 | PreserveWhitespace = true 28 | }; 29 | 30 | _logger.LogInformation("Checking if project is Maui"); 31 | 32 | xmlDoc.Load(fileInfo.FullName); 33 | 34 | var useMauiNode = xmlDoc.SelectSingleNode("/Project/PropertyGroup/UseMaui"); 35 | 36 | return useMauiNode?.InnerText?.Equals("true", StringComparison.OrdinalIgnoreCase) == true; 37 | } 38 | 39 | public virtual async Task IsPackageInstalledAsync(DirectoryInfo directory, string packageName, CancellationToken ct) 40 | { 41 | var projectAssetsJson = directory.GetFiles(Path.Join("obj", "project.assets.json"), SearchOption.TopDirectoryOnly)?.FirstOrDefault(); 42 | if (projectAssetsJson?.Directory?.FullName != null) 43 | { 44 | try 45 | { 46 | var fileContent = await File.ReadAllTextAsync(projectAssetsJson.FullName, ct); 47 | if (fileContent.Contains($"\"{packageName}/", StringComparison.OrdinalIgnoreCase)) 48 | { 49 | return true; 50 | } 51 | } 52 | catch (Exception ex) 53 | { 54 | _logger.LogError(ex, "Could not check if project is WinUI, assuming it is not."); 55 | } 56 | } 57 | 58 | return false; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWAAppInfoManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Text.Json; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using MSStore.CLI.Services.PWABuilder; 9 | 10 | namespace MSStore.CLI.Services 11 | { 12 | internal class PWAAppInfoManager : IPWAAppInfoManager 13 | { 14 | private const string PWAAppInfoJsonFileName = "pwaAppInfo.json"; 15 | 16 | public async Task LoadAsync(string directoryPath, CancellationToken ct) 17 | { 18 | try 19 | { 20 | var appInfoPath = Path.Combine(directoryPath, PWAAppInfoJsonFileName); 21 | using var file = File.Open(appInfoPath, FileMode.Open); 22 | 23 | return await JsonSerializer.DeserializeAsync(file, PWAAppInfoSourceGenerationContext.Default.PWAAppInfo, ct) 24 | ?? new PWAAppInfo(); 25 | } 26 | catch (FileNotFoundException) 27 | { 28 | return new PWAAppInfo(); 29 | } 30 | } 31 | 32 | public async Task SaveAsync(PWAAppInfo pwaAppInfo, string directoryPath, CancellationToken ct) 33 | { 34 | var appInfoPath = Path.Combine(directoryPath, PWAAppInfoJsonFileName); 35 | using var file = File.Open(appInfoPath, FileMode.OpenOrCreate); 36 | file.SetLength(0); 37 | file.Position = 0; 38 | await JsonSerializer.SerializeAsync( 39 | file, 40 | pwaAppInfo, 41 | PWAAppInfoSourceGenerationContext.Default.PWAAppInfo, 42 | ct); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/ClassicPackage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class ClassicPackage 7 | { 8 | public bool Generate { get; set; } 9 | public string? Version { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/GenerateZipRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class GenerateZipRequest 7 | { 8 | public string? Url { get; set; } 9 | public string? Name { get; set; } 10 | public string? PackageId { get; set; } 11 | public string? Version { get; set; } 12 | public bool AllowSigning { get; set; } 13 | public ClassicPackage? ClassicPackage { get; set; } 14 | public Publisher? Publisher { get; set; } 15 | public string? ResourceLanguage { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/IPWABuilderClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace MSStore.CLI.Services.PWABuilder 9 | { 10 | internal interface IPWABuilderClient 11 | { 12 | Task GenerateZipAsync(GenerateZipRequest generateZipRequest, string outputZipPath, IProgress progress, CancellationToken ct); 13 | Task FindWebManifestAsync(Uri site, CancellationToken ct); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/Icon.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class Icon 7 | { 8 | public string? Src { get; set; } 9 | public string? Sizes { get; set; } 10 | public string? Type { get; set; } 11 | public string? Purpose { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/IconExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Globalization; 5 | using System.Numerics; 6 | 7 | namespace MSStore.CLI.Services.PWABuilder 8 | { 9 | internal static class IconExtensions 10 | { 11 | public static Vector2 GetSize(this Icon icon) 12 | { 13 | var sizes = icon.Sizes; 14 | if (string.IsNullOrEmpty(sizes)) 15 | { 16 | return default; 17 | } 18 | 19 | var dimensions = sizes.Split('x'); 20 | return new Vector2(int.Parse(dimensions[0], CultureInfo.InvariantCulture), int.Parse(dimensions[1], CultureInfo.InvariantCulture)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/PWAAppInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Services.PWABuilder 7 | { 8 | internal class PWAAppInfo 9 | { 10 | public string? AppId { get; set; } 11 | public Uri? Uri { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/PWAAppInfoSourceGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace MSStore.CLI.Services.PWABuilder 7 | { 8 | /// 9 | /// Source Generator Configuration for JSON Serialization/Deserialization of the PWA Application Informations. 10 | /// 11 | [JsonSerializable(typeof(PWAAppInfo))] 12 | internal partial class PWAAppInfoSourceGenerationContext : JsonSerializerContext 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/PWASourceGenerationContext .cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | 7 | namespace MSStore.CLI.Services.PWABuilder 8 | { 9 | /// 10 | /// Source Generator Configuration for JSON Serialization/Deserialization of PWA Builder API calls. 11 | /// 12 | [JsonSourceGenerationOptions] 13 | [JsonSerializable(typeof(JsonDocument))] 14 | [JsonSerializable(typeof(JsonElement))] 15 | [JsonSerializable(typeof(GenerateZipRequest))] 16 | [JsonSerializable(typeof(WebManifestFindResponse))] 17 | internal partial class PWASourceGenerationContext : JsonSerializerContext 18 | { 19 | private static PWASourceGenerationContext? _default; 20 | private static PWASourceGenerationContext? _defaultPretty; 21 | 22 | public static PWASourceGenerationContext GetCustom(bool writeIndented = false) 23 | { 24 | if (writeIndented) 25 | { 26 | return _defaultPretty ??= 27 | CreateCustom(writeIndented); 28 | } 29 | else 30 | { 31 | return _default ??= 32 | CreateCustom(writeIndented); 33 | } 34 | 35 | static PWASourceGenerationContext CreateCustom(bool writeIndented) 36 | { 37 | return new PWASourceGenerationContext(new JsonSerializerOptions 38 | { 39 | DefaultIgnoreCondition = JsonIgnoreCondition.Never, 40 | PropertyNameCaseInsensitive = true, 41 | IgnoreReadOnlyFields = false, 42 | IgnoreReadOnlyProperties = false, 43 | IncludeFields = false, 44 | WriteIndented = writeIndented 45 | }); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/Publisher.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class Publisher 7 | { 8 | public string? DisplayName { get; set; } 9 | public string? CommonName { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/ScreenShot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class ScreenShot 7 | { 8 | public string? Src { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/WebManifestFindContent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class WebManifestFindContent 7 | { 8 | public WebManifestJson? Json { get; set; } 9 | public string? Url { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/WebManifestFindResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace MSStore.CLI.Services.PWABuilder 5 | { 6 | internal class WebManifestFindResponse 7 | { 8 | public WebManifestFindContent? Content { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PWABuilder/WebManifestJson.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.CLI.Services.PWABuilder 7 | { 8 | internal class WebManifestJson 9 | { 10 | public string? Description { get; set; } 11 | public string? Display { get; set; } 12 | public List? Icons { get; set; } 13 | public string? Name { get; set; } 14 | public List? Screenshots { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PartnerCenter/AccountEnrollment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.CLI.Services.PartnerCenter 7 | { 8 | internal class AccountEnrollment 9 | { 10 | public string? Id { get; set; } 11 | public string? Cid { get; set; } 12 | public string? Status { get; set; } 13 | public string? AccountType { get; set; } 14 | public string? TypeName { get; set; } 15 | public string? Name { get; set; } 16 | public Dictionary? Attributes { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PartnerCenter/AccountEnrollmentExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Spectre.Console; 5 | 6 | namespace MSStore.CLI.Services.PartnerCenter 7 | { 8 | internal static class AccountEnrollmentExtensions 9 | { 10 | public static void WriteInfo(this AccountEnrollment account, IAnsiConsole ansiConsole) 11 | { 12 | ansiConsole.WriteLine($"Developer Account Name: \t{account.Name}"); 13 | ansiConsole.WriteLine($"Developer Account Type: \t{account.AccountType}"); 14 | ansiConsole.WriteLine($"Developer Account Status: \t{account.Status}"); 15 | 16 | ansiConsole.WriteLine(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PartnerCenter/AccountEnrollments.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace MSStore.CLI.Services.PartnerCenter 7 | { 8 | internal class AccountEnrollments 9 | { 10 | public int TotalCount { get; set; } 11 | public List? Items { get; set; } 12 | public Dictionary? Attributes { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PartnerCenter/IPartnerCenterManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace MSStore.CLI.Services.PartnerCenter 8 | { 9 | internal interface IPartnerCenterManager 10 | { 11 | bool Enabled { get; } 12 | Task GetEnrollmentAccountsAsync(CancellationToken ct); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/PartnerCenter/PartnerCenterGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | 7 | namespace MSStore.CLI.Services.PartnerCenter 8 | { 9 | /// 10 | /// Source Generator Configuration for JSON Serialization/Deserialization of Microsoft Partner Center calls. 11 | /// 12 | [JsonSourceGenerationOptions] 13 | [JsonSerializable(typeof(AccountEnrollments))] 14 | internal partial class PartnerCenterGenerationContext : JsonSerializerContext 15 | { 16 | private static PartnerCenterGenerationContext? _default; 17 | private static PartnerCenterGenerationContext? _defaultPretty; 18 | 19 | public static PartnerCenterGenerationContext GetCustom(bool writeIndented = false) 20 | { 21 | if (writeIndented) 22 | { 23 | return _defaultPretty ??= 24 | CreateCustom(writeIndented); 25 | } 26 | else 27 | { 28 | return _default ??= 29 | CreateCustom(writeIndented); 30 | } 31 | 32 | static PartnerCenterGenerationContext CreateCustom(bool writeIndented) 33 | { 34 | return new PartnerCenterGenerationContext(new JsonSerializerOptions 35 | { 36 | PropertyNamingPolicy = JsonNamingPolicy.CamelCase, 37 | DefaultIgnoreCondition = JsonIgnoreCondition.Never, 38 | PropertyNameCaseInsensitive = true, 39 | IgnoreReadOnlyFields = false, 40 | IgnoreReadOnlyProperties = false, 41 | IncludeFields = false, 42 | WriteIndented = writeIndented 43 | }); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Telemetry/TelemetryConfigurations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace MSStore.CLI.Services.Telemetry 7 | { 8 | internal class TelemetryConfigurations 9 | { 10 | public bool? TelemetryEnabled { get; set; } 11 | public string? TelemetryGuid { get; set; } 12 | public DateTime? TelemetryGuidDateTime { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Telemetry/TelemetryConnectionStringProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Reflection; 6 | using System.Text.Json; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace MSStore.CLI.Services.Telemetry 12 | { 13 | internal class TelemetryConnectionStringProvider 14 | { 15 | public string? AIConnectionString { get; set; } 16 | 17 | internal static async Task LoadAsync(ILogger? logger = null, CancellationToken ct = default) 18 | { 19 | var assembly = typeof(TelemetryConnectionStringProvider).GetTypeInfo().Assembly; 20 | using var resource = assembly.GetManifestResourceStream("MSStore.CLI.config.json"); 21 | 22 | if (resource == null) 23 | { 24 | return null; 25 | } 26 | 27 | try 28 | { 29 | return await JsonSerializer.DeserializeAsync(resource, TelemetrySourceGenerationContext.Default.TelemetryConnectionStringProvider, ct); 30 | } 31 | catch (Exception ex) 32 | { 33 | logger?.LogError(ex, "Error while reading telemetry configuration."); 34 | return null; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/Telemetry/TelemetrySourceGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace MSStore.CLI.Services.Telemetry 7 | { 8 | /// 9 | /// Source Generator Configuration for JSON Serialization/Deserialization of Telemetry configurations. 10 | /// 11 | [JsonSerializable(typeof(TelemetryConnectionStringProvider))] 12 | [JsonSerializable(typeof(TelemetryConfigurations))] 13 | internal partial class TelemetrySourceGenerationContext : JsonSerializerContext 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/TokenManager/ITokenManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Identity.Client; 7 | 8 | namespace MSStore.CLI.Services.TokenManager 9 | { 10 | internal interface ITokenManager 11 | { 12 | IAccount? CurrentUser { get; } 13 | Task SelectAccountAsync(bool notMSA, bool forceSelection, CancellationToken ct); 14 | Task GetTokenAsync(string[] scopes, CancellationToken ct); 15 | Task ClearAllCacheAsync(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MSStore.CLI/Services/ZipFileManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.IO.Compression; 6 | 7 | namespace MSStore.CLI.Services 8 | { 9 | internal class ZipFileManager : IZipFileManager 10 | { 11 | public void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName) 12 | { 13 | if (File.Exists(destinationArchiveFileName)) 14 | { 15 | File.Delete(destinationArchiveFileName); 16 | } 17 | 18 | ZipFile.CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, CompressionLevel.Optimal, false); 19 | } 20 | 21 | public void ExtractZip(string sourceArchiveFileName, string destinationDirectoryName) 22 | { 23 | ZipFile.ExtractToDirectory(sourceArchiveFileName, destinationDirectoryName, true); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MSStore.CLI/StatusContextExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using MSStore.API; 6 | using Spectre.Console; 7 | 8 | namespace MSStore.CLI 9 | { 10 | internal static class StatusContextExtensions 11 | { 12 | public static void ErrorStatus(this StatusContext _, IAnsiConsole ansiConsole, string message) 13 | { 14 | ansiConsole.MarkupLine($":collision: [bold red]{message.EscapeMarkup()}[/]"); 15 | } 16 | 17 | public static void ErrorStatus(this StatusContext _, IAnsiConsole ansiConsole, Exception exception) 18 | { 19 | switch (exception) 20 | { 21 | case ArgumentException ex: 22 | ErrorStatus(_, ansiConsole, ex.Message); 23 | break; 24 | case MSStoreWrappedErrorException ex: 25 | var message = ex.Message + Environment.NewLine + string.Join(Environment.NewLine, ex.ResponseErrors); 26 | ErrorStatus(_, ansiConsole, message); 27 | break; 28 | case Exception: 29 | ErrorStatus(_, ansiConsole, "Error!"); 30 | break; 31 | } 32 | } 33 | 34 | public static void SuccessStatus(this StatusContext ctx, IAnsiConsole ansiConsole, string? message = null) 35 | { 36 | if (message != null) 37 | { 38 | ansiConsole.MarkupLine($":check_mark_button: {message}"); 39 | } 40 | else 41 | { 42 | ansiConsole.MarkupLine($":check_mark_button: [bold green]{ctx.Status}[/]"); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MSStore.CLI/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "AIConnectionString": "#{AI_CONNECTION_STRING}#" 3 | } -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses [GitHub Issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or 6 | feature request as a new Issue. 7 | 8 | For help and questions about using this project, please look at our [Wiki][wiki] for using the Microsoft Store Developer CLI and our [Contributor's Guide][contributor] if you want to work on MSStoreCLI. 9 | 10 | ## Microsoft Support Policy 11 | 12 | Support for the Microsoft Store Developer CLI is limited to the resources listed above. 13 | 14 | [gh-issue]: https://github.com/microsoft/msstore-cli/issues/new/choose 15 | [gh-bug]: https://github.com/microsoft/msstore-cli/issues/new?assignees=&labels=Issue-Bug&template=bug_report.md&title= 16 | [gh-feature]: https://github.com/microsoft/msstore-cli/issues/new?assignees=&labels=&template=feature_request.md&title= 17 | [wiki]: https://github.com/microsoft/msstore-cli/wiki 18 | [contributor]: https://github.com/microsoft/msstore-cli/blob/main/CONTRIBUTING.md -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /privacy.md: -------------------------------------------------------------------------------- 1 | # Data Collection 2 | 3 | The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. 4 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", 3 | "version": "0.2.1-alpha", 4 | "publicReleaseRefSpec": [ 5 | "^refs/heads/main$", 6 | "^refs/heads/rel/v\\d+(?:\\.\\d+)?$" 7 | ], 8 | "cloudBuild": { 9 | "buildNumber": { 10 | "enabled": true 11 | } 12 | }, 13 | "release": { 14 | "branchName": "rel/v{version}", 15 | "versionIncrement": "build" 16 | } 17 | } --------------------------------------------------------------------------------