├── templates ├── windows-admin-center-extension-template │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── app │ │ │ ├── default │ │ │ │ ├── default.component.css │ │ │ │ ├── default.component.html │ │ │ │ ├── default.component.ts │ │ │ │ ├── default.module.ts │ │ │ │ ├── default.component.spec.ts │ │ │ │ └── default.routing.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.ts │ │ │ ├── app-routing.module.ts │ │ │ └── app.module.ts │ │ ├── favicon.ico │ │ ├── typings.d.ts │ │ ├── tsconfig.app.json │ │ ├── resources │ │ │ ├── scripts │ │ │ │ ├── Get-Process.ps1 │ │ │ │ ├── Get-Service.ps1 │ │ │ │ ├── Get-WinRmState.ps1 │ │ │ │ ├── Get-Error.ps1 │ │ │ │ └── Get-Exception.ps1 │ │ │ ├── strings │ │ │ │ └── strings.resjson │ │ │ └── icons │ │ │ │ └── Server.svg │ │ ├── tsconfig.spec.json │ │ ├── environments │ │ │ ├── environment.ts │ │ │ └── environment.prod.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── test.ts │ │ ├── karma.conf.js │ │ └── polyfills.ts │ ├── loc │ │ └── langMap.xml │ ├── .gitattribute │ ├── index.d.ts │ ├── index.js │ ├── tsconfig.json │ ├── .editorconfig │ ├── gulpfile.ts │ │ ├── common │ │ │ ├── lint.ts │ │ │ ├── copy.ts │ │ │ ├── clean.ts │ │ │ ├── validate.ts │ │ │ ├── test.ts │ │ │ ├── compile.ts │ │ │ ├── config.ts │ │ │ ├── resjson.ts │ │ │ ├── utilities.ts │ │ │ └── powershell.ts │ │ ├── config-data.ts │ │ └── index.ts │ ├── tsconfig.inline.json │ ├── package.json │ ├── tslint.json │ └── angular.json ├── legacy │ └── windows-admin-center-extension-template │ │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── app │ │ │ ├── default │ │ │ │ ├── default.component.css │ │ │ │ ├── default.component.html │ │ │ │ ├── default.component.ts │ │ │ │ ├── default.module.ts │ │ │ │ ├── default.component.spec.ts │ │ │ │ └── default.routing.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.ts │ │ │ ├── app-routing.module.ts │ │ │ └── app.module.ts │ │ ├── resources │ │ │ ├── scripts │ │ │ │ ├── Get-Process.ps1 │ │ │ │ ├── Get-Service.ps1 │ │ │ │ ├── Get-Error.ps1 │ │ │ │ ├── Get-Exception.ps1 │ │ │ │ └── Get-WinRmState.ps1 │ │ │ ├── strings │ │ │ │ └── strings.resjson │ │ │ └── icons │ │ │ │ └── Server.svg │ │ ├── test-util │ │ │ ├── load-common-libraries.test.helper.ts │ │ │ ├── load-babel-require.helper.ts │ │ │ └── load-jsdom.helper.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── main.ts │ │ └── polyfills.ts │ │ ├── .babelrc │ │ ├── tools │ │ ├── setupSsl.cmd │ │ ├── gulp-license.js │ │ ├── UpdateExtensionName.ps1 │ │ └── ssl │ │ │ └── server.pem │ │ ├── index.js │ │ ├── .vscode │ │ ├── settings.json │ │ └── launch.json │ │ ├── index.d.ts │ │ ├── .editorconfig │ │ ├── tsconfig-inline.json │ │ ├── tsconfig.json │ │ ├── angular-cli.json │ │ ├── gulps │ │ ├── gulp-merge-json-in-folders │ │ │ ├── index.ts │ │ │ ├── index.js │ │ │ ├── json-merge.ts │ │ │ └── json-merge.js │ │ ├── gulp-ps-code │ │ │ ├── index.ts │ │ │ ├── index.js │ │ │ ├── ps-code-convert.ts │ │ │ └── ps-code-convert.js │ │ ├── gulp-svg-code │ │ │ ├── index.ts │ │ │ ├── index.js │ │ │ ├── svg-code-convert.ts │ │ │ └── svg-code-convert.js │ │ └── gulp-resjson │ │ │ ├── index.js │ │ │ ├── index.ts │ │ │ ├── resjson-convert.ts │ │ │ └── resjson-convert.js │ │ ├── package.json │ │ ├── tslint.json │ │ └── gulpfile.js ├── ignores │ ├── npm │ └── git └── manifest │ ├── tool-manifest.json │ └── solution-manifest.json ├── package.json ├── .gitignore ├── LICENSE ├── .gitattributes ├── README.md ├── SECURITY.md └── src └── index.js /templates/windows-admin-center-extension-template/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/default/default.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/default/default.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/loc/langMap.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/scripts/Get-Process.ps1: -------------------------------------------------------------------------------- 1 | get-process -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/scripts/Get-Service.ps1: -------------------------------------------------------------------------------- 1 | Param([string]$name) 2 | get-service -Name $name -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/.gitattribute: -------------------------------------------------------------------------------- 1 | package.json text eol=lf 2 | package-lock.json text eol=lf 3 | src/manifest.json text eol=lf 4 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tools/setupSsl.cmd: -------------------------------------------------------------------------------- 1 | xcopy/s /q %appdata%\npm\node_modules\angular-cli\node_modules\webpack-dev-server\ssl\*.* .\ssl\*.* -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/default/default.component.html: -------------------------------------------------------------------------------- 1 |

2 | Congratulations, you have now created a new Windows Admin Center extension! 3 |

4 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/default/default.component.html: -------------------------------------------------------------------------------- 1 |

2 | Congratulations, you have now created a new Windows Admin Center extension! 3 |

4 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/windows-admin-center-extension-template/HEAD/templates/windows-admin-center-extension-template/src/favicon.ico -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | // Typings reference file, you can add your own global typings here 2 | // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html 3 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/scripts/Get-Error.ps1: -------------------------------------------------------------------------------- 1 | Param([int]$wait) 2 | sleep $wait 3 | write-progress -Activity "running" -PercentComplete 50 4 | write-error "=== Error Error Error === ($wait)" 5 | 6 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/scripts/Get-Exception.ps1: -------------------------------------------------------------------------------- 1 | Param([int]$wait) 2 | sleep $wait 3 | write-progress -Activity "running" -PercentComplete 50 4 | throw "=== Exception Exception Exception === ($wait)" 5 | 6 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/scripts/Get-WinRmState.ps1: -------------------------------------------------------------------------------- 1 | 1..30 | foreach { 2 | sleep 2 3 | $p = [math]::floor($_/30 * 100) 4 | write-progress -Activity "running" -PercentComplete $p 5 | get-service winrm 6 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/test-util/load-common-libraries.test.helper.ts: -------------------------------------------------------------------------------- 1 | require('./load-jsdom.helper'); 2 | require('./load-babel-require.helper'); 3 | 4 | require('rxjs'); 5 | 6 | require('@microsoft/windows-admin-center-sdk/dist/core/polyfills'); -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist-app", 5 | "types": [] 6 | }, 7 | "exclude": [ 8 | "test.ts", 9 | "**/*.spec.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/scripts/Get-Process.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Returns all currently running processes. 5 | 6 | .DESCRIPTION 7 | Returns all currently running processes. 8 | 9 | .ROLE 10 | Readers 11 | 12 | #> 13 | 14 | Get-Process -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /templates/ignores/npm: -------------------------------------------------------------------------------- 1 | #excluding everything by default 2 | **/* 3 | 4 | #include dist 5 | !dist 6 | !dist/**/* 7 | 8 | #include bundle 9 | !bundle 10 | !bundle/**/* 11 | 12 | //exclude test files 13 | dist/**/*.test.js 14 | dist/**/*.test.d.ts 15 | dist/**/*.test.helper.js 16 | dist/**/*.test.helper.d.ts 17 | 18 | #include index 19 | !index.js 20 | !index.d.ts -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/scripts/Get-Service.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Returns a specific service. 5 | 6 | .DESCRIPTION 7 | Returns a specific service. 8 | 9 | .ROLE 10 | Readers 11 | 12 | #> 13 | 14 | Param 15 | ( 16 | [Parameter(Mandatory = $true)] 17 | [string]$name 18 | ) 19 | 20 | Get-Service -Name $name -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 3 | * 4 | * @license 5 | * Copyright (c) Microsoft. All rights reserved. 6 | * 7 | * @module 8 | * @description 9 | * Entry point for all public APIs of this project. 10 | */ 11 | export * from './dist/main'; -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 3 | * 4 | * @license 5 | * Copyright (c) Microsoft. All rights reserved. 6 | * 7 | * @module 8 | * @description 9 | * Entry point for all public APIs of this project. 10 | */ 11 | export * from './dist/app/main'; -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 3 | * 4 | * @license 5 | * Copyright (c) Microsoft. All rights reserved. 6 | * 7 | * @module 8 | * @description 9 | * Entry point for all public APIs of this project. 10 | */ 11 | export * from './dist/app/main'; -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "__COMMENT_NOTICE__": "Normally, this file supports comments. However if comments are present the whole file may be overridden by msft-sme-build.", 3 | "__MERGE_NOTICE__": "THIS FILE WAS MERGED FROM msft-sme-build. some properties in this file may be overridden if changed.", 4 | "typescript.tsdk": "./node_modules/typescript/lib" 5 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 3 | * 4 | * @license 5 | * Copyright (c) Microsoft. All rights reserved. 6 | * 7 | * @module 8 | * @description 9 | * Entry point for all public APIs of this project. 10 | */ 11 | export * from './dist/main'; -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/default/default.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'default-component', 5 | templateUrl: './default.component.html', 6 | styleUrls: ['./default.component.css'] 7 | }) 8 | export class DefaultComponent implements OnInit { 9 | constructor() { 10 | // 11 | } 12 | 13 | public ngOnInit() { 14 | // 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/default/default.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'default', 5 | templateUrl: './default.component.html', 6 | styleUrls: ['./default.component.css'] 7 | }) 8 | export class DefaultComponent implements OnInit { 9 | 10 | constructor() { 11 | // 12 | } 13 | 14 | public ngOnInit() { 15 | // 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/default/default.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { DefaultComponent } from './default.component'; 5 | import { Routing } from './default.routing'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, 10 | Routing 11 | ], 12 | declarations: [DefaultComponent] 13 | }) 14 | export class DefaultModule { } 15 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/default/default.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { DefaultComponent } from './default.component'; 5 | import { Routing } from './default.routing'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, 10 | Routing 11 | ], 12 | declarations: [DefaultComponent] 13 | }) 14 | export class DefaultModule { } 15 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/strings/strings.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "//": "manifest section", 3 | "Manifest_displayName": "{!product-display-name}", 4 | "Manifest_description": "{!product-description}", 5 | "Manifest_category": "SME", 6 | 7 | "//": "{!ProductName}", 8 | "{!ProductName}_title": "{!product-title}", 9 | 10 | "//": "about", 11 | "{!ProductName}_about": "{!product-about}", 12 | "{!ProductName}_aboutDescription": "{!product-about-description}" 13 | } 14 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/scripts/Get-WinRmState.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Checks for WimRM service every 2 seconds, 30 times. 5 | 6 | .DESCRIPTION 7 | Checks for WimRM service every 2 seconds, 30 times. 8 | 9 | .ROLE 10 | Readers 11 | 12 | #> 13 | 14 | Write-Progress -Activity "Running" -PercentComplete 0 15 | 1..30 | ForEach-Object { 16 | Start-Sleep 2 17 | $p = [math]::floor($_/30 * 100) 18 | Write-Progress -Activity "Running" -PercentComplete $p 19 | Get-Service winrm 20 | } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/scripts/Get-Error.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Example script that will return an error after a specified time. 5 | 6 | .DESCRIPTION 7 | Example script that will return an error after a specified time. 8 | 9 | .ROLE 10 | Readers 11 | 12 | #> 13 | 14 | Param 15 | ( 16 | [Parameter(Mandatory = $true)] 17 | [int]$wait 18 | ) 19 | 20 | Write-Progress -Activity "Running" -PercentComplete 50 21 | Start-Sleep $wait 22 | Write-Error "=== Error Error Error === ($wait)" 23 | 24 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "module": "es2015", 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "target": "es5", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": [ 17 | "es2018", 18 | "dom" 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/scripts/Get-Exception.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Example script that will throw an exception after a specified time. 5 | 6 | .DESCRIPTION 7 | Example script that will throw an exception after a specified time. 8 | 9 | .ROLE 10 | Readers 11 | 12 | #> 13 | 14 | Param 15 | ( 16 | [Parameter(Mandatory = $true)] 17 | [int]$wait 18 | ) 19 | 20 | Write-Progress -Activity "Running" -PercentComplete 50 21 | Start-Sleep $wait 22 | throw "=== Exception Exception Exception === ($wait)" 23 | 24 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/.editorconfig: -------------------------------------------------------------------------------- 1 | # THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 2 | # Editor configuration, see http://editorconfig.org 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | 16 | [*.ts] 17 | indent_size = 4 18 | 19 | [*.js] 20 | indent_size = 4 21 | 22 | [*.css] 23 | indent_size = 4 -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/lint.ts: -------------------------------------------------------------------------------- 1 | const { series, src } = require('gulp'); 2 | const tslint = require('gulp-tslint'); 3 | const Utilities = require('./utilities'); 4 | 5 | module LintModule { 6 | export function lintApp() { 7 | return src(['src/**/*.ts', '!src/generated/**/*.*']) 8 | .pipe(tslint()) 9 | .pipe(tslint.report({ 'emitError': true, 'reportLimit': 0, 'summarizeFailureOutput': true })); 10 | } 11 | 12 | export const lint = lintApp; 13 | } 14 | 15 | Utilities.exportFunctions(exports, LintModule); 16 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/.editorconfig: -------------------------------------------------------------------------------- 1 | # THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 2 | # Editor configuration, see http://editorconfig.org 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | 16 | [*.ts] 17 | indent_size = 4 18 | 19 | [*.js] 20 | indent_size = 4 21 | 22 | [*.css] 23 | indent_size = 4 -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/strings/strings.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "//": "manifest section", 3 | "{!CompanyName}{!ProductName}_Manifest_displayName": "{!product-display-name}", 4 | "{!CompanyName}{!ProductName}_Manifest_description": "{!product-description}", 5 | "{!CompanyName}{!ProductName}_Manifest_keywords": "SME", 6 | 7 | "//": "{!ProductName}", 8 | "{!CompanyName}{!ProductName}_title": "{!product-title}", 9 | 10 | "//": "about", 11 | "{!CompanyName}{!ProductName}_about": "{!product-about}", 12 | "{!CompanyName}{!ProductName}_aboutDescription": "{!product-about-description}" 13 | } 14 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | /** 5 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 6 | * 7 | * The build system defaults to the dev environment which uses `environment.ts`, but if you do 8 | * `ng build --env=prod` then `environment.prod.ts` will be used instead. 9 | * The list of which env maps to which file can be found in `angular-cli.json`. 10 | */ 11 | export const environment = { 12 | production: false 13 | }; 14 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | /** 5 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 6 | * 7 | * The build system defaults to the dev environment which uses `environment.ts`, but if you do 8 | * `ng build --env=prod` then `environment.prod.ts` will be used instead. 9 | * The list of which env maps to which file can be found in `angular-cli.json`. 10 | */ 11 | export const environment = { 12 | production: true 13 | }; 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "windows-admin-center-cli", 3 | "version": "0.1.29", 4 | "description": "Cli for creating a new Windows Admin Center extension.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "bin": { 10 | "wac": "./src/index.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/Microsoft/windows-admin-center-extension-template" 15 | }, 16 | "author": "Microsoft", 17 | "license": "MIT", 18 | "dependencies": { 19 | "fs-extra": "^4.0.0", 20 | "minimist": "^1.2.0", 21 | "path-exists": "^3.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | /** 4 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 5 | * 6 | * The build system defaults to the dev environment which uses `environment.ts`, but if you do 7 | * `ng build --env=prod` then `environment.prod.ts` will be used instead. 8 | * The list of which env maps to which file can be found in `angular-cli.json`. 9 | */ 10 | export const environment = { 11 | production: true 12 | }; -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | /** 4 | * THIS FILE WAS GENERATED FROM msft-sme-build. DO NOT MODIFY. To change this file, make the appropriate changes in build 5 | * 6 | * The build system defaults to the dev environment which uses `environment.ts`, but if you do 7 | * `ng build --env=prod` then `environment.prod.ts` will be used instead. 8 | * The list of which env maps to which file can be found in `angular-cli.json`. 9 | */ 10 | export const environment = { 11 | production: false 12 | }; -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /templates/ignores/git: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /bundle 3 | /src/generated 4 | /src/assets/strings/**/*.json 5 | /dist 6 | /inlineSrc 7 | /inlineDist 8 | /tmp 9 | 10 | # dependencies 11 | /node_modules 12 | /bower_components 13 | 14 | # IDEs and editors 15 | /.idea 16 | /.vs 17 | /obj 18 | /*ntvs_analysis* 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | /ssl 25 | *.log 26 | 27 | # test 28 | **/*junit*.xml 29 | unittests/* 30 | scenariotestresults/* 31 | 32 | # misc 33 | /.sass-cache 34 | /connect.lock 35 | /coverage/* 36 | /libpeerconnection.log 37 | npm-debug.log 38 | testem.log 39 | /typings 40 | 41 | #System Files 42 | .DS_Store 43 | Thumbs.db 44 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tsconfig-inline.json: -------------------------------------------------------------------------------- 1 | { 2 | "//": "Inline version of tsconfig", 3 | "angularCompilerOptions": { 4 | "skipTemplateCodegen": true 5 | }, 6 | "compilerOptions": { 7 | "baseUrl": "", 8 | "declaration": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "inlineSourceMap": true, 12 | "lib": [ 13 | "es6", 14 | "dom" 15 | ], 16 | "module": "es6", 17 | "moduleResolution": "node", 18 | "outDir": "./dist", 19 | "sourceRoot": "./inlineSrc", 20 | "target": "es5" 21 | }, 22 | "include": [ 23 | "inlineSrc/**/*.ts" 24 | ] 25 | } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/copy.ts: -------------------------------------------------------------------------------- 1 | const { dest, src } = require('gulp'); 2 | const Utilities = require('./utilities'); 3 | 4 | module CopyModule { 5 | 6 | export function copyApp(): any { 7 | return src( 8 | [ 9 | 'src/**/*.json', 10 | 'src/**/*.d.ts', 11 | 'src/**/*.ps1', 12 | 'src/assets/**/*.*' 13 | ], 14 | { base: 'src' }) 15 | .pipe(dest('dist')); 16 | } 17 | 18 | export function inlineDist(): any { 19 | return src('inlineDist/inlineSrc/**/*.*') 20 | .pipe(dest('dist')); 21 | } 22 | } 23 | 24 | Utilities.exportFunctions(exports, CopyModule); 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /bundle 5 | /src/generated 6 | /src/assets/strings/**/*.json 7 | /dist 8 | /inlineSrc 9 | /tmp 10 | 11 | # dependencies 12 | /node_modules 13 | /bower_components 14 | 15 | # IDEs and editors 16 | /.idea 17 | /.vs 18 | /obj 19 | /*ntvs_analysis* 20 | .project 21 | .classpath 22 | .c9/ 23 | *.launch 24 | .settings/ 25 | /ssl 26 | *.log 27 | 28 | # test 29 | **/*junit*.xml 30 | unittests/* 31 | scenariotestresults/* 32 | 33 | # misc 34 | /.sass-cache 35 | /connect.lock 36 | /coverage/* 37 | /libpeerconnection.log 38 | npm-debug.log 39 | testem.log 40 | /typings 41 | 42 | # e2e 43 | /e2e/*.js 44 | /e2e/*.map 45 | 46 | #System Files 47 | .DS_Store 48 | Thumbs.db -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy, OnInit } from '@angular/core'; 2 | import { AppContextService, AuthorizationService, NavigationService } from '@microsoft/windows-admin-center-sdk/angular'; 3 | 4 | @Component({ 5 | selector: 'sme-root', 6 | templateUrl: './app.component.html' 7 | }) 8 | export class AppComponent implements OnDestroy, OnInit { 9 | constructor( 10 | private appContext: AppContextService, private navigationService: NavigationService) { 11 | } 12 | 13 | public ngOnInit(): void { 14 | this.appContext.ngInit({ navigationService: this.navigationService }); 15 | } 16 | 17 | public ngOnDestroy() { 18 | this.appContext.ngDestroy(); 19 | } 20 | } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy, OnInit } from '@angular/core'; 2 | import { AppContextService, AuthorizationService, NavigationService } from '@microsoft/windows-admin-center-sdk/angular'; 3 | 4 | @Component({ 5 | selector: 'sme-root', 6 | templateUrl: './app.component.html' 7 | }) 8 | export class AppComponent implements OnDestroy, OnInit { 9 | constructor( 10 | private appContext: AppContextService, private navigationService: NavigationService) { 11 | } 12 | 13 | public ngOnInit(): void { 14 | this.appContext.ngInit({ navigationService: this.navigationService }); 15 | } 16 | 17 | public ngOnDestroy() { 18 | this.appContext.ngDestroy(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/config-data.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Config } from './common/config'; 3 | 4 | function gulpConfig(): Config { 5 | return { 6 | resjson: { 7 | resourceName: '{!CompanyName}{!ProductName}', 8 | localeOffset: 0, 9 | localePath: 'loc' 10 | }, 11 | powershell: { 12 | name: '{!company-name}.{!module-name}', 13 | guid: '{!guid}', 14 | list: [ 15 | 'src', 16 | 'node_modules/@microsoft/windows-admin-center-sdk' 17 | ], 18 | enablePester: false, 19 | skipCim: true 20 | }, 21 | test: { 22 | skip: true 23 | } 24 | }; 25 | } 26 | 27 | exports.gulpConfig = gulpConfig; 28 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/default/default.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DefaultComponent } from './default.component'; 4 | 5 | describe('DefaultComponent', () => { 6 | let component: DefaultComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DefaultComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DefaultComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/default/default.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DefaultComponent } from './default.component'; 4 | 5 | describe('DefaultComponent', () => { 6 | let component: DefaultComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DefaultComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DefaultComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "__MERGE_NOTICE__": "THIS FILE WAS MERGED FROM msft-sme-build. some properties in this file may be overridden if changed.", 3 | "__WHY_TWO_TSCONFIGS__": "There are 2 tsconfigs in this project. one is for ngc and visual studio at the root of the project. The other is for ng build and ng serve.", 4 | "compilerOptions": { 5 | "baseUrl": "", 6 | "declaration": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "lib": [ 10 | "es6", 11 | "dom" 12 | ], 13 | "mapRoot": "./", 14 | "module": "es6", 15 | "moduleResolution": "node", 16 | "outDir": "./dist", 17 | "sourceMap": true, 18 | "target": "es5", 19 | "typeRoots": [ 20 | "../node_modules/@types" 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/default/default.routing.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { DefaultComponent } from './default.component'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: DefaultComponent, 10 | // if the component has child components that need to be routed to, include them in the children array. 11 | children: [ 12 | { 13 | path: '', 14 | redirectTo: 'base', 15 | pathMatch: 'full' 16 | } 17 | ] 18 | }]; 19 | 20 | @NgModule({ 21 | imports: [ 22 | RouterModule.forChild(routes) 23 | ], 24 | exports: [ 25 | RouterModule 26 | ] 27 | }) 28 | export class Routing { } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/default/default.routing.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { DefaultComponent } from './default.component'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: DefaultComponent, 10 | // if the component has child components that need to be routed to, include them in the children array. 11 | children: [ 12 | { 13 | path: '', 14 | redirectTo: 'base', 15 | pathMatch: 'full' 16 | } 17 | ] 18 | }]; 19 | 20 | @NgModule({ 21 | imports: [ 22 | RouterModule.forChild(routes) 23 | ], 24 | exports: [ 25 | RouterModule 26 | ] 27 | }) 28 | export class Routing { } 29 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/clean.ts: -------------------------------------------------------------------------------- 1 | const { src } = require('gulp'); 2 | const gulpClean = require('gulp-clean'); 3 | const Utilities = require('./utilities'); 4 | 5 | module CleanModule { 6 | export function clean(): any { 7 | return src( 8 | [ 9 | 'dist', 10 | 'inlineDist', 11 | 'inlineSrc', 12 | 'scenariotestresults', 13 | 'unittests', 14 | 'src/assets/strings', 15 | 'src/assets/styles', 16 | 'src/generated' 17 | ], 18 | { 19 | read: false, 20 | allowEmpty: true 21 | }) 22 | .pipe(gulpClean({ force: true })); 23 | } 24 | } 25 | 26 | Utilities.exportFunctions(exports, CleanModule); 27 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/test-util/load-babel-require.helper.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | // node cannot read ES6 files so we use babel to transpile them 5 | let babelCompileLibraries = [ 6 | '/node_modules/@microsoft/windows-admin-center-sdk', 7 | '/node_modules/@angular/', 8 | '/dist/' 9 | ]; 10 | 11 | let startsWith = babelCompileLibraries.map((relativePath) => (process.cwd().split('\\').join('/') + relativePath).toUpperCase()); 12 | 13 | require('babel-register')({ 14 | ignore: function (filename) { 15 | filename = filename.toUpperCase(); 16 | if (startsWith.find((startWith) => filename.indexOf(startWith) === 0)) { 17 | return false; 18 | } else { 19 | return true; 20 | } 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "__MERGE_NOTICE__": "THIS FILE WAS MERGED FROM msft-sme-build. some properties in this file may be overridden if changed.", 3 | "__WHY_TWO_TSCONFIGS__": "There are 2 tsconfigs in this project. one is for ngc and visual studio at the root of the project. The other is for ng build and ng serve.", 4 | "angularCompilerOptions": { 5 | "skipTemplateCodegen": true 6 | }, 7 | "compilerOptions": { 8 | "baseUrl": "", 9 | "declaration": true, 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "inlineSourceMap": true, 13 | "lib": [ 14 | "es6", 15 | "dom" 16 | ], 17 | "module": "es6", 18 | "moduleResolution": "node", 19 | "outDir": "./dist", 20 | "sourceRoot": "./src", 21 | "target": "es5" 22 | }, 23 | "include": [ 24 | "src/**/*.ts" 25 | ] 26 | } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/validate.ts: -------------------------------------------------------------------------------- 1 | const { parallel, src } = require('gulp'); 2 | const schemaForm = require('@microsoft/windows-admin-center-sdk/tools/gulp-schema-form'); 3 | const manifestValidator = require('@microsoft/windows-admin-center-sdk/tools/gulp-manifest-validator'); 4 | const Utilities = require('./utilities'); 5 | 6 | module ValidateModule { 7 | function schemaFormValidateResourceString() { 8 | return src('src/**/*.ts') 9 | .pipe(schemaForm()); 10 | } 11 | 12 | // special gulp task to test the manifest validation gulp tool. 13 | function testValidateManifests() { 14 | return src('src/manifest.json') 15 | .pipe(manifestValidator()); 16 | } 17 | 18 | export const validate = parallel(schemaFormValidateResourceString, testValidateManifests); 19 | } 20 | 21 | Utilities.exportFunctions(exports, ValidateModule); 22 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/main.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | import './polyfills.ts'; 5 | 6 | import { enableProdMode } from '@angular/core'; 7 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 8 | import { CoreEnvironment } from '@microsoft/windows-admin-center-sdk/core'; 9 | import { AppModule } from './app/app.module'; 10 | import { environment } from './environments/environment'; 11 | 12 | if (environment.production) { 13 | enableProdMode(); 14 | } 15 | 16 | // initialize SME module environment with localization settings. 17 | CoreEnvironment.initialize( 18 | { 19 | name: '{!company-name}.{!product-name}', 20 | isProduction: environment.production, 21 | shellOrigin: '*' 22 | }, 23 | { 24 | resourcesPath: 'assets/strings' 25 | }) 26 | .then(() => platformBrowserDynamic().bootstrapModule(AppModule)); 27 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/main.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | import './polyfills.ts'; 5 | 6 | import { enableProdMode } from '@angular/core'; 7 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 8 | import { CoreEnvironment } from '@microsoft/windows-admin-center-sdk/core'; 9 | import { AppModule } from './app/app.module'; 10 | import { environment } from './environments/environment'; 11 | import { PowerShellScripts } from './generated/powershell-scripts'; 12 | 13 | if (environment.production) { 14 | enableProdMode(); 15 | } 16 | 17 | // initialize SME module environment with localization settings. 18 | CoreEnvironment.initialize( 19 | { 20 | name: '{!company-name}.{!product-name}', 21 | powerShellModuleName: PowerShellScripts.module, 22 | isProduction: environment.production, 23 | shellOrigin: '*' 24 | }, 25 | { 26 | resourcesPath: 'assets/strings' 27 | }) 28 | .then(() => platformBrowserDynamic().bootstrapModule(AppModule)); 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 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 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/tsconfig.inline.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "", 4 | "sourceRoot": "./inlineSrc", 5 | "outDir": "./inlineDist", 6 | "target": "es2015", 7 | "module": "es2015", 8 | "moduleResolution": "node", 9 | "declaration": true, 10 | "sourceMap": true, 11 | "inlineSources": true, 12 | "emitDecoratorMetadata": true, 13 | "experimentalDecorators": true, 14 | "importHelpers": true, 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "dom", 20 | "es2018" 21 | ] 22 | }, 23 | "angularCompilerOptions": { 24 | "annotateForClosureCompiler": true, 25 | "skipTemplateCodegen": true, 26 | "strictMetadataEmit": true, 27 | "fullTemplateTypeCheck": true, 28 | "strictInjectionParameters": true, 29 | "enableResourceInlining": true 30 | }, 31 | "exclude": [ 32 | "inlineSrc/environment", 33 | "inlineSrc/main.ts", 34 | "inlineSrc/public_api.ts", 35 | "inlineSrc/test.ts", 36 | "src", 37 | "bundle", 38 | "index.d.ts", 39 | "**/*.spec.ts", 40 | "gulpfile.ts" 41 | ] 42 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { IdleComponent } from '@microsoft/windows-admin-center-sdk/angular'; 4 | 5 | // These are the basic routes that are required in order to load an extension and make service calls. 6 | const appRoutes: Routes = [ 7 | // The idle component route is used for 'long running' processes that take any amount of time (async). 8 | // This is a required path and component. 9 | { 10 | path: 'idle', 11 | component: IdleComponent 12 | }, 13 | { 14 | path: '', 15 | loadChildren: 'app/default/default.module#DefaultModule' 16 | }, 17 | // this child route is used to route back to the home path when an invalid URL is provided to the browser. 18 | { 19 | path: '**', 20 | redirectTo: '' // double check navigation 21 | } 22 | ]; 23 | 24 | @NgModule({ 25 | imports: [ 26 | RouterModule.forRoot( 27 | appRoutes, 28 | { 29 | // un-comment to enable debug log messages 30 | // enableTracing: true, 31 | 32 | // don't navigate at initially. 33 | initialNavigation: true 34 | }) 35 | ], 36 | exports: [ 37 | RouterModule 38 | ] 39 | }) 40 | export class AppRoutingModule {} 41 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/test.ts: -------------------------------------------------------------------------------- 1 | import 'zone.js/dist/zone-testing'; 2 | 3 | import { getTestBed } from '@angular/core/testing'; 4 | import { 5 | BrowserDynamicTestingModule, 6 | platformBrowserDynamicTesting 7 | } from '@angular/platform-browser-dynamic/testing'; 8 | import { MsftSmeMock } from '@microsoft/windows-admin-center-sdk/core/base/msft-sme.mock'; 9 | import { ConsoleMock } from '@microsoft/windows-admin-center-sdk/core/test-utilities/console.mock'; 10 | 11 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 12 | declare var __karma__: any; 13 | declare var require: any; 14 | 15 | // Prevent Karma from running prematurely. 16 | __karma__.loaded = function () { 17 | // loaded event handler for karma 18 | }; 19 | 20 | // First, initialize the Angular testing environment. 21 | getTestBed().initTestEnvironment( 22 | BrowserDynamicTestingModule, 23 | platformBrowserDynamicTesting() 24 | ); 25 | 26 | // Setup our mocks before all the tests run. 27 | beforeAll(() => { 28 | const strings = require('./assets/strings/strings.json'); 29 | MsftSmeMock.mockStrings(strings); 30 | MsftSmeMock.mockSelf(); 31 | ConsoleMock.mockConsole(); 32 | }); 33 | 34 | // Then we find all the tests. 35 | const context = require.context('./', true, /\.spec\.ts/); 36 | // And load the modules. 37 | context.keys().map(context); 38 | // Finally, start Karma to run the tests. 39 | __karma__.start(); 40 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/resources/icons/Server.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/resources/icons/Server.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/test.ts: -------------------------------------------------------------------------------- 1 | import { Config } from './config'; 2 | const { dest, src } = require('gulp'); 3 | const testRunner = require('@microsoft/windows-admin-center-sdk/tools/test-runner'); 4 | const Utilities = require('./utilities'); 5 | const argv = Utilities.gulpArgv(); 6 | const config: Config = require('../config-data').gulpConfig(); 7 | 8 | module TestModule { 9 | export function unitTestApp(cb, options: any = {}): void { 10 | const args = ['test']; 11 | if (argv['prod']) { 12 | args.push('--prod'); 13 | } else if (argv['debug']) { 14 | args.push('--c=debug'); 15 | } 16 | 17 | Utilities.ng(cb, args, options, code => { 18 | return code 19 | ? `ng test exited with code ${code}, indicating some tests have failed. Check the above log output for failed tests.` 20 | : null; 21 | }); 22 | } 23 | 24 | export function pester(cb) { 25 | testRunner({ 26 | pester: { 27 | testPath: './tests/powershell', 28 | srcPath: './src/resources/scripts/*.ps1', 29 | outputPath: `./unittests/pesterResults.xml`, 30 | verbose: argv.verbose 31 | } 32 | }, cb); 33 | } 34 | 35 | export const test = config.powershell.enablePester ? parallel(unitTestApp, pester) : unitTestApp; 36 | } 37 | 38 | Utilities.exportFunctions(exports, TestModule); 39 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { IdleComponent } from '@microsoft/windows-admin-center-sdk/angular'; 4 | import { DefaultModule } from './default/default.module'; 5 | 6 | // These are the basic routes that are required in order to load an extension and make service calls. 7 | const appRoutes: Routes = [ 8 | // The idle component route is used for 'long running' processes that take any amount of time (async). 9 | // This is a required path and component. 10 | { 11 | path: 'idle', 12 | component: IdleComponent 13 | }, 14 | { 15 | path: '', 16 | loadChildren: './default/default.module#DefaultModule' 17 | }, 18 | // this child route is used to route back to the home path when an invalid URL is provided to the browser. 19 | { 20 | path: '**', 21 | redirectTo: '' // double check navigation 22 | } 23 | ]; 24 | 25 | @NgModule({ 26 | imports: [ 27 | RouterModule.forRoot( 28 | appRoutes, 29 | { 30 | // un-comment to enable debug log messages 31 | // enableTracing: true, 32 | 33 | // don't navigate at initially. 34 | initialNavigation: true 35 | }) 36 | ], 37 | exports: [ 38 | RouterModule 39 | ] 40 | }) 41 | export class AppRoutingModule {} 42 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { ErrorHandler, NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { BrowserModule } from '@angular/platform-browser'; 5 | import { 6 | AppContextService, 7 | AppErrorHandler, 8 | CoreServiceModule, 9 | DialogModule, 10 | GuidedPanelModule, 11 | IconModule, 12 | IdleModule, 13 | LoadingWheelModule, 14 | ResourceService, 15 | SmeUxModule 16 | } from '@microsoft/windows-admin-center-sdk/angular'; 17 | import { AppRoutingModule } from './app-routing.module'; 18 | import { AppComponent } from './app.component'; 19 | 20 | @NgModule({ 21 | declarations: [ 22 | AppComponent 23 | ], 24 | imports: [ 25 | CoreServiceModule, 26 | CommonModule, 27 | BrowserModule, 28 | DialogModule, 29 | FormsModule, 30 | SmeUxModule, 31 | IconModule, 32 | LoadingWheelModule, 33 | GuidedPanelModule, 34 | IdleModule, 35 | AppRoutingModule 36 | ], 37 | providers: [ 38 | ResourceService, 39 | { 40 | provide: ErrorHandler, 41 | useClass: AppErrorHandler 42 | } 43 | ], 44 | bootstrap: [AppComponent] 45 | }) 46 | export class AppModule { 47 | constructor(private appContextService: AppContextService) { 48 | this.appContextService.initializeModule({}); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { ErrorHandler, NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { BrowserModule } from '@angular/platform-browser'; 5 | import { 6 | AppContextService, 7 | AppErrorHandler, 8 | CoreServiceModule, 9 | DialogModule, 10 | GuidedPanelModule, 11 | IconModule, 12 | IdleModule, 13 | LoadingWheelModule, 14 | PipesModule, 15 | ResourceService, 16 | SmeStylesModule, 17 | SvgModule 18 | } from '@microsoft/windows-admin-center-sdk/angular'; 19 | import { AppRoutingModule } from './app-routing.module'; 20 | import { AppComponent } from './app.component'; 21 | 22 | @NgModule({ 23 | declarations: [ 24 | AppComponent 25 | ], 26 | imports: [ 27 | CoreServiceModule, 28 | CommonModule, 29 | BrowserModule, 30 | DialogModule, 31 | FormsModule, 32 | SmeStylesModule, 33 | SvgModule, 34 | IconModule, 35 | LoadingWheelModule, 36 | GuidedPanelModule, 37 | PipesModule, 38 | IdleModule, 39 | AppRoutingModule 40 | ], 41 | providers: [ 42 | ResourceService, 43 | { 44 | provide: ErrorHandler, 45 | useClass: AppErrorHandler 46 | } 47 | ], 48 | bootstrap: [AppComponent] 49 | }) 50 | export class AppModule { 51 | constructor(private appContextService: AppContextService) { 52 | this.appContextService.initializeModule({}); 53 | } 54 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tools/gulp-license.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var buffer_1 = require("buffer"); 4 | var gutil = require("gulp-util"); 5 | var Path = require("path"); 6 | var through2 = require("through2"); 7 | var PLUGIN_NAME = 'gulp-license'; 8 | /** 9 | * Plugin level function 10 | */ 11 | function gulpLicense(getLicense) { 12 | function extendError(pError, error) { 13 | if (error && (typeof error === 'object')) { 14 | ['name', 'errno'].forEach(function (property) { 15 | if (property in error) { 16 | // tslint:disable-next-line:no-invalid-this 17 | this[property] = error[property]; 18 | } 19 | }, pError); 20 | } 21 | return pError; 22 | } 23 | return through2.obj(function (file, enc, cb) { 24 | try { 25 | var path = Path.parse(file.path); 26 | var license = getLicense(path.ext); 27 | if (license) { 28 | var contents = file.contents.toString('utf8'); 29 | if(!contents.includes(license)) { 30 | contents = license + contents; 31 | file.contents = new buffer_1.Buffer(contents); 32 | } 33 | } 34 | return cb(null, file); 35 | } 36 | catch (e) { 37 | var error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new gutil.PluginError(PLUGIN_NAME, e.message), e) : e; 38 | return cb(error); 39 | } 40 | }); 41 | } 42 | module.exports = gulpLicense; -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/test-util/load-jsdom.helper.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | // Loads JSDOM and configures it so UTs can access all the features as winthin a browser 4 | let jsdom = require('jsdom'); 5 | (global).document = jsdom.jsdom(''); 6 | (global).window = document.defaultView; 7 | (global).navigator = window.navigator; 8 | 9 | // load jQuery that is needed by signalR 10 | (global).window.jQuery = require('jquery/dist/jquery.js'); 11 | (global).$ = (global).window.jQuery; 12 | (global).window.Event = {}; 13 | 14 | Object.keys(document.defaultView).forEach(property => { 15 | if (typeof global[property] === 'undefined') { 16 | global[property] = document.defaultView[property]; 17 | } 18 | }); 19 | 20 | class MockStorage implements Storage { 21 | public length: number; 22 | 23 | private items = {}; 24 | 25 | [index: number]: string; 26 | 27 | public clear(): void { 28 | this.items = {}; 29 | } 30 | 31 | public getItem(key: string): string { 32 | return this.items[key]; 33 | } 34 | 35 | public key(index: number): string { 36 | return this[index]; 37 | } 38 | 39 | public removeItem(key: string): void { 40 | this.items[key] = undefined; 41 | } 42 | 43 | public setItem(key: string, data: string): void { 44 | this.items[key] = data; 45 | } 46 | } 47 | 48 | (global).localStorage = new MockStorage(); 49 | (global).sessionStorage = new MockStorage(); 50 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "__COMMENT_NOTICE__": "Normally, this file supports comments. However if comments are present the whole file may be overridden by msft-sme-build.", 3 | "__MERGE_NOTICE__": "THIS FILE WAS MERGED FROM msft-sme-build. some properties in this file may be overridden if changed.", 4 | "__MORE_INFROMATION__": "For more information about this file, visit: https://go.microsoft.com/fwlink/?linkid=830387", 5 | "configurations": [ 6 | { 7 | "args": [ 8 | "generate-resjson-interface" 9 | ], 10 | "cwd": "${workspaceRoot}", 11 | "name": "gulp debug", 12 | "outFiles": [ 13 | ], 14 | "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", 15 | "request": "launch", 16 | "sourceMaps": true, 17 | "stopOnEntry": false, 18 | "type": "node" 19 | }, 20 | { 21 | "args": [ 22 | "build" 23 | ], 24 | "cwd": "${workspaceRoot}", 25 | "name": "Build", 26 | "outFiles": [ 27 | ], 28 | "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", 29 | "request": "launch", 30 | "sourceMaps": true, 31 | "stopOnEntry": false, 32 | "type": "node" 33 | }, 34 | { 35 | "args": [ 36 | "test" 37 | ], 38 | "cwd": "${workspaceRoot}", 39 | "name": "test", 40 | "outFiles": [ 41 | "${workspaceRoot}/dist/**/*.js" 42 | ], 43 | "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", 44 | "request": "launch", 45 | "sourceMaps": true, 46 | "stopOnEntry": false, 47 | "type": "node2" 48 | } 49 | ], 50 | "version": "0.2.0" 51 | } -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | process.env.CHROME_BIN = require('puppeteer').executablePath(); 4 | 5 | module.exports = function(config) { 6 | config.set({ 7 | basePath: '', 8 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 9 | plugins: [ 10 | require('karma-jasmine'), 11 | require('karma-chrome-launcher'), 12 | require('karma-jasmine-html-reporter'), 13 | require('karma-coverage-istanbul-reporter'), 14 | require('@angular-devkit/build-angular/plugins/karma') 15 | ], 16 | client: { 17 | clearContext: false // leave Jasmine Spec Runner output visible in browser 18 | }, 19 | coverageIstanbulReporter: { 20 | dir: require('path').join(__dirname, '../unittests/app/coverage'), 21 | reports: ['lcovonly'], 22 | fixWebpackSourcePaths: true, 23 | thresholds: { 24 | // 80 percent code coverage would be much more ideal. 25 | statements: 0, 26 | lines: 0, 27 | branches: 0, 28 | functions: 0 29 | } 30 | }, 31 | reporters: ['progress', 'kjhtml'], 32 | port: 9876, 33 | colors: true, 34 | logLevel: config.LOG_INFO, 35 | // logLevel: config.LOG_DEBUG, 36 | autoWatch: true, 37 | browsers: ['ChromeHeadless'], 38 | singleRun: true 39 | // browsers: ['Chrome'], 40 | // singleRun: false 41 | }); 42 | }; -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/compile.ts: -------------------------------------------------------------------------------- 1 | const { dest, series, src } = require('gulp'); 2 | const inlineNg2Template = require('gulp-inline-ng2-template'); 3 | const ngc = require('@angular/compiler-cli/src/main'); 4 | const Utilities = require('./utilities'); 5 | const argv = Utilities.gulpArgv(); 6 | 7 | module CompileModule { 8 | function getBundleArguments(appName: string): string[] { 9 | const args = ['build', appName, '--aot', '--progress=false', '--extract-licenses=false']; 10 | if (argv['verbose']) { args.push('--verbose'); } 11 | if (argv['prod']) { args.push('--prod'); } 12 | if (argv['watch']) { args.push('--watch'); } 13 | return args; 14 | } 15 | 16 | function getServeArguments(): string[] { 17 | const args = ['serve'].concat(process.argv.slice(3)); 18 | return args; 19 | } 20 | 21 | export function inlineSource(): any { 22 | return src('./src/**/*.ts') 23 | .pipe(inlineNg2Template({ useRelativePaths: true })) 24 | .pipe(dest('inlineSrc')); 25 | } 26 | 27 | export function inlineCompile(cb): any { 28 | const errors = []; 29 | ngc.main(['-p', 'tsconfig.inline.json'], (consoleError) => { errors.push(consoleError); }); 30 | errors.length > 0 ? cb(errors.join('\n')) : cb(); 31 | } 32 | 33 | export function bundleApp(cb): void { 34 | const args = getBundleArguments('module-app'); 35 | Utilities.ng(cb, args); 36 | } 37 | 38 | export function serveApp(cb): void { 39 | const args = getServeArguments(); 40 | Utilities.ng(cb, args); 41 | } 42 | } 43 | 44 | Utilities.exportFunctions(exports, CompileModule); 45 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Minimum information to control common gulp files. 3 | */ 4 | export interface Config { 5 | resjson: { 6 | /** 7 | * The prefix name of ResJSON resource key used on strings.resjson. 8 | */ 9 | resourceName: string; 10 | 11 | /** 12 | * The depth of loc/output folder. 13 | */ 14 | localeOffset: number; 15 | 16 | /** 17 | * The output folder of localized strings. 18 | */ 19 | localePath: string; 20 | }; 21 | powershell: { 22 | /** 23 | * Skip processing the powershell code. 24 | */ 25 | skip?: boolean; 26 | 27 | /** 28 | * The name of PowerShell module. 29 | */ 30 | name: string; 31 | 32 | /** 33 | * The GUID of PowerShell module. 34 | */ 35 | guid: string; 36 | 37 | /** 38 | * The list of PowerShell script folders. 39 | */ 40 | list: string[]; 41 | 42 | /** 43 | * Enable the pester test. 44 | */ 45 | enablePester: boolean; 46 | 47 | /** 48 | * Skip the CIM generator. 49 | */ 50 | skipCim?: boolean; 51 | 52 | /** 53 | * Skip the module generator. 54 | */ 55 | skipModule?: boolean; 56 | 57 | /** 58 | * Skip the resjson resource string generator. 59 | */ 60 | skipResjson?: boolean; 61 | 62 | /** 63 | * Skip the manifest resource generator. 64 | */ 65 | skipManifest?: boolean; 66 | }; 67 | test?: { 68 | skip: boolean; 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "__APPS_PROP__": "The first item in the 'apps' object is expected to be the main application. Additional items will be left alone", 3 | "__MERGE_NOTICE__": "THIS FILE WAS MERGED FROM msft-sme-build. some properties in this file may be overridden if changed.", 4 | "apps": [ 5 | { 6 | "assets": [ 7 | "assets", 8 | "manifest.json" 9 | ], 10 | "environmentSource": "environments/environment.ts", 11 | "environments": { 12 | "dev": "environments/environment.ts", 13 | "prod": "environments/environment.prod.ts" 14 | }, 15 | "index": "index.html", 16 | "main": "main.ts", 17 | "outDir": "bundle", 18 | "root": "src", 19 | "scripts": [ 20 | "../node_modules/jquery/dist/jquery.min.js", 21 | "../node_modules/bootstrap/dist/js/bootstrap.min.js" 22 | ], 23 | "styles": [ 24 | "../node_modules/bootstrap/dist/css/bootstrap.min.css", 25 | "../node_modules/@microsoft/windows-admin-center-sdk/dist/angular/assets/sme-icons/css/sme-icons.css", 26 | "../node_modules/@microsoft/windows-admin-center-sdk/dist/angular/assets/winstrap-tmp/css/winstrap.min.css", 27 | "../node_modules/@microsoft/windows-admin-center-sdk/dist/angular/assets/winstrap-tmp/css/winstrap-optional.min.css", 28 | "../node_modules/primeng/resources/primeng.min.css", 29 | "../node_modules/primeng/resources/themes/bootstrap/theme.css" 30 | ], 31 | "tsconfig": "tsconfig.json" 32 | } 33 | ], 34 | "defaults": { 35 | "inline": { 36 | "style": false, 37 | "template": false 38 | }, 39 | "prefixInterfaces": false, 40 | "styleExt": "css" 41 | }, 42 | "project": { 43 | "name": "hello-world", 44 | "version": "1.0.0-beta.25.5" 45 | } 46 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-merge-json-in-folders/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | import gutil = require('gulp-util'); 4 | import through2 = require('through2'); 5 | import jsonMerge = require('./json-merge'); 6 | 7 | let PluginError = gutil.PluginError; 8 | let PLUGIN_NAME = 'gulp-merge-json-in-folders'; 9 | 10 | function gulpMergeJsonInFolders(options) { 11 | function extendError(pError, error) { 12 | if (error && (typeof error === 'object')) { 13 | ['name', 'errno'].forEach(function (property) { 14 | if (property in error) { 15 | this[property] = error[property]; 16 | } 17 | }, pError); 18 | } 19 | 20 | return pError; 21 | } 22 | 23 | // 24 | // (Options): 25 | // 26 | // source path of current folder for 'strings.json' 27 | // src: string; 28 | // 29 | 30 | // override options settings if not specified. 31 | options = Object.assign({ src: './src/assets/strings' }, options || {}); 32 | 33 | let externalSources: string[] = []; 34 | 35 | return through2.obj( 36 | /** 37 | * @this {Transform} 38 | */ 39 | function (file, encoding, callback) { 40 | if (file.isDirectory()) { 41 | externalSources.push(file.path); 42 | } 43 | 44 | callback(); 45 | }, 46 | 47 | /** 48 | * @this {Flush} 49 | */ 50 | function (callback) { 51 | try { 52 | const merge = new jsonMerge.JsonMerge(); 53 | const files = merge.mergeJsonInFolders(options.src, externalSources); 54 | files.forEach(file => this.push(file)); 55 | } catch (e) { 56 | let error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 57 | gutil.log(error); 58 | } 59 | 60 | callback(); 61 | }); 62 | 63 | }; 64 | 65 | module.exports = gulpMergeJsonInFolders; -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-merge-json-in-folders/index.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | exports.__esModule = true; 4 | var gutil = require("gulp-util"); 5 | var through2 = require("through2"); 6 | var jsonMerge = require("./json-merge"); 7 | var PluginError = gutil.PluginError; 8 | var PLUGIN_NAME = 'gulp-merge-json-in-folders'; 9 | function gulpMergeJsonInFolders(options) { 10 | function extendError(pError, error) { 11 | if (error && (typeof error === 'object')) { 12 | ['name', 'errno'].forEach(function (property) { 13 | if (property in error) { 14 | this[property] = error[property]; 15 | } 16 | }, pError); 17 | } 18 | return pError; 19 | } 20 | // 21 | // (Options): 22 | // 23 | // source path of current folder for 'strings.json' 24 | // src: string; 25 | // 26 | // override options settings if not specified. 27 | options = Object.assign({ src: './src/assets/strings' }, options || {}); 28 | var externalSources = []; 29 | return through2.obj( 30 | /** 31 | * @this {Transform} 32 | */ 33 | function (file, encoding, callback) { 34 | if (file.isDirectory()) { 35 | externalSources.push(file.path); 36 | } 37 | callback(); 38 | }, 39 | /** 40 | * @this {Flush} 41 | */ 42 | function (callback) { 43 | var _this = this; 44 | try { 45 | var merge = new jsonMerge.JsonMerge(); 46 | var files = merge.mergeJsonInFolders(options.src, externalSources); 47 | files.forEach(function (file) { return _this.push(file); }); 48 | } 49 | catch (e) { 50 | var error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 51 | gutil.log(error); 52 | } 53 | callback(); 54 | }); 55 | } 56 | ; 57 | module.exports = gulpMergeJsonInFolders; 58 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/resjson.ts: -------------------------------------------------------------------------------- 1 | import { Config } from './config'; 2 | const { dest, parallel, series, src } = require('gulp'); 3 | const gulpResJson = require('@microsoft/windows-admin-center-sdk/tools/gulp-resjson'); 4 | const gulpMergeJsonInFolders = require('@microsoft/windows-admin-center-sdk/tools/gulp-merge-json-in-folders'); 5 | const manifestResource = require('@microsoft/windows-admin-center-sdk/tools/gulp-manifest-resource'); 6 | const Utilities = require('./utilities'); 7 | const config: Config = require('../config-data').gulpConfig(); 8 | 9 | module ResjsonModule { 10 | function resjsonJson(): any { 11 | return src('src/resources/strings/**/*.resjson') 12 | .pipe(gulpResJson({ json: true })) 13 | .pipe(dest('./src/assets/strings')); 14 | } 15 | 16 | function resjsonJsonLocalized(): any { 17 | return src(config.resjson.localePath + '/**/*.resjson') 18 | .pipe(gulpResJson({ json: true, localeOffset: config.resjson.localeOffset })) 19 | .pipe(dest('./src/assets/strings')); 20 | } 21 | 22 | function resjsonInterface(): any { 23 | return src('src/resources/**/*.resjson') 24 | .pipe(gulpResJson({ typescript: 'interface' })) 25 | .pipe(dest('src/generated')); 26 | } 27 | 28 | function mergeLocalizedJson(): any { 29 | return src(['./node_modules/@microsoft/windows-admin-center-sdk/**/assets/strings']) 30 | .pipe(gulpMergeJsonInFolders({ src: './src/assets/strings' })) 31 | .pipe(dest('src/assets/strings')); 32 | } 33 | 34 | function updateManifestResource(): any { 35 | return src(['src/resources/strings/strings.resjson', config.resjson.localePath + '/**/*.resjson']) 36 | .pipe(manifestResource({ resourceName: config.resjson.resourceName })) 37 | .pipe(dest('.')); 38 | } 39 | 40 | export const resjson = series( 41 | parallel(resjsonJson, resjsonJsonLocalized, resjsonInterface), 42 | parallel(mergeLocalizedJson, updateManifestResource) 43 | ); 44 | } 45 | 46 | Utilities.exportFunctions(exports, ResjsonModule); 47 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tools/UpdateExtensionName.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Alias("n")] 3 | [Parameter(Mandatory=$true)] 4 | [string]$name, 5 | [switch] $Clean = $false 6 | ) 7 | 8 | $name = $name.ToLower(); 9 | $componentName = $name.ToUpper()[0] 10 | $componentName += $name.Substring(1) 11 | 12 | $baseDirectory = Get-Location | Split-Path 13 | 14 | $appDirectory = $baseDirectory + "\src\app" 15 | $exampleDirectory = $appDirectory + "\hello" 16 | 17 | function RenameFilesInDirectory($directory) 18 | { 19 | "Renaming files..." 20 | $fileSelect = $directory + "\hello.*" 21 | $filesToChange = Split-Path $fileSelect -Leaf -Resolve 22 | foreach($file in $filesToChange) 23 | { 24 | if($file -ne "hello.service.ts") 25 | { 26 | $filePath = $directory + "\" + $file 27 | $content = Get-Content $filePath 28 | 29 | $newContent = $content.Replace('hello', $name) 30 | $newContent = $newContent.Replace('Hello', $componentName) 31 | 32 | $newFileName = $file.Replace('hello', $name) 33 | $newFilePath = $directory + "\" + $newFileName 34 | # do file update 35 | $newContent | Out-File $newFilePath 36 | Remove-Item $filePath 37 | } 38 | } 39 | 40 | #and now to rename the folder 41 | Rename-Item $directory $name 42 | } 43 | 44 | function UpdateComponentReferences($directory) 45 | { 46 | "Updating app references..." 47 | $fileSelect = $directory + "\app*" 48 | Split-Path $fileSelect -Leaf -Resolve | ForEach-Object { 49 | $updateFile = $directory + "\" + $_ 50 | $content = Get-Content $updateFile 51 | 52 | $newContent = $content.Replace('hello', $name) 53 | $newContent = $newContent.Replace('Hello', $componentName) 54 | 55 | $newContent | Out-File $updateFile 56 | } 57 | } 58 | 59 | function CleanDirectory($directory) 60 | { 61 | "Cleaning..." 62 | # Remove-Item 63 | } 64 | 65 | RenameFilesInDirectory($exampleDirectory) 66 | 67 | UpdateComponentReferences($appDirectory) 68 | 69 | if($Clean.IsPresent) 70 | { 71 | CleanDirectory($exampleDirectory) 72 | } 73 | 74 | 75 | "Done." -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-ps-code/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | 4 | import through2 = require('through2'); 5 | import gutil = require('gulp-util'); 6 | import Path = require('path'); 7 | import Vinyl = require('vinyl'); 8 | import PsCode = require('./ps-code-convert'); 9 | 10 | let PluginError = gutil.PluginError; 11 | let PLUGIN_NAME = 'gulp-ps-code'; 12 | 13 | /** 14 | * Plugin level function 15 | */ 16 | function gulpPsCode(options) { 17 | // 18 | // (Options): 19 | // 20 | // name of generated file. 21 | // name: string; default is 'powershell-script.ts' 22 | // 23 | // remove comments at default: 24 | // noComments: boolean; 25 | // 26 | 27 | // override options settings if not specified. 28 | options = Object.assign({ name: 'powershell-scripts.ts' }, options || {}); 29 | 30 | function extendError(pError, error) { 31 | if (error && (typeof error === 'object')) { 32 | ['name', 'errno'].forEach(function (property) { 33 | if (property in error) { 34 | this[property] = error[property]; 35 | } 36 | }, pError); 37 | } 38 | 39 | return pError; 40 | } 41 | 42 | let collection = {}; 43 | let lastFile = null; 44 | 45 | return through2.obj( 46 | function (file, enc, cb) { 47 | let error = null; 48 | try { 49 | let path = Path.parse(file.path); 50 | if (path.ext === '.ps1') { 51 | if (collection[path.base]) { 52 | throw new Error('gulp-ps-code requires unique name of ps file, conflicted with ' + path.base); 53 | } 54 | 55 | let data = file.contents.toString('utf8'); 56 | collection[path.base] = data; 57 | lastFile = file; 58 | } 59 | } catch (e) { 60 | error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 61 | } 62 | 63 | return cb(error); 64 | }, 65 | function (cb) { 66 | let converter = new PsCode.PsCodeConverter(); 67 | converter.contentReset(); 68 | converter.generate(collection); 69 | 70 | let tsFile = new Vinyl({ 71 | cwd: lastFile.cwd, 72 | base: lastFile.base, 73 | path: lastFile.base + '/' + options.name, 74 | contents: new Buffer(converter.content) 75 | }); 76 | this.push(tsFile); 77 | cb(); 78 | }); 79 | } 80 | 81 | module.exports = gulpPsCode; 82 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/index.ts: -------------------------------------------------------------------------------- 1 | import { Config } from './common/config'; 2 | const { series, parallel, task, watch } = require('gulp'); 3 | const Utilities = require('./common/utilities'); 4 | const config: Config = require('./config-data').gulpConfig(); 5 | 6 | const cleanModule = require('./common/clean'); 7 | const lintModule = require('./common/lint'); 8 | const resjsonModule = require('./common/resjson'); 9 | const powershellModule = require('./common/powershell'); 10 | const validateModule = require('./common/validate'); 11 | const compileModule = require('./common/compile'); 12 | const copyModule = require('./common/copy'); 13 | const testModule = require('./common/test'); 14 | 15 | module IndexModule { 16 | // Export tasks 17 | export const clean = cleanModule.clean; 18 | export const lint = lintModule.lint; 19 | export const lintApp = lintModule.lintApp; 20 | export const validate = validateModule.validate; 21 | export const resjson = resjsonModule.resjson; 22 | export const powershell = config.powershell.skip ? function powershellSkip(cb) { cb(); } : powershellModule.powershell; 23 | export const copy = copyModule.copyApp; 24 | export const inlineDist = copyModule.inlineDist; 25 | export const inlineSource = compileModule.inlineSource; 26 | export const inlineCompile = compileModule.inlineCompile; 27 | export const bundleApp = compileModule.bundleApp; 28 | export const serveApp = compileModule.serveApp; 29 | export const ut = testModule.unitTestApp; 30 | export const pester = testModule.pester; 31 | export const test = config.test && config.test.skip ? function skipTest(cb) {cb();}: testModule.test; 32 | 33 | // Build Tasks 34 | export const generate = parallel(resjson, powershell); 35 | export const compile = series(inlineSource, inlineCompile, inlineDist); 36 | export const app = series(lintApp, bundleApp, copy); 37 | export const build = series(clean, generate, validate, lint, compile, copy, test, app); 38 | 39 | // Serve Tasks 40 | export function watchResource(cb) { 41 | watch(['src/resources/**/*.resjson', 'src/resources/**/*.ps1'], { ignoreInitial: false }, generate); 42 | cb(); 43 | } 44 | 45 | export const serve = series(watchResource, serveApp); 46 | } 47 | 48 | Utilities.exportFunctions(exports, IndexModule); 49 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-svg-code/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | 4 | import through2 = require('through2'); 5 | import gutil = require('gulp-util'); 6 | import Path = require('path'); 7 | import Vinyl = require('vinyl'); 8 | import SvgCode = require('./svg-code-convert'); 9 | 10 | let PluginError = gutil.PluginError; 11 | let PLUGIN_NAME = 'gulp-svg-code'; 12 | 13 | /** 14 | * Plugin level function 15 | */ 16 | function gulpSvgCode() { 17 | function extendError(pError, error) { 18 | if (error && (typeof error === 'object')) { 19 | ['name', 'errno'].forEach( 20 | function (property) { 21 | if (property in error) { 22 | this[property] = error[property]; 23 | } 24 | }, 25 | pError); 26 | } 27 | 28 | return pError; 29 | } 30 | 31 | let pathPrefix = null; 32 | let collection = {}; 33 | return through2.obj( 34 | function (file, enc, cb) { 35 | let error = null; 36 | try { 37 | let path = Path.parse(file.path); 38 | if (path.ext === '.svg') { 39 | if (pathPrefix === null) { 40 | pathPrefix = path.dir; 41 | } else { 42 | let segments = path.dir.split('\\'); 43 | let segPrefix = pathPrefix.split('\\'); 44 | let newPrefix = []; 45 | for (let i = 0; i < segPrefix.length; i++) { 46 | if (segments[i].toLocaleUpperCase() !== segPrefix[i].toLocaleUpperCase()) { 47 | pathPrefix = newPrefix.join('\\'); 48 | break; 49 | } 50 | 51 | newPrefix.push(segments[i]); 52 | } 53 | } 54 | 55 | let data = file.contents.toString('utf8'); 56 | collection[file.path] = data; 57 | } 58 | } catch (e) { 59 | error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 60 | } 61 | 62 | return cb(error); 63 | }, 64 | function (cb) { 65 | let converter = new SvgCode.SvgCodeConverter(); 66 | converter.contentReset(); 67 | converter.generate(collection, pathPrefix); 68 | 69 | let cssFile = new Vinyl({ 70 | cwd: '/', 71 | base: pathPrefix, 72 | path: pathPrefix + '\\svg.css', 73 | contents: new Buffer(converter.contentCss) 74 | }); 75 | this.push(cssFile); 76 | 77 | let tsFile = new Vinyl({ 78 | cwd: '/', 79 | base: pathPrefix, 80 | path: pathPrefix + '\\svg.ts', 81 | contents: new Buffer(converter.contentTs) 82 | }); 83 | this.push(tsFile); 84 | cb(); 85 | }); 86 | } 87 | 88 | module.exports = gulpSvgCode; 89 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-ps-code/index.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | exports.__esModule = true; 4 | var through2 = require("through2"); 5 | var gutil = require("gulp-util"); 6 | var Path = require("path"); 7 | var Vinyl = require("vinyl"); 8 | var PsCode = require("./ps-code-convert"); 9 | var PluginError = gutil.PluginError; 10 | var PLUGIN_NAME = 'gulp-ps-code'; 11 | /** 12 | * Plugin level function 13 | */ 14 | function gulpPsCode(options) { 15 | // 16 | // (Options): 17 | // 18 | // name of generated file. 19 | // name: string; default is 'powershell-script.ts' 20 | // 21 | // remove comments at default: 22 | // noComments: boolean; 23 | // 24 | // override options settings if not specified. 25 | options = Object.assign({ name: 'powershell-scripts.ts' }, options || {}); 26 | function extendError(pError, error) { 27 | if (error && (typeof error === 'object')) { 28 | ['name', 'errno'].forEach(function (property) { 29 | if (property in error) { 30 | this[property] = error[property]; 31 | } 32 | }, pError); 33 | } 34 | return pError; 35 | } 36 | var collection = {}; 37 | var lastFile = null; 38 | return through2.obj(function (file, enc, cb) { 39 | var error = null; 40 | try { 41 | var path = Path.parse(file.path); 42 | if (path.ext === '.ps1') { 43 | if (collection[path.base]) { 44 | throw new Error('gulp-ps-code requires unique name of ps file, conflicted with ' + path.base); 45 | } 46 | var data = file.contents.toString('utf8'); 47 | collection[path.base] = data; 48 | lastFile = file; 49 | } 50 | } 51 | catch (e) { 52 | error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 53 | } 54 | return cb(error); 55 | }, function (cb) { 56 | var converter = new PsCode.PsCodeConverter(); 57 | converter.contentReset(); 58 | converter.generate(collection); 59 | var tsFile = new Vinyl({ 60 | cwd: lastFile.cwd, 61 | base: lastFile.base, 62 | path: lastFile.base + '/' + options.name, 63 | contents: new Buffer(converter.content) 64 | }); 65 | this.push(tsFile); 66 | cb(); 67 | }); 68 | } 69 | module.exports = gulpPsCode; 70 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/utilities.ts: -------------------------------------------------------------------------------- 1 | const values = require('yargs').argv; 2 | const childProcess = require('child_process'); 3 | const log = require('fancy-log'); 4 | const appRoot = require('app-root-path'); 5 | 6 | module Utilities { 7 | 8 | function toBoolean(value: any, defaultValue: boolean = false) { 9 | return defaultValue ? value !== false : !!value; 10 | } 11 | 12 | export function gulpArgv(): { [index: string]: boolean } { 13 | return { 14 | prod: toBoolean(values['prod']), 15 | verbose: toBoolean(values['verbose']), 16 | junit: toBoolean(values['junit']), 17 | expandCss: toBoolean(values['expandcss']), 18 | target: values['target'], 19 | debug: values['debug'], 20 | styles: toBoolean(values['styles']), 21 | resources: toBoolean(values['resources']), 22 | core: toBoolean(values['core']), 23 | angular: toBoolean(values['angular']), 24 | app: toBoolean(values['app']), 25 | devGuide: toBoolean(values['devguide']) 26 | }; 27 | } 28 | 29 | export function exportFunctions(context: any, gulpModule: any): void { 30 | for (const func in gulpModule) { 31 | if (gulpModule.hasOwnProperty(func)) { 32 | context[func] = gulpModule[func]; 33 | } 34 | } 35 | } 36 | 37 | export function ng(cb, args, options = {}, codeHandler = null) { 38 | const ng_cmd = appRoot.path + '\\node_modules\\.bin\\ng.cmd'; 39 | log(ng_cmd, args.join(' ')); 40 | const errors = []; 41 | const cmd = childProcess.spawn(ng_cmd, args, options); 42 | cmd.stdout.on('data', function (data) { log(data.toString().trim()); }); 43 | cmd.stderr.on('data', function (data) { 44 | const message = data.toString().trim(); 45 | if (message.toUpperCase().startsWith('ERROR')) { 46 | log.error(message); 47 | errors.push(message); 48 | } else { 49 | log(message); 50 | } 51 | }); 52 | cmd.on('exit', function (code) { 53 | if (codeHandler) { 54 | const codeError = codeHandler(code); 55 | if (codeError) { 56 | errors.push(codeError); 57 | } 58 | } 59 | if (errors.length > 0) { 60 | cb(errors.join('\n')); 61 | } else { cb(); } 62 | }); 63 | 64 | } 65 | } 66 | 67 | Utilities.exportFunctions(exports, Utilities); 68 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Uncomment each section to enable it. 2 | # See the following link for more details 3 | # https://git-scm.com/docs/gitattributes 4 | 5 | ############################################################################### 6 | # Set default behavior to automatically normalize line endings. 7 | # This ensures that all files that git considers to be text will have normalized (LF) line endings in the repository. 8 | # The core.eol configuration variable controls which line endings git will use for normalized files in your working directory; 9 | # the default is to use the native line ending for your platform, or CRLF if core.autocrlf is set. 10 | ############################################################################### 11 | * text=auto 12 | 13 | ############################################################################### 14 | # Denote files that will always have CRLF line endings 15 | # While git normally leaves file contents alone, it can be configured to normalize line endings when files are checked out. 16 | ############################################################################### 17 | 18 | ## Basic file types 19 | # *.xml text eol=crlf 20 | # *.txt text eol=crlf 21 | 22 | ## Visual Studio file types 23 | # *.sln text eol=crlf 24 | # *.csproj text eol=crlf 25 | # *.vbproj text eol=crlf 26 | # *.fsproj text eol=crlf 27 | # *.dbproj text eol=crlf 28 | # *.vcxproj text eol=crlf 29 | # *.vcxitems text eol=crlf 30 | # *.props text eol=crlf 31 | # *.filters text eol=crlf 32 | # *.h text eol=crlf 33 | # *.c text eol=crlf 34 | # *.cpp text eol=crlf 35 | # *.cs text eol=crlf 36 | # *.vb text eol=crlf 37 | 38 | ## PowerShell file types 39 | # *.ps1 text eol=crlf 40 | # *.psm1 text eol=crlf 41 | # *.psd1 text eol=crlf 42 | # *.psc1 text eol=crlf 43 | # *.ps1xml text eol=crlf 44 | # *.clixml text eol=crlf 45 | 46 | ## Denote all files that are truly binary and should not be modified. 47 | # *.png binary 48 | # *.jpg binary 49 | # *.dll binary 50 | # *.exe binary 51 | 52 | ############################################################################### 53 | # Set default behavior for command prompt diff. 54 | # It can tell git whether to generate a textual patch for the path or to treat the path as a binary file. It can also affect what line is shown on the hunk 55 | # header @@ -k,l +n,m @@ line, tell git to use an external command to generate the diff, or ask git to convert binary files to a text format before generating the diff. 56 | # Note: This is only used by command line 57 | ############################################################################## 58 | 59 | # *.cs diff=csharp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows Admin Center CLI # 2 | 3 | The Windows Admin Center CLI was created to simplify the process of generating new tools for the platform. 4 | 5 | ## Usage ## 6 | 7 | There is only one command for the CLI, "Create". In order to create a new tool, type the following: 8 | 9 | ``` 10 | wac create --company --tool 11 | ``` 12 | For instance, when creating a tool called Foo for Microsoft, my command would be: 13 | 14 | ``` 15 | wac create --company Microsoft --tool Foo 16 | ``` 17 | 18 | You can also use the CLI to create solution extensions as well: 19 | 20 | ``` 21 | wac create --company Microsoft --tool Foo --solution MySolution 22 | ``` 23 | 24 | In addition to creating extensions, you can specify which version of the SDK you want to utilize. There are 5 rings for you to choose from: 25 | 26 | * legacy (the GA release behind the current, 2 updates per year) 27 | * latest (the most current GA release, 2 updates per year) 28 | * insider (build most recently released to Insiders. Updates monthly) 29 | * next (current dev build. Updates frequently, up to weekly) 30 | * experimental (Updates frequently, up to daily) 31 | 32 | In order to specify which SDK version you want to use, add the version tag to the create command: 33 | 34 | ``` 35 | wac create --company Microsoft --tool Foo --version insider 36 | ``` 37 | 38 | Default value is latest. 39 | 40 | ## Get started with the SDK ## 41 | 42 | Getting started with Windows Admin Center development is easy! Follow along with [step-by-step directions](https://docs.microsoft.com/windows-server/manage/windows-admin-center/extend/prepare-development-environment) to prepare your environment, and learn more about writing and publishing extensions at our [documentation site](https://aka.ms/WACSDKDocs). 43 | 44 | Don't have Windows Admin Center installed yet? [Download](https://aka.ms/WACDownloadPage) Windows Admin Center. 45 | 46 | ## Contributing ## 47 | 48 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 49 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 50 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 51 | 52 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 53 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 54 | provided by the bot. You will only need to do this once across all repos using our CLA. 55 | 56 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 57 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 58 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 59 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-svg-code/index.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | exports.__esModule = true; 4 | var through2 = require("through2"); 5 | var gutil = require("gulp-util"); 6 | var Path = require("path"); 7 | var Vinyl = require("vinyl"); 8 | var SvgCode = require("./svg-code-convert"); 9 | var PluginError = gutil.PluginError; 10 | var PLUGIN_NAME = 'gulp-svg-code'; 11 | /** 12 | * Plugin level function 13 | */ 14 | function gulpSvgCode() { 15 | function extendError(pError, error) { 16 | if (error && (typeof error === 'object')) { 17 | ['name', 'errno'].forEach(function (property) { 18 | if (property in error) { 19 | this[property] = error[property]; 20 | } 21 | }, pError); 22 | } 23 | return pError; 24 | } 25 | var pathPrefix = null; 26 | var collection = {}; 27 | return through2.obj(function (file, enc, cb) { 28 | var error = null; 29 | try { 30 | var path = Path.parse(file.path); 31 | if (path.ext === '.svg') { 32 | if (pathPrefix === null) { 33 | pathPrefix = path.dir; 34 | } 35 | else { 36 | var segments = path.dir.split('\\'); 37 | var segPrefix = pathPrefix.split('\\'); 38 | var newPrefix = []; 39 | for (var i = 0; i < segPrefix.length; i++) { 40 | if (segments[i].toLocaleUpperCase() !== segPrefix[i].toLocaleUpperCase()) { 41 | pathPrefix = newPrefix.join('\\'); 42 | break; 43 | } 44 | newPrefix.push(segments[i]); 45 | } 46 | } 47 | var data = file.contents.toString('utf8'); 48 | collection[file.path] = data; 49 | } 50 | } 51 | catch (e) { 52 | error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 53 | } 54 | return cb(error); 55 | }, function (cb) { 56 | var converter = new SvgCode.SvgCodeConverter(); 57 | converter.contentReset(); 58 | converter.generate(collection, pathPrefix); 59 | var cssFile = new Vinyl({ 60 | cwd: '/', 61 | base: pathPrefix, 62 | path: pathPrefix + '\\svg.css', 63 | contents: new Buffer(converter.contentCss) 64 | }); 65 | this.push(cssFile); 66 | var tsFile = new Vinyl({ 67 | cwd: '/', 68 | base: pathPrefix, 69 | path: pathPrefix + '\\svg.ts', 70 | contents: new Buffer(converter.contentTs) 71 | }); 72 | this.push(tsFile); 73 | cb(); 74 | }); 75 | } 76 | module.exports = gulpSvgCode; 77 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/gulpfile.ts/common/powershell.ts: -------------------------------------------------------------------------------- 1 | import { Config } from './config'; 2 | const { dest, series, src } = require('gulp'); 3 | const psCode = require('@microsoft/windows-admin-center-sdk/tools/gulp-ps-code'); 4 | const psCim = require('@microsoft/windows-admin-center-sdk/tools/gulp-ps-cim'); 5 | const psModule = require('@microsoft/windows-admin-center-sdk/tools/gulp-ps-module'); 6 | const psResjson = require('@microsoft/windows-admin-center-sdk/tools/gulp-ps-resjson'); 7 | const psManifest = require('@microsoft/windows-admin-center-sdk/tools/gulp-ps-manifest'); 8 | const Utilities = require('./utilities'); 9 | const config: Config = require('../config-data').gulpConfig(); 10 | 11 | module PowerShellModule { 12 | function powershellCim() { 13 | return src('src/powershell-cim-config.json') 14 | .pipe(psCim()) 15 | .pipe(dest('src/generated/scripts/')); 16 | } 17 | 18 | function powershellCode() { 19 | return src(['src/resources/scripts/**/*.ps1', 'src/generated/scripts/**/*.ps1']) 20 | .pipe(psCode({ powerShellModuleName: config.powershell.name })) 21 | .pipe(dest('src/generated/')); 22 | } 23 | 24 | function powershellModule() { 25 | const powerShellModulePaths = []; 26 | config.powershell.list.forEach(item => { 27 | powerShellModulePaths.push(item + '/resources/scripts/**/*.ps1'); 28 | powerShellModulePaths.push(item + '/generated/scripts/**/*.ps1'); 29 | }); 30 | return src(powerShellModulePaths) 31 | .pipe(psModule(config.powershell)) 32 | .pipe(dest('dist/powershell-module/' + config.powershell.name)); 33 | } 34 | 35 | function powershellResjson() { 36 | return src(['src/resources/strings/strings.resjson', config.resjson.localePath + '/**/*.resjson']) 37 | .pipe(psResjson({ resourceName: config.powershell.name })) 38 | .pipe(dest('dist/packages/shell/dist/powershell-module/' + config.resjson.resourceName)); 39 | } 40 | 41 | function powershellManifest(): any { 42 | return src(['src/resources/scripts/**/*.ps1']) 43 | .pipe(psManifest({ powerShellModuleName: config.powershell.name })) 44 | .pipe(dest('.')); 45 | } 46 | 47 | const seriesArray = []; 48 | if (!config.powershell.skipCim) { 49 | seriesArray.push(powershellCim); 50 | } 51 | 52 | seriesArray.push(powershellCode); 53 | 54 | if (!config.powershell.skipModule) { 55 | seriesArray.push(powershellModule); 56 | } 57 | 58 | if (!config.powershell.skipResjson) { 59 | seriesArray.push(powershellResjson); 60 | } 61 | 62 | if (!config.powershell.skipManifest) { 63 | seriesArray.push(powershellManifest); 64 | } 65 | 66 | export const powershell = seriesArray.length === 1 ? powershellCode : series(seriesArray); 67 | } 68 | 69 | Utilities.exportFunctions(exports, PowerShellModule); 70 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tools/ssl/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA5b5hZ2dxwP0Q05MMVZGZrs+ecc5ZzOBbvkvk1CZ7D/7aXeyd 3 | /vWRXD66ZQbkwp8XUxchAvLCmy84pCwcxdajXoT/Ydj80X+SPuHdx7YxodSY9rl5 4 | KfOj5n3n4UPxOJRXFWznOG+aterqYb+WRTmcJfS9+cJtfCz5QNnYHhdzcDePClP8 5 | d78o/6VMGAxl2sucoF+yx9XAs1vQD6wYiNWh5POdlxXAr1iuztuny/MV0dlnt1/2 6 | NQtpVj3OveMNqi6LedO3beWMu5Nb3snnUdK68ExoiJVtbJZ5zEolMrY9zS9J3lTV 7 | kq7whZUAm18ahbUX8g3jfl25XEVUjjKbNB3vfQIDAQABAoIBAANyKpXZeFxTr2ft 8 | Abda2rpDhPXiCXjIOLgO/VytQxVHVlEoVmpXlpmSm0seolnE9x2Y8DbSG1cmiyvz 9 | OW9CO+sUBZybG5es2S22R5RSSEZMIQs6VvXpIKE5bDv1v+2AVBoPKxyul9x4rJFQ 10 | xVk+dvgexqazYt8E8awmWFaDNYkOVQCBcBvbiObg1g7m3iY8vaTnTOixYva++++0 11 | +7XcVwYsF1yD8UE8I311ujhsoi+bK6Skz/lNqy+//59pIae9hRHAo2Mh79zCxapf 12 | miDbTI9Vs39eL6h52yO1V+fJ352sFJzxlx8xDGEPJeVqS6ht8C067BXAgVGvvaMl 13 | 7jGT44UCgYEA+nAG77B+buP/qGYJMYYZQuUxQQq7nM0D2QA1u233lQMUBaTzDQTq 14 | jhSfdlko2uguad8HaqmVS2fhHQXFDNsCWTmrA7r3qB2TvWCOct4a+sAosP/CWRo9 15 | Dk67hKCpPBVMA1HBcj0gmYccd4/Wz8d1DfiUyv63dTWCiVUNOQU1rFsCgYEA6tiw 16 | X4RqdT9kz0FETENG0y7TV/VHBeqGJLcyzekc1+HX5vUuextaaDBplzxmES6WnQO3 17 | 9geEksD/4pKuAJUNQUjUSYEabWuSIO3ix2irJEmX6UISGJOVKGnmOzrdgOzVZg30 18 | gqRr0JXm99ci93piQewqXVYWfeqWLSw8u6NL+wcCgYBweQmUciaGNN1nytOMK1aD 19 | BZ3WQTS7GhQFTCPVlnCfuq8uTcNecHvK7ZYkN6yyi530rFaPX7QOFowyVZoGyQFI 20 | Ay870KdTGF12qruu+PMS9GQSAftNuwv6tf9fdCwtML9fqkL/xFY0vUpao/3seP6o 21 | FKD2fej0ueBzPwBeQGm3iwKBgF6PKVUMaCEViW26Bdn/LMFTlV1RMWu8Zo7aBObL 22 | +gUitmAUUMbY2Koi9CEk/KPmclZ+bM/vbv34IBAGp3Esks26mV+PUCjGq2v+3NUV 23 | 2/McfsI5DDhBFEnVehJXPWDv+2zAKbeApLiz4u/f/ABRksagZN54D05b6mP97+ZN 24 | dgZ5AoGBAIBXSJ24JOo6Z8hiqQVEO9oI1ZQlwzc2TR1dKrjLBl2y7/AClSr3b2++ 25 | iNQOyycweCF8WPM+Pf9fRBjI6STtiboVAcCq/vP/eSGX5SJWRSTENFTiBprdcj2P 26 | p+exFe+9P1yAy5WxLnt7cTFsdgqG6HXq0MOEUIyNcLVWnmZnIncC 27 | -----END RSA PRIVATE KEY----- 28 | -----BEGIN CERTIFICATE----- 29 | MIIDIDCCAgigAwIBAgIJAL7WpFUUJ1eDMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV 30 | BAMTCWxvY2FsaG9zdDAeFw0xNjEwMjkxNDAzNDJaFw0yNjEwMjcxNDAzNDJaMBQx 31 | EjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 32 | ggEBAOW+YWdnccD9ENOTDFWRma7PnnHOWczgW75L5NQmew/+2l3snf71kVw+umUG 33 | 5MKfF1MXIQLywpsvOKQsHMXWo16E/2HY/NF/kj7h3ce2MaHUmPa5eSnzo+Z95+FD 34 | 8TiUVxVs5zhvmrXq6mG/lkU5nCX0vfnCbXws+UDZ2B4Xc3A3jwpT/He/KP+lTBgM 35 | ZdrLnKBfssfVwLNb0A+sGIjVoeTznZcVwK9Yrs7bp8vzFdHZZ7df9jULaVY9zr3j 36 | Daoui3nTt23ljLuTW97J51HSuvBMaIiVbWyWecxKJTK2Pc0vSd5U1ZKu8IWVAJtf 37 | GoW1F/IN435duVxFVI4ymzQd730CAwEAAaN1MHMwHQYDVR0OBBYEFKkaLYAmQMa/ 38 | 1mDLJBlOn+h116WbMEQGA1UdIwQ9MDuAFKkaLYAmQMa/1mDLJBlOn+h116WboRik 39 | FjAUMRIwEAYDVQQDEwlsb2NhbGhvc3SCCQC+1qRVFCdXgzAMBgNVHRMEBTADAQH/ 40 | MA0GCSqGSIb3DQEBCwUAA4IBAQCi2ywUN/y5fgH2PTVZjgKq6AUD/RqrdTISa2UO 41 | kxcSPlSGNlapjHD3iGpZ2FdyCVYoCIIRx9Eol9B2VW7gihbJrMdybbZk1v16AN1y 42 | sqgcHhXOeEh4Phi/suljZOaCWGoj1eZOvTXV7fZjeSq4lmdXEwFGuxXwVgvt8teM 43 | vJT6i3DtxcD7+V60Q691ky+QuZqDG1FKVmzXQ1CNt7Bq3075pled1KJz8ziIEdjc 44 | KeBDWN/NLbyZeBwlg9QxrbGazxGedMQdDzG5kyaaXwhCvAxfY2yHzkV/2iFE17AJ 45 | 0796jb2KsrT6JNtwkMye1Jc/ZwNat7InH5WkqFzUrCKqw08u 46 | -----END CERTIFICATE----- 47 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | // tslint:disable:ordered-imports 22 | // tslint:disable-next-line:jsdoc-format 23 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 24 | import 'core-js/es6/symbol'; 25 | import 'core-js/es6/object'; 26 | import 'core-js/es6/function'; 27 | import 'core-js/es6/parse-int'; 28 | import 'core-js/es6/parse-float'; 29 | import 'core-js/es6/number'; 30 | import 'core-js/es6/math'; 31 | import 'core-js/es6/string'; 32 | import 'core-js/es6/date'; 33 | import 'core-js/es6/array'; 34 | import 'core-js/es6/regexp'; 35 | import 'core-js/es6/map'; 36 | import 'core-js/es6/set'; 37 | 38 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 39 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 40 | 41 | /** IE10 and IE11 requires the following to support `@angular/animation`. */ 42 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 43 | 44 | // tslint:disable-next-line:jsdoc-format 45 | /** Evergreen browsers require these. **/ 46 | import 'core-js/es6/reflect'; 47 | import 'core-js/es7/reflect'; 48 | 49 | // tslint:disable-next-line:jsdoc-format 50 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/ 51 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 52 | 53 | /*************************************************************************************************** 54 | * Zone JS is required by Angular itself. 55 | */ 56 | import 'zone.js/dist/zone'; // Included with Angular CLI. 57 | 58 | /*************************************************************************************************** 59 | * APPLICATION IMPORTS 60 | */ 61 | // Server management tools specific polyfills 62 | import '@microsoft/windows-admin-center-sdk/dist/core/polyfills'; 63 | 64 | /** 65 | * Date, currency, decimal and percent pipes. 66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 67 | */ 68 | // import 'intl'; // Run `npm install --save intl`. 69 | /** 70 | * Need to import at least one locale-data with intl. 71 | */ 72 | // import 'intl/locale-data/jsonp/en'; -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Microsoft Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | 14 | * 15 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 16 | */ 17 | 18 | /*************************************************************************************************** 19 | * BROWSER POLYFILLS 20 | */ 21 | 22 | // tslint:disable:ordered-imports 23 | // tslint:disable-next-line:jsdoc-format 24 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 25 | import 'core-js/es6/symbol'; 26 | import 'core-js/es6/object'; 27 | import 'core-js/es6/function'; 28 | import 'core-js/es6/parse-int'; 29 | import 'core-js/es6/parse-float'; 30 | import 'core-js/es6/number'; 31 | import 'core-js/es6/math'; 32 | import 'core-js/es6/string'; 33 | import 'core-js/es6/date'; 34 | import 'core-js/es6/array'; 35 | import 'core-js/es6/regexp'; 36 | import 'core-js/es6/map'; 37 | import 'core-js/es6/set'; 38 | 39 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 40 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 41 | 42 | /** IE10 and IE11 requires the following to support `@angular/animation`. */ 43 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 44 | 45 | // tslint:disable-next-line:jsdoc-format 46 | /** Evergreen browsers require these. **/ 47 | import 'core-js/es6/reflect'; 48 | import 'core-js/es7/reflect'; 49 | 50 | // tslint:disable-next-line:jsdoc-format 51 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/ 52 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 53 | 54 | /*************************************************************************************************** 55 | * Zone JS is required by Angular itself. 56 | */ 57 | import 'zone.js/dist/zone'; // Included with Angular CLI. 58 | 59 | /*************************************************************************************************** 60 | * APPLICATION IMPORTS 61 | */ 62 | // Server management tools specific polyfills 63 | import '@microsoft/windows-admin-center-sdk/core/polyfills'; 64 | 65 | /** 66 | * Date, currency, decimal and percent pipes. 67 | * Needed for: All but Chrome, Firefox, Microsoft Edge, IE11 and Safari 10 68 | */ 69 | // import 'intl'; // Run `npm install --save intl`. 70 | /** 71 | * Need to import at least one locale-data with intl. 72 | */ 73 | // import 'intl/locale-data/jsonp/en'; 74 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "MIT", 3 | "main": "index.js", 4 | "name": "@{!company-name}/{!product-name}", 5 | "private": true, 6 | "version": "0.1.0", 7 | "peerDependencies": { 8 | "@microsoft/windows-admin-center-sdk": "latest", 9 | "@angular/animations": "7.1.1", 10 | "@angular/common": "7.1.1", 11 | "@angular/compiler": "7.1.1", 12 | "@angular/core": "7.1.1", 13 | "@angular/forms": "7.1.1", 14 | "@angular/language-service": "7.1.1", 15 | "@angular/platform-browser": "7.1.1", 16 | "@angular/platform-browser-dynamic": "7.1.1", 17 | "@angular/router": "7.1.1", 18 | "core-js": "2.6.0", 19 | "rxjs": "6.3.3", 20 | "zone.js": "0.8.26" 21 | }, 22 | "devDependencies": { 23 | "@angular-devkit/build-angular": "^0.12.1", 24 | "@angular-devkit/build-ng-packagr": "0.11.2", 25 | "@angular/animations": "7.1.1", 26 | "@angular/cli": "7.1.2", 27 | "@angular/common": "7.1.1", 28 | "@angular/compiler": "7.1.1", 29 | "@angular/compiler-cli": "7.1.1", 30 | "@angular/core": "7.1.1", 31 | "@angular/forms": "7.1.1", 32 | "@angular/language-service": "7.1.1", 33 | "@angular/platform-browser": "7.1.1", 34 | "@angular/platform-browser-dynamic": "7.1.1", 35 | "@angular/router": "7.1.1", 36 | "@microsoft/windows-admin-center-sdk": "latest", 37 | "@types/chart.js": "2.7.40", 38 | "@types/jasmine": "~2.8.8", 39 | "@types/jasminewd2": "~2.0.3", 40 | "@types/jquery": "3.3.22", 41 | "@types/karma": "3.0.1", 42 | "@types/node": "8.9.5", 43 | "@types/signalr": "2.2.35", 44 | "ajv": "6.4.0", 45 | "ansi-colors": "1.0.1", 46 | "app-root-path": "^2.2.1", 47 | "codelyzer": "4.5.0", 48 | "core-js": "2.6.0", 49 | "gulp": "^4.0.0", 50 | "gulp-clean": "0.4.0", 51 | "gulp-inline-ng2-template": "5.0.1", 52 | "gulp-jasmine": "2.4.2", 53 | "gulp-plumber": "1.1.0", 54 | "gulp-sourcemaps": "^2.6.4", 55 | "gulp-tslint": "8.1.3", 56 | "gulp-typescript": "4.0.2", 57 | "gulp-watch": "4.3.11", 58 | "jasmine-core": "~2.99.1", 59 | "jasmine-reporters": "2.3.1", 60 | "jasmine-spec-reporter": "~4.2.1", 61 | "jquery": "3.3.1", 62 | "jsdom": "9.10.0", 63 | "karma": "^3.1.4", 64 | "karma-chrome-launcher": "^2.2.0", 65 | "karma-coverage-istanbul-reporter": "2.0.1", 66 | "karma-jasmine": "~1.1.2", 67 | "karma-jasmine-html-reporter": "^0.2.2", 68 | "karma-typescript": "4.0.0", 69 | "ng-packagr": "4.4.0", 70 | "plugin-error": "1.0.1", 71 | "puppeteer": "1.12.2", 72 | "run-sequence": "2.2.0", 73 | "rxjs": "6.3.3", 74 | "rxjs-tslint": "^0.1.5", 75 | "rxjs-tslint-rules": "4.10.0", 76 | "selenium-webdriver": "3.6.0", 77 | "signalr": "2.3.0", 78 | "ts-helpers": "^1.1.1", 79 | "ts-node": "5.0.1", 80 | "tsickle": "0.33.1", 81 | "tslint": "5.11.0", 82 | "tslint-consistent-codestyle": "1.14.0", 83 | "tslint-eslint-rules": "5.4.0", 84 | "tslint-microsoft-contrib": "5.2.1", 85 | "typescript": "3.1.6", 86 | "zone.js": "0.8.26" 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "MIT", 3 | "main": "index.js", 4 | "name": "@{!company-name}/{!product-name}", 5 | "private": true, 6 | "version": "0.1.0", 7 | "peerDependencies": { 8 | "@microsoft/windows-admin-center-sdk": "legacy", 9 | "@angular/animations": "5.1.2", 10 | "@angular/common": "5.1.2", 11 | "@angular/compiler": "5.1.2", 12 | "@angular/core": "5.1.2", 13 | "@angular/forms": "5.1.2", 14 | "@angular/language-service": "5.1.2", 15 | "@angular/platform-browser": "5.1.2", 16 | "@angular/platform-browser-dynamic": "5.1.2", 17 | "@angular/router": "5.1.2", 18 | "chart.js": "2.4.0", 19 | "bootstrap": "3.3.7", 20 | "core-js": "2.5.3", 21 | "primeng": "4.1.0", 22 | "rxjs": "5.5.6", 23 | "winstrap": "0.5.11", 24 | "zone.js": "0.8.18" 25 | }, 26 | "devDependencies": { 27 | "@microsoft/windows-admin-center-sdk": "legacy", 28 | "@angular/animations": "5.1.2", 29 | "@angular/cli": "1.6.5", 30 | "@angular/common": "5.1.2", 31 | "@angular/compiler": "5.1.2", 32 | "@angular/compiler-cli": "5.1.2", 33 | "@angular/core": "5.1.2", 34 | "@angular/forms": "5.1.2", 35 | "@angular/language-service": "5.1.2", 36 | "@angular/platform-browser": "5.1.2", 37 | "@angular/platform-browser-dynamic": "5.1.2", 38 | "@angular/router": "5.1.2", 39 | "chart.js": "2.4.0", 40 | "bootstrap": "3.3.7", 41 | "core-js": "2.5.3", 42 | "primeng": "4.1.0", 43 | "rxjs": "5.5.6", 44 | "winstrap": "0.5.11", 45 | "zone.js": "0.8.18", 46 | "@types/chart.js": "0.0.8", 47 | "@types/jasmine": "2.5.54", 48 | "@types/jasminewd2": "2.0.3", 49 | "@types/jquery": "3.3.22", 50 | "@types/node": "^8.5.2", 51 | "@types/signalr": "2.2.35", 52 | "ansi-colors": "1.0.1", 53 | "babel-cli": "^6.26.0", 54 | "babel-preset-es2015": "^6.22.0", 55 | "codelyzer": "^4.0.2", 56 | "gulp": "3.9.1", 57 | "gulp-batch": "1.0.5", 58 | "gulp-clean": "0.3.2", 59 | "gulp-inline-ng2-template": "4.1.0", 60 | "gulp-jasmine": "2.4.2", 61 | "gulp-ngc": "0.3.0", 62 | "gulp-plumber": "1.1.0", 63 | "gulp-rename": "1.2.2", 64 | "gulp-sourcemaps": "^2.6.2", 65 | "gulp-tslint": "8.1.2", 66 | "gulp-typescript": "^3.2.3", 67 | "gulp-watch": "4.3.11", 68 | "jasmine-core": "2.6.4", 69 | "jasmine-node": "1.14.5", 70 | "jasmine-reporters": "2.2.1", 71 | "jasmine-spec-reporter": "4.1.1", 72 | "jasmine-terminal-reporter": "1.0.3", 73 | "jquery": "3.3.1", 74 | "jsdom": "9.10.0", 75 | "karma": "^1.7.1", 76 | "karma-chrome-launcher": "^2.1.1", 77 | "karma-cli": "^1.0.1", 78 | "karma-coverage-istanbul-reporter": "^1.2.1", 79 | "karma-jasmine": "^1.1.1", 80 | "karma-jasmine-html-reporter": "^0.2.2", 81 | "karma-remap-istanbul": "^0.2.1", 82 | "ping": "0.2.2", 83 | "protractor": "^5.1.2", 84 | "readline-sync": "^1.4.9", 85 | "run-sequence": "2.2.0", 86 | "selenium-webdriver": "3.6.0", 87 | "signalr": "^2.2.2", 88 | "ts-helpers": "^1.1.1", 89 | "ts-node": "^4.1.0", 90 | "tslint": "^5.7.0", 91 | "tslint-eslint-rules": "4.1.1", 92 | "tslint-microsoft-contrib": "5.0.1", 93 | "typescript": "2.5.3" 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer", 4 | "node_modules/rxjs-tslint", 5 | "node_modules/tslint-eslint-rules/dist/rules", 6 | "node_modules/tslint-microsoft-contrib", 7 | "node_modules/tslint-consistent-codestyle/rules" 8 | ], 9 | "rules": { 10 | "rxjs-collapse-imports": true, 11 | "rxjs-proper-imports": true, 12 | 13 | "arrow-return-shorthand": true, 14 | "callable-types": true, 15 | "class-name": true, 16 | "comment-format": [ 17 | true, 18 | "check-space" 19 | ], 20 | "curly": true, 21 | "eofline": true, 22 | "forin": true, 23 | "import-blacklist": [ 24 | true, 25 | "rxjs/Rx" 26 | ], 27 | "import-spacing": true, 28 | "ordered-imports": true, 29 | "indent": [ 30 | true, 31 | "spaces" 32 | ], 33 | "interface-over-type-literal": true, 34 | "label-position": true, 35 | "max-line-length": [ 36 | true, 37 | 140 38 | ], 39 | "member-access": false, 40 | "member-ordering": [ 41 | true, 42 | { 43 | "order": [ 44 | "static-field", 45 | "instance-field", 46 | "static-method", 47 | "instance-method" 48 | ] 49 | } 50 | ], 51 | "no-arg": true, 52 | "no-bitwise": true, 53 | "no-console": [ 54 | true, 55 | "debug", 56 | "info", 57 | "time", 58 | "timeEnd", 59 | "trace" 60 | ], 61 | "no-construct": true, 62 | "no-debugger": true, 63 | "no-duplicate-super": true, 64 | "no-empty": false, 65 | "no-empty-interface": true, 66 | "no-eval": true, 67 | "no-inferrable-types": [ 68 | true, 69 | "ignore-params" 70 | ], 71 | "no-misused-new": true, 72 | "no-non-null-assertion": true, 73 | "no-redundant-jsdoc": true, 74 | "no-shadowed-variable": true, 75 | "no-string-literal": false, 76 | "no-string-throw": true, 77 | "no-switch-case-fall-through": true, 78 | "no-trailing-whitespace": true, 79 | "no-unnecessary-initializer": true, 80 | "no-unused-expression": true, 81 | "no-var-keyword": true, 82 | "object-literal-sort-keys": false, 83 | "one-line": [ 84 | true, 85 | "check-open-brace", 86 | "check-catch", 87 | "check-else", 88 | "check-whitespace" 89 | ], 90 | "prefer-const": true, 91 | "quotemark": [ 92 | true, 93 | "single" 94 | ], 95 | "radix": true, 96 | "semicolon": [ 97 | true, 98 | "always" 99 | ], 100 | "triple-equals": [ 101 | true, 102 | "allow-null-check" 103 | ], 104 | "typedef": true, 105 | "typedef-whitespace": [ 106 | true, 107 | { 108 | "call-signature": "nospace", 109 | "index-signature": "nospace", 110 | "parameter": "nospace", 111 | "property-declaration": "nospace", 112 | "variable-declaration": "nospace" 113 | } 114 | ], 115 | "unified-signatures": false, 116 | "variable-name": false, 117 | "whitespace": [ 118 | true, 119 | "check-branch", 120 | "check-decl", 121 | "check-operator", 122 | "check-separator", 123 | "check-type" 124 | ], 125 | "no-output-on-prefix": true, 126 | "use-input-property-decorator": true, 127 | "use-output-property-decorator": true, 128 | "use-host-property-decorator": true, 129 | "no-input-rename": true, 130 | "no-output-rename": true, 131 | "use-life-cycle-interface": true, 132 | "use-pipe-transform-interface": true, 133 | 134 | "interface-name": [ 135 | true, 136 | "never-prefix" 137 | ], 138 | "component-class-suffix": true, 139 | "directive-class-suffix": true, 140 | "naming-convention": [ 141 | true, 142 | { 143 | "type": "enumMember", 144 | "format": "PascalCase" 145 | } 146 | ] 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-resjson/index.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | exports.__esModule = true; 4 | var through2 = require("through2"); 5 | var gutil = require("gulp-util"); 6 | var Path = require("path"); 7 | var Resjson = require("./resjson-convert"); 8 | var Vinyl = require("vinyl"); 9 | var PluginError = gutil.PluginError; 10 | var PLUGIN_NAME = 'gulp-resjson'; 11 | function gulpResjson(options) { 12 | // 13 | // (Options): 14 | // 15 | // enable to produce xxxx.d.ts file. 16 | // definition: string; { null, 'module' } 17 | // 18 | // enable to produce xxxx.ts file. 19 | // typescript: string; { null, 'module', 'interface' } 20 | // 21 | // enable to produce xxxx.json file. 22 | // json: boolean; 23 | // 24 | // if set a space charactors, it adds formating of JSON. 25 | // it set null, space will be eliminated. 26 | // jsonSpace: string | number; 27 | // 28 | // override options settings if not specified. 29 | options = Object.assign({ definition: null, typescript: null, json: false, jsonSpace: null }, options || {}); 30 | function extendError(pError, error) { 31 | if (error && (typeof error === 'object')) { 32 | ['name', 'errno'].forEach(function (property) { 33 | if (property in error) { 34 | this[property] = error[property]; 35 | } 36 | }, pError); 37 | } 38 | return pError; 39 | } 40 | return through2.obj( 41 | /** 42 | * @this {Transform} 43 | */ 44 | function (file, encoding, callback) { 45 | var error = null; 46 | try { 47 | if (file.isNull()) { 48 | // nothing to do 49 | return callback(null, file); 50 | } 51 | if (file.isStream()) { 52 | // file.contents is a Stream - https://nodejs.org/api/stream.html 53 | this.emit('error', new PluginError(PLUGIN_NAME, 'Streams not supported!')); 54 | return callback(null, file); 55 | } 56 | else if (file.isBuffer()) { 57 | var data = file.contents.toString('utf8'); 58 | var converter = new Resjson.ResJsonConverter(options); 59 | converter.convert(data); 60 | var path = Path.parse(file.path); 61 | if (options.definition) { 62 | var dtFile = new Vinyl({ 63 | cwd: '/', 64 | base: path.dir, 65 | path: path.dir + '/' + path.name + '.d.ts', 66 | contents: new Buffer(converter.contentDefinition) 67 | }); 68 | this.push(dtFile); 69 | } 70 | if (options.typescript) { 71 | var content = options.typescript === 'interface' ? converter.contentInterface : converter.contentTypescript; 72 | var tsFile = new Vinyl({ 73 | cwd: '/', 74 | base: path.dir, 75 | path: path.dir + '/' + path.name + '.ts', 76 | contents: new Buffer(content) 77 | }); 78 | this.push(tsFile); 79 | } 80 | if (options.json) { 81 | var base = options.srcRoot || path.dir; 82 | var content = JSON.stringify(converter.outputJson, null, options.jsonSpace); 83 | var jsonFile = new Vinyl({ 84 | cwd: '/', 85 | base: base, 86 | path: path.dir + '\\' + path.name + '.json', 87 | contents: new Buffer(content) 88 | }); 89 | this.push(jsonFile); 90 | } 91 | } 92 | } 93 | catch (e) { 94 | error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 95 | } 96 | callback(error); 97 | }); 98 | } 99 | ; 100 | module.exports = gulpResjson; 101 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-resjson/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 'use strict'; 3 | import through2 = require('through2'); 4 | import gutil = require('gulp-util'); 5 | import Path = require('path'); 6 | import Resjson = require('./resjson-convert'); 7 | import Vinyl = require('vinyl'); 8 | 9 | let PluginError = gutil.PluginError; 10 | let PLUGIN_NAME = 'gulp-resjson'; 11 | 12 | function gulpResjson(options) { 13 | // 14 | // (Options): 15 | // 16 | // enable to produce xxxx.d.ts file. 17 | // definition: string; { null, 'module' } 18 | // 19 | // enable to produce xxxx.ts file. 20 | // typescript: string; { null, 'module', 'interface' } 21 | // 22 | // enable to produce xxxx.json file. 23 | // json: boolean; 24 | // 25 | // if set a space charactors, it adds formating of JSON. 26 | // it set null, space will be eliminated. 27 | // jsonSpace: string | number; 28 | // 29 | 30 | // override options settings if not specified. 31 | options = Object.assign({ definition: null, typescript: null, json: false, jsonSpace: null }, options || {}); 32 | 33 | function extendError(pError, error) { 34 | if (error && (typeof error === 'object')) { 35 | ['name', 'errno'].forEach(function (property) { 36 | if (property in error) { 37 | this[property] = error[property]; 38 | } 39 | }, pError); 40 | } 41 | 42 | return pError; 43 | } 44 | 45 | return through2.obj( 46 | /** 47 | * @this {Transform} 48 | */ 49 | function (file, encoding, callback) { 50 | let error = null; 51 | try { 52 | if (file.isNull()) { 53 | // nothing to do 54 | return callback(null, file); 55 | } 56 | 57 | if (file.isStream()) { 58 | // file.contents is a Stream - https://nodejs.org/api/stream.html 59 | this.emit('error', new PluginError(PLUGIN_NAME, 'Streams not supported!')); 60 | return callback(null, file); 61 | } else if (file.isBuffer()) { 62 | let data = file.contents.toString('utf8'); 63 | let converter = new Resjson.ResJsonConverter(options); 64 | converter.convert(data); 65 | 66 | let path = Path.parse(file.path); 67 | if (options.definition) { 68 | let dtFile = new Vinyl({ 69 | cwd: '/', 70 | base: path.dir, 71 | path: path.dir + '/' + path.name + '.d.ts', 72 | contents: new Buffer(converter.contentDefinition) 73 | }); 74 | this.push(dtFile); 75 | } 76 | 77 | if (options.typescript) { 78 | let content = options.typescript === 'interface' ? converter.contentInterface : converter.contentTypescript; 79 | let tsFile = new Vinyl({ 80 | cwd: '/', 81 | base: path.dir, 82 | path: path.dir + '/' + path.name + '.ts', 83 | contents: new Buffer(content) 84 | }); 85 | this.push(tsFile); 86 | } 87 | 88 | if (options.json) { 89 | let base = options.srcRoot || path.dir; 90 | let content = JSON.stringify(converter.outputJson, null, options.jsonSpace); 91 | let jsonFile = new Vinyl({ 92 | cwd: '/', 93 | base: base, 94 | path: path.dir + '\\' + path.name + '.json', 95 | contents: new Buffer(content) 96 | }); 97 | this.push(jsonFile); 98 | } 99 | } 100 | } catch (e) { 101 | error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? extendError(new PluginError(PLUGIN_NAME, e.message), e) : e; 102 | } 103 | 104 | callback(error); 105 | }); 106 | }; 107 | 108 | module.exports = gulpResjson 109 | -------------------------------------------------------------------------------- /templates/windows-admin-center-extension-template/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "module-app": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "bundle", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "src/tsconfig.app.json", 21 | "assets": [ 22 | "src/assets", 23 | "src/manifest.json" 24 | ], 25 | "styles": [ 26 | "node_modules/@microsoft/windows-admin-center-sdk/styles/css/main.css" 27 | ], 28 | "scripts": [ 29 | "node_modules/jquery/dist/jquery.min.js" 30 | ] 31 | }, 32 | "configurations": { 33 | "production": { 34 | "fileReplacements": [ 35 | { 36 | "replace": "src/environments/environment.ts", 37 | "with": "src/environments/environment.prod.ts" 38 | } 39 | ], 40 | "optimization": true, 41 | "outputHashing": "all", 42 | "sourceMap": false, 43 | "extractCss": true, 44 | "namedChunks": true, 45 | "aot": true, 46 | "extractLicenses": false, 47 | "vendorChunk": false, 48 | "buildOptimizer": true, 49 | "budgets": [ 50 | { 51 | "type": "initial", 52 | "maximumWarning": "2mb", 53 | "maximumError": "5mb" 54 | } 55 | ] 56 | } 57 | } 58 | }, 59 | "serve": { 60 | "builder": "@angular-devkit/build-angular:dev-server", 61 | "options": { 62 | "browserTarget": "module-app:build" 63 | }, 64 | "configurations": { 65 | "production": { 66 | "browserTarget": "module-app:build:production" 67 | } 68 | } 69 | }, 70 | "extract-i18n": { 71 | "builder": "@angular-devkit/build-angular:extract-i18n", 72 | "options": { 73 | "browserTarget": "module-app:build" 74 | } 75 | }, 76 | "test": { 77 | "builder": "@angular-devkit/build-angular:karma", 78 | "options": { 79 | "codeCoverage": true, 80 | "main": "src/test.ts", 81 | "polyfills": "src/polyfills.ts", 82 | "tsConfig": "src/tsconfig.spec.json", 83 | "karmaConfig": "src/karma.conf.js", 84 | "styles": [ 85 | "node_modules/@microsoft/windows-admin-center-sdk/styles/css/main.css" 86 | ], 87 | "scripts": [], 88 | "assets": [ 89 | "src/assets", 90 | "src/manifests.json" 91 | ] 92 | }, 93 | "configurations": { 94 | "production": { 95 | "fileReplacements": [ 96 | { 97 | "replace": "src/environments/environment.ts", 98 | "with": "src/environments/environment.prod.ts" 99 | } 100 | ], 101 | "sourceMap": false 102 | }, 103 | "debug": { 104 | "sourceMap": true, 105 | "browsers": "Chrome", 106 | "watch": true 107 | } 108 | } 109 | }, 110 | "lint": { 111 | "builder": "@angular-devkit/build-angular:tslint", 112 | "options": { 113 | "tsConfig": [ 114 | "src/tsconfig.app.json", 115 | "src/tsconfig.spec.json" 116 | ], 117 | "exclude": [ 118 | "**/node_modules/**" 119 | ] 120 | } 121 | } 122 | } 123 | } 124 | }, 125 | "defaultProject": "module-app" 126 | } 127 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "__COMMENT_NOTICE__": "Normally, this file supports comments. However if comments are present the whole file may be overridden by msft-sme-build.", 3 | "__MERGE_NOTICE__": "THIS FILE WAS MERGED FROM msft-sme-build. some properties in this file may be overridden if changed.", 4 | "rules": { 5 | "align": [ 6 | true, 7 | "statements", 8 | "arguments" 9 | ], 10 | "brace-style": [ 11 | true, 12 | "1tbs", 13 | { 14 | "allowSingleLine": true 15 | } 16 | ], 17 | "class-name": true, 18 | "comment-format": [ 19 | true, 20 | "check-space" 21 | ], 22 | "eofline": false, 23 | "forin": true, 24 | "function-name": [ 25 | true, 26 | { 27 | "static-method-regex": "^[a-z][\\w\\d]+$" 28 | } 29 | ], 30 | "import-destructuring-spacing": true, 31 | "indent": [ 32 | true, 33 | "spaces" 34 | ], 35 | "interface-name": [ 36 | true, 37 | "never-prefix" 38 | ], 39 | "jsdoc-format": true, 40 | "label-position": true, 41 | "max-line-length": [ 42 | true, 43 | 140 44 | ], 45 | "member-access": true, 46 | "member-ordering": [ 47 | true, 48 | "static-before-instance", 49 | "variables-before-functions" 50 | ], 51 | "new-parens": true, 52 | "no-access-missing-member": false, 53 | "no-arg": true, 54 | "no-attribute-parameter-decorator": true, 55 | "no-bitwise": true, 56 | "no-consecutive-blank-lines": [ 57 | true, 58 | 1 59 | ], 60 | "no-console": [ 61 | true, 62 | "debug", 63 | "info", 64 | "time", 65 | "timeEnd", 66 | "trace" 67 | ], 68 | "no-construct": true, 69 | "no-debugger": true, 70 | "no-duplicate-variable": true, 71 | "no-empty": true, 72 | "no-eval": true, 73 | "no-forward-ref": true, 74 | "no-inferrable-types": [ 75 | true, 76 | "ignore-params" 77 | ], 78 | "no-input-rename": true, 79 | "no-invalid-this": [ 80 | true, 81 | "check-function-in-method" 82 | ], 83 | "no-output-rename": true, 84 | "no-parameter-properties": false, 85 | "no-reference": true, 86 | "no-shadowed-variable": true, 87 | "no-string-literal": false, 88 | "no-switch-case-fall-through": true, 89 | "no-trailing-whitespace": false, 90 | "no-unused-expression": true, 91 | "no-use-before-declare": [ "errors" ], 92 | "no-var-keyword": true, 93 | "object-literal-key-quotes": [ 94 | true, 95 | "as-needed" 96 | ], 97 | "object-literal-sort-keys": false, 98 | "one-line": [ 99 | true, 100 | "check-catch", 101 | "check-finally", 102 | "check-else", 103 | "check-whitespace" 104 | ], 105 | "one-variable-per-declaration": [ 106 | true, 107 | "ignore-for-loop" 108 | ], 109 | "ordered-imports": [ 110 | true, 111 | { 112 | "import-sources-order": "case-insensitive", 113 | "named-imports-order": "case-insensitive" 114 | } 115 | ], 116 | "quotemark": [ 117 | true, 118 | "single", 119 | "avoid-escape" 120 | ], 121 | "radix": true, 122 | "semicolon": [ 123 | "always" 124 | ], 125 | "trailing-comma": [ 126 | true, 127 | { 128 | "multiline": "never", 129 | "singleline": "never" 130 | } 131 | ], 132 | "triple-equals": [ 133 | true, 134 | "allow-null-check" 135 | ], 136 | "typedef-whitespace": [ 137 | true, 138 | { 139 | "call-signature": "nospace", 140 | "index-signature": "nospace", 141 | "parameter": "nospace", 142 | "property-declaration": "nospace", 143 | "variable-declaration": "nospace" 144 | } 145 | ], 146 | "use-host-property-decorator": true, 147 | "use-input-property-decorator": true, 148 | "use-life-cycle-interface": true, 149 | "use-output-property-decorator": true, 150 | "use-pipe-transform-interface": true, 151 | "variable-name": [ 152 | true, 153 | "check-format", 154 | "ban-keywords" 155 | ], 156 | "whitespace": [ 157 | true, 158 | "check-branch", 159 | "check-decl", 160 | "check-operator", 161 | "check-separator", 162 | "check-type" 163 | ] 164 | }, 165 | "rulesDirectory": [ 166 | "node_modules/codelyzer", 167 | "node_modules/tslint-eslint-rules/dist/rules", 168 | "node_modules/tslint-microsoft-contrib" 169 | ] 170 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-ps-code/ps-code-convert.ts: -------------------------------------------------------------------------------- 1 | declare function escape(data: string): string; 2 | declare function unescape(data: string): string; 3 | 4 | export interface Options { 5 | noComments: boolean; 6 | name: string; 7 | } 8 | 9 | export class PsCodeConverter { 10 | private static removeCommentsTrue = '##RemoveComments=true##'; 11 | private static removeCommentsFalse = '##RemoveComments=false##'; 12 | private static commentStart = '<#'; 13 | private static commentEnd = '#>'; 14 | private static comment = '#'; 15 | private static openContent = 16 | `/* tslint:disable */ 17 | /** 18 | * @file Source code generated by gulp-ps-code. 19 | * @version 1.0 20 | */ 21 | export module PowerShellScripts { 22 | 'use strict' 23 | `; 24 | private static closeContent = 25 | `} 26 | `; 27 | private buffer: string[]; 28 | 29 | constructor(private options?: Options) { 30 | this.options = options ? options : { noComments: true, name: 'powershell-scripts.ts' }; 31 | if (!this.options.hasOwnProperty('noComments')) { 32 | this.options.noComments = true; 33 | } 34 | } 35 | 36 | public get content(): string { 37 | return this.buffer.join(''); 38 | } 39 | 40 | public contentReset(): void { 41 | this.buffer = []; 42 | } 43 | 44 | public generate(collection: { [index: string]: string }): void { 45 | let tsBase = null; 46 | this.buffer.push(PsCodeConverter.openContent); 47 | this.addData(collection); 48 | this.buffer.push(PsCodeConverter.closeContent); 49 | } 50 | 51 | private jsonName (original: string): string { 52 | // let name = original[0].toLowerCase() + original.substr(1); 53 | let name = original; 54 | name = this.replaceAll(name, '-', '_'); 55 | name = name.substr(0, name.length - 4); 56 | return name; 57 | } 58 | 59 | private regexEscape(str: string): string { 60 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 61 | } 62 | 63 | private replaceAll(input: string, searchValue: string, replaceValue: string): string { 64 | return input.replace(new RegExp(this.regexEscape(searchValue), 'g'), replaceValue); 65 | } 66 | 67 | private addToContent(name: string, script: string, indent: number): void { 68 | this.buffer.push(this.indent(indent) + 'export const ' + name + ': string = ' + script + ';\n'); 69 | } 70 | 71 | private addData(current: { [index: string]: string }): void { 72 | let keys = Object.keys(current); 73 | for (let key of keys) { 74 | let script = ''; 75 | let content: string = current[key]; 76 | let name = this.jsonName(key); 77 | script = '##' + name + '##:' + key + '\n'; 78 | let removeComments = this.options.noComments; 79 | if (content.indexOf(PsCodeConverter.removeCommentsFalse) > 0) { 80 | removeComments = false; 81 | } else if (content.indexOf(PsCodeConverter.removeCommentsTrue) > 0) { 82 | removeComments = true; 83 | } 84 | 85 | let skipping = false; 86 | let lines = content.split('\r'); 87 | lines.forEach((value, index, array) => { 88 | let text = value.replace('\n', ''); 89 | if (removeComments) { 90 | let process = true; 91 | text = text.trim(); 92 | if (text.startsWith(PsCodeConverter.commentStart)) { 93 | skipping = true; 94 | } 95 | 96 | if (skipping) { 97 | process = false; 98 | if (text.endsWith(PsCodeConverter.commentEnd)) { 99 | skipping = false; 100 | } 101 | } 102 | 103 | if (process && !text.startsWith(PsCodeConverter.comment) && text.length > 0) { 104 | script += text + '\n'; 105 | } 106 | } else { 107 | script += text + '\n'; 108 | } 109 | 110 | }); 111 | let data = JSON.stringify(script); 112 | data = this.replaceAll(data, '\'', '\\u0027'); 113 | data = this.replaceAll(data, '<', '\\u003c'); 114 | data = this.replaceAll(data, '>', '\\u003e'); 115 | data = this.replaceAll(data, '&', '\\u0026'); 116 | this.addToContent(name, data, 1); 117 | } 118 | } 119 | 120 | private indent(count: number): string { 121 | let pad = ''; 122 | for (let i = 0; i < count; i++) { 123 | pad += ' '; 124 | } 125 | 126 | return pad; 127 | } 128 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-ps-code/ps-code-convert.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.__esModule = true; 3 | var PsCodeConverter = (function () { 4 | function PsCodeConverter(options) { 5 | this.options = options; 6 | this.options = options ? options : { noComments: true, name: 'powershell-scripts.ts' }; 7 | if (!this.options.hasOwnProperty('noComments')) { 8 | this.options.noComments = true; 9 | } 10 | } 11 | Object.defineProperty(PsCodeConverter.prototype, "content", { 12 | get: function () { 13 | return this.buffer.join(''); 14 | }, 15 | enumerable: true, 16 | configurable: true 17 | }); 18 | PsCodeConverter.prototype.contentReset = function () { 19 | this.buffer = []; 20 | }; 21 | PsCodeConverter.prototype.generate = function (collection) { 22 | var tsBase = null; 23 | this.buffer.push(PsCodeConverter.openContent); 24 | this.addData(collection); 25 | this.buffer.push(PsCodeConverter.closeContent); 26 | }; 27 | PsCodeConverter.prototype.jsonName = function (original) { 28 | // let name = original[0].toLowerCase() + original.substr(1); 29 | var name = original; 30 | name = this.replaceAll(name, '-', '_'); 31 | name = name.substr(0, name.length - 4); 32 | return name; 33 | }; 34 | PsCodeConverter.prototype.regexEscape = function (str) { 35 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 36 | }; 37 | PsCodeConverter.prototype.replaceAll = function (input, searchValue, replaceValue) { 38 | return input.replace(new RegExp(this.regexEscape(searchValue), 'g'), replaceValue); 39 | }; 40 | PsCodeConverter.prototype.addToContent = function (name, script, indent) { 41 | this.buffer.push(this.indent(indent) + 'export const ' + name + ': string = ' + script + ';\n'); 42 | }; 43 | PsCodeConverter.prototype.addData = function (current) { 44 | var keys = Object.keys(current); 45 | var _loop_1 = function (key) { 46 | var script = ''; 47 | var content = current[key]; 48 | var name_1 = this_1.jsonName(key); 49 | script = '##' + name_1 + '##:' + key + '\n'; 50 | var removeComments = this_1.options.noComments; 51 | if (content.indexOf(PsCodeConverter.removeCommentsFalse) > 0) { 52 | removeComments = false; 53 | } 54 | else if (content.indexOf(PsCodeConverter.removeCommentsTrue) > 0) { 55 | removeComments = true; 56 | } 57 | var skipping = false; 58 | var lines = content.split('\r'); 59 | lines.forEach(function (value, index, array) { 60 | var text = value.replace('\n', ''); 61 | if (removeComments) { 62 | var process_1 = true; 63 | text = text.trim(); 64 | if (text.startsWith(PsCodeConverter.commentStart)) { 65 | skipping = true; 66 | } 67 | if (skipping) { 68 | process_1 = false; 69 | if (text.endsWith(PsCodeConverter.commentEnd)) { 70 | skipping = false; 71 | } 72 | } 73 | if (process_1 && !text.startsWith(PsCodeConverter.comment) && text.length > 0) { 74 | script += text + '\n'; 75 | } 76 | } 77 | else { 78 | script += text + '\n'; 79 | } 80 | }); 81 | var data = JSON.stringify(script); 82 | data = this_1.replaceAll(data, '\'', '\\u0027'); 83 | data = this_1.replaceAll(data, '<', '\\u003c'); 84 | data = this_1.replaceAll(data, '>', '\\u003e'); 85 | data = this_1.replaceAll(data, '&', '\\u0026'); 86 | this_1.addToContent(name_1, data, 1); 87 | }; 88 | var this_1 = this; 89 | for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 90 | var key = keys_1[_i]; 91 | _loop_1(key); 92 | } 93 | }; 94 | PsCodeConverter.prototype.indent = function (count) { 95 | var pad = ''; 96 | for (var i = 0; i < count; i++) { 97 | pad += ' '; 98 | } 99 | return pad; 100 | }; 101 | return PsCodeConverter; 102 | }()); 103 | PsCodeConverter.removeCommentsTrue = '##RemoveComments=true##'; 104 | PsCodeConverter.removeCommentsFalse = '##RemoveComments=false##'; 105 | PsCodeConverter.commentStart = '<#'; 106 | PsCodeConverter.commentEnd = '#>'; 107 | PsCodeConverter.comment = '#'; 108 | PsCodeConverter.openContent = "/* tslint:disable */\n/**\n * @file Source code generated by gulp-ps-code.\n * @version 1.0\n */\nexport module PowerShellScripts {\n 'use strict'\n"; 109 | PsCodeConverter.closeContent = "}\n"; 110 | exports.PsCodeConverter = PsCodeConverter; 111 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulpfile.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const gulp = require('gulp'); 4 | const gutil = require('gulp-util'); 5 | const clean = require('gulp-clean'); 6 | const ngCompile = require('gulp-ngc'); 7 | const gulpTslint = require('gulp-tslint'); 8 | const tslint = require('tslint'); 9 | const argv = require('yargs').argv; 10 | const runSequence = require('run-sequence'); 11 | const inlineNg2Template = require('gulp-inline-ng2-template'); 12 | const child_process = require('child_process'); 13 | const gulpPsCode = require('./gulps/gulp-ps-code'); 14 | const gulpResJson = require('./gulps/gulp-resjson'); 15 | const gulpSvgCode = require('./gulps/gulp-svg-code'); 16 | const gulpMergeJsonInFolders = require('./gulps/gulp-merge-json-in-folders'); 17 | const gulpLicense = require('./tools/gulp-license'); 18 | 19 | gulp.task('license', () => { 20 | return gulp.src('src/**/*.*') 21 | .pipe(gulpLicense((fileType) => { 22 | switch (fileType) { 23 | case '.ts': { 24 | return '// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\n\r'; 25 | } 26 | case '.html': { 27 | return '\n\r'; 28 | } 29 | default: { 30 | return; 31 | } 32 | } 33 | })) 34 | .pipe(gulp.dest('./src')); 35 | }); 36 | 37 | gulp.task('clean', () => { 38 | return gulp.src(['dist', 'bundle', 'src/generated', 'src/assets/strings', 'inlineSrc'], { read: false }) 39 | .pipe(clean({ force: true })); 40 | }); 41 | 42 | gulp.task('generate-powershell', () => { 43 | return gulp.src(['src/resources/scripts/**/*.ps1']) 44 | .pipe(gulpPsCode({ name: 'powershell-scripts.ts', removeComments: true })) 45 | .pipe(gulp.dest('src/generated')); 46 | }); 47 | 48 | gulp.task('generate-svg', () => { 49 | return gulp.src(['src/resources/icons/**/*.svg']) 50 | .pipe(gulpSvgCode()) 51 | .pipe(gulp.dest('src/generated')); 52 | }); 53 | 54 | gulp.task('generate-resjson-json', () => { 55 | return gulp.src(['src/resources/strings/**/*.resjson']) 56 | .pipe(gulpResJson({ json: true })) 57 | .pipe(gulp.dest('./src/assets/strings')); 58 | }); 59 | 60 | gulp.task('generate-resjson-interface', () => { 61 | return gulp.src(['src/resources/strings/**/*.resjson']) 62 | .pipe(gulpResJson({ typescript: 'interface' })) 63 | .pipe(gulp.dest('src/generated')); 64 | }); 65 | 66 | gulp.task('merge-localized-json', () => { 67 | return gulp.src(['./node_modules/@microsoft/windows-admin-center-sdk/dist/assets/strings', './node_modules/@msft-sme/**/dist/assets/strings']) 68 | .pipe(gulpMergeJsonInFolders({ src: './src/assets/strings' })) 69 | .pipe(gulp.dest('src/assets/strings')); 70 | }); 71 | 72 | gulp.task('generate-resjson', (cb) => { 73 | runSequence(['generate-resjson-json', 'generate-resjson-interface'], 'merge-localized-json', cb); 74 | }); 75 | 76 | gulp.task('generate', (cb) => { 77 | runSequence(['generate-powershell', 'generate-svg', 'generate-resjson'], cb); 78 | }); 79 | 80 | gulp.task('lint', () => { 81 | var program = tslint.Linter.createProgram("./tsconfig.json"); 82 | return gulp.src('src/**/*.ts') 83 |   .pipe(gulpTslint({ program })) 84 | .pipe(gulpTslint.report({ 85 | "emitError": true, 86 | "reportLimit": 0, 87 | "summarizeFailureOutput": true 88 | })); 89 | }); 90 | 91 | gulp.task('inline', function() { 92 | return gulp.src('./src/**/*.ts') 93 | .pipe(inlineNg2Template({ useRelativePaths: true })) 94 | .pipe(gulp.dest('inlineSrc')); 95 | }); 96 | 97 | gulp.task('copy', () => { 98 | return gulp.src(['src/**/*.json', 'src/**/*.d.ts', 'src/assets/**/*.*'], { base: 'src' }) 99 | .pipe(gulp.dest('dist')); 100 | }); 101 | 102 | gulp.task('compile', () => { 103 | return ngCompile('./tsconfig-inline.json'); 104 | }); 105 | 106 | gulp.task('bundle', cb => { 107 | var args = process.argv.slice(3); 108 | args.splice(0, 0, 'build', '-progress=false'); 109 | var cmd = child_process.spawn('ng.cmd', args); 110 | cmd.stdout.on('data', function (data) { gutil.log(data.toString()); }); 111 | cmd.stderr.on('data', function (data) { gutil.log(data.toString()); }); 112 | cmd.on('exit', function (code) { cb(); }); 113 | }); 114 | 115 | gulp.task('serve', (cb) => { 116 | var args = process.argv.slice(3); 117 | args.splice(0, 0, 'serve', '-progress=false'); 118 | var cmd = child_process.spawn('ng.cmd', args); 119 | cmd.stdout.on('data', function (data) { gutil.log(data.toString()); }); 120 | cmd.stderr.on('data', function (data) { gutil.log(data.toString()); }); 121 | cmd.on('exit', function (code) { cb(); }); 122 | }); 123 | 124 | gulp.task('build', (cb) => { 125 | runSequence('clean', 'generate', 'lint', 'inline', ['compile', 'copy'], 'bundle', cb); 126 | }); 127 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-merge-json-in-folders/json-merge.ts: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const fsPath = require('path'); 3 | const readlineSync = require('readline-sync'); 4 | const gutil = require('gulp-util'); 5 | const Vinyl = require('vinyl'); 6 | 7 | export interface Options { 8 | // source folder 9 | src: string; 10 | } 11 | 12 | export class JsonMerge { 13 | /** 14 | * Recursively merges JSON files with the same name and same subPath from the sourceFolders into the JSON files 15 | * in the targetFolderPath. 16 | * 17 | * @example 18 | * src/assets/resources/strings/ <- targetFolderPath 19 | * strings.json 20 | * es/strings.json 21 | * pt/strings.json 22 | * [ 23 | * 'node_modules/@msft-sme/core/dist/assets/resources/strings', 24 | * 'node_modules/@msft-sme/ng2/dist/assets/resources/strings' 25 | * ] <- sourceFoldersPath 26 | * 27 | * src/assets/resources/strings/strings.json contents are merged with the contents of 28 | * node_modules/@msft-sme/core/dist/assets/resources/strings/strings.json and 29 | * node_modules/@msft-ng2/core/dist/assets/resources/strings/strings.json 30 | * and the source file is overwritten by the merged content 31 | * 32 | * @param targetFolderPathRoot {string} The path of the base folder where the destination files are placed. 33 | * @param sourceFoldersPathRoot {string[]} The array of paths to the source folders from where to read the JSON files to merge 34 | */ 35 | public mergeJsonInFolders(targetFolderPathRoot: string, sourceFoldersPathRoot: string[]): any[] { 36 | const outputFiles: any[] = []; 37 | const targetFilesContentMap = {}; 38 | let targetFiles = this.getFilePaths(targetFolderPathRoot); 39 | targetFiles.forEach((targetFile) => { 40 | let relativePath = targetFile.substring(targetFolderPathRoot.length + 1, targetFile.length); 41 | targetFilesContentMap[relativePath] = this.readJSON(targetFile); 42 | 43 | }); 44 | 45 | sourceFoldersPathRoot.forEach((sourceFolderPathRoot) => { 46 | let sourceFiles = this.getFilePaths(sourceFolderPathRoot); 47 | sourceFiles.forEach((sourceFile) => { 48 | let relativePath = sourceFile.substring(sourceFolderPathRoot.length + 1, sourceFile.length); 49 | let sourceJson = this.readJSON(sourceFile); 50 | 51 | this.mergeJsons(relativePath, sourceJson, targetFilesContentMap); 52 | }); 53 | }); 54 | 55 | Object.keys(targetFilesContentMap).forEach(path => { 56 | let jsonFile = new Vinyl({ 57 | cwd: './', 58 | path: path, 59 | contents: new Buffer(JSON.stringify(targetFilesContentMap[path])) 60 | }); 61 | outputFiles.push(jsonFile); 62 | }); 63 | 64 | return outputFiles; 65 | } 66 | 67 | private getFilePaths(dir, paths: string[] = []): string[] { 68 | if (!dir.endsWith('/')) { 69 | dir += '/'; 70 | } 71 | 72 | let files = fs.readdirSync(dir); 73 | files.forEach(file => { 74 | let filePath = dir + file; 75 | if (fs.statSync(filePath).isDirectory()) { 76 | paths.concat(this.getFilePaths(filePath, paths)); 77 | } else { 78 | paths.push(dir + file); 79 | } 80 | 81 | }); 82 | 83 | return paths; 84 | } 85 | 86 | private mergeJsons(relativePath: string, sourceJson: any, targetFilesContentMap: {}): void { 87 | if (targetFilesContentMap[relativePath]) { 88 | this.extend(targetFilesContentMap[relativePath], [sourceJson]); 89 | } else { 90 | targetFilesContentMap[relativePath] = sourceJson; 91 | } 92 | } 93 | 94 | private readJSON(path: string): any { 95 | return JSON.parse(fs.readFileSync(path, 'utf8')); 96 | } 97 | 98 | private isObject(value): boolean { 99 | return value !== null && typeof value === 'object'; 100 | } 101 | 102 | private isFunction(value): boolean { 103 | return typeof value === 'function'; 104 | } 105 | 106 | private extend(dest: any, sources: any[]): any { 107 | if (!sources || sources.length === 0) { 108 | return dest; 109 | } 110 | 111 | for (let i = 0; i < sources.length; i++) { 112 | let src = sources[i]; 113 | // Cant extend primitives or null/undefined values. so skip them 114 | if (!this.isObject(src) && !this.isFunction(src)) { 115 | continue; 116 | } 117 | let keys = Object.keys(src); 118 | let ki = keys.length; 119 | while (ki--) { 120 | let srcField = keys[ki]; 121 | let srcValue = src[srcField]; 122 | let destValue = srcValue; 123 | 124 | if (this.isObject(srcValue) && !Array.isArray(srcValue)) { 125 | destValue = {}; 126 | this.extend(destValue, [dest[srcField], srcValue]); 127 | } 128 | 129 | dest[srcField] = destValue; 130 | } 131 | } 132 | 133 | return dest; 134 | } 135 | } -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-merge-json-in-folders/json-merge.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.__esModule = true; 3 | var fs = require('fs'); 4 | var fsPath = require('path'); 5 | var readlineSync = require('readline-sync'); 6 | var gutil = require('gulp-util'); 7 | var Vinyl = require('vinyl'); 8 | var JsonMerge = (function () { 9 | function JsonMerge() { 10 | } 11 | /** 12 | * Recursively merges JSON files with the same name and same subPath from the sourceFolders into the JSON files 13 | * in the targetFolderPath. 14 | * 15 | * @example 16 | * src/assets/resources/strings/ <- targetFolderPath 17 | * strings.json 18 | * es/strings.json 19 | * pt/strings.json 20 | * [ 21 | * 'node_modules/@microsoft/windows-admin-center-sdk/core/dist/assets/resources/strings', 22 | * 'node_modules/@microsoft/windows-admin-center-sdk/ng2/dist/assets/resources/strings' 23 | * ] <- sourceFoldersPath 24 | * 25 | * src/assets/resources/strings/strings.json contents are merged with the contents of 26 | * node_modules/@microsoft/windows-admin-center-sdk/core/dist/assets/resources/strings/strings.json and 27 | * node_modules/@microsoft/windows-admin-center-sdk/ng2/core/dist/assets/resources/strings/strings.json 28 | * and the source file is overwritten by the merged content 29 | * 30 | * @param targetFolderPathRoot {string} The path of the base folder where the destination files are placed. 31 | * @param sourceFoldersPathRoot {string[]} The array of paths to the source folders from where to read the JSON files to merge 32 | */ 33 | JsonMerge.prototype.mergeJsonInFolders = function (targetFolderPathRoot, sourceFoldersPathRoot) { 34 | var _this = this; 35 | var outputFiles = []; 36 | var targetFilesContentMap = {}; 37 | var targetFiles = this.getFilePaths(targetFolderPathRoot); 38 | targetFiles.forEach(function (targetFile) { 39 | var relativePath = targetFile.substring(targetFolderPathRoot.length + 1, targetFile.length); 40 | targetFilesContentMap[relativePath] = _this.readJSON(targetFile); 41 | }); 42 | sourceFoldersPathRoot.forEach(function (sourceFolderPathRoot) { 43 | var sourceFiles = _this.getFilePaths(sourceFolderPathRoot); 44 | sourceFiles.forEach(function (sourceFile) { 45 | var relativePath = sourceFile.substring(sourceFolderPathRoot.length + 1, sourceFile.length); 46 | var sourceJson = _this.readJSON(sourceFile); 47 | _this.mergeJsons(relativePath, sourceJson, targetFilesContentMap); 48 | }); 49 | }); 50 | Object.keys(targetFilesContentMap).forEach(function (path) { 51 | var jsonFile = new Vinyl({ 52 | cwd: './', 53 | path: path, 54 | contents: new Buffer(JSON.stringify(targetFilesContentMap[path])) 55 | }); 56 | outputFiles.push(jsonFile); 57 | }); 58 | return outputFiles; 59 | }; 60 | JsonMerge.prototype.getFilePaths = function (dir, paths) { 61 | var _this = this; 62 | if (paths === void 0) { paths = []; } 63 | if (!dir.endsWith('/')) { 64 | dir += '/'; 65 | } 66 | var files = fs.readdirSync(dir); 67 | files.forEach(function (file) { 68 | var filePath = dir + file; 69 | if (fs.statSync(filePath).isDirectory()) { 70 | paths.concat(_this.getFilePaths(filePath, paths)); 71 | } 72 | else { 73 | paths.push(dir + file); 74 | } 75 | }); 76 | return paths; 77 | }; 78 | JsonMerge.prototype.mergeJsons = function (relativePath, sourceJson, targetFilesContentMap) { 79 | if (targetFilesContentMap[relativePath]) { 80 | this.extend(targetFilesContentMap[relativePath], [sourceJson]); 81 | } 82 | else { 83 | targetFilesContentMap[relativePath] = sourceJson; 84 | } 85 | }; 86 | JsonMerge.prototype.readJSON = function (path) { 87 | return JSON.parse(fs.readFileSync(path, 'utf8')); 88 | }; 89 | JsonMerge.prototype.isObject = function (value) { 90 | return value !== null && typeof value === 'object'; 91 | }; 92 | JsonMerge.prototype.isFunction = function (value) { 93 | return typeof value === 'function'; 94 | }; 95 | JsonMerge.prototype.extend = function (dest, sources) { 96 | if (!sources || sources.length === 0) { 97 | return dest; 98 | } 99 | for (var i = 0; i < sources.length; i++) { 100 | var src = sources[i]; 101 | // Cant extend primitives or null/undefined values. so skip them 102 | if (!this.isObject(src) && !this.isFunction(src)) { 103 | continue; 104 | } 105 | var keys = Object.keys(src); 106 | var ki = keys.length; 107 | while (ki--) { 108 | var srcField = keys[ki]; 109 | var srcValue = src[srcField]; 110 | var destValue = srcValue; 111 | if (this.isObject(srcValue) && !Array.isArray(srcValue)) { 112 | destValue = {}; 113 | this.extend(destValue, [dest[srcField], srcValue]); 114 | } 115 | dest[srcField] = destValue; 116 | } 117 | } 118 | return dest; 119 | }; 120 | return JsonMerge; 121 | }()); 122 | exports.JsonMerge = JsonMerge; 123 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-svg-code/svg-code-convert.ts: -------------------------------------------------------------------------------- 1 | declare function escape(data: string): string; 2 | declare function unescape(data: string): string; 3 | 4 | export class SvgCodeConverter { 5 | private static openContentTs = 6 | `/* tslint:disable */ 7 | /** 8 | * @file Source code generated by gulp-svg-code. 9 | * @version 1.0 10 | */ 11 | export module Svg { 12 | 'use strict' 13 | `; 14 | private static closeContentTs = 15 | `} 16 | `; 17 | private static openContentCss = 18 | `/** 19 | * @file Source code generated by gulp-svg-code. 20 | * @version 1.0 21 | */ 22 | `; 23 | private outputCss: string[] = []; 24 | private outputTs: string[] = []; 25 | 26 | public get contentCss(): string { 27 | return this.outputCss.join(''); 28 | } 29 | 30 | public get contentTs(): string { 31 | return this.outputTs.join(''); 32 | } 33 | 34 | public contentReset(): void { 35 | this.outputCss = []; 36 | this.outputTs = []; 37 | } 38 | 39 | public generate(collection: { [index: string]: any }, pathPrefix: string): void { 40 | let root = this.createStructure(collection, pathPrefix); 41 | this.outputCss.push(SvgCodeConverter.openContentCss); 42 | this.outputTs.push(SvgCodeConverter.openContentTs); 43 | this.addData(root, []); 44 | this.outputTs.push(SvgCodeConverter.closeContentTs); 45 | } 46 | 47 | private addData(current: any, segments: string[]): void { 48 | const ignores = [ ' { 68 | value = value.replace('\n', ''); 69 | if (value && value.length > 1) { 70 | let skip = false; 71 | for (let item of ignores) { 72 | if (value.indexOf(item) >= 0) { 73 | skip = true; 74 | break; 75 | } 76 | } 77 | 78 | if (!skip) { 79 | svg += value; 80 | // this.outputCss.push(value); 81 | this.outputTs.push(value); 82 | } 83 | } 84 | }); 85 | 86 | svg = this.replaceAll(svg, '"', '\''); 87 | svg = this.replaceAll(svg, '%', '%25'); 88 | svg = this.replaceAll(svg, '#', '%23'); 89 | svg = this.replaceAll(svg, '{', '%7B'); 90 | svg = this.replaceAll(svg, '}', '%7D'); 91 | svg = this.replaceAll(svg, '<', '%3C'); 92 | svg = this.replaceAll(svg, '>', '%3E'); 93 | this.outputCss.push('charset=utf8,' + svg); 94 | 95 | this.outputCss.push('");\r\n'); 96 | this.outputCss.push('}\r\n'); 97 | this.outputCss.push('\r\n'); 98 | 99 | this.outputTs.push('\';\r\n'); 100 | } 101 | 102 | segments.pop(); 103 | } 104 | 105 | for (let index = 0; index < nested.length; index++) { 106 | let { content, segs } = nested[index]; 107 | this.outputTs.push(this.indent(segs.length) + 'export module ' + segs[segs.length - 1] + ' {\r\n'); 108 | this.addData(nested[index].content, nested[index].segs); 109 | this.outputTs.push(this.indent(segs.length) + '}\r\n'); 110 | } 111 | } 112 | 113 | private createStructure(collection: { [index: string]: any }, pathPrefix: string): any { 114 | let root = {}; 115 | let keys = Object.keys(collection).sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase())); 116 | for (let key of keys) { 117 | let shortName = key.substr(0, key.length - '.svg'.length); 118 | shortName = this.replaceAll(shortName.substr(pathPrefix.length + 1), '-', '_').toLowerCase(); 119 | let segments = shortName.split('\\'); 120 | let current = root; 121 | for (let index = 0; index < segments.length - 1; index++) { 122 | let segment = segments[index]; 123 | if (current.hasOwnProperty(segment)) { 124 | current = current[segment]; 125 | } else { 126 | current[segment] = {}; 127 | current = current[segment]; 128 | } 129 | } 130 | 131 | current[segments[segments.length - 1]] = collection[key]; 132 | } 133 | 134 | return root; 135 | } 136 | 137 | private regexEscape(str: string): string { 138 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 139 | } 140 | 141 | private replaceAll(input: string, searchValue: string, replaceValue: string): string { 142 | return input.replace(new RegExp(this.regexEscape(searchValue), 'g'), replaceValue); 143 | } 144 | 145 | private indent(count: number): string { 146 | let pad = ''; 147 | for (let i = 0; i < count; i++) { 148 | pad += ' '; 149 | } 150 | 151 | return pad; 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-svg-code/svg-code-convert.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.__esModule = true; 3 | var SvgCodeConverter = (function () { 4 | function SvgCodeConverter() { 5 | this.outputCss = []; 6 | this.outputTs = []; 7 | } 8 | Object.defineProperty(SvgCodeConverter.prototype, "contentCss", { 9 | get: function () { 10 | return this.outputCss.join(''); 11 | }, 12 | enumerable: true, 13 | configurable: true 14 | }); 15 | Object.defineProperty(SvgCodeConverter.prototype, "contentTs", { 16 | get: function () { 17 | return this.outputTs.join(''); 18 | }, 19 | enumerable: true, 20 | configurable: true 21 | }); 22 | SvgCodeConverter.prototype.contentReset = function () { 23 | this.outputCss = []; 24 | this.outputTs = []; 25 | }; 26 | SvgCodeConverter.prototype.generate = function (collection, pathPrefix) { 27 | var root = this.createStructure(collection, pathPrefix); 28 | this.outputCss.push(SvgCodeConverter.openContentCss); 29 | this.outputTs.push(SvgCodeConverter.openContentTs); 30 | this.addData(root, []); 31 | this.outputTs.push(SvgCodeConverter.closeContentTs); 32 | }; 33 | SvgCodeConverter.prototype.addData = function (current, segments) { 34 | var _this = this; 35 | var ignores = [' 1) { 55 | var skip = false; 56 | for (var _i = 0, ignores_1 = ignores; _i < ignores_1.length; _i++) { 57 | var item = ignores_1[_i]; 58 | if (value.indexOf(item) >= 0) { 59 | skip = true; 60 | break; 61 | } 62 | } 63 | if (!skip) { 64 | svg_1 += value; 65 | // this.outputCss.push(value); 66 | _this.outputTs.push(value); 67 | } 68 | } 69 | }); 70 | svg_1 = this_1.replaceAll(svg_1, '"', '\''); 71 | svg_1 = this_1.replaceAll(svg_1, '%', '%25'); 72 | svg_1 = this_1.replaceAll(svg_1, '#', '%23'); 73 | svg_1 = this_1.replaceAll(svg_1, '{', '%7B'); 74 | svg_1 = this_1.replaceAll(svg_1, '}', '%7D'); 75 | svg_1 = this_1.replaceAll(svg_1, '<', '%3C'); 76 | svg_1 = this_1.replaceAll(svg_1, '>', '%3E'); 77 | this_1.outputCss.push('charset=utf8,' + svg_1); 78 | this_1.outputCss.push('");\r\n'); 79 | this_1.outputCss.push('}\r\n'); 80 | this_1.outputCss.push('\r\n'); 81 | this_1.outputTs.push('\';\r\n'); 82 | } 83 | segments.pop(); 84 | }; 85 | var this_1 = this; 86 | for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 87 | var key = keys_1[_i]; 88 | _loop_1(key); 89 | } 90 | for (var index = 0; index < nested.length; index++) { 91 | var _a = nested[index], content = _a.content, segs = _a.segs; 92 | this.outputTs.push(this.indent(segs.length) + 'export module ' + segs[segs.length - 1] + ' {\r\n'); 93 | this.addData(nested[index].content, nested[index].segs); 94 | this.outputTs.push(this.indent(segs.length) + '}\r\n'); 95 | } 96 | }; 97 | SvgCodeConverter.prototype.createStructure = function (collection, pathPrefix) { 98 | var root = {}; 99 | var keys = Object.keys(collection).sort(function (left, right) { return left.toLowerCase().localeCompare(right.toLowerCase()); }); 100 | for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) { 101 | var key = keys_2[_i]; 102 | var shortName = key.substr(0, key.length - '.svg'.length); 103 | shortName = this.replaceAll(shortName.substr(pathPrefix.length + 1), '-', '_').toLowerCase(); 104 | var segments = shortName.split('\\'); 105 | var current = root; 106 | for (var index = 0; index < segments.length - 1; index++) { 107 | var segment = segments[index]; 108 | if (current.hasOwnProperty(segment)) { 109 | current = current[segment]; 110 | } 111 | else { 112 | current[segment] = {}; 113 | current = current[segment]; 114 | } 115 | } 116 | current[segments[segments.length - 1]] = collection[key]; 117 | } 118 | return root; 119 | }; 120 | SvgCodeConverter.prototype.regexEscape = function (str) { 121 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 122 | }; 123 | SvgCodeConverter.prototype.replaceAll = function (input, searchValue, replaceValue) { 124 | return input.replace(new RegExp(this.regexEscape(searchValue), 'g'), replaceValue); 125 | }; 126 | SvgCodeConverter.prototype.indent = function (count) { 127 | var pad = ''; 128 | for (var i = 0; i < count; i++) { 129 | pad += ' '; 130 | } 131 | return pad; 132 | }; 133 | return SvgCodeConverter; 134 | }()); 135 | SvgCodeConverter.openContentTs = "/* tslint:disable */\n/**\n * @file Source code generated by gulp-svg-code.\n * @version 1.0\n */\nexport module Svg {\n 'use strict'\n"; 136 | SvgCodeConverter.closeContentTs = "}\n"; 137 | SvgCodeConverter.openContentCss = "/**\n * @file Source code generated by gulp-svg-code.\n * @version 1.0\n */\n"; 138 | exports.SvgCodeConverter = SvgCodeConverter; 139 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-resjson/resjson-convert.ts: -------------------------------------------------------------------------------- 1 | export interface Options { 2 | // enable to produce xxxx.d.ts file. 3 | // { null, 'module' } 4 | definition: string; 5 | 6 | // enable to produce xxxx.ts file. 7 | // { null, 'module', 'interface' } 8 | typescript: string; 9 | 10 | // enable to produce xxxx.json file. 11 | json: boolean; 12 | 13 | // if set a space characters, it adds formating of JSON. 14 | // it set null, space will be eliminated. 15 | jsonSpace: string | number; 16 | } 17 | 18 | interface NameValuePair { 19 | name: string; 20 | value: any; 21 | } 22 | 23 | export class ResJsonConverter { 24 | private static openContent = 25 | `/* tslint:disable */ 26 | /** 27 | * @file Source code generated by gulp-resjson. 28 | * @version 1.0 29 | */ 30 | `; 31 | private static closeContent = 32 | `} 33 | `; 34 | public outputJson: any; 35 | private outputDefinition: string[]; 36 | private outputTypescript: string[]; 37 | private outputInterface: string[]; 38 | private jsonCurrent: any; 39 | 40 | constructor(private options: Options) { 41 | } 42 | 43 | public get contentDefinition(): string { 44 | return this.outputDefinition.join(''); 45 | } 46 | 47 | public get contentTypescript(): string { 48 | return this.outputTypescript.join(''); 49 | } 50 | 51 | public get contentInterface(): string { 52 | return this.outputInterface.join(''); 53 | } 54 | 55 | public contentReset(): void { 56 | this.outputDefinition = []; 57 | this.outputTypescript = []; 58 | this.outputInterface = []; 59 | this.outputJson = {}; 60 | this.jsonCurrent = this.outputJson; 61 | } 62 | 63 | public convert(content: string) { 64 | let root = {}; 65 | // Remove comments, /* multilinecomment*/ and // one line comment and "//": "JSON element comment" 66 | content = content.replace(/(\/\*([^*]|[\n]|(\*+([^*/]|[\n])))*\*\/+)|( +\/\/.*)|( +\"\/\/\".*)/g, ''); 67 | let data: any = JSON.parse(content); 68 | let itemKeys = Object.keys(data); 69 | 70 | // build a data tree. 71 | for (let itemKey of itemKeys) { 72 | // remove localization comments 73 | if (itemKey.startsWith('//') || (itemKey.startsWith('_') && itemKey.endsWith('.comment'))) { 74 | continue; 75 | } 76 | 77 | let current = root; 78 | let itemValue = data[itemKey]; 79 | const keys = itemKey.split('_'); 80 | let count = keys.length; 81 | for (let key of keys) { 82 | count--; 83 | if (count > 0) { 84 | if (!current.hasOwnProperty(key)) { 85 | current[key] = {}; 86 | } 87 | 88 | current = current[key]; 89 | 90 | if (typeof current !== 'object') { 91 | throw new Error('Resource key already exists: ' + itemKey); 92 | } 93 | } else { 94 | current[key] = itemValue; 95 | } 96 | } 97 | } 98 | 99 | this.contentReset(); 100 | this.traverse([{ name: 'Strings', value: root }], 0); 101 | } 102 | 103 | private jsonNewValue(name: string): any { 104 | let old = this.jsonCurrent; 105 | let json = {}; 106 | this.jsonCurrent[name] = json; 107 | this.jsonCurrent = json; 108 | 109 | return old; 110 | } 111 | 112 | private jsonAddValue(name: string, value: any): void { 113 | this.jsonCurrent[name] = value; 114 | } 115 | 116 | private scan(node: any): { keyItems: NameValuePair[], dataItems: NameValuePair[] } { 117 | let current = node; 118 | let keyItems: NameValuePair[] = []; 119 | let dataItems: NameValuePair[] = []; 120 | for (let itemKey in current) { 121 | if (current.hasOwnProperty(itemKey)) { 122 | let itemValue: any = current[itemKey]; 123 | if (typeof itemValue === 'object') { 124 | keyItems.push({ name: itemKey, value: itemValue }); 125 | } else if (typeof itemValue === 'string') { 126 | dataItems.push({ name: itemKey, value: itemValue }); 127 | } 128 | } 129 | } 130 | 131 | return { 132 | keyItems: keyItems, 133 | dataItems: dataItems 134 | }; 135 | } 136 | 137 | private traverse(keyItems: NameValuePair[], indent: number): void { 138 | const indentSpace = ' '; 139 | let indentName = ''; 140 | for (let i = 0; i < indent; i++) { 141 | indentName += indentSpace; 142 | } 143 | 144 | let indentValue: string = indentName + indentSpace; 145 | if (keyItems.length > 0) { 146 | for (let item of keyItems) { 147 | if (indent === 0) { 148 | this.outputDefinition.push(ResJsonConverter.openContent); 149 | this.outputTypescript.push(ResJsonConverter.openContent); 150 | this.outputInterface.push(ResJsonConverter.openContent); 151 | this.outputDefinition.push('export declare module ' + item.name + ' {\r\n'); 152 | this.outputTypescript.push('export module ' + item.name + ' {\r\n \'use strict\';\r\n'); 153 | this.outputInterface.push('export interface ' + item.name + ' {\r\n'); 154 | } else { 155 | this.outputDefinition.push(indentName + 'module ' + item.name + ' {\r\n'); 156 | this.outputTypescript.push(indentName + 'export module ' + item.name + ' {\r\n'); 157 | this.outputInterface.push(indentName + item.name + ': {\r\n'); 158 | } 159 | 160 | let jsonOld = this.jsonNewValue(item.name); 161 | let results = this.scan(item.value); 162 | for (let item2 of results.dataItems) { 163 | this.outputDefinition.push(indentValue + 'const ' + item2.name + ': string;\r\n'); 164 | this.outputTypescript.push(indentValue + 'export const ' + item2.name + ' = \'' + item2.value + '\';\r\n'); 165 | this.outputInterface.push(indentValue + item2.name + ': string;\r\n'); 166 | this.jsonAddValue(item2.name, item2.value); 167 | } 168 | 169 | this.traverse(results.keyItems, ++indent); 170 | this.jsonCurrent = jsonOld; 171 | 172 | this.outputDefinition.push(indentName + '}\r\n'); 173 | this.outputTypescript.push(indentName + '}\r\n'); 174 | this.outputInterface.push(indentName + '};\r\n'); 175 | } 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /templates/legacy/windows-admin-center-extension-template/gulps/gulp-resjson/resjson-convert.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.__esModule = true; 3 | var ResJsonConverter = (function () { 4 | function ResJsonConverter(options) { 5 | this.options = options; 6 | } 7 | Object.defineProperty(ResJsonConverter.prototype, "contentDefinition", { 8 | get: function () { 9 | return this.outputDefinition.join(''); 10 | }, 11 | enumerable: true, 12 | configurable: true 13 | }); 14 | Object.defineProperty(ResJsonConverter.prototype, "contentTypescript", { 15 | get: function () { 16 | return this.outputTypescript.join(''); 17 | }, 18 | enumerable: true, 19 | configurable: true 20 | }); 21 | Object.defineProperty(ResJsonConverter.prototype, "contentInterface", { 22 | get: function () { 23 | return this.outputInterface.join(''); 24 | }, 25 | enumerable: true, 26 | configurable: true 27 | }); 28 | ResJsonConverter.prototype.contentReset = function () { 29 | this.outputDefinition = []; 30 | this.outputTypescript = []; 31 | this.outputInterface = []; 32 | this.outputJson = {}; 33 | this.jsonCurrent = this.outputJson; 34 | }; 35 | ResJsonConverter.prototype.convert = function (content) { 36 | var root = {}; 37 | // Remove comments, /* multilinecomment*/ and // one line comment and "//": "JSON element comment" 38 | content = content.replace(/(\/\*([^*]|[\n]|(\*+([^*/]|[\n])))*\*\/+)|( +\/\/.*)|( +\"\/\/\".*)/g, ''); 39 | var data = JSON.parse(content); 40 | var itemKeys = Object.keys(data); 41 | // build a data tree. 42 | for (var _i = 0, itemKeys_1 = itemKeys; _i < itemKeys_1.length; _i++) { 43 | var itemKey = itemKeys_1[_i]; 44 | // remove localization comments 45 | if (itemKey.startsWith('//') || (itemKey.startsWith('_') && itemKey.endsWith('.comment'))) { 46 | continue; 47 | } 48 | var current = root; 49 | var itemValue = data[itemKey]; 50 | var keys = itemKey.split('_'); 51 | var count = keys.length; 52 | for (var _a = 0, keys_1 = keys; _a < keys_1.length; _a++) { 53 | var key = keys_1[_a]; 54 | count--; 55 | if (count > 0) { 56 | if (!current.hasOwnProperty(key)) { 57 | current[key] = {}; 58 | } 59 | current = current[key]; 60 | if (typeof current !== 'object') { 61 | throw new Error('Resource key already exists: ' + itemKey); 62 | } 63 | } 64 | else { 65 | current[key] = itemValue; 66 | } 67 | } 68 | } 69 | this.contentReset(); 70 | this.traverse([{ name: 'Strings', value: root }], 0); 71 | }; 72 | ResJsonConverter.prototype.jsonNewValue = function (name) { 73 | var old = this.jsonCurrent; 74 | var json = {}; 75 | this.jsonCurrent[name] = json; 76 | this.jsonCurrent = json; 77 | return old; 78 | }; 79 | ResJsonConverter.prototype.jsonAddValue = function (name, value) { 80 | this.jsonCurrent[name] = value; 81 | }; 82 | ResJsonConverter.prototype.scan = function (node) { 83 | var current = node; 84 | var keyItems = []; 85 | var dataItems = []; 86 | for (var itemKey in current) { 87 | if (current.hasOwnProperty(itemKey)) { 88 | var itemValue = current[itemKey]; 89 | if (typeof itemValue === 'object') { 90 | keyItems.push({ name: itemKey, value: itemValue }); 91 | } 92 | else if (typeof itemValue === 'string') { 93 | dataItems.push({ name: itemKey, value: itemValue }); 94 | } 95 | } 96 | } 97 | return { 98 | keyItems: keyItems, 99 | dataItems: dataItems 100 | }; 101 | }; 102 | ResJsonConverter.prototype.traverse = function (keyItems, indent) { 103 | var indentSpace = ' '; 104 | var indentName = ''; 105 | for (var i = 0; i < indent; i++) { 106 | indentName += indentSpace; 107 | } 108 | var indentValue = indentName + indentSpace; 109 | if (keyItems.length > 0) { 110 | for (var _i = 0, keyItems_1 = keyItems; _i < keyItems_1.length; _i++) { 111 | var item = keyItems_1[_i]; 112 | if (indent === 0) { 113 | this.outputDefinition.push(ResJsonConverter.openContent); 114 | this.outputTypescript.push(ResJsonConverter.openContent); 115 | this.outputInterface.push(ResJsonConverter.openContent); 116 | this.outputDefinition.push('export declare module ' + item.name + ' {\r\n'); 117 | this.outputTypescript.push('export module ' + item.name + ' {\r\n \'use strict\';\r\n'); 118 | this.outputInterface.push('export interface ' + item.name + ' {\r\n'); 119 | } 120 | else { 121 | this.outputDefinition.push(indentName + 'module ' + item.name + ' {\r\n'); 122 | this.outputTypescript.push(indentName + 'export module ' + item.name + ' {\r\n'); 123 | this.outputInterface.push(indentName + item.name + ': {\r\n'); 124 | } 125 | var jsonOld = this.jsonNewValue(item.name); 126 | var results = this.scan(item.value); 127 | for (var _a = 0, _b = results.dataItems; _a < _b.length; _a++) { 128 | var item2 = _b[_a]; 129 | this.outputDefinition.push(indentValue + 'const ' + item2.name + ': string;\r\n'); 130 | this.outputTypescript.push(indentValue + 'export const ' + item2.name + ' = \'' + item2.value + '\';\r\n'); 131 | this.outputInterface.push(indentValue + item2.name + ': string;\r\n'); 132 | this.jsonAddValue(item2.name, item2.value); 133 | } 134 | this.traverse(results.keyItems, ++indent); 135 | this.jsonCurrent = jsonOld; 136 | this.outputDefinition.push(indentName + '}\r\n'); 137 | this.outputTypescript.push(indentName + '}\r\n'); 138 | this.outputInterface.push(indentName + '};\r\n'); 139 | } 140 | } 141 | }; 142 | return ResJsonConverter; 143 | }()); 144 | ResJsonConverter.openContent = "/* tslint:disable */\n/**\n * @file Source code generated by gulp-resjson.\n * @version 1.0\n */\n"; 145 | ResJsonConverter.closeContent = "}\n"; 146 | exports.ResJsonConverter = ResJsonConverter; 147 | -------------------------------------------------------------------------------- /templates/manifest/tool-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../node_modules/@microsoft/windows-admin-center-sdk/core/manifest/module-schema.json#", 3 | "name": "{!company-name}.{!product-name}", 4 | "displayName": "resources:strings:displayName", 5 | "description": "resources:strings:description", 6 | "target": "/modules/{!company-name}.{!module-name}", 7 | "icon": "sme-icon:sme-icon-powerShell", 8 | "keywords": [ 9 | "resources:strings:keywords" 10 | ], 11 | "entryPoints": [ 12 | { 13 | "entryPointType": "tool", 14 | "name": "main", 15 | "urlName": "{!primary-url-name}", 16 | "displayName": "resources:strings:displayName", 17 | "description": "resources:strings:description", 18 | "icon": "sme-icon:sme-icon-powerShell", 19 | "path": "", 20 | "requirements": [ 21 | { 22 | "solutionIds": [ 23 | "msft.sme.server-manager!servers", 24 | "msft.sme.server-manager!windowsClients", 25 | "msft.sme.developer-tools!main" 26 | ], 27 | "connectionTypes": [ 28 | "msft.sme.connection-type.server", 29 | "msft.sme.connection-type.windows-client" 30 | ] 31 | } 32 | ] 33 | } 34 | ], 35 | "resources": [ 36 | { 37 | "locale": "default", 38 | "strings": { 39 | "keywords": "example", 40 | "description": "{!product-description}", 41 | "displayName": "{!primary-display-name}" 42 | } 43 | }, 44 | { 45 | "locale": "cs-CZ", 46 | "strings": { 47 | "keywords": "example", 48 | "description": "{!product-description}", 49 | "displayName": "{!primary-display-name}" 50 | } 51 | }, 52 | { 53 | "locale": "de-DE", 54 | "strings": { 55 | "keywords": "example", 56 | "description": "{!product-description}", 57 | "displayName": "{!primary-display-name}" 58 | } 59 | }, 60 | { 61 | "locale": "en-US", 62 | "strings": { 63 | "keywords": "example", 64 | "description": "{!product-description}", 65 | "displayName": "{!primary-display-name}" 66 | } 67 | }, 68 | { 69 | "locale": "es-ES", 70 | "strings": { 71 | "keywords": "example", 72 | "description": "{!product-description}", 73 | "displayName": "{!primary-display-name}" 74 | } 75 | }, 76 | { 77 | "locale": "fr-FR", 78 | "strings": { 79 | "keywords": "example", 80 | "description": "{!product-description}", 81 | "displayName": "{!primary-display-name}" 82 | } 83 | }, 84 | { 85 | "locale": "hu-HU", 86 | "strings": { 87 | "keywords": "example", 88 | "description": "{!product-description}", 89 | "displayName": "{!primary-display-name}" 90 | } 91 | }, 92 | { 93 | "locale": "it-IT", 94 | "strings": { 95 | "keywords": "example", 96 | "description": "{!product-description}", 97 | "displayName": "{!primary-display-name}" 98 | } 99 | }, 100 | { 101 | "locale": "ja-JP", 102 | "strings": { 103 | "keywords": "example", 104 | "description": "{!product-description}", 105 | "displayName": "{!primary-display-name}" 106 | } 107 | }, 108 | { 109 | "locale": "ko-KR", 110 | "strings": { 111 | "keywords": "example", 112 | "description": "{!product-description}", 113 | "displayName": "{!primary-display-name}" 114 | } 115 | }, 116 | { 117 | "locale": "nl-NL", 118 | "strings": { 119 | "keyword-example": "example", 120 | "description": "{!product-description}", 121 | "displayName": "{!primary-display-name}" 122 | } 123 | }, 124 | { 125 | "locale": "pl-PL", 126 | "strings": { 127 | "keywords": "example", 128 | "description": "{!product-description}", 129 | "displayName": "{!primary-display-name}" 130 | } 131 | }, 132 | { 133 | "locale": "pl-PL", 134 | "strings": { 135 | "keywords": "example", 136 | "description": "{!product-description}", 137 | "displayName": "{!primary-display-name}" 138 | } 139 | }, 140 | { 141 | "locale": "pt-BR", 142 | "strings": { 143 | "keywords": "example", 144 | "description": "{!product-description}", 145 | "displayName": "{!primary-display-name}" 146 | } 147 | }, 148 | { 149 | "locale": "pt-PT", 150 | "strings": { 151 | "keywords": "example", 152 | "description": "{!product-description}", 153 | "displayName": "{!primary-display-name}" 154 | } 155 | }, 156 | { 157 | "locale": "ru-RU", 158 | "strings": { 159 | "keywords": "example", 160 | "description": "{!product-description}", 161 | "displayName": "{!primary-display-name}" 162 | } 163 | }, 164 | { 165 | "locale": "sv-SE", 166 | "strings": { 167 | "keywords": "example", 168 | "description": "{!product-description}", 169 | "displayName": "{!primary-display-name}" 170 | } 171 | }, 172 | { 173 | "locale": "tr-TR", 174 | "strings": { 175 | "keywords": "example", 176 | "description": "{!product-description}", 177 | "displayName": "{!primary-display-name}" 178 | } 179 | }, 180 | { 181 | "locale": "zh-CN", 182 | "strings": { 183 | "keywords": "example", 184 | "description": "{!product-description}", 185 | "displayName": "{!primary-display-name}" 186 | } 187 | }, 188 | { 189 | "locale": "zh-TW", 190 | "strings": { 191 | "keywords": "example", 192 | "description": "{!product-description}", 193 | "displayName": "{!primary-display-name}" 194 | } 195 | } 196 | ] 197 | } 198 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var fse = require('fs-extra'); 4 | var minimist = require('minimist'); 5 | var pathExists = require('path-exists'); 6 | var update = require('./update-version'); 7 | 8 | const argv = minimist(process.argv.slice(2)); 9 | 10 | if (argv._ == 'updateSeven') { 11 | update.update((argv.audit === undefined || argv.audit === true) && argv.update === undefined, process.cwd()); 12 | } 13 | else if (argv._ == 'create') { 14 | createExtension(); 15 | } 16 | else { 17 | console.log('unrecognized command: ' + argv._); 18 | } 19 | 20 | function createExtension() { 21 | /** 22 | * Arguments: 23 | * --company - name of the company or person making the extension. 24 | * --tool - name of the tool / extension that is being built. 25 | * --version - tag of the version to use. 26 | **/ 27 | let normalizedCompany = normalizeString(argv.company ? argv.company : ''); 28 | let normalizedTool = normalizeString(argv.tool ? argv.tool : ''); 29 | 30 | let version = argv.version ? argv.version.toLowerCase() : ''; 31 | let extensionType = argv.solution ? 'solution' : 'tool'; 32 | let normalizedSolution = argv.solution ? normalizeString(argv.solution) : ''; 33 | 34 | if (argv.length === 0 || !isValidVersion(version) || !normalizedCompany || !normalizedTool) { 35 | console.error('Usage: wac create --company --name --version [--verbose]'); 36 | console.log('or'); 37 | console.log('wac create --company --solution --tool --type --version [--verbose]'); 38 | console.log('Valid version tags: \'legacy\', \'latest\', \'insider\', \'next\', \'experimental\''); 39 | console.log('More information can be found here:'); 40 | process.exit(1); 41 | } 42 | 43 | if (normalizedSolution === '') { 44 | create(extensionType, normalizedCompany, normalizedTool, '', version); 45 | } else { 46 | create(extensionType, normalizedCompany, normalizedSolution, normalizedTool, version); 47 | } 48 | } 49 | 50 | function create(type, company, primary, secondary, version) { 51 | const ignoresPath = __dirname.substring(0, __dirname.length - 3) + 'templates\\ignores'; 52 | const legacyTemplatePath = __dirname.substring(0, __dirname.length - 3) + 'templates\\legacy\\windows-admin-center-extension-template'; 53 | const templatePath = __dirname.substring(0, __dirname.length - 3) + 'templates\\windows-admin-center-extension-template'; 54 | const manifestTemplatePath = __dirname.substring(0, __dirname.length - 3) + 'templates\\manifest'; 55 | 56 | if (pathExists.sync(primary)) { 57 | console.error('This tool definition already exists. No changes have been made.') 58 | } else { 59 | let productPath = './' + primary; 60 | console.log(productPath); 61 | fse.mkdirSync(primary); 62 | 63 | if (version === 'legacy') { 64 | fse.copySync(legacyTemplatePath, productPath); 65 | } else { 66 | fse.copySync(templatePath, productPath); 67 | } 68 | 69 | fse.copyFileSync(ignoresPath + '\\git', productPath + '\\.gitignore'); 70 | fse.copyFileSync(ignoresPath + '\\npm', productPath + '\\.npmignore'); 71 | 72 | if (type === 'tool') { 73 | // make tool manifest 74 | fse.copyFileSync(manifestTemplatePath + '\\tool-manifest.json', productPath + '\\src\\manifest.json'); 75 | } else if (type === 'solution') { 76 | // make solution manifest 77 | fse.copyFileSync(manifestTemplatePath + '\\solution-manifest.json', productPath + '\\src\\manifest.json'); 78 | } 79 | 80 | updateFiles(company, primary, secondary, version); 81 | printOutro(primary); 82 | } 83 | } 84 | 85 | function updateFiles(company, primary, secondary, version) { 86 | /* 87 | / files that need updating: 88 | / root package.json 89 | / src/manifest.json 90 | / src/resources/strings/strings.resjson 91 | / src/main.ts 92 | / in Experimental: gulpfile.js 93 | */ 94 | var cleanDirectory = {}; 95 | let rootPackagePath = './' + primary + '/package.json'; 96 | let manifestFilePath = './' + primary + '/src/manifest.json'; 97 | let mainFilePath = './' + primary + '/src/main.ts'; 98 | let stringsFilePath = './' + primary + '/src/resources/strings/strings.resjson'; 99 | let gulpFilePath = './' + primary + '/gulpfile.ts/config-data.ts'; 100 | 101 | let packageName = '@' + company.toLowerCase() + '/' + primary.toLowerCase(); 102 | let manifestName = company.toLowerCase() + '.' + primary.toLowerCase(); 103 | let stringsProduct = primary.split('-').join(''); // Strings file cannot handle dashes. 104 | let stringsCompany = company.split('-').join(''); 105 | let companyPackageIdentifier = company.split('-').join('') + primary.split('-').join(''); 106 | 107 | /* 108 | / Default version is 'legacy' in legacy/windows-admin-center-extension-template/package.json 109 | / Default version is 'latest' in windows-admin-center-extension-template/package.json 110 | */ 111 | if (version === 'next' || version === 'insider' || version === 'experimental') { 112 | let existingVersion = '"@microsoft/windows-admin-center-sdk": "latest",'; 113 | cleanDirectory[rootPackagePath] = { 114 | '@{!company-name}/{!product-name}': packageName, 115 | '"@microsoft/windows-admin-center-sdk": "latest",': existingVersion.replace('latest', version) 116 | }; 117 | } else { 118 | cleanDirectory[rootPackagePath] = { '@{!company-name}/{!product-name}': packageName }; 119 | } 120 | 121 | if (version !== 'legacy') { 122 | cleanDirectory[gulpFilePath] = { 123 | '{!company-name}.{!module-name}': manifestName, 124 | '{!CompanyName}{!ProductName}': stringsCompany + stringsProduct, 125 | '{!guid}': uuidv4(), 126 | '{!company-package-id}': companyPackageIdentifier 127 | }; 128 | } 129 | 130 | 131 | cleanDirectory[manifestFilePath] = { 132 | '{!company-name}.{!module-name}': manifestName, 133 | '{!company-name}.{!product-name}': manifestName, 134 | '{!primary-display-name}': primary, 135 | '{!primary-url-name}': primary.toLowerCase(), 136 | '{!secondary-display-name}': secondary, 137 | '{!secondary-url-name}': secondary.toLowerCase() 138 | }; 139 | 140 | cleanDirectory[stringsFilePath] = { 141 | '{!product-display-name}': stringsProduct, 142 | '{!product-title}': stringsProduct, 143 | '{!ProductName}': stringsProduct, 144 | '{!CompanyName}': stringsCompany 145 | }; 146 | 147 | cleanDirectory[mainFilePath] = { '{!company-name}.{!product-name}': manifestName }; 148 | 149 | for (var key in cleanDirectory) { 150 | cleanFile(key, cleanDirectory[key]); 151 | } 152 | } 153 | 154 | function cleanFile(key, values) { 155 | console.log('Updating: ' + key); 156 | for (var valuesKey in values) { 157 | // console.log('Looking for:' + valuesKey + ' - ' + values[valuesKey]); 158 | let fileData = fse.readFileSync(key, 'utf8'); 159 | let displayNameIndex = fileData.indexOf(valuesKey); 160 | while (displayNameIndex > 0) { 161 | fileData = fileData.replace(valuesKey, values[valuesKey]); 162 | displayNameIndex = fileData.indexOf(valuesKey); 163 | } 164 | 165 | fse.outputFileSync(key, fileData); 166 | } 167 | } 168 | 169 | function printOutro(product) { 170 | console.log(''); 171 | console.log('Thank you for using the Windows Admin Center CLI.'); 172 | console.log(''); 173 | console.log('Next steps:'); 174 | console.log('cd into your new directory (cd ' + product + ') and then run \'npm install\' -> \'gulp build\' to build your new extension'); 175 | console.log('After that, \'gulp serve -p 4200\' to serve your new extension on port 4200'); 176 | console.log('Additional information can be found here: https://aka.ms/wacsdkdocs'); 177 | } 178 | 179 | function normalizeString(input) { 180 | return input.split(' ').join('-'); 181 | } 182 | 183 | function isValidVersion(version) { 184 | return version === 'legacy' || version === 'latest' || version === 'next' || version === 'insider' || version === 'release' || version === '' || version === 'experimental'; 185 | } 186 | 187 | // this came from here: https://gist.github.com/jed/982883 188 | function uuidv4(a) { return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuidv4) } -------------------------------------------------------------------------------- /templates/manifest/solution-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../node_modules/@microsoft/windows-admin-center-sdk/core/manifest/module-schema.json#", 3 | "name": "{!company-name}.{!product-name}", 4 | "displayName": "resources:strings:displayName", 5 | "description": "resources:strings:description", 6 | "target": "/modules/{!company-name}.{!module-name}", 7 | "icon": "sme-icon:sme-icon-powerShell", 8 | "keywords": [ 9 | "resources:strings:keywords" 10 | ], 11 | "entryPoints": [ 12 | { 13 | 14 | "entryPointType": "solution", 15 | "name": "solution", 16 | "urlName": "{!primary-url-name}", 17 | "displayName": "resources:strings:solutionName", 18 | "description": "resources:strings:solutionDescription", 19 | "icon": "sme-icon:sme-icon-powerShell", 20 | "rootNavigationBehavior": "connections", 21 | "connections": { 22 | "header": "resources:strings:connectionsListHeader", 23 | "connectionTypes": [ 24 | "msft.sme.connection-type.server", 25 | "msft.sme.connection-type.windows-client" 26 | ] 27 | }, 28 | "tools": { 29 | "enabled": true, 30 | "defaultTool": "home" 31 | } 32 | }, 33 | { 34 | "entryPointType": "tool", 35 | "name": "home", 36 | "urlName": "{!secondary-url-name}", 37 | "displayName": "resources:strings:displayName", 38 | "description": "resources:strings:description", 39 | "icon": "sme-icon:sme-icon-powerShell", 40 | "path": "", 41 | "requirements": [ 42 | { 43 | "solutionIds": [ 44 | "msft.sme.server-manager!servers", 45 | "msft.sme.server-manager!windowsClients", 46 | "{!company-name}.{!product-name}!solution" 47 | ], 48 | "connectionTypes": [ 49 | "msft.sme.connection-type.server", 50 | "msft.sme.connection-type.windows-client" 51 | ] 52 | } 53 | ] 54 | } 55 | ], 56 | "resources": [ 57 | { 58 | "locale": "default", 59 | "strings": { 60 | "keywords": "example", 61 | "description": "{!product-description}", 62 | "displayName": "{!secondary-display-name}", 63 | "solutionName": "{!primary-display-name}", 64 | "solutionDescription": "{!solution-description}" 65 | } 66 | }, 67 | { 68 | "locale": "cs-CZ", 69 | "strings": { 70 | "keywords": "example", 71 | "description": "{!product-description}", 72 | "displayName": "{!secondary-display-name}", 73 | "solutionName": "{!primary-display-name}", 74 | "solutionDescription": "{!solution-description}" 75 | } 76 | }, 77 | { 78 | "locale": "de-DE", 79 | "strings": { 80 | "keywords": "example", 81 | "description": "{!product-description}", 82 | "displayName": "{!secondary-display-name}", 83 | "solutionName": "{!primary-display-name}", 84 | "solutionDescription": "{!solution-description}" 85 | } 86 | }, 87 | { 88 | "locale": "en-US", 89 | "strings": { 90 | "keywords": "example", 91 | "description": "{!product-description}", 92 | "displayName": "{!secondary-display-name}", 93 | "solutionName": "{!primary-display-name}", 94 | "solutionDescription": "{!solution-description}" 95 | } 96 | }, 97 | { 98 | "locale": "es-ES", 99 | "strings": { 100 | "keywords": "example", 101 | "description": "{!product-description}", 102 | "displayName": "{!secondary-display-name}", 103 | "solutionName": "{!primary-display-name}", 104 | "solutionDescription": "{!solution-description}" 105 | } 106 | }, 107 | { 108 | "locale": "fr-FR", 109 | "strings": { 110 | "keywords": "example", 111 | "description": "{!product-description}", 112 | "displayName": "{!secondary-display-name}", 113 | "solutionName": "{!primary-display-name}", 114 | "solutionDescription": "{!solution-description}" 115 | } 116 | }, 117 | { 118 | "locale": "hu-HU", 119 | "strings": { 120 | "keywords": "example", 121 | "description": "{!product-description}", 122 | "displayName": "{!secondary-display-name}", 123 | "solutionName": "{!primary-display-name}", 124 | "solutionDescription": "{!solution-description}" 125 | } 126 | }, 127 | { 128 | "locale": "it-IT", 129 | "strings": { 130 | "keywords": "example", 131 | "description": "{!product-description}", 132 | "displayName": "{!secondary-display-name}", 133 | "solutionName": "{!primary-display-name}", 134 | "solutionDescription": "{!solution-description}" 135 | } 136 | }, 137 | { 138 | "locale": "ja-JP", 139 | "strings": { 140 | "keywords": "example", 141 | "description": "{!product-description}", 142 | "displayName": "{!secondary-display-name}", 143 | "solutionName": "{!primary-display-name}", 144 | "solutionDescription": "{!solution-description}" 145 | } 146 | }, 147 | { 148 | "locale": "ko-KR", 149 | "strings": { 150 | "keywords": "example", 151 | "description": "{!product-description}", 152 | "displayName": "{!secondary-display-name}", 153 | "solutionName": "{!primary-display-name}", 154 | "solutionDescription": "{!solution-description}" 155 | } 156 | }, 157 | { 158 | "locale": "nl-NL", 159 | "strings": { 160 | "keywords": "example", 161 | "description": "{!product-description}", 162 | "displayName": "{!secondary-display-name}", 163 | "solutionName": "{!primary-display-name}", 164 | "solutionDescription": "{!solution-description}" 165 | } 166 | }, 167 | { 168 | "locale": "pl-PL", 169 | "strings": { 170 | "keywords": "example", 171 | "description": "{!product-description}", 172 | "displayName": "{!secondary-display-name}", 173 | "solutionName": "{!primary-display-name}", 174 | "solutionDescription": "{!solution-description}" 175 | } 176 | }, 177 | { 178 | "locale": "pt-BR", 179 | "strings": { 180 | "keywords": "example", 181 | "description": "{!product-description}", 182 | "displayName": "{!secondary-display-name}", 183 | "solutionName": "{!primary-display-name}", 184 | "solutionDescription": "{!solution-description}" 185 | } 186 | }, 187 | { 188 | "locale": "pt-PT", 189 | "strings": { 190 | "keywords": "example", 191 | "description": "{!product-description}", 192 | "displayName": "{!secondary-display-name}", 193 | "solutionName": "{!primary-display-name}", 194 | "solutionDescription": "{!solution-description}" 195 | } 196 | }, 197 | { 198 | "locale": "ru-RU", 199 | "strings": { 200 | "keywords": "example", 201 | "description": "{!product-description}", 202 | "displayName": "{!secondary-display-name}", 203 | "solutionName": "{!primary-display-name}", 204 | "solutionDescription": "{!solution-description}" 205 | } 206 | }, 207 | { 208 | "locale": "sv-SE", 209 | "strings": { 210 | "keywords": "example", 211 | "description": "{!product-description}", 212 | "displayName": "{!secondary-display-name}", 213 | "solutionName": "{!primary-display-name}", 214 | "solutionDescription": "{!solution-description}" 215 | } 216 | }, 217 | { 218 | "locale": "tr-TR", 219 | "strings": { 220 | "keywords": "example", 221 | "description": "{!product-description}", 222 | "displayName": "{!secondary-display-name}", 223 | "solutionName": "{!primary-display-name}", 224 | "solutionDescription": "{!solution-description}" 225 | } 226 | }, 227 | { 228 | "locale": "zh-CN", 229 | "strings": { 230 | "keywords": "example", 231 | "description": "{!product-description}", 232 | "displayName": "{!secondary-display-name}", 233 | "solutionName": "{!primary-display-name}", 234 | "solutionDescription": "{!solution-description}" 235 | } 236 | }, 237 | { 238 | "locale": "zh-TW", 239 | "strings": { 240 | "keywords": "example", 241 | "description": "{!product-description}", 242 | "displayName": "{!secondary-display-name}", 243 | "solutionName": "{!primary-display-name}", 244 | "solutionDescription": "{!solution-description}" 245 | } 246 | } 247 | ] 248 | } 249 | --------------------------------------------------------------------------------