diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bd85744c4..ab2c2ef71 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,35 +1,49 @@ { - "name": "CLI devcontainer", - "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", - "features": { - "ghcr.io/devcontainers/features/dotnet": { - "version": "10.0", - "additionalVersions": ["8.0"] - }, - "ghcr.io/devcontainers/features/node": { - "version": "12" - }, - "ghcr.io/devcontainers/features/github-cli": {}, - "ghcr.io/nils-geistmann/devcontainers-features/zsh": { - "plugins": "git dotnet node npm" - } + "name": "CLI devcontainer", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "capAdd": ["SYS_PTRACE"], + "features": { + "ghcr.io/devcontainers/features/dotnet": { + "version": "10.0", + "additionalVersions": ["6.0", "8.0"] }, - "customizations": { - "vscode": { - "extensions": [ - "ms-dotnettools.csdevkit", - "mhutchie.git-graph", - "actboy168.tasks", - "esbenp.prettier-vscode", - "EditorConfig.EditorConfig", - "redhat.vscode-yaml", - "davidanson.vscode-markdownlint", - "github.vscode-github-actions" - ] - } + "ghcr.io/devcontainers/features/node": { + "version": "18", + "additionalVersions": ["20"] }, - "containerEnv": { - "NPM_CONFIG_MIN_RELEASE_AGE": "3" + "ghcr.io/devcontainers/features/github-cli": {}, + "ghcr.io/nils-geistmann/devcontainers-features/zsh": { + "plugins": "git dotnet node npm dotenv" }, - "postCreateCommand": "npm ci && echo \"alias 'cmf=/workspaces/cli/cmf-cli/bin/Debug/cmf'\" >> /home/$USER/.bashrc" + "ghcr.io/stuartleeks/dev-container-features/shell-history": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csdevkit", + "mhutchie.git-graph", + "actboy168.tasks", + "esbenp.prettier-vscode", + "EditorConfig.EditorConfig", + "redhat.vscode-yaml", + "davidanson.vscode-markdownlint", + "github.vscode-github-actions", + "FullStackSpider.visual-nuget" + ] + }, + "settings": { + "dotnet.solution.autoOpen": "src/cmf-cli.slnx", + "csharp.experimental.debug.hotReload": true, + "editor.formatOnSave": true, + "editor.rulers": [120], + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true + } + }, + "containerEnv": { + "DOTNET_CLI_TELEMETRY_OPTOUT": "1", + "NPM_CONFIG_MIN_RELEASE_AGE": "3", + "ZSH_DOTENV_PROMPT": "false" + }, + "postCreateCommand": "npm ci && echo \"alias 'cmf=/workspaces/cli/cmf-cli/bin/Debug/cmf'\" >> /home/$USER/.bashrc" } diff --git a/.github/agents/cmf-cli-dotnet.agent.md b/.github/agents/cmf-cli-dotnet.agent.md new file mode 100644 index 000000000..d3b8acd73 --- /dev/null +++ b/.github/agents/cmf-cli-dotnet.agent.md @@ -0,0 +1,79 @@ +--- +name: cmf-cli-dotnet +description: .NET/C# developer for the cmf-cli repository. Use this agent when implementing CLI commands, fixing C# bugs, writing tests, or refactoring code in core/, cmf-cli/, features/, or tests/. +tools: + - codebase + - editFiles + - fetch + - findTestFiles + - problems + - runCommands + - runTasks + - runTests + - search + - usages +--- + +You are a senior .NET/C# developer working exclusively on the **Critical Manufacturing CLI** (`cmf-cli` repository). + +## Repository Layout + +- `core/` – shared CLI infrastructure (base commands, utilities, services, constants) +- `cmf-cli/` – main executable (commands, handlers, builders, factories) +- `features/` – CLI feature implementations (src + test sub-folders) +- `tests/` – automated tests (MSTest + FluentAssertions + Moq) +- `docs/` – documentation (update when behaviour changes) + +Always explore the relevant folder before modifying code. Prefer existing abstractions in `core/` over creating new ones. + +## Skills + +Apply the **dotnet-best-practices** skill for all C# code you write or review. + +## C# Conventions + +- Follow existing namespace structure: `Cmf.CLI.{Feature}` or `Cmf.Common.CLI.{Area}` +- Use primary constructor syntax for dependency injection +- Use async/await for I/O and long-running tasks; return `Task` or `Task` +- Use `ResourceManager` for user-facing strings (see `CliMessages.resx` / `CoreMessages.resx`) +- Keep methods small and focused; avoid large classes +- Prefer `ArgumentNullException.ThrowIfNull` for guard clauses + +## CLI Command Design + +Every command must have: +- A clear `[CmfCommand]` attribute with description, examples, and parent binding +- Input argument/option validation with helpful error messages +- A corresponding test in `tests/Specs/` + +Follow the pattern in existing commands under `cmf-cli/Commands/`. + +## Testing Rules + +- Framework: **MSTest** with **FluentAssertions** assertions +- Pattern: **Arrange / Act / Assert** +- Mock dependencies with **Moq** +- Cover both success and failure scenarios, including null-argument validation +- Never break existing tests; update them when behaviour intentionally changes + +## Safety Constraints + +- Do NOT change licensing or publishing workflows +- Do NOT introduce breaking changes to existing CLI commands +- Do NOT remove commands without providing a migration path +- Do NOT add external NuGet dependencies without justification + +## Build & Validate + +Use the workspace **build** task (`dotnet build cmf-cli/cmf.csproj`) to verify changes compile. +Use the **runTests** tool or `dotnet test tests/tests.csproj` to validate test results. +Always check for compiler errors and warnings (`problems` tool) after editing. + +## Commit Messages + +Follow [Conventional Commits](https://www.conventionalcommits.org/): +- `feat(scope): description` for new features +- `fix(scope): description` for bug fixes +- `test(scope): description` for test additions +- `docs(scope): description` for documentation updates +- `refactor(scope): description` for refactors diff --git a/.github/agents/skills/dotnet-best-practices/SKILL.md b/.github/agents/skills/dotnet-best-practices/SKILL.md new file mode 100644 index 000000000..183d3beb1 --- /dev/null +++ b/.github/agents/skills/dotnet-best-practices/SKILL.md @@ -0,0 +1,85 @@ +--- +name: dotnet-best-practices +description: 'Ensure .NET/C# code meets best practices for the solution/project.' +--- + +# .NET/C# Best Practices + +Your task is to ensure .NET/C# code in ${selection} meets the best practices specific to this solution/project. This includes: + +## Documentation & Structure + +- Create comprehensive XML documentation comments for all public classes, interfaces, methods, and properties +- Include parameter descriptions and return value descriptions in XML comments +- Follow the established namespace structure: {Core|Console|App|Service}.{Feature} + +## Design Patterns & Architecture + +- Use primary constructor syntax for dependency injection (e.g., `public class MyClass(IDependency dependency)`) +- Implement the Command Handler pattern with generic base classes (e.g., `CommandHandler`) +- Use interface segregation with clear naming conventions (prefix interfaces with 'I') +- Follow the Factory pattern for complex object creation. + +## Dependency Injection & Services + +- Use constructor dependency injection with null checks via ArgumentNullException +- Register services with appropriate lifetimes (Singleton, Scoped, Transient) +- Use Microsoft.Extensions.DependencyInjection patterns +- Implement service interfaces for testability + +## Resource Management & Localization + +- Use ResourceManager for localized messages and error strings +- Separate LogMessages and ErrorMessages resource files +- Access resources via `_resourceManager.GetString("MessageKey")` + +## Async/Await Patterns + +- Use async/await for all I/O operations and long-running tasks +- Return Task or Task from async methods +- Use ConfigureAwait(false) where appropriate +- Handle async exceptions properly + +## Testing Standards + +- Use MSTest framework with FluentAssertions for assertions +- Follow AAA pattern (Arrange, Act, Assert) +- Use Moq for mocking dependencies +- Test both success and failure scenarios +- Include null parameter validation tests + +## Configuration & Settings + +- Use strongly-typed configuration classes with data annotations +- Implement validation attributes (Required, NotEmptyOrWhitespace) +- Use IConfiguration binding for settings +- Support appsettings.json configuration files + +## Semantic Kernel & AI Integration + +- Use Microsoft.SemanticKernel for AI operations +- Implement proper kernel configuration and service registration +- Handle AI model settings (ChatCompletion, Embedding, etc.) +- Use structured output patterns for reliable AI responses + +## Error Handling & Logging + +- Use structured logging with Microsoft.Extensions.Logging +- Include scoped logging with meaningful context +- Throw specific exceptions with descriptive messages +- Use try-catch blocks for expected failure scenarios + +## Performance & Security + +- Use C# 12+ features and .NET 8 optimizations where applicable +- Implement proper input validation and sanitization +- Use parameterized queries for database operations +- Follow secure coding practices for AI/ML operations + +## Code Quality + +- Ensure SOLID principles compliance +- Avoid code duplication through base classes and utilities +- Use meaningful names that reflect domain concepts +- Keep methods focused and cohesive +- Implement proper disposal patterns for resources diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 0d620b432..c518ca1d3 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -4,7 +4,6 @@ on: workflow_dispatch: push: branches: - - main - development paths-ignore: - 'features/**' @@ -20,7 +19,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12, 18] + node-version: [18, 20] steps: - uses: actions/checkout@v4 @@ -28,8 +27,8 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 6.0.x 8.0.x + 10.0.x - name: Setup Node ${{ matrix.node-version }} uses: actions/setup-node@v4 @@ -40,13 +39,13 @@ jobs: run: | dotnet build --configuration Release - - name: Test (Node 12) - if: matrix.node-version == 12 - run: dotnet test --configuration Release --no-build --no-restore --verbosity normal --filter "TestCategory!=Node18" --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults - - - name: Test (Node 18) + - name: Test ${{ matrix.node-version }} if: matrix.node-version == 18 - run: dotnet test --configuration Release --no-build --no-restore --verbosity normal --filter "TestCategory!=Node12" --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults + run: dotnet test --configuration Release --no-build --no-restore --verbosity normal --filter "TestCategory!=Node20" --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults + + - name: Test ${{ matrix.node-version }} + if: matrix.node-version == 20 + run: dotnet test --configuration Release --no-build --no-restore --verbosity normal --filter "TestCategory!=Node18" --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults - name: Merge Coverage Reports run: | diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index decc46894..09440968a 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -21,8 +21,8 @@ jobs: registry-url: https://registry.npmjs.org/ - uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' - - name: Install zip + dotnet-version: '10.0.x' + - name: install zip uses: montudor/action-zip@v0.1.0 - run: npm ci - run: npm run build:prod @@ -32,9 +32,6 @@ jobs: - name: Create artifact linux-x64 run: zip -X -r ../cmf-cli.linux-x64.zip . working-directory: dist/linux-x64 - - name: Create artifact osx-x64 - run: zip -X -r ../cmf-cli.osx-x64.zip . - working-directory: dist/osx-x64 - name: Publish win-x64 to release uses: JasonEtco/upload-to-release@master with: @@ -47,12 +44,6 @@ jobs: args: dist/cmf-cli.linux-x64.zip application/zip env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Publish osx-x64 to release - uses: JasonEtco/upload-to-release@master - with: - args: dist/cmf-cli.osx-x64.zip application/zip - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Get version from npm package id: package-version run: echo "version=$(node -p "require('./npm/package.json').version")" >> $GITHUB_OUTPUT @@ -60,8 +51,6 @@ jobs: run: curl -v --user "${{secrets.CRITICALMANUFACTURING_IO_USER}}:${{secrets.CRITICALMANUFACTURING_IO_TOKEN}}" --upload-file dist/cmf-cli.win-x64.zip https://criticalmanufacturing.io/repository/tools/cmf-cli.win-x64-${{ steps.package-version.outputs.version }}.zip - name: Upload linux-x64 to criticalmanufacturing.io run: curl -v --user "${{secrets.CRITICALMANUFACTURING_IO_USER}}:${{secrets.CRITICALMANUFACTURING_IO_TOKEN}}" --upload-file dist/cmf-cli.linux-x64.zip https://criticalmanufacturing.io/repository/tools/cmf-cli.linux-x64-${{ steps.package-version.outputs.version }}.zip - - name: Upload osx-x64 to criticalmanufacturing.io - run: curl -v --user "${{secrets.CRITICALMANUFACTURING_IO_USER}}:${{secrets.CRITICALMANUFACTURING_IO_TOKEN}}" --upload-file dist/cmf-cli.osx-x64.zip https://criticalmanufacturing.io/repository/tools/cmf-cli.osx-x64-${{ steps.package-version.outputs.version }}.zip - run: npm run publish if: "github.event.release.prerelease" env: diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index 66b60e905..e4fb8de10 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -40,12 +40,12 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 6.0.x 8.0.x + 10.0.x - name: Setup node versions uses: actions/setup-node@v4 with: - node-version: '12' + node-version: '18' - name: Check NuGet minimum package age run: npm run check:nuget:min-age - name: Install dependencies diff --git a/.gitignore b/.gitignore index 95f4bb0b9..bf60b00a2 100644 --- a/.gitignore +++ b/.gitignore @@ -367,4 +367,6 @@ npm/*.tgz #vendors !**/vendors/** -.DS_Store \ No newline at end of file +.DS_Store + +.env \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index 476fe8e37..90c9a7208 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -7,7 +7,7 @@ staged_files=$(git diff --cached --name-only) # Check if any changes are in cmf-cli, core, or tests folders if echo "$staged_files" | grep -qE "^(cmf-cli|core|tests)/"; then echo "Changes detected in cmf-cli, core, or tests folders. Running tests..." - dotnet test --filter "(TestCategory!=LongRunning)&(TestCategory!=Node12)" + dotnet test --filter "(TestCategory!=LongRunning)" else echo "No changes in cmf-cli, core, or tests folders. Skipping tests." fi diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 35017f5c2..6c49d638b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -37,6 +37,30 @@ "/consoleloggerparameters:NoSummary" ], "problemMatcher": "$msCompile" + }, + { + "label": "use-node", + "type": "shell", + "hide": true, + "command": ". /usr/local/share/nvm/nvm.sh && nvm use ${input:NodeVersion} && if [ \"${input:NodeVersion}\" = \"20\" ]; then echo \"Node18\" > /tmp/TEST_CATEGORY; else echo \"Node20\" > /tmp/TEST_CATEGORY; fi" + }, + { + "label": "integration-tests", + "type": "shell", + "command": "dotnet test --configuration Release -verbosity diagnostic", + "dependsOn": "use-node" + } + ], + "inputs": [ + { + "id": "NodeVersion", + "type": "pickString", + "description": "Select Node.js version", + "options": [ + "18", + "20" + ], + "default": "18" } ] } \ No newline at end of file diff --git a/cmf-cli.sln b/cmf-cli.sln deleted file mode 100644 index 6619a5498..000000000 --- a/cmf-cli.sln +++ /dev/null @@ -1,42 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.3.32929.385 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmf", "cmf-cli\cmf.csproj", "{992E16A7-340F-42E4-9281-F3759D8E73FB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{81DA6013-EDAA-4629-B5CC-EC2989AE3613}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tests", "tests\tests.csproj", "{C9C222C5-6236-4991-B3CF-6289E2ACBF09}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "core", "core\core.csproj", "{BF10AAE5-ACB7-47FD-9C85-F0AAEF1A7820}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {992E16A7-340F-42E4-9281-F3759D8E73FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {992E16A7-340F-42E4-9281-F3759D8E73FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {992E16A7-340F-42E4-9281-F3759D8E73FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {992E16A7-340F-42E4-9281-F3759D8E73FB}.Release|Any CPU.Build.0 = Release|Any CPU - {C9C222C5-6236-4991-B3CF-6289E2ACBF09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9C222C5-6236-4991-B3CF-6289E2ACBF09}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9C222C5-6236-4991-B3CF-6289E2ACBF09}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9C222C5-6236-4991-B3CF-6289E2ACBF09}.Release|Any CPU.Build.0 = Release|Any CPU - {BF10AAE5-ACB7-47FD-9C85-F0AAEF1A7820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BF10AAE5-ACB7-47FD-9C85-F0AAEF1A7820}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BF10AAE5-ACB7-47FD-9C85-F0AAEF1A7820}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BF10AAE5-ACB7-47FD-9C85-F0AAEF1A7820}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {992BC2A0-4206-4E1E-90FB-CD17A5897017} - EndGlobalSection -EndGlobal diff --git a/cmf-cli.slnx b/cmf-cli.slnx new file mode 100644 index 000000000..63f28fa6b --- /dev/null +++ b/cmf-cli.slnx @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/cmf-cli/Commands/BaseCommand.cs b/cmf-cli/Commands/BaseCommand.cs index 8b7742a8b..38a5f4e55 100644 --- a/cmf-cli/Commands/BaseCommand.cs +++ b/cmf-cli/Commands/BaseCommand.cs @@ -108,7 +108,7 @@ public static void AddPluginCommands(Command command) var cmdInstance = new Command(commandPlugin.Key); var commandHandler = new PluginCommand(commandPlugin.Key, commandPlugin.Value); commandHandler.Configure(cmdInstance); - command.AddCommand(cmdInstance); + command.Add(cmdInstance); } } } diff --git a/cmf-cli/Commands/LayerTemplateCommand.cs b/cmf-cli/Commands/LayerTemplateCommand.cs index 8f3d3290a..03b2b5abf 100644 --- a/cmf-cli/Commands/LayerTemplateCommand.cs +++ b/cmf-cli/Commands/LayerTemplateCommand.cs @@ -5,9 +5,9 @@ using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -55,15 +55,24 @@ protected LayerTemplateCommand(string commandName, PackageType packageType, IFil /// base command public override void Configure(Command cmd) { - GetBaseCommandConfig(cmd); - cmd.Handler = CommandHandler.Create>(Execute); + var (workingDirArg, versionOpt) = GetBaseCommandConfig(cmd); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArg); + var version = parseResult.GetValue(versionOpt); + + Execute(workingDir, version, null); + return Task.FromResult(0); + }); } /// /// Injects the base arguments and options into the command, required for layer commands /// /// base command - protected void GetBaseCommandConfig(Command cmd) + /// Tuple with the workingDir argument and version option for use in SetAction + protected (Argument, Option) GetBaseCommandConfig(Command cmd) { var nearestRootPackage = FileSystemUtilities.GetPackageRootByType( this.fileSystem.Directory.GetCurrentDirectory(), @@ -71,19 +80,22 @@ protected void GetBaseCommandConfig(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestRootPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); - cmd.AddOption(new Option( - aliases: new[] { "--version" }, - description: "Package Version", - getDefaultValue: () => "1.0.0" - )); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestRootPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestRootPackage?.FullName) + }; + cmd.Add(workingDirArgument); + + var versionOption = new Option("--version") + { + Description = "Package Version", + DefaultValueFactory = _ => "1.0.0" + }; + cmd.Add(versionOption); + + return (workingDirArgument, versionOption); } protected (string, string) GetOrganizationAndProductFromProjectConfig() diff --git a/cmf-cli/Commands/assemble/AssembleCommand.cs b/cmf-cli/Commands/assemble/AssembleCommand.cs index 0f9a922f0..d2e361650 100644 --- a/cmf-cli/Commands/assemble/AssembleCommand.cs +++ b/cmf-cli/Commands/assemble/AssembleCommand.cs @@ -9,9 +9,9 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -54,34 +54,52 @@ public AssembleCommand(IFileSystem fileSystem) : base(fileSystem) { } /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, "."), - isDefault: true) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + DefaultValueFactory = _ => Parse(null, "."), + CustomParser = argResult => Parse(argResult, ".") + }; + cmd.Add(workingDirArgument); - cmd.AddOption(new Option( - aliases: new string[] { "-o", "--outputDir" }, - parseArgument: argResult => Parse(argResult, "Assemble"), - isDefault: true, - description: "Output directory for assembled package")); + var outputDirOption = new Option("--outputDir", "-o") + { + Description = "Output directory for assembled package", + DefaultValueFactory = _ => Parse(null, "Assemble"), + CustomParser = argResult => Parse(argResult, "Assemble") + }; + cmd.Add(outputDirOption); - cmd.AddOption(new Option( - aliases: new string[] { "--cirepo" }, - description: "Repository where Continuous Integration packages are located (url or folder)")); + var ciRepoOption = new Option("--cirepo") + { + Description = "Repository where Continuous Integration packages are located (url or folder)" + }; + cmd.Add(ciRepoOption); - cmd.AddOption(new Option( - aliases: new string[] { "-r", "--repos", "--repo" }, - description: "Repository or repositories where published dependencies are located (url or folder)")); + var reposOption = new Option("--repos", "-r", "--repo") + { + Description = "Repository or repositories where published dependencies are located (url or folder)" + }; + cmd.Add(reposOption); - cmd.AddOption(new Option( - aliases: new string[] { "--includeTestPackages" }, - description: "Include test packages on assemble")); + var includeTestPackagesOption = new Option("--includeTestPackages") + { + Description = "Include test packages on assemble" + }; + cmd.Add(includeTestPackagesOption); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + var outputDir = parseResult.GetValue(outputDirOption); + var ciRepo = parseResult.GetValue(ciRepoOption); + var repos = parseResult.GetValue(reposOption); + var includeTestPackages = parseResult.GetValue(includeTestPackagesOption); + + Execute(workingDir, outputDir, ciRepo, repos, includeTestPackages); + return Task.FromResult(0); + }); } /// @@ -366,4 +384,4 @@ internal void HandleAppPkg(IDirectoryInfo outputDir, CmfPackage cmfPackage) #endregion } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/build/BuildCommand.cs b/cmf-cli/Commands/build/BuildCommand.cs index 84360400f..6668a762a 100644 --- a/cmf-cli/Commands/build/BuildCommand.cs +++ b/cmf-cli/Commands/build/BuildCommand.cs @@ -6,8 +6,8 @@ using Cmf.CLI.Utilities; using Microsoft.Extensions.DependencyInjection; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -45,21 +45,30 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - cmd.AddArgument(new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true) + + var packagePathArgument = new Argument("packagePath") { - Description = "Package Path" - }); + Description = "Package Path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) + }; + cmd.Add(packagePathArgument); + + var testOption = new Option("--test") + { + Description = "Build and Run Unit Tests", + DefaultValueFactory = _ => false + }; + cmd.Add(testOption); - cmd.AddOption(new Option( - aliases: new[] { "--test" }, - description: "Build and Run Unit Tests", - getDefaultValue: () => false - )); + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + var test = parseResult.GetValue(testOption); - cmd.Handler = CommandHandler.Create(Execute); + Execute(pkgPath, test); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/build/GenerateBasedOnTemplatesCommand.cs b/cmf-cli/Commands/build/GenerateBasedOnTemplatesCommand.cs index a2da89e04..0533c1e82 100644 --- a/cmf-cli/Commands/build/GenerateBasedOnTemplatesCommand.cs +++ b/cmf-cli/Commands/build/GenerateBasedOnTemplatesCommand.cs @@ -1,11 +1,11 @@ using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO; using System.IO.Abstractions; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Cmf.CLI.Constants; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; @@ -34,16 +34,21 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - var arg = new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true) + + var packagePathArgument = new Argument("packagePath") { - Description = "Package Path" + Description = "Package Path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) }; + cmd.Add(packagePathArgument); - cmd.AddArgument(arg); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + Execute(pkgPath); + return Task.FromResult(0); + }); } /// @@ -59,7 +64,7 @@ public void Execute(IDirectoryInfo packagePath) var helpRoot = FileSystemUtilities.GetPackageRootByType(packagePath.FullName, PackageType.Help, this.fileSystem).FullName; var project = ExecutionContext.Instance.ProjectConfig.Tenant; - var helpPackagesRoot = (mesVersion.Major > 9) ? this.fileSystem.Path.Join(helpRoot, "projects") : this.fileSystem.Path.Join(helpRoot, "src", "packages"); + var helpPackagesRoot = this.fileSystem.Path.Join(helpRoot, "projects"); var helpPackages = this.fileSystem.Directory.GetDirectories(helpPackagesRoot); var pkgName = CmfPackage.Load(this.fileSystem.FileInfo.New(this.fileSystem.Path.Join(helpRoot, CliConstants.CmfPackageFileName))).PackageId.ToLowerInvariant(); foreach (var helpPackagePath in helpPackages) @@ -79,7 +84,7 @@ public void Execute(IDirectoryInfo packagePath) } } - Generate(helpPackagePath, useLegacyFormat ? project : ( (mesVersion.Major > 9) ? pkgName.Replace(".", "-").ToLowerInvariant() : pkgName)); + Generate(helpPackagePath, useLegacyFormat ? project : pkgName.Replace(".", "-").ToLowerInvariant()); } } diff --git a/cmf-cli/Commands/build/GenerateMenuItemsCommand.cs b/cmf-cli/Commands/build/GenerateMenuItemsCommand.cs index 6675e7184..bf949e4b9 100644 --- a/cmf-cli/Commands/build/GenerateMenuItemsCommand.cs +++ b/cmf-cli/Commands/build/GenerateMenuItemsCommand.cs @@ -1,12 +1,12 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO; using System.IO.Abstractions; using System.Linq; using System.Text.Json; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Enums; @@ -43,16 +43,21 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - var arg = new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true) + + var packagePathArgument = new Argument("packagePath") { - Description = "Package Path" + Description = "Package Path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) }; + cmd.Add(packagePathArgument); - cmd.AddArgument(arg); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + Execute(pkgPath); + return Task.FromResult(0); + }); } /// @@ -78,8 +83,8 @@ public void Execute(IDirectoryInfo packagePath) var regex = new Regex("\"?id\"?:\\s+[\"'](.*)[\"']"); // match for menu item IDs - var packagesDir = (mesVersion.Major > 9) ? this.fileSystem.DirectoryInfo.New(this.fileSystem.Path.Join(helpRoot, "projects")) : this.fileSystem.DirectoryInfo.New(this.fileSystem.Path.Join(helpRoot, "src", "packages")); - var helpPackages = packagesDir.GetDirectories("cmf.docs.area.*".Replace(".", (mesVersion.Major > 9) ? "-" : ".")); + var packagesDir = this.fileSystem.DirectoryInfo.New(this.fileSystem.Path.Join(helpRoot, "projects")); + var helpPackages = packagesDir.GetDirectories("cmf.docs.area.*".Replace(".", "-")); void GetMetadataFromFolder(IDirectoryInfo current, List metadata, IDirectoryInfo parent = null) { diff --git a/cmf-cli/Commands/build/IoTLibCommand.cs b/cmf-cli/Commands/build/IoTLibCommand.cs index 58d12366b..83a08a8c4 100644 --- a/cmf-cli/Commands/build/IoTLibCommand.cs +++ b/cmf-cli/Commands/build/IoTLibCommand.cs @@ -5,9 +5,9 @@ using Cmf.CLI.Core.Objects; using Cmf.CLI.Utilities; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New { @@ -40,16 +40,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestRootPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestRootPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestRootPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// @@ -59,37 +63,30 @@ public override void Configure(Command cmd) /// package version public void Execute(IDirectoryInfo workingDir) { - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major > 9) - { - IFileInfo cmfpackageFile = this.fileSystem.FileInfo.New($"{workingDir}/{CliConstants.CmfPackageFileName}"); - var cmfPackage = CmfPackage.Load(cmfpackageFile, setDefaultValues: true, this.fileSystem); + IFileInfo cmfpackageFile = this.fileSystem.FileInfo.New($"{workingDir}/{CliConstants.CmfPackageFileName}"); + var cmfPackage = CmfPackage.Load(cmfpackageFile, setDefaultValues: true, this.fileSystem); - if (cmfPackage.PackageType != PackageType.IoT) - { - throw new CliException(CliMessages.CommandIsOnlyValidForPackageOfTypeIoT); - } + if (cmfPackage.PackageType != PackageType.IoT) + { + throw new CliException(CliMessages.CommandIsOnlyValidForPackageOfTypeIoT); + } - var listOfLibs = workingDir.EnumerateDirectories().FirstOrDefault(dir => dir.Name == "dist").EnumerateDirectories(); - cmfPackage.RelatedPackages?.ForEach(relatedPackage => + var listOfLibs = workingDir.EnumerateDirectories().FirstOrDefault(dir => dir.Name == "dist").EnumerateDirectories(); + cmfPackage.RelatedPackages?.ForEach(relatedPackage => + { + if (relatedPackage.CmfPackage.GetFileInfo().Directory.GetFile(CliConstants.AngularJson) != null) { - if (relatedPackage.CmfPackage.GetFileInfo().Directory.GetFile(CliConstants.AngularJson) != null) + foreach (var lib in listOfLibs) { - foreach (var lib in listOfLibs) + new NPMCommand() { - new NPMCommand() - { - DisplayName = "npm link dist", - Args = new string[] { "link", lib.FullName }, - WorkingDirectory = relatedPackage.CmfPackage.GetFileInfo().Directory - }.Exec(); - } + DisplayName = "npm link dist", + Args = new string[] { "link", lib.FullName }, + WorkingDirectory = relatedPackage.CmfPackage.GetFileInfo().Directory + }.Exec(); } - }); - } - else - { - throw new CliException(string.Format(CliMessages.InvalidVersionForCommand, "10")); - } + } + }); } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/build/business/ValidateStartAndEndMethodsCommand.cs b/cmf-cli/Commands/build/business/ValidateStartAndEndMethodsCommand.cs index 25dafc685..166409820 100644 --- a/cmf-cli/Commands/build/business/ValidateStartAndEndMethodsCommand.cs +++ b/cmf-cli/Commands/build/business/ValidateStartAndEndMethodsCommand.cs @@ -4,9 +4,9 @@ using Cmf.CLI.Core.Attributes; using Microsoft.Extensions.DependencyInjection; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Text; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.build.business; @@ -31,22 +31,27 @@ public ValidateStartAndEndMethodsCommand(IFileSystem fileSystem) : base(fileSyst /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "solutionPath", - description: "The solution path" - )); + var solutionPathArgument = new Argument("solutionPath") + { + Description = "The solution path" + }; + cmd.Add(solutionPathArgument); - var filesArgument = new Argument( - name: "files", - description: "The files to validate" - ) + var filesArgument = new Argument("files") { + Description = "The files to validate", Arity = ArgumentArity.ZeroOrMore }; + cmd.Add(filesArgument); - cmd.AddArgument(filesArgument); + cmd.SetAction((parseResult, cancellationToken) => + { + var solutionPath = parseResult.GetValue(solutionPathArgument); + var files = parseResult.GetValue(filesArgument); - cmd.Handler = CommandHandler.Create(Execute); + Execute(solutionPath, files); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/build/html/ExtractI18nCommand.cs b/cmf-cli/Commands/build/html/ExtractI18nCommand.cs index d75149014..c678e5cb2 100644 --- a/cmf-cli/Commands/build/html/ExtractI18nCommand.cs +++ b/cmf-cli/Commands/build/html/ExtractI18nCommand.cs @@ -1,8 +1,7 @@ using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.Diagnostics; -using System.IO; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Constants; using Cmf.CLI.Core; @@ -52,16 +51,21 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - var arg = new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true) + + var packagePathArgument = new Argument("packagePath") { - Description = "Package Path" + Description = "Package Path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) }; + cmd.Add(packagePathArgument); - cmd.AddArgument(arg); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + Execute(pkgPath); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/build/html/LinkLBOsCommand.cs b/cmf-cli/Commands/build/html/LinkLBOsCommand.cs index 171cbe801..20b0c363b 100644 --- a/cmf-cli/Commands/build/html/LinkLBOsCommand.cs +++ b/cmf-cli/Commands/build/html/LinkLBOsCommand.cs @@ -1,7 +1,7 @@ using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.Diagnostics; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Constants; using Cmf.CLI.Core; @@ -25,16 +25,21 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - var arg = new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true) + + var packagePathArgument = new Argument("packagePath") { - Description = "Package Path" + Description = "Package Path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) }; + cmd.Add(packagePathArgument); - cmd.AddArgument(arg); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + Execute(pkgPath); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/build/html/LocalizeCommand.cs b/cmf-cli/Commands/build/html/LocalizeCommand.cs index fb2649217..f69e9c010 100644 --- a/cmf-cli/Commands/build/html/LocalizeCommand.cs +++ b/cmf-cli/Commands/build/html/LocalizeCommand.cs @@ -1,7 +1,7 @@ using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.Diagnostics; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Constants; using Cmf.CLI.Core.Attributes; @@ -31,16 +31,21 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - var arg = new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true) + + var packagePathArgument = new Argument("packagePath") { - Description = "Package Path" + Description = "Package Path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) }; + cmd.Add(packagePathArgument); - cmd.AddArgument(arg); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + Execute(pkgPath); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/bump/BumpCommand.cs b/cmf-cli/Commands/bump/BumpCommand.cs index 6dd2b47bb..4b87dff55 100644 --- a/cmf-cli/Commands/bump/BumpCommand.cs +++ b/cmf-cli/Commands/bump/BumpCommand.cs @@ -7,9 +7,9 @@ using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -26,29 +26,49 @@ public class BumpCommand : BaseCommand /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "packagePath", - getDefaultValue: () => { return new("."); }, - description: "Package path")); - - cmd.AddOption(new Option( - aliases: new string[] { "-v", "--version" }, - description: "Will bump all versions to the version specified")); - - cmd.AddOption(new Option( - aliases: new string[] { "-b", "--buildNr" }, - description: "Will add this version next to the version (v-b)")); - - cmd.AddOption(new Option( - aliases: new string[] { "-p", "--preRelease" }, - description: "Will add this version as pre-release version (v-p)")); - - cmd.AddOption(new Option( - aliases: new string[] { "-r", "--root" }, - description: "Will bump only versions under a specific root folder (i.e. 1.0.0)")); + var packagePathArgument = new Argument("packagePath") + { + Description = "Package path", + DefaultValueFactory = _ => new DirectoryInfo(".") + }; + cmd.Add(packagePathArgument); + + var versionOption = new Option("--version", "-v") + { + Description = "Will bump all versions to the version specified" + }; + cmd.Add(versionOption); + + var buildNrOption = new Option("--buildNr", "-b") + { + Description = "Will add this version next to the version (v-b)" + }; + cmd.Add(buildNrOption); + + var preReleaseOption = new Option("--preRelease", "-p") + { + Description = "Will add this version as pre-release version (v-p)" + }; + cmd.Add(preReleaseOption); + + var rootOption = new Option("--root", "-r") + { + Description = "Will bump only versions under a specific root folder (i.e. 1.0.0)" + }; + cmd.Add(rootOption); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var packagePath = parseResult.GetValue(packagePathArgument); + var version = parseResult.GetValue(versionOption); + var buildNr = parseResult.GetValue(buildNrOption); + var preRelease = parseResult.GetValue(preReleaseOption); + var root = parseResult.GetValue(rootOption); + + Execute(packagePath, version, buildNr, preRelease, root); + return Task.FromResult(0); + }); } /// @@ -57,6 +77,7 @@ public override void Configure(Command cmd) /// The package path. /// The version. /// The version for build Nr. + /// The pre-release version. /// The root. /// /// diff --git a/cmf-cli/Commands/bump/BumpIoTConfigurationCommand.cs b/cmf-cli/Commands/bump/BumpIoTConfigurationCommand.cs index 0085e12f5..fd7cac25b 100644 --- a/cmf-cli/Commands/bump/BumpIoTConfigurationCommand.cs +++ b/cmf-cli/Commands/bump/BumpIoTConfigurationCommand.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Objects; @@ -26,65 +26,103 @@ public class BumpIoTConfigurationCommand : BumpCommand /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "path", - parse: (argResult) => Parse(argResult, "."), - isDefault: true - ) + var pathArgument = new Argument("path") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, "."), + DefaultValueFactory = _ => Parse(null, ".") + }; + cmd.Add(pathArgument); + + var versionOption = new Option("--version", "-v") + { + Description = "Will bump all versions to the version specified" + }; + cmd.Add(versionOption); + + var buildNrVersionOption = new Option("--buildNrVersion", "-b") + { + Description = "Will add this version next to the version (v-b)" + }; + cmd.Add(buildNrVersionOption); + + var preReleaseVersionOption = new Option("--preReleaseVersion", "-p") + { + Description = "Will add this version as pre-release version (v-p)" + }; + cmd.Add(preReleaseVersionOption); + + var masterDataOption = new Option("--masterData", "-md") + { + Description = "Will bump IoT MasterData version (only applies to .json)", + DefaultValueFactory = _ => false + }; + cmd.Add(masterDataOption); + + var iotOption = new Option("--iot", "-iot") + { + Description = "Will bump IoT Automation Workflows", + DefaultValueFactory = _ => true + }; + cmd.Add(iotOption); + + var packageNamesOption = new Option("--packageNames", "-pckNames") + { + Description = "Packages to be bumped" + }; + cmd.Add(packageNamesOption); + + var rootOption = new Option("--root", "-r") + { + Description = "Specify root to specify version where we want to apply the bump" + }; + cmd.Add(rootOption); + + var groupOption = new Option("--group", "-g") + { + Description = "Group of workflows to change, typically they are grouped by Automation Manager" + }; + cmd.Add(groupOption); + + var workflowNameOption = new Option("--workflowName", "-wkflName") + { + Description = "Specific workflow to be bumped" + }; + cmd.Add(workflowNameOption); + + var isToTagOption = new Option("--isToTag", "-isToTag") + { + Description = "Instead of replacing the version will add -$version", + DefaultValueFactory = _ => false + }; + cmd.Add(isToTagOption); - cmd.AddOption(new Option( - aliases: new string[] { "-v", "--version" }, - description: "Will bump all versions to the version specified")); - - cmd.AddOption(new Option( - aliases: new string[] { "-b", "--buildNrVersion" }, - description: "Will add this version next to the version (v-b)")); - - cmd.AddOption(new Option( - aliases: new string[] { "-p", "--preReleaseVersion" }, - description: "Will add this version as pre-release version (v-p)")); - - cmd.AddOption(new Option( - aliases: new string[] { "-md", "--masterData" }, - getDefaultValue: () => { return false; }, - description: "Will bump IoT MasterData version (only applies to .json)")); - - cmd.AddOption(new Option( - aliases: new string[] { "-iot", "--iot" }, - getDefaultValue: () => { return true; }, - description: "Will bump IoT Automation Workflows")); - - cmd.AddOption(new Option( - aliases: new string[] { "-pckNames", "--packageNames" }, - description: "Packages to be bumped")); - - cmd.AddOption(new Option( - aliases: new string[] { "-r", "--root" }, - description: "Specify root to specify version where we want to apply the bump")); - - cmd.AddOption(new Option( - aliases: new string[] { "-g", "--group" }, - description: "Group of workflows to change, typically they are grouped by Automation Manager")); - - cmd.AddOption(new Option( - aliases: new string[] { "-wkflName", "--workflowName" }, - description: "Specific workflow to be bumped")); - - cmd.AddOption(new Option( - aliases: new string[] { "-isToTag", "--isToTag" }, - getDefaultValue: () => { return false; }, - description: "Instead of replacing the version will add -$version")); - - cmd.AddOption(new Option( - aliases: new string[] { "-mdCustomization", "--mdCustomization" }, - getDefaultValue: () => { return false; }, - description: "Instead of replacing the version will add -$version")); + var mdCustomizationOption = new Option("--mdCustomization", "-mdCustomization") + { + Description = "Instead of replacing the version will add -$version", + DefaultValueFactory = _ => false + }; + cmd.Add(mdCustomizationOption); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var path = parseResult.GetValue(pathArgument); + var version = parseResult.GetValue(versionOption); + var buildNr = parseResult.GetValue(buildNrVersionOption); + var preReleaseVersion = parseResult.GetValue(preReleaseVersionOption); + var isToBumpMasterdata = parseResult.GetValue(masterDataOption); + var isToBumpIoT = parseResult.GetValue(iotOption); + var packageNames = parseResult.GetValue(packageNamesOption); + var root = parseResult.GetValue(rootOption); + var group = parseResult.GetValue(groupOption); + var workflowName = parseResult.GetValue(workflowNameOption); + var isToTag = parseResult.GetValue(isToTagOption); + var onlyMdCustomization = parseResult.GetValue(mdCustomizationOption); + + Execute(path, version, buildNr, preReleaseVersion, isToBumpMasterdata, isToBumpIoT, packageNames, root, group, workflowName, isToTag, onlyMdCustomization); + return Task.FromResult(0); + }); } /// @@ -92,8 +130,8 @@ public override void Configure(Command cmd) /// /// The package directory. /// The version. - /// - /// + /// + /// /// if set to true [is to bump masterdata]. /// if set to true [is to bump io t]. /// The package names. @@ -102,9 +140,9 @@ public override void Configure(Command cmd) /// Name of the workflow. /// if set to true [is to tag]. /// if set to true [only md customization]. - /// + /// /// - public void Execute(IDirectoryInfo path, string version, string buildNrVersion, string preReleaseVersion, bool isToBumpMasterdata, bool isToBumpIoT, string packageNames, string root, string group, string workflowName, bool isToTag, bool onlyMdCustomization) + public void Execute(IDirectoryInfo path, string version, string buildNrVersion, string preReleaseVersion, bool isToBumpMasterdata, bool isToBumpIoT, string packageNames, string root, string group, string workflowName, bool isToTag, bool onlyMdCustomization) { using var activity = ExecutionContext.ServiceProvider?.GetService()?.StartExtendedActivity(this.GetType().Name); @@ -121,13 +159,13 @@ public void Execute(IDirectoryInfo path, string version, string buildNrVersion, automationWorkflowDirectories = automationWorkflowDirectories.Where(awf => awf.Contains(root))?.ToList(); } - if (!string.IsNullOrEmpty(buildNrVersion) && !string.IsNullOrEmpty(preReleaseVersion)) - { - throw new CliException(string.Format(CliMessages.MutuallyExclusiveProperties, "buildNrVersion, preReleaseVersion")); - } - - string versionSuffix = !string.IsNullOrEmpty(buildNrVersion) ? buildNrVersion : preReleaseVersion; - + if (!string.IsNullOrEmpty(buildNrVersion) && !string.IsNullOrEmpty(preReleaseVersion)) + { + throw new CliException(string.Format(CliMessages.MutuallyExclusiveProperties, "buildNrVersion, preReleaseVersion")); + } + + string versionSuffix = !string.IsNullOrEmpty(buildNrVersion) ? buildNrVersion : preReleaseVersion; + foreach (string automationWorkflowDirectory in automationWorkflowDirectories) { #region Bump AutomationWorkflow @@ -142,7 +180,7 @@ public void Execute(IDirectoryInfo path, string version, string buildNrVersion, groups = groups.Where(gr => gr.Contains(group)).ToList(); } - groups.ForEach(group => IoTUtilities.BumpWorkflowFiles(group, version, versionSuffix, workflowName, packageNames, this.fileSystem)); + groups.ForEach(group => IoTUtilities.BumpWorkflowFiles(group, version, versionSuffix, workflowName, packageNames, this.fileSystem)); } #endregion Bump AutomationWorkflow @@ -151,7 +189,7 @@ public void Execute(IDirectoryInfo path, string version, string buildNrVersion, if (isToBumpMasterdata) { - IoTUtilities.BumpIoTMasterData(automationWorkflowDirectory, version, versionSuffix, this.fileSystem, onlyCustomization: onlyMdCustomization); + IoTUtilities.BumpIoTMasterData(automationWorkflowDirectory, version, versionSuffix, this.fileSystem, onlyCustomization: onlyMdCustomization); } #endregion Bump IoT Masterdata diff --git a/cmf-cli/Commands/bump/BumpIoTCustomizationCommand.cs b/cmf-cli/Commands/bump/BumpIoTCustomizationCommand.cs index 931a9b9a3..d316f847e 100644 --- a/cmf-cli/Commands/bump/BumpIoTCustomizationCommand.cs +++ b/cmf-cli/Commands/bump/BumpIoTCustomizationCommand.cs @@ -1,5 +1,4 @@ using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using Cmf.CLI.Constants; using Cmf.CLI.Core.Attributes; @@ -7,6 +6,7 @@ using Cmf.CLI.Core.Objects; using Cmf.CLI.Utilities; using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -23,37 +23,57 @@ public class BumpIoTCustomizationCommand : BaseCommand /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, "."), - isDefault: true - ) + var pathArgument = new Argument("path") { - Description = "Package Path" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, "."), + DefaultValueFactory = _ => Parse(null, ".") + }; + cmd.Add(pathArgument); - cmd.AddOption(new Option( - aliases: new string[] { "-v", "--version" }, - description: "Will bump all versions to the version specified")); + var versionOption = new Option("--version", "-v") + { + Description = "Will bump all versions to the version specified" + }; + cmd.Add(versionOption); - cmd.AddOption(new Option( - aliases: new string[] { "-b", "--buildNrVersion" }, - description: "Will add this version next to the version (v-b)")); + var buildNrVersionOption = new Option("--buildNrVersion", "-b") + { + Description = "Will add this version next to the version (v-b)" + }; + cmd.Add(buildNrVersionOption); + + var preReleaseVersionOption = new Option("--preReleaseVersion", "-p") + { + Description = "Will add this version as pre-release version (v-p)" + }; + cmd.Add(preReleaseVersionOption); - cmd.AddOption(new Option( - aliases: new string[] { "-p", "--preReleaseVersion" }, - description: "Will add this version as pre-release version (v-p)")); + var packageNamesOption = new Option("--packageNames", "-pckNames") + { + Description = "Packages to be bumped" + }; + cmd.Add(packageNamesOption); - cmd.AddOption(new Option( - aliases: new string[] { "-pckNames", "--packageNames" }, - description: "Packages to be bumped")); + var isToTagOption = new Option("--isToTag", "-isToTag") + { + Description = "Instead of replacing the version will add -$version", + DefaultValueFactory = _ => false + }; + cmd.Add(isToTagOption); - cmd.AddOption(new Option( - aliases: new string[] { "-isToTag", "--isToTag" }, - getDefaultValue: () => { return false; }, - description: "Instead of replacing the version will add -$version")); + cmd.SetAction((parseResult, cancellationToken) => + { + var path = parseResult.GetValue(pathArgument); + var version = parseResult.GetValue(versionOption); + var buildNr = parseResult.GetValue(buildNrVersionOption); + var preReleaseVersion = parseResult.GetValue(preReleaseVersionOption); + var packageNames = parseResult.GetValue(packageNamesOption); + var isToTag = parseResult.GetValue(isToTagOption); - cmd.Handler = CommandHandler.Create(Execute); + Execute(path, version, buildNr, preReleaseVersion, packageNames, isToTag); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/init/InitCommand.cs b/cmf-cli/Commands/init/InitCommand.cs index 98d3c4e19..92a8b5361 100644 --- a/cmf-cli/Commands/init/InitCommand.cs +++ b/cmf-cli/Commands/init/InitCommand.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.CommandLine.Parsing; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; using Cmf.CLI.Constants; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; @@ -88,167 +88,266 @@ public InitCommand(IFileSystem fileSystem) : base("init", fileSystem) /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "projectName", - parse: (argResult) => ParseArgument(argResult) - )); - cmd.AddArgument(new Argument( - name: "rootPackageName", - parse: (argResult) => ParseArgument(argResult, "Cmf.Custom.Package"), - isDefault: true - )); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => ParseArgument(argResult, "."), - isDefault: true - ) - { - Description = "Working Directory" - }); - cmd.AddOption(new Option( - aliases: new[] { "--version" }, - description: "Package Version", - getDefaultValue: () => "1.0.0" - )); - cmd.AddOption(new Option( - aliases: new[] { "-c", "--config" }, - parseArgument: argResult => Parse(argResult), - isDefault: true, - description: "Configuration file exported from Setup" - ) { IsRequired = true }); - cmd.AddOption(new Option( - aliases: ["--appConfig"], - parseArgument: argResult => Parse(argResult), - isDefault: true, - description: "App Configuration file" - ) { IsRequired = false }); - cmd.AddOption(new Option( - aliases: new[] { "-t", "--repositoryType" }, - getDefaultValue: () => CliConstants.DefaultRepositoryType, - description: "The type of repository we should initialize. Are we customizing MES or creating a new Application?" - ) { IsRequired = true }); + var projectNameArgument = new Argument("projectName") + { + CustomParser = argResult => ParseArgument(argResult) + }; + cmd.Add(projectNameArgument); + + var rootPackageNameArgument = new Argument("rootPackageName") + { + CustomParser = argResult => ParseArgument(argResult, "Cmf.Custom.Package"), + DefaultValueFactory = _ => "Cmf.Custom.Package" + }; + cmd.Add(rootPackageNameArgument); + + var workingDirArgument = new Argument("workingDir") + { + Description = "Working Directory", + CustomParser = argResult => ParseArgument(argResult, "."), + DefaultValueFactory = _ => ParseArgument(null, ".") + }; + cmd.Add(workingDirArgument); + + var versionOption = new Option("--version") + { + Description = "Package Version", + DefaultValueFactory = _ => "1.0.0" + }; + cmd.Add(versionOption); + + var configOption = new Option("--config", "-c") + { + Description = "Configuration file exported from Setup", + Required = true, + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(configOption); + + var appConfigOption = new Option("--appConfig") + { + Description = "App Configuration file", + Required = false, + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(appConfigOption); + + var repositoryTypeOption = new Option("--repositoryType", "-t") + { + Description = "The type of repository we should initialize. Are we customizing MES or creating a new Application?", + DefaultValueFactory = _ => CliConstants.DefaultRepositoryType, + Required = true + }; + cmd.Add(repositoryTypeOption); // template-time options. These are all mandatory - cmd.AddOption(new Option( - aliases: new[] { "--baseVersion", "--MESVersion" }, - description: "Target CM framework/MES version" - ) { IsRequired = true }); - cmd.AddOption(new Option( - aliases: new[] { "--DevTasksVersion" }, - description: "Critical Manufacturing dev-tasks version. Only required if you are targeting a version lower than v10." - ) { IsRequired = false }); - cmd.AddOption(new Option( - aliases: new[] { "--HTMLStarterVersion" }, - description: "HTML Starter version. Only required if you are targeting a version lower than v10." - ) { IsRequired = false }); - cmd.AddOption(new Option( - aliases: new[] { "--yoGeneratorVersion" }, - description: "@criticalmanufacturing/html Yeoman generator version. Only required if you are targeting a version lower than v10." - ) { IsRequired = false }); - cmd.AddOption(new Option( - aliases: new[] { "--ngxSchematicsVersion" }, - description: "@criticalmanufacturing/ngx-schematics version. Only required if you are targeting a version equal or higher than v10." - ) { IsRequired = false }); - cmd.AddOption(new Option( - aliases: new[] { "--nugetVersion" }, - description: "NuGet versions to target. This is usually the MES version" - ) { IsRequired = true }); - // TODO: remove this one? - cmd.AddOption(new Option( - aliases: new[] { "--testScenariosNugetVersion" }, - description: "Test Scenarios Nuget Version" - ) { IsRequired = true }); + var baseVersionOption = new Option("--baseVersion", "--MESVersion") + { + Description = "Target CM framework/MES version", + Required = true + }; + cmd.Add(baseVersionOption); + + var devTasksVersionOption = new Option("--DevTasksVersion") + { + Description = "Critical Manufacturing dev-tasks version.", + Required = false + }; + cmd.Add(devTasksVersionOption); + + var htmlStarterVersionOption = new Option("--HTMLStarterVersion") + { + Description = "HTML Starter version.", + Required = false + }; + cmd.Add(htmlStarterVersionOption); + + var yoGeneratorVersionOption = new Option("--yoGeneratorVersion") + { + Description = "@criticalmanufacturing/html Yeoman generator version.", + Required = false + }; + cmd.Add(yoGeneratorVersionOption); + + var ngxSchematicsVersionOption = new Option("--ngxSchematicsVersion") + { + Description = "@criticalmanufacturing/ngx-schematics version.", + Required = false + }; + cmd.Add(ngxSchematicsVersionOption); + + var nugetVersionOption = new Option("--nugetVersion") + { + Description = "NuGet versions to target. This is usually the MES version", + Required = true + }; + cmd.Add(nugetVersionOption); + + var testScenariosNugetVersionOption = new Option("--testScenariosNugetVersion") + { + Description = "Test Scenarios Nuget Version", + Required = true + }; + cmd.Add(testScenariosNugetVersionOption); // repositories - cmd.AddOption(new Option( - aliases: new[] { "--deploymentDir" }, - description: "Deployments directory. Deprecated, supports only file paths/network shares. When using NPM feeds, use --ciRepo and --releaseRepos instead." - ) { IsRequired = false }); - cmd.AddOption(new Option( - aliases: new[] { "--ciRepo" }, - description: "The repository (network share or NPM feed) where CI packages are published to. Must be passed only and only if --deploymentDir is not." - ) { IsRequired = false }); - cmd.AddOption(new Option>( - aliases: new[] { "--releaseRepos" }, - description: "The list of repositories (network shares and/or NPM feeds) where approved packages to be delivered are published to. Must be passed only and only if --deploymentDir is not." - ) + var deploymentDirOption = new Option("--deploymentDir") + { + Description = "Deployments directory. Deprecated, supports only file paths/network shares. When using NPM feeds, use --ciRepo and --releaseRepos instead.", + Required = false, + CustomParser = argResult => ParseUri(argResult) + }; + cmd.Add(deploymentDirOption); + + var ciRepoOption = new Option("--ciRepo") { + Description = "The repository (network share or NPM feed) where CI packages are published to. Must be passed only and only if --deploymentDir is not.", + Required = false, + CustomParser = argResult => ParseUri(argResult) + }; + cmd.Add(ciRepoOption); + + var releaseReposOption = new Option>("--releaseRepos") + { + Description = "The list of repositories (network shares and/or NPM feeds) where approved packages to be delivered are published to. Must be passed only and only if --deploymentDir is not.", Arity = ArgumentArity.ZeroOrMore, - AllowMultipleArgumentsPerToken = true - }); + AllowMultipleArgumentsPerToken = true, + CustomParser = argResult => ParseUriList(argResult) + }; + cmd.Add(releaseReposOption); - cmd.AddOption(new Option( - aliases: new[] { "--tenant" }, - description: "MES Tenant Name" - ) { IsRequired = false }); + var tenantOption = new Option("--tenant") + { + Description = "MES Tenant Name", + Required = false + }; + cmd.Add(tenantOption); // infra options - cmd.AddOption(new Option( - aliases: new[] { "--infra", "--infrastructure" }, - parseArgument: argResult => Parse(argResult), - isDefault: true, - description: "Infrastructure JSON file" - )); - cmd.AddOption(new Option( - aliases: new[] { "--nugetRegistry" }, - description: "NuGet registry that contains the MES packages" - )); - cmd.AddOption(new Option( - aliases: new[] { "--npmRegistry" }, - description: "NPM registry that contains the MES packages" - )); - - cmd.AddOption(new Option( - aliases: new[] { "--ISOLocation" }, - parseArgument: argResult => Parse(argResult), - isDefault: true, - description: "MES ISO file" - )); - cmd.AddOption(new Option( - aliases: new[] { "--nugetRegistryUsername" }, - description: "NuGet registry username" - )); - cmd.AddOption(new Option( - aliases: new[] { "--nugetRegistryPassword" }, - description: "NuGet registry password" - )); + var infrastructureOption = new Option("--infrastructure", "--infra") + { + Description = "Infrastructure JSON file", + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(infrastructureOption); + + var nugetRegistryOption = new Option("--nugetRegistry") + { + Description = "NuGet registry that contains the MES packages", + CustomParser = argResult => ParseUri(argResult) + }; + cmd.Add(nugetRegistryOption); + + var npmRegistryOption = new Option("--npmRegistry") + { + Description = "NPM registry that contains the MES packages", + CustomParser = argResult => ParseUri(argResult) + }; + cmd.Add(npmRegistryOption); + + var isoLocationOption = new Option("--ISOLocation") + { + Description = "MES ISO file", + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(isoLocationOption); + + var nugetRegistryUsernameOption = new Option("--nugetRegistryUsername") + { + Description = "NuGet registry username" + }; + cmd.Add(nugetRegistryUsernameOption); + + var nugetRegistryPasswordOption = new Option("--nugetRegistryPassword") + { + Description = "NuGet registry password" + }; + cmd.Add(nugetRegistryPasswordOption); const string OnlyIfTypeAppWarning = "Use only if repository type is App."; - cmd.AddOption(new Option( - aliases: new[] { "--appId" }, - description: $"Application identifier. {OnlyIfTypeAppWarning}" - ) { IsRequired = false }); - - cmd.AddOption(new Option( - aliases: new[] { "--appName" }, - description: $"Application name. {OnlyIfTypeAppWarning}" - ) { IsRequired = false }); - - cmd.AddOption(new Option( - aliases: new[] { "--appAuthor" }, - description: $"Application author. {OnlyIfTypeAppWarning}" - ) { IsRequired = false }); - - cmd.AddOption(new Option( - aliases: new[] { "--appDescription" }, - description: $"Application description. {OnlyIfTypeAppWarning}" - ) { IsRequired = false }); - - cmd.AddOption(new Option( - aliases: new[] { "--appLicensedApplication" }, - description: $"License for new application. {OnlyIfTypeAppWarning}" - ) { IsRequired = false }); - - cmd.AddOption(new Option( - aliases: new[] { "--appIcon" }, - parseArgument: argResult => Parse(argResult), - description: $"Application icon. {OnlyIfTypeAppWarning}" - ) { IsRequired = false }); + + var appIdOption = new Option("--appId") + { + Description = $"Application identifier. {OnlyIfTypeAppWarning}", + Required = false + }; + cmd.Add(appIdOption); + + var appNameOption = new Option("--appName") + { + Description = $"Application name. {OnlyIfTypeAppWarning}", + Required = false + }; + cmd.Add(appNameOption); + + var appAuthorOption = new Option("--appAuthor") + { + Description = $"Application author. {OnlyIfTypeAppWarning}", + Required = false + }; + cmd.Add(appAuthorOption); + + var appDescriptionOption = new Option("--appDescription") + { + Description = $"Application description. {OnlyIfTypeAppWarning}", + Required = false + }; + cmd.Add(appDescriptionOption); + + var appLicensedApplicationOption = new Option("--appLicensedApplication") + { + Description = $"License for new application. {OnlyIfTypeAppWarning}", + Required = false + }; + cmd.Add(appLicensedApplicationOption); + + var appIconOption = new Option("--appIcon") + { + Description = $"Application icon. {OnlyIfTypeAppWarning}", + Required = false, + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(appIconOption); // Add the handler - cmd.Handler = CommandHandler.Create((InitArguments args) => + cmd.SetAction((parseResult, cancellationToken) => { - this.Execute(args); + var args = new InitArguments + { + projectName = parseResult.GetValue(projectNameArgument), + rootPackageName = parseResult.GetValue(rootPackageNameArgument), + workingDir = parseResult.GetValue(workingDirArgument), + version = parseResult.GetValue(versionOption), + config = parseResult.GetValue(configOption), + appConfig = parseResult.GetValue(appConfigOption), + repositoryType = parseResult.GetValue(repositoryTypeOption), + BaseVersion = parseResult.GetValue(baseVersionOption), + DevTasksVersion = parseResult.GetValue(devTasksVersionOption), + HTMLStarterVersion = parseResult.GetValue(htmlStarterVersionOption), + yoGeneratorVersion = parseResult.GetValue(yoGeneratorVersionOption), + ngxSchematicsVersion = parseResult.GetValue(ngxSchematicsVersionOption), + nugetVersion = parseResult.GetValue(nugetVersionOption), + testScenariosNugetVersion = parseResult.GetValue(testScenariosNugetVersionOption), + deploymentDir = parseResult.GetValue(deploymentDirOption), + ciRepo = parseResult.GetValue(ciRepoOption), + releaseRepos = parseResult.GetValue(releaseReposOption), + Tenant = parseResult.GetValue(tenantOption), + infrastructure = parseResult.GetValue(infrastructureOption), + nugetRegistry = parseResult.GetValue(nugetRegistryOption), + npmRegistry = parseResult.GetValue(npmRegistryOption), + ISOLocation = parseResult.GetValue(isoLocationOption), + nugetRegistryUsername = parseResult.GetValue(nugetRegistryUsernameOption), + nugetRegistryPassword = parseResult.GetValue(nugetRegistryPasswordOption), + appId = parseResult.GetValue(appIdOption), + appName = parseResult.GetValue(appNameOption), + appAuthor = parseResult.GetValue(appAuthorOption), + appDescription = parseResult.GetValue(appDescriptionOption), + appLicensedApplication = parseResult.GetValue(appLicensedApplicationOption), + appIcon = parseResult.GetValue(appIconOption) + }; + + Execute(args); + return Task.FromResult(0); }); } @@ -326,7 +425,7 @@ internal void Execute(InitArguments x) { throw new CliException("Invalid option `--ciRepo` when also using `--deploymentDir`. Use one or the other, but not both."); } - if (x.releaseRepos != null) + if (x.releaseRepos != null && x.releaseRepos.Count > 0) { throw new CliException("Invalid option `--releaseRepos` when also using `--deploymentDir`. Use one or the other, but not both."); } @@ -380,7 +479,7 @@ internal void Execute(InitArguments x) { throw new CliException("Missing option `--ciRepo` or `--deploymentDir`. Please specify one or the other (but not both)."); } - if (x.releaseRepos == null) + if (x.releaseRepos == null || x.releaseRepos.Count == 0) { throw new CliException("Missing option `--releaseRepos` or `--deploymentDir`. Please specify one or the other (but not both)."); } @@ -463,33 +562,14 @@ internal void Execute(InitArguments x) var version = Version.Parse(x.BaseVersion); args.AddRange(new []{ "--dotnetSDKVersion", ExecutionContext.ServiceProvider.GetService().DotNetSdk(version) }); - if (version.Major > 9) + if(version < new Version(10,0)) { - if (string.IsNullOrWhiteSpace(x.ngxSchematicsVersion)) - { - throw new CliException( - "--ngxSchematicsVersion is required when targeting a base version of 10 or above."); - } + throw new CliException("MES Versions under 10 are no longer supported with the newest version of the CLI. Please use cmf-cli 5.8.0 or lower."); } - else + + if (string.IsNullOrWhiteSpace(x.ngxSchematicsVersion)) { - var errors = new List(); - if (string.IsNullOrWhiteSpace(x.DevTasksVersion)) - { - errors.Add("--DevTasksVersion is required when targeting a base version lower than 10."); - } - if (string.IsNullOrWhiteSpace(x.HTMLStarterVersion)) - { - errors.Add("--HTMLStarterVersion is required when targeting a base version lower than 10."); - } - if (string.IsNullOrWhiteSpace(x.yoGeneratorVersion)) - { - errors.Add("--yoGeneratorVersion is required when targeting a base version lower than 10."); - } - if (errors.Count > 0) - { - throw new CliException(string.Join(Environment.NewLine, errors)); - } + throw new CliException("--ngxSchematicsVersion is missing, please specify it."); } #endregion @@ -555,6 +635,18 @@ internal void Execute(InitArguments x) } bool isToIgnoreOptionToken = false; + + /// + /// Parse list of URIs from argument result + /// + /// the arguments to parse + /// List of parsed URIs or null if no tokens + private List ParseUriList(ArgumentResult argResult) + { + var array = ParseUriArray(argResult); + return array != null ? new List(array) : null; + } + /// /// parse argument specific for InitCommand /// This is needed until this issue is not fixed: @@ -571,9 +663,10 @@ private T ParseArgument(ArgumentResult argResult, string @default = null) { var argValue = @default; - if (!isToIgnoreOptionToken && argResult.Tokens.Any()) + if (!isToIgnoreOptionToken && argResult != null && argResult.Tokens.Any()) { - var isOptionAndShouldBeIgnored = isToIgnoreOptionToken || (bool)argResult.Tokens?.FirstOrDefault()?.Value.StartsWith("-"); + var firstTokenValue = argResult.Tokens?.FirstOrDefault()?.Value; + var isOptionAndShouldBeIgnored = firstTokenValue?.StartsWith("-") ?? false; if (isOptionAndShouldBeIgnored) { isToIgnoreOptionToken = true; @@ -603,4 +696,4 @@ private T ParseArgument(ArgumentResult argResult, string @default = null) }; } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/list/ListDependenciesCommand.cs b/cmf-cli/Commands/list/ListDependenciesCommand.cs index 111c6181d..6f82ce7dc 100644 --- a/cmf-cli/Commands/list/ListDependenciesCommand.cs +++ b/cmf-cli/Commands/list/ListDependenciesCommand.cs @@ -1,6 +1,5 @@ using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Threading; using System.Threading.Tasks; @@ -43,21 +42,30 @@ public ListDependenciesCommand(IFileSystem fileSystem) : base(fileSystem) /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, "."), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, "."), + DefaultValueFactory = _ => Parse(null, ".") + }; + cmd.Add(workingDirArgument); - cmd.AddOption(new Option( - aliases: new string[] { "-r", "--repos", "--repo" }, - description: "Repositories where dependencies are located (folder)")); + var reposOption = new Option("--repos", "-r", "--repo") + { + Description = "Repositories where dependencies are located (folder)", + CustomParser = argResult => ParseUriArray(argResult) + }; + cmd.Add(reposOption); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + var repos = parseResult.GetValue(reposOption); + + Execute(workingDir, repos); + return Task.FromResult(0); + }); } /// @@ -115,9 +123,6 @@ public void Execute(IDirectoryInfo workingDir, Uri[] repos) Log.Render(tree); }); } - - - } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/login/LoginCommand.cs b/cmf-cli/Commands/login/LoginCommand.cs index a1e64de02..d4f876dbc 100644 --- a/cmf-cli/Commands/login/LoginCommand.cs +++ b/cmf-cli/Commands/login/LoginCommand.cs @@ -1,6 +1,4 @@ -using Cmf.CLI.Core; -using Cmf.CLI.Core.Attributes; -using Cmf.CLI.Core.Commands; +using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Constants; using Cmf.CLI.Core.Enums; using Cmf.CLI.Core.Interfaces; @@ -10,7 +8,6 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; using System.Threading.Tasks; @@ -45,48 +42,85 @@ public LoginCommand(IFileSystem fileSystem) : base(fileSystem) /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "repositoryType", description: "Type of repository for login" - ) { Arity = ArgumentArity.ZeroOrOne }); - cmd.AddArgument(new Argument( - name: "repository", description: "URL of repository for login" - ) { Arity = ArgumentArity.ZeroOrOne }); - - cmd.AddOption(new Option( - aliases: new[] { "-T", "--auth-type" }, - description: "Type of authentication type to use (only needed if the repository type supports more than one)" - )); - cmd.AddOption(new Option( - aliases: new[] { "-t", "--token" }, - description: "Token used for this, used when the auth type is Bearer" - )); - cmd.AddOption(new Option( - aliases: new[] { "-u", "--username" }, - description: "Account username, used when the auth type is Basic" - )); - cmd.AddOption(new Option( - aliases: new[] { "-p", "--password" }, - description: "Account password, used when the auth type is Basic" - )); - cmd.AddOption(new Option( - aliases: new[] { "-d", "--domain" }, - description: "For repositories that support it, the domain to use when logging in." - )); - cmd.AddOption(new Option( - aliases: new[] { "-k", "--key" }, - description: "For repositories that support it, the key under which we should store the credential" - )); - cmd.AddOption(new Option( - aliases: new[] { "--store-only" }, - description: "If true, the credentials are stord on the .cmf-auth.json file, but are not applied to the credentials file of the tool (NPM, NuGet, Docker, etc...)" - )); - cmd.AddOption(new Option( - aliases: new[] { "--no-prompt" }, - description: "Do not display any interactive prompts. If a prompt was needed, an error will be raised instead" - )); + var repositoryTypeArgument = new Argument("repositoryType") + { + Description = "Type of repository for login", + Arity = ArgumentArity.ZeroOrOne + }; + cmd.Add(repositoryTypeArgument); + + var repositoryArgument = new Argument("repository") + { + Description = "URL of repository for login", + Arity = ArgumentArity.ZeroOrOne + }; + cmd.Add(repositoryArgument); + + var authTypeOption = new Option("--auth-type", "-T") + { + Description = "Type of authentication type to use (only needed if the repository type supports more than one)" + }; + cmd.Add(authTypeOption); + + var tokenOption = new Option("--token", "-t") + { + Description = "Token used for this, used when the auth type is Bearer" + }; + cmd.Add(tokenOption); + + var usernameOption = new Option("--username", "-u") + { + Description = "Account username, used when the auth type is Basic" + }; + cmd.Add(usernameOption); + + var passwordOption = new Option("--password", "-p") + { + Description = "Account password, used when the auth type is Basic" + }; + cmd.Add(passwordOption); + + var domainOption = new Option("--domain", "-d") + { + Description = "For repositories that support it, the domain to use when logging in." + }; + cmd.Add(domainOption); + + var keyOption = new Option("--key", "-k") + { + Description = "For repositories that support it, the key under which we should store the credential" + }; + cmd.Add(keyOption); + + var storeOnlyOption = new Option("--store-only") + { + Description = "If true, the credentials are stord on the .cmf-auth.json file, but are not applied to the credentials file of the tool (NPM, NuGet, Docker, etc...)" + }; + cmd.Add(storeOnlyOption); + + var noPromptOption = new Option("--no-prompt") + { + Description = "Do not display any interactive prompts. If a prompt was needed, an error will be raised instead" + }; + cmd.Add(noPromptOption); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var repositoryType = parseResult.GetValue(repositoryTypeArgument); + var repository = parseResult.GetValue(repositoryArgument); + var authType = parseResult.GetValue(authTypeOption); + var token = parseResult.GetValue(tokenOption); + var username = parseResult.GetValue(usernameOption); + var password = parseResult.GetValue(passwordOption); + var domain = parseResult.GetValue(domainOption); + var key = parseResult.GetValue(keyOption); + var storeOnly = parseResult.GetValue(storeOnlyOption); + var noPrompt = parseResult.GetValue(noPromptOption); + + Execute(repositoryType, repository, authType, token, username, password, domain, key, storeOnly, noPrompt); + return Task.FromResult(0); + }); } /// @@ -212,4 +246,4 @@ internal string Prompt(string label, bool noPrompt) return Console.ReadLine(); } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/login/SyncCommand.cs b/cmf-cli/Commands/login/SyncCommand.cs index ab8b43165..3c99efde5 100644 --- a/cmf-cli/Commands/login/SyncCommand.cs +++ b/cmf-cli/Commands/login/SyncCommand.cs @@ -1,18 +1,12 @@ using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; -using Cmf.CLI.Core.Commands; -using Cmf.CLI.Core.Constants; -using Cmf.CLI.Core.Enums; using Cmf.CLI.Core.Interfaces; using Cmf.CLI.Core.Objects; using Cmf.CLI.Core.Repository.Credentials; -using Cmf.CLI.Utilities; using Microsoft.Extensions.DependencyInjection; using System; -using System.Collections; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; using System.Threading.Tasks; @@ -47,7 +41,29 @@ public SyncCommand(IFileSystem fileSystem) : base(fileSystem) public override void Configure(Command cmd) { // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + // Get parent command arguments + RepositoryCredentialsType? repositoryType = null; + string repository = null; + + // In beta5, we need to access parent command arguments through the parse result + // The parent command is "login" which has repositoryType and repository arguments + if (cmd.Parents.FirstOrDefault() is Command parentCommand) + { + if (parentCommand.Arguments.FirstOrDefault(a => a.Name == "repositoryType") is Argument repositoryTypeArg) + { + repositoryType = parseResult.GetValue(repositoryTypeArg); + } + if (parentCommand.Arguments.FirstOrDefault(a => a.Name == "repository") is Argument repositoryArg) + { + repository = parseResult.GetValue(repositoryArg); + } + } + + Execute(repositoryType, repository); + return Task.FromResult(0); + }); } /// @@ -134,4 +150,4 @@ internal async Task ExecuteAsync(RepositoryCredentialsType? repositoryType, stri } } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/new/BusinessCommand.cs b/cmf-cli/Commands/new/BusinessCommand.cs index cd2e2ae44..32cf28f9a 100644 --- a/cmf-cli/Commands/new/BusinessCommand.cs +++ b/cmf-cli/Commands/new/BusinessCommand.cs @@ -1,13 +1,15 @@ using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Constants; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Enums; using Cmf.CLI.Core.Objects; +using Cmf.CLI.Services; using Cmf.CLI.Utilities; +using Microsoft.Extensions.DependencyInjection; namespace Cmf.CLI.Commands.New { @@ -40,13 +42,23 @@ public BusinessCommand(IFileSystem fileSystem) : base("business", PackageType.Bu /// public override void Configure(Command cmd) { - cmd.AddOption(new Option( - aliases: new[] { "--addApplicationVersionAssembly", "-av" }, - description: "Will add application version project to the final solution if project is an app" - )); - base.GetBaseCommandConfig(cmd); + var addApplicationVersionAssemblyOption = new Option("--addApplicationVersionAssembly", "-av") + { + Description = "Will add application version project to the final solution if project is an app" + }; + cmd.Add(addApplicationVersionAssemblyOption); + + var (workingDirArg, versionOpt) = base.GetBaseCommandConfig(cmd); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArg); + var version = parseResult.GetValue(versionOpt); + var addApplicationVersionAssembly = parseResult.GetValue(addApplicationVersionAssemblyOption); - cmd.Handler = CommandHandler.Create(this.Execute); + Execute(workingDir, version, addApplicationVersionAssembly); + return Task.FromResult(0); + }); } /// @@ -73,28 +85,25 @@ protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirect var mesVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; var includeMESNugets = true; - if (mesVersion.Major > 8) - { - this.CommandName = "business9"; - var baseLayer = ExecutionContext.Instance.ProjectConfig.BaseLayer ?? CliConstants.DefaultBaseLayer; - includeMESNugets = baseLayer == BaseLayer.MES; - Log.Debug($"Project is targeting base layer {baseLayer}, so scaffolding {(includeMESNugets ? "with" : "without")} MES nugets."); + this.CommandName = "business10"; // template name + var baseLayer = ExecutionContext.Instance.ProjectConfig.BaseLayer ?? CliConstants.DefaultBaseLayer; + includeMESNugets = baseLayer == BaseLayer.MES; + Log.Debug($"Project is targeting base layer {baseLayer}, so scaffolding {(includeMESNugets ? "with" : "without")} MES nugets."); - args.AddRange(new []{ "--targetFramework", mesVersion.Major >= 11 ? "net8.0" : "net6.0" }); + args.AddRange(new []{ "--targetFramework", ExecutionContext.ServiceProvider.GetService().DotNetTargetFramework(mesVersion) }); - if (ExecutionContext.Instance.ProjectConfig.RepositoryType == RepositoryType.App) + if (ExecutionContext.Instance.ProjectConfig.RepositoryType == RepositoryType.App) + { + var appData = ExecutionContext.Instance.AppData ?? + throw new CliException("Could not retrieve repository AppData."); + args.AddRange(new[] { - var appData = ExecutionContext.Instance.AppData ?? - throw new CliException("Could not retrieve repository AppData."); - args.AddRange(new[] - { - "--app", "true", - "--licensedAppName", appData.licensedApplication, - "--fileVersion", $"{mesVersion}.0", - "--assemblyVersion", $"{mesVersion.Major}.{mesVersion.Minor}.0.0", - "--addApplicationVersionAssembly", AddApplicationVersionAssembly.ToString() - }); - } + "--app", "true", + "--licensedAppName", appData.licensedApplication, + "--fileVersion", $"{mesVersion}.0", + "--assemblyVersion", $"{mesVersion.Major}.{mesVersion.Minor}.0.0", + "--addApplicationVersionAssembly", AddApplicationVersionAssembly.ToString() + }); } // calculate relative path to local environment and create a new symbol for it diff --git a/cmf-cli/Commands/new/DataCommand.cs b/cmf-cli/Commands/new/DataCommand.cs index 175a341b2..9de6fda78 100644 --- a/cmf-cli/Commands/new/DataCommand.cs +++ b/cmf-cli/Commands/new/DataCommand.cs @@ -1,17 +1,17 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; -using System.Linq; -using System.Text.Json; +using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Constants; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Enums; using Cmf.CLI.Core.Objects; +using Cmf.CLI.Services; using Cmf.CLI.Utilities; +using Microsoft.Extensions.DependencyInjection; namespace Cmf.CLI.Commands.New { @@ -34,20 +34,31 @@ public DataCommand(IFileSystem fileSystem) : base("data", PackageType.Data, file /// public override void Configure(Command cmd) { - base.GetBaseCommandConfig(cmd); - cmd.AddOption(new Option( - aliases: new[] { "--businessPackage" }, - parseArgument: argResult => Parse(argResult), - isDefault: true, - description: "Business package where the Process Rules project should be built" - )); - cmd.Handler = CommandHandler.Create(this.Execute); + var (workingDirArg, versionOpt) = GetBaseCommandConfig(cmd); + + var businessPackageOption = new Option("--businessPackage") + { + Description = "Business package where the Process Rules project should be built", + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(businessPackageOption); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArg); + var version = parseResult.GetValue(versionOpt); + var businessPackage = parseResult.GetValue(businessPackageOption); + + Execute(workingDir, version, businessPackage); + return Task.FromResult(0); + }); } /// protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirectoryInfo workingDir, List args) { var repoType = ExecutionContext.Instance.ProjectConfig.RepositoryType ?? CliConstants.DefaultRepositoryType; + Version version = ExecutionContext.Instance.ProjectConfig.MESVersion; var relativePathToRoot = this.fileSystem.Path.Join("..", //always one level deeper @@ -61,12 +72,7 @@ protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirect "--rootRelativePath", relativePathToRoot, "--repositoryType", repoType.ToString() }); - - #region version-specific bits - - var version = ExecutionContext.Instance.ProjectConfig.MESVersion; - args.AddRange(new []{ "--targetFramework", version.Major > 8 ? "net6.0" : "netstandard2.0" }); - #endregion + args.AddRange(new []{ "--targetFramework", DependencyVersionService.NET6TARGETFRAMEWORK }); return args; } diff --git a/cmf-cli/Commands/new/FeatureCommand.cs b/cmf-cli/Commands/new/FeatureCommand.cs index 2685c9649..88b98fcc5 100644 --- a/cmf-cli/Commands/new/FeatureCommand.cs +++ b/cmf-cli/Commands/new/FeatureCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Commands; using Cmf.CLI.Core.Objects; @@ -38,24 +38,37 @@ public FeatureCommand(IFileSystem fileSystem) : base("feature", fileSystem) public override void Configure(Command cmd) { var root = FileSystemUtilities.GetProjectRoot(this.fileSystem); - cmd.AddArgument(new Argument( - name: "packageName", - description: "The Feature package name" - )); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, root?.FullName), - isDefault: true - ) + + var packageNameArgument = new Argument("packageName") + { + Description = "The Feature package name" + }; + cmd.Add(packageNameArgument); + + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, root?.FullName), + DefaultValueFactory = _ => Parse(null, root?.FullName) + }; + cmd.Add(workingDirArgument); + + var versionOption = new Option("--version") + { + Description = "Package Version", + DefaultValueFactory = _ => "1.0.0" + }; + cmd.Add(versionOption); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + var packageName = parseResult.GetValue(packageNameArgument); + var version = parseResult.GetValue(versionOption); + + Execute(workingDir, packageName, version); + return Task.FromResult(0); }); - cmd.AddOption(new Option( - aliases: new[] { "--version" }, - description: "Package Version", - getDefaultValue: () => "1.0.0" - )); - cmd.Handler = CommandHandler.Create(Execute); } /// diff --git a/cmf-cli/Commands/new/GrafanaCommand.cs b/cmf-cli/Commands/new/GrafanaCommand.cs index bdb64c3d8..c294ffd19 100644 --- a/cmf-cli/Commands/new/GrafanaCommand.cs +++ b/cmf-cli/Commands/new/GrafanaCommand.cs @@ -31,11 +31,6 @@ public GrafanaCommand(IFileSystem fileSystem) : base("grafana", PackageType.Graf /// protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirectoryInfo workingDir, List args) { - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 10) - { - throw new CliException("Version unsupported, available in MES >= 10"); - } - var isRepositoryType = ExecutionContext.Instance.ProjectConfig.RepositoryType == RepositoryType.App; args.AddRange(new[] diff --git a/cmf-cli/Commands/new/HTMLCommand.cs b/cmf-cli/Commands/new/HTMLCommand.cs index dbbdf083d..9ee3ceb78 100644 --- a/cmf-cli/Commands/new/HTMLCommand.cs +++ b/cmf-cli/Commands/new/HTMLCommand.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Constants; using Cmf.CLI.Core; @@ -15,7 +15,6 @@ using Cmf.CLI.Utilities; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace Cmf.CLI.Commands.New { @@ -40,15 +39,16 @@ public HTMLCommand(IFileSystem fileSystem) : base("html", PackageType.HTML, file /// public override void Configure(Command cmd) { - base.GetBaseCommandConfig(cmd); - cmd.AddOption(new Option( - aliases: new[] { "--htmlPkg", "--htmlPackage" }, - description: "Path to the MES Presentation HTML package (required for MES versions up to 9.x)", - isDefault: false, - parseArgument: argResult => Parse(argResult) - ) - { IsRequired = false }); - cmd.Handler = CommandHandler.Create(this.Execute); + var (workingDirArg, versionOpt) = base.GetBaseCommandConfig(cmd); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArg); + var version = parseResult.GetValue(versionOpt); + + Execute(workingDir, version); + return Task.FromResult(0); + }); } /// @@ -77,243 +77,10 @@ protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirect /// /// nearest root package /// package version - /// The MES Presentation HTML package path - public void Execute(IDirectoryInfo workingDir, string version, IFileInfo htmlPackage) + public void Execute(IDirectoryInfo workingDir, string version) { CommandUtilities.ThrowIfNoProjectConfig(ExecutionContext.Instance); - - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major > 9) - { - this.ExecuteV10(workingDir, version); - } - else - { - this.ExecuteV9(workingDir, version, htmlPackage); - } - } - - public void ExecuteV9(IDirectoryInfo workingDir, string version, IFileInfo htmlPackage) - { - if (htmlPackage == null) - { - throw new CliException("--htmlPkg option is required for MES versions up to 9.x"); - } - if (!htmlPackage.Exists) - { - throw new CliException($"Cannot find HTML package {htmlPackage.FullName}"); - } - var baseLayer = ExecutionContext.Instance.ProjectConfig.BaseLayer ?? CliConstants.DefaultBaseLayer; - this.baseWebPackage = baseLayer == BaseLayer.MES - ? "@criticalmanufacturing/mes-ui-web" - : "@criticalmanufacturing/core-ui-web"; - Log.Debug($"Project is targeting base layer {baseLayer}, so scaffolding with base web package {baseWebPackage}"); - - base.Execute(workingDir, version); // create package base - generate cmfpackage.json - - var nameIdx = Array.FindIndex(base.executedArgs, item => string.Equals(item, "--name")); - var pkgName = base.executedArgs[nameIdx + 1]; - var htmlStarterVersion = ExecutionContext.Instance.ProjectConfig.HTMLStarterVersion; - // clone HTMLStarter content in the folder - var pkgFolder = workingDir.GetDirectories(pkgName).FirstOrDefault(); - if (!pkgFolder?.Exists ?? false) - { - throw new CliException($"Package folder {pkgFolder.Name} does not exist. This is a template error. Please open an issue on GitHub."); - } - this.CloneHTMLStarter(htmlStarterVersion, pkgFolder); - - // root package.json - var rootPkgJsonPath = this.fileSystem.Path.Join(pkgFolder.FullName, "package.json"); - var json = fileSystem.File.ReadAllText(rootPkgJsonPath); - dynamic rootPkgJson = JsonConvert.DeserializeObject(json); - if (rootPkgJson == null) - { - throw new CliException("Could not load package.json"); - } - var devTasksVersion = ExecutionContext.Instance.ProjectConfig.DevTasksVersion; - var yoGeneratorVersion = ExecutionContext.Instance.ProjectConfig.YoGeneratorVersion; - var projectName = ExecutionContext.Instance.ProjectConfig.ProjectName; - var repositoryURL = ExecutionContext.Instance.ProjectConfig.RepositoryURL; - var tenant = ExecutionContext.Instance.ProjectConfig.Tenant; - rootPkgJson.devDependencies["@criticalmanufacturing/dev-tasks"] = devTasksVersion.ToString(); - rootPkgJson.devDependencies["@criticalmanufacturing/generator-html"] = yoGeneratorVersion.ToString(); - rootPkgJson.devDependencies["@types/node"] = "^12.0.0"; - rootPkgJson.name = $"customization.{tenant?.ToLowerInvariant()}"; - rootPkgJson.description = $"HTML customization package for {projectName}"; - rootPkgJson.repository.url = repositoryURL; - json = JsonConvert.SerializeObject(rootPkgJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(rootPkgJsonPath, json); - Log.Verbose("Updated package.json"); - - // .dev-tasks.json - var devTasksPath = this.fileSystem.Path.Join(pkgFolder.FullName, ".dev-tasks.json"); - var devTasksStr = fileSystem.File.ReadAllText(devTasksPath); - dynamic devTasksJson = JsonConvert.DeserializeObject(devTasksStr); - if (devTasksJson == null) - { - throw new CliException("Could not load .dev-tasks.json"); - } - var npmRegistry = ExecutionContext.Instance.ProjectConfig.NPMRegistry; - var mesVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - var targetVersion = mesVersion; - var injectAppsPackage = targetVersion.CompareTo(new Version("8.3.0")) >= 0; - if (injectAppsPackage) - { - Log.Debug($"Target MES version is 8.3.0+, injecting `cmf.core.app` into packages list."); - } - devTasksJson.packagePrefix = "customization"; - devTasksJson.webAppPrefix = "customization"; - devTasksJson.registry = npmRegistry; - devTasksJson.isWebAppCompilable = true; - devTasksJson.channel = $"release-{mesVersion.Major}{mesVersion.Minor}{mesVersion.Build}"; - devTasksStr = JsonConvert.SerializeObject(devTasksJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(devTasksPath, devTasksStr); - Log.Verbose("Updated .dev-tasks.json"); - - // install dev dependencies/tooling - Log.Verbose("Executing npm install, this will take a while..."); - (new NPMCommand() { Command = "install", WorkingDirectory = pkgFolder }).Exec(); - - var htmlDevTasksConfigPath = this.fileSystem.Path.GetTempFileName(); - var htmlDevTasksConfigJson = -$@"{{ - ""answers"": {{ - ""packagePrefix"": ""customization"", - ""registry"": ""{npmRegistry}"", - ""confirmSkip"": ""y"", - ""channel"": ""release-{mesVersion.Major}{mesVersion.Minor}{mesVersion.Build}"" - }} -}}"; - this.fileSystem.File.WriteAllText(htmlDevTasksConfigPath, htmlDevTasksConfigJson); - var htmlWebAppConfigPath = this.fileSystem.Path.GetTempFileName(); - var htmlWebAppConfigJson = -$@"{{ - ""answers"": {{ - ""appName"": ""web"", - ""basePackage"": ""{this.baseWebPackage}"" - }} -}}"; - this.fileSystem.File.WriteAllText(htmlWebAppConfigPath, htmlWebAppConfigJson); - - // create web app - // npx yeoman-gen-run --name @criticalmanufacturing/html --config "$pathHTMLConfig" -- --keep - Log.Verbose("Generate web app, this will take a while..."); - (new NPXCommand() - { - Command = "yeoman-gen-run", - WorkingDirectory = pkgFolder, - Args = new[] - { - "--name", "@criticalmanufacturing/html", "--config", htmlDevTasksConfigPath, "--", "--keep" - } - }).Exec(); - // npx yeoman-gen-run --name @criticalmanufacturing/html:application --config "$path" - (new NPXCommand() - { - Command = "yeoman-gen-run", - WorkingDirectory = pkgFolder, - Args = new[] - { - "--name", "@criticalmanufacturing/html:application", "--config", htmlWebAppConfigPath - } - }).Exec(); - Log.Verbose("Web app generated!"); - - Log.Debug("Obtaining sources from MES Presentation HTML package..."); - var htmlPkgConfigJsonStr = FileSystemUtilities.GetFileContentFromPackage(htmlPackage.FullName, "config.json"); - // replace tokens that would break Json parse - htmlPkgConfigJsonStr = Regex.Replace(htmlPkgConfigJsonStr, @"\$\([^\)]+\)", "0", RegexOptions.Multiline); - dynamic htmlPkgConfigJson = null; - try - { - htmlPkgConfigJson = JsonConvert.DeserializeObject(htmlPkgConfigJsonStr); - } - catch (Exception e) - { - throw new CliException("Could not load ISO config.json", e); - } - var htmlPkgPackages = - (htmlPkgConfigJson.packages.available as JArray).Where(p => baseLayer == BaseLayer.MES || !p.Value().Contains("cmf.mes")); - - // config.json - var configJsonPath = this.fileSystem.Path.Join(pkgFolder.FullName, "apps", - this.fileSystem.Path.Join("customization.web", "config.json")); - var configJsonStr = fileSystem.File.ReadAllText(configJsonPath); - if (!configJsonStr.Contains("$(")) - { - // config.json has no tokens and can be malformed. We need to make sure it parses, so we inject some dummy values that will be thrown away later - Log.Debug("Generated config.json does not contain tokens and is possibly malformed. Setting some dummy values so we can deserialize it."); - configJsonStr = configJsonStr - .Replace("\"port\": ", "\"port\": 0") - .Replace("\"enableSsl\": ,", "\"enableSsl\": false,"); - - configJsonStr = Regex.Replace(configJsonStr, "\"isLoadBalancerEnabled\": (false)?\r?\n", - "\"isLoadBalancerEnabled\": false\n"); - } - configJsonStr = Regex.Replace(configJsonStr, @"\$\([^\)]+\)", "0", RegexOptions.Multiline); - dynamic configJsonJson = null; - try - { - configJsonJson = JsonConvert.DeserializeObject(configJsonStr); - } - catch (Exception e) - { - throw new CliException("Could not load webapp config.json", e); - } - if (configJsonJson == null) - { - throw new CliException("Could not load webapp config.json"); - } - var restPort = ExecutionContext.Instance.ProjectConfig.RESTPort; - configJsonJson.host.rest.enableSsl = false; - configJsonJson.host.rest.address = "localhost"; - configJsonJson.host.rest.port = restPort; - configJsonJson.host.isLoadBalancerEnabled = false; - configJsonJson.host.tenant.name = tenant; - configJsonJson.general.defaultDomain = ExecutionContext.Instance.ProjectConfig.DefaultDomain; - configJsonJson.general.environmentName = $"{projectName}Local"; - configJsonJson.version = $"{projectName} $(Build.BuildNumber) - {mesVersion}"; - configJsonJson.packages.available = JArray.FromObject(htmlPkgPackages.Concat(injectAppsPackage ? new[] { new JValue("cmf.core.app") } : Array.Empty())); - configJsonJson.packages.bundlePath = $"node_modules/{this.baseWebPackage}/bundles"; - configJsonStr = JsonConvert.SerializeObject(configJsonJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(configJsonPath, configJsonStr); - Log.Verbose("Updated config.json"); - - // use lodash - // use custom LBOs - Log.Verbose("Updating web app package.json"); - var webAppPath = this.fileSystem.Path.Join(pkgFolder.FullName, - "apps", "customization.web"); - var webAppPkgJsonPath = this.fileSystem.Path.Join(webAppPath, "package.json"); - var projectRoot = FileSystemUtilities.GetProjectRoot(this.fileSystem); - var relativePathToRoot = - this.fileSystem.Path.GetRelativePath( - webAppPath, projectRoot.FullName) - .Replace("\\", "/"); - var webAppPkgJsonStr = fileSystem.File.ReadAllText(webAppPkgJsonPath); - dynamic webAppPkgJson = JsonConvert.DeserializeObject(webAppPkgJsonStr); - webAppPkgJson.dependencies["lodash"] = "3.10.1"; - webAppPkgJson.cmfLinkDependencies["cmf.lbos"] = $"file:{relativePathToRoot}/Libs/LBOs/TypeScript"; - webAppPkgJsonStr = JsonConvert.SerializeObject(webAppPkgJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(webAppPkgJsonPath, webAppPkgJsonStr); - - // remove package locks - Log.Verbose("Generating accurate package-locks for future installs. This will take a while..."); - var rootPkgLockJsonPath = this.fileSystem.Path.Join(pkgFolder.FullName, "package-lock.json"); - this.fileSystem.File.Delete(rootPkgLockJsonPath); - var webAppPkgLockJsonPath = this.fileSystem.Path.Join( - fileSystem.Path.Join(pkgFolder.FullName, "apps", "customization.web"), "package-lock.json"); - this.fileSystem.File.Delete(webAppPkgLockJsonPath); - // gulp install --update - (new GulpCommand() - { - WorkingDirectory = pkgFolder, - GulpFile = "gulpfile.js", - Task = "install", - DisplayName = "Gulp Install", - GulpJS = "node_modules/gulp/bin/gulp.js", - Args = new[] { "--update" }, - }).Exec(); - Log.Information("HTML package generated"); + this.ExecuteV10(workingDir, version); } public void ExecuteV10(IDirectoryInfo workingDir, string version) @@ -485,4 +252,4 @@ public void ExecuteV10(IDirectoryInfo workingDir, string version) Log.Verbose("Updated config.json"); } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/new/HelpCommand.cs b/cmf-cli/Commands/new/HelpCommand.cs index 1517f222e..df4f4cf86 100644 --- a/cmf-cli/Commands/new/HelpCommand.cs +++ b/cmf-cli/Commands/new/HelpCommand.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Constants; using Cmf.CLI.Core; @@ -42,14 +42,16 @@ public HelpCommand(IFileSystem fileSystem) : base("help", PackageType.Help, file /// public override void Configure(Command cmd) { - base.GetBaseCommandConfig(cmd); - cmd.AddOption(new Option( - aliases: new[] { "--docPkg", "--documentationPackage" }, - description: "Path to the MES documentation package (required for MES versions up to 9.x)", - parseArgument: argResult => Parse(argResult) - ) - { IsRequired = false }); - cmd.Handler = CommandHandler.Create(this.Execute); + var (workingDirArg, versionOpt) = base.GetBaseCommandConfig(cmd); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArg); + var version = parseResult.GetValue(versionOpt); + + Execute(workingDir, version); + return Task.FromResult(0); + }); } /// @@ -93,227 +95,9 @@ protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirect /// /// nearest root package /// package version - /// The MES documentation package path - public void Execute(IDirectoryInfo workingDir, string version, IFileInfo documentationPackage) - { - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major > 9) - { - Log.Debug("Running v>=10 template"); - this.ExecuteV10(workingDir, version, ExecutionContext.Instance.ProjectConfig.MESVersion.Major); - } - else - { - Log.Debug("Running v<10 template"); - this.ExecuteV9(workingDir, version, documentationPackage); - } - } - - public void ExecuteV9(IDirectoryInfo workingDir, string version, IFileInfo documentationPackage) - { - if (documentationPackage == null) - { - throw new CliException("--docPkg option is required for MES versions up to 9.x"); - } - if (!documentationPackage.Exists) - { - throw new CliException($"Cannot find Documentation package {documentationPackage.FullName}"); - } - base.Execute(workingDir, version); // create package base - generate cmfpackage.json - var nameIdx = Array.FindIndex(base.executedArgs, item => string.Equals(item, "--name")); - var pkgName = base.executedArgs[nameIdx + 1]; - var htmlStarterVersion = ExecutionContext.Instance.ProjectConfig.HTMLStarterVersion; - // clone HTMLStarter content in the folder - var pkgFolder = workingDir.GetDirectories(pkgName).FirstOrDefault(); - if (!pkgFolder?.Exists ?? false) - { - throw new CliException($"Package folder {pkgFolder.Name} does not exist. This is a template error. Please open an issue on GitHub."); - } - this.CloneHTMLStarter(htmlStarterVersion, pkgFolder); - - // root package.json - var rootPkgJsonPath = this.fileSystem.Path.Join(pkgFolder.FullName, "package.json"); - var json = fileSystem.File.ReadAllText(rootPkgJsonPath); - dynamic rootPkgJson = JsonConvert.DeserializeObject(json); - if (rootPkgJson == null) - { - throw new CliException("Could not load package.json"); - } - var devTasksVersion = ExecutionContext.Instance.ProjectConfig.DevTasksVersion; - var yoGeneratorVersion = ExecutionContext.Instance.ProjectConfig.YoGeneratorVersion; - var projectName = ExecutionContext.Instance.ProjectConfig.ProjectName; - var repositoryURL = ExecutionContext.Instance.ProjectConfig.RepositoryURL; - rootPkgJson.devDependencies["@criticalmanufacturing/dev-tasks"] = devTasksVersion.ToString(); - rootPkgJson.devDependencies["@criticalmanufacturing/generator-html"] = yoGeneratorVersion.ToString(); - rootPkgJson.devDependencies["@types/node"] = "^12.0.0"; - rootPkgJson.name = "cmf.docs.area"; - rootPkgJson.description = $"Help customization package for {projectName}"; - rootPkgJson.repository.url = repositoryURL; - json = JsonConvert.SerializeObject(rootPkgJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(rootPkgJsonPath, json); - Log.Verbose("Updated package.json"); - - // .dev-tasks.json - var devTasksPath = this.fileSystem.Path.Join(pkgFolder.FullName, ".dev-tasks.json"); - var devTasksStr = fileSystem.File.ReadAllText(devTasksPath); - dynamic devTasksJson = JsonConvert.DeserializeObject(devTasksStr); - if (devTasksJson == null) - { - throw new CliException("Could not load .dev-tasks.json"); - } - var npmRegistry = ExecutionContext.Instance.ProjectConfig.NPMRegistry; - var mesVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - devTasksJson.packagePrefix = "cmf.docs.area"; - devTasksJson.webAppPrefix = "cmf.docs.area"; - devTasksJson.registry = npmRegistry; - devTasksJson.channel = $"release-{mesVersion.Major}{mesVersion.Minor}{mesVersion.Build}"; - devTasksStr = JsonConvert.SerializeObject(devTasksJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(devTasksPath, devTasksStr); - Log.Verbose("Updated .dev-tasks.json"); - - // install dev dependencies/tooling - Log.Verbose("Executing npm install, this will take a while..."); - (new NPMCommand() { Command = "install", WorkingDirectory = pkgFolder }).Exec(); - - var helpDevTasksConfigPath = this.fileSystem.Path.GetTempFileName(); - var helpDevTasksConfigJson = -$@"{{ - ""answers"": {{ - ""packagePrefix"": ""cmf.docs.area"", - ""registry"": ""{npmRegistry}"", - ""confirmSkip"": ""y"", - ""channel"": ""release-{mesVersion.Major}{mesVersion.Minor}{mesVersion.Build}"" - }} -}}"; - this.fileSystem.File.WriteAllText(helpDevTasksConfigPath, helpDevTasksConfigJson); - var helpWebAppConfigPath = this.fileSystem.Path.GetTempFileName(); - var helpWebAppConfigJson = -@"{ - ""answers"": { - ""appName"": ""web"", - ""basePackage"": ""other"", - ""otherPackage"": ""cmf.docs.web"" - } -}"; - this.fileSystem.File.WriteAllText(helpWebAppConfigPath, helpWebAppConfigJson); - - // create web app - // npx yeoman-gen-run --name @criticalmanufacturing/html --config "$pathHTMLConfig" - Log.Verbose("Generate web app, this will take a while..."); - (new NPXCommand() - { - Command = "yeoman-gen-run", - WorkingDirectory = pkgFolder, - Args = new[] - { - "--name", "@criticalmanufacturing/html", "--config", helpDevTasksConfigPath - } - }).Exec(); - // npx yeoman-gen-run --name @criticalmanufacturing/html:application cmf.docs.area.web --config "$path" - (new NPXCommand() - { - Command = "yeoman-gen-run", - WorkingDirectory = pkgFolder, - Args = new[] - { - "--name", "@criticalmanufacturing/html:application", "cmf.docs.area.web", "--config", helpWebAppConfigPath - } - }).Exec(); - Log.Verbose("Web app generated!"); - - - Log.Debug("Obtaining sources from MES Documentation package..."); - var docPkgConfigJsonStr = FileSystemUtilities.GetFileContentFromPackage(documentationPackage.FullName, "config.json"); - // replace tokens that would break Json parse - docPkgConfigJsonStr = Regex.Replace(docPkgConfigJsonStr, @"\$\([^\)]+\)", "0", RegexOptions.Multiline); - dynamic docPkgConfigJson = JsonConvert.DeserializeObject(docPkgConfigJsonStr); - var docPkgIndexHtml = FileSystemUtilities.GetFileContentFromPackage(documentationPackage.FullName, "index.html"); - - // config.json - var configJsonPath = this.fileSystem.Path.Join(pkgFolder.FullName, "apps", - this.fileSystem.Path.Join("cmf.docs.area.web", "config.json")); - var configJsonStr = fileSystem.File.ReadAllText(configJsonPath); - configJsonStr = Regex.Replace(configJsonStr, @"\$\([^\)]+\)", "0", RegexOptions.Multiline); - dynamic configJsonJson = JsonConvert.DeserializeObject(configJsonStr); - if (configJsonJson == null) - { - throw new CliException("Could not load config.json"); - } - var restPort = ExecutionContext.Instance.ProjectConfig.RESTPort; - configJsonJson.host.rest.enableSsl = false; - configJsonJson.host.rest.address = "localhost"; - configJsonJson.host.rest.port = restPort; - configJsonJson.host.isLoadBalancerEnabled = false; - configJsonJson.host.tenant.name = ExecutionContext.Instance.ProjectConfig.Tenant; - configJsonJson.general.defaultDomain = ExecutionContext.Instance.ProjectConfig.DefaultDomain; - configJsonJson.version = $"{projectName} $(Build.BuildNumber) - {mesVersion}"; - configJsonJson.packages.available = docPkgConfigJson.packages.available; - configJsonJson.packages.Remove("bundlePath"); - if (configJsonJson.packages.bundles != null) - { - configJsonJson.packages.bundles.metadata = false; - configJsonJson.packages.bundles.i18n = false; - } - configJsonStr = JsonConvert.SerializeObject(configJsonJson, Formatting.Indented); - this.fileSystem.File.WriteAllText(configJsonPath, configJsonStr); - Log.Verbose("Updated config.json"); - - //index.html (copied from Documentation package) - var indexHtmlPath = this.fileSystem.Path.Join(pkgFolder.FullName, "apps", - this.fileSystem.Path.Join("cmf.docs.area.web", "index.html")); - this.fileSystem.File.WriteAllText(indexHtmlPath, docPkgIndexHtml.Replace("", "")); - - // generate doc package - Log.Verbose("Generating documentation package. This will take a while..."); - var tenant = ExecutionContext.Instance.ProjectConfig.Tenant; - var assetsPkgName = $"cmf.docs.area.{pkgName.ToLowerInvariant()}"; - var helpPkgConfigPath = this.fileSystem.Path.GetTempFileName(); - var helpPkgConfigJson = -$@"{{ - ""answers"": {{ - ""packageName"": ""{assetsPkgName}"", - ""dependencies"": ""{assetsPkgName}"" - }} -}}"; - this.fileSystem.File.WriteAllText(helpPkgConfigPath, helpPkgConfigJson); - (new NPXCommand() - { - Command = "yeoman-gen-run", - WorkingDirectory = pkgFolder, - Args = new[] - { - // the package name must be in the same argument as the generator name: this is a yeoman-gen-run limitation: - // when yeoman-gen-run runs env.run(genName, doneFunc), genName gets split into [name, ...args] which causes args to be empty - // the actual invocation should be env.run([genName, ...config.cli.args], doneFunc) - "--name", $@"""@criticalmanufacturing/html:package {assetsPkgName}""", "--config", helpPkgConfigPath - } - }).Exec(); - Log.Verbose("Generated documentation package"); - - Log.Verbose("Generating assets..."); - base.ExecuteTemplate("helpSrcPkg", new[] - { - "--output", this.fileSystem.Path.Join(pkgFolder.FullName, "src", "packages"), - "--name", assetsPkgName, - "--dfPackageName", pkgName.ToLowerInvariant(), - "--Tenant", tenant - }); - - Log.Verbose("Changing web app port and package type..."); - // replace type of package gulpfile - var assetsPkgGulpFilePath = this.fileSystem.Path.Join(pkgFolder.FullName, "src", - this.fileSystem.Path.Join("packages", assetsPkgName, "gulpfile.js")); - var assetsPkgGulpFile = fileSystem.File.ReadAllText(assetsPkgGulpFilePath); - this.fileSystem.File.WriteAllText(assetsPkgGulpFilePath, assetsPkgGulpFile.Replace("type: 'module'", "type: 'documentation'")); - // replace port of webapp gulpfile - var webAppGulpFilePath = this.fileSystem.Path.Join(pkgFolder.FullName, - this.fileSystem.Path.Join("apps", "cmf.docs.area.web", "gulpfile.js")); - var webAppGulpFile = fileSystem.File.ReadAllText(webAppGulpFilePath); - this.fileSystem.File.WriteAllText(webAppGulpFilePath, webAppGulpFile.Replace("defaultPort: 7000", "defaultPort: 7001")); - Log.Information("Help package generated"); - } - - public void ExecuteV10(IDirectoryInfo workingDir, string version, int majorVersion) + public void Execute(IDirectoryInfo workingDir, string version) { + int majorVersion = ExecutionContext.Instance.ProjectConfig.MESVersion.Major; var ngxSchematicsVersion = ExecutionContext.Instance.ProjectConfig.NGXSchematicsVersion; if (ngxSchematicsVersion == null) { @@ -371,7 +155,6 @@ public void ExecuteV10(IDirectoryInfo workingDir, string version, int majorVersi "--name", assetsPkgName, "--dfPackageName", projectName, "--Tenant", tenant, - "--v10metadata", true.ToString(), "--dfPackageNamePascalCase", string.Join("", projectName.Split("-").Select(seg => Regex.Replace(seg, @"\b(\w)", m => m.Value.ToUpper()))) }); diff --git a/cmf-cli/Commands/new/IoTCommand.cs b/cmf-cli/Commands/new/IoTCommand.cs index f1e0f2de2..f96152391 100644 --- a/cmf-cli/Commands/new/IoTCommand.cs +++ b/cmf-cli/Commands/new/IoTCommand.cs @@ -10,9 +10,9 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New { @@ -41,18 +41,30 @@ public IoTCommand(IFileSystem fileSystem) : base("iot", PackageType.IoT, fileSys public override void Configure(Command cmd) { - base.GetBaseCommandConfig(cmd); - - cmd.AddOption(new Option( - aliases: new[] { "--htmlPackageLocation" }, - description: "Location of the HTML Package" - )); - - cmd.AddOption(new Option( - aliases: new[] { "--isAngularPackage" }, - description: "Customization package with angular" - )); - cmd.Handler = CommandHandler.Create(this.Execute); + var (workingDirArg, versionOpt) = base.GetBaseCommandConfig(cmd); + + var htmlPackageLocationOption = new Option("--htmlPackageLocation") + { + Description = "Location of the HTML Package" + }; + cmd.Add(htmlPackageLocationOption); + + var isAngularPackageOption = new Option("--isAngularPackage") + { + Description = "Customization package with angular" + }; + cmd.Add(isAngularPackageOption); + + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArg); + var version = parseResult.GetValue(versionOpt); + var htmlPackageLocation = parseResult.GetValue(htmlPackageLocationOption); + var isAngularPackage = parseResult.GetValue(isAngularPackageOption); + + Execute(workingDir, version, htmlPackageLocation, isAngularPackage); + return Task.FromResult(0); + }); } /// @@ -100,32 +112,24 @@ protected override List GenerateArgs(IDirectoryInfo projectRoot, IDirect public void Execute(IDirectoryInfo workingDir, string version, string htmlPackageLocation, bool isAngularPackage) { var mesVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - if (mesVersion.Major > 9) + // (ATL) Automation Task Library Package + // only introduced in v10.2.7 + var executeV10ATL = !isAngularPackage && mesVersion >= new Version(10, 2, 7) && mesVersion < new Version(11, 0, 0); + + // only introduced in v11 + var executeV11ATL = !isAngularPackage && mesVersion >= new Version(11, 0, 0); + + if (executeV10ATL) + { + this.ExecuteV10ATL(workingDir, version); + } + else if (executeV11ATL) { - // (ATL) Automation Task Library Package - // only introduced in v10.2.7 - var executeV10ATL = !isAngularPackage && mesVersion >= new Version(10, 2, 7) && mesVersion < new Version(11, 0, 0); - - // only introduced in v11 - var executeV11ATL = !isAngularPackage && mesVersion >= new Version(11, 0, 0); - - if (executeV10ATL) - { - this.ExecuteV10ATL(workingDir, version); - } - else if (executeV11ATL) - { - this.ExecuteV11ATL(workingDir, version); - } - else - { - this.ExecuteV10AngularPackage(workingDir, version, htmlPackageLocation); - } + this.ExecuteV11ATL(workingDir, version); } else { - this.CommandName = "iot-upto9x"; - base.Execute(workingDir, version); + this.ExecuteV10AngularPackage(workingDir, version, htmlPackageLocation); } } diff --git a/cmf-cli/Commands/new/NewCommand.cs b/cmf-cli/Commands/new/NewCommand.cs index e91eae81e..356ebf2dd 100644 --- a/cmf-cli/Commands/new/NewCommand.cs +++ b/cmf-cli/Commands/new/NewCommand.cs @@ -1,6 +1,6 @@ using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Commands; @@ -13,6 +13,7 @@ namespace Cmf.CLI.Commands public class NewCommand : TemplateCommand { private Command _cmd; + /// /// Configure command /// @@ -20,11 +21,19 @@ public class NewCommand : TemplateCommand public override void Configure(Command cmd) { this._cmd = cmd; - cmd.AddOption(new Option( - aliases: new[] { "--reset" }, - description: "Reset template engine. Use this if after an upgrade the templates are not working correctly." - )); - cmd.Handler = CommandHandler.Create(Execute); + + var resetOption = new Option("--reset") + { + Description = "Reset template engine. Use this if after an upgrade the templates are not working correctly." + }; + cmd.Add(resetOption); + + cmd.SetAction((parseResult, cancellationToken) => + { + var reset = parseResult.GetValue(resetOption); + Execute(reset); + return Task.FromResult(0); + }); } /// @@ -39,7 +48,9 @@ public void Execute(bool reset) } else { - this._cmd.Invoke(new[] { "-h" }); + // In beta5, use Parse and Invoke pattern instead of direct Invoke + var parseResult = this._cmd.Parse(new[] { "-h" }); + parseResult.Invoke(); } } diff --git a/cmf-cli/Commands/new/TestCommand.cs b/cmf-cli/Commands/new/TestCommand.cs index b9bf9f99e..49a8fbc01 100644 --- a/cmf-cli/Commands/new/TestCommand.cs +++ b/cmf-cli/Commands/new/TestCommand.cs @@ -5,10 +5,11 @@ using Cmf.CLI.Utilities; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; -using System.Linq; using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Cmf.CLI.Services; namespace Cmf.CLI.Commands.New { @@ -31,12 +32,19 @@ public TestCommand(IFileSystem fileSystem) : base("tests", PackageType.Tests, fi /// public override void Configure(Command cmd) { - cmd.AddOption(new Option( - aliases: new[] { "--version" }, - description: "Package Version", - getDefaultValue: () => "1.0.0" - )); - cmd.Handler = CommandHandler.Create(Execute); + var versionOption = new Option("--version") + { + Description = "Package Version", + DefaultValueFactory = _ => "1.0.0" + }; + cmd.Add(versionOption); + + cmd.SetAction((parseResult, cancellationToken) => + { + var version = parseResult.GetValue(versionOption); + Execute(version); + return Task.FromResult(0); + }); } /// @@ -98,7 +106,7 @@ public void Execute(string version) } #region version-specific bits - args.AddRange(new []{ "--targetFramework", mesVersion.Major > 8 ? mesVersion.Major >= 11 ? "net8.0" : "net6.0" : "netcoreapp3.1" }); + args.AddRange(new []{ "--targetFramework", ExecutionContext.ServiceProvider.GetService().DotNetTargetFramework(mesVersion) }); if (mesVersion >= new Version(11, 2, 3)) { @@ -112,4 +120,4 @@ public void Execute(string version) base.RegisterAsDependencyInParent("Cmf.Custom.Tests.MasterData", version, projectRoot.FullName, isTestPackage: true); } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/new/iot/GenerateBusinessScenarioCommand.cs b/cmf-cli/Commands/new/iot/GenerateBusinessScenarioCommand.cs index f117aefd6..2bd722bd7 100644 --- a/cmf-cli/Commands/new/iot/GenerateBusinessScenarioCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateBusinessScenarioCommand.cs @@ -8,8 +8,8 @@ using Spectre.Console; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -43,17 +43,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); - + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// @@ -92,7 +95,6 @@ private List GenerateArgs( string packageVersion, string identifier) { - var mesVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; Log.Debug($"Creating IoT Task Library Package at {workingDir}"); var args = new List(); diff --git a/cmf-cli/Commands/new/iot/GenerateConverterCommand.cs b/cmf-cli/Commands/new/iot/GenerateConverterCommand.cs index 129b86498..a39ef1461 100644 --- a/cmf-cli/Commands/new/iot/GenerateConverterCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateConverterCommand.cs @@ -10,9 +10,9 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Text; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -45,16 +45,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/new/iot/GenerateDotnetDriverCommand.cs b/cmf-cli/Commands/new/iot/GenerateDotnetDriverCommand.cs index 1798d5d6f..83cf0791f 100644 --- a/cmf-cli/Commands/new/iot/GenerateDotnetDriverCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateDotnetDriverCommand.cs @@ -8,8 +8,8 @@ using Spectre.Console; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -42,16 +42,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/new/iot/GenerateDotnetFrameworkDriverCommand.cs b/cmf-cli/Commands/new/iot/GenerateDotnetFrameworkDriverCommand.cs index 53d279a65..4570a9f68 100644 --- a/cmf-cli/Commands/new/iot/GenerateDotnetFrameworkDriverCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateDotnetFrameworkDriverCommand.cs @@ -8,8 +8,8 @@ using Spectre.Console; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -42,16 +42,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/new/iot/GenerateDriverCommand.cs b/cmf-cli/Commands/new/iot/GenerateDriverCommand.cs index a881c12f0..067963f14 100644 --- a/cmf-cli/Commands/new/iot/GenerateDriverCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateDriverCommand.cs @@ -8,8 +8,8 @@ using Spectre.Console; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -42,16 +42,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/new/iot/GenerateTaskCommand.cs b/cmf-cli/Commands/new/iot/GenerateTaskCommand.cs index f1b8053cc..b5a58cb2e 100644 --- a/cmf-cli/Commands/new/iot/GenerateTaskCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateTaskCommand.cs @@ -11,9 +11,9 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -50,16 +50,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/new/iot/GenerateTaskLibraryCommand.cs b/cmf-cli/Commands/new/iot/GenerateTaskLibraryCommand.cs index 36da973d3..6dff59428 100644 --- a/cmf-cli/Commands/new/iot/GenerateTaskLibraryCommand.cs +++ b/cmf-cli/Commands/new/iot/GenerateTaskLibraryCommand.cs @@ -10,9 +10,9 @@ using Spectre.Console; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.New.IoT { @@ -46,17 +46,20 @@ public override void Configure(Command cmd) this.fileSystem ); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, nearestIoTPackage?.FullName), - isDefault: true - ) + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); - + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, nearestIoTPackage?.FullName), + DefaultValueFactory = _ => Parse(null, nearestIoTPackage?.FullName) + }; + cmd.Add(workingDirArgument); - cmd.Handler = CommandHandler.Create(this.Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workingDir = parseResult.GetValue(workingDirArgument); + Execute(workingDir); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/pack/PackCommand.cs b/cmf-cli/Commands/pack/PackCommand.cs index b363bff0b..ed7b2b692 100644 --- a/cmf-cli/Commands/pack/PackCommand.cs +++ b/cmf-cli/Commands/pack/PackCommand.cs @@ -1,4 +1,3 @@ - using Cmf.CLI.Constants; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Interfaces; @@ -8,8 +7,8 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -47,31 +46,46 @@ public override void Configure(Command cmd) { workingDir = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, workingDir), - isDefault: true - ) + + var workingDirArgument = new Argument("workingDir") { - Description = "Working Directory" - }); + Description = "Working Directory", + DefaultValueFactory = _ => Parse(null, workingDir), + CustomParser = argResult => Parse(argResult, workingDir) + }; + cmd.Add(workingDirArgument); - cmd.AddOption(new Option( - aliases: new string[] { "-o", "--outputDir" }, - parseArgument: argResult => Parse(argResult, $"{workingDir}/Package"), - isDefault: true, - description: "Output directory for created package")); + var outputDirOption = new Option("--outputDir", "-o") + { + Description = "Output directory for created package", + DefaultValueFactory = _ => Parse(null, $"{workingDir}/Package"), + CustomParser = argResult => Parse(argResult, $"{workingDir}/Package") + }; + cmd.Add(outputDirOption); - cmd.AddOption(new Option( - aliases: new string[] { "-f", "--force" }, - description: "Overwrite all packages even if they already exists")); + var forceOption = new Option("--force", "-f") + { + Description = "Overwrite all packages even if they already exists" + }; + cmd.Add(forceOption); - cmd.AddOption(new Option( - aliases: new string[] { "--dry-run" }, - description: "List the final structure of the package without creating files")); + var dryRunOption = new Option("--dry-run") + { + Description = "List the final structure of the package without creating files" + }; + cmd.Add(dryRunOption); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var workDir = parseResult.GetValue(workingDirArgument); + var outputDir = parseResult.GetValue(outputDirOption); + var force = parseResult.GetValue(forceOption); + var dryRun = parseResult.GetValue(dryRunOption); + + Execute(workDir, outputDir, force, dryRun); + return Task.FromResult(0); + }); } /// @@ -146,4 +160,4 @@ public void Execute(CmfPackage cmfPackage, IDirectoryInfo outputDir, bool force, } } } -} +} \ No newline at end of file diff --git a/cmf-cli/Commands/plugin/NewPluginCommand.cs b/cmf-cli/Commands/plugin/NewPluginCommand.cs index 81c08ab8d..e2ee96bc4 100644 --- a/cmf-cli/Commands/plugin/NewPluginCommand.cs +++ b/cmf-cli/Commands/plugin/NewPluginCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Commands; @@ -23,27 +23,42 @@ public NewPluginCommand(IFileSystem fileSystem) : base("plugin", fileSystem) public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "name", - description: "The name of the plugin. Will also be used as NPM package id, so make sure it is valid for this purpose. If you are scoping the package, you need to escape the organization name, e.g. \\@org/package." - )); - cmd.AddArgument(new Argument( - name: "binary", - description: "The name of the plugin binary. This name will be prefixed with 'cmf-' to be handled by the CLI, e.g. examplePlugin will generate the cmf-examplePlugin binary in the path" - )); - cmd.AddArgument(new Argument( - name: "description", - description: "The command description, e.g. \"My amazing plugin\"" - )); - cmd.AddArgument(new Argument( - name: "workingDir", - parse: (argResult) => Parse(argResult, "."), - isDefault: true - ) + var nameArgument = new Argument("name") { - Description = "Working Directory" + Description = "The name of the plugin. Will also be used as NPM package id, so make sure it is valid for this purpose. If you are scoping the package, you need to escape the organization name, e.g. \\@org/package." + }; + cmd.Add(nameArgument); + + var binaryArgument = new Argument("binary") + { + Description = "The name of the plugin binary. This name will be prefixed with 'cmf-' to be handled by the CLI, e.g. examplePlugin will generate the cmf-examplePlugin binary in the path" + }; + cmd.Add(binaryArgument); + + var descriptionArgument = new Argument("description") + { + Description = "The command description, e.g. \"My amazing plugin\"" + }; + cmd.Add(descriptionArgument); + + var workingDirArgument = new Argument("workingDir") + { + Description = "Working Directory", + CustomParser = argResult => Parse(argResult, "."), + DefaultValueFactory = _ => Parse(null, ".") + }; + cmd.Add(workingDirArgument); + + cmd.SetAction((parseResult, cancellationToken) => + { + var name = parseResult.GetValue(nameArgument); + var binary = parseResult.GetValue(binaryArgument); + var description = parseResult.GetValue(descriptionArgument); + var workingDir = parseResult.GetValue(workingDirArgument); + + Execute(name, binary, description, workingDir); + return Task.FromResult(0); }); - cmd.Handler = CommandHandler.Create(this.Execute); } public void Execute(string name, string binary, string description, IDirectoryInfo workingDir) diff --git a/cmf-cli/Commands/plugin/PluginCommand.cs b/cmf-cli/Commands/plugin/PluginCommand.cs index e835d76e4..29af2a2e0 100644 --- a/cmf-cli/Commands/plugin/PluginCommand.cs +++ b/cmf-cli/Commands/plugin/PluginCommand.cs @@ -2,9 +2,8 @@ using System.Linq; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; -using System.CommandLine.Parsing; using System.Diagnostics; +using System.Threading.Tasks; using Cmf.CLI.Core; using Cmf.CLI.Core.Enums; using Cmf.CLI.Utilities; @@ -43,15 +42,14 @@ public PluginCommand(string commandName, string commandPath) /// /// public override void Configure(Command cmd) - { - cmd.TreatUnmatchedTokensAsErrors = false; + { // Add the handler - cmd.Handler = CommandHandler.Create( - (ParseResult parseResult, IConsole console) => - { - // console.Out.WriteLine($"{parseResult}"); - this.Execute(parseResult.UnparsedTokens); - }); + cmd.SetAction((parseResult, cancellationToken) => + { + // Get unmatched tokens from parseResult + this.Execute(parseResult.UnmatchedTokens); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/plugin/PluginsCommand.cs b/cmf-cli/Commands/plugin/PluginsCommand.cs index 501dd35a0..2127f21aa 100644 --- a/cmf-cli/Commands/plugin/PluginsCommand.cs +++ b/cmf-cli/Commands/plugin/PluginsCommand.cs @@ -1,6 +1,6 @@ using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; +using System.Threading.Tasks; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Objects; @@ -14,10 +14,18 @@ public class PluginsCommand : BaseCommand { public override void Configure(Command cmd) { - cmd.AddOption(new Option( - aliases: new [] { "-r", "--registry" }, - description: "Registries to query for plugins. If unspecified, uses the default NPMJS registry.")); - cmd.Handler = CommandHandler.Create(Execute); + var registryOption = new Option("--registry", "-r") + { + Description = "Registries to query for plugins. If unspecified, uses the default NPMJS registry." + }; + cmd.Add(registryOption); + + cmd.SetAction((parseResult, cancellationToken) => + { + var registry = parseResult.GetValue(registryOption); + Execute(registry); + return Task.FromResult(0); + }); } public void Execute(Uri[] registry) diff --git a/cmf-cli/Commands/publish/PublishCommand.cs b/cmf-cli/Commands/publish/PublishCommand.cs index 2c320e82c..209decc49 100644 --- a/cmf-cli/Commands/publish/PublishCommand.cs +++ b/cmf-cli/Commands/publish/PublishCommand.cs @@ -1,8 +1,8 @@ using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Interfaces; @@ -34,44 +34,46 @@ public PublishCommand(IFileSystem fileSystem) : base(fileSystem) { } public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "file", - parse: (argResult) => Parse(argResult), - isDefault: false) + var fileArgument = new Argument("file") { - Description = "Package file" - }); + Description = "Package file", + CustomParser = argResult => Parse(argResult) + }; + cmd.Add(fileArgument); - cmd.AddOption(new Option( - aliases: new string[] { "--ci" }, - description: "Use the Continuous Integration repository URL from the repositories file" - )); + var ciOption = new Option("--ci") + { + Description = "Use the Continuous Integration repository URL from the repositories file" + }; + cmd.Add(ciOption); - cmd.AddOption(new Option( - aliases: new string[] { "--release" }, - description: "Use the first non-CI repository URL from the repositories file" - )); + var releaseOption = new Option("--release") + { + Description = "Use the first non-CI repository URL from the repositories file" + }; + cmd.Add(releaseOption); - cmd.AddOption(new Option( - aliases: new string[] { "--repository" }, - description: "Repository the package should be published to", - parseArgument: result => - { - var value = result.Tokens[0].Value; - if (!Uri.TryCreate(value, UriKind.Absolute, out var uri)) - { - result.ErrorMessage = "The repository must be a valid absolute URI."; - return null; - } - return uri; - } - )); + var repositoryOption = new Option("--repository") + { + Description = "Repository the package should be published to", + CustomParser = argResult => ParseUri(argResult) + }; + cmd.Add(repositoryOption); - cmd.IsHidden = + cmd.Hidden = !(ExecutionContext.ServiceProvider?.GetService()?.UseRepositoryClients ?? false); // Add the handler - cmd.Handler = CommandHandler.Create(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var file = parseResult.GetValue(fileArgument); + var repository = parseResult.GetValue(repositoryOption); + var ci = parseResult.GetValue(ciOption); + var release = parseResult.GetValue(releaseOption); + + Execute(file, repository, ci, release); + return Task.FromResult(0); + }); } public void Execute(IFileInfo file, Uri repository, bool ci, bool release) @@ -102,7 +104,6 @@ public void Execute(IFileInfo file, Uri repository, bool ci, bool release) $"The `--{(ci ? "ci" : "release")}` flag can only be used when no explicit `--repository is passed`."); } - var repositoryLocator = ExecutionContext.ServiceProvider?.GetService(); if (ci) { diff --git a/cmf-cli/Commands/restore/RestoreCommand.cs b/cmf-cli/Commands/restore/RestoreCommand.cs index cd1761df0..c03cd1eef 100644 --- a/cmf-cli/Commands/restore/RestoreCommand.cs +++ b/cmf-cli/Commands/restore/RestoreCommand.cs @@ -7,8 +7,8 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO.Abstractions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands.restore { @@ -39,9 +39,11 @@ public RestoreCommand(IFileSystem fileSystem) : base(fileSystem) { } /// public override void Configure(Command cmd) { - cmd.AddOption(new Option( - aliases: new string[] { "-r", "--repos", "--repo" }, - description: "Repositories where dependencies are located (folder)")); + var reposOption = new Option("--repos", "-r", "--repo") + { + Description = "Repositories where dependencies are located (folder)" + }; + cmd.Add(reposOption); var packageRoot = FileSystemUtilities.GetPackageRoot(this.fileSystem); var packagePath = "."; @@ -49,13 +51,23 @@ public override void Configure(Command cmd) { packagePath = this.fileSystem.Path.GetRelativePath(this.fileSystem.Directory.GetCurrentDirectory(), packageRoot.FullName); } - var arg = new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, packagePath), - isDefault: true, - description: "Package path"); - cmd.AddArgument(arg); - cmd.Handler = CommandHandler.Create(Execute); + + var packagePathArgument = new Argument("packagePath") + { + Description = "Package path", + CustomParser = argResult => Parse(argResult, packagePath), + DefaultValueFactory = _ => Parse(null, packagePath) + }; + cmd.Add(packagePathArgument); + + cmd.SetAction((parseResult, cancellationToken) => + { + var pkgPath = parseResult.GetValue(packagePathArgument); + var repos = parseResult.GetValue(reposOption); + + Execute(pkgPath, repos); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/upgrade/UpgradeBaseCommand.cs b/cmf-cli/Commands/upgrade/UpgradeBaseCommand.cs index 9785a0dea..eff96cb4c 100644 --- a/cmf-cli/Commands/upgrade/UpgradeBaseCommand.cs +++ b/cmf-cli/Commands/upgrade/UpgradeBaseCommand.cs @@ -1,4 +1,3 @@ -using Cmf.CLI.Constants; using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Constants; @@ -7,15 +6,12 @@ using Cmf.CLI.Factories; using Cmf.CLI.Utilities; using Microsoft.Extensions.DependencyInjection; -using SharpCompress.Common; using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; using System.IO; using System.IO.Abstractions; -using System.Linq; -using System.Text.RegularExpressions; +using System.Threading.Tasks; namespace Cmf.CLI.Commands { @@ -48,31 +44,43 @@ public UpgradeBaseCommand(IFileSystem fileSystem) : base(fileSystem) /// public override void Configure(Command cmd) { - cmd.AddArgument(new Argument( - name: "packagePath", - parse: (argResult) => Parse(argResult, "."), - description: "Package path")); - - cmd.AddArgument(new Argument( - name: "BaseVersion", - description: "New framework/MES Version" - )); - - cmd.AddOption(new Option( - aliases: new string[] { "-iot", "--iotVersion" }, - description: "New MES version for the IoT workflows & masterdatas." - )); - - cmd.AddOption(new Option>( - aliases: new string[] { "-ignore", "--iotPackagesToIgnore" }, - description: "IoT packages to ignore when updating the MES version of the tasks in IoT workflows" - ) + var packagePathArgument = new Argument("packagePath") { - AllowMultipleArgumentsPerToken = true, - }); + Description = "Package path", + CustomParser = argResult => Parse(argResult, ".") + }; + cmd.Add(packagePathArgument); + + var baseVersionArgument = new Argument("BaseVersion") + { + Description = "New framework/MES Version" + }; + cmd.Add(baseVersionArgument); + + var iotVersionOption = new Option("--iotVersion", "-iot") + { + Description = "New MES version for the IoT workflows & masterdatas." + }; + cmd.Add(iotVersionOption); + + var iotPackagesToIgnoreOption = new Option>("--iotPackagesToIgnore", "-ignore") + { + Description = "IoT packages to ignore when updating the MES version of the tasks in IoT workflows", + AllowMultipleArgumentsPerToken = true + }; + cmd.Add(iotPackagesToIgnoreOption); // Add the handler - cmd.Handler = CommandHandler.Create>(Execute); + cmd.SetAction((parseResult, cancellationToken) => + { + var packagePath = parseResult.GetValue(packagePathArgument); + var baseVersion = parseResult.GetValue(baseVersionArgument); + var iotVersion = parseResult.GetValue(iotVersionOption); + var iotPackagesToIgnore = parseResult.GetValue(iotPackagesToIgnoreOption); + + Execute(packagePath, baseVersion, iotVersion, iotPackagesToIgnore); + return Task.FromResult(0); + }); } /// diff --git a/cmf-cli/Commands/upgrade/UpgradeCommand.cs b/cmf-cli/Commands/upgrade/UpgradeCommand.cs deleted file mode 100644 index ab1832199..000000000 --- a/cmf-cli/Commands/upgrade/UpgradeCommand.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Cmf.CLI.Constants; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Attributes; -using Cmf.CLI.Core.Constants; -using Cmf.CLI.Core.Interfaces; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Factories; -using Cmf.CLI.Utilities; -using Microsoft.Extensions.DependencyInjection; -using SharpCompress.Common; -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.NamingConventionBinder; -using System.IO; -using System.IO.Abstractions; -using System.Linq; -using System.Text.RegularExpressions; - -namespace Cmf.CLI.Commands -{ - /// - /// Dummy upgrade command (only here to make "cmf upgrade base" work) - /// - /// - [CmfCommand("upgrade", Id = "upgrade", Description = "Project upgrade utilities")] - public class UpgradeCommand : BaseCommand - { - - /// - /// constructor for System.IO filesystem - /// - public UpgradeCommand() : base() - { - } - - /// - /// constructor - /// - /// - public UpgradeCommand(IFileSystem fileSystem) : base(fileSystem) - { - } - - /// - /// Configure command - /// - /// - public override void Configure(Command cmd) - { - // Add the handler - cmd.Handler = CommandHandler.Create(Execute); - } - - public void Execute(IDirectoryInfo packagePath) {} - } -} \ No newline at end of file diff --git a/cmf-cli/Constants/CliConstants.cs b/cmf-cli/Constants/CliConstants.cs index c0c059d7d..038cfee4a 100644 --- a/cmf-cli/Constants/CliConstants.cs +++ b/cmf-cli/Constants/CliConstants.cs @@ -14,11 +14,6 @@ public static class CliConstants /// public const string FolderTemplates = "templateFiles"; - /// - /// The folder install dependencies - /// - public const string FolderInstallDependencies = "installDependencies"; - /// /// Tests Folder /// diff --git a/cmf-cli/Factories/PackageTypeFactory.cs b/cmf-cli/Factories/PackageTypeFactory.cs index 642b6559a..762790537 100644 --- a/cmf-cli/Factories/PackageTypeFactory.cs +++ b/cmf-cli/Factories/PackageTypeFactory.cs @@ -45,75 +45,29 @@ public static IPackageTypeHandler GetPackageTypeHandler(CmfPackage cmfPackage, b PackageType.Root => new RootPackageTypeHandler(cmfPackage), PackageType.Generic => new GenericPackageTypeHandler(cmfPackage), PackageType.Business => new BusinessPackageTypeHandler(cmfPackage), - PackageType.HTML => HtmlHandler(cmfPackage), - PackageType.Help => HelpHandler(cmfPackage), + PackageType.HTML => new HtmlNgCliPackageTypeHandler(cmfPackage), + PackageType.Help => new HelpNgCliPackageTypeHandler(cmfPackage), PackageType.IoT => new IoTPackageTypeHandler(cmfPackage), PackageType.IoTData => cmfPackage.HandlerVersion switch { - 2 => new IoTDataPackageTypeHandlerV2(cmfPackage), - 1 => new IoTDataPackageTypeHandler(cmfPackage), + 1 => throw new CliException("Support for V1 Data packages was removed in CLI 6.0.0"), _ => new IoTDataPackageTypeHandlerV2(cmfPackage) }, PackageType.Data => cmfPackage.HandlerVersion switch { - 2 => new DataPackageTypeHandlerV2(cmfPackage), - 1 => new DataPackageTypeHandler(cmfPackage), + 1 => throw new CliException("Support for V1 Data packages was removed in CLI 6.0.0"), _ => new DataPackageTypeHandlerV2(cmfPackage) }, PackageType.Reporting => new ReportingPackageTypeHandler(cmfPackage), PackageType.ExportedObjects => new ExportedObjectsPackageTypeHandler(cmfPackage), PackageType.Database => new DatabasePackageTypeHandler(cmfPackage), PackageType.Tests => new TestPackageTypeHandler(cmfPackage), - PackageType.SecurityPortal => SecurityPortalHandler(cmfPackage), + PackageType.SecurityPortal => new SecurityPortalPackageTypeHandlerV2(cmfPackage), PackageType.Grafana => new GrafanaPackageTypeHandler(cmfPackage), _ => throw new CliException(string.Format(CoreMessages.PackageTypeHandlerNotImplemented, cmfPackage.PackageType.ToString())) }; return packageTypeHandler; } - - private static IPackageTypeHandler HelpHandler(CmfPackage cmfPackage) - { - var targetVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - var minimumVersion = new Version("10.0.0"); - if (targetVersion.CompareTo(minimumVersion) < 0) - { - return new HelpGulpPackageTypeHandler(cmfPackage); - } - - return new HelpNgCliPackageTypeHandler(cmfPackage); - } - - private static IPackageTypeHandler HtmlHandler(CmfPackage cmfPackage) - { - var targetVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - var minimumVersion = new Version("10.0.0"); - if (targetVersion.CompareTo(minimumVersion) < 0) - { - return new HtmlGulpPackageTypeHandler(cmfPackage); - } - - return new HtmlNgCliPackageTypeHandler(cmfPackage); - } - - /// - /// Creates the specific Security Portal package handler. - /// - /// If the ProjectConfig's MESVersion is less than 10.0.0, a is created and returned. - /// Otherwise, a is created and returned. - /// - /// - /// - private static IPackageTypeHandler SecurityPortalHandler(CmfPackage cmfPackage) - { - var targetVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - var minimumVersion = new Version("10.0.0"); - if (targetVersion.CompareTo(minimumVersion) < 0) - { - return new SecurityPortalPackageTypeHandler(cmfPackage); - } - - return new SecurityPortalPackageTypeHandlerV2(cmfPackage); - } } } diff --git a/cmf-cli/Handlers/PackageType/DataPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/DataPackageTypeHandler.cs deleted file mode 100644 index 3e960193c..000000000 --- a/cmf-cli/Handlers/PackageType/DataPackageTypeHandler.cs +++ /dev/null @@ -1,84 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using Cmf.CLI.Builders; -using Cmf.CLI.Constants; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Enums; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Utilities; - -namespace Cmf.CLI.Handlers -{ - /// - /// - /// - /// - public class DataPackageTypeHandler : PackageTypeHandler - { - /// - /// Initializes a new instance of the class. - /// - /// The CMF package. - public DataPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) - { - Log.Debug("Using Data Handler v1"); - // TargetDirectory with DateTimeStamp to avoid wrong files installation - cmfPackage.SetDefaultValues - ( - isUniqueInstall: - true, - targetDirectory: - $"installPackages/{cmfPackage.PackageId}.{cmfPackage.Version}-{DateTime.Now.ToString("yyyyMMddHHmmss")}", - steps: - new List() - { - new Step(StepType.DeployFiles) - { - ContentPath = "**/**" - }, - new Step(StepType.Generic) - { - OnExecute = $"$(Package[{cmfPackage.PackageId}].TargetDirectory)/RunCustomizationInstallDF.ps1" - } - } - ); - - BuildSteps = new IBuildCommand[] - { - new JSONValidatorCommand() - { - DisplayName = "JSON Validator Command", - FilesToValidate = GetContentToPack(this.fileSystem.DirectoryInfo.New(".")) - } - }; - - cmfPackage.DFPackageType = PackageType.Business; - } - - /// - /// Copies the install dependencies. - /// - /// The package output dir. - protected override void CopyInstallDependencies(IDirectoryInfo packageOutputDir) - { - FileSystemUtilities.CopyInstallDependenciesFiles(packageOutputDir, PackageType.Data, this.fileSystem); - - string globalVariablesPath = this.fileSystem.Path.Join(packageOutputDir.FullName, "Builds/.vars", "global.yml"); - - string globalVariablesFile = this.fileSystem.File.ReadAllText(globalVariablesPath); - globalVariablesFile = globalVariablesFile.Replace(CliConstants.TokenVersion, CmfPackage.Version); - this.fileSystem.File.WriteAllText(globalVariablesPath, globalVariablesFile); - - IFileInfo runCustomizationInstallDF = this.fileSystem.FileInfo.New(this.fileSystem.Path.Join(packageOutputDir.FullName, "RunCustomizationInstallDF.ps1")); - - string fileContent = runCustomizationInstallDF.ReadToString(); - - fileContent = fileContent.Replace(CliConstants.TokenPackageId, CmfPackage.PackageId); - - this.fileSystem.File.WriteAllText(runCustomizationInstallDF.FullName, fileContent); - } - } -} \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/HelpGulpPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/HelpGulpPackageTypeHandler.cs deleted file mode 100644 index 08377896a..000000000 --- a/cmf-cli/Handlers/PackageType/HelpGulpPackageTypeHandler.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System.Collections.Generic; -using System.IO.Abstractions; -using System.Text.RegularExpressions; -using Cmf.CLI.Builders; -using Cmf.CLI.Commands; -using Cmf.CLI.Commands.restore; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Enums; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Utilities; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json; -using System.IO; - - -namespace Cmf.CLI.Handlers -{ - /// - /// - /// - /// - public class HelpGulpPackageTypeHandler : PresentationPackageTypeHandler - { - /// - /// Initializes a new instance of the class. - /// - /// - public HelpGulpPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) - { - cmfPackage.SetDefaultValues - ( - targetDirectory: - "UI/Help", - targetLayer: - "help" - ); - - BuildSteps = new IBuildCommand[] - { - new ExecuteCommand() - { - Command = new RestoreCommand(), - DisplayName = "cmf restore", - Execute = command => - { - command.Execute(cmfPackage.GetFileInfo().Directory, null); - } - }, - new NPMCommand() - { - DisplayName = "NPM Install", - Command = "install", - Args = new []{ "--force" }, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new GulpCommand() - { - GulpFile = "gulpfile.js", - Task = "install", - DisplayName = "Gulp Install", - GulpJS = "node_modules/gulp/bin/gulp.js", - Args = new [] { "--update" }, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - // generate based on templates - new ExecuteCommand() - { - DisplayName = "Generate help pages based on templates", - Command = new GenerateBasedOnTemplatesCommand(), - Execute = command => - { - command.Execute(cmfPackage.GetFileInfo().Directory); - } - }, - // generate menu items - new ExecuteCommand() - { - DisplayName = "Generate menu items", - Command = new GenerateMenuItemsCommand(), - Execute = command => - { - command.Execute(cmfPackage.GetFileInfo().Directory); - } - }, - new GulpCommand() - { - GulpFile = "gulpfile.js", - Task = "build", - DisplayName = "Gulp Build", - GulpJS = "node_modules/gulp/bin/gulp.js", - Args = new [] { "--production" }, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - }; - - cmfPackage.DFPackageType = PackageType.Presentation; - } - - /// - /// Bumps the Base version of the package - /// - /// The new Base version. - public override void UpgradeBase(string version, string iotVersion, List iotPackagesToIgnore) - { - base.UpgradeBase(version, iotVersion, iotPackagesToIgnore); - UpgradeBaseUtilities.UpdateNPMProject(this.fileSystem, this.CmfPackage, version); - - // Update the version in the config.json file - IFileInfo config = this.fileSystem.FileInfo.New(Path.Join(this.CmfPackage.GetFileInfo().DirectoryName, "apps", "cmf.docs.area.web", "config.json")); - - if (config.Exists) - { - Log.Information($"Updating apps/cmf.docs.area.web/config.json file"); - - string text = fileSystem.File.ReadAllText(config.FullName); - JObject configObject = JsonConvert.DeserializeObject(text); - - if (configObject.ContainsKey("version")) - { - string configVersion = (string)configObject["version"]; - configObject["version"] = Regex.Replace(configVersion, @"\d+\.\d+\.\d+", version); - } - - fileSystem.File.WriteAllText(config.FullName, JsonConvert.SerializeObject(configObject, Formatting.Indented)); - } - } - } -} \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/HtmlGulpPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/HtmlGulpPackageTypeHandler.cs deleted file mode 100644 index be0595889..000000000 --- a/cmf-cli/Handlers/PackageType/HtmlGulpPackageTypeHandler.cs +++ /dev/null @@ -1,129 +0,0 @@ - -using System.Collections.Generic; -using System.IO.Abstractions; -using System.Text.RegularExpressions; -using Cmf.CLI.Builders; -using Cmf.CLI.Commands.restore; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Enums; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Utilities; -using Cmf.CLI.Services; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json; -using Microsoft.TemplateEngine.Abstractions; -using System.IO; - -namespace Cmf.CLI.Handlers -{ - /// - /// - /// - /// - public class HtmlGulpPackageTypeHandler : PresentationPackageTypeHandler - { - /// - /// Initializes a new instance of the class. - /// - /// - public HtmlGulpPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) - { - // Validate Node.js version before proceeding with build setup - // Only validate if ExecutionContext is properly initialized - if (ExecutionContext.Instance?.ProjectConfig != null && ExecutionContext.ServiceProvider != null) - { - var dependencyVersionService = ExecutionContext.ServiceProvider.GetService(); - if (dependencyVersionService != null) - { - var mesVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; - var requiredNodeVersion = dependencyVersionService.Node(mesVersion); - NodeVersionUtilities.ValidateNodeVersion(mesVersion, requiredNodeVersion); - } - } - - cmfPackage.SetDefaultValues - ( - targetDirectory: - "UI/Html", - targetLayer: - "ui", - steps: - new List - { - new Step(StepType.DeployFiles) - { - ContentPath = "bundles/**" - } - } - ); - - BuildSteps = new IBuildCommand[] - { - new ExecuteCommand() - { - Command = new RestoreCommand(), - DisplayName = "cmf restore", - Execute = command => - { - command.Execute(cmfPackage.GetFileInfo().Directory, null); - } - }, - new NPMCommand() - { - DisplayName = "NPM Install", - Command = "install", - Args = new []{ "--force" }, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new GulpCommand() - { - GulpFile = "gulpfile.js", - Task = "install", - DisplayName = "Gulp Install", - GulpJS = "node_modules/gulp/bin/gulp.js", - Args = new [] { "--update" }, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new GulpCommand() - { - GulpFile = "gulpfile.js", - Task = "build", - DisplayName = "Gulp Build", - GulpJS = "node_modules/gulp/bin/gulp.js", - Args = new [] { "--production" , "--dist", "--brotli"}, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - }; - - cmfPackage.DFPackageType = PackageType.Presentation; - } - - /// - /// Bumps the Base version of the package - /// - /// The new Base version. - public override void UpgradeBase(string version, string iotVersion, List iotPackagesToIgnore) - { - base.UpgradeBase(version, iotVersion, iotPackagesToIgnore); - UpgradeBaseUtilities.UpdateNPMProject(this.fileSystem, this.CmfPackage, version); - - IFileInfo projectConfig = this.fileSystem.FileInfo.New(Path.Join(this.CmfPackage.GetFileInfo().DirectoryName, "apps", "customization.web", "config.json")); - if (projectConfig.Exists) - { - Log.Information($"Updating apps/customization.web/config.json file"); - - string text = fileSystem.File.ReadAllText(projectConfig.FullName); - JObject configObject = JsonConvert.DeserializeObject(text); - - if (configObject.ContainsKey("version")) - { - string configVersion = (string)configObject["version"]; - configObject["version"] = Regex.Replace(configVersion, @"\d+\.\d+\.\d+", version); - } - - fileSystem.File.WriteAllText(projectConfig.FullName, JsonConvert.SerializeObject(configObject, Formatting.Indented)); - } - } - } -} \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/HtmlNgCliPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/HtmlNgCliPackageTypeHandler.cs index 4e9e777fe..137570eed 100644 --- a/cmf-cli/Handlers/PackageType/HtmlNgCliPackageTypeHandler.cs +++ b/cmf-cli/Handlers/PackageType/HtmlNgCliPackageTypeHandler.cs @@ -4,13 +4,11 @@ using System.IO.Abstractions; using System.Linq; using System.Text.RegularExpressions; -using System.Threading.Tasks; using Cmf.CLI.Builders; using Cmf.CLI.Commands.html; using Cmf.CLI.Commands.restore; using Cmf.CLI.Constants; using Cmf.CLI.Core; -using Cmf.CLI.Core.Constants; using Cmf.CLI.Core.Enums; using Cmf.CLI.Core.Objects; using Cmf.CLI.Utilities; @@ -240,44 +238,5 @@ public override void UpgradeBase(string version, string iotVersion, List // Log.Information($"{outputDir.FullName}/{CmfPackage.ZipPackageName} created"); // // } - - /// - /// Generates the presentation configuration file. - /// - /// The package output dir. - private void GeneratePresentationConfigFile(IDirectoryInfo packageOutputDir) - { - Log.Debug("Generating Presentation config.json"); - string path = $"{packageOutputDir.FullName}/assets/{CliConstants.CmfPackagePresentationConfig}"; - - List transformInjections = new(); - - IDirectoryInfo cmfPackageDirectory = CmfPackage.GetFileInfo().Directory; - - foreach (ContentToPack contentToPack in CmfPackage.ContentToPack) - { - if (contentToPack.Action == PackAction.Transform) - { - transformInjections.Add(contentToPack.Source); - } - } - - // Get Template - string fileContent = ResourceUtilities.GetEmbeddedResourceContent($"{CliConstants.FolderTemplates}/{CmfPackage.PackageType}/config.ng.json"); - - fileContent = fileContent.Replace(CliConstants.TokenVersion, CmfPackage.Version); - - string injection = string.Empty; - if (transformInjections.HasAny()) - { - // we actually want a trailing comma here, because the inject token is in the middle of the document. If this changes we need to put more logic here. - var injections = transformInjections.Select(injection => this.fileSystem.File.ReadAllText($"{cmfPackageDirectory}/{injection}") + ","); - injection = string.Join(System.Environment.NewLine, injections); - } - fileContent = fileContent.Replace(CliConstants.TokenJDTInjection, injection); - fileContent = fileContent.Replace(CliConstants.CacheId, DateTime.Now.ToString("yyyyMMddHHmmss")); - - this.fileSystem.File.WriteAllText(path, fileContent); - } } } \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/IoTDataPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/IoTDataPackageTypeHandler.cs deleted file mode 100644 index 818f79fec..000000000 --- a/cmf-cli/Handlers/PackageType/IoTDataPackageTypeHandler.cs +++ /dev/null @@ -1,104 +0,0 @@ - -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Enums; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Utilities; -using Utils = Cmf.CLI.Utilities.FileSystemUtilities; - -namespace Cmf.CLI.Handlers -{ - /// - /// - /// - /// - public class IoTDataPackageTypeHandler : DataPackageTypeHandler - { - /// - /// Initializes a new instance of the class. - /// - /// The CMF package. - public IoTDataPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) - { - cmfPackage.DFPackageType = PackageType.Business; - } - - /// - /// Bumps the specified CMF package. - /// - /// The version. - /// The version suffix. - /// The bump information. - public override void Bump(string version, string versionSuffix, Dictionary bumpInformation = null) - { - base.Bump(version, versionSuffix, bumpInformation); - // Get All AutomationWorkflowFiles Folders - List automationWorkflowDirectory = this.fileSystem.Directory.GetDirectories(CmfPackage.GetFileInfo().DirectoryName, "AutomationWorkflowFiles", SearchOption.AllDirectories).ToList(); - - // Get Parent Root - IDirectoryInfo parentRootDirectory = FileSystemUtilities.GetPackageRootByType(CmfPackage.GetFileInfo().DirectoryName, PackageType.Root, this.fileSystem); - CmfPackageCollection cmfPackageIoT = parentRootDirectory.LoadCmfPackagesFromSubDirectories(packageType: PackageType.IoT); - - #region GetCustomPackages - - // Get Dev Tasks - string packageNames = null; - string devTasksJson = null; - dynamic devTasksJsonObject; - foreach (CmfPackage iotPackage in cmfPackageIoT) - { - string devTasksFile = this.fileSystem.Directory.GetFiles(iotPackage.GetFileInfo().DirectoryName, ".dev-tasks.json")[0]; - - devTasksJson = this.fileSystem.File.ReadAllText(devTasksFile); - devTasksJsonObject = JsonConvert.DeserializeObject(devTasksJson); - - packageNames += devTasksJsonObject["packagesBuildBump"]?.ToString(); - - if (string.IsNullOrEmpty(packageNames)) - { - packageNames += devTasksJsonObject["packages"]?.ToString(); - } - } - - #endregion GetCustomPackages - - #region Filter by Root - - if (bumpInformation.ContainsKey("root") && !String.IsNullOrEmpty(bumpInformation["root"] as string)) - { - string root = bumpInformation["root"] as string; - if (!automationWorkflowDirectory.Any()) - { - Log.Warning($"No AutomationWorkflowFiles found in root {root}"); - } - // Get All AutomationWorkflowFiles Folders that are under root - automationWorkflowDirectory = automationWorkflowDirectory.Where(awf => awf.Contains(root))?.ToList() ?? new(); - } - - #endregion Filter by Root - - foreach (string automationWorkflowFileGroup in automationWorkflowDirectory) - { - #region Bump AutomationWorkflow - - // Get All Group Folders - List groups = this.fileSystem.Directory.GetDirectories(automationWorkflowFileGroup, "*").ToList(); - - groups.ForEach(group => IoTUtilities.BumpWorkflowFiles(group, version, versionSuffix, null, packageNames, this.fileSystem)); - - #endregion Bump AutomationWorkflow - - #region Bump IoT Masterdata - - IoTUtilities.BumpIoTMasterData(automationWorkflowFileGroup, version, versionSuffix, this.fileSystem, packageNames, onlyCustomization: true); - - #endregion Bump IoT Masterdata - } - } - } -} \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/IoTPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/IoTPackageTypeHandler.cs index 45960df3e..640ece42e 100644 --- a/cmf-cli/Handlers/PackageType/IoTPackageTypeHandler.cs +++ b/cmf-cli/Handlers/PackageType/IoTPackageTypeHandler.cs @@ -1,6 +1,7 @@ using Cmf.CLI.Builders; using Cmf.CLI.Commands.New; using Cmf.CLI.Commands.restore; +using Cmf.CLI.Constants; using Cmf.CLI.Core; using Cmf.CLI.Core.Constants; using Cmf.CLI.Core.Enums; @@ -21,7 +22,7 @@ namespace Cmf.CLI.Handlers /// /// /// - public class IoTPackageTypeHandler : PresentationPackageTypeHandler + public class IoTPackageTypeHandler : PackageTypeHandler { /// /// Initializes a new instance of the class. @@ -29,150 +30,94 @@ public class IoTPackageTypeHandler : PresentationPackageTypeHandler /// The CMF package. public IoTPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) { - var minimumVersion = new Version("8.3.5"); var targetVersion = ExecutionContext.Instance.ProjectConfig.MESVersion; IBuildCommand[] buildCommands = Array.Empty(); var defaultSteps = new List(); - if (targetVersion.CompareTo(minimumVersion) < 0) + var packageLocation = "projects"; + + if (!this.IsAngularProject(cmfPackage.GetFileInfo().Directory.FullName)) { - Log.Debug( - $"MES version lower than {minimumVersion}, skipping DeployRepositoryFiles and GenerateRepositoryIndex steps. Make sure you have alternative steps in your manifest."); + defaultSteps = this.AddAutomationTaskLibrariesStep(targetVersion, CmfPackage, defaultSteps); + defaultSteps = this.AddAutomationBusinessScenarioStep(targetVersion, CmfPackage, defaultSteps); } - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 10) + + buildCommands = new IBuildCommand[] { - buildCommands = new IBuildCommand[] + new ExecuteCommand() { - new ExecuteCommand() - { - Command = new RestoreCommand(), - DisplayName = "cmf restore", - Execute = command => - { - command.Execute(cmfPackage.GetFileInfo().Directory, null); - } - }, - new NPMCommand() - { - DisplayName = "NPM Install", - Command = "install", - Args = new[] {"--force"}, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new GulpCommand() + Command = new RestoreCommand(), + DisplayName = "cmf restore", + Execute = command => { - GulpFile = "gulpfile.js", - Task = "install", - DisplayName = "Gulp Install", - GulpJS = "node_modules/gulp/bin/gulp.js", - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new GulpCommand() - { - GulpFile = "gulpfile.js", - Task = "build", - DisplayName = "Gulp Build", - GulpJS = "node_modules/gulp/bin/gulp.js", - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new GulpCommand() - { - GulpFile = "gulpfile.js", - Task = "cliTest", - DisplayName = "Gulp Test", - GulpJS = "node_modules/gulp/bin/gulp.js", - WorkingDirectory = cmfPackage.GetFileInfo().Directory, - Test = true + command.Execute(cmfPackage.GetFileInfo().Directory, null); } - }; - } - else - { - var packageLocation = "projects"; - - if (!this.IsAngularProject(cmfPackage.GetFileInfo().Directory.FullName)) + }, + new NPMCommand() { - defaultSteps = this.AddAutomationTaskLibrariesStep(targetVersion, CmfPackage, defaultSteps); - defaultSteps = this.AddAutomationBusinessScenarioStep(targetVersion, CmfPackage, defaultSteps); - } - - buildCommands = new IBuildCommand[] + DisplayName = "NPM Install", + Command = "install", + Args = new[] {"--force"}, + WorkingDirectory = cmfPackage.GetFileInfo().Directory + }, + new NPMCommand() { - new ExecuteCommand() + DisplayName = "NPM Lint", + Command = "run lint", + WorkingDirectory = cmfPackage.GetFileInfo().Directory, + ConditionForExecute = () => { - Command = new RestoreCommand(), - DisplayName = "cmf restore", - Execute = command => + var packageJsons = this.GetPackageJsons(cmfPackage, packageLocation); + + if(packageJsons == null && !packageJsons.Any()) { - command.Execute(cmfPackage.GetFileInfo().Directory, null); + return false; } - }, - new NPMCommand() - { - DisplayName = "NPM Install", - Command = "install", - Args = new[] {"--force"}, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new NPMCommand() - { - DisplayName = "NPM Lint", - Command = "run lint", - WorkingDirectory = cmfPackage.GetFileInfo().Directory, - ConditionForExecute = () => - { - var packageJsons = this.GetPackageJsons(cmfPackage, packageLocation); - - if(packageJsons == null && !packageJsons.Any()) - { - return false; - } - foreach (var packageJson in packageJsons ) - { - var json = fileSystem.File.ReadAllText(packageJson.FullName); - dynamic packageJsonContent = JsonConvert.DeserializeObject(json); - - if(packageJsonContent?["scripts"] == null || packageJsonContent?["scripts"]?["lint"] == null) - { - return false; - } - } - return true; - } - }, - new NPMCommand() - { - DisplayName = "NPM Build", - Command = "run build -ws", - Args = new[] {"--force"}, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new NPMCommand() - { - DisplayName = "NPM Test", - Command = "run test -ws", - Args = new[] {"--force"}, - WorkingDirectory = cmfPackage.GetFileInfo().Directory - }, - new ExecuteCommand() - { - Command = new IoTLibCommand(), - DisplayName = "cmf iot lib command", - ConditionForExecute = () => + foreach (var packageJson in packageJsons ) { - if(cmfPackage.GetFileInfo().Directory.EnumerateDirectories().Any(dir => dir.Name == "dist")) + var json = fileSystem.File.ReadAllText(packageJson.FullName); + dynamic packageJsonContent = JsonConvert.DeserializeObject(json); + + if(packageJsonContent?["scripts"] == null || packageJsonContent?["scripts"]?["lint"] == null) { - return true; + return false; } - return false; - }, - Execute = command => + } + return true; + } + }, + new NPMCommand() + { + DisplayName = "NPM Build", + Command = "run build -ws", + Args = new[] {"--force"}, + WorkingDirectory = cmfPackage.GetFileInfo().Directory + }, + new NPMCommand() + { + DisplayName = "NPM Test", + Command = "run test -ws", + Args = new[] {"--force"}, + WorkingDirectory = cmfPackage.GetFileInfo().Directory + }, + new ExecuteCommand() + { + Command = new IoTLibCommand(), + DisplayName = "cmf iot lib command", + ConditionForExecute = () => + { + if(cmfPackage.GetFileInfo().Directory.EnumerateDirectories().Any(dir => dir.Name == "dist")) { - command.Execute(cmfPackage.GetFileInfo().Directory); + return true; } + return false; }, - }; - } + Execute = command => + { + command.Execute(cmfPackage.GetFileInfo().Directory); + } + }, + }; // Add Steps defaultSteps.AddRange(new List() @@ -210,8 +155,7 @@ public IoTPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) // Validate Steps defaultSteps = defaultSteps.Where(step => - // if MES version is inferior to 8.3.5, the DeployRepositoryFiles and GenerateRepositoryIndex steps are not supported - targetVersion.CompareTo(minimumVersion) >= 0 || step.Type != StepType.DeployRepositoryFiles && step.Type != StepType.GenerateRepositoryIndex + step.Type != StepType.DeployRepositoryFiles && step.Type != StepType.GenerateRepositoryIndex ).ToList(); cmfPackage.SetDefaultValues @@ -237,15 +181,6 @@ public IoTPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) cmfPackage.DFPackageType = PackageType.Presentation; } - /// - /// Copies the install dependencies. - /// - /// The package output dir. - protected override void CopyInstallDependencies(IDirectoryInfo packageOutputDir) - { - FileSystemUtilities.CopyInstallDependenciesFiles(packageOutputDir, PackageType.IoT, this.fileSystem); - } - /// /// Bumps the specified CMF package. /// @@ -257,33 +192,50 @@ public override void Bump(string version, string versionSuffix, Dictionary src -> Package XPTO - IoTUtilities.BumpIoTCustomPackages(CmfPackage.GetFileInfo().DirectoryName, version, versionSuffix, packageNames, this.fileSystem); + var metadataVersion = GenericUtilities.RetrieveNewPresentationVersion(regexMatch[1], version, versionSuffix); + metadataFile = Regex.Replace(metadataFile, regex, string.Format("version: \"{0}\"", metadataVersion)); + this.fileSystem.File.WriteAllText(fileName, metadataFile); } } @@ -325,20 +277,8 @@ public override void Pack(IDirectoryInfo packageOutputDir, IDirectoryInfo output IDirectoryInfo outputDirPath = this.fileSystem.DirectoryInfo.New($"{packageOutputDir}/runtimePackages"); outputDirPath.Create(); - // Is not Supported in workspaces - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 10) - { - NPMCommand npmCommand = new NPMCommand() - { - DisplayName = "npm shrinkwrap", - Args = new string[] { "shrinkwrap" }, - WorkingDirectory = packDirectory - }; - - npmCommand.Exec(); - } - string debugFlag = Log.Level <= LogLevel.Debug ? "-d" : ""; + if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 11) { var environmentVariables = new Dictionary() @@ -427,6 +367,7 @@ public override void Pack(IDirectoryInfo packageOutputDir, IDirectoryInfo output } } + GeneratePresentationConfigFile(packageOutputDir); base.Pack(packageOutputDir, outputDir, dryRun); } @@ -575,5 +516,103 @@ private List AddAutomationBusinessScenarioStep(Version targetVersion, CmfP } return defaultSteps; } + + public void GeneratePresentationConfigFile(IDirectoryInfo packageOutputDir) + { + Log.Debug("Generating Presentation config.json"); + string path = $"{packageOutputDir.FullName}/{CliConstants.CmfPackagePresentationConfig}"; + + List packageList = new(); + List transformInjections = new(); + + IDirectoryInfo cmfPackageDirectory = CmfPackage.GetFileInfo().Directory; + + foreach (ContentToPack contentToPack in CmfPackage.ContentToPack) + { + if (contentToPack.Action == null || contentToPack.Action == PackAction.Pack) + { + // TODO: Validate if contentToPack.Source exists before + IDirectoryInfo[] packDirectories = cmfPackageDirectory.GetDirectories(contentToPack.Source); + + foreach (IDirectoryInfo packDirectory in packDirectories) + { + dynamic packageJson = packDirectory.GetFile(CoreConstants.PackageJson); + if (packageJson != null) + { + string packageName = packageJson.name; + + // For IoT Packages we should ignore the driver packages + if (CmfPackage.PackageType == PackageType.IoT && packageName.Contains(CliConstants.Driver, System.StringComparison.InvariantCultureIgnoreCase)) + { + continue; + } + + packageList.Add($"'{packageName}'"); + } + } + } + else if (contentToPack.Action == PackAction.Transform) + { + transformInjections.Add(contentToPack.Source); + } + } + + if (packageList.HasAny()) + { + // Get Template + string fileContent = ResourceUtilities.GetEmbeddedResourceContent($"{CliConstants.FolderTemplates}/{CmfPackage.PackageType}/{CliConstants.CmfPackagePresentationConfig}"); + + string packagesToRemove = string.Empty; + List packagesToAdd = new(); + + for (int i = 0; i < packageList.Count; i++) + { + if (CmfPackage.PackageType == PackageType.IoT) + { + packagesToRemove += $"@.path=={packageList[i]}"; + } + else + { + packagesToRemove += $"@=={packageList[i]}"; + } + + if (packageList.Count > 1 && + i != packageList.Count - 1) + { + packagesToRemove += " || "; + } + + string packageToAdd = packageList[i].Replace("'", "\""); + if (CmfPackage.PackageType == PackageType.IoT) + { + packageToAdd = string.Format("{{\"path\": {0} }}", packageToAdd); + } + + packagesToAdd.Add(packageToAdd); + } + + fileContent = fileContent.Replace(CliConstants.TokenPackagesToRemove, packagesToRemove); + fileContent = fileContent.Replace(CliConstants.TokenPackagesToAdd, string.Join(",", packagesToAdd)); + fileContent = fileContent.Replace(CliConstants.TokenVersion, CmfPackage.Version); + + string injection = string.Empty; + if (transformInjections.HasAny()) + { + // we actually want a trailing comma here, because the inject token is in the middle of the document. If this changes we need to put more logic here. + var injections = transformInjections.Select(injection => this.fileSystem.File.ReadAllText($"{cmfPackageDirectory}/{injection}") + ","); + injection = string.Join(System.Environment.NewLine, injections); + } + fileContent = fileContent.Replace(CliConstants.TokenJDTInjection, injection); + fileContent = fileContent.Replace(CliConstants.CacheId, DateTime.Now.ToString("yyyyMMddHHmmss")); + + this.fileSystem.File.WriteAllText(path, fileContent); + } + else + { + Log.Debug("Could not find UI packages, so skipping generating config.json transform"); + this.CmfPackage.Steps = this.CmfPackage.Steps + .Where(step => step.Type != StepType.TransformFile && step.File != "config.json").ToList(); + } + } } } \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/PackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/PackageTypeHandler.cs index ddc7e036f..099a872dd 100644 --- a/cmf-cli/Handlers/PackageType/PackageTypeHandler.cs +++ b/cmf-cli/Handlers/PackageType/PackageTypeHandler.cs @@ -21,7 +21,6 @@ using Cmf.CLI.Core.Services; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json.Linq; -using SharpCompress.Common; [assembly: InternalsVisibleTo("tests")] @@ -474,18 +473,6 @@ internal virtual List GetContentToPack(IDirectoryInfo packageOutputD #endregion Private Methods - #region Protected Methods - - /// - /// Copies the install dependencies. - /// - /// The package output dir. - protected virtual void CopyInstallDependencies(IDirectoryInfo packageOutputDir) - { - } - - #endregion Protected Methods - #region Public Methods /// @@ -632,9 +619,6 @@ public virtual void Pack(IDirectoryInfo packageOutputDir, IDirectoryInfo outputD // Only perform actual packing operations if not in dry-run mode if (!dryRun) { - // TODO: To be removed? Install dependencies - CopyInstallDependencies(packageOutputDir); - GenerateDeploymentFrameworkManifest(packageOutputDir); FinalArchive(packageOutputDir, outputDir); diff --git a/cmf-cli/Handlers/PackageType/PresentationPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/PresentationPackageTypeHandler.cs deleted file mode 100644 index 84dd32bcb..000000000 --- a/cmf-cli/Handlers/PackageType/PresentationPackageTypeHandler.cs +++ /dev/null @@ -1,252 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; -using System.Text.RegularExpressions; -using Cmf.CLI.Constants; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Constants; -using Cmf.CLI.Core.Enums; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Utilities; - -namespace Cmf.CLI.Handlers -{ - /// - /// Base handler for UI packages - /// - /// - public class PresentationPackageTypeHandler : PackageTypeHandler - { - #region Private Methods - - /// - /// Generates the presentation configuration file. - /// - /// The package output dir. - /// If set to true, the method will simulate the generation without writing files. - public void GeneratePresentationConfigFile(IDirectoryInfo packageOutputDir, bool dryRun = false) - { - Log.Debug("Generating Presentation config.json"); - string path = $"{packageOutputDir.FullName}/{CliConstants.CmfPackagePresentationConfig}"; - - List packageList = new(); - List transformInjections = new(); - - IDirectoryInfo cmfPackageDirectory = CmfPackage.GetFileInfo().Directory; - - foreach (ContentToPack contentToPack in CmfPackage.ContentToPack) - { - if (contentToPack.Action == null || contentToPack.Action == PackAction.Pack) - { - // TODO: Validate if contentToPack.Source exists before - IDirectoryInfo[] packDirectories = cmfPackageDirectory.GetDirectories(contentToPack.Source); - - foreach (IDirectoryInfo packDirectory in packDirectories) - { - dynamic packageJson = packDirectory.GetFile(CoreConstants.PackageJson); - if (packageJson != null) - { - string packageName = packageJson.name; - - // For IoT Packages we should ignore the driver packages - if (CmfPackage.PackageType == PackageType.IoT && packageName.Contains(CliConstants.Driver, System.StringComparison.InvariantCultureIgnoreCase)) - { - continue; - } - - packageList.Add($"'{packageName}'"); - } - } - } - else if (contentToPack.Action == PackAction.Transform) - { - transformInjections.Add(contentToPack.Source); - } - } - - if (packageList.HasAny()) - { - // Get Template - string fileContent = ResourceUtilities.GetEmbeddedResourceContent($"{CliConstants.FolderTemplates}/{CmfPackage.PackageType}/{CliConstants.CmfPackagePresentationConfig}"); - - string packagesToRemove = string.Empty; - List packagesToAdd = new(); - - for (int i = 0; i < packageList.Count; i++) - { - if (CmfPackage.PackageType == PackageType.IoT) - { - packagesToRemove += $"@.path=={packageList[i]}"; - } - else - { - packagesToRemove += $"@=={packageList[i]}"; - } - - if (packageList.Count > 1 && - i != packageList.Count - 1) - { - packagesToRemove += " || "; - } - - string packageToAdd = packageList[i].Replace("'", "\""); - if (CmfPackage.PackageType == PackageType.IoT) - { - packageToAdd = string.Format("{{\"path\": {0} }}", packageToAdd); - } - - packagesToAdd.Add(packageToAdd); - } - - fileContent = fileContent.Replace(CliConstants.TokenPackagesToRemove, packagesToRemove); - fileContent = fileContent.Replace(CliConstants.TokenPackagesToAdd, string.Join(",", packagesToAdd)); - fileContent = fileContent.Replace(CliConstants.TokenVersion, CmfPackage.Version); - - string injection = string.Empty; - if (transformInjections.HasAny()) - { - // we actually want a trailing comma here, because the inject token is in the middle of the document. If this changes we need to put more logic here. - var injections = transformInjections.Select(injection => this.fileSystem.File.ReadAllText($"{cmfPackageDirectory}/{injection}") + ","); - injection = string.Join(System.Environment.NewLine, injections); - } - fileContent = fileContent.Replace(CliConstants.TokenJDTInjection, injection); - fileContent = fileContent.Replace(CliConstants.CacheId, DateTime.Now.ToString("yyyyMMddHHmmss")); - - Log.Debug($"The package contains the following UI packages: {string.Join(", ", packageList)}"); - Log.Debug($"The following config.json transformations would be applied: {string.Join(", ", transformInjections)}"); - - if (!dryRun) - { - this.fileSystem.File.WriteAllText(path, fileContent); - } - else - { - Log.Information($"The following config.json would be generated at {path}"); - } - } - else - { - Log.Debug("Could not find UI packages, so skipping generating config.json transform"); - this.CmfPackage.Steps = this.CmfPackage.Steps - .Where(step => step.Type != StepType.TransformFile && step.File != "config.json").ToList(); - } - } - - #endregion Private Methods - - #region Public Methods - - /// - /// Initializes a new instance of the class. - /// - /// The CMF package. - public PresentationPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) - { - if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 10) - { - cmfPackage.SetDefaultValues - ( - steps: - new List - { - new Step(StepType.DeployFiles) - { - ContentPath = "node_modules/**" - }, - new Step(StepType.TransformFile) - { - File = "config.json", - TagFile = true - } - } - - ); - } - - DefaultContentToIgnore.AddRange(new List - { - "node_modules", - "test", - "*.ts", - "node.exe", - "CompileProject.ps1", - "node_modules_cache.zip" - }); - } - - /// - /// Bumps the specified version. - /// - /// The version. - /// The version suffix. - /// The bump information. - public override void Bump(string version, string versionSuffix, Dictionary bumpInformation = null) - { - base.Bump(version, versionSuffix, bumpInformation); - - string parentDirectory = CmfPackage.GetFileInfo().DirectoryName; - string[] filesToUpdate = this.fileSystem.Directory.GetFiles(parentDirectory, "package.json", SearchOption.AllDirectories); - foreach (var fileName in filesToUpdate) - { - if (fileName.Contains("node_modules")) - { - continue; - } - string json = this.fileSystem.File.ReadAllText(fileName); - dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json); - - if (jsonObj["version"] == null) - { - throw new CliException(string.Format(CoreMessages.MissingMandatoryPropertyInFile, "version", fileName)); - } - - jsonObj["version"] = GenericUtilities.RetrieveNewPresentationVersion(jsonObj["version"].ToString(), version, versionSuffix); - - this.fileSystem.File.WriteAllText(fileName, Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented)); - } - - filesToUpdate = this.fileSystem.Directory.GetFiles(parentDirectory, "*metadata.ts", SearchOption.AllDirectories); - foreach (var fileName in filesToUpdate) - { - if (fileName.Contains("node_modules") - || fileName.Contains("\\src\\style")) // prevent metadata.ts in the \src\style from being taken into account - { - continue; - } - string metadataFile = this.fileSystem.File.ReadAllText(fileName); - - // take in consideration double quotes and single quotes - string[] quotes = { "\"", "'" }; - string regex = @$"version: ({quotes[0]}|{quotes[1]})[0-9.-]*({quotes[0]}|{quotes[1]})"; - - var regexMatch = Regex.Match(metadataFile, regex, RegexOptions.Singleline)?.Value?.Split(quotes, StringSplitOptions.TrimEntries); - if (regexMatch?.Length <= 1) - { - continue; // in case that version is not found on metadata.ts skip this - } - - var metadataVersion = GenericUtilities.RetrieveNewPresentationVersion(regexMatch[1], version, versionSuffix); - metadataFile = Regex.Replace(metadataFile, regex, string.Format("version: \"{0}\"", metadataVersion)); - this.fileSystem.File.WriteAllText(fileName, metadataFile); - } - } - - /// - /// Packs the specified package output dir. - /// - /// The package output dir. - /// The output dir. - /// if set to true list the package structure without creating files. - public override void Pack(IDirectoryInfo packageOutputDir, IDirectoryInfo outputDir, bool dryRun = false) - { - GeneratePresentationConfigFile(packageOutputDir, dryRun); - - base.Pack(packageOutputDir, outputDir, dryRun); - } - - #endregion Public Methods - } -} \ No newline at end of file diff --git a/cmf-cli/Handlers/PackageType/SecurityPortalPackageTypeHandler.cs b/cmf-cli/Handlers/PackageType/SecurityPortalPackageTypeHandler.cs deleted file mode 100644 index f706d022e..000000000 --- a/cmf-cli/Handlers/PackageType/SecurityPortalPackageTypeHandler.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using Cmf.CLI.Constants; -using Cmf.CLI.Core; -using Cmf.CLI.Core.Enums; -using Cmf.CLI.Core.Objects; -using Cmf.CLI.Handlers; -using Cmf.CLI.Utilities; - -namespace Cmf.CLI.Handlers -{ - - /// - /// Handler for SecurityPortal packages - /// - public class SecurityPortalPackageTypeHandler : PackageTypeHandler - { - /// - /// Initializes a new instance of the class. - /// - /// - public SecurityPortalPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage) - { - cmfPackage.SetDefaultValues - ( - targetDirectory: - "SecurityPortal", - targetLayer: - "securityportal", - steps: - new List - { - new(StepType.TransformFile) - { - File = "config.json", - TagFile = true - } - } - ); - - cmfPackage.DFPackageType = PackageType.Business; - } - - - /// - /// Packs the specified package output dir. - /// - /// The package output dir. - /// The output dir. - /// if set to true list the package structure without creating files. - public override void Pack(IDirectoryInfo packageOutputDir, IDirectoryInfo outputDir, bool dryRun = false) - { - Log.Debug("Generating SecurityPortal config.json"); - string path = $"{packageOutputDir.FullName}{Path.DirectorySeparatorChar}{CliConstants.CmfPackageSecurityPortalConfig}"; - - IDirectoryInfo cmfPackageDirectory = CmfPackage.GetFileInfo().Directory; - - dynamic configJson = cmfPackageDirectory.GetFile(CliConstants.CmfPackageSecurityPortalConfig); - if (configJson != null) - { - string packageName = configJson.id; - string type = configJson.type; - string metadataUrl = configJson.config.metadataUrl; - string redirectUrl = configJson.config.redirectUrl; - string clientId = configJson.config.clientId; - - // Get Template - string fileContent = ResourceUtilities.GetEmbeddedResourceContent($"{CliConstants.FolderTemplates}/{CmfPackage.PackageType}/{CliConstants.CmfPackageSecurityPortalConfig}"); - - fileContent = fileContent.Replace(CliConstants.TokenPackageId, packageName); - fileContent = fileContent.Replace(CliConstants.StrategyPath, CliConstants.DefaultStrategyPath).Replace(CliConstants.Tenant, ExecutionContext.Instance.ProjectConfig.Tenant); - fileContent = fileContent.Replace(CliConstants.Strategy, type); - fileContent = fileContent.Replace(CliConstants.MetadataUrl, metadataUrl); - fileContent = fileContent.Replace(CliConstants.RedirectUrl, redirectUrl); - fileContent = fileContent.Replace(CliConstants.ClientId, clientId); - - if (!dryRun) - { - this.fileSystem.File.WriteAllText(path, fileContent); - - GenerateDeploymentFrameworkManifest(packageOutputDir); - - FinalArchive(packageOutputDir, outputDir); - - Log.Debug($"{outputDir.FullName}{Path.DirectorySeparatorChar}{CmfPackage.ZipPackageName} created"); - Log.Information($"{CmfPackage.PackageName} packed"); - } - else - { - Log.Information($"Dry-run mode: Listing package structure for {CmfPackage.PackageName}"); - Log.Information($"Package would be created at: {outputDir.FullName}{Path.DirectorySeparatorChar}{CmfPackage.ZipPackageName}"); - Log.Information($"Dry-run completed for {CmfPackage.PackageName}"); - } - - } - else - { - throw new CliException("No config.json was provided"); - } - } - } -} \ No newline at end of file diff --git a/cmf-cli/Program.cs b/cmf-cli/Program.cs index 77fa5c523..a64c2683c 100644 --- a/cmf-cli/Program.cs +++ b/cmf-cli/Program.cs @@ -7,10 +7,8 @@ using Cmf.CLI.Core.Objects; using Microsoft.Extensions.DependencyInjection; using Cmf.CLI.Core.Enums; -using System.CommandLine.Parsing; using System.IO.Abstractions; using System.Linq; -using System.Reflection; using Cmf.CLI.Constants; using Cmf.CLI.Core.Interfaces; using Cmf.CLI.Core.Services; @@ -36,7 +34,7 @@ public static async Task Main(string[] args) { var fileSystem = new FileSystem(); - var (rootCommand, parser) = await StartupModule.Configure( + var rootCommand = await StartupModule.Configure( packageId: CliConstants.PackageName, envVarPrefix: "cmf_cli", description: "Critical Manufacturing CLI", @@ -57,33 +55,33 @@ public static async Task Main(string[] args) using var activity = ExecutionContext.ServiceProvider.GetService()!.StartActivity("Main"); var result = -1; - + if (rootCommand != null) { - var nonPluginCommands = rootCommand.Children.Where(symbol => symbol is Command).ToList(); + var nonPluginCommands = rootCommand.Subcommands.ToList(); BaseCommand.AddPluginCommands(rootCommand); var pluginCommands = - rootCommand.Children.Where(cmd => cmd is Command && nonPluginCommands.All(np => np.Name != cmd.Name)).ToList(); + rootCommand.Subcommands.Where(cmd => nonPluginCommands.All(np => np.Name != cmd.Name)).ToList(); if (args.Length > 0 && pluginCommands.FirstOrDefault(pc => pc.Name == args[0]) is Command pluginMatch) { - // we are executing a plugin. we should forward all arguments (except the first) to the plugin - var pluginArgs = args[1..]; - - // we should invoke this through the System.CommandLine API but right now we'd have to generate a new pipeline. We'll revisit this in a next version, as it's expected the pipeline instantiation gets more flexible. - var type = pluginMatch!.Handler!.GetType(); - var method = type.GetField("_handlerDelegate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)!; - var del = method.GetValue(pluginMatch.Handler) as Delegate; - var pluginCommand = del!.Target as PluginCommand; - pluginCommand!.Execute(pluginArgs); - result = 0; + // we are executing a plugin: parse and invoke through System.CommandLine + // which will trigger the Action set by PluginCommand.Configure() + var parseResult = rootCommand.Parse(args); + result = await parseResult.InvokeAsync(); } else { ExecutionContext.Initialize(fileSystem); ExecutionContext.ServiceProvider.GetService()! .InitializeClientsForRepositories(ExecutionContext.Instance.FileSystem); - result = await parser.InvokeAsync(args); + + // Global validation for all CLI core commands + ValidateMesVersion(ExecutionContext.Instance.ProjectConfig?.MESVersion?.Major); + + // Parse and invoke using beta5 pattern + ParseResult parseResult = rootCommand.Parse(args); + result = await parseResult.InvokeAsync(); } } @@ -104,5 +102,17 @@ public static async Task Main(string[] args) return (int)ErrorCode.Default; } } + + /// + /// This function will validate MES Version on every command. + /// This server to lock the CLI from executing on any project below version 10. + /// + internal static void ValidateMesVersion(int? majorVersion) + { + if (majorVersion < 10) + { + throw new CliException("MES Versions under 10 are no longer supported with the newest version of the CLI. Please use cmf-cli 5.8.0 or lower."); + } + } } } \ No newline at end of file diff --git a/cmf-cli/cmf.csproj b/cmf-cli/cmf.csproj index 985d29ef8..b75a0eade 100644 --- a/cmf-cli/cmf.csproj +++ b/cmf-cli/cmf.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 cmf Cmf.CLI true @@ -29,10 +29,11 @@ - - + + + @@ -74,16 +75,6 @@ - - - - - - - Always - - - diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/CMFDatabaseActions.psm1 b/cmf-cli/installDependencies/Data/CMFInstallActions/CMFDatabaseActions.psm1 deleted file mode 100644 index e56c78576..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/CMFDatabaseActions.psm1 +++ /dev/null @@ -1,1363 +0,0 @@ -# -# CMFDatabaseActions.psm1 -# - -$ModulePath = Split-Path $MyInvocation.MyCommand.Path - -<# - .SYNOPSIS - Run an SQL command on any SQL Server database. - - .DESCRIPTION - Executes an SQL command on an SQL Server database specified using its instance name and database name. - - .PARAMETER dataSource - Data source name (i.e. instance name) to be used when connecting to the database. - - .PARAMETER database - Default database name on which command will be ran. - - .PARAMETER sqlCommand - String containing the SQL Command to be ran on the database. - - .PARAMETER username - Username to use to connect to the database if SQL Authentication is used. If not specified, windows authentication will - be used. - - .PARAMETER password - Password to use to connect to the database if SQL Authentication is used. - - .PARAMETER timeOut - the wait time before terminating the attempt to execute a command and generating an error. - - .EXAMPLE - Invoke-SQL -dataSource 'CMF-VM-TEST\ONLINE' -database 'cmNavigoODS' -sqlCommand $command - - .EXAMPLE - Invoke-SQL -dataSource 'CMF-VM-TEST\ONLINE' -database 'cmNavigoODS' -sqlCommand $command -username 'TestUser' -password 'TestPassword' - - .NOTES - Query results are not returned. - GO batch separators are supported, provided they are in separate lines on the sqlCommand string. -#> -function Invoke-SQL -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $dataSource, - - [Parameter(Mandatory=$True)] - [string] $database, - - [Parameter(Mandatory=$True)] - [string] $sqlCommand, - - [Parameter(Mandatory=$False)] - [string] $username, - - [Parameter(Mandatory=$False)] - [string] $password, - - [Parameter(Mandatory=$False)] - $timeOut = $null, - - [Parameter(Mandatory=$False)] - [switch]$returnScalar - ) - - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ModulePath\References\Microsoft.SqlServer.BatchParser.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ModulePath\References\Microsoft.SqlServer.SqlClrProvider.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ModulePath\References\Microsoft.SqlServer.Smo.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ModulePath\References\Microsoft.SqlServer.ConnectionInfo.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ModulePath\References\Microsoft.SqlServer.Management.Sdk.Sfc.dll)) | Out-Null - - $srv = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $dataSource - $srv.ConnectionContext.DatabaseName = $database - if ($username) - { - $srv.ConnectionContext.LoginSecure = $False - $srv.ConnectionContext.Login = $username - $srv.ConnectionContext.Password = $password - } - - try - { - if( $timeOut ) - { - LogWrite " Timeout $timeOut secs" - $srv.ConnectionContext.StatementTimeout = $timeOut - } - if ( $returnScalar ) - { - $result = $srv.ConnectionContext.ExecuteScalar($sqlCommand) - } - else - { - $result = $srv.ConnectionContext.ExecuteNonQuery($sqlCommand) - } - } - catch [Exception] - { - throw $_.Exception.InnerException - } - finally - { - $srv.ConnectionContext.Disconnect() - } - - return $result -} - -<# - .SYNOPSIS - Run an SQL Script file on a cmNavigo database. - - .DESCRIPTION - Runs a set of SQL statements from a file on one of the environment databases. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER database - Database that the script should be ran on. Possible values include 'Online', 'ODS' and 'DWH' - - .PARAMETER scriptPath - Absolute path to the script file to run - - .PARAMETER username - Username to use to connect to the database if SQL Authentication is used. If not specified, windows authentication will - be used. - - .PARAMETER password - Password to use to connect to the database if SQL Authentication is used. - - .EXAMPLE - Invoke-SQLScript $env -database 'Online' -scriptPath '.\Analytics\Release 015.1.sql' -username 'CMFUser' -password 'CMFUser' - - .NOTES - Assumes SQL Script file is saved with UTF8 encoding. - GO batch separators are supported, assuming they are placed in separate lines. -#> -function Invoke-SQLScript -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject] $env, - - # Database - [Parameter(Mandatory=$True)] - [CMFDatabase] $database, - - # Script path - [Parameter(Mandatory=$True)] - [string] $scriptPath, - - # TimeoutScript path - [Parameter(Mandatory=$False)] - $timeOut = $null - ) - - $username = "" - $password = "" - - switch ($database) - { - "Online" - { - $databaseName = $env.OnlineDBName - $databaseServer = $env.OnlineClusterInstance - - if ($env.SQLOnlineWindowsAuthentication -eq $false) - { - $username = $env.SQLOnlineUser - $password = Get-ClearTextFromEncryptedString $env.SQLOnlinePassword - } - } - "ODS" - { - $databaseName = $env.ODSDBName - $databaseServer = $env.ODSClusterInstance - - if ($env.SQLODSWindowsAuthentication -eq $false) - { - $username = $env.SQLODSUser - $password = Get-ClearTextFromEncryptedString $env.SQLODSPassword - } - } - "DWH" - { - $databaseName = $env.DWHDBName - $databaseServer = $env.DWHClusterInstance - - if ($env.SQLDWHWindowsAuthentication -eq $false) - { - $username = $env.SQLDWHUser - $password = Get-ClearTextFromEncryptedString $env.SQLDWHPassword - } - } - } - - [string] $commandText = (Get-Content -Path $scriptPath -Encoding UTF8 | Out-String) - $commandText = $commandText.replace('$(DatabaseName)', $databaseName); - $commandText = $commandText.replace('$(OnlineDatabaseName)', $env.OnlineDBName); - $commandText = $commandText.replace('$(ODSDatabaseName)', $env.ODSDBName); - $commandText = $commandText.replace('$(DWHDatabaseName)', $env.DWHDBName); - - $scriptName = Split-Path $scriptPath -leaf - LogWrite " > Running SQL script $scriptName on $database database..." - $result = Invoke-SQL $databaseServer $databaseName $commandText $username $password $timeOut - LogWrite " * Executed SQL script $scriptName" -foregroundColor Green -} - -<# - .SYNOPSIS - Backup cmNavigo databases - - .DESCRIPTION - Backup one or all cmNavigo databases to a predefined folder (according to environment configuration). The backup folder is - created if it doesn't exist, as long as it is a network shared folder. - - Online database backups are stored on the path specified on the $env.OnlineBackupLocation property. - ODS database backups are stored on the path specified on the $env.ODSBackupLocation property. - DWH database backups are stored on the path specified on the $env.DWHBackupLocation property. - If the specific backup folder for a given database is null or not defined, the standard backup location will be used, - specified on the $env.BackupLocation property. - - Backups are identified by a backupIdentifier token which can later be used to restore the backup. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER backupIdentifier - Token used to identify the backups that will be taken. Backup files will be named according to this token. - If not specified, the file will be named using the current date/time in the format "yyyy.mm.dd-HHmmss". - - .PARAMETER database - Database to be backed up. Possible values include 'Online', 'ODS' and 'DWH'. - If not specified, all databases are backed up. - - .PARAMETER username - Username to use to connect to the database if SQL Authentication is used. If not specified, windows authentication will - be used. - - .PARAMETER password - Password to use to connect to the database if SQL Authentication is used. - - .PARAMETER useCompression - Flag to enable compression of backups - - .PARAMETER useParallelJob - Flag to enable parallel jobs. Useful when backing up several large databases - - .EXAMPLE - Backup-CMFDatabase $env - - .EXAMPLE - Backup-CMFDatabase $env -backupIdentifier 'Before4.2' - - .EXAMPLE - Backup-CMFDatabase $env -backupIdentifier 'Before4.2' -useParallelJob - - .EXAMPLE - Backup-CMFDatabase $env -backupIdentifier 'Before4.2' -database 'Online' - - .EXAMPLE - Backup-CMFDatabase $env -backupIdentifier 'Before4.2' -username 'CMFTest' -password 'CMFPassword' - - .NOTES - Local backup folders are local on the DB server and are not recommended. If the local folder does not exist, an error will - be thrown. - Backups are taken by SQL Server BACKUP DATABASE statement with the NOFORMAT, INIT, SKIP, NOREWIND, NOUNLOAD, COPY_ONLY - and STATS = 10 options. - Backup file names follow the naming convention: -.bak - - Requires permissions to write and create directories on the specified backup locations. -#> -function Backup-CMFDatabase -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # BackupID - [Parameter(Mandatory=$False)] - $backupIdentifier =$null, - - # Database - [Parameter(Mandatory=$False)] - [CMFDatabase] $database, - - # Username - [Parameter(Mandatory=$False)] - [string] $username, - - # Password - [Parameter(Mandatory=$False)] - [string] $password, - - # UseCompression - [Parameter(Mandatory=$False)] - $useCompression = $null, - - # Parallel backups - [Parameter(Mandatory=$False)] - [switch]$useParallelJob, - - [Parameter(Mandatory=$False)] - [int] $timeout = 600 - - ) - - LogWrite " > Starting database backup..." - - [CMFDatabase[]] $dbsToBackup = @() - if($database -ne $null) - { - $dbsToBackup += $database - } - else - { - $dbsTobackup = @('Online', 'ODS', 'DWH') - } - - $bgJobs = @() - - foreach($dbToBackup in $dbsToBackup) - { - $activityDescription = "Backing up " + $dbToBackup + " database" - LogWrite (" " + $activityDescription) - - $username = "" - $password = "" - - switch ($dbToBackup) - { - "Online" - { - $databaseName = $env.OnlineDBName - $databaseServer = $env.OnlineClusterInstance - $backupLocation = $env.OnlineBackupLocation - if ($env.SQLOnlineWindowsAuthentication -eq $false) - { - - $username = $env.SQLOnlineUser - $password = Get-ClearTextFromEncryptedString $env.SQLOnlinePassword - } - } - "ODS" - { - $databaseName = $env.ODSDBName - $databaseServer = $env.ODSClusterInstance - $backupLocation = $env.ODSBackupLocation - if ($env.SQLODSWindowsAuthentication -eq $false) - { - $username = $env.SQLODSUser - $password = Get-ClearTextFromEncryptedString $env.SQLODSPassword - } - } - "DWH" - { - $databaseName = $env.DWHDBName - $databaseServer = $env.DWHClusterInstance - $backupLocation = $env.DWHBackupLocation - - if ($env.SQLDWHWindowsAuthentication -eq $false) - { - $username = $env.SQLDWHUser - $password = Get-ClearTextFromEncryptedString $env.SQLDWHPassword - } - } - } - - if( $useCompression -eq $null ) - { - $useCompression = $env.SQLBackupCompression - } - - $compressionOption = "" - if($useCompression) - { - $compressionOption = ", COMPRESSION " - } - - # Prepare scripts - if ($backupIdentifier -eq $null) - { - $backupIdentifier = (Get-Date -Format "yyyy.MM.dd-HHmmss") - } - - # Get default backup location if specific is null - if ($backupLocation -eq $null) - { - $backupLocation = $env.BackupLocation - } - - # Check if folder is a network path - if ( ($backupLocation.StartsWith('\\'))) - { - # create backup folder if it doesn't exist - if (-not (Test-Path $backupLocation)) - { - $result = New-Item -ItemType Directory -Force -Path $backupLocation | Out-Null - } - - $backupFileName = $backupLocation+'\'+$backupIdentifier+'\'+$databaseName+"-"+$backupIdentifier+".bak" - $continueBackup = OverwriteBackupFile $backupFileName - } - else - { - # check if folder exists inside SQL Server instance - $sqlScript = "DECLARE @BackupDestination nvarchar(500) = N'$backupLocation'; - DECLARE @DirectoryExists int; EXEC master.dbo.xp_fileexist @BackupDestination, @DirectoryExists OUT; - IF @DirectoryExists = 0 EXEC master.sys.xp_create_subdir @BackupDestination;" - - $result = Invoke-SQL $databaseServer $databaseName $sqlScript -username $username -password $password - $backupFileName = $backupLocation+'\'+$backupIdentifier+'\'+$databaseName+"-"+$backupIdentifier+".bak" - $continueBackup = $true - } - - # create backup folder if it doesn't exist - New-Item -ItemType Directory -Force -Path (Split-Path -parent $backupFileName) | Out-Null - - if ($continueBackup -eq $True) - { - - $backupScript = "BACKUP DATABASE ["+$databaseName+"] TO DISK = N'"+$backupFileName+"' WITH COPY_ONLY, NOFORMAT, INIT, NAME = N'"+$databaseName+"-Full Database Backup', SKIP, NOREWIND, NOUNLOAD "+ $compressionOption +", STATS = 10" - - if( -not($useParallelJob) ) - { - Write-Progress -Activity ($activityDescription) -Status "Please wait..." - $result = Invoke-SQL $databaseServer $databaseName $backupScript -username $username -password $password -timeOut $timeout - Write-Progress -Activity $activityDescription -Completed -Status (" " + $dbToBackup + " Backed Up") - LogWrite (" " + $dbToBackup + " Backed Up") - } - else - { - LogWrite "$activityDescription started" - $sc = { - param($databaseServer, $databaseName, $backupScript, $username, $password, $timeOut) - $result = Invoke-SQL $databaseServer $databaseName $backupScript -username $username -password $password -timeOut $timeOut - } - - $initscript= [scriptblock]::create(@" - [Environment]::SetEnvironmentVariable("CMFInstallActionsPreventClear", "true") -import-module -name "$ModulePath\CMFInstallActions.psd1" -"@) - - $bgJobs += Start-Job -Name $activityDescription -ScriptBlock $sc -ArgumentList @($databaseServer, $databaseName, $backupScript, $username, $password, $timeOut) -InitializationScript $initscript - } - } - else - { - LogWrite (" Backup of database " + $dbToBackup + " was bypassed due to previous backup file...") -foregroundColor Yellow - } - } - if( $useParallelJob ){ - Wait-Job -Job $bgJobs | Out-Null - - foreach ($job in $bgJobs) { - $RemoteErr = $null - $output = Receive-Job $job -Keep -ErrorVariable RemoteErr - if( $RemoteErr -ne $null ) - { - throw $RemoteErr - } else { - LogWrite (" " + $job.Name + " finished") - } - } - } - - LogWrite " * Finished database backup!" -foregroundColor Green -} - -<# - .SYNOPSIS - Restore cmNavigo databases - - .DESCRIPTION - Restore one or all cmNavigo databases from a predefined folder (according to environment configuration). - - Online database backups are stored on the path specified on the $env.OnlineBackupLocation property. - ODS database backups are stored on the path specified on the $env.ODSBackupLocation property. - DWH database backups are stored on the path specified on the $env.DWHBackupLocation property. - If the specific backup folder for a given database is null or not defined, the standard backup location will be used, - specified on the $env.BackupLocation property. - - Backups are identified by a backupIdentifier token which should correspond to a previously taken backup. - - AlwaysOn High-Availability Groups are supported. Make sure to set the $env.OnlineClusterAlwaysOn, - $env.ODSClusterAlwaysOn and $env.DWHClusterAlwaysOn to $true. - The definition of the replicas included in the HADR cluster is also required, using: - - $env.OnlineReplicas += 'CMF-VM-CLT-DB1\ONLINE2014' - $env.OnlineReplicas += 'CMF-VM-CLT-DB2\ONLINE2014' - $env.ODSReplicas = $env.OnlineReplicas - $env.DWHReplicas = $env.OnlineReplicas - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER backupIdentifier - Token used to identify the backup files to be restored. - - .PARAMETER database - Database to be restored. Possible values include 'Online', 'ODS' and 'DWH'. - If not specified, all databases are restored, in the following order: Online, ODS, DWH. - - .PARAMETER requireConfirmation - Set this flag to force an interactive confirmation from the user before restoring the database. - - .EXAMPLE - Restore-CMFDatabase $env - - .EXAMPLE - Restore-CMFDatabase $env -backupIdentifier 'Before4.2' - - .EXAMPLE - Restore-CMFDatabase $env -backupIdentifier 'Before4.2' -database 'Online' - - .NOTES - Backup file names are assumed to follow the naming convention: -.bak - Before restore, existing database is set to single user mode with immediate rollback. Database is restored to multi-user mode after - restore is complete. - After completion of the restore procedure, database is set as TRUSTWORTHY and the dbowner is changed to 'sa'. - - cmNavigo application hosts must be stopped during the restore procedure. -#> -function Restore-CMFDatabase -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # BackupID - [Parameter(Mandatory=$True)] - [string]$backupIdentifier, - - # Database - [Parameter(Mandatory=$False)] - $database, - - # Require Confirmation - [Parameter(Mandatory=$False)] - [switch]$requireConfirmation, - - [Parameter(Mandatory=$False)] - [int]$timeout = 600 - ) - - LogWrite " > Starting database restore..." - - [CMFDatabase[]] $dbsToBackup = @() - if($database) - { - $dbsToBackup += $database - } - else - { - $dbsTobackup = @('Online', 'ODS', 'DWH') - } - - foreach($dbToBackup in $dbsToBackup) - { - $activityDescription = "Restoring $dbToBackup database" - LogWrite (" " + $activityDescription) - Write-Progress -Activity ($activityDescription) -Status "Please wait..." - - $username = "" - $password = "" - - switch ($dbToBackup) - { - "Online" - { - $databaseName = $env.OnlineDBName - $databaseServer = $env.OnlineClusterInstance - $backupLocation = $env.OnlineBackupLocation - $replicas = $env.OnlineReplicas - - if ($env.SQLOnlineWindowsAuthentication -eq $false) - { - $username = $env.SQLOnlineUser - $password = Get-ClearTextFromEncryptedString $env.SQLOnlinePassword - } - - $isAlwaysOn = $env.OnlineClusterAlwaysOn - } - "ODS" - { - $databaseName = $env.ODSDBName - $databaseServer = $env.ODSClusterInstance - $backupLocation = $env.ODSBackupLocation - $replicas = $env.ODSReplicas - - if ($env.SQLODSWindowsAuthentication -eq $false) - { - $username = $env.SQLODSUser - $password = Get-ClearTextFromEncryptedString $env.SQLODSPassword - } - - $isAlwaysOn = $env.ODSClusterAlwaysOn - } - "DWH" - { - $databaseName = $env.DWHDBName - $databaseServer = $env.DWHClusterInstance - $backupLocation = $env.DWHBackupLocation - $replicas = $env.DWHReplicas - - if ($env.SQLDWHWindowsAuthentication -eq $false) - { - $username = $env.SQLDWHUser - $password = Get-ClearTextFromEncryptedString $env.SQLDWHPassword - } - - $isAlwaysOn = $env.DWHClusterAlwaysOn - } - } - - if ($requireConfirmation) - { - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-host " Please confirm if you want to proceed with Restore operation for $dbToBackup database" - Write-Host " Do not restore [n]" -ForegroundColor Yellow -NoNewline - Write-Host " Proceed with restore [y]: " -NoNewline - } - - $confirmation = Read-Host - if ($confirmation -ne 'y') - { - # If the user does not confirm the restore, proceed to the next database - LogWrite (" Restore of database $dbToBackup was not performed due to user selection.") -foregroundColor Yellow - continue - } - } - - # Get default backup location if specific is null - if ($null -eq $backupLocation) - { - $backupLocation = $env.BackupLocation - } - - # Prepare scripts - if ($null -eq $backupIdentifier) - { - $backupIdentifier = (Get-Date -Format "yyyy.MM.dd-HHmmss") - } - - $backupFileName = $backupLocation + "\" + $backupIdentifier + "\" + $databaseName + "-" + $backupIdentifier + ".bak" - - if ($isAlwaysOn -ne $true) - { - # No AlwaysOn - single server or windows failover clustering - use regular restore scripts - Restore-SqlDatabase -instanceName $databaseServer ` - -databaseName $databaseName ` - -backupFilename $backupFileName ` - -username $username ` - -password $password ` - -timeout $timeout - } - else - { - # AlwaysOn Logic - $availabilityGroupName = Get-AvailabilityGroupNameFromListenerAddress -instanceName $databaseServer ` - -username $username ` - -password $password - - # Determine what server is acting as primary - $primaryServer = Get-PrimaryForAvailabilityGroup ` - -replicas $replicas ` - -database $databaseName ` - -username $username -password $password - - # Remove DB from AG and drop from secondary - Write-Progress -Activity $activityDescription -Status "Removing $dbtoBackup database from Availability Group..." - Remove-DatabaseFromAvailabilityGroup ` - -database $databaseName ` - -availabilityGroup $availabilityGroupName ` - -replicas $replicas ` - -primary $primaryServer ` - -DropFromSecondary ` - -username $username -password $password - - # Restore on primary server - Write-Progress -Activity $activityDescription -Status "Restoring $dbtoBackup database on primary replica..." - Restore-SqlDatabase ` - -databaseName $databaseName ` - -instanceName $primaryServer ` - -backupFilename $backupFileName ` - -username $username -password $password ` - -timeout $timeout - - # Re-add to availability group - $backupLocation = $env.BackupLocation - Write-Progress -Activity $activityDescription -Status "Joining $dbtoBackup database to Availability Group..." - Add-DatabaseToAvailabilityGroup ` - -database $databaseName ` - -availabilityGroupInstanceName $databaseServer ` - -primary $primaryServer ` - -replicas $replicas ` - -backupLocation $backupLocation ` - -username $username -password $password - - } - - Write-Progress -Activity $activityDescription -Completed -Status "Restore of $dbToBackup database has been completed." - } - - LogWrite " * Finished database restore!" -foregroundColor Green -} - -<# - .SYNOPSIS - Restores an SQL database - - .DESCRIPTION - Executes a simple restore command for an SQL database - - .PARAMETER instanceName - SQL Server instance name against which the RESTORE statement will be ran - - .PARAMETER databaseName - Name of the database to be backed up - - .PARAMETER backupFilename - Path to the backup file to restore - - .PARAMETER username - Username to be used to connect to the database. If $null, Windows Authentication will be used. - - .PARAMETER password - Password used to connect to the database. If $username is not set, Windows Authentication will be used. - - .PARAMETER restoreOnly - If set, no operation will be performed on the existing database before restoring (not set to single_user) - - .PARAMETER norecovery - If set, the NORECOVERY option is used. Required for restoring database replicas for AlwaysOn. - - .EXAMPLE - Restore-SQLDatabase 'MSSQL\ONLINE' 'Development' 'C:\Backup.bak' -#> -function Restore-SQLDatabase -{ - param - ( - # Instance name - [Parameter(Mandatory=$True)] - [string] $instanceName, - - # Database Name - [Parameter(Mandatory=$True)] - $databaseName, - - # Backup file name - [Parameter(Mandatory=$True)] - [string] $backupFilename, - - # Username - [Parameter(Mandatory=$False)] - [string] $username, - - # Password - [Parameter(Mandatory=$False)] - [string] $password, - - # Restore only - [Parameter(Mandatory=$False)] - [switch] $restoreOnly, - - # Use NORECOVERY option - [Parameter(Mandatory=$False)] - [switch] $norecovery, - - [Parameter(Mandatory=$False)] - [string] $TargetLocation, - - [Parameter(Mandatory=$False)] - [int] $timeout = 600 - - ) - - $restoreScript = "" - if (!$restoreOnly) - { - $restoreScript += "ALTER DATABASE [" + $databaseName + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE `n" - } - if ($norecovery) - { - $restoreScript += "RESTORE DATABASE [" + $databaseName + "] FROM DISK = N'" + $backupFileName + "' WITH NORECOVERY, FILE = 1, NOUNLOAD, REPLACE, STATS = 5 `n" - } - else - { - $restoreScript += "RESTORE DATABASE [" + $databaseName + "] FROM DISK = N'" + $backupFileName + "' WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 5 `n" - $restoreScript += "ALTER DATABASE [" + $databaseName + "] SET MULTI_USER `n" - $restoreScript += "GO `n" - $restoreScript += "USE [" + $databaseName + "] `n" - $restoreScript += "GO `n" - $restoreScript += "ALTER DATABASE CURRENT SET TRUSTWORTHY ON `n" - $restoreScript += "EXEC sp_changedbowner 'sa'" - } - $result = Invoke-SQL $instanceName 'master' $restoreScript -username $username -password $password -timeout $timeout - -} - -<# - .SYNOPSIS - Executes scripts of a entire folder - - .DESCRIPTION - Executes all scripts ( *.sql ) against a database - - .PARAMETER dataSource - Data source name (i.e. instance name) to be used when connecting to the database. - - .PARAMETER folderPath - Folder containing the scripts to be executed - - .EXAMPLE - Invoke-PackageSqlScripts $env 'Online' 'c:\package\database\online' -#> -function Invoke-PackageSqlScripts -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # CMFDataBase - [Parameter(Mandatory=$True)] - $dataBase, - - #directory to enumerate the files - [Parameter(Mandatory=$True)] - $folderPath, - - [Parameter(Mandatory=$False)] - $timeOut = $null - ) - - if( Test-Path $folderPath ) - { - foreach($file in ( Get-ChildItem $folderPath -Filter '*.sql') ) - { - Invoke-SQLScript $env -database $database -scriptPath $file.FullName -timeout $timeOut - } - } -} - -<# - .SYNOPSIS - Removes a database from an availability group - - .DESCRIPTION - Removes a given system database from the respective HADR availability group. - Optionally, the database can be dropped from all secondary replicas, which is useful for a restore operation. - - .PARAMETER availabilityGroup - Instance name for the Availability Group - - .PARAMETER replicas - List of replicas in the availability group - - .PARAMETER database - database to be removed from the availability group - - .PARAMETER primary - Primary server for the availability group - - .PARAMETER username - Username to be used to connect to the database. If $null, Windows Authentication will be used. - - .PARAMETER password - Password used to connect to the database. If $username is not set, Windows Authentication will be used. - - .PARAMETER DropFromSecondary - Set to true to enable dropping the database from the secondary servers - - .EXAMPLE - $replicas += 'CMF-VM-CLT-DB1\ONLINE2012' - $replicas += 'CMF-VM-CLT-DB2\ONLINE2012' - Remove-DatabaseFromAvailabilityGroup -availability 'AG2012\ONLINE' -replicas $replicas -database 'Development' - - .EXAMPLE - $replicas += 'CMF-VM-CLT-DB1\ONLINE2012' - $replicas += 'CMF-VM-CLT-DB2\ONLINE2012' - $primary = 'CMF-VM-CLT-DB2\ONLINE2012' - Remove-DatabaseFromAvailabilityGroup -availability 'AG2012\ONLINE' -replicas $replicas -database 'Development' -primary $primary -DropFromSecondary -#> -function Remove-DatabaseFromAvailabilityGroup -{ - param - ( - # availability Group name - [Parameter(Mandatory=$True)] - [string] $availabilityGroup, - - # Availability group replicas - [Parameter(Mandatory=$True)] - $replicas, - - # Database - [Parameter(Mandatory=$True)] - [string] $database, - - # primary server - [Parameter(Mandatory=$False)] - $primary, - - # Username - [Parameter(Mandatory=$False)] - [string] $username, - - # Password - [Parameter(Mandatory=$False)] - [string] $password, - - # Drop from secondary servers - [Parameter(Mandatory=$False)] - [switch] $DropFromSecondary = $False - ) - - # Check which server is primary - if ($null -eq $primary) - { - $primary = Get-PrimaryForAvailabilityGroup -replicas $replicas -database $database -username $username -password $password - } - - - # Remove database from availability group - $sql = "ALTER AVAILABILITY GROUP [$availabilityGroup] REMOVE DATABASE [$database]; " - $result = Invoke-SQL $primary 'master' $sql -username $username -password $password - - # Drop database from all secondary servers - if ($DropFromSecondary) - { - foreach($server in $replicas) - { - if ($server -ne $primary) - { - # Wait for database to be in restoring state before continuing -- otherwise DROP DATABASE will fail - $sql = "WHILE ((select DATABASEPROPERTYEX('$database', 'Status')) <> 'RESTORING') WAITFOR DELAY '00:00:01'" - $result = Invoke-SQL $server 'master' $sql -username $username -password $password -timeOut 120 - - # Drop it. - $sql = "DROP DATABASE [$database];" - $result = Invoke-SQL $server 'master' $sql -username $username -password $password - } - } - } - -} - -<# - .SYNOPSIS - Adds a database to an availability group - - .DESCRIPTION - Adds a given system database the an respective availability group. - - Assumes that the secondary replica does not contain a database with the same name. Script will perform full - backups and log backups from the primary replica and apply them to the secondary replicas before joining the availability group. - - .PARAMETER availabilityGroupInstanceName - Instance name for the Availability Group - - .PARAMETER replicas - List of replicas in availability group in the availability group - - .PARAMETER database - Database to be added to the availability group - - .PARAMETER backupLocation - Path to store temporary database and log backups required for adding databases to HADR cluster - - .PARAMETER primary - Primary server for the availability group - - .PARAMETER username - Username to be used to connect to the database. If $null, Windows Authentication will be used. - - .PARAMETER password - Password used to connect to the database. If $username is not set, Windows Authentication will be used. - - .EXAMPLE - $replicas += 'CMF-VM-CLT-DB1\ONLINE2012' - $replicas += 'CMF-VM-CLT-DB2\ONLINE2012' - $primary = 'CMF-VM-CLT-DB2\ONLINE2012' - Remove-DatabaseFromAvailabilityGroup 'AG2012\ONLINE' -replicas $replicas -database 'Development' -primary $primary -#> -function Add-DatabaseToAvailabilityGroup -{ - param - ( - # availability Group instance name - [Parameter(Mandatory=$True)] - [string] $availabilityGroupInstanceName, - - # Availability group nodes - [Parameter(Mandatory=$True)] - $replicas, - - # Database - [Parameter(Mandatory=$True)] - [string] $database, - - # Backup location - [Parameter(Mandatory=$True)] - [string] $backupLocation, - - # primary server - [Parameter(Mandatory=$True)] - $primary, - - # Username - [Parameter(Mandatory=$False)] - [string] $username, - - # Password - [Parameter(Mandatory=$False)] - [string] $password - ) - - $availabilityGroup = $availabilityGroupInstanceName.Split("\")[0] - - # Add database to availability group - $sql = "ALTER AVAILABILITY GROUP [" + $availabilityGroup + "] ADD DATABASE ["+ $database + "]" - $result = Invoke-SQL $availabilityGroupInstanceName 'master' $sql -username $username -password $password - - # Create primary full backup and log backup - $timestamp = Get-Date -format yyyymmddhhmmss - $fullbackupPath = Join-Path $backupLocation "$databaseName_$timestamp.bak" - $logbackupPath = Join-Path $backupLocation "$databaseName_$timestamp.trn" - - $sql = "BACKUP DATABASE [$database] TO DISK = N'$fullbackupPath' WITH COPY_ONLY, FORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION, STATS = 5" - $result = Invoke-SQL $availabilityGroupInstanceName 'master' $sql -username $username -password $password - - $sql = "BACKUP LOG [$database] TO DISK = N'$logbackupPath' WITH COPY_ONLY, NOFORMAT, NOINIT, NOSKIP, REWIND, NOUNLOAD, COMPRESSION, STATS = 5" - $result = Invoke-SQL $availabilityGroupInstanceName 'master' $sql -username $username -password $password - - # Restore database on secondary replicas - foreach($server in $replicas) - { - if ($server -ne $primary) - { - # Ensure replica has privileges to create databases - $sql = "ALTER AVAILABILITY GROUP $availabilityGroup GRANT CREATE ANY DATABASE;" - $result = Invoke-SQL $server 'master' $sql -username $username -password $password - - # Get seeding mode to determine if restore is to be made or not... - $sql = "DECLARE @ReturnValue NVARCHAR(512) = N'MANUAL' - DECLARE @DBVersion INT - DECLARE @StringVersion NVARCHAR(512) = CONVERT(NVARCHAR, SERVERPROPERTY('productversion')) - DECLARE @FinalChar INTEGER = CHARINDEX('.', @StringVersion, 1) - - IF( @FinalChar > 1) - BEGIN - SET @StringVersion = SUBSTRING(@StringVersion, 1, @FinalChar - 1) - END - - SET @DBVersion = CONVERT(INTEGER, @StringVersion) - IF(@DBVersion >= 13) - BEGIN - - SELECT @ReturnValue = AR.[seeding_mode_desc] - from [sys].[availability_replicas] AR - INNER JOIN [sys].[availability_groups] AG ON AG.[group_id] = AR.[group_id] - WHERE AG.[name] = '$availabilityGroup' AND AR.[replica_server_name] = '$server' - - END - - SELECT @ReturnValue SeedingMode" - $seedingMode = Invoke-SQL $server 'master' $sql -username $username -password $password -returnScalar - - # If we're dealing with a manual seeding mode, restore database in secondary replica along with the log - if($seedingMode -eq "MANUAL") { - - # Restore Full backup - $sql = "RESTORE DATABASE [$database] FROM DISK = N'$fullbackupPath' WITH NORECOVERY, NOUNLOAD, STATS = 5" - $result = Invoke-SQL $server 'master' $sql -username $username -password $password - - # Restore log - $sql = "RESTORE LOG [$database] FROM DISK = N'$logbackupPath' WITH NORECOVERY, NOUNLOAD, STATS = 5" - $result = Invoke-SQL $server 'master' $sql -username $username -password $password - - # Wait for replica to become online and add to availability group - $sql = @' - begin try - declare @conn bit - declare @count int - declare @replica_id uniqueidentifier - declare @group_id uniqueidentifier - set @conn = 0 - set @count = 30 -- wait for 5 minutes - - if (serverproperty('IsHadrEnabled') = 1) - and (isnull((select member_state from master.sys.dm_hadr_cluster_members where upper(member_name) = upper(cast(serverproperty('ComputerNamePhysicalNetBIOS') as nvarchar(256)))), 0) <> 0) - and (isnull((select state from master.sys.database_mirroring_endpoints), 1) = 0) - begin - select @group_id = ags.group_id from master.sys.availability_groups as ags where name = N'$(AVAILABILITYGROUPNAME)' - select @replica_id = replicas.replica_id from master.sys.availability_replicas as replicas where upper(replicas.replica_server_name) = upper(@@SERVERNAME) and group_id = @group_id - while @conn <> 1 and @count > 0 - begin - set @conn = isnull((select connected_state from master.sys.dm_hadr_availability_replica_states as states where states.replica_id = @replica_id), 1) - if @conn = 1 - begin - -- exit loop when the replica is connected, or if the query cannot find the replica status - break - end - waitfor delay '00:00:10' - set @count = @count - 1 - end - end - end try - begin catch - -- If the wait loop fails, do not stop execution of the alter database statement - end catch - ALTER DATABASE [$(DATABASE)] SET HADR AVAILABILITY GROUP = [$(AVAILABILITYGROUPNAME)]; -'@ - - $sql = $sql.Replace('$(AVAILABILITYGROUPNAME)', $availabilityGroup) - $sql = $sql.Replace('$(DATABASE)', $database) - - $result = Invoke-SQL $server 'master' $sql -username $username -password $password - - } - } - } - - try { - Remove-Item $fullbackupPath -ErrorAction Stop - } - catch { - LogWrite " > Error while removing $fullbackupPath" -foreGroundColor Red - } - - try { - Remove-Item $logbackupPath -ErrorAction Stop - } - catch { - LogWrite " > Error while removing $logbackupPath" -foreGroundColor Red - } -} - -<# - .SYNOPSIS - Returns the primary server for an availability group - - .DESCRIPTION - Returns the name of the primary SQL server instance on a given availability group - - .PARAMETER Replicas - List of all replicas in availability group - - .PARAMETER database - Name of the database to be checked - - .PARAMETER username - Username to be used to connect to the database. If $null, Windows Authentication will be used. - - .PARAMETER password - Password used to connect to the database. If $username is not set, Windows Authentication will be used. - - .EXAMPLE - Get-PrimaryForAvailabilityGroup -replicas $nodes -database $databaseName -username $username -password $password -#> -function Get-PrimaryForAvailabilityGroup -{ - param - ( - # Availability group nodes - [Parameter(Mandatory=$True)] - $replicas, - - # Database - [Parameter(Mandatory=$True)] - [string] $database, - - # Username - [Parameter(Mandatory=$False)] - [string] $username, - - # Password - [Parameter(Mandatory=$False)] - [string] $password - ) - - $sql = "select role_desc " - $sql += "from sys.dm_hadr_availability_replica_states states " - $sql += "inner join sys.databases dbs on dbs.replica_id = states.replica_id " - $sql += "where is_local = 1 and name = '" + $database + "'" - foreach($server in $replicas) - { - $result = Invoke-SQL $server 'master' $sql -username $username -password $password -returnScalar - if ($result -eq "PRIMARY") - { - $primaryServer = $server - break - } - } - - if ($null -eq $primaryServer) - { - throw "Database is not part of any availability group" - } - - return $primaryServer -} - -<# - .SYNOPSIS - Returns the availability group name from the listener address - - .DESCRIPTION - Returns the availability group name from the listener address - - .PARAMETER instanceName - Address of the availability group instance - - .PARAMETER username - Username to be used to connect to the database. If $null, Windows Authentication will be used. - - .PARAMETER password - Password used to connect to the database. If $username is not set, Windows Authentication will be used. - - .EXAMPLE - Get-AvailabilityGroupNameFromListenerAddress -instanceName 'AG2016' -database $databaseName -username $username -password $password -#> -function Get-AvailabilityGroupNameFromListenerAddress -{ - param - ( - # Availability group instance - [Parameter(Mandatory=$True)] - $instanceName, - - # Username - [Parameter(Mandatory=$False)] - [string] $username, - - # Password - [Parameter(Mandatory=$False)] - [string] $password - ) - - $listenerAddress = $instanceName.Split("\")[0] - - $sql = "SELECT ags.name FROM sys.availability_groups ags " - $sql += "INNER JOIN sys.availability_group_listeners agsl " - $sql += "ON ags.group_id = agsl.group_id AND agsl.dns_name = '" + $listenerAddress + "'" - - $agName = Invoke-SQL $instanceName 'master' $sql -username $username -password $password -returnScalar - - if ($null -eq $agName) - { - throw "Could not determine Availability Group name for listener address " + $listenerAddress - } - - return $agName -} - -<# - .SYNOPSIS - Prompts the interactive user for a password and test against a data source. - - .DESCRIPTION - Prompts the interactive user for a password and test against a data source. - - .PARAMETER dataSource - Data source name (i.e. instance name) to be used when connecting to the database. - - .PARAMETER username - Username to use to connect to the sql server if SQL Authentication is used. - be used. - - .OUTPUTS - A password, in CLEAR TEXT, validated against the datasource specified - - .EXAMPLE - Read-SQLPassword -dataSource 'CMF-VM-TEST\ONLINE' -username SQLUser -#> -function Read-SQLPassword -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $dataSource, - - [Parameter(Mandatory=$True)] - [string] $username - ) - - $securePassword = Read-Host "Enter password for user $username at $dataSource" -AsSecureString - $psCred = New-Object System.Management.Automation.PSCredential $username, $securePassword - [string] $clearPassword = $psCred.GetNetworkCredential().Password - - - try - { - $dummy = Invoke-SQL -dataSource $dataSource -database 'master' -sqlCommand "SELECT GETUTCDATE()" -username $username -password $clearPassword - } - catch [Exception] - { - LogWrite $_.Exception.Message -ForegroundColor Red - throw "Invalid password for $username" - } - - return $clearPassword -} - -<# - .SYNOPSIS - Prompt message asking if should overwrite a existing backup - - .DESCRIPTION - Returns the result if should overwrite a existing backup - - .PARAMETER $backupPath - The location of the backup path - - .EXAMPLE - OverwriteBackupFile 'c:\filename.zip' - - -#> -function OverwriteBackupFile -{ - Param - ( - [string]$backupPath - ) - - if (Test-Path $backupPath) - { - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-host " Backup file " $backupPath "already exists!!" - Write-Host " Ignore Backup [i]" -ForegroundColor Yellow -NoNewline - Write-Host " or Overwrite [o]: " -NoNewline - - - $confirmation = Read-Host - } - else - { - $confirmation = 'o' - } - - if ($confirmation -ne 'o') - { - return $false - } - } - - return $true - -} \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/CMFInstallActions.psd1 b/cmf-cli/installDependencies/Data/CMFInstallActions/CMFInstallActions.psd1 deleted file mode 100644 index 2e474df14..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/CMFInstallActions.psd1 and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/CMFInstallActions.psm1 b/cmf-cli/installDependencies/Data/CMFInstallActions/CMFInstallActions.psm1 deleted file mode 100644 index 8d20a637f..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/CMFInstallActions.psm1 +++ /dev/null @@ -1,5391 +0,0 @@ -$ModulePath = Split-Path $MyInvocation.MyCommand.Path -$Logfile = "$(gc env:computername)" + "_" + (Get-Date).ToString("yyyyMMddHH.mm.ss") + ".log" -$GenericLogFile = $true -$ShowProgressBar = $false - -Add-Type -TypeDefinition "public enum CMFDatabase { Online, ODS, DWH, Replication }" - -#clear screen when this module is called - -if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - if( -not($env:CMFInstallActionsPreventClear )) - { - clear - } -} - -# Set Global Variables for CMF Folders -if( !($CMFFoldersLoaded)) -{ - Set-Variable CMFFoldersLoaded -Value $true -scope global - if( !($CMFBusinessTier)) - { - Set-Variable CMFBusinessTier -Value 'BusinessTier' -scope global - } - if( !($CMFDiscoveryService)) - { - Set-Variable CMFDiscoveryService -Value 'DiscoveryService' -scope global - } - if( !($CMFHelp)) - { - Set-Variable CMFHelp -Value 'UI\Help' -scope global - } - if( !($CMFHTML)) - { - Set-Variable CMFHTML -Value 'UI\Html' -scope global - } - if( !($CMFLBOGenerator)) - { - Set-Variable CMFLBOGenerator -Value 'LBOGenerator' -scope global - } - if( !($CMFLBOGeneratorWCF)) - { - Set-Variable CMFLBOGeneratorWCF -Value 'LBOGeneratorWCF' -scope global - } - if( !($CMFMasterDataLoader)) - { - Set-Variable CMFMasterDataLoader -Value 'MasterDataLoader' -scope global - } - if( !($CMFMessageBusGateway)) - { - Set-Variable CMFMessageBusGateway -Value 'MessageBusGateway' -scope global - } - if( !($CMFPresentationTier)) - { - Set-Variable CMFPresentationTier -Value 'UI\Silverlight' -scope global - } - if( !($CMFProtectUnprotectConfigFile)) - { - Set-Variable CMFProtectUnprotectConfigFile -Value 'ProtectUnprotectConfigFile' -scope global - } -} - -<# - .SYNOPSIS - Creates a new object to represent a cmNavigo environment - - .DESCRIPTION - Returns a new custom object which contains all the required information to run the installation scripts. - - .PARAMETER SystemName - cmNavigo environment name selected during installation. This is usually part of the website address. - - .EXAMPLE - $env = New-CMFEnvironment 'Staging' - $env.NLBAddress = 'cmf-vm-test' - $env.ServicePort = 9050 - $env.ReadPasswordToSignGeneratedLBOs = $true - $env.ApplicationServers += New-CMFServer 'cmf-vm-test' - $env.OnlineClusterInstance = 'cmf-vm-test\ONLINE' - $env.ODSClusterInstance = 'cmf-vm-test\ONLINE' - $env.DWHClusterInstance = 'cmf-vm-test\ONLINE' - $env.NavigoServiceName = 'cmFoundationSrv' + $env.SystemName + 'Host' - $env.BackupLocation = '\\CMF-VM-test\'+$env.SystemName+'Shares\Backups\Test' - $env.OnlineBackupLocation = '\\CMF-VM-test\'+$env.SystemName+'Shares\Backups\Test\Online' - $env.ODSBackupLocation = '\\CMF-VM-test\'+$env.SystemName+'Shares\Backups\Test\ODS' - $env.DWHBackupLocation = '\\CMF-VM-test\'+$env.SystemName+'Shares\Backups\Test\DWH' - $env.SQLOnlineWindowsAuthentication = $true - $env.SQLOnlineUser = 'user' - $env.SQLOnlinePassword = 'pass' #Read-SQLPassword '«DataSource»' '«UserName»' - $env.SQLODSWindowsAuthentication = $true - $env.SQLODSUser = 'user' - $env.SQLODSPassword = 'pass' #Read-SQLPassword '«DataSource»' '«UserName»' - $env.SQLDWHWindowsAuthentication = $false - $env.SQLDWHUser = 'user' - $env.SQLDWHPassword = 'pass' #Read-SQLPassword '«DataSource»' '«UserName»' - $env.SQLBackupCompression = $true - $env.ReportServerUri = 'http://cmf-vm-atsh/ReportServer_Online' - $env.ReportUseDefaultCredential = $true - $env.ReportServerUser = '«CMFUser»' - $env.ReportServerPassword = '«CMFUser»' - $env.ReportsOnlineDataSource = '/Datasources/StagingAS' - $env.ReportsODSDataSouce = '/Datasources/StagingODS' - $env.ReportsDWHDataSource = '/Datasources/StagingDWH' - - .OUTPUTS - A custom object representing the cmNavigo environment. The object contains the following properties: - - NLBAddress: address of the NLB cluster in use (or the single app server if NLB is not in use) - - ServicePort: port used for WCF services exposed by the application host - - ReadPasswordToSignGeneratedLBOs: Flag to read password to GenerateLBOs. Required when certificate is encrypted with password. - - ApplicationServers: list of application servers. Should be objects created with the New-CMFServer function. - - OnlineClusterInstance:instance name for the ONLINE database - - ODSClusterInstance: instance name for the ODS database - - DWHClusterInstance: instance name for the DWH database - - OnlineClusterAlwaysOn set to $true if ONLINE cluster is an AlwaysOn Availability Group - - ODSClusterInstanceAlwaysOn set to $true if ODS cluster is an AlwaysOn Availability Group - - DWHClusterInstanceAlwaysOn set to $true if DWH cluster is an AlwaysOn Availability Group - - OnlineReplicas list of database replicas used in HADR cluster for Online database - - ODSReplicas list of database replicas used in HADR cluster for ODS database - - DWHReplicas list of database replicas used in HADR cluster for DWH database - - NavigoServiceName name of the windows service running the application hosts in each app server - - BackupLocation location of the database backups (can be overridden by specific locations per database) - - OnlineBackupLocation: location of the database backups for the online database - - ODSBackupLocation: location of the ODS database backups - - DWHBackupLocation: location of the DWH database backups - - SQLOnlineWindowsAuthentication: Set if the SQL Connection to Online Database is using Windows Authentication - - SQLOnlineUser: The SQL Online Username - - SQLOnlinePassword: The SQL Online Password for selected user - - SQLODSWindowsAuthentication: Set if the SQL Connection to ODS Database is using Windows Authentication - - SQLODSUser: The SQL ODS Username - - SQLODSPassword: The SQL ODS Password for selected user - - SQLDWHWindowsAuthentication: Set if the SQL Connection to DataWareHouse Database is using Windows Authentication - - SQLDWHUser: The SQL DataWareHouse Username - - SQLDWHPassword: The SQL DataWareHouse Password for selected user - - SQLBackupCompression Flag to compress database backups - - ReportServerUri: The ReportServer Uri of Reports - - ReportUseDefaultCredential: Set if the connection to the Report Server is using the default credentials, or if need to set credentials - - ReportServerUser: The Username to access to reportserver - - ReportServerPassword: The password to access to reportserver for selected user - - ReportsOnlineDataSource: The name (and path) of the ReportServer Datasource to database Online - - ReportsODSDataSouce: The name (and path) of the ReportServer Datasource to database ODS - - ReportsDWHDataSource: The name (and path) of the ReportServer Datasource to database DataWareHouse - - .NOTES - The ApplicationServers properties of the returned object are lists which should be filled - with objects created using the New-CMFServer function. Check the corresponding help entry for additional - information. -#> -function New-CMFEnvironment() -{ - param - ( - [string] $SystemName - ) - - $NavigoServiceName = 'cmHostService' + $SystemName - $ODSDBName = $SystemName + 'ODS' - $DWHDBName = $SystemName + 'DWH' - $ReportsOnlineDataSource = '/Datasources/'+$SystemName - $ReportsASDataSource = '/Datasources/'+$SystemName+'AS' - $ReportsODSDataSouce = '/Datasources/'+$SystemName+'ODS' - $ReportsDWHDataSource = '/Datasources/'+$SystemName+'DWH' - - $environment = new-object PSObject - - $environment | add-member -type NoteProperty -Name SystemName -Value $SystemName - - $environment | add-member -type NoteProperty -Name NavigoServiceName -Value $NavigoServiceName - - # derived database names - $environment | add-member -type NoteProperty -Name OnlineDBName -Value $SystemName - $environment | add-member -type NoteProperty -Name ODSDBName -Value $ODSDBName - $environment | add-member -type NoteProperty -Name DWHDBName -Value $DWHDBName - - # database instances - $environment | add-member -type NoteProperty -Name OnlineClusterInstance -Value $null - $environment | add-member -type NoteProperty -Name ODSClusterInstance -Value $null - $environment | add-member -type NoteProperty -Name DWHClusterInstance -Value $null - $environment | add-member -type NoteProperty -Name OnlineClusterAlwaysOn -Value $false - $environment | add-member -type NoteProperty -Name ODSClusterAlwaysOn -Value $false - $environment | add-member -type NoteProperty -Name DWHClusterAlwaysOn -Value $false - $environment | add-member -type NoteProperty -Name OnlineReplicas -Value @() - $environment | add-member -type NoteProperty -Name ODSReplicas -Value @() - $environment | add-member -type NoteProperty -Name DWHReplicas -Value @() - - # server names - $environment | add-member -type NoteProperty -Name ApplicationServers -Value @() - $environment | add-member -type NoteProperty -Name NLBAddress -Value $null - $environment | add-member -type NoteProperty -Name ServicePort -Value $null - $environment | add-member -type NoteProperty -Name ReadPasswordToSignGeneratedLBOs -Value $false - - # backup locations - $environment | add-member -type NoteProperty -Name BackupLocation -Value $null - $environment | add-member -type NoteProperty -Name OnlineBackupLocation -Value $null - $environment | add-member -type NoteProperty -Name ODSBackupLocation -Value $null - $environment | add-member -type NoteProperty -Name DWHBackupLocation -Value $null - - #backup option - $environment | add-member -type NoteProperty -Name SQLBackupCompression -Value $null - - - # user / password for SQL Online - $environment | add-member -type NoteProperty -Name SQLOnlineWindowsAuthentication -Value $null - $environment | add-member -type NoteProperty -Name SQLOnlineUser -Value $null - $environment | add-member -type NoteProperty -Name SQLOnlinePassword -Value $null - - # user / password for SQL ODS - $environment | add-member -type NoteProperty -Name SQLODSWindowsAuthentication -Value $null - $environment | add-member -type NoteProperty -Name SQLODSUser -Value $null - $environment | add-member -type NoteProperty -Name SQLODSPassword -Value $null - - # user / password for SQL DWH - $environment | add-member -type NoteProperty -Name SQLDWHWindowsAuthentication -Value $null - $environment | add-member -type NoteProperty -Name SQLDWHUser -Value $null - $environment | add-member -type NoteProperty -Name SQLDWHPassword -Value $null - - #report server configuration - $environment | add-member -type NoteProperty -Name ReportServerUri -Value $null - $environment | add-member -type NoteProperty -Name ReportUseDefaultCredential -Value $null - $environment | add-member -type NoteProperty -Name ReportServerUser -Value $null - $environment | add-member -type NoteProperty -Name ReportServerPassword -Value $null - $environment | add-member -type NoteProperty -Name ReportsOnlineDataSource -Value $ReportsOnlineDataSource - $environment | add-member -type NoteProperty -Name ReportsODSDataSouce -Value $ReportsODSDataSouce - $environment | add-member -type NoteProperty -Name ReportsDWHDataSource -Value $ReportsDWHDataSource - $environment | add-member -type NoteProperty -Name ReportsASDataSource -Value $ReportsASDataSource - - #erp generation - $environment | add-member -type NoteProperty -Name GenerateErpCustomManagement -Value $true - - # TemporaryFileShare information - $environment | add-member -type NoteProperty -Name TemporaryFileShare -Value $null - - # user / password for HOST - $environment | add-member -type NoteProperty -Name AdminUser -Value $null - $environment | add-member -type NoteProperty -Name AdminPass -Value $null - - # tenant information - $environment | add-member -type NoteProperty -Name ClientTenantName -Value $null - - # UseSSL information - $environment | add-member -type NoteProperty -Name UseSSL -Value $null - - return $environment -} - -<# - .SYNOPSIS - Creates a new object to represent a server that's part of a cmNavigo installation. - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties for a server that's part of - a cmNavigo installation. Some of the properties on the returned object are only applicable to application servers. - - .PARAMETER ServerName - Machine name used to identify the server. - - .EXAMPLE - $appServer = New-CMFServer 'cmf-vm-test' - $appServer.BusinessInstallationPath = 'C:\'+$env.SystemName+'\Business Tier' - $appServer.GUIInstallationPath = 'C:\inetpub\wwwroot\' + $env.SystemName - $appServer.XAPUpdaterPath = 'C:\'+$env.SystemName+'\cmNavigo Tools\XapUpdater' - - .EXAMPLE - $env = New-CMFEnvironment 'Staging' - $env.ApplicationServers += New-CMFServer 'cmf-vm-test' - - # Installation Paths on App Servers - foreach($appServer in $env.ApplicationServers) - { - $appServer.BusinessInstallationPath = 'C:\'+$env.SystemName+'\Business Tier' - $appServer.GUIInstallationPath = 'C:\inetpub\wwwroot\' + $env.SystemName - $appServer.XAPUpdaterPath = 'C:\'+$env.SystemName+'\cmNavigo Tools\XapUpdater' - } - - .OUTPUTS - A custom object representing the cmNavigo server. The object contains the following properties: - - BusinessInstallationPath: Local path to the business tier installation folder - - GUIInstallationPath: Local path to the presentation tier installation folder (website) - - XAPUpdaterPath: Local path to the XAPUpdated tool, used to generate LBOs on the server -#> -function New-CMFServer() -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $ServerName, - [Parameter(Mandatory=$False)] - [string] $InstallationPath = $null - ) - - # Version dependent - $appServerBusinessInstallationPath = $InstallationPath + "\$CMFBusinessTier" - $appServerXAPUpdaterPath = $InstallationPath + "\$CMFLBOGeneratorWCF\XapUpdater" - $appServerGUIInstallationPath = $InstallationPath + "\$CMFPresentationTier" - $appServerHTMLPath = $InstallationPath + "\$CMFHTML" - $appServerHelpPath = $InstallationPath + "\$CMFHelp" - $appServerLBOGeneratorPath = $InstallationPath + "\$CMFLBOGenerator" - $appServerMasterDataLoaderPath = $InstallationPath + "\$CMFMasterDataLoader" - $appServerProtectUnprotectConfigFilePath = $InstallationPath + "\$CMFProtectUnprotectConfigFile" - - $server = new-object PSObject - - # Main Properties - $server | add-member -type NoteProperty -Name ServerName -Value $ServerName - $server | add-member -type NoteProperty -Name InstallationPath -Value $InstallationPath - - # Business and GUIs - $server | add-member -type NoteProperty -Name BusinessInstallationPath -Value $appServerBusinessInstallationPath - $server | add-member -type NoteProperty -Name GUIInstallationPath -Value $appServerGUIInstallationPath - $server | add-member -type NoteProperty -Name HTMLPath -Value $appServerHTMLPath - $server | add-member -type NoteProperty -Name HelpPath -Value $appServerHelpPath - - # Tools - $server | add-member -type NoteProperty -Name XAPUpdaterPath -Value $appServerXAPUpdaterPath - $server | add-member -type NoteProperty -Name LBOGeneratorPath -Value $appServerLBOGeneratorPath - $server | add-member -type NoteProperty -Name MasterDataLoaderPath -Value $appServerMasterDataLoaderPath - $server | add-member -type NoteProperty -Name ProtectUnprotectConfigFilePath -Value $appServerProtectUnprotectConfigFilePath - - return $server -} - -<# - .SYNOPSIS - Creates a new object to represent a cmNavigo custom service. - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties to load a custom service assembly to - cmNavigo. Should be used in conjunction with Install-CMFCustomServices function. - - .PARAMETER AssemblyName - Assembly file name to be loaded - - .PARAMETER ServiceName - Name of the service to be registered in cmNavigo - - .PARAMETER InterfaceName - Interface name to be loaded - - .EXAMPLE - New-CMFService -AssemblyName 'Cmf.Custom.Services.BackEnd.BackEndManagement.dll' -ServiceName 'BEBurnInResultsManagement' -InterfaceName 'IBEBurnInResultsManagement' - - .OUTPUTS - A custom object representing the cmNavigo service. The object contains the following properties: - - AssemblyName: Assembly file name to be loaded - - ServiceName: Name of the service to be registered in cmNavigo - - InterfaceName: Interface name to be loaded -#> -function New-CMFService() -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $AssemblyName, - - [Parameter(Mandatory=$True)] - [string] $ServiceName, - - [Parameter(Mandatory=$True)] - [string] $InterfaceName - ) - - $service = new-object PSObject - - $service | add-member -type NoteProperty -Name AssemblyName -Value $AssemblyName - $service | add-member -type NoteProperty -Name ServiceName -Value $ServiceName - $service | add-member -type NoteProperty -Name InterfaceName -Value $InterfaceName - - return $service -} - -<# - .SYNOPSIS - Prepares the current powershell session to call cmNavigo WCF services using LBOs - - .DESCRIPTION - Configures and loads the app.config file and Light Business Objects (LBOs) assembly to allow calling cmNavigo WCF services. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .EXAMPLE - Use-LightBusinessObjects $env - - .NOTES - The LBOs assembly loaded should be placed on the References folder, with the standard name - (Cmf.Proxy.LightBusinessObjects.Assembly.dll). - All service calls are synchronous. -#> -function Use-LightBusinessObjects() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env - ) - - $config_path = (Resolve-Path $ModulePath'\References\MasterData.Exe.config').Path - - sp $config_path IsReadOnly $false - - # Adjust endpoints - Add-Type -AssemblyName ('System.configuration, version=4.0.0.0, '+ 'Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')#System.Configuration - - [Configuration.ConfigurationManager].GetField("s_initState", "NonPublic, Static").SetValue($null, 0) - [Configuration.ConfigurationManager].GetField("s_configSystem", "NonPublic, Static").SetValue($null, $null) - ([Configuration.ConfigurationManager].Assembly.GetTypes() | where {$_.FullName -eq "System.Configuration.ClientConfigPaths"})[0].GetField("s_current", "NonPublic, Static").SetValue($null, $null) - - [System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $null) - [System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $config_path) - #endregion - - # Load LBOs assembly - $candidateAssembly = (Resolve-Path "$ModulePath\References\Cmf.LightBusinessObjects.dll") - - # Load your target version of the assembly - [System.Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\Cmf.LoadBalancing.dll")) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\Cmf.MessageBus.Client.dll")) | Out-Null - if ( Test-Path ("$ModulePath\References\System.Net.Http.dll") ) { - [System.Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\System.Net.Http.dll")) | Out-Null - } - - # Method to intercept resolution of binaries - $onAssemblyResolveEventHandler = [System.ResolveEventHandler] { - param($sender, $e) - - # Write-Host "ResolveEventHandler: Attempting FullName resolution of $($e.Name)" - foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies()) { - if ($assembly.FullName -eq $e.Name) { - # Write-Host "Successful FullName resolution of $($e.Name)" - return $assembly - } - } - - # Write-Host "ResolveEventHandler: Attempting name-only resolution of $($e.Name)" - foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies()) { - # Get just the name from the FullName (no version) - $assemblyName = $assembly.FullName.Substring(0, $assembly.FullName.IndexOf(", ")) - - if ($e.Name.StartsWith($($assemblyName + ","))) { - - # Write-Host "Successful name-only (no version) resolution of $assemblyName" - return $assembly - } - } - - # Write-Host "Unable to resolve $($e.Name)" - return $null - } - - # Wire-up event handler - [System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolveEventHandler) - - # Load into app domain - $assembly = [System.Reflection.Assembly]::LoadFrom($candidateAssembly) | Out-Null -} - -<# - .SYNOPSIS - Installs customization assemblies into the business tier directory of application servers. - - .DESCRIPTION - Copies customization assemblies to the business tier folder on one or all application servers. - All copied files will be overwritten if already existing. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER filesPath - Absolute Path to the items to copy. Should be a string ending in \* to copy all files in a given directory or - \*.dll to copy only assemblies. - - .PARAMETER applicationServer - If defined, files will only be copied to the specified application server. - - .EXAMPLE - Install-CMFBusinessAssemblies $env -filesPath .\Business\* - - .NOTES - Application hosts should be stopped for the copy to succeed. - Requires administrative privileges on the application servers. -#> -function Install-CMFBusinessAssemblies() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Path of the business assemblies to install - [Parameter(Mandatory=$True)] - [string]$filesPath, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - LogWrite (" > Starting installation of business assemblies...") - - $source = $filesPath - foreach($appServer in $serversToUse) - { - LogWrite (" Copying assemblies to " + $appServer.ServerName + " ...") - $target = '\\' + $appServer.ServerName + '\' + $appServer.BusinessInstallationPath -replace ':', '$' - - try - { - Copy-Item $source $target -recurse -force - } - catch [Exception] - { - # locked files? - $randomDir = [System.IO.Path]::GetRandomFileName(); - $currentDate = (Get-Date).AddDays(-1).ToString('yyyy-MM-dd') - $lockedPath = Join-Path -Path (Split-Path -parent $target) -ChildPath ("\Backups\Locked-$currentDate-$randomDir") - - LogWrite ("Error Copying "+ $_.Exception.Message) -ForeGroundColor Red - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host $_.Exception -ForegroundColor Red|format-list -force - } - - LogWrite "Creating locked folder $lockedPath" -ForeGroundColor Yellow - mkdir $lockedPath |out-null - gci -path $source -filter *.dll | ForEach-Object { - $fi = join-path $target $_.Name; - if (Test-Path $fi ){ - move -path $fi -destination $lockedPath - } - } - LogWrite "Trying to copy again... " -ForeGroundColor Yellow - Copy-Item $source $target -recurse -force - } - - } - - LogWrite (" * Completed installation of business assemblies!") -foregroundColor Green -} - -<# - .SYNOPSIS - - -<# - .SYNOPSIS - Copies files to a CMF Folder [on testings] - - .DESCRIPTION - Copies files to a CMF Folder on one or all application servers. - All copied files will be overwritten if already existing. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER folder - Destination folder inside the CMF environment. - - .PARAMETER filesPath - Absolute Path to the items to copy. Should be a string ending in \* to copy all files in a given directory or - \*.dll to copy only assemblies. - - .PARAMETER applicationServer - If defined, files will only be copied to the specified application server. - - .EXAMPLE - Publish-CMFFolder $env -folder BusinessTier -filesPath .\Business\* - - .NOTES - Application hosts should be stopped for the copy to succeed. - Requires administrative privileges on the application servers. -#> -function Publish-CMFFolder() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Folder - [Parameter(Mandatory=$True)] - [string] $folder, - - # Path of the business assemblies to install - [Parameter(Mandatory=$True)] - [string]$filesPath, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - LogWrite (" > Copying files to $folder...") - - $source = $filesPath - foreach($appServer in $serversToUse) - { - LogWrite (" Copying files to " + $appServer.ServerName + " ...") - $target = '\\' + $appServer.ServerName + '\' + ($appServer.InstallationPath -replace ':', '$') - $target = (Join-Path -Path $target -ChildPath ("\" + $folder)) - - try - { - Copy-Item $source $target -recurse -force - } - catch [Exception] - { - # locked fuiles? - $randomDir = [System.IO.Path]::GetRandomFileName(); - $currentDate = (Get-Date).AddDays(-1).ToString('yyyy-MM-dd') - $lockedPath = Join-Path -Path (Split-Path -parent $target) -ChildPath ("\Backups\Locked-$currentDate-$randomDir") - - LogWrite ("Error Copying "+ $_.Exception.Message) -ForeGroundColor Red - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host $_.Exception -ForegroundColor Red|format-list -force - } - - LogWrite "Creating locked folder $lockedPath" -ForeGroundColor Yellow - mkdir $lockedPath |out-nll - gci -path $source -filter *.dll | ForEach-Object { - $fi = join-path $target $_.Name; - if (Test-Path $fi ){ - move -path $fi -destination $lockedPath - } - } - LogWrite "Trying to copy again... " -ForeGroundColor Yellow - Copy-Item $source $target -recurse -force - } - - } - - LogWrite (" * Completed copying files to $folder!") -foregroundColor Green -} - -<# - .SYNOPSIS - Installs customization assemblies and addins into the presentation tier directory of application servers. - - .DESCRIPTION - Copies customization assemblies and addin files to the presentation tier folder on one or all application servers. - All copied files will be overwritten if already existing. - All files are copied to the ClientBin subfolder. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER filesPath - Absolute Path to the items to copy. Should be a string ending in \* to copy all files in a given directory or - \*.dll to copy only assemblies. - - .PARAMETER applicationServer - If defined, files will only be copied to the specified application server. - - .PARAMETER copyToWebRoot - If defined, copy to web root folder (GUIInstallationPath) instead of ClientBin - - .EXAMPLE - Install-CMFPresentationAssemblies $env -filesPath .\Presentation\* - - .NOTES - Requires administrative privileges on the application servers. -#> -function Install-CMFPresentationAssemblies() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Path of the presentation assemblies to install - [Parameter(Mandatory=$True)] - [string]$filesPath, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer, - - # switch to copy to webroot - [Parameter(Mandatory=$False)] - [switch] $copyToWebRoot - - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - LogWrite (" > Starting installation of presentation assemblies...") - - $source = $filesPath - foreach($appServer in $serversToUse) - { - LogWrite (" Copying assemblies to " + $appServer.ServerName + " ...") - - if( $copyToWebRoot) - { - $target = '\\' + $appServer.ServerName + '\' + $appServer.GUIInstallationPath -replace ':', '$' - } - else - { - $target = '\\' + $appServer.ServerName + '\' + $appServer.GUIInstallationPath + '\ClientBin' -replace ':', '$' - } - - Copy-Item $source $target -recurse -force - } - LogWrite ' * Completed installation of presentation assemblies!' -foregroundColor Green -} - -<# - .SYNOPSIS - Register new addin extensions on the ApplicationRoster.xml file - - .DESCRIPTION - Register a specified addin on the ApplicationRoster.xml file on one or all application servers. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER addinsToRegister - Array containing the names of all addins to be registered. - - .PARAMETER applicationServer - If defined, addins will only be registered on the specified application server. - - .EXAMPLE - Register-CMFAddins $env -addinsToRegister @('MyCustomGUIS') - - .NOTES - If the addins are already registered, they won't be added again. - Requires administrative privileges on the application servers. -#> -function Register-CMFAddins() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # List of addins to register - [Parameter(Mandatory=$True)] - [string[]]$addinsToRegister, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer - - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - $password = Get-SecureStringFromEncryptedString $env.AdminPass - $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env.AdminUser, $password - - LogWrite(' > Registering addins in application servers...') - # Prepare script to run on each app server - $sc = - { - param($appServer, $addinsToRegister) - - # get xml content - $applicationRosterPath = $appServer.GUIInstallationPath + '\ApplicationRoster.xml' - [xml] $appRosterXml = Get-Content $applicationRosterPath - - # register each addin - foreach($addin in $addinsToRegister) - { - $node = $appRosterXml.App.Addins.Addin | where {$_.name -eq $addin} - if ($node -eq $null) - { - # node does not exist, we need to add it - $node = $appRosterXml.App.Addins.Addin[0].Clone() - $node.name = $addin - $node.source = $addin + '.addin' - $node = $appRosterXml.App.Addins.AppendChild($node) - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host ' Registering addin' + $addin + 'on app server ' + $appserver.ServerName + '...' - } - } - else - { - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host ' Addin was already registered on app server ' + $appserver.ServerName -foregroundColor Yellow - } - } - } - - $appRosterXml.Save($applicationRosterPath) - } - - # Execute script on each app server - foreach($appServer in $serversToUse) - { - Invoke-Command -ComputerName $appServer.ServerName -ScriptBlock $sc -ArgumentList $appServer,$addinsToRegister -Credential $cred - LogWrite (" Addins inserted/updated in server " + $appserver.ServerName) - } - LogWrite ' * Addins registered!' -foregroundColor Green -} - -<# - .SYNOPSIS - Stop cmNavigo application hosts. - - .DESCRIPTION - Stops cmNavigo application hosts on one or all application servers and manages their inclusion on the NLB cluster - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER applicationServer - If defined, addins will only be registered on the specified application server. - - .PARAMETER disableNLBManagement - If set, hosts will not be removed from the NLB cluster. To be used when third-party NLB solutions are in use. - - .EXAMPLE - Stop-NavigoHosts $env - - .EXAMPLE - Stop-NavigoHosts $env -applicationServer $env.ApplicationServers[0] -disableNLBManagement - - .NOTES - Host will only be removed from the NLB cluster if there is more than one application server registered on the $env object - passed as argument. Connections to the host are drained for a maximum of 2 minutes before the host is stopped and removed - from the NLB cluster (drainstop). - Requires administrative privileges on the application servers. -#> -function Stop-NavigoHosts() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer, - - # Disable manage NLBs - [Parameter(Mandatory=$False)] - [switch]$disableNLBManagement - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - $password = Get-SecureStringFromEncryptedString $env.AdminPass - $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env.AdminUser, $password - - LogWrite ' > Stopping application hosts...' - foreach($appServer in $serversToUse) - { - if (-not ($disableNLBManagement)) - { - # before stopping, remove host from NLB, if NLB is in use - if ($env.ApplicationServers.Length -gt 1) - { - LogWrite (" Removing host " + $appServer.ServerName + " from NLB...") - Invoke-Command -ComputerName $appServer.ServerName -Credential $cred -ScriptBlock { Stop-NlbClusterNode -Drain -Timeout 2 } - } - } - - # stop service - # Create a new session remotely to wait for process - $sess = New-PSSession -ComputerName $appServer.ServerName -Credential $cred - Enter-PSSession -Session $sess - - try - { - # request stop service - $service = Get-Service -computername $appServer.ServerName -Name $env.NavigoServiceName - if ($service.Status -eq 'Stopped') - { - LogWrite (" Service was already stopped on " + $appServer.ServerName) -foregroundColor Yellow - } - else - { - LogWrite (" Stopping MES host on " + $appServer.ServerName + "...") - - $service.Stop() - - $service.WaitForStatus('Stopped','00:01:00') - - if ($service.Status -ne 'Stopped') - { - throw 'Service termination timed out!' - } - } - - $processId = gwmi Win32_Service -Filter ("Name LIKE '" + $env.NavigoServiceName + "'") | select -expand ProcessId - - if ($processId -and $processId -ne "0") - { - # Wait 10 seconds to process die, if not process continue but notification is done - $retries = 11 - - $activityDescription = "Killing process" - Write-Progress -Activity ($activityDescription) -Status "Please wait..." - $processKilled = $False - for($i=1; $i -le $retries ; $i++) - { - $processActive = Get-Process -Id $processId -ErrorAction SilentlyContinue - if($processActive -eq $null) - { - $processKilled = $True - break - } - else - { - kill $processId -Force - } - - SLEEP 1 - Write-Progress -Activity ($activityDescription) -CurrentOperation ("Tentative n " + $i ) -Status ("Please wait...") - } - - if($processKilled -eq $True) - { - Write-Progress -Activity $activityDescription -Completed -Status "Process was killed with success." - } - else - { - Write-Progress -Activity $activityDescription -Completed -Status "Killing process failed." - LogWrite (" Killing process failed") -ForeGroundColor Yellow - } - } - else - { - #hack sometimes process id is not found in the process. - #because of that we force a sleep. - - $totalTimeToWait = 5 - LogWrite (" No process id found. Wait " + $totalTimeToWait.ToString() + " seconds to process end") - - $processStopDescription = "Wait " + $totalTimeToWait.ToString() + " seconds to process stop" - Write-Progress -Activity ($processStopDescription) -Status "Please wait..." - for($i=0; $i -le $totalTimeToWait ; $i++) - { - SLEEP 1 - Write-Progress -Activity ($processStopDescription) -CurrentOperation (($i + 1).ToString() + " of " + $totalTimeToWait.ToString()) -Status ("Please wait...") - } - - Write-Progress -Activity $processStopDescription -Completed -Status "Sleep time for Process stop ended." - LogWrite (" End of wait till the process end") - - } - } - finally - { - Remove-PSSession -Session $sess - Exit-PSSession - } - } - LogWrite ' * Application services stopped!' -foregroundColor Green -} - -<# - .SYNOPSIS - Start cmNavigo application hosts. - - .DESCRIPTION - Starts cmNavigo application hosts on one or all application servers and manages their inclusion on the NLB cluster - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER applicationServer - If defined, addins will only be registered on the specified application server. - - .PARAMETER disableNLBManagement - If set, hosts will not be added to the NLB cluster. To be used when third-party NLB solutions are in use. - - .EXAMPLE - Start-NavigoHosts $env - - .EXAMPLE - Start-NavigoHosts $env -applicationServer $env.ApplicationServers[0] -disableNLBManagement - - .NOTES - Host will only be added to the NLB cluster if there is more than one application server registered on the $env object - passed as argument. - Requires administrative privileges on the application servers. -#> -function Start-NavigoHosts() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer, - - # Disable manage NLBs - [Parameter(Mandatory=$False)] - [switch]$disableNLBManagement - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - LogWrite ' > Starting application hosts...' - foreach($appServer in $env.ApplicationServers) - { - $service = Get-Service -computername $appServer.ServerName -Name $env.NavigoServiceName - if ($service.Status -eq 'Running') - { - LogWrite (" Service is already started on " + $appServer.ServerName) -foregroundColor Yellow - } - else - { - LogWrite (" Starting MES host on " + $appServer.ServerName + " ...") - $service.Start() - $service.WaitForStatus('Running', '00:02:00') - } - - if (-not ($disableNLBManagement)) - { - # after starting, start host in NLB, if NLB is in use - if ($env.ApplicationServers.Length -gt 1) - { - Invoke-Command -ComputerName $appServer.ServerName -ScriptBlock { Start-NlbClusterNode } - } - } - } - LogWrite ' * Application services started!' -foregroundColor Green -} - - -<# - .SYNOPSIS - Stop a specific service on all application services. - - .DESCRIPTION - Stops any service on one or all application servers - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER applicationServer - If defined, addins will only be registered on the specified application server. - - .PARAMETER serviceName - Service name to be stopped - - .EXAMPLE - Stop-SpecificService $env -serviceName $env.NavigoRemoteImportExportGatewayServiceName - - .EXAMPLE - Stop-SpecificService $env -applicationServer $env.ApplicationServers[0] -serviceName $env.NavigoRemoteImportExportGatewayServiceName - - .NOTES - Requires administrative privileges on the application servers. -#> -function Stop-SpecificService() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer, - - #Service Name - [Parameter(Mandatory=$True)] - [string]$serviceName - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - - LogWrite " > Stopping service $serviceName..." - foreach($appServer in $serversToUse) - { - # stop service - # Create a new session remotely to wait for process - $password = Get-SecureStringFromEncryptedString $env.AdminPass - $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env.AdminUser, $password - - $sess = New-PSSession -ComputerName $appServer.ServerName -Credential $cred - Enter-PSSession -Session $sess - - try - { - # request stop service - $service = Get-Service -computername $appServer.ServerName -Name $serviceName - if ($service) - { - if ($service.Status -eq 'Stopped') - { - LogWrite (" Service was already stopped on " + $appServer.ServerName) -foregroundColor Yellow - } - else - { - LogWrite (" Stopping service on " + $appServer.ServerName + "...") - - $service.Stop() - - $service.WaitForStatus('Stopped','00:01:00') - - if ($service.Status -ne 'Stopped') - { - throw 'Service termination timed out!' - } - } - } - - $processId = gwmi Win32_Service -Filter ("Name LIKE '" + $service + "'") | select -expand ProcessId - - if ($processId -and $processId -ne "0") - { - # Wait 10 seconds to process die, if not process continue but notification is done - $retries = 11 - - $activityDescription = "Killing process" - Write-Progress -Activity ($activityDescription) -Status "Please wait..." - $processKilled = $False - for($i=1; $i -le $retries ; $i++) - { - $processActive = Get-Process -Id $processId -ErrorAction SilentlyContinue - if($processActive -eq $null) - { - $processKilled = $True - break - } - else - { - kill $processId -Force - } - - SLEEP 1 - Write-Progress -Activity ($activityDescription) -CurrentOperation ("Tentative n� " + $i ) -Status ("Please wait...") - } - - if($processKilled -eq $True) - { - Write-Progress -Activity $activityDescription -Completed -Status "Process was killed with success." - } - else - { - Write-Progress -Activity $activityDescription -Completed -Status "Killing process failed." - LogWrite (" Killing process failed") -ForeGroundColor Yellow - } - } - else - { - #hack sometimes process id is not found in the process. - #because of that we force a sleep. - - $totalTimeToWait = 5 - LogWrite (" No process id found. Wait " + $totalTimeToWait.ToString() + " seconds to process end") - - $processStopDescription = "Wait " + $totalTimeToWait.ToString() + " seconds to process stop" - Write-Progress -Activity ($processStopDescription) -Status "Please wait..." - for($i=0; $i -le $totalTimeToWait ; $i++) - { - SLEEP 1 - Write-Progress -Activity ($processStopDescription) -CurrentOperation (($i + 1).ToString() + " of " + $totalTimeToWait.ToString()) -Status ("Please wait...") - } - - Write-Progress -Activity $processStopDescription -Completed -Status "Sleep time for Process stop ended." - LogWrite (" End of wait till the process end") - - } - } - finally - { - Remove-PSSession -Session $sess - Exit-PSSession - } - } - LogWrite " * Service $serviceName stopped!" -foregroundColor Green -} - -<# - .SYNOPSIS - Start a specific service on all application services. - - .DESCRIPTION - Starts any service on one or all application servers - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER applicationServer - If defined, addins will only be registered on the specified application server. - - .PARAMETER serviceName - Service name to be started - - .EXAMPLE - Start-SpecificService $env -serviceName $env.NavigoRemoteImportExportGatewayServiceName - - .EXAMPLE - Start-SpecificService $env -applicationServer $env.ApplicationServers[0] -serviceName $env.NavigoRemoteImportExportGatewayServiceName - - .NOTES - Requires administrative privileges on the application servers. -#> -function Start-SpecificService() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer, - - #Service Name - [Parameter(Mandatory=$True)] - [string]$serviceName - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - LogWrite " > Starting service $serviceName..." - foreach($appServer in $env.ApplicationServers) - { - $service = Get-Service -computername $appServer.ServerName -Name $serviceName - if ($service) - { - if ($service.Status -eq 'Running') - { - LogWrite (" Service is already started on " + $appServer.ServerName) -foregroundColor Yellow - } - else - { - LogWrite (" Starting service on " + $appServer.ServerName + " ...") - $service.Start() - $service.WaitForStatus('Running', '00:02:00') - } - } - } - LogWrite " * Service $serviceName started!" -foregroundColor Green -} - -<# - .SYNOPSIS - Installs cmNavigo custom services - - .DESCRIPTION - Install one or more cmNavigo custom services. If already existing, the services are removed and re-added. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER services - Array containing the services to be added. Each service should be a custom object created with the New-CMFService - function. - Each individual interface must be registered as a different service. - - .PARAMETER assembliesPath - Absolute path to the directory containing the specified service assemblies. - - .EXAMPLE - Invoke-SQLScript $env -database 'Online' -scriptPath '.\Analytics\Release 015.1.sql' -username 'CMFUser' -password 'CMFUser' - - .NOTES - Assumes SQL Script file is saved with UTF8 encoding. - GO batch separators are supported, assuming they are placed in separate lines. -#> -function Install-CMFCustomServices() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Services to Install - [Parameter(Mandatory=$True)] - [Object[]]$services, - - [Parameter(Mandatory=$True)] - [string] $assembliesPath - ) - - LogWrite " > Starting deploy of custom services to database..." - - Use-LightBusinessObjects $env - - #region Try to remove the service if it already exists - try - { - [Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.GetAllServicesInput] $getServiceInput = New-Object Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.GetAllServicesInput - $getServiceInput.Filter = New-Object Cmf.Foundation.BusinessObjects.QueryObject.FilterCollection - [Cmf.Foundation.BusinessObjects.ServiceIntegrator.ServiceContractCollection] $existingServices = $getServiceInput.GetAllServicesSync().Services - #Write-Host $existingServices.Count - foreach($service in $services) - { - $existingService = $existingServices | Where-Object { $service.ServiceName -eq $_.Name }# | Select -First 1 - if($existingService) - { - LogWrite (" Service " + $service.InterfaceName + " already exists and will be removed...") -foregroundColor Yellow - - [Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.RemoveServiceInput] $removeServiceInput = New-Object Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.RemoveServiceInput - $removeServiceInput.Service = $existingService - $removeServiceInput.RemoveServiceSync() | Out-Null - - } - - - } - } - catch [Exception] - { - LogWrite $_.Exception.Message - } - #endregion - - foreach($service in $services) - { - #region Read assembly and compute checksum - LogWrite (" Adding service " + $service.InterfaceName + " ...") - - $sha = New-Object System.Security.Cryptography.SHA256CryptoServiceProvider - $assemblyPath = Join-Path $assembliesPath $service.AssemblyName - [byte[]] $assemblyBytes = [System.IO.File]::ReadAllBytes($assemblyPath) - [byte[]] $checksum = $sha.ComputeHash($assemblyBytes) - - [Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.GetExportedTypesForAssemblyInput] $getTypesInput = New-Object Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.GetExportedTypesForAssemblyInput - $getTypesInput.Assembly = New-Object Cmf.Foundation.BusinessObjects.ServiceIntegrator.ServiceAssembly - $getTypesInput.Assembly.Assembly = $assemblyBytes - $fullAssemblyName = $getTypesInput.GetExportedTypesForAssemblySync().FullAssemblyName - #endregion - - #region Prepare Service Contract - [Cmf.Foundation.BusinessObjects.ServiceIntegrator.ServiceContract] $serviceContract = New-Object Cmf.Foundation.BusinessObjects.ServiceIntegrator.ServiceContract - $serviceContract.Name = $service.ServiceName - $serviceContract.IsSystem = $false - $serviceContract.Active = $true - $serviceContract.Description = $service.ServiceName - $serviceContract.ServiceInterface = $service.InterfaceName - $serviceContract.ServiceAssembly = New-Object Cmf.Foundation.BusinessObjects.ServiceIntegrator.ServiceAssembly - $serviceContract.ServiceAssembly.IsSystem = $false - $serviceContract.ServiceAssembly.Name = $fullAssemblyName - $serviceContract.ServiceAssembly.Assembly = $assemblyBytes - $serviceContract.ServiceAssembly.Checksum = $checksum - #endregion - - # Call Service - [Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.CreateServiceInput] $createServiceInput = New-Object Cmf.Foundation.BusinessOrchestration.WCFServiceManagement.InputObjects.CreateServiceInput - $createServiceInput.Service = $serviceContract - $return = $createServiceInput.CreateServiceSync() - } - - LogWrite " * Finished deploy of custom services to database!" -foregroundColor Green -} - -<# - .SYNOPSIS - Generates LBOs - - .DESCRIPTION - Generate LBOs and update XAP files on one or all application servers. Assumes LBO generator is correctly configured on - each application server. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER applicationServer - If defined, LBOs will be generated only in the specified application server. - - .EXAMPLE - Update-LightBusinessObjects $env - - .NOTES - Requires admininstrative permissions on the application servers. -#> -function Update-LightBusinessObjects() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$isToGenerateWCF = $false - - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - LogWrite ' > Generating LBOs in application servers...' - - - $certPassword = $null - - $password = Get-SecureStringFromEncryptedString $env.AdminPass - $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env.AdminUser, $password - - if( $env.ReadPasswordToSignGeneratedLBOs -eq $true ) - { - $secureCertPassword = Read-Host "Enter certificate password:" -AsSecureString - $psCred = New-Object System.Management.Automation.PSCredential ("dummyUser", $secureCertPassword) - $certPassword = $psCred.GetNetworkCredential().Password; - } - - - # Prepare script to runon each app server - $sc = - { - param($XAPUpdaterPath, $certPassword) - - if( -not($certPassword -eq $null)) - { - $tmpFile = [System.IO.Path]::GetTempFileName()+'.cmd' - - try - { - Set-Content $tmpFile "echo $certPassword | ""$XAPUpdaterPath\GenerateLBOsAndUpdateXapFile.bat""" - - Start-Process $tmpFile -Wait -WorkingDirectory $XAPUpdaterPath | Out-Host - } - finally - { - if( Test-Path $tmpFile ){ - Set-Content $tmpFile ' ' # clear the contents - Remove-Item $tmpFile - } - } - } - else - { - Set-Location -Path $XAPUpdaterPath - .\GenerateLBOsAndUpdateXapFile.bat - } - } - # Prepare script to runon each app server - $puhfc = - { - param($protectUnprotectConfigFilePath, $mode, $businessInstallationPath) - - $arguments = "/Mode:$mode /InstallPath:""$businessInstallationPath""" - - Write-Host "Deal with host config file" - Set-Location -Path $protectUnprotectConfigFilePath - Start-Process Cmf.Tools.ProtectUnprotectConfigFile.exe $arguments -Wait - } - - # Prepare script to runon each app server - $restlboc = - { - param($lboGeneratorPath) - - Set-Location -Path $lboGeneratorPath - .\LBOUpdater.ps1 - } - - # Execute batch script on each app server - foreach($appServer in $serversToUse) - { - LogWrite( ' Starting LBO Generation on '+ $appserver.ServerName +' ...') - - if($isToGenerateWCF) - { - #WCF LBOs - Invoke-Command -ScriptBlock $sc -ArgumentList @($appServer.XAPUpdaterPath, $certPassword) -ComputerName $appServer.ServerName -Credential $cred - } - - #Unprotect HostConfigFile - Invoke-Command -ScriptBlock $puhfc -ArgumentList @($appServer.ProtectUnprotectConfigFilePath, 2, $appServer.BusinessInstallationPath) -ComputerName $appServer.ServerName -Credential $cred - - #REST LBOs - Invoke-Command -ScriptBlock $restlboc -ArgumentList @($appServer.LBOGeneratorPath) -ComputerName $appServer.ServerName -Credential $cred - - #Protect HostConfigFile - Invoke-Command -ScriptBlock $puhfc -ArgumentList @($appServer.ProtectUnprotectConfigFilePath, 1, $appServer.BusinessInstallationPath) -ComputerName $appServer.ServerName -Credential $cred - - LogWrite (' Finished LBO Generation on ' +$appserver.ServerName +' ...') - } - - LogWrite ' * LBOs generated!' -foregroundColor Green -} - -<# - .SYNOPSIS - Gets the Available Types of a given Master Data file - - .DESCRIPTION - Uses the master data loader application logic to get the available types of the master data file. - This function uses the same logic as the standard Master Data Loader in Navigo. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER excelFile - Absolute to the Excel file to be loaded. - - .PARAMETER TypesToExclude - String array containing the types to be excluded. - If TypesToLoad is defined, this parameter is ignored. - - .EXAMPLE - Get-MasterDataAvailableTypes $env -excelFile 'C:\MasterData.xlsx' - - .EXAMPLE - Get-MasterDataAvailableTypes $env -excelFile 'C:\MasterData.xlsx' -typesToExclude @('Document') - - .NOTES - Master data logic uses LBOs to load data into cmNavigo. The LBOs assenmbly used is located on the References folder. -#> -function Get-MasterDataAvailableTypes() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - #Excel file - [Parameter(Mandatory=$True)] - [string] $excelFile, - - #Exclude Types - [Parameter(Mandatory=$False)] - [string[]] $TypesToExclude - ) - - Use-LightBusinessObjects $env - - # Prepare config arguments - # Load master data logic assembly - [Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\MasterData.Logic.dll")) | Out-Null - - $configArguments = [MasterData.Logic.ConfigArguments]::Singleton - $configArguments.UploadedFile = $excelFile - - # Get available types - [MasterData.Logic.Runner]::GetAvailableTypes() - - # Prepare types to load - $TypesToLoad = @() - foreach($typeToLoad in $configArguments.AvailableTypes) - { - if (-not ($TypesToExclude -ne $null -and $TypesToExclude.Contains($typeToLoad.UserObjectType))) - { - $TypesToLoad += $typeToLoad.UserObjectType - } - } - - return $TypesToLoad -} - -<# - .SYNOPSIS - Load Master Data file - - .DESCRIPTION - Uses the master data loader application logic to load a master data file into cmNavigo. - This function uses the same logic as the standard Master Data Loader in Navigo. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER excelFile - Absolute to the Excel file to be loaded. - - .PARAMETER typesToLoad - String array containing the types to be loaded. - If not defined, all types on the excel file will be loaded. - - .PARAMETER deeBasePath - Absolute path to the folder containing the code files for DEE rules to be imported. - Required if DEE rules are to be imported. - - .PARAMETER documentsBasePath - Absolute path to the folder containint the documents to be uploaded. - Required if Documents are to be imported. - - .PARAMETER createInCollection - Set this flag if objects are to be loaded in collection. If not set, objects are loaded individually. - - .PARAMETER TypesToExclude - String array containing the types to be excluded. - If TypesToLoad is defined, this parameter is ignored. - - .EXAMPLE - Invoke-MasterDataLoader $env -excelFile 'C:\MasterData.xlsx' - - .EXAMPLE - Invoke-MasterDataLoader $env -excelFile 'C:\MasterData.xlsx' -typesToLoad @('Parameter', 'DataCollection') - - .EXAMPLE - Invoke-MasterDataLoader $env -excelFile 'C:\MasterData.xlsx' -typesToLoad @('DEEAction') -deeBasePath 'C:\DEE' - - .EXAMPLE - Invoke-MasterDataLoader $env -excelFile 'C:\MasterData.xlsx' -typesToLoad @('Document') -documentsBasePath 'C:\Documents' - - .EXAMPLE - Invoke-MasterDataLoader $env -excelFile 'C:\MasterData.xlsx' -deeBasePath 'C:\DEE' -createInCollection - - .NOTES - Master data logic uses LBOs to load data into cmNavigo. The LBOs assenmbly used is located on the References folder. - Master data loading errors are shown on the console but not actually treated as execution errors or exceptions, - since they are a common occurrence in deployment procedures. -#> -function Invoke-MasterDataLoader() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - #Excel file - [Parameter(Mandatory=$True)] - [string] $excelFile, - - #Types to load - [Parameter(Mandatory=$False)] - [string[]] $TypesToLoad, - - #Dee base path - [Parameter(Mandatory=$False)] - [string] $deeBasePath, - - #Document base path - [Parameter(Mandatory=$False)] - [string] $documentsBasePath, - - #Mapping Files base path - [Parameter(Mandatory=$False)] - [string] $mappingFilesBasePath, - - #Automation Workflow Files base path - [Parameter(Mandatory=$False)] - [string] $automationWorkflowFilesBasePath, - - #Checklist Image base path - [Parameter(Mandatory=$False)] - [string] $checklistImageBasePath, - - #ImportObjects base path - [Parameter(Mandatory=$False)] - [string] $importObjectBasePath, - - #create in collection - [Parameter(Mandatory=$False)] - [switch] $createInCollection, - - #Exclude Types - [Parameter(Mandatory=$False)] - [string[]] $TypesToExclude - ) - - LogWrite " > Starting master data installation..." - LogWrite " $excelFile" - - Use-LightBusinessObjects $env - - # Prepare config arguments - # Load master data logic assembly - [Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\MasterData.Logic.dll")) | Out-Null - - $configArguments = [MasterData.Logic.ConfigArguments]::Singleton - $configArguments.UploadedFile = $excelFile - $configArguments.CreateInCollection = $createInCollection - if ($deeBasePath) { $configArguments.DeeActionBasePath = (Resolve-Path $deeBasePath).Path } - if ($documentsBasePath) { $configArguments.DocumentFilesBasePath = (Resolve-Path $documentsBasePath).Path } - if ($automationWorkflowFilesBasePath) { $configArguments.AutomationWorkflowFilesBasePath = (Resolve-Path $automationWorkflowFilesBasePath).Path } - if ($mappingFilesBasePath) { $configArguments.MappingFilesBasePath = (Resolve-Path $mappingFilesBasePath).Path } - if ($checklistImageBasePath) { $configArguments.ChecklistImagePath = (Resolve-Path $checklistImageBasePath).Path } - if ($importObjectBasePath) { $configArguments.ImportObjectBasePath = (Resolve-Path $importObjectBasePath).Path } - - # Get available types - [MasterData.Logic.Runner]::GetAvailableTypes() - # Prepare types to load - if($TypesToLoad -eq $null) - { - $TypesToLoad = @() - foreach($typeToLoad in $configArguments.AvailableTypes) - { - if (-not ($TypesToExclude -ne $null -and $TypesToExclude.Contains($typeToLoad.UserObjectType))) - { - $TypesToLoad += $typeToLoad.UserObjectType - } - } - } - - if ( $TypesToLoad.length -gt 0 ) { - LogWrite " Loading types: " - foreach($type in $TypesToLoad) - { - LogWrite (" - " + $type) - } - $TypesToLoad = $TypesToLoad | % { $_.ToLower() } - $configArguments.ObjectsToLoad = $TypesToLoad - - $global:hasErrors = 0 - - # register for logger events - $logger = [MasterData.Logic.Logger] - $eventJob = Register-ObjectEvent -InputObject $logger -EventName OnLog -Action { - if($event.SourceArgs[0].LogType -eq [MasterData.Logic.LogType]::Error) - { - LogWrite (" " + $event.SourceArgs[0].LogMessage) -ForegroundColor Red - - $global:hasErrors = 1 - - if($global:InteractiveMode -eq $false -and $setPartiallySucceeded ) - { - # Assuming this is running as part of a TFS build, set the build task to partially succeeded - Write-Host "##vso[task.complete result=SucceededWithIssues;] There was at least one error during master data loading. Please check the master data log for details." - } - } - else - { - LogWrite (" "+$event.SourceArgs[0].LogMessage) - } - } - - # Run master data - try - { - $activityDescription = "Uploading master data to MES..." - Write-Progress -Activity ($activityDescription) -Status "Please wait..." - [MasterData.Logic.Runner]::Run([MasterData.Logic.Runner+RunnerMode]::Upload) - Write-Progress -Activity $activityDescription -Completed -Status "Master data has finished." - } - finally - { - [System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $null) - Unregister-Event -SourceIdentifier $eventJob.Name - } - - LogWrite " * Finished running master data ($excelFile)!" -foregroundColor Green - } - else { - LogWrite " * No types to load on master data ($excelFile)!" -foregroundColor Green - } - - return $global:hasErrors -} - -<# - .SYNOPSIS - Load Master Data files by folder - - .DESCRIPTION - Uses the master data loader application logic to load master data files within a folder into cmNavigo. - This function uses the same logic as the standard Master Data Loader in Navigo. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER excelFolder - Absolute to the Excel file to be loaded. - - .PARAMETER typesToLoad - String array containing the types to be loaded. - If not defined, all types on the excel file will be loaded. - - .PARAMETER deeBasePath - Absolute path to the folder containing the code files for DEE rules to be imported. - Required if DEE rules are to be imported. - - .PARAMETER documentsBasePath - Absolute path to the folder containint the documents to be uploaded. - Required if Documents are to be imported. - - .PARAMETER createInCollection - Set this flag if objects are to be loaded in collection. If not set, objects are loaded individually. - - .PARAMETER TypesToExclude - String array containing the types to be excluded. - If TypesToLoad is defined, this parameter is ignored. - - .PARAMETER stopOnError - Stop loading if it finds error in loading onne master data - - .EXAMPLE - Invoke-MasterDataLoaderByFolder $env -excelFolder 'C:\MasterData' - - .EXAMPLE - Invoke-MasterDataLoaderByFolder $env -excelFolder 'C:\MasterData' -typesToLoad @('Parameter', 'DataCollection') - - .EXAMPLE - Invoke-MasterDataLoaderByFolder $env -excelFolder 'C:\MasterData' -typesToLoad @('DEEAction') -deeBasePath 'C:\DEE' - - .EXAMPLE - Invoke-MasterDataLoaderByFolder $env -excelFolder 'C:\MasterData' -typesToLoad @('Document') -documentsBasePath 'C:\Documents' - - .EXAMPLE - Invoke-MasterDataLoaderByFolder $env -excelFolder 'C:\MasterData' -deeBasePath 'C:\DEE' -createInCollection - - .NOTES - Master data logic uses LBOs to load data into cmNavigo. The LBOs assenmbly used is located on the References folder. - Master data loading errors are shown on the console but not actually treated as execution errors or exceptions, - since they are a common occurrence in deployment procedures. -#> -function Invoke-MasterDataLoaderByFolder() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - #Excel file - [Parameter(Mandatory=$True)] - [string] $excelFolder, - - #Types to load - [Parameter(Mandatory=$False)] - [string[]] $TypesToLoad, - - #Dee base path - [Parameter(Mandatory=$False)] - [string] $deeBasePath, - - #Document base path - [Parameter(Mandatory=$False)] - [string] $documentsBasePath, - - #Mapping Files base path - [Parameter(Mandatory=$False)] - [string] $mappingFilesBasePath, - - #Automation Workflow Files base path - [Parameter(Mandatory=$False)] - [string] $automationWorkflowFilesBasePath, - - #Checklist Image base path - [Parameter(Mandatory=$False)] - [string] $checklistImageBasePath, - - #ImportObjects base path - [Parameter(Mandatory=$False)] - [string] $importObjectBasePath, - - #create in collection - [Parameter(Mandatory=$False)] - [switch] $createInCollection, - - #Exclude Types - [Parameter(Mandatory=$False)] - [string[]] $TypesToExclude, - - #Stop on Error - [Parameter(Mandatory=$False)] - [bool] $stopOnError - ) - - Use-LightBusinessObjects $env - # Prepare config arguments - - if (Test-Path $excelFolder) - { - $excelFolder = "$(Resolve-Path $excelFolder)" - # Master Data Files in folder - $excelFiles = Get-ChildItem ($excelFolder) -File -Include '*.xlsx','*.xml','*.json' -recurse | Where {$_.FullName -notlike "*\AutomationWorkflowFiles\*"} | Sort-Object Name - LogWrite (" * Loading $($excelFiles.Count) MasterData files from folder ($excelFolder)...") - $OriginalTypesToLoad = $TypesToLoad - $OriginalTypesToExclude = $TypesToExclude - - foreach ($file in $excelFiles ) - { - # Get available types - # Prepare types to load - if ( $TypesToLoad -eq $null ) - { - $TypesToLoad = Get-MasterDataAvailableTypes $env $file $TypesToExclude - } - - if (!($TypesToExclude -contains 'LookupTableValues') -and - (!$TypesToLoad -or ($TypesToLoad -contains 'LookupTableValues'))) - { - for ($i=0; $i -lt 10; $i++) { - $hasErrors = Invoke-MasterDataLoader $env ` - -excelFile $file ` - -typesToLoad @('LookupTableValues') - if(! $hasErrors) - { - break - } - } - } - - if (!($TypesToExclude -contains 'EntityTypeProperty') -and - (!$TypesToLoad -or ($TypesToLoad -contains 'EntityTypeProperty'))) - { - for ($i=0; $i -lt 10; $i++) { - $hasErrors = Invoke-MasterDataLoader $env ` - -excelFile $file ` - -typesToLoad @('EntityTypeProperty') - if(! $hasErrors) - { - break - } - } - } - - if (!($TypesToExclude -contains 'Config') -and - (!$TypesToLoad -or ($TypesToLoad -contains 'Config'))) - { - for ($i=0; $i -lt 10; $i++) { - $hasErrors = Invoke-MasterDataLoader $env ` - -excelFile $file ` - -typesToLoad @('Config') - if(! $hasErrors) - { - break - } - } - } - - $TypesToExclude += 'Config' - $TypesToExclude += 'EntityTypeProperty' - $TypesToExclude += 'LookupTableValues' - - # Identify the Actual Types to be loaded (TypesToLoad - TypesToExclude) - $ActualTypesToLoad = @() - foreach ( $typeToLoad in $TypesToLoad ) { - if (-not ( $TypesToExclude.Contains($typeToLoad) )) - { - $ActualTypesToLoad += $typeToLoad - } - } - - if ( $ActualTypesToLoad.length -gt 0 ) { - $hasErrors = Invoke-MasterDataLoader $env ` - -excelFile $file ` - -deeBasePath $deeBasePath ` - -documentsBasePath $documentsBasePath ` - -mappingFilesBasePath $mappingFilesBasePath ` - -automationWorkflowFilesBasePath $automationWorkflowFilesBasePath ` - -checklistImageBasePath $checklistImageBasePath ` - -importObjectBasePath $importObjectBasePath ` - -createInCollection:$createInCollection ` - -typesToLoad $ActualTypesToLoad ` - -TypesToExclude $TypesToExclude - } - - $TypesToLoad = $OriginalTypesToLoad - $TypesToExclude = $OriginalTypesToExclude - - if($stopOnError -and $hasErrors ) - { - break - } - } - } - else { - LogWrite ("No MasterData found in folder ($excelFolder)...") -foregroundColor Yellow - } - - return $global:hasErrors -} - -<# - .SYNOPSIS - Import cmNavigo objects - - .DESCRIPTION - Imports objects to cmNavigo exported to xml using the native Export functionality. - Supports versioned and non-versioned entity types. For versioned objects, a new change set is created and approved. The imported - object is set effective. - Static model objects that have import/export support in cmNavigo are also supported. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER fileName - Path to the xml file to be imported. - - .EXAMPLE - Import-NavigoObject $env 'C:\DataCollection1.xml' -#> -function Import-NavigoObject -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # file - [Parameter(Mandatory=$True)] - [string]$filename - ) - - LogWrite " > Starting object import..." - - Use-LightBusinessObjects $env - - #region Get entity type to find if it's versionable - [xml] $xml = Get-Content $filename - [string] $fullTypeName = $xml.'CMF.ExportFile'.Object.type - $entityTypeName = $fullTypeName.Split(", ")[0].Split(".")[-1] - - # use try block to deal with objects from static model (not entity types) - try - { - [Cmf.Foundation.BusinessOrchestration.EntityTypeManagement.InputObjects.GetEntityTypeByNameInput]$getETinput = New-Object Cmf.Foundation.BusinessOrchestration.EntityTypeManagement.InputObjects.GetEntityTypeByNameInput - $getETinput.Name = $entityTypeName - $isVersioned = $getETinput.GetEntityTypeByNameSync().EntityType.IsVersioned - } - catch [Exception] { $isVersioned = $false } - #endregion - - # create change set - if ($isVersioned) - { - [Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.CreateChangeSetInput] $createCSInput = New-Object Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.CreateChangeSetInput - [Cmf.Foundation.BusinessObjects.ChangeSet] $changeSet = New-Object Cmf.Foundation.BusinessObjects.ChangeSet - $changeSet.Name = [guid]::NewGuid() - $createCSInput.ChangeSet = $changeSet - $changeSet.Type = 'General' - $changeSet.MakeEffectiveOnApproval = $true - $changeSet = $createCSInput.CreateChangeSetSync().ChangeSet - } - - # Call service for import - [Cmf.Foundation.BusinessOrchestration.ImportExportManagement.InputObjects.ImportObjectsInput] $inputObj = New-Object Cmf.Foundation.BusinessOrchestration.ImportExportManagement.InputObjects.ImportObjectsInput - $inputObj.Xml = Get-Content $filename -Encoding UTF8 - $inputObj.ChangeSet = $changeSet - - $return = $inputObj.ImportObjectsSync() - - $object = $return.Objects[0] - - if ($isVersioned) - { - # Approve Change set - [Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.RequestChangeSetApprovalInput] $requestApprovalInput = New-Object Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.RequestChangeSetApprovalInput - $requestApprovalInput.ChangeSet = $changeSet - $requestApprovalInput.IgnoreLastServiceId = $true - $return = $requestApprovalInput.RequestChangeSetApprovalSync() - } - - LogWrite (" Imported object " + $object.Name + "of type " + $object.GetType().Name + " ...") - - LogWrite " * Finished importing object!" -foregroundColor Green -} - -<# - .SYNOPSIS - Import cmNavigo objects - - .DESCRIPTION - Imports objects to cmNavigo exported to xml using the native Export functionality. - Supports versioned and non-versioned entity types. For versioned objects, a new change set is created and approved. The imported - object is set effective. - Static model objects that have import/export support in cmNavigo are also supported. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER objectsPath - Path of XML files to be imported. - - .EXAMPLE - Import-NavigoObjects $env $listObjectsToImport -securityToken "uipagesimportdf" -#> -function Import-NavigoObjects -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # objectsPath - [Parameter(Mandatory=$True)] - [string]$objectsPath, - - # securityToken - [Parameter(Mandatory=$False)] - [string]$securityToken - - ) - - LogWrite " > Importing objects from folder $($objectsPath)..." - if (Test-Path ($objectsPath)) { - Use-LightBusinessObjects $env - - if ($securityToken) - { - #Insert import token in table - $InsertQuery = "INSERT INTO [Control].[T_ImportToken] (SecurityToken, IsTokenActive) - VALUES ('$securityToken', 1);" - - $filePath = '.\InsertImportToken.sql'; - - Set-Content -path $filePath -value $InsertQuery - try{ - Invoke-SQLScript $env -database 'Online' -scriptPath $filePath - }finally{ - Remove-Item $filePath - } - } - - # Extract ZIP files to be imported - $archivesToDecompress = Get-ChildItem ("$objectsPath\*") -Include *.zip| Sort-Object Name - foreach($archive in $archivesToDecompress) - { - LogWrite (" > Extracting archive " + (Resolve-Path $archive | Split-Path -Leaf) + "...") - $filesExpanded = Expand-Archive $archive -Destination (Resolve-Path $archive | Split-Path -Parent) -Force - } - - $filesToImport = Get-ChildItem ("$objectsPath\*") -Include *.xml,*.cmf| Sort-Object Name - - if($filesToImport.Count -gt 0){ - - foreach($filename in $filesToImport) - { - LogWrite (" > Importing file " + (Resolve-Path $filename | Split-Path -Leaf) + "...") - - #region Get entity type to find if it's versionable - [xml] $xml = Get-Content $filename - [string] $fullTypeName = $xml.'CMF.ExportFile'.Object.type - $entityTypeName = $fullTypeName.Split(", ")[0].Split(".")[-1] - - # use try block to deal with objects from static model (not entity types) - try - { - [Cmf.Foundation.BusinessOrchestration.EntityTypeManagement.InputObjects.GetEntityTypeByNameInput]$getETinput = New-Object Cmf.Foundation.BusinessOrchestration.EntityTypeManagement.InputObjects.GetEntityTypeByNameInput - $getETinput.Name = $entityTypeName - $isVersioned = $getETinput.GetEntityTypeByNameSync().EntityType.IsVersioned - } - catch [Exception] { $isVersioned = $false } - #endregion - - - # create change set - if ($isVersioned) - { - [Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.CreateChangeSetInput] $createCSInput = New-Object Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.CreateChangeSetInput - [Cmf.Foundation.BusinessObjects.ChangeSet] $changeSet = New-Object Cmf.Foundation.BusinessObjects.ChangeSet - $changeSet.Name = [guid]::NewGuid() - $createCSInput.ChangeSet = $changeSet - $changeSet.Type = 'General' - $changeSet.MakeEffectiveOnApproval = $true - $changeSet = $createCSInput.CreateChangeSetSync().ChangeSet - } - - - # Call service for import - [Cmf.Foundation.BusinessOrchestration.ImportExportManagement.InputObjects.ImportObjectsInput] $inputObj = New-Object Cmf.Foundation.BusinessOrchestration.ImportExportManagement.InputObjects.ImportObjectsInput - $inputObj.Xml = Get-Content $filename -Encoding UTF8 - $inputObj.ChangeSet = $changeSet - - if ($securityToken) - { - $inputObj.SecurityToken = "$securityToken" - $inputObj.EntityTypeNamesReplace = New-Object System.Collections.ObjectModel.Collection -TypeName String - $inputObj.EntityTypeNamesReplace[0] = $entityTypeName - } - - $return = $inputObj.ImportObjectsSync() - - $objects = $return.Objects - - if ($isVersioned) - { - # Approve Change set - [Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.RequestChangeSetApprovalInput] $requestApprovalInput = New-Object Cmf.Foundation.BusinessOrchestration.ChangeSetManagement.InputObjects.RequestChangeSetApprovalInput - $requestApprovalInput.ChangeSet = $changeSet - $requestApprovalInput.IgnoreLastServiceId = $true - $return = $requestApprovalInput.RequestChangeSetApprovalSync() - } - - foreach ($object in $objects) { - LogWrite (" Imported object " + $object.Name + " of type " + $object.GetType().Name + " ...") - } - } - } - - #Delete import token in table - if ($securityToken) - { - $DELQuery = "DELETE From [Control].[T_ImportToken] Where SecurityToken='$securityToken'" - $filePath = '.\DeleteImportToken.sql'; - - Set-Content -path $filePath -value $DELQuery - try{ - Invoke-SQLScript $env -database 'Online' -scriptPath $filePath - }finally{ - Remove-Item $filePath - } - } - - LogWrite " * Finished importing objects!" -foregroundColor Green - } else { - LogWrite " ! Folder not found!" -foregroundColor Yellow - } -} - -<# - .SYNOPSIS - Creates a new object to represent a cmNavigo ERP Action. - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties to load a custom ERP action to - cmNavigo. Should be used in conjunction with Install-ERPActions function. - - .PARAMETER ActionName - Name of the action - - .PARAMETER Description - The description of the ERP action - - .PARAMETER SourceName - The Name of the IDOC to use - - .PARAMETER TargetName - The Name of the DEE Action to use - - .EXAMPLE - $erpActions += New-ERPAction -actionName 'Employee01' -description 'Creates employees from SAP' -sourceName 'HRMD_A09' -targetName 'ZHRMDIDocReceiverAction' - - .OUTPUTS - A custom object representing the cmNavigo service. The object contains the following properties: - - ActionName: The name of ERP action - - Description: The description of the action - - SourceName: The name of the IDOC to use - - TargetName: The name of the DEE to use -#> -function New-ERPAction() -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $actionName, - - [Parameter(Mandatory=$True)] - [string] $description, - - [Parameter(Mandatory=$True)] - [string] $sourceName, - - [Parameter(Mandatory=$True)] - [string] $targetName - ) - - $erpAction = new-object PSObject - - $erpAction | add-member -type NoteProperty -Name ActionName -Value $actionName - $erpAction | add-member -type NoteProperty -Name Description -Value $description - $erpAction | add-member -type NoteProperty -Name SourceName -Value $sourceName - $erpAction | add-member -type NoteProperty -Name TargetName -Value $targetName - - return $erpAction -} - -<# - .SYNOPSIS - Installs cmNavigo ERP Actions - - .DESCRIPTION - Install one or more cmNavigo ERP Actions. If already existing, the ERP action will be ignore and nothing will be done. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER erpActions - Array containing the ERP actions to be added. Each action should be a custom object created with the New-ERPAction - function. - - - .EXAMPLE - Install-ERPActions $env -erpActions $erpActions - -#> -function Install-ERPActions() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Services to Install - [Parameter(Mandatory=$True)] - [Object[]]$erpActions - ) - - LogWrite " > Starting deploy of ERP action to database..." - - Use-LightBusinessObjects $env - - foreach($service in $erpActions) - { - [Cmf.Foundation.BusinessOrchestration.ErpManagement.InputObjects.GetErpTriggerByNameInput] $getErpTrigger = New-Object Cmf.Foundation.BusinessOrchestration.ErpManagement.InputObjects.GetErpTriggerByNameInput - $getErpTrigger.Name = $service.ActionName - - $continue = $true - - try - { - $result = $getErpTrigger.GetErpTriggerByNameSync() - if ($result -or $result.ErpTrigger -or $result.ErpTrigger.Name) - { - LogWrite (" Trigger " + $service.ActionName + " already in server ") $appserver.ServerName -foregroundColor Yellow - continue = $false - } - } - catch{} - - - - if ($continue) - { - LogWrite (" Adding ERP Action " + $service.ActionName + " ...") - [Cmf.Foundation.BusinessOrchestration.ErpManagement.InputObjects.CreateErpTriggerInput] $createServiceInput = New-Object Cmf.Foundation.BusinessOrchestration.ErpManagement.InputObjects.CreateErpTriggerInput - - [Cmf.Foundation.Erp.ErpTrigger] $inputObj = New-Object Cmf.Foundation.Erp.ErpTrigger - $inputObj.Name = $service.ActionName - $inputObj.Description = $service.Description - $inputObj.SourceName = $service.SourceName - $inputObj.Targetname = $service.Targetname - $inputObj.Type = [Cmf.Foundation.Erp.ErpTriggerType]::DeeRule - - $createServiceInput.ErpTrigger = $inputObj; - $return = $createServiceInput.CreateErpTriggerSync() - - } - - } - - LogWrite " * Finished deploy of ERP actions to database!" -foregroundColor Green -} - -<# - .SYNOPSIS - Creates a new object to represent a cmNavigo ERP Function. - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties to load a custom ERP function to - cmNavigo. Should be used in conjunction with Install-ERPFunctions function. - - .PARAMETER FunctionName - The Name of the function - - .EXAMPLE - New-ERPFunction -functionName 'BAPI_TRANSACTION_COMMIT' - - .OUTPUTS - A custom object representing the cmNavigo ERP Function. The object contains the following properties: - - FunctionName: Name of the function to import -#> -function New-ERPFunction() -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $functionName - ) - - $erpFunction = new-object PSObject - - $erpFunction | add-member -type NoteProperty -Name FunctionName -Value $functionName - - return $erpFunction -} - -<# - .SYNOPSIS - Installs cmNavigo ERP Functions - - .DESCRIPTION - Install one or more cmNavigo ERP Functions. If already exists, the ERP function will be ignore and nothing will be done. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER erpActions - Array containing the ERP functions to be added. Each function should be a custom object created with the New-ERPFunction - function. - - .EXAMPLE - Install-ERPFunctions $env -erpFunctions $erpFunctions -createServices $false - - -#> -function Install-ERPFunctions() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Services to Install - [Parameter(Mandatory=$True)] - [Object[]]$erpFunctions, - - # If Create Services - [Parameter(Mandatory=$True)] - [bool]$createServices - ) - - LogWrite " > Starting deploy of ERP function to database..." - - $functionsAdded = 0; - Use-LightBusinessObjects $env - - foreach($service in $erpFunctions) - { - try - { - [Cmf.Foundation.BusinessOrchestration.ErpManagement.OutputObjects.CreateErpFunctionInput] $getErpTrigger = New-Object Cmf.Foundation.BusinessOrchestration.ErpManagement.OutputObjects.CreateErpFunctionInput - - [Cmf.Foundation.Erp.ErpFunction] $inputObj = New-Object Cmf.Foundation.Erp.ErpFunction - - $inputObj.Name = $service.FunctionName - $getErpTrigger.ErpFunction = $inputObj; - - $result = $getErpTrigger.CreateErpFunctionSync() - - LogWrite (" Function " + $service.FunctionName + " was added.") - $functionsAdded = $functionsAdded + 1; - } - catch [Exception] - { - LogWrite $_.Exception.Message - } - } - - - - if ($functionsAdded -gt 0) - { - LogWrite (" ERP Functions added " + $functionsAdded + ".") -foregroundColor Green - [Cmf.Foundation.BusinessOrchestration.ErpManagement.InputObjects.GenerateSourceCodeInput] $generateServices = New-Object Cmf.Foundation.BusinessOrchestration.ErpManagement.InputObjects.GenerateSourceCodeInput - $generateServices.CreateServices = $createServices - $result = $generateServices.ErpGenerateSourceCodeSync(); - LogWrite (' Code was generated successfully.') - } - else - { - LogWrite (" ERP Functions added " + $functionsAdded +"." ) -foregroundColor Yellow - } - - LogWrite (" * Finished deploy of ERP Functions to database!") -foregroundColor Green - -} - - -<# - .SYNOPSIS - Creates a new object to represent a cmNavigo DEE Action. - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties to load a DEE Action to - cmNavigo. Should be used in conjunction with Execute-DEEAction or Delete-DEEAction function. - - .PARAMETER FunctionName - The Name of the DEE action - - .EXAMPLE - New-DEEAction -deeName 'ATSHTBRevertResourceState' - - .OUTPUTS - A custom object representing the cmNavigo DEE Action. The object contains the following properties: - - DEEName: Name of the DEE Action -#> -function New-DEEAction() -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $deeName - ) - - $deeAction = new-object PSObject - - $deeAction | add-member -type NoteProperty -Name DEEACtionName -Value $deeName - - return $deeAction -} - -<# - .SYNOPSIS - Execute cmNavigo DEE Actions - - .DESCRIPTION - Execute one or more cmNavigo DEE Actions. If the execution fails, a message will be sent to user, but the process continue. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER deeActions - Array containing the DEE Actions to be executed. Each DEE Action should be a custom object created with the New-DEEAction - function. - - .EXAMPLE - Execute-DEEAction $env -deeActions $deeActions - -#> -function Invoke-DEEAction() -{ - - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Actions to execute - [Parameter(Mandatory=$True)] - [Object[]]$deeActions - ) - - LogWrite " > Starting execution of DEE actions..." - - $totalActionsToExecute = $deeActions.Count - $executedActions = 0; - $activityDescription = 'Execution DEE Actions' - - Write-Progress -Activity ($activityDescription) -PercentComplete 0 -CurrentOperation "0% complete" -Status "Please wait..." - - - Use-LightBusinessObjects $env - $index = 0 - - foreach($dee in $deeActions) - { - $percentage = [int](($index / $totalActionsToExecute) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status (($index + 1).ToString() + " of " + $totalActionsToExecute.ToString() + ". Execution action " + $dee.DEEACtionName + "... Please wait...") - - try - { - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.ExecuteActionInput] $inputAction = New-Object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.ExecuteActionInput - - [Cmf.Foundation.Common.DynamicExecutionEngine.Action] $action = New-Object Cmf.Foundation.Common.DynamicExecutionEngine.Action - $action.Name = $dee.DEEACtionName - - $inputAction.Action = $action - - $result = $inputAction.ExecuteActionSync() - - LogWrite (" DEE Action " + $dee.DEEACtionName + " was executed correctly.") - $executedActions = $executedActions + 1; - } - catch [Exception] - { - LogWrite $_.Exception.Message - } - finally - { - $index = $index + 1 - $percentage = [int](($index / $totalActionsToExecute) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status "Please wait..." - } - } - - Write-Progress -Activity $activityDescription -Completed -Status "Actions has been executed." - - if ($executedActions -gt 0) - { - if ($executedActions -eq $totalActionsToExecute) - { - LogWrite (" DEE actions executed with success.") -foregroundColor Green - } - else - { - LogWrite (" Not all DEE actions executed with success.") -foregroundColor Yellow - } - } - else - { - LogWrite (" DEE ACtions did not execute with success." ) -foregroundColor Yellow - } - - LogWrite (" * Finished Execution DEE Actions!") -foregroundColor Green -} - -<# - .SYNOPSIS - Delete cmNavigo DEE Actions - - .DESCRIPTION - Delete one or more cmNavigo DEE Actions. If the delete fails, a message will be sent to user, but the process continue. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER deeActions - Array containing the DEE Actions to be executed. Each DEE Action should be a custom object created with the New-DEEAction - function. - - .EXAMPLE - Delete-DEEAction $env -deeActions $deeActions - -#> -function Remove-DEEAction() -{ - - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Actions to execute - [Parameter(Mandatory=$True)] - [Object[]]$deeActions - ) - - LogWrite " > Starting execution of DEE actions..." - - $totalActionsDelete = $deeActions.Count - $deletedActions = 0; - $activityDescription = 'Deleting DEE Actions' - - Write-Progress -Activity ($activityDescription) -PercentComplete 0 -CurrentOperation "0% complete" -Status "Please wait..." - - - Use-LightBusinessObjects $env - $index = 0 - - foreach($dee in $deeActions) - { - $percentage = [int](($index / $totalActionsDelete) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status (($index + 1).ToString() + " of " + $totalActionsDelete.ToString() + ". Delete action " + $dee.DEEACtionName + "... Please wait...") - - try - { - - [Cmf.Foundation.Common.DynamicExecutionEngine.Action] $action = New-Object Cmf.Foundation.Common.DynamicExecutionEngine.Action - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionInput] $removeAction = New-Object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionInput - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects] $getAction = New-Object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.GetActionByNameInput - - $getAction.Name = $dee.DEEACtionName - - $action = $getAction.GetActionByNameSync().Action - $removeAction.Action = $action; - $result = $removeAction.RemoveActionSync(); - - - LogWrite (" DEE Action " + $dee.DEEACtionName + " was deleted correctly.") - $deletedActions = $deletedActions + 1; - } - catch [Exception] - { - LogWrite $_.Exception.Message - } - finally - { - $index = $index + 1 - $percentage = [int](($index / $totalActionsDelete) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status "Please wait..." - } - } - - Write-Progress -Activity $activityDescription -Completed -Status "Actions has been deleted." - - if ($deletedActions -gt 0) - { - if ($deletedActions -eq $totalActionsDelete) - { - LogWrite (" DEE actions deleted with success.") -foregroundColor Green - } - else - { - LogWrite (" Not all DEE actions deleted with success.") -foregroundColor Yellow - } - } - else - { - LogWrite (" DEE Actions did not delete with success." ) -foregroundColor Yellow - } - - LogWrite (" * Finished delete DEE Actions!") -foregroundColor Green -} - - - -<# - .SYNOPSIS - Remove cmNavigo DEE Actions Triggers - - .DESCRIPTION - Delete one, or all, DEE Action triggers from action. If no trigger defined, all triggers for that DEE action will be deleted - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER $deeActionName - The Dee action name that contains the trigger to be deleted - - .PARAMETER $triggerName - The name of the trigger to be deleted - - .EXAMPLE - Remove-DEEActionTrigger $env -deeActionName 'ATSHTBRevertResourceState' -triggerName 'BusinessObjects.ChecklistInstance.Terminate.Post' - - .EXAMPLE - Remove-DEEActionTrigger $env -deeActionName 'ATSHTBRevertResourceState' - -#> - -function Remove-DEEActionTrigger() -{ - - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # DEE Action - [Parameter(Mandatory=$True)] - [string]$deeActionName, - - [Parameter(Mandatory=$False)] - [string]$triggerName - ) - Use-LightBusinessObjects $env - - [Cmf.Foundation.Common.DynamicExecutionEngine.Action] $action = New-Object Cmf.Foundation.Common.DynamicExecutionEngine.Action - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects] $getAction = New-Object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.GetActionByNameInput - $getAction.Name = $deeActionName - $action = $getAction.GetActionByNameSync().Action - - - [Cmf.Foundation.Common.DynamicExecutionEngine.ActionGroupActionCollection] $actionGroups = new-object Cmf.Foundation.Common.DynamicExecutionEngine.ActionGroupActionCollection - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionGroupActionsInput] $removeActionGroup = new-object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionGroupActionsInput - - if ($triggerName) - { - LogWrite (" > Deleting Action trigger " + $triggerName + " on DEE Action " + $deeActionName + "...") - $found = $false - - for($i=0; $i -le $action.ActionGroupActions.Count ; $i++) - { - $actionGroup = $action.ActionGroupActions[$i] - if ($actionGroup.ActionGroup -ne $null -and $actionGroup.ActionGroup.Name.toLower().equals($triggerName.ToLower())) - { - $removeActionGroup = new-object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionGroupActionsInput - $removeActionGroup.ActionGroupActions = new-object Cmf.Foundation.Common.DynamicExecutionEngine.ActionGroupActionCollection - $removeActionGroup.ActionGroup = $actionGroup.ActionGroup; - $removeActionGroup.ActionGroupActions.Add($actionGroup); - $result = $removeActionGroup.RemoveActionGroupActionsSync(); - $found = $true - break - } - } - - if ($found -eq $true) - { - LogWrite (" > Action trigger " + $triggerName + " on DEE Action " + $deeActionName + "deleted with success...") -foregroundColor Green - } - else - { - LogWrite (" > Action trigger " + $triggerName + " on DEE Action " + $deeActionName + " not found ...") -ForeGroundColor Yellow - } - - } - else - { - LogWrite (" > Deleting all actions trigger from DEE Action " + $deeActionName + "...") - - for($i=0; $i -le $action.ActionGroupActions.Count ; $i++) - { - $actionGroup = $action.ActionGroupActions[$i] - if ($actionGroup.ActionGroup -ne $null) - { - LogWrite (" > Deleting Action trigger " + $actionGroup.ActionGroup.Name + "...") - - $removeActionGroup = new-object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionGroupActionsInput - $removeActionGroup.ActionGroupActions = new-object Cmf.Foundation.Common.DynamicExecutionEngine.ActionGroupActionCollection - $removeActionGroup.ActionGroup = $actionGroup.ActionGroup; - $removeActionGroup.ActionGroupActions.Add($actionGroup); - $result = $removeActionGroup.RemoveActionGroupActionsSync(); - } - - } - LogWrite (" > All actions trigger was deleted from DEE Action " + $deeActionName + "...") -ForeGroundColor Green - } -} - - -<# - .SYNOPSIS - Generic function to write display all messages, and write them to a log file - - .DESCRIPTION - Writes log message to display. Called like the Write-Host, but with the feature to write all display to log file. - If there is the need to not write the log file in certain transaction, a global variable ($GenericLogFile) is inside of this file, - and we can set it to not write log file. - By default, always write file with this criteria: [computername]_[currentdate (yyyyMMddHH.mm.ss)].log - - - .PARAMETER $logstring - The string to display and write to log file - - .PARAMETER $ForeGroundColor - Possiblity to define a foreground color for the string to display. - The ForeGroundColor also defines to level of information (Red = Error; YEllow = Warning; Other = Info) - - .PARAMETER $BackgroundColor - Possiblity to define a background color for the string to display - - .PARAMETER $LogToFile - If want to display a certain message, but not want to write in log file - - .EXAMPLE - LogWrite 'The message to display' - - .EXAMPLE - LogWrite ("The message to display with parameters " + parameter[0] + "_" + parameter[b] + ".") - - .EXAMPLE - LogWrite 'The message to display' -foregroundColor Green - - .EXAMPLE - LogWrite 'The message to display' -foregroundColor Green -logToFile $false - - - .OUTPUTS - A custom object representing the cmNavigo ERP Function. The object contains the following properties: - - FunctionName: Name of the function to import -#> -Function LogWrite -{ - Param ( - [string]$logstring - - ,[Parameter(Mandatory=$False)] - [string]$ForeGroundColor - - ,[Parameter(Mandatory=$False)] - [string]$BackgroundColor - - ,[Parameter(Mandatory=$False)] - [bool]$LogToFile = $true - ) - - $messageType = "[INFO]" - - if($global:InteractiveMode -eq "") - { - $global:InteractiveMode = $true - } - - - if ($ForeGroundColor -eq '') - { - if ($global:InteractiveMode -eq $true) - { - $ForeGroundColor = (get-host).ui.rawui.ForegroundColor - } - } - else - { - if ($ForeGroundColor.ToLower() -eq "red") - { - $messageType = "[ERROR]" - } - elseif ($ForeGroundColor.ToLower() -eq "yellow") - { - $messageType = "[WARNING]" - } - } - - if ($BackgroundColor -eq '') - { - if ($global:InteractiveMode -eq $true) - { - $BackgroundColor = (get-host).ui.rawui.BackgroundColor - } - } - - if($global:InteractiveMode -eq $true){ - Write-Host $logstring -ForegroundColor $ForeGroundColor -BackgroundColor $BackgroundColor - } - else { - Write-Verbose "$messageType $logstring" -Verbose - } - - $logTime = "[" + (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + "]" - if ($GenericLogFile -eq $true -and $LogToFile -eq $true) - { - Add-content $Logfile -value ($logTime + $messageType + $logstring) - } -} - - - -<# - .SYNOPSIS - Create a command to extract files from a zipped file - - .DESCRIPTION - Create a command to extract files from a zipped file. This command intends to be called with 3 parameters - This function, by it self, does not execute anything. Must be called inside a Invoke-Command action - - - .PARAMETER $targetdir - The location where to extract the files - - - .PARAMETER $zipfilename - The location,and the name, of the zip file to extact - - .PARAMETER $activityDescription - The description of what is to uniz - - .EXAMPLE - OverwriteBackupFile 'c:\filename.zip' - - -#> -function CreateUnzipCommand -{ - return { - param($targetdir, $zipfilename, $activityDescription, $removeTarget = $true) - - if ( ( Test-Path $zipfilename ) -eq $true ) - { - if (!(Test-Path $targetdir)) - { - $r = mkdir $targetdir - } - - [Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" ) | Out-Null - [Reflection.Assembly]::LoadWithPartialName( "System.IO.Path" ) | Out-Null - - $manifestFileName = "BackupManifest.xml" - - $zip = [System.IO.Compression.ZipFile]::OpenRead($zipfilename) - - # Check if backup has a manifest - $backupManifestFile = $zip.Entries | Where-Object { $_.FullName -eq "$manifestFileName" } - if ( $backupManifestFile ) - { - # Try to read manifest from zip file - try { - $ZipStream = $backupManifestFile.Open() - - $Reader = [System.IO.StreamReader]::new($ZipStream) - $backupManifest = $Reader.ReadToEnd() - } - finally - { - if ( $Reader ) { - $Reader.Dispose(); - } - if ( $ZipStream ) { - $ZipStream.Dispose(); - } - } - } - - if ( $backupManifest ) { - # Backup Manifest was found in zip file - Partial Restore - $backupManifest = [xml]$backupManifest - - # Get Files/Folders to be restored - $files = $backupManifest.BackupManifest.Content.File - $folders = $backupManifest.BackupManifest.Content.Folder - - $manifestInTargetDir = Join-Path -Path "$targetdir" -ChildPath "$manifestFileName" - if ( $removeTarget ) { - - if ( Test-Path -Path "$manifestInTargetDir" ) { - Remove-Item -Path "$manifestInTargetDir" -Force - } - - foreach ( $file in $files ) { - $fileToRemove = Join-Path -Path "$targetdir" -ChildPath "$file" - if ( Test-Path -Path "$fileToRemove" ) { - Remove-Item -Path "$fileToRemove" -Force - } - } - - foreach ( $folder in $folders ) { - $folderToRemove = Join-Path -Path "$targetdir" -ChildPath "$folder" - if ( Test-Path -Path "$folderToRemove" ) { - Remove-Item -Path "$folderToRemove" -Recurse -Force - } - } - } - } else { - # No Backup Manifest was found in zip file - Full Restore - if ( $removeTarget ) { - Get-ChildItem $targetdir | ForEach-Object { - Remove-Item $_.FullName -Recurse -Force - } - } - } - - [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfilename, $targetdir); - - # remove manifest from target dir after restoring zip - if ( $manifestInTargetDir -and ( Test-Path -Path "$manifestInTargetDir" ) ) { - Remove-Item -Path "$manifestInTargetDir" -Force - } - } - else - { - throw 'Specified backup file does not exist.' - } - } -} - - -<# - .SYNOPSIS - Creates a new object to represent a cmNavigo Report. - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties to load a custom report to - cmNavigo. Should be used in conjunction with Install-Reports function. - - .PARAMETER ReportPath - The physical location of the report to upload - - .PARAMETER Database - Default database name on which report will be ran - - .PARAMETER ReportFolder - The folder location where the report will be uploaded - - .EXAMPLE - New-Report -reportPath $ScriptPath'\Reports\Chemical Lab.rdl' -database 'ODS' -reportFolder '/Custom' - - .EXAMPLE - New-Report -reportPath $ScriptPath'\Reports\Chemical Lab_Online.rdl' -database 'Online' -reportFolder '/Custom' - - .EXAMPLE - New-Report -reportPath $ScriptPath'\Reports\Chemical Lab_DWH.rdl' -database 'DWH' -reportFolder '/Custom' - - - .OUTPUTS - A custom object representing the cmNavigo Report. The object contains the following properties: - - ReportPath: The physical location of the report to upload - - Database: The database name on which report will be ran - - ReportFolder: THe folder where report will be uploaded - - -#> -function New-Report -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $reportPath, - - # Database - [Parameter(Mandatory=$True)] - [CMFDatabase] $database, - - [Parameter(Mandatory=$True)] - [string] $reportFolder - - ) - - $report = new-object PSObject - - $report| add-member -type NoteProperty -Name ReportPath -Value $reportPath - $report| add-member -type NoteProperty -Name DataBase -Value $database - $report| add-member -type NoteProperty -Name ReportFolder -Value $reportFolder - - return $report -} - -<# - .SYNOPSIS - Installs cmNavigo Reports - - .DESCRIPTION - Install one or more cmNavigo Reports. If already existing, the report will be replaced. - Also, the datasource of the report will be updated. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER reports - Array containing the reports to be added. Each report should be a custom object created with the New-Report - function. - - .EXAMPLE - Install-Reports -env $env -reports $reports - - .NOTES - If Report folder does not exist, it will be created. - The datasource and report will be overwritten if send more than one time -#> -function Install-Reports -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Reports to Install - [Parameter(Mandatory=$True)] - [Object[]]$reports - - ) - - Use-LightBusinessObjects $env - - LogWrite " > Starting adding Reports to server..." - - $reportServerUri = $env.ReportServerUri + "/ReportService2010.asmx?wsdl" - - if ($env.ReportUseDefaultCredential) - { - $rs = New-WebServiceProxy -Uri $reportServerUri -UseDefaultCredential - } - else - { - $username = $env.ReportServerUser - $password = $env.ReportServerPassword - $credentials = New-Object System.Management.Automation.PSCredential -ArgumentList @($username,(ConvertTo-SecureString -String $password -AsPlainText -Force)) - $rs = New-WebServiceProxy -Uri $reportServerUri -Credential $credentials - } - if ($rs -ne $null) - { - - $warnings = $null - try - { - $activityDescription = "Adding reports to Report server..." - LogWrite (" " + $activityDescription) - $total = $reports.Count - $index = 0 - Write-Progress -Activity ($activityDescription) -PercentComplete 0 -CurrentOperation "0% complete" -Status "Please wait..." - $uploadSuccess = 0; - foreach($reportInfo in $reports) - { - try - { - $reportName = [System.IO.Path]::GetFileNameWithoutExtension($reportInfo.ReportPath) - $bytes = [System.IO.File]::ReadAllBytes($reportInfo.ReportPath) - - [Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput] $inputGetConfigPath = New-Object Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput - - $reportRootFolder = "" - try - { - $inputGetConfigPath.Path = "/Cmf/System/Configuration/Reporting/Reports Root Folder/" - $resultGetConfigPath = $inputGetConfigPath.GetConfigByPathSync() - } - catch [Exception]{ - Write-Host $_.Exception - } - - if ($resultGetConfigPath.Config) - { - $reportRootFolder = $resultGetConfigPath.Config.Value - } - - $reportInfo.ReportFolder = $reportRootFolder + $reportInfo.ReportFolder - - $targetFolderPath = $reportInfo.ReportFolder - $percentage = [int](($index / $total) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status (($index + 1).ToString() + " of " + $total.ToString() + ". Uploading report " + $reportName +" to " + $targetFolderPath + "... Please wait...") - - LogWrite(" " + "Uploading report " + $reportName +" to " + $targetFolderPath + "...") - $x = $reportInfo.ReportFolder.Split('/') - $i = 0; - if ($x.Count -ge 1) - { - $reportFolder = "/" - - while ($i -lt $x.Count) - { - #Check if folder is existing, create if not found - try - { - $i = $i + 1 - if ($x[1] -ne "") - { - $reportPath = $x[$i] - $reportFolderCopy = $reportFolder; - if ($i -eq 1) - { - $reportFolder = $reportFolder + $reportPath - } - else - { - $reportFolder = $reportFolder + "/" + $reportPath - } - #need to do this first, because the parent folder may exists, but the child don't - $ignoreMessage = $rs.CreateFolder($reportPath,$reportFolderCopy, $null) - - } - } - catch [System.Web.Services.Protocols.SoapException] - { - if (-not( $_.Exception.Detail.InnerText -match "[^rsItemAlreadyExists400]")) - { - $msg = "[Install-SSRSRDL()] Error creating folder: $reportFolder. Msg: '{0}'" -f $_.Exception.Detail.InnerText - throw $msg - } - } - } - } - - $report = $rs.CreateCatalogItem( - - "Report", # Catalog item type - $reportName, # Report name - $targetFolderPath,# Destination folder - $true, # Overwrite report if it exists? - $bytes, # .rdl file contents - $null, # Properties to set. - [ref]$warnings # Warnings that occurred while uploading. - ) - - - # Get the names of the data sources that the - # uploaded report references. Note that this might be different from - # the name of the datasource as it is deployed on the report server! - foreach($itemDataSource in @($rs.GetItemDataSources($report.Path))) - { - $referencedDataSourceName = $itemDataSource.Name - $targetDatasourceRef = ""; - - switch ($referencedDataSourceName) - { - "ONLINEDataSource" - { - $targetDatasourceRef = $env.ReportsOnlineDataSource - } - "ODSDataSource" - { - $targetDatasourceRef = $env.ReportsODSDataSouce - } - "DWHDataSource" - { - $targetDatasourceRef = $env.ReportsDWHDataSource - } - } - - if($targetDatasourceRef -ne "") - { - # Change the datasource for the report to $targetDatasourceRef - # Note that we can access the types such as DataSource with the prefix - # "SSRS" only because we specified that as our namespace when we - # created the proxy with New-WebServiceProxy. - $proxyNamespace = $rs.GetType().Namespace - - $myDataSource = New-Object ("$proxyNamespace.DataSource") - $myDataSource.Name = $referencedDataSourceName - $myDataSource.Item = New-Object ("$proxyNamespace.DataSourceReference") - $myDataSource.Item.Reference = $targetDatasourceRef - - $rs.SetItemDataSources($report.Path, $myDataSource) - } - } - - $uploadSuccess = $uploadSuccess + 1 - } - catch [Exception] - { - LogWrite(" " + "Error uploading report " + $reportName +" to " + $targetFolderPath + ". Error: " + $_.Exception.Message) -ForeGroundColor Red - } - finally - { - $index = $index + 1 - $percentage = [int](($index / $total) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status "Please wait..." - } - } - - Write-Progress -Activity $activityDescription -Completed -Status "Reports has been uploaded to server." - - if ($uploadSuccess -eq 0) - { - LogWrite (" * " + $uploadSuccess + " of " + $reports.Count + " Reports has been uploaded to server! Errors occurred. ") -foregroundColor Red - } - else - { - if ($uploadSuccess -eq $reports.Count) - { - LogWrite (" * " + $uploadSuccess + " of " + $reports.Count + " Reports has been uploaded to server!") -foregroundColor Green - } - else - { - LogWrite (" * " + $uploadSuccess + " of " + $reports.Count + " Reports has been uploaded to server!") -foregroundColor Yellow - } - } - } - finally - { - $d = $rs.Dispose() - } - } - else - { - LogWrite (" * Error getting access to report server. No reports has been uploaded ") -foregroundColor Red - } -} - -<# - .SYNOPSIS - Installs reports within a given folder - - .DESCRIPTION - Installs MES Reports. - If already existing, the report will be replaced. Also, the datasource of the report will be updated. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER folderPath - Folder where the reports are located. - - .EXAMPLE - Install-ReportsInFolder -env $env -folderPath $reportsFolderPath - - .NOTES - If Report folder does not exist, it will be created. - The datasource and report will be overwritten if send more than one time -#> -function Install-ReportsInFolder -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Base folder path of the reports to load - [Parameter(Mandatory=$True)] - [string]$folderPath - ) - - Use-LightBusinessObjects $env - - if(Test-Path ($folderPath)) - { - # this is to convert relative path into full path - $folderPath = Resolve-Path $folderPath - $folderPath = "$folderPath" # convert back to string - - LogWrite (" > Loading Reports from folder $($folderPath)...") - - $reports = @() - - $reportFiles = Get-ChildItem -Path $folderPath -Filter '*.rdl' -Recurse - LogWrite (" Number of reports found to deploy: $($reportFiles.Count)") - if ($reportFiles.Count -gt 0) - { - $dataSourceNames = @("Online", "ODS", "DWH") - foreach ($reportFile in $reportFiles) - { - #region Resolve Report Folder - $reportFolder = "" - $localPathStartIndex = $folderPath.Split("\").Count - - $folder = $folderPath.Split("\")[$localPathStartIndex - 1] - - $print = "" + $reportFile.FullName - $splitedPath = $print.Split("\") - - $fileIndex = ($splitedPath.Count - 1) - - $foundFolder = $false - for ($i=0; $i -lt $fileIndex; $i++) - { - if ( $foundFolder -eq $true ) { - $reportFolder += "/" + $splitedPath[$i] - } - - if ( $splitedPath[$i] -eq $folder ) { - $foundFolder = $true - } - } - if ($reportFolder -eq "") { - LogWrite (" * Could not resolve ReportFolder") -ForegroundColor Yellow - } - #endregion - - #region Resolve report data source (database) - [xml]$report = Get-Content -Path $reportFile.FullName - $dataSources = $report.Report.DataSources.DataSource.Name - #default data source ODS - $dataSourceName = $dataSourceNames[1]; - foreach($dataSource in $dataSources) - { - if($dataSource.Contains($dataSourceNames[1])) - { - $dataSourceName = $dataSourceNames[1] - } - elseif($dataSource.Contains($dataSourceNames[2])) - { - $dataSourceName = $dataSourceNames[2] - } - else - { - $dataSourceName = $dataSourceNames[0] - } - } - #endregion - $reports += New-Report -reportPath $reportFile.FullName -database "$dataSourceName" -reportFolder $reportFolder - } - Install-Reports -env $env -reports $reports - } - Install-ReportServerResources -env $env -folder $folderPath - } else { - LogWrite (" * Folder $($folderPath) does not exist...") -foregroundColor Yellow - } -} - -<# - .SYNOPSIS - Installs resources in report server - - .DESCRIPTION - Install all resources in a specific folder. If already existing, the resource will be replaced. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER folder - Folder containing the resources to be added. - - .EXAMPLE - Install-ReportServerResources -env $env -folder ".\Reports" - - Where .\Reports structure is: - .\Reports\_Images\Logo.jpg - .\Reports\_Images\Logo.jpg - - .NOTES - If resource folder does not exist, it will be created. - The resource will be overwritten if send more than one time -#> -function Install-ReportServerResources -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Folder - [Parameter(Mandatory=$True)] - [string]$folder - ) - - # exclude reports [use Install-Reports instead] - # TODO: maybe install everything in this function (?) - if(Test-Path ($folder)) - { - # this is to convert relative path into full path - $folder = Resolve-Path $folder - $folder = "$folder" # convert back to string - - LogWrite (" > Loading Report Resources from folder $($folder)...") - $resourceFiles = Get-ChildItem -Path $folder -Exclude '*.rdl' -Recurse -File - LogWrite (" Number of report resources found to deploy: " + $resourceFiles.Count) - - if ($resourceFiles.Count -gt 0) - { - Use-LightBusinessObjects $env - - LogWrite " > Starting adding resources to report server..." - - $reportServerUri = $env.ReportServerUri + "/ReportService2010.asmx?wsdl" - - if ($env.ReportUseDefaultCredential) - { - $rs = New-WebServiceProxy -Uri $reportServerUri -UseDefaultCredential - } - else - { - $username = $env.ReportServerUser - $password = $env.ReportServerPassword - $credentials = New-Object System.Management.Automation.PSCredential -ArgumentList @($username,(ConvertTo-SecureString -String $password -AsPlainText -Force)) - $rs = New-WebServiceProxy -Uri $reportServerUri -Credential $credentials - } - if ($rs -ne $null) - { - - $warnings = $null - try - { - $activityDescription = "Adding resources to Report server..." - LogWrite (" " + $activityDescription) - $total = $resourceFiles.Count - $index = 0 - Write-Progress -Activity ($activityDescription) -PercentComplete 0 -CurrentOperation "0% complete" -Status "Please wait..." - $uploadSuccess = 0; - - # Content MIME Types Map - $KnownMimeTypes = @{ - ".jpg" = "image/jpeg"; - ".jpeg" = "image/jpeg"; - ".gif" = "image/gif"; - ".png" = "image/png"; - ".tiff" = "image/tiff"; - ".zip" = "application/zip"; - ".json" = "application/json"; - ".xml" = "application/xml"; - ".rar" = "application/x-rar-compressed"; - ".gzip" = "application/x-gzip"; - } - - - [Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput] $inputGetConfigPath = New-Object Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput - $reportRootFolder = "" - try - { - $inputGetConfigPath.Path = "/Cmf/System/Configuration/Reporting/Reports Root Folder/" - $resultGetConfigPath = $inputGetConfigPath.GetConfigByPathSync() - } - catch [Exception]{ - Write-Host $_.Exception - } - - if ($resultGetConfigPath.Config) - { - $reportRootFolder = $resultGetConfigPath.Config.Value - } - - $folder = Resolve-Path $folder - foreach($resourceFile in $resourceFiles) - { - LogWrite ( $resourceFile.FullName ) - try - { - $resourceName = [System.IO.Path]::GetFileName($resourceFile.FullName) - $bytes = [System.IO.File]::ReadAllBytes($resourceFile.FullName) - $file = Get-ChildItem $resourceFile.FullName - $fileMimeType = $KnownMimeTypes[$file.Extension.ToLower()]; - - $localPathStartIndex = $folder.Split("\").Count - - $splitedPath = ("" + $resourceFile.FullName).Split("\") - - $fileIndex = ($splitedPath.Count - 1) - - $resourceFolder = $reportRootFolder - - $i = $localPathStartIndex - while ($i -lt $fileIndex) - { - $resourceFolder += "/" + $splitedPath[$i] - $i++ - } - - $targetFolderPath = $resourceFolder - $percentage = [int](($index / $total) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status (($index + 1).ToString() + " of " + $total.ToString() + ". Uploading resource " + $resourceName +" to " + $targetFolderPath + "... Please wait...") - - LogWrite(" " + "Uploading resource " + $resourceName +" to " + $targetFolderPath + "...") - $x = $resourceFolder.Split('/') - $i = 0; - if ($x.Count -ge 1) - { - $reportFolder = "/" - - while ($i -lt $x.Count) - { - #Check if folder is existing, create if not found - try - { - $i = $i + 1 - if ($x[1] -ne "") - { - $reportPath = $x[$i] - $reportFolderCopy = $reportFolder; - if ($i -eq 1) - { - $reportFolder = $reportFolder + $reportPath - } - else - { - $reportFolder = $reportFolder + "/" + $reportPath - } - #need to do this first, because the parent folder may exists, but the child don't - $ignoreMessage = $rs.CreateFolder($reportPath,$reportFolderCopy, $null) - - } - } - catch [System.Web.Services.Protocols.SoapException] - { - if (-not( $_.Exception.Detail.InnerText -match "[^rsItemAlreadyExists400]")) - { - $msg = "[Install-SSRSRDL()] Error creating folder: $reportFolder. Msg: '{0}'" -f $_.Exception.Detail.InnerText - throw $msg - } - } - } - } - - - $report = $rs.CreateCatalogItem( - "Resource", # Catalog item type - $resourceName, # resource name - $targetFolderPath, # Destination folder - $true, # Overwrite resource if it exists? - $bytes, # file content - @{'Name'='MimeType'; 'Value'=$fileMimeType}, # Properties to set. - [ref]$warnings # Warnings that occurred while uploading. - ) - - $uploadSuccess = $uploadSuccess + 1 - - } - catch [Exception] - { - LogWrite(" " + "Error uploading report " + $reportName +" to " + $targetFolderPath + ". Error: " + $_.Exception.Message) -ForeGroundColor Red - } - finally - { - $index = $index + 1 - $percentage = [int](($index / $total) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status "Please wait..." - } - } - - Write-Progress -Activity $activityDescription -Completed -Status "resources has been uploaded to server." - - if ($uploadSuccess -eq 0) - { - LogWrite (" * " + $uploadSuccess + " of " + $total + " resources has been uploaded to server! Errors occurred. ") -foregroundColor Red - } - else - { - if ($uploadSuccess -eq $total) - { - LogWrite (" * " + $uploadSuccess + " of " + $total + " resources has been uploaded to server!") -foregroundColor Green - } - else - { - LogWrite (" * " + $uploadSuccess + " of " + $total + " resources has been uploaded to server!") -foregroundColor Yellow - } - } - } - finally - { - $d = $rs.Dispose() - } - } - else - { - LogWrite (" * Error getting access to report server. No resources has been uploaded ") -foregroundColor Red - } - } - } else { - LogWrite (" * Folder $($folder) does not exist...") -foregroundColor Yellow - } -} - -<# - .SYNOPSIS - Remove cmNavigo Reports - - .DESCRIPTION - Remove one or more cmNavigo Reports. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER reports - Array containing the reports to be added. - - .EXAMPLE - Remove-Reports -env $env -reports $reportsToRemove - - .NOTES - If thr Report does not exist an exception will be thrown -#> - -function Remove-Reports -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Reports to Remove - [Parameter(Mandatory=$True)] - [Object[]]$reports - - ) - - LogWrite " > Starting removing Reports from server..." - - $reportServerUri = $env.ReportServerUri + "/ReportService2010.asmx?wsdl" - - if ($env.ReportUseDefaultCredential) - { - $rs = New-WebServiceProxy -Uri $reportServerUri -UseDefaultCredential - } - else - { - $username = $env.ReportServerUser - $password = $env.ReportServerPassword - $credentials = New-Object System.Management.Automation.PSCredential -ArgumentList @($username,(ConvertTo-SecureString -String $password -AsPlainText -Force)) - $rs = New-WebServiceProxy -Uri $reportServerUri -Credential $credentials - } - if ($rs -ne $null) - { - - $warnings = $null - try - { - $activityDescription = "Removing reports to Report server..." - LogWrite (" " + $activityDescription) - $total = $reports.Count - $index = 0 - Write-Progress -Activity ($activityDescription) -PercentComplete 0 -CurrentOperation "0% complete" -Status "Please wait..." - $uploadSuccess = 0; - foreach($reportInfo in $reports) - { - try - { - $reportName = [System.IO.Path]::GetFileNameWithoutExtension($reportInfo.ReportPath) - $percentage = [int](($index / $total) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status (($index + 1).ToString() + " of " + $total.ToString() + ". Removing report " + $reportName +" to " + $targetFolderPath + "... Please wait...") - - LogWrite(" " + "Remove report " + $reportInfo + "...") - - $rs.DeleteItem( - ($reportInfo) - ) - } - catch [Exception] - { - LogWrite(" " + "Error removing report " + $reportName +" to " + $reportInfo + ". Error: " + $_.Exception.Message) -ForeGroundColor Red - } - finally - { - $index = $index + 1 - $percentage = [int](($index / $total) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status "Please wait..." - } - } - } - finally - { - $d = $rs.Dispose() - } - } - else - { - LogWrite (" * Error getting access to report server. No reports has been removed ") -foregroundColor Red - } -} - - - -<# - .SYNOPSIS - Creates and optionally executes post installation actions - - .DESCRIPTION - Creates and optionally executes post installation actions inside a folder - - .PARAMETER folderPath - Folder containing the rules to be executed - - .PARAMETER executeRules - Flag to control if rules are to executed - - .PARAMETER deleteRules - - .PARAMETER continueOnError - - .EXAMPLE - LoadProcessRules $env -folderPath 'c:\package\database\online' - LoadProcessRules $env -folderPath 'c:\package\database\online' -continueOnError $true -#> -function LoadProcessRules() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - #directory to enumerate the files - [Parameter(Mandatory=$True)] - $folderPath, - - [Parameter(Mandatory=$False)] - $executeRules = $true, - - [Parameter(Mandatory=$False)] - $deleteRules = $true, - - [Parameter(Mandatory=$False)] - $continueOnError = $false - ) - - if( Test-Path $folderPath ) - { - Use-LightBusinessObjects $env - [Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\MasterData.Logic.dll")) | Out-Null - - $listRules = Get-ChildItem $folderPath -Filter '*.cs' | Sort-Object Name - foreach($file in $listRules ) - { - $ruleName = $file.Name.Replace(".cs","") - try - { - LogWrite "Creating rule $ruleName..." - $action = [MasterData.Logic.DEEActionLoader]::InsertAction($file.FullName, $ruleName, $false) - - if( $executeRules) - { - LogWrite "Executing rule $ruleName..." - - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.ExecuteActionInput] $executeInput = New-Object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.ExecuteActionInput - $executeInput.Action = [MasterData.Logic.DEEActionLoader]::GetActionByName($ruleName) - $executeInput.ExecuteActionSync(); - } - - if( $deleteRules) - { - LogWrite "Deleting rule $ruleName..." - - [Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionInput] $removeInput = New-Object Cmf.Foundation.BusinessOrchestration.DynamicExecutionEngineManagement.InputObjects.RemoveActionInput - $removeInput.Action = [MasterData.Logic.DEEActionLoader]::GetActionByName($ruleName) - $removeInput.RemoveActionSync() - } - } - catch [Exception] - { - if($continueOnError){ - LogWrite "Error on rule $ruleName $_.Exception.Message " -foregroundColor Red - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host $_.Exception -ForegroundColor Red|format-list -force - } - }else{ - throw $_.Exception - } - } - } - } -} - - -<# - .SYNOPSIS - Sets the customization version string inside the cmNavigo database and in AppServer HTML config file - - .DESCRIPTION - Sets the customization version string inside the cmNavigo database and in AppServer HTML config file - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER version - The version number, in free text - - .PARAMETER appServerOnly - When used the customization version will be set only on HTML config - - .EXAMPLE - Set-CustomizationVersion $env -version 'Sprint 52' - - .EXAMPLE - Set-CustomizationVersion $env -version '4.2.1.0' - - .EXAMPLE - Set-CustomizationVersion $env -version '4.2.1.0' -appServerOnly -#> -function Set-CustomizationVersion -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject] $env, - - # String - [Parameter(Mandatory=$True)] - [string] $version, - - # Indicates if the version is to be apply on Application Servers only - [Parameter(Mandatory=$False)] - [switch] $appServerOnly - ) - - if ( -not $appServerOnly ) { - # Sets Customization Version on database - $filePath = '.\Customization.sql'; - $scriptContent = "EXEC [dbo].[P_SetCustomizationVersion] @ApplicationName = N'cmNavigo', @Version = '"+$version+"'" - - LogWrite " * Setting customization version $version" - - Set-Content -path $filePath -value $scriptContent - try { - Invoke-SQLScript $env -database 'Online' -scriptPath $filePath - } - finally{ - Remove-Item $filePath - } - } - - # Sets Customization Version on Application Server HTML Config file - foreach ( $server in $env.ApplicationServers ) { - $targetInstallation = ('\\' + $server.ServerName + '\' + $server.InstallationPath + '\' + $CMFHTML) -replace ':', '$'; - $configFile = Join-Path -Path $targetInstallation -ChildPath "\config.json"; - - # Update config.json - if(-not (Test-Path $configFile)){ - LogWrite " ! config.json not found" -foregroundColor Red - } else { - $jsonObject = Get-Content -Raw -Path $configFile | ConvertFrom-Json; - - LogWrite " Updating config.json" - if (($jsonObject.PSobject.Properties | Foreach {$_.Name}) -contains "customizationVersion") { - $jsonObject.customizationVersion = $version; - } else { - $jsonObject | add-member -Name "customizationVersion" -value $version -MemberType NoteProperty - } - - # Save config.json - $jsonObject | ConvertTo-Json -Depth 10 | Out-File $configFile; - } - } -} - - - -<# - .SYNOPSIS - Replaces tokens inside the files, including all subfolders items. - - .DESCRIPTION - Replaces tokens inside the files, including all subfolder - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER path - The folder to search to items - - .PARAMETER tokens - Hashtable with the token and values to replace - - .PARAMETER filters - Specifies a filter in items - - .EXAMPLE - Set-ScriptTokens $env -path 'Analytics' -filters @('*.sql','*.xmla') -tokens @{ '$(DWHInstance)' = $env.DWHClusterInstance; '$(DWHUser)' = $env.SQLDWHUser;'$(DWHUserPasswd)' = $env.SQLDWHPassword; } -#> -function Set-ScriptTokens() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Path - [Parameter(Mandatory=$True)] - [string] $path, - - - [Parameter(Mandatory=$True)] - $tokens, - - [Parameter(Mandatory=$False)] - $filters - ) - - Get-ChildItem -path $path -Include $filters -Recurse | ForEach-Object { - - $fileName = $_.FullName - $tmp = $fileName + ".tmp" - $tokenCount = 0 - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host "Found $fileName" - } - Get-Content $fileName | ForEach-Object { - $line = $_ - $tokens.GetEnumerator() | ForEach-Object { - if( $line.Contains($_.Key) ){ - $line = $line.Replace($_.Key, $_.Value) - $tokenCount++; - } - } - $line - } | Set-Content $tmp - - - Move-Item $tmp $fileName -force - - if( $tokenCount -gt 0 ){ - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host "Replaced $tokenCount token(s) at $fileName" - } - } - } - - LogWrite (" * Finished replacing tokens") -foregroundColor Green -} - - -function TransformXmlFile($src,$xdt,$dst) -{ - [Reflection.Assembly]::LoadFrom((Resolve-Path "$ModulePath\References\Microsoft.Web.XmlTransform.dll")) | Out-Null - - $doc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument - $doc.PreserveWhiteSpace = $true - $doc.Load($src) - - $trn = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt) - - if ($trn.Apply($doc)) - { - $doc.Save($dst) - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Output "Output file: $dst" - Write-Host 'applyConfigTransformation - $trn.Apply completed' - } - } - else - { - throw ("Transformation " + $src + " with " + $xdt + " terminated with status False") - } -} - -<# - .SYNOPSIS - Transforms the business configuration files, using XML Document Transformation - - .DESCRIPTION - Transforms the business configuration files (Cmf.Foundation.Services.HostService.exe.config and Cmf.Foundation.Services.HostConsole.exe.config ) using the XML Document Transformation - Requires the reference Microsoft.Web.XmlTransform.dll - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER transformFile - The file with XDT instructions to apply - - .PARAMETER filters - Specifies a filter in items - - .PARAMETER applicationServer - If defined, transformation will only be applied to the specified application server. - - .EXAMPLE - XDT sample - - - - - - Install-CMFBusinessConfigTransformation $env -transformFile 'changeconfig.xdt' - - .EXAMPLE - Install-CMFBusinessConfigTransformation $env -transformFile 'changeconfig.xdt' -applicationServer $server1 - -#> -function Install-CMFBusinessConfigTransformation() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # transformFile - [Parameter(Mandatory=$True)] - [string] $transformFile, - - [Parameter(Mandatory=$False)] - $applicationServer - ) - - $fileNames = @("Cmf.Foundation.Services.HostService.dll.config") - - LogWrite " > Executing host configuration file transformation to $transformFile" -foregroundColor Green - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - - if($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true){ - Write-Host "Starting transforming config files" - } - - $source = $filesPath - foreach($appServer in $serversToUse) - { - $target = '\\' + $appServer.ServerName + '\' + $appServer.BusinessInstallationPath -replace ':', '$' - - foreach($fileName in $fileNames) - { - $configFile = Join-Path $target $fileName - - TransformXmlFile $configFile $transformFile $configFile - } - } - - LogWrite (" * Finished transforming config") -foregroundColor Green -} - -<# - .SYNOPSIS - Installs customization packages on HTML5 Presentation - - .DESCRIPTION - Copies packages to the node_modules of HTML5 installation. - Deals with config.json - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER packageFolder - Absolute Path to the packages to install. - - .PARAMETER prefix - If defined, it will look for packages that begins with the given prefix. Default value is customization. - - .PARAMETER applicationServer - Application server path - - .PARAMETER target - Target path to install. I.e. UI\Help OR UI\HTML - By default, it uses the UI\HTML. - - .PARAMETER doNotRemovePackages - When $true, it will not remove the delivered packages. - This can be used to deliver partially a package, or when a PrivateFix from the ProductTeam needs to be deployed. - By default, it will remove the package before delivering it. - - .PARAMETER isConnectIoTPackages - When $true, it will handle them as connect iot packages. - When not connect iot, the packages will be added to the config under the packages section also a two level package (@mainPackage/subPackage) is expected; - When connect iot, the packages will be added to the config under the connectiot section; - - .EXAMPLE - Install-CMFHTMLPackages $env -packageFolder ./package/html5 -applicationServer "./html" - - .NOTES - Requires administrative privileges on the application servers. -#> -function Install-CMFHTMLPackages() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Path to the folder with the customization packages - [Parameter(Mandatory=$True)] - [string]$packageFolder, - - # Prefix of the packages (Default is customization) - [Parameter(Mandatory=$False)] - [string] $prefix="customization", - - # Application Server Path - [Parameter(Mandatory=$False)] - [string] $applicationServer, - - # target ($CMFHTML / $CMFHelp) (Default is $CMFHTML) - [Parameter(Mandatory=$False)] - [string] $target, - - # do not remove packages (being delivered) - [Parameter(Mandatory=$False)] - [switch] $doNotRemovePackages, - - # is connect iot packages - [Parameter(Mandatory=$False)] - [switch] $isConnectIoTPackages - ) - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - # default target to $CMFHTML - if (-not $target) { - $target = "$CMFHTML" - } - - foreach($server in $serversToUse) - { - #declare some paths - $targetInstallation = ('\\' + $server.ServerName + '\' + $server.InstallationPath + '\' + $target) -replace ':', '$'; - $mainPackageList = @(); - $packagesToInstall = @(); - $nodeModulesFolder = Join-Path -Path $targetInstallation -ChildPath "node_modules"; - $configFile = Join-Path -Path $targetInstallation -ChildPath "\config.json"; - $indexHtmlFile = Join-Path -Path $packageFolder -ChildPath "\index.html"; - - # Get the packages to Install - # Get only directories, as sometimes .gitkeep is present here - Get-ChildItem -Path:$packageFolder -Directory | ForEach-Object { - $mainPackageName =$_.Name; - if ( $isConnectIoTPackages ) { - $mainPackageFullPath = $_.FullName; - $mainPackageList += $mainPackageName - Get-ChildItem -Path "$mainPackageFullPath" -Directory | ForEach-Object { - $packagesToInstall += "$mainPackageName/$($_.Name)" - } - } - else { - $packagesToInstall += $mainPackageName; - } - } - - if ($packagesToInstall.length -gt 0) { - LogWrite " Packages to install:" - foreach ( $packageName in $packagesToInstall) { - LogWrite " - $packageName" - } - - if (-not $doNotRemovePackages) { - LogWrite " Removing old packages" - # Remove old customization packages - Get-ChildItem $nodeModulesFolder | ForEach-Object { - if ( $isConnectIoTPackages ) { - if ( $mainPackageList.Contains($_.Name) ) { - $mainPackageName = $_.Name; - Get-ChildItem -Path "$($_.FullName)" -Directory | ForEach-Object { - if ( $packagesToInstall.Contains("$mainPackageName/$($_.Name)") ) { - LogWrite " - Removed package $mainPackageName/$($_.Name)" - Remove-Item $_.FullName -Force -Recurse; - } - } - } - } - else { - if ( $packagesToInstall.Contains($_.Name) ) { - LogWrite " - Removed package $($_.Name)" - Remove-Item $_.FullName -Force -Recurse; - } - } - } - } - - # Copy packages to node_modules folder - LogWrite " Copying packages" - Get-ChildItem -Path:$packageFolder -Directory | ForEach-Object { - - $mainFolderName = $($_.Name); - - if ( $isConnectIoTPackages ) { - - Get-ChildItem -Path "$($_.FullName)" -Directory | ForEach-Object { - - if($_ -like "*driver*" -and $_ -notlike "*task*") { - LogWrite " Is an IoT Driver so will not copy" - } else { - LogWrite " Is not IoT Driver so will copy" - $subDir = $_.FullName.Split('\') | select -Last 1; - $destDir = -join("$nodeModulesFolder","\","$mainFolderName","\", "$_"); - Robocopy $_.FullName "`"$destDir"`" /S /IS | Out-Null; - } - - } - - } else { - $destDir = -join("$nodeModulesFolder","\",$_.Name); - Robocopy $_.FullName "$destDir" /S /IS | Out-Null; - } - } - - - # Update config.json - if(-not (Test-Path $configFile)){ - LogWrite " ! config.json not found" -foregroundColor Red - } - $jsonObject = Get-Content -Raw -Path $configFile | ConvertFrom-Json; - - LogWrite " Updating config.json" - # Add packages - if (-not $isConnectIoTPackages) { - $packagesList = New-Object System.Collections.Generic.List[System.String]; - $jsonObject.packages.available | ForEach-Object { - $packagesList.Add($_); - } - # Add new packages - foreach ($packageToInstall in $packagesToInstall) { - if (-not $packagesList.Contains($packageToInstall)) { - LogWrite " Adding $packageToInstall to config.json" - $packagesList.Add($packageToInstall); - } - } - - $jsonObject.packages.available = $packagesList.ToArray(); - } - else { - $packagesList = @() - $jsonObject.connectiot.packages | ForEach-Object { - $packagesList += $_; - } - - foreach ($packageToInstall in $packagesToInstall) { - if (-not ($packagesList.path -contains $packageToInstall)) { - if($packageToInstall -like "*driver*" -and $packageToInstall -notlike "*task*") { - LogWrite " Will not add $packageToInstall to config.json (connectIot), because it's a Driver" - } else { - LogWrite " Adding $packageToInstall to config.json (connectIot)" - $packagesList += ([PSCustomObject]@{ path = $packageToInstall }) - } - } - } - - $jsonObject.connectiot.packages = $packagesList; - } - - # Update config.json cacheId - $now = Get-Date; - $randomSuffix = "" + (Get-Random -Maximum 99999 -Minimum 10000); - $jsonObject.cacheId = "" + $now.Year + $now.Month + $now.Day + $now.Hour + $now.Minute + $randomSuffix; - - # Save config.json - $jsonObject | ConvertTo-Json -Depth 10 | Out-File $configFile; - - # Update with index.html - if(-not (Test-Path $indexHtmlFile)){ - LogWrite " No index.html to publish" - } else { - LogWrite " Deal with index.html" - Copy-Item $indexHtmlFile $targetInstallation -recurse -force - } - } - else { - LogWrite " No packages found to install..." - } - LogWrite (" * $($target) installation in " + $server.ServerName + " completed") -foregroundColor Green; - } -} - -<# - .SYNOPSIS - Creates a new object to represent a CM MES Config - - .DESCRIPTION - Returns a new custom object which contains all the required configuration properties create or update a configuration entry - cmNavigo. Should be used in conjunction with Set-Config - - .PARAMETER parentPath - The Config path - - .PARAMETER name - The Config name - - .PARAMETER value - The Config value - - .PARAMETER valueType - The Config value type. This parameter is required when creating a new config. It can take the following values: - Boolean, Decimal, Double, Int16, Int32, Int64, String - - .EXAMPLE - New-Config -parentPath '/Cmf/System/Configuration/ERP/' -name 'IsActive' -Value 'TRUE' - - .OUTPUTS - A custom object representing the CM MES Config. The object contains the following properties: - - ParentPath: The config parent path - - Name: Name of the Config - - Value: The value of the config - - ValueType: The data type of the config -#> -function New-Config() -{ - param - ( - [Parameter(Mandatory=$True)] - [string] $parentPath, - - [Parameter(Mandatory=$True)] - [string] $name, - - [Parameter(Mandatory=$True)] - [string] $value, - - [Parameter(Mandatory=$False)] - [string] $valueType - ) - - $config = new-object PSObject - - $config | add-member -type NoteProperty -Name ParentPath -Value $parentPath - $config | add-member -type NoteProperty -Name Name -Value $name - $config | add-member -type NoteProperty -Name Value -Value $value - $config | add-member -type NoteProperty -Name ValueType -Value $valueType - - return $config -} - -<# - .SYNOPSIS - Creates or updates a CM MES configuration entry - - .DESCRIPTION - Creates and/or saves one or more CM MES Configs. If the execution fails, a message will be sent to user, but the process continues. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER configs - Array containing the Configs to create and/or save. Each Config should be a custom object created with the function New-Config - function. - - .EXAMPLE - Execute-DEEAction $env -configs $configs - -#> -function Set-Config() -{ - - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Configs to create and/or save - [Parameter(Mandatory=$True)] - [Object[]]$configs - ) - - LogWrite " > Starting create and/or save of Configs..." - - $totalConfigsToCreateOrSave = $configs.Count - $createdSavedConfigs = 0; - $activityDescription = 'Create or Save of Configs' - - Write-Progress -Activity ($activityDescription) -PercentComplete 0 -CurrentOperation "0% complete" -Status "Please wait..." - - - Use-LightBusinessObjects $env - $index = 0 - - foreach($config in $configs) - { - $percentage = [int](($index / $totalConfigsToCreateOrSave) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status (($index + 1).ToString() + " of " + $totalConfigsToCreateOrSave.ToString() + ". Creating/saving the config " + $config.Name + " at " + $config.ParentPath + "... Please wait...") - - try - { - - [Cmf.Foundation.Configuration.Config] $configuration = New-Object Cmf.Foundation.Configuration.Config - $configuration.Name = $config.Name - $configuration.Value = $config.Value - if($config.ValueType) - { - $configuration.ValueType = ("System." + $config.ValueType) - } - - [Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput] $inputGetConfigPath = New-Object Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput - - try - { - $inputGetConfigPath.Path = ($config.ParentPath + "/" + $config.Name) - $resultGetConfigPath = $inputGetConfigPath.GetConfigByPathSync() - } - catch [Exception]{} - - - if ($resultGetConfigPath.Config) - { - # Config exists, update it - - $resultGetConfigPath.Config.Name = $configuration.Name - $resultGetConfigPath.Config.Value = $configuration.Value - $resultGetConfigPath.Config.ValueType = $configuration.ValueType - - [Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.UpdateConfigInput] $inputUpdateConfig = New-Object Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.UpdateConfigInput - $inputUpdateConfig.Config = $resultGetConfigPath.Config - $resultUpdateConfig = $inputUpdateConfig.UpdateConfigSync() - - LogWrite (" Config " + $config.ParentPath + "/" + $config.Name + " was saved correctly.") - } - else - { - # Config does not exist, create it - - [Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.CreateConfigInput] $inputCreateConfig = New-Object Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.CreateConfigInput - $inputCreateConfig.ParentPath = $config.ParentPath - $inputCreateConfig.Config = $configuration - $resultCreateConfig = $inputCreateConfig.CreateConfigSync() - - LogWrite (" Config " + $config.ParentPath + "/" + $config.Name + " was created correctly.") - } - - $createdSavedConfigs = $createdSavedConfigs + 1; - } - catch [Exception] - { - LogWrite $_.Exception.Message - } - finally - { - $index = $index + 1 - $percentage = [int](($index / $totalConfigsToCreateOrSave) * 100) - Write-Progress -Activity ($activityDescription) -PercentComplete $percentage -CurrentOperation "$percentage% complete" -Status "Please wait..." - } - } - - Write-Progress -Activity $activityDescription -Completed -Status "Configs have been created/saved." - - if ($createdSavedConfigs -gt 0) - { - if ($createdSavedConfigs -eq $totalConfigsToCreateOrSave) - { - LogWrite (" Configs created/saved with success.") -foregroundColor Green - } - else - { - LogWrite (" Not all Configs were created/saved with success.") -foregroundColor Yellow - } - } - else - { - LogWrite (" Configs were not created/saved with success." ) -foregroundColor Yellow - } - - LogWrite (" * Finished create/save Configs!") -foregroundColor Green -} - -<# - .SYNOPSIS - Gets a CM MES configuration entry - - .DESCRIPTION - Return a CM MES Config. If the execution fails, a message will be sent to user, but the process continues. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER configPath - Path of the Config to get. - - .EXAMPLE - Get-Config $env -configPath '/Cmf/System/Configuration/ConnectIoT/RepositoryLocation/' - -#> -function Get-Config() -{ - - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Path of the Config to get - [Parameter(Mandatory=$True)] - [string]$configPath - ) - - Use-LightBusinessObjects $env - try - { - [Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput] $inputGetConfigPath = New-Object Cmf.Foundation.BusinessOrchestration.ConfigurationManagement.InputObjects.GetConfigByPathInput - $inputGetConfigPath.Path = $configPath - $resultGetConfigPath = $inputGetConfigPath.GetConfigByPathSync() - - if ($resultGetConfigPath.Config) - { - # Config exists, return it - return $resultGetConfigPath.Config.Value - } - else - { - LogWrite (" Config $configPath was not found") - } - } - catch [Exception] - { - LogWrite $_.Exception.Message - } -} - - - - -<# - .SYNOPSIS - Backup the CMF Folder - - .DESCRIPTION - Makes a backup of the CMF Folder to a zip. - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER backupIdentifier - Name that identifies the backup - - .PARAMETER folderToBackup - Application folder to back up - - .PARAMETER applicationServer - Application server path - - .PARAMETER manifest - Manifest XML file with the content to be backed-up. - - .EXAMPLE - Backup-CMFFolder $env -backupIdentifier "Sprint01" -folderToBackup "UI\HTML" -applicationServer "./html" - - .NOTES - Requires administrative privileges on the application servers. -#> -function Backup-CMFFolder() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Name that identifies the backup - [Parameter(Mandatory=$True)] - [string] $backupIdentifier, - - # Folder to Backup - [Parameter(Mandatory=$True)] - [string] $folderToBackup, - - # Application Server Path - [Parameter(Mandatory=$False)] - [string] $applicationServer, - - # backup manifest - [Parameter(Mandatory=$False)] - [xml] $manifest - ) - - LogWrite (" > Starting " + $folderToBackup + " backup...") - - # Get servers to use - $serversToUse = @() - - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - foreach($server in $serversToUse) - { - $folderParsed = $folderToBackup.Split("\")[-1] - $backupPath = Join-Path -Path ($env.BackupLocation) -ChildPath ("\"+$backupIdentifier+"\" + $server.ServerName.Split('.')[0] + "-" + $folderParsed + "-"+$env.SystemName+"-"+$backupIdentifier+".zip") - - $continueBackup = OverwriteBackupFile $backupPath - - if($continueBackup -eq $true) - { - $sc = - { - param($sourcedir, $zipfilename, $activityDescription, $manifest) - Write-Progress -Activity ($activityDescription) -Status "Please wait..." - - # create backup folder if it doesn't exist - $mainBackupFolder = (Split-Path -parent $zipfilename) - New-Item -ItemType Directory -Force -Path $mainBackupFolder | Out-Null - - # check if manifest was provided - and identify files and folders to backup - if ( $manifest ) - { - $filesToBackup = @() - foreach ( $node in $manifest.BackupManifest.Content.File ) { - $filesToBackup += $node - } - - $foldersToBackup = @() - foreach ( $node in $manifest.BackupManifest.Content.Folder ) { - $foldersToBackup += $node - } - } - - # remove previous file if it already exists - if (Test-Path $zipfilename) { Remove-Item $zipfilename } - - [Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" ) | Out-Null - $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal - if ( ( -not $filesToBackup ) -and ( -not $foldersToBackup ) ) { - # No Files and No Folders to Backup - Full Backup - [System.IO.Compression.ZipFile]::CreateFromDirectory( $sourcedir, $zipfilename, $compressionLevel, $false ) - } - else { - # Files or Folders to Backup - Partial Backup - - #region: create temporary folder to copy files to be backed-up - $tempBackup = "$mainBackupFolder\tmp_backup" - if ( Test-Path $tempBackup ) { Remove-Item $tempBackup -Force -Recurse } - - New-Item -ItemType Directory -Force -Path "$tempBackup" | Out-Null - #endregion - if ( $filesToBackup ) { - foreach ( $item in $filesToBackup ) { - $fileToBackup = "$(Join-Path -Path $sourcedir -ChildPath $item)" - if ( Test-Path -Path "$fileToBackup" ) { - $itemPath = "$(Split-Path -Path $item)" - if ( $itemPath -ne '.' ) { - if ( -not (Test-Path "$tempBackup\$itemPath" ) ) { - New-Item -Path "$tempBackup" -type Directory -Name $itemPath -Force | Out-Null - } - } - - $fileName = "$(Split-Path $fileToBackup -Leaf)" - - $fileToBackup = "$((Resolve-Path $fileToBackup).Path)" - $sourceFolder = "$( Split-Path -Path $fileToBackup)" - - robocopy "$sourceFolder" "$tempBackup\$itemPath" $fileName | Out-Null - } - } - } - - if ( $foldersToBackup ) { - foreach ( $folder in $foldersToBackup ) { - $sourceFolder = "$(Join-Path -Path $sourcedir -ChildPath $folder)" - - if ( Test-Path -Path "$sourceFolder" ) { - robocopy "$sourceFolder" "$tempBackup\$folder" /e | Out-Null - } - } - } - - # Save manifest into tempbackup folder to be zipped - $manifest.Save( "$tempBackup\BackupManifest.xml" ) - - [System.IO.Compression.ZipFile]::CreateFromDirectory( $tempBackup, $zipfilename, $compressionLevel, $false ) - - # Delete tempbackup folder after the zip - if ( Test-Path $tempBackup ) { Remove-Item $tempBackup -Force -Recurse } - } - - Write-Progress -Activity $activityDescription -Completed -Status "Backup has beeen done." - } - - $activityDescription = "Backing up "+$folderToBackup+" in " + $server.ServerName + " ..." - LogWrite (" " + $activityDescription ) - - $FolderFullPath = (Join-Path -Path $server.InstallationPath -ChildPath ("\"+$folderToBackup)) - - $password = Get-SecureStringFromEncryptedString $env.AdminPass - $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env.AdminUser, $password - - $userName = $env.AdminUser - $password = Get-ClearTextFromEncryptedString $env.AdminPass - $uri = new-object System.Uri($backupPath) - $backupServer = "\\"+$uri.host - $sess = New-PSSession -ComputerName $server.ServerName -Credential $cred - Enter-PSSession -Session $sess - Invoke-Command -Session $sess -ScriptBlock { (net use $using:backupServer $using:password /USER:$using:userName) | Out-Null } - Invoke-Command -Session $sess -ScriptBlock $sc ` - -ArgumentList @($FolderFullPath,$backupPath, $activityDescription, $manifest) - Invoke-Command -Session $sess -ScriptBlock { (net use $using:backupServer /delete) | Out-Null } - Remove-PSSession -Session $sess - Exit-PSSession - } - else - { - LogWrite (" Backup of "+$folderToBackup+" in " + $server.ServerName + " was bypassed due to previous backup file...") -foregroundColor Yellow - } - } - - LogWrite (" * Finished "+$folderToBackup+" backup!") -foregroundColor Green -} - - -<# - .SYNOPSIS - Restore the Folder - - .DESCRIPTION - Makes a restore of the Folder installation given a backupFile - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER backupIdentifier - Name that identifies the backup - - - .PARAMETER applicationServer - Application server path - - .EXAMPLE - Restore-CMFHTML $env -backupIdentifier "Sprint01" -applicationServer "./html" - - .NOTES - Requires administrative privileges on the application servers. -#> -function Restore-CMFFolder() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # Name that identifies the backup - [Parameter(Mandatory=$True)] - [string] $backupIdentifier, - - # Folder to Backup - [Parameter(Mandatory=$True)] - [string] $folderToBackup, - - # Application Server Path - [Parameter(Mandatory=$False)] - [string] $applicationServer - ) - - LogWrite (" > Starting "+$folderToBackup+" restore...") - - # Get servers to use - $serversToUse = @() - if ($applicationServer) - { - $serversToUse += $applicationServer - } - else - { - $serversToUse = $env.ApplicationServers - } - - foreach($server in $serversToUse) - { - $folderParsed = $folderToBackup.Split("\")[-1] - $backupPath = Join-Path -Path ($env.BackupLocation) -ChildPath ("\"+$backupIdentifier+"\" + $server.ServerName.Split('.')[0] + "-" + $folderParsed + "-"+$env.SystemName+"-"+$backupIdentifier+".zip") - - $sc = CreateUnzipCommand - - $activityDescription = "Restoring "+$folderToBackup+" in " + $server.ServerName + "..." - LogWrite (" " + $activityDescription) - try{ - - $FolderFullPath = (Join-Path -Path $server.InstallationPath -ChildPath ("\"+$folderToBackup)) - - $password = Get-SecureStringFromEncryptedString $env.AdminPass - $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env.AdminUser, $password - - $userName = $env.AdminUser - $password = Get-ClearTextFromEncryptedString $env.AdminPass - $uri = new-object System.Uri($backupPath) - $backupServer = "\\"+$uri.host - $sess = New-PSSession -ComputerName $server.ServerName -Credential $cred - Enter-PSSession -Session $sess - Invoke-Command -Session $sess -ScriptBlock { (net use $using:backupServer $using:password /USER:$using:userName) | Out-Null } - Invoke-Command -Session $sess -ScriptBlock $sc ` - -ArgumentList @($FolderFullPath,$backupPath, $activityDescription) - Invoke-Command -Session $sess -ScriptBlock { (net use $using:backupServer /delete) | Out-Null } - Remove-PSSession -Session $sess - Exit-PSSession - - }catch { throw (" * Invoke-Command ERROR "+$_) } - } - - LogWrite (" * Finished "+$folderToBackup+" restore!") -foregroundColor Green -} - -function Get-EncryptedStringFromClearText() -{ - param ( - [Parameter(Mandatory=$True)] - [string] $ClearText - ) - $SecureString = Get-SecureStringFromClearText $ClearText - $EncryptedString = Get-EncryptedStringFromSecureString $SecureString - return $EncryptedString -} - -function Get-ClearTextFromEncryptedString() -{ - param ( - [Parameter(Mandatory=$True)] - [string] $EncryptedString - ) - $SecureString = Get-SecureStringFromEncryptedString $EncryptedString - $ClearText = Get-ClearTextFromSecureString $SecureString - return $ClearText -} - -function Get-ClearTextFromSecureString() -{ - param ( - [Parameter(Mandatory=$True)] - [SecureString] $SecureString - ) - $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) - $ClearText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) - return $ClearText -} - -function Get-EncryptedStringFromSecureString() -{ - param ( - [Parameter(Mandatory=$True)] - [SecureString] $SecureString - ) - $SecureStringKey = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43) - $EncryptedString = ConvertFrom-SecureString $SecureString -Key $SecureStringKey - return $EncryptedString -} - -function Get-SecureStringFromClearText() -{ - param ( - [Parameter(Mandatory=$True)] - [string] $ClearText - ) - $SecureString = ConvertTo-SecureString $ClearText -AsPlainText -Force - return $SecureString -} - -function Get-SecureStringFromEncryptedString() -{ - param ( - [Parameter(Mandatory=$True)] - [string] $EncryptedString - ) - $SecureStringKey = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43) - $SecureString = ConvertTo-SecureString $EncryptedString -Key $SecureStringKey - return $SecureString -} - - -<# - .SYNOPSIS - Backup CMFEnvironment - - .DESCRIPTION - By default creates a backup of the CMFEnvironment databases (online, ods, dwh) and folders (BusinessTier, HTML) - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER backupIdentifier - Name that identifies the backup to be created - - .PARAMETER applicationServer - Application server path - - .PARAMETER databases - Databases to be backed up (default: online, ods, dwh) - - .PARAMETER folders - Folders to be backed up (default: BusinessTier, HTML) - - .EXAMPLE - Backup-CMFEnvironment $env -backupIdentifier "Sprint01" -applicationServer -applicationServer $env.ApplicationServers[0] -#> -function Backup-CMFEnvironment() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # backupIdentifier - [Parameter(Mandatory=$True)] - [string] $backupIdentifier, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer - ) - - # Nice to have utility - to be done in the future -} - -<# - .SYNOPSIS - Restores CMFEnvironment - - .DESCRIPTION - By default restores the CMFEnvironment databases (online, ods, dwh) and folders (BusinessTier, HTML) - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER backupIdentifier - Name that identifies the backup to be restored - - .PARAMETER applicationServer - Application server path - - .PARAMETER databases - Databases to be restored (default: online, ods, dwh) - - .PARAMETER folders - Folders to be restored (default: BusinessTier, HTML) - - .EXAMPLE - Restore-CMFEnvironment $env -backupIdentifier "Sprint01" -applicationServer -applicationServer $env.ApplicationServers[0] - - .NOTES - Requires administrative privileges on the application servers. -#> -function Restore-CMFEnvironment() -{ - param - ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # backupIdentifier - [Parameter(Mandatory=$True)] - [string] $backupIdentifier, - - # Application Server - [Parameter(Mandatory=$False)] - [PSObject]$applicationServer - ) - - # Nice to have utility - to be done in the future -} - - -<# - .SYNOPSIS - Gets CMFEnvironment from config file. - - .DESCRIPTION - Gets the CMFEnvironment file from a configuration file (ps1 or json) - - .PARAMETER environmentConfigName - Environment configuration name. - - .PARAMETER environmentConfigPath - Environment configuration folder path. - - .EXAMPLE - $env = ( Get-CMFEnvironment -environmentConfigName "$EnvironmentConfigName" -environmentConfigPath "$PackageRootFolder\EnvironmentConfigs" -cmfInstallActionsPath "$PackageRootFolder\CMFInstallActions" ) -#> -function Get-CMFEnvironment() -{ - param - ( - # environmentConfigPath - [Parameter(Mandatory=$True)] - [string] $environmentConfigPath, - - # cmfInstallActionsPath - [Parameter(Mandatory=$True)] - [string] $cmfInstallActionsPath - ) - - if ( -not ( Test-Path $cmfInstallActionsPath ) ){ - throw "cmfInstallActionsPath is invalid... Folder '$cmfInstallActionsPath' does not exist..." - } - if ( -not ( Test-Path $environmentConfigPath ) ){ - throw "environmentConfigPath is invalid... Folder '$environmentConfigPath' does not exist..." - } - - $cmfInstallActionsPath = (Resolve-Path -Path $cmfInstallActionsPath).Path - $environmentConfigPath = (Resolve-Path -Path $environmentConfigPath).Path - - if (Test-Path $environmentConfigPath) - { - # Loading json configuration file - $env = & $cmfInstallActionsPath\EnvironmentConfigParser.ps1 -ConfigFilePath $environmentConfigPath -ReferencesDir $cmfInstallActionsPath\References - } - else - { - throw "Config $environmentConfigPath not found!" - } - - return $env -} - -<# - .SYNOPSIS - Gets a variable from an Yaml file - - .DESCRIPTION - Gets a variable from an Yaml file - - .PARAMETER FilePath - Yaml File Path - - .PARAMETER VariableName - Name of Variable to Get - - .EXAMPLE - ParseYamlVariables -filePath "[PATH]\GlobalVariables.yml" -VariableName "CurrentPackage" -#> -function ParseYamlVariables() -{ - param - ( - # File - [Parameter(Mandatory=$True)] - [string]$FilePath, - - # VariableName - [Parameter(Mandatory=$True)] - [string] $VariableName - ) - - foreach ($line in Get-Content $FilePath) - { - if ($line -match $VariableName) - { - return $line.Split("'")[1]; - } - } -} - -<# - .SYNOPSIS - Gets Master Data Loader dependencies - - .DESCRIPTION - Gets Master Data Loader dependencies - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .EXAMPLE - Get-MDLDependencies $env -#> -function Get-MDLDependencies() -{ - param ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env - ) - - # Copy MDL dependencies - LogWrite ("Copy References from Master Data Loader") - $appServer = $env.ApplicationServers[0] - $mdlPath = $appServer.MasterDataLoaderPath; - $mdlPath = '\\' + $appServer.ServerName + '\' + $mdlPath -replace ':', '$' - - Robocopy "$mdlPath" "$ModulePath\References" "*.dll" "MasterData.exe.config" /XF "Cmf.LightBusinessObjects.dll" /S /IS /XO | Out-Null -} - -<# - .SYNOPSIS - Deploy IoT Packages - - .DESCRIPTION - Deploy IoT Packages - - .PARAMETER env - Environment configuration, created with New-CMFEnvironment function. - - .PARAMETER packageRootFolder - PackageRootFolder - - .EXAMPLE - IoTPackages-Deploy $env -#> -function IoTPackages-Deploy() -{ - param ( - # CMFEnvironment - [Parameter(Mandatory=$True)] - [PSObject]$env, - - # PackageRootFolder - [Parameter(Mandatory=$True)] - [string] $packageRootFolder - ) - - LogWrite "Publishing IoT Packages" - - $repositoryLocation = Get-Config $env -configPath '/Cmf/System/Configuration/ConnectIoT/RepositoryLocation/' - if(-not $repositoryLocation) - { - throw "Missing Configuration /Cmf/System/Configuration/ConnectIoT/RepositoryLocation/" - } - $repositoryType = Get-Config $env -configPath '/Cmf/System/Configuration/ConnectIoT/RepositoryType/' - if(-not $repositoryType) - { - LogWrite (" Config /Cmf/System/Configuration/ConnectIoT/RepositoryType/ was not found. Fallback to RepositoryType = Npm.") - $repositoryType = "Npm" - } - - $successfullyPublishedPackagesCounter = 0 - $unsuccessfullyPublishedPackagesCounter = 0 - & cd $packageRootFolder - - if($repositoryType -eq "Directory") - { - foreach ($IoTPackageProjectReference in Get-ChildItem "$PackageRootFolder\AutomationCustomPackages\" -Directory) - { - foreach ($folder in Get-ChildItem "$PackageRootFolder\AutomationCustomPackages\$IoTPackageProjectReference\" -Directory) - { - cd "$PackageRootFolder\AutomationCustomPackages\$IoTPackageProjectReference\$folder" - foreach ($package in Get-ChildItem -Depth 2 -Filter "*.tgz") - { - Copy-Item -Force -Recurse -Verbose $package -Destination $repositoryLocation - if($LASTEXITCODE -ge 0){ - $successfullyPublishedPackagesCounter++ - }else - { - $unsuccessfullyPublishedPackagesCounter++ - LogWrite "Could not publish package $($package)" - } - } - } - } - Invoke-Expression "& '$repositoryLocation\.rebuildDatabase.ps1'" - } - elseif($repositoryType -eq "Npm") - { - $NpmServerAddress = $repositoryLocation - $parts = $NpmServerAddress.Split(':') - $machineName = $parts[1].Replace('//','') - $port = $parts[2] - $Tag = "IoT_100" - - Write-Verbose -Verbose "Deploying $Tag to $NpmServerAddress..." - - $psi = New-Object System.Diagnostics.ProcessStartInfo; - $psi.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden; - $psi.FileName = "cmd.exe"; #process file - $psi.UseShellExecute = $false; #start the process from it's own executable file - $psi.RedirectStandardInput = $true; #enable the process to read from standard input - $psi.RedirectStandardOutput = $true; #enable the process to read from standard output - $psi.RedirectStandardError = $true; #enable the process to read from standard error - $psi.CreateNoWindow = $true; - - $UserName = $env.AdminUser.Split('\')[1] - $UserPassword = Get-ClearTextFromEncryptedString $env.AdminPass - $UserEmail = "$userName@$userName.com" - - $p = [System.Diagnostics.Process]::Start($psi); - - Start-Sleep -s 2 #wait 2 seconds so that the process can be up and running - - $p.StandardInput.WriteLine("npm adduser --registry $NpmServerAddress"); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for the stdin to be ready to receive input - $p.StandardInput.WriteLine($UserName.ToLowerInvariant()); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for the stdin to be ready to receive input - $p.StandardInput.WriteLine($UserPassword); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for the stdin to be ready to receive input - $p.StandardInput.WriteLine($UserEmail); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for adduser command to finish - - Stop-Process -Id $p.Id -Force - - foreach ($IoTPackageProjectReference in Get-ChildItem "$PackageRootFolder\AutomationCustomPackages\" -Directory) - { - foreach ($folder in Get-ChildItem "$PackageRootFolder\AutomationCustomPackages\$IoTPackageProjectReference" -Directory) - { - cd "$PackageRootFolder\AutomationCustomPackages\$IoTPackageProjectReference\$folder" - foreach ($package in Get-ChildItem -Depth 2 -Filter "*.tgz") { - try - { - $command = "npm unpublish $IoTPackageProjectReference/$folder --registry $NpmServerAddress --tag $Tag --force --loglevel=error" - LogWrite $command - powershell $command -NoNewWindow - - } - catch - { - LogWrite "Unpublished package $($package) not needed" - } - - $command = "npm publish $package --registry $NpmServerAddress --tag $Tag --force --loglevel=error" - LogWrite $command - powershell $command -NoNewWindow - if($LASTEXITCODE -ge 0){ - $successfullyPublishedPackagesCounter++ - }else - { - $unsuccessfullyPublishedPackagesCounter++ - LogWrite "Could not publish package $($package)" - } - } - } - } - } - - LogWrite "Successfully published $($successfullyPublishedPackagesCounter) packages." - LogWrite "$($unsuccessfullyPublishedPackagesCounter) packages were not published successfully." -} \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/CustomizationInstall.ps1 b/cmf-cli/installDependencies/Data/CMFInstallActions/CustomizationInstall.ps1 deleted file mode 100644 index f6c32b278..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/CustomizationInstall.ps1 +++ /dev/null @@ -1,639 +0,0 @@ -# Powershell script to load CMF Customizations into a CM MES Installation -# Author: Luis Ponte -# Last Modified by: PI DevOps -# Last Modified on: 2020/07/07 -# -------------------------------------------------------------------------- -param( - [string]$EnvironmentConfigName, - [switch]$InteractiveMode = $false, - [string]$PlantName = "", - [switch]$BackupBefore = $true, - [switch]$RunAppInstall = $true -) - -if ([string]::IsNullOrWhiteSpace($EnvironmentConfigName)) -{ - throw "Missing mandatory parameter: EnvironmentConfigName" -} - -################################################ -# Variables - -$ErrorActionPreference = "Stop" -$global:InteractiveMode = $InteractiveMode -$EXITCODE = 0 -$sortRegex = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20) }) } - - -# Scripts & Configs -$scriptPath = Split-Path $MyInvocation.MyCommand.Path -$packageRootFolder = Resolve-Path (Join-Path $scriptPath '..') # change to match package root folder -$cmfInstallActionsFolder = "$packageRootFolder\CMFInstallActions" -$runMasterDataScript = "$cmfInstallActionsFolder\InvokeMasterData.ps1" -$runAppInstallScript = "$cmfInstallActionsFolder\AppInstall.ps1" -$jsonConfigFilePath = "$packageRootFolder\EnvironmentConfigs\$EnvironmentConfigName.json" - -# Load Module with CMF Install Actions and Environment configuration -Import-Module $cmfInstallActionsFolder\CMFInstallActions.psd1 -$env = (Get-CMFEnvironment -environmentConfigPath $jsonConfigFilePath -cmfInstallActionsPath $cmfInstallActionsFolder) - -$customizationVersion = ParseYamlVariables -File "$packageRootFolder\EnvironmentConfigs\GlobalVariables.yml" -VariableName "CurrentPackage" -$releaseID = "Release $customizationVersion" -$backupIdentifier = 'BeforePackage_' + $customizationVersion - -# Business -$businessFolder = "$packageRootFolder\Business" -$backupBusinessTier = ($RunAppInstall -and (Test-Path -Path "$businessFolder")) - -# HTML -$htmlFolder = "$packageRootFolder\UI\HTML" -$backupUIHtml = ($RunAppInstall -and (Test-Path -Path "$htmlFolder")) - -# Help -$helpFolder = "$packageRootFolder\UI\Help" -$backupUIHelp = ($RunAppInstall -and (Test-Path -Path "$helpFolder")) - -# DeeRules -$deeRulesFolder = "$packageRootFolder\DeeRules" - -# ProcessRules -$processRulesFolder = "$deeRulesFolder\ProcessRules" -$processRulesFolderEntityTypes = "$processRulesFolder\EntityTypes" - -# Powershell -$powershellFolder = "$packageRootFolder\Powershell" - -# MasterData -$masterDataFolder = "$packageRootFolder\MasterData" - -# ExportedObjects -$exportedObjectsFolder = "$packageRootFolder\ExportedObjects" - -# Database -$databaseFolder = "$packageRootFolder\Database" -$databaseFolderOnline = "$databaseFolder\Online"; -$databaseFolderODS= "$databaseFolder\ODS"; -$databaseFolderDWH= "$databaseFolder\DWH"; - -# Reports -$reportsFolder = "$packageRootFolder\Reports" - -# MasterDataFiles -$automationWorkflowFilesFolder = "AutomationWorkflowFiles" -$checklistImageFilesFolder = "ChecklistImages" -$exportedObjectsMDFolder = "ExportedObjects" - -# IoT -$automationCustomPackagesFolder = "$packageRootFolder\AutomationCustomPackages" - -# Defaults Before & After -$before = "Before" -$after = "After" -$plantBefore ="$PlantName\$before" -$plantAfter = "$PlantName\$after" - -try { - LogWrite "CM MES Customization Installation" -ForegroundColor Cyan - LogWrite "------------------------------------" - LogWrite ("Release Package ID > " + $releaseID) - LogWrite ("Customization version > " + $customizationVersion) - LogWrite ("Backup Identifier > " + $BackupIdentifier) - LogWrite "------------------------------------" - - LogWrite "Script Input Parameters" -ForegroundColor Cyan - LogWrite "------------------------------------" - LogWrite ("EnvironmentConfigName: $EnvironmentConfigName") - LogWrite ("InteractiveMode: $InteractiveMode") - LogWrite ("Global.InteractiveMode: $global:InteractiveMode") - LogWrite ("PlantName: $PlantName") - LogWrite ("BackupBefore: $BackupBefore") - LogWrite ("RunAppInstall: $RunAppInstall") - LogWrite "------------------------------------" - - $DoBackup = $BackupBefore - if ($env:IsBackupDone) { - if ($env:IsBackupDone -eq $true) { - $DoBackup = $false - $BackupBefore = $false; - } - } - - if($DoBackup -eq $true) - { - $systemBackupPSExpression = "& '$packageRootFolder\DeploymentTools\SystemBackup.ps1' " + - "-EnvironmentConfigName '$EnvironmentConfigName' " + - "-backupIdentifier '$backupIdentifier' " + - "-InteractiveMode:$" + $InteractiveMode + " " + - "-FullBackup:$" + "$false " + - "-BackupDBOnline " + - "-BackupDBODS " + - "-BackupDBDWH " + - "-BackupBusinessTier:$" + "$BackupBusinessTier " + - "-BackupUIHtml:$" + "$BackupUIHtml " + - "-BackupUIHelp:$" + "$BackupUIHelp " + - "-backupBasedOnDeliverables" - - Invoke-Expression $systemBackupPSExpression - } - else - { - LogWrite "Backup skipped as it was done in a previous step of the execution thread" -foregroundColor Yellow - } - - Get-MDLDependencies $env - - # Disable perform transformations on host configuration files - Install-CMFBusinessConfigTransformation $env -transformFile "$cmfInstallActionsFolder\DownTimeConfig.xdt" - - # Disabling ERP integration if needed - $isERPEnabled = Get-Config $env -configPath '/Cmf/System/Configuration/ERP/IsActive/' - if ($isERPEnabled) - { - $config = New-Config -parentPath '/Cmf/System/Configuration/ERP' -name 'IsActive' -Value 'FALSE' -ValueType 'Boolean' - Set-Config $env $config - } - - ######################################################################################################################### - # Execute load entity types process rules - - if (Test-Path "$processRulesFolderEntityTypes") - { - LogWrite "Executing entity type process rules..." -foregroundColor Green - LoadProcessRules $env "$processRulesFolderEntityTypes" - } - - ################################################################################################################################ - # Execute pre process rules - - if (Test-Path "$processRulesFolder") - { - foreach ($folder in Get-ChildItem $processRulesFolder -Directory | Sort-Object $sortRegex) - { - $processRulesFolderBefore = "$processRulesFolder\" + $folder.Name + "\$before" - if (Test-Path "$processRulesFolderBefore") - { - LogWrite "Executing $folder process rules (pre-deployment)..." -foregroundColor Green - LoadProcessRules $env "$processRulesFolderBefore" - } - - if($PlantName) - { - $processRulesFolderPlantBefore = "$processRulesFolder\" + $folder.Name + "\$plantBefore" - if (Test-Path "$processRulesFolderPlantBefore") - { - LogWrite "Executing $folder process rules (pre-deployment)..." -foregroundColor Green - LoadProcessRules $env "$processRulesFolderPlantBefore" - } - } - } - } - - - ################################################################################################################################################## - # Execute pre powershell scripts - - if (Test-Path "$powershellFolder") - { - foreach ($folder in Get-ChildItem $powershellFolder -Directory | Sort-Object $sortRegex) - { - $powershellFolderBefore = "$powershellFolder\" + $folder.Name + "\$before" - if (Test-Path "$powershellFolderBefore") - { - foreach ($file in Get-ChildItem $powershellFolderBefore -File -Filter '*.ps1') - { - Logwrite "Executing Powershell script $file" -foregroundColor Green - $fileFullPath = "$powershellFolderBefore\$file" - Invoke-Expression "& '$fileFullPath' -EnvironmentConfigName $EnvironmentConfigName" - } - } - - if($PlantName) - { - $powershellFolderPlantBefore = "$powershellFolder\" + $folder.Name + "\$plantBefore" - if (Test-Path "$powershellFolderPlantBefore") - { - foreach ($file in Get-ChildItem $powershellFolderPlantBefore -File -Filter '*.ps1') - { - Logwrite "Executing Powershell script $file" -foregroundColor Green - $fileFullPath = "$powershellFolderPlantBefore\$file" - Invoke-Expression "& '$fileFullPath' -EnvironmentConfigName $EnvironmentConfigName" - } - } - } - } - } - - - - - ###################################################################################################################################### - # Run pre SQL Scripts - - if (Test-Path "$databaseFolder") - { - if (Test-Path $databaseFolderOnline) - { - foreach ($folder in Get-ChildItem $databaseFolderOnline -Directory | Sort-Object $sortRegex) - { - $databaseFolderBefore = "$databaseFolderOnline\" + $folder.Name + "\$before" - if(Test-Path $databaseFolderBefore) - { - LogWrite ("Executing Online DB scripts from $databaseFolderBefore") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'Online' -folderPath $databaseFolderBefore - } - - if($PlantName) - { - $databaseFolderPlantBefore = "$databaseFolderOnline\" + $folder.Name + "\$plantBefore" - if(Test-Path $databaseFolderPlantBefore) - { - LogWrite ("Executing Online DB scripts from $databaseFolderPlantBefore") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'Online' -folderPath $databaseFolderPlantBefore - } - } - } - } - - if (Test-Path "$databaseFolderODS") - { - foreach ($folder in Get-ChildItem $databaseFolderODS -Directory | Sort-Object $sortRegex) - { - $databaseFolderBefore = "$databaseFolderODS\" + $folder.Name + "\$before" - if(Test-Path "$databaseFolderBefore") - { - LogWrite ("Executing ODS DB scripts from $databaseFolderBefore") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'ODS' -folderPath $databaseFolderBefore - } - - if($PlantName) - { - $databaseFolderPlantBefore = "$databaseFolderODS\" + $folder.Name + "\$plantBefore" - if(Test-Path "$databaseFolderPlantBefore") - { - LogWrite ("Executing ODS DB scripts from $databaseFolderPlantBefore") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'ODS' -folderPath $databaseFolderPlantBefore - } - } - } - } - - if (Test-Path "$databaseFolderDWH") - { - foreach ($folder in Get-ChildItem $databaseFolderDWH -Directory | Sort-Object $sortRegex) - { - $databaseFolderBefore = "$databaseFolderDWH\" + $folder.Name + "\$before" - if(Test-Path "$databaseFolderBefore") - { - LogWrite ("Executing DWH DB scripts from $databaseFolderBefore") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'DWH' -folderPath $databaseFolderBefore - } - - if($PlantName) - { - $databaseFolderPlantBefore = "$databaseFolderDWH\" + $folder.Name + "\$plantBefore" - if(Test-Path "$databaseFolderPlantBefore") - { - LogWrite ("Executing DWH DB scripts from $databaseFolderPlantBefore") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'DWH' -folderPath $databaseFolderPlantBefore - } - } - } - } - } - - ########################################################################################################################## - # Run IoT Packages Deploy - if (Test-Path "$automationCustomPackagesFolder") - { - IoTPackages-Deploy $env $packageRootFolder - } - - ######################################################################################################################################### - # Run Master Data - - if (Test-Path "$masterDataFolder") - { - # If no DEERulesFolder exists the variable will be empty - if(Test-Path "$deeRulesFolder") - { - $deeRulesFolderPath = "$deeRulesFolder"; - } - - foreach ($f in Get-ChildItem $masterDataFolder -Directory | Sort-Object $sortRegex) - { - $folder = $f.FullName - - # If no AutomationWorkFlowFiles exists the variable will be empty - if (Test-Path "$folder\$automationWorkflowFilesFolder") - { - $automationWorkflowFilesBasePath = "$folder\$automationWorkflowFilesFolder" - } - - # If no ChecklistImageFiles exists the variable will be empty - if(Test-Path "$folder\$checklistImageFilesFolder") - { - $checklistImageFilesBasePath = "$folder\$checklistImageFilesFolder" - } - - # If no ExportedObjects exists the variable will be empty - if(Test-Path "$folder\$exportedObjectsMDFolder") - { - $exportedObjectsMDBasePath = "$folder\$exportedObjectsMDFolder" - } - - $runMasterDataPSExpression = "& '$runMasterDataScript'" + - " -EnvironmentConfigName '$EnvironmentConfigName'" + - " -MasterDataFolderPath '$folder'" + - " -DeeRulesPath '$deeRulesFolderPath'" + - " -AutomationWorkflowFilesPath '$automationWorkflowFilesBasePath'" + - " -ChecklistImageFilesPath '$checklistImageFilesBasePath'" + - " -ExportedObjectsFilesPath '$exportedObjectsMDBasePath'" + - " -ExecuteAsSubScript" + - " -InteractiveMode:$" + $InteractiveMode - Invoke-Expression $runMasterDataPSExpression - - $plantFolder = "$folder\$PlantName" - if($PlantName -and (Test-Path $plantFolder)) - { - # If no ChecklistImageFiles exists the variable will be empty - if(Test-Path "$plantFolder\$checklistImageFilesFolder") - { - $checklistImageFilesBasePath = "$plantFolder\$checklistImageFilesFolder" - } - - # If no ExportedObjects exists the variable will be empty - if(Test-Path "$plantFolder\$exportedObjectsMDFolder") - { - $exportedObjectsMDBasePath = "$plantFolder\$exportedObjectsMDFolder" - } - - $runMasterDataPSExpression = "& '$runMasterDataScript'" + - " -EnvironmentConfigName '$EnvironmentConfigName'" + - " -MasterDataFolderPath '$plantFolder'" + - " -DeeRulesPath '$deeRulesFolderPath'" + - " -AutomationWorkflowFilesPath '$automationWorkflowFilesBasePath'" + - " -ChecklistImageFilesPath '$checklistImageFilesBasePath'" + - " -ExportedObjectsFilesPath '$exportedObjectsMDBasePath'" + - " -ExecuteAsSubScript" + - " -InteractiveMode:$" + $InteractiveMode - Invoke-Expression $runMasterDataPSExpression - } - } - } - - ########################################################################################################################## - # Run post SQL Scripts - - if (Test-Path "$databaseFolder") - { - if (Test-Path "$databaseFolderOnline") - { - foreach ($folder in Get-ChildItem $databaseFolderOnline -Directory | Sort-Object $sortRegex) - { - $databaseFolderAfter = "$databaseFolderOnline\" + $folder.Name + "\$after" - if(Test-Path "$databaseFolderAfter") - { - LogWrite ("Executing Online DB scripts from $databaseFolderAfter") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'Online' -folderPath $databaseFolderAfter - } - - if($PlantName) - { - $databaseFolderPlantAfter = "$databaseFolderOnline\" + $folder.Name + "\$plantAfter" - if(Test-Path "$databaseFolderPlantAfter") - { - LogWrite ("Executing Online DB scripts from $databaseFolderPlantAfter") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'Online' -folderPath $databaseFolderPlantAfter - } - } - } - } - - if (Test-Path "$databaseFolderODS") - { - foreach ($folder in Get-ChildItem $databaseFolderODS -Directory | Sort-Object $sortRegex) - { - $databaseFolderAfter = "$databaseFolderODS\" + $folder.Name + "\$after" - if(Test-Path "$databaseFolderAfter") - { - LogWrite ("Executing ODS DB scripts from $databaseFolderAfter") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'ODS' -folderPath $databaseFolderAfter - } - - if($PlantName) - { - $databaseFolderPlantAfter = "$databaseFolderODS\" + $folder.Name + "\$plantAfter" - if(Test-Path "$databaseFolderPlantAfter") - { - LogWrite ("Executing ODS DB scripts from $databaseFolderPlantAfter") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'ODS' -folderPath $databaseFolderPlantAfter - } - } - } - } - - if (Test-Path "$databaseFolderDWH") - { - foreach ($folder in Get-ChildItem $databaseFolderDWH -Directory | Sort-Object $sortRegex) - { - $databaseFolderAfter = "$databaseFolderDWH\" + $folder.Name + "\$after" - if(Test-Path "$databaseFolderAfter") - { - LogWrite ("Executing DWH DB scripts from $databaseFolderAfter") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'DWH' -folderPath $databaseFolderAfter - } - - if($PlantName) - { - $databaseFolderPlantAfter = "$databaseFolderDWH\" + $folder.Name + "\$plantAfter" - if(Test-Path "$databaseFolderPlantAfter") - { - LogWrite ("Executing DWH DB scripts from $databaseFolderAfter") -foregroundColor Green - Invoke-PackageSqlScripts $env -database 'DWH' -folderPath $databaseFolderAfter - } - } - } - } - - # Restart host - Stop-NavigoHosts $env -disableNLBManagement - Start-NavigoHosts $env -disableNLBManagement - } - - ################################################################################################################################################## - # Execute post powershell scripts - - if (Test-Path "$powershellFolder") - { - foreach ($folder in Get-ChildItem $powershellFolder -Directory | Sort-Object $sortRegex) - { - $powershellFolderAfter = "$powershellFolder\" + $folder.Name + "\$after" - if (Test-Path "$powershellFolderAfter") - { - foreach ($file in Get-ChildItem $powershellFolderAfter -File -Filter '*.ps1') - { - Logwrite "Executing Powershell script $file" -foregroundColor Green - $fileFullPath = "$powershellFolderAfter\$file" - Invoke-Expression "& '$fileFullPath' -EnvironmentConfigName $EnvironmentConfigName" - } - } - - if($PlantName) - { - $powershellFolderPlantAfter = "$powershellFolder\" + $folder.Name + "\$plantAfter" - if (Test-Path "$powershellFolderPlantAfter") - { - foreach ($file in Get-ChildItem $powershellFolderPlantAfter -File -Filter '*.ps1') - { - Logwrite "Executing Powershell script $file" -foregroundColor Green - $fileFullPath = "$powershellFolderPlantAfter\$file" - Invoke-Expression "& '$fileFullPath' -EnvironmentConfigName $EnvironmentConfigName" - } - } - } - } - } - - ################################################################################################################################ - # Execute post process rules - - if (Test-Path "$processRulesFolder") - { - foreach ($folder in Get-ChildItem "$processRulesFolder" -Directory | Sort-Object $sortRegex) - { - $processRulesFolderAfter = "$processRulesFolder\" + $folder.Name + "\$after" - if (Test-Path "$processRulesFolderAfter") - { - LogWrite "Executing $folder process rules (post-deployment)..." -foregroundColor Green - LoadProcessRules $env "$processRulesFolderAfter" - } - - if($PlantName) - { - $processRulesFolderPlantAfter = "$processRulesFolder\" + $folder.Name + "\$plantAfter" - if (Test-Path "$processRulesFolderPlantAfter") - { - LogWrite "Executing $folder process rules (post-deployment)..." -foregroundColor Green - LoadProcessRules $env "$processRulesFolderPlantAfter" - } - } - } - } - - ########################################################################################################################## - # Import Exported Objects - - if (Test-Path "$exportedObjectsFolder") - { - foreach ($f in Get-ChildItem "$exportedObjectsFolder" -Directory | Sort-Object $sortRegex) - { - $folder = $f.FullName - Import-NavigoObjects $env "$folder" -securityToken "customImport" - - $plantFolder = "$folder\$PlantName" - if($PlantName -and (Test-Path $plantFolder)) - { - Import-NavigoObjects $env "$plantFolder" -securityToken "customImport" - } - } - } - - ########################################################################################################################## - # Deploy Reports & Resources in Report Server - - if(Test-Path $reportsFolder) - { - foreach ($f in Get-ChildItem "$reportsFolder" -Directory | Sort-Object $sortRegex) - { - $folder = $f.FullName - Install-ReportsInFolder -env $env -folderPath "$folder" - - $plantFolder = "$folder\$PlantName" - if($PlantName -and (Test-Path $plantFolder)) - { - Install-ReportsInFolder -env $env -folderPath "$plantFolder" - } - } - } - - - ########################################################################################################################## - - LogWrite "Executing host configuration file transformation to $cmfInstallActionsFolder\UpTimeConfig.xdt" -foregroundColor Green - Install-CMFBusinessConfigTransformation $env -transformFile "$cmfInstallActionsFolder\UpTimeConfig.xdt" - - # Enabling ERP integration - if ($isERPEnabled) - { - $config = New-Config -parentPath '/Cmf/System/Configuration/ERP' -name 'IsActive' -Value 'TRUE' -ValueType 'Boolean' - Set-Config $env $config - } - - #LogWrite "Updating customization version" - #Set-CustomizationVersion $env -version $customizationVersion - - #LogWrite "Starting and stopping hosts to ensure all configurations are reloaded" - #Stop-NavigoHosts $env -disableNLBManagement - #Start-NavigoHosts $env -disableNLBManagement - - # Generate LBOs - #LogWrite "Generating LBOs..." -foregroundColor Green - #Update-LightBusinessObjects $env -isToGenerateWCF $false - - LogWrite "`n >> INSTALLATION COMPLETE`n" -foregroundColor Green -backgroundColor DarkGreen - - $EXITCODE = 0 - -} - -catch -{ - $ErrorMessage = $_.Exception.Message - LogWrite (" ! " + $ErrorMessage) -ForegroundColor Red - - $restoreSystem = $true - if ($global:InteractiveMode -eq "" -Or $global:InteractiveMode -eq $true) - { - Write-host " Rollback system to " $backupIdentifier "?" - Write-Host " Rollback [r]" -ForegroundColor Yellow -NoNewline - Write-Host " Bypass rollback [b]: " -NoNewline - - $confirmation = Read-Host - - $restoreSystem = ( $confirmation -ne 'b' ) - } - - if ( $BackupBefore -and $restoreSystem ) - { - LogWrite (" !! Installation Aborted!") -ForegroundColor Red -backgroundColor DarkRed - LogWrite "`n * Initiating rollback..." -ForegroundColor Yellow - - Stop-NavigoHosts $env - - $systemRestorePSExpression = "& '$PackageRootFolder\DeploymentTools\SystemRestore.ps1' " + - "-EnvironmentConfigName '$EnvironmentConfigName' " + - "-backupIdentifier 'DoNotBackup' " + - "-restoreIdentifier '$backupIdentifier' " + - "-InteractiveMode:$" + $InteractiveMode + " " + - "-FullRestore:$" + "$false " + - "-RestoreDBOnline " + - "-RestoreDBODS " + - "-RestoreDBDWH " + - "-RestoreBusinessTier:$" + "$backupBusinessTier " + - "-RestoreUIHtml:$" + "$backupUIHtml " + - "-RestoreUIHelp:$" + "$backupUIHelp " - - Invoke-Expression $systemRestorePSExpression - - Start-NavigoHosts $env - - LogWrite "`n >> Rollback complete!`n" -foregroundColor Black -backgroundColor Yellow - } - - $EXITCODE = 1 -} -finally -{ - Remove-Module CMFInstallActions -} -Exit $EXITCODE \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/DownTimeConfig.xdt b/cmf-cli/installDependencies/Data/CMFInstallActions/DownTimeConfig.xdt deleted file mode 100644 index 46e5bd81b..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/DownTimeConfig.xdt +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/EnvironmentConfigParser.ps1 b/cmf-cli/installDependencies/Data/CMFInstallActions/EnvironmentConfigParser.ps1 deleted file mode 100644 index 84ed2496c..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/EnvironmentConfigParser.ps1 +++ /dev/null @@ -1,194 +0,0 @@ -param( - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$ConfigFilePath, - [string]$ReferencesDir = "..\CMFInstallActions\References\" -) -if(Test-Path $ConfigFilePath) -{ - $configJson = Get-Content $ConfigFilePath | ConvertFrom-Json - - $env = New-CMFEnvironment $configJson.'Product.SystemName' - - # Decrypt-Encrypt All Passwords - # Load DLL that contains the methods to decrypt the passwords of the parameter file - $ScriptPath = Split-Path $MyInvocation.MyCommand.Path - [void][System.Reflection.Assembly]::LoadFile("$ReferencesDir\Cmf.Encrypt.Utils.dll") - $encrypter = New-Object Cmf.Encrypt.Utils.EncryptionService - - $AdminPass = ""; - if ([string]::IsNullOrEmpty($AdminPass)) { - $AdminPass = $configJson.'Product.ApplicationServer.ServiceUser.Password' - # Some parameter files have the passwords already decrypted - $AdminPass = $encrypter.DecryptIfNeeded($AdminPass) - } - - $SQLOnlinePassword = ""; - if ([string]::IsNullOrEmpty($SQLOnlinePassword)) { - $SQLOnlinePassword = $configJson.'Package[Product.Database.Online].Database.Password' - # Some parameter files have the passwords already decrypted - $SQLOnlinePassword = $encrypter.DecryptIfNeeded($SQLOnlinePassword) - } - - $SQLODSPassword = ""; - if ([string]::IsNullOrEmpty($SQLODSPassword)) { - $SQLODSPassword = $configJson.'Package[Product.Database.Ods].Database.Password' - # Some parameter files have the passwords already decrypted - $SQLODSPassword = $encrypter.DecryptIfNeeded($SQLODSPassword) - } - - $SQLDWHPassword = ""; - if ([string]::IsNullOrEmpty($SQLDWHPassword)) { - $SQLDWHPassword = $configJson.'Package[Product.Database.Dwh].Database.Password' - # Some parameter files have the passwords already decrypted - $SQLDWHPassword = $encrypter.DecryptIfNeeded($SQLDWHPassword) - } - - $env.NLBAddress = $configJson.'Product.ApplicationServer.Address' - $env.UseSSL = $false # $configJson.'Product.Presentation.IisConfiguration.Binding.IsSslEnabled' - - $env.ReadPasswordToSignGeneratedLBOs = $false # How to get this? - $env.GenerateErpCustomManagement = $false # How to get this? - - $env.ServicePort = $configJson.'Product.ApplicationServer.Port' - $env.ClientTenantName = $configJson.'Product.Tenant.Name' - - # Backups will use the following structure - # BackupLocation \ BackupIdentifier \ Database-BackupIdentifier.bak - # BackupLocation \ BackupIdentifier \ ServerName-BackupFolder-BackupIdentifier.zip - $env.BackupLocation = $configJson.'Product.Database.BackupShare' - - #### #### #### #### #### #### - #### Application Servers #### - #### #### #### #### #### #### - - # New-CMFServer 'ServerName' 'InstallationPath' - # To Enable Autentication on the servers the following commands should be run on the servers - # This allows the server to delegate credentials to all domain PCs, - # Enable-WSManCredSSP -Role "Client" -DelegateComputer "*.CMF.CRITICALMANUFACTURING.COM" - # This allows the server to receive the credentials - # Enable-WSManCredSSP -Role "Server" - $InstallationPath = $configJson.'Packages.Root.TargetDirectory' - $env.ApplicationServers += New-CMFServer $env.NLBAddress $InstallationPath - - $env.AdminUser = $configJson.'Product.ApplicationServer.ServiceUser.UserName' - # To cypher the password, please run the following commands in powershell, Remove the break lines of the result - # Import-Module \CMFInstallActions\CMFInstallActions.psm1 - # Get-EncryptedStringFromClearText "ClearTextPassword" - $env.AdminPass = Get-EncryptedStringFromClearText $AdminPass - - $env.TemporaryFileShare = $configJson.'Product.DocumentManagement.TemporaryFolder' - - #### #### #### #### #### #### - #### Database Servers #### - #### #### #### #### #### #### - - $alwaysOn = if($configJson.'Product.Database.IsAlwaysOn' -eq 'True') { $true } else { $false }; - $env.OnlineClusterInstance = $configJson.'Package[Product.Database.Online].Database.Server' - $env.OnlineClusterAlwaysOn = $alwaysOn - $env.ODSClusterInstance = $configJson.'Package[Product.Database.Ods].Database.Server' - $env.ODSClusterAlwaysOn = $alwaysOn - $env.DWHClusterInstance = $configJson.'Package[Product.Database.Dwh].Database.Server' - $env.DWHClusterAlwaysOn = $alwaysOn - - # $true if windows authentication ; $false for not use - $env.SQLOnlineWindowsAuthentication = $false - # The user to access to online DB. - $env.SQLOnlineUser = $configJson.'Package[Product.Database.Online].Database.User' - # Read-SQLPassword $env.OnlineClusterInstance $env.SQLOnlineUser - $env.SQLOnlinePassword = Get-EncryptedStringFromClearText $SQLOnlinePassword - # $true if windows authentication ; $false for not use - $env.SQLODSWindowsAuthentication = $false - $env.SQLODSUser = $configJson.'Package[Product.Database.Ods].Database.User' - $env.SQLODSPassword = Get-EncryptedStringFromClearText $SQLODSPassword - # $true if windows authentication ; $false for not use - $env.SQLDWHWindowsAuthentication = $false - $env.SQLDWHUser = $configJson.'Package[Product.Database.Dwh].Database.User' - $env.SQLDWHPassword = Get-EncryptedStringFromClearText $SQLDWHPassword - $env.SQLBackupCompression = $true - - if($alwaysOn) - { - # Get Replicas - - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ReferencesDir\Microsoft.SqlServer.BatchParser.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ReferencesDir\Microsoft.SqlServer.SqlClrProvider.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ReferencesDir\Microsoft.SqlServer.Smo.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ReferencesDir\Microsoft.SqlServer.ConnectionInfo.dll)) | Out-Null - [System.Reflection.Assembly]::LoadFrom((Resolve-Path $ReferencesDir\Microsoft.SqlServer.Management.Sdk.Sfc.dll)) | Out-Null - - $commandText += "SELECT DISTINCT r.replica_server_name as Name" - $commandText += " FROM sys.availability_replicas r" - $commandText += " INNER JOIN sys.availability_groups ags" - $commandText += " ON ags.group_id = r.group_id" - - #Online - - $srv = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $env.OnlineClusterInstance - $srv.ConnectionContext.DatabaseName = $env.SystemName - $srv.ConnectionContext.LoginSecure = $False - $srv.ConnectionContext.Login = $env.SQLOnlineUser - $srv.ConnectionContext.Password = $SQLOnlinePassword - - $onlineResult = $srv.ConnectionContext.ExecuteWithResults($commandText) - - foreach ($row in $onlineResult.Tables[0].Rows) - { - $env.OnlineReplicas += "$($row.Name)"; - } - - $srv.ConnectionContext.Disconnect() - - #ODS - - $srv = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $env.OdsClusterInstance - $srv.ConnectionContext.DatabaseName = $env.SystemName + 'ODS' - $srv.ConnectionContext.LoginSecure = $False - $srv.ConnectionContext.Login = $env.SQLODSUser - $srv.ConnectionContext.Password = $SQLODSPassword - - $odsResult = $srv.ConnectionContext.ExecuteWithResults($commandText) - - foreach ($row in $odsResult.Tables[0].Rows) - { - $env.ODSReplicas += "$($row.Name)"; - } - - $srv.ConnectionContext.Disconnect() - - #DWH - - $srv = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $env.DwhClusterInstance - $srv.ConnectionContext.DatabaseName = $env.SystemName + 'DWH' - $srv.ConnectionContext.LoginSecure = $False - $srv.ConnectionContext.Login = $env.SQLDWHUser - $srv.ConnectionContext.Password = $SQLDWHPassword - - $dwhResult = $srv.ConnectionContext.ExecuteWithResults($commandText) - - foreach ($row in $dwhResult.Tables[0].Rows) - { - $env.DWHReplicas += "$($row.Name)"; - } - - $srv.ConnectionContext.Disconnect() - } - - - # Define if different backup locations for the different databases are required. - $env.OnlineBackupLocation = $env.BackupLocation - $env.ODSBackupLocation = $env.BackupLocation - $env.DWHBackupLocation = $env.BackupLocation - - # ReportServer Configuration - $env.ReportServerUri = $configJson.'Package.ReportingServices.Address' #The Uri to the ReportServer - $env.ReportUseDefaultCredential = $true #$true if windows authentication ; $false for not use - # $env.ReportServerUser = '«CMFUser»' # The user to access to reporting services. - # $env.ReportServerPassword = '«CMFUser»' # The password to access to reporting services - - return $env -} -else -{ - throw "File $($ConfigFilePath) not found..." -} \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/InvokeMasterData.ps1 b/cmf-cli/installDependencies/Data/CMFInstallActions/InvokeMasterData.ps1 deleted file mode 100644 index 324bc256e..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/InvokeMasterData.ps1 +++ /dev/null @@ -1,122 +0,0 @@ -# Powershell script to load CM master data -# Author: Oscar Martins -# Last Modified by: Oscar Martins -# Last Modified on: 10/05/2017 -# -------------------------------------------------------------------------- -param( - [string]$EnvironmentConfigName, - [switch]$InteractiveMode = $False, - [string]$MasterDataFilePath, - [string]$MasterDataFolderPath, - [string]$DeeRulesPath, - [string]$AutomationWorkflowFilesPath, - [string]$ChecklistImageFilesPath, - [string]$ExportedObjectsFilesPath, - [switch]$ExecuteAsSubScript -) - -if ([string]::IsNullOrWhiteSpace($EnvironmentConfigName)) { - throw "Missing mandatory parameter: EnvironmentConfigName" -} - -################################################ -# Variables - -$ErrorActionPreference = "Stop" -$global:InteractiveMode = $InteractiveMode -$EXITCODE = 0 - - -# Scripts & Configs -$scriptPath = Split-Path $MyInvocation.MyCommand.Path -$packageRootFolder = Resolve-Path (Join-Path $scriptPath '..') # change to match package root folder -$cmfInstallActionsFolder = "$packageRootFolder\CMFInstallActions" -$jsonConfigFilePath = "$packageRootFolder\EnvironmentConfigs\$EnvironmentConfigName.json" -$loadedModule = $false - -# Load Module with CMF Install actions and Environment configuration -if (!(Get-Module CMFInstallActions)) { - Import-Module $cmfInstallActionsFolder\CMFInstallActions.psd1 - LogWrite (" * CMFInstallActions module imported") -ForegroundColor Green - - $loadedModule = $true -} - -$env = (Get-CMFEnvironment -environmentConfigPath $jsonConfigFilePath -cmfInstallActionsPath $cmfInstallActionsFolder) - -if ($loadedModule) { - Get-MDLDependencies $env -} - -try { - if ( -not $ExecuteAsSubScript ) { - LogWrite "Loading Master Data" -ForegroundColor Cyan - LogWrite "------------------------------------" - LogWrite "Script Input Parameters" -ForegroundColor Cyan - LogWrite "------------------------------------" - LogWrite ("MasterDataFilePath: $MasterDataFilePath" ) - LogWrite ("MasterDataFolderPath: $MasterDataFolderPath" ) - LogWrite ("DeeRulesPath: $DeeRulesPath" ) - LogWrite ("AutomationWorkflowFilesPath: $AutomationWorkflowFilesPath" ) - LogWrite ("ChecklistImageFilesPath: $ChecklistImageFilesPath" ) - LogWrite ("ExportedObjectsFilesPath: $ExportedObjectsFilesPath" ) - LogWrite ("EnvironmentConfigName: $EnvironmentConfigName") - LogWrite ("InteractiveMode: $InteractiveMode") - LogWrite ("Global.InteractiveMode: $($global:InteractiveMode)") - LogWrite "------------------------------------" - } - - if ($AutomationWorkflowFilesPath -and (Test-Path ("$AutomationWorkflowFilesPath"))) { - $automationWorkflowFilesBasePath = "$AutomationWorkflowFilesPath" - } - - if ($ChecklistImageFilesPath -and (Test-Path ("$ChecklistImageFilesPath"))) { - $checklistImageFilesBasePath = "$ChecklistImageFilesPath" - } - - if ($ExportedObjectsFilesPath -and (Test-Path ("$ExportedObjectsFilesPath"))) { - $exportedObjectsFilesBasePath = "$ExportedObjectsFilesPath" - } - - if ((-not $MasterDataFolderPath) -and (-not $MasterDataFilePath)) { - throw 'One of the following parameters are mandatory: MasterDataFilePath or MasterDataFolderPath' - } - - # Run master data by folder - if ($MasterDataFolderPath) { - # Run master data by folder - $output = Invoke-MasterDataLoaderByFolder $env ` - -excelFolder $MasterDataFolderPath ` - -deeBasePath $DeeRulesPath ` - -automationWorkflowFilesBasePath $automationWorkflowFilesBasePath ` - -checklistImageBasePath $checklistImageFilesBasePath ` - -importObjectBasePath $exportedObjectsFilesBasePath - } - else { - # Run master data by file - $output = Invoke-MasterDataLoader $env ` - -excelFile $MasterDataFilePath ` - -deeBasePath $DeeRulesPath ` - -automationWorkflowFilesBasePath $automationWorkflowFilesBasePath ` - -checklistImageBasePath $checklistImageFilesBasePath ` - -importObjectBasePath $exportedObjectsFilesBasePath - } -} -catch { - if ( $ExecuteAsSubScript ) { - throw $_ - } - else { - $ErrorMessage = $_.Exception.Message - LogWrite (" ! " + $ErrorMessage) -ForegroundColor Red - - LogWrite (" !! Installation Aborted!") -ForegroundColor Red -backgroundColor DarkRed - LogWrite "`n * No rollback action taken..." -ForegroundColor Yellow - } -} -finally { - if ( $loadedModule ) { - LogWrite " * CMFInstallActions module removed" -ForegroundColor Green - Remove-Module CMFInstallActions - } -} \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Cmf.Encrypt.Utils.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Cmf.Encrypt.Utils.dll deleted file mode 100644 index 4808b65ff..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Cmf.Encrypt.Utils.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.BatchParserClient.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.BatchParserClient.dll deleted file mode 100644 index 357fd21ea..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.BatchParserClient.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.ConnectionInfo.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.ConnectionInfo.dll deleted file mode 100644 index 26e047ac5..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.ConnectionInfo.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.Management.Sdk.Sfc.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.Management.Sdk.Sfc.dll deleted file mode 100644 index f66b7846a..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.Management.Sdk.Sfc.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.Smo.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.Smo.dll deleted file mode 100644 index a5eb987ce..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.Smo.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SmoExtended.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SmoExtended.dll deleted file mode 100644 index 1014d9ced..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SmoExtended.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SqlClrProvider.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SqlClrProvider.dll deleted file mode 100644 index 591883dcf..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SqlClrProvider.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SqlEnum.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SqlEnum.dll deleted file mode 100644 index f5708bc6a..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.SqlServer.SqlEnum.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.Web.XmlTransform.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.Web.XmlTransform.dll deleted file mode 100644 index 9795e4f90..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/Microsoft.Web.XmlTransform.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/appSettings b/cmf-cli/installDependencies/Data/CMFInstallActions/References/appSettings deleted file mode 100644 index 20fb6df2e..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/References/appSettings +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/References/microsoft.sqlserver.batchparser.dll b/cmf-cli/installDependencies/Data/CMFInstallActions/References/microsoft.sqlserver.batchparser.dll deleted file mode 100644 index cc72ce189..000000000 Binary files a/cmf-cli/installDependencies/Data/CMFInstallActions/References/microsoft.sqlserver.batchparser.dll and /dev/null differ diff --git a/cmf-cli/installDependencies/Data/CMFInstallActions/UpTimeConfig.xdt b/cmf-cli/installDependencies/Data/CMFInstallActions/UpTimeConfig.xdt deleted file mode 100644 index 1ea383467..000000000 --- a/cmf-cli/installDependencies/Data/CMFInstallActions/UpTimeConfig.xdt +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/EnvironmentConfigs/DF.json b/cmf-cli/installDependencies/Data/EnvironmentConfigs/DF.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmf-cli/installDependencies/Data/EnvironmentConfigs/GlobalVariables.yml b/cmf-cli/installDependencies/Data/EnvironmentConfigs/GlobalVariables.yml deleted file mode 100644 index ca214883a..000000000 --- a/cmf-cli/installDependencies/Data/EnvironmentConfigs/GlobalVariables.yml +++ /dev/null @@ -1,2 +0,0 @@ -variables: - CurrentPackage: '$(version)' diff --git a/cmf-cli/installDependencies/Data/GenerateLBOs.ps1 b/cmf-cli/installDependencies/Data/GenerateLBOs.ps1 deleted file mode 100644 index 51ae88f67..000000000 --- a/cmf-cli/installDependencies/Data/GenerateLBOs.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -param($installPath, $toolsPath, $step, $hostContext, $cmfExecutionContext, $workingDirectory) - -Write-Host ' Starting LBO Generation ...' - -$installationPath = $cmfExecutionContext.Variables.GetValue("Packages.Root.TargetDirectory").Replace("\", "\\") - -$businessInstallationPath = "$installationPath\BusinessTier" -$protectUnprotectConfigFilePath = "$installationPath\ProtectUnprotectConfigFile" -$lboGeneratorPath = "$installationPath\LBOGenerator" - -$arguments = "/Mode:2 /InstallPath:""$businessInstallationPath""" - -#Unprotect HostConfigFile -Write-Host "Deal with host config file" -Set-Location -Path $protectUnprotectConfigFilePath -Start-Process Cmf.Tools.ProtectUnprotectConfigFile.exe $arguments -Wait - -#REST LBOs -Set-Location -Path $lboGeneratorPath -.\LBOUpdater.ps1 - -$arguments = "/Mode:1 /InstallPath:""$businessInstallationPath""" - -#Unprotect HostConfigFile -Write-Host "Deal with host config file" -Set-Location -Path $protectUnprotectConfigFilePath -Start-Process Cmf.Tools.ProtectUnprotectConfigFile.exe $arguments -Wait - -$filePath = (Get-Item $myinvocation.mycommand.path).DirectoryName.ToString() + "\GenerateLBOs.ps1" - -Remove-Item $filePath -Force -Recurse \ No newline at end of file diff --git a/cmf-cli/installDependencies/Data/RunCustomizationInstallDF.ps1 b/cmf-cli/installDependencies/Data/RunCustomizationInstallDF.ps1 deleted file mode 100644 index fef8425c9..000000000 --- a/cmf-cli/installDependencies/Data/RunCustomizationInstallDF.ps1 +++ /dev/null @@ -1,73 +0,0 @@ -######################################################################################## -# this script uses the information available as deployment variables -# to install a customizationpackage -######################################################################################## -param($installPath, $toolsPath, $step, $hostContext, $cmfExecutionContext, $workingDirectory) - -$TargetDirectory = $cmfExecutionContext.Variables.GetValue("Package[$(packageId)].TargetDirectory") -$SystemName = $cmfExecutionContext.Variables.GetValue("Product.SystemName") -$AdminPass = $cmfExecutionContext.Variables.GetValue("Product.ApplicationServer.ServiceUser.Password") -$SQLOnlinePassword = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Online].Database.Password") -$SQLODSPassword = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Ods].Database.Password") -$SQLDWHPassword = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Dwh].Database.Password") -$NLBAddress = $cmfExecutionContext.Variables.GetValue("Product.ApplicationServer.Address") -$ServicePort = $cmfExecutionContext.Variables.GetValue("Product.ApplicationServer.Port") -$ClientTenantName = $cmfExecutionContext.Variables.GetValue("Product.Tenant.Name") -$BackupLocation = $cmfExecutionContext.Variables.GetValue("Product.Database.BackupShare").Replace("\", "\\") -$InstallationPath = $cmfExecutionContext.Variables.GetValue("Packages.Root.TargetDirectory").Replace("\", "\\") -$AdminUser = $cmfExecutionContext.Variables.GetValue("Product.ApplicationServer.ServiceUser.UserName").Replace("\", "\\") -$AlwaysOn = $cmfExecutionContext.Variables.GetValue("Product.Database.IsAlwaysOn") -$OnlineClusterInstance = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Online].Database.Server").Replace("\", "\\") -$ODSClusterInstance = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Ods].Database.Server").Replace("\", "\\") -$DWHClusterInstance = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Dwh].Database.Server").Replace("\", "\\") -$SQLOnlineUser = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Online].Database.User") -$SQLODSUser = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Ods].Database.User") -$SQLDWHUser = $cmfExecutionContext.Variables.GetValue("Package[Product.Database.Dwh].Database.User") - -cd "$TargetDirectory" - -$dfConfig = @" -{ -"Product.SystemName": "$SystemName", -"Product.ApplicationServer.ServiceUser.Password": "$AdminPass", -"Package[Product.Database.Online].Database.Password": "$SQLOnlinePassword", -"Package[Product.Database.Ods].Database.Password": "$SQLODSPassword", -"Package[Product.Database.Dwh].Database.Password": "$SQLDWHPassword", -"Product.ApplicationServer.Address": "$NLBAddress", -"Product.Presentation.IisConfiguration.Binding.IsSslEnabled": false, -"Product.ApplicationServer.Port": "$ServicePort", -"Product.Tenant.Name": "$ClientTenantName", -"Product.Database.BackupShare": "$BackupLocation", -"Packages.Root.TargetDirectory": "$InstallationPath", -"Product.ApplicationServer.ServiceUser.UserName": "$AdminUser", -"Product.DocumentManagement.TemporaryFolder": "", -"Product.Database.IsAlwaysOn": "$AlwaysOn", -"Package[Product.Database.Online].Database.Server": "$OnlineClusterInstance", -"Package[Product.Database.Ods].Database.Server": "$ODSClusterInstance", -"Package[Product.Database.Dwh].Database.Server": "$DWHClusterInstance", -"Package[Product.Database.Online].Database.User": "$SQLOnlineUser", -"Package[Product.Database.Ods].Database.User": "$SQLODSUser", -"Package[Product.Database.Dwh].Database.User": "$SQLDWHUser" -} -"@ | Out-File "$TargetDirectory\EnvironmentConfigs\DF.json" - - -$EnvironmentConfigName = "DF" -$InteractiveMode = $false -$BaseScriptPath = $TargetDirectory -$RunAppInstall = $false -$BackupBefore = $false -$ScriptPath = "$BaseScriptPath\CMFInstallActions\CustomizationInstall.ps1"; -$ScriptParameters = "-EnvironmentConfigName " + $EnvironmentConfigName +" -InteractiveMode:$" + $InteractiveMode + " -BackupBefore:$" + $BackupBefore + " -RunAppInstall:$" + $RunAppInstall; - -if($PlantName) -{ - $ScriptParameters = $ScriptParameters + " -PlantName " + $PlantName -} - -$command = ("& '$ScriptPath' $ScriptParameters") -Powershell $command -NoNewWindow | Out-Host - -if ($LASTEXITCODE -ne 0) { - throw "Customization Installation Aborted!" -} diff --git a/cmf-cli/installDependencies/IoT/runtimePackages/PublishToDirectory.ps1 b/cmf-cli/installDependencies/IoT/runtimePackages/PublishToDirectory.ps1 deleted file mode 100644 index 3dbe5f49e..000000000 --- a/cmf-cli/installDependencies/IoT/runtimePackages/PublishToDirectory.ps1 +++ /dev/null @@ -1,38 +0,0 @@ -######################################################################################## -# this script uses the information available as deployment variables -# to publish connect IoMT packages to a directory (repository) -######################################################################################## -param($installPath, $toolsPath, $step, $hostContext, $cmfExecutionContext, $workingDirectory) - -$IsPublishToDirectoryEnabled = $cmfExecutionContext.Variables.GetValue("Local.Repository.Directory.Enabled") -if ($IsPublishToDirectoryEnabled -eq $true) { - $SourceDirectory = $installPath - $TargetDirectory = $cmfExecutionContext.Variables.GetValue("Local.Repository.Directory.Location") - $repositoryBuilderScriptFileName = ".rebuildDatabase.ps1" - - # Test source directory - If (-Not (Test-Path $SourceDirectory -pathType container)) { - Write-Error "Could not find packages source directory $($SourceDirectory)." -ErrorAction Stop - } - $packageCount = (Get-ChildItem "$SourceDirectory/*" -Filter "*.tgz").Count; - If ($packageCount -eq 0) { - Write-Error "Could not find packages to copy in the source directory $($SourceDirectory)." -ErrorAction Stop - } - - # Test target directory - If (-Not (Test-Path $TargetDirectory -pathType container)) { - New-Item -ItemType Directory -Force -Path $TargetDirectory - Write-Verbose -Verbose "Created target directory $($TargetDirectory)." - } - - # Copy packages - Copy-item -Force -Recurse -Verbose "$SourceDirectory\*.tgz" -Destination $TargetDirectory - Write-Verbose -Verbose "Successfully copied $($packageCount) packages." - - # Rebuild database on TargetDirectory so that both newer and existing packages(if any) are merged together - Write-Verbose -Verbose "Rebuilding directory content definition in target directory $($TargetDirectory)" - & "$($TargetDirectory)\$($repositoryBuilderScriptFileName)" - -} else { - Write-Verbose -Verbose "Publish to directory repository is not enabled" -} diff --git a/cmf-cli/installDependencies/IoT/runtimePackages/PublishToRepository.bat b/cmf-cli/installDependencies/IoT/runtimePackages/PublishToRepository.bat deleted file mode 100644 index 3d997b087..000000000 --- a/cmf-cli/installDependencies/IoT/runtimePackages/PublishToRepository.bat +++ /dev/null @@ -1,17 +0,0 @@ -@echo off - -set NPM=http://127.0.0.1:4873 -set TAG="IoT_805" -set FORCE= - -rem Uncomment the next line if you plan to deploy over a deployed version -rem set FORCE="--force" - -echo Deploying %TAG% to %NPM%"... - - -call npm adduser --registry %NPM% - -forfiles /m *.tgz /c "cmd /c NPM publish @path --registry %NPM% --tag %TAG% %FORCE%" - -timeout 10 \ No newline at end of file diff --git a/cmf-cli/installDependencies/IoT/runtimePackages/PublishToRepository.ps1 b/cmf-cli/installDependencies/IoT/runtimePackages/PublishToRepository.ps1 deleted file mode 100644 index 9a24b2828..000000000 --- a/cmf-cli/installDependencies/IoT/runtimePackages/PublishToRepository.ps1 +++ /dev/null @@ -1,71 +0,0 @@ -######################################################################################## -# this script uses the information available as deployment variables -# to publish connect IoT packages to local npm repository -######################################################################################## -param($installPath, $toolsPath, $step, $hostContext, $cmfExecutionContext, $workingDirectory) - -$IsPublishToRepositoryEnabled = $cmfExecutionContext.Variables.GetValue("Local.Repository.Server.Enabled") -if ($IsPublishToRepositoryEnabled -eq $true) { - $TargetDirectory = $installPath - $LocalRegistryAddress = $cmfExecutionContext.Variables.GetValue("Local.Repository.Server.Address") - $Tag = $cmfExecutionContext.Variables.GetValue("Publish.Tag") - $UserName = $cmfExecutionContext.Variables.GetValue("Local.Repository.Server.UserName") - $UserPassword = $cmfExecutionContext.Variables.GetValue("Local.Repository.Server.UserPassword") - $UserEmail = $cmfExecutionContext.Variables.GetValue("Local.Repository.Server.UserEmail") - - $NpmServerAddress = $LocalRegistryAddress - $parts = $NpmServerAddress.Split(':') - $machineName = $parts[1].Replace('//','') - $port = $parts[2].Replace('/','') - - If (-Not (Test-Path $TargetDirectory -pathType container)) { - Write-Error "Could not find packages source directory $($TargetDirectory)." -ErrorAction Stop - } - - if ((Test-NetConnection -ComputerName $machineName -Port $port).TcpTestSucceeded -eq $false) { - Write-Error "Could not find $($NpmServerAddress)." -ErrorAction Stop - } - - Write-Verbose -Verbose "Deploying $Tag to $NpmServerAddress..." - - $psi = New-Object System.Diagnostics.ProcessStartInfo; - $psi.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden; - $psi.FileName = "cmd.exe"; #process file - $psi.UseShellExecute = $false; #start the process from it's own executable file - $psi.RedirectStandardInput = $true; #enable the process to read from standard input - - $p = [System.Diagnostics.Process]::Start($psi); - - Start-Sleep -s 2 #wait 2 seconds so that the process can be up and running - - $p.StandardInput.WriteLine("npm adduser --registry $NpmServerAddress"); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for the stdin to be ready to receive input - $p.StandardInput.WriteLine($UserName.ToLowerInvariant()); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for the stdin to be ready to receive input - $p.StandardInput.WriteLine($UserPassword); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for the stdin to be ready to receive input - $p.StandardInput.WriteLine($UserEmail); #StandardInput property of the Process is a .NET StreamWriter object - Start-Sleep -s 2 #wait for adduser command to finish - - Stop-Process -Id $p.Id -Force - $successfullyPublishedPackagesCounter = 0 - $unsuccessfullyPublishedPackagesCounter = 0 - & cd $TargetDirectory - foreach ($package in Get-ChildItem "$TargetDirectory/*" -Filter "*.tgz") { - $result = & npm publish $package --registry $NpmServerAddress --tag $Tag --force - if($LASTEXITCODE -ge 0){ - $successfullyPublishedPackagesCounter++ - }else{ - $unsuccessfullyPublishedPackagesCounter++ - Write-Error "Could not publish package $($package)" - } - if(-not([string]::IsNullOrWhiteSpace($result))) { - Write-Verbose -Verbose $result - } - } - - Write-Verbose -Verbose "Successfully published $($successfullyPublishedPackagesCounter) packages." - Write-Verbose -Verbose "$($unsuccessfullyPublishedPackagesCounter) packages were not published successfully." -} else { - Write-Verbose -Verbose "Publish to npm server repository is not enabled" -} diff --git a/cmf-cli/installDependencies/IoT/runtimePackages/ValidateIoTInstall.ps1 b/cmf-cli/installDependencies/IoT/runtimePackages/ValidateIoTInstall.ps1 deleted file mode 100644 index 6555e2e0b..000000000 --- a/cmf-cli/installDependencies/IoT/runtimePackages/ValidateIoTInstall.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -######################################################################################## -# this script uses the information available as deployment variables -# to validate if at least one of the options is selected -######################################################################################## -param($installPath, $toolsPath, $step, $hostContext, $cmfExecutionContext, $workingDirectory) - -$IsPublishToDirectoryEnabled = $cmfExecutionContext.Variables.GetValue("Local.Repository.Directory.Enabled") -$IsPublishToRepositoryEnabled = $cmfExecutionContext.Variables.GetValue("Local.Repository.Server.Enabled") -if ($IsPublishToDirectoryEnabled -eq $false -and $IsPublishToRepositoryEnabled -eq $false) { - - throw "Publish to directory repository and Publish to directory repository are not enabled" -} \ No newline at end of file diff --git a/cmf-cli/installDependencies/readme.md b/cmf-cli/installDependencies/readme.md deleted file mode 100644 index 679fff54d..000000000 --- a/cmf-cli/installDependencies/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -Here goes all install dependencies for each PackageType -The pack command will pickup all needed files \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/from900/.template.config/template.json b/cmf-cli/resources/template_feed/business/from900/.template.config/template.json index c5beb2c05..a6fa7cb1f 100644 --- a/cmf-cli/resources/template_feed/business/from900/.template.config/template.json +++ b/cmf-cli/resources/template_feed/business/from900/.template.config/template.json @@ -6,9 +6,9 @@ ], "description": "Generate a new business package", "name": "Business Package (> MES 9)", - "identity": "cmf-cli.new.business9", - "groupIdentity": "cmf-cli.new.business9", - "shortName": "business9", + "identity": "cmf-cli.new.business10", + "groupIdentity": "cmf-cli.new.business10", + "shortName": "business10", // You can create the project using this short name instead of the one above. "tags": { "language": "C#", diff --git a/cmf-cli/resources/template_feed/business/upto8x/.template.config/template.json b/cmf-cli/resources/template_feed/business/upto8x/.template.config/template.json deleted file mode 100644 index b226a8bd2..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/.template.config/template.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/template", - "author": "Critical Manufacturing", - "classifications": [ - "cli" - ], - "description": "Generate a new business package", - "name": "Business Package", - "identity": "cmf-cli.new.business", - "groupIdentity": "cmf-cli.new.business", - "shortName": "business", - // You can create the project using this short name instead of the one above. - "tags": { - "language": "C#", - // Specify that this template is in C#. - "type": "project" - }, - "sourceName": "Business.Package", - // Will replace the string 'MyProject.StarterWeb' with the value provided via -n. - "preferNameDirectory": true, - "symbols": { - "name": { - "type": "parameter", - "datatype": "string", - "description": "The custom package name", - "displayName": "Package Name", - "replaces": "<%= $CLI_PARAM_CustomPackageName %>" - }, - "packageVersion": { - "type": "parameter", - "datatype": "string", - "description": "The custom package version", - "displayName": "Package Version", - "replaces": "<%= $CLI_PARAM_CustomPackageVersion %>" - }, - "Tenant": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Tenant %>", - "fileRename": "%Tenant%" - }, - "MESVersion": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_MESVersion %>" - }, - "Product": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Product %>", - "fileRename": "%Product%" - }, - "Organization": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Organization %>", - "fileRename": "%Org%" - }, - "idSegment": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_idSegment %>", - "fileRename": "%idSegment%" - }, - "localEnvRelativePath": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_localEnvRelativePath %>" - }, - "deploymentMetadataRelativePath": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_deploymentMetadataRelativePath %>" - } - } -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Org%.%Product%.%idSegment%.Common.csproj b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Org%.%Product%.%idSegment%.Common.csproj deleted file mode 100644 index 7fc7f961f..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Org%.%Product%.%idSegment%.Common.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - netstandard2.0 - Library - false - false - <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common - <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common - - - <%= $CLI_PARAM_localEnvRelativePath %>\BusinessTier - - - ..\Release - - - - - - - - - - \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Tenant%Constants.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Tenant%Constants.cs deleted file mode 100644 index 201cd9be1..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Tenant%Constants.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common -{ - public class <%= $CLI_PARAM_Tenant %>Constants - { - } -} diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Tenant%Utilities.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Tenant%Utilities.cs deleted file mode 100644 index 60d335db3..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/%Tenant%Utilities.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common -{ - public class <%= $CLI_PARAM_Tenant %>Utilities - { - } -} diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/Properties/AssemblyInfo.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/Properties/AssemblyInfo.cs deleted file mode 100644 index fc8d88c19..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("6c3d698d-7f9e-4e39-a571-deb63582ca52")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/app.config b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/app.config deleted file mode 100644 index 58c01219d..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Common/app.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/%Org%.%Product%.%idSegment%.Orchestration.csproj b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/%Org%.%Product%.%idSegment%.Orchestration.csproj deleted file mode 100644 index 348ecbacf..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/%Org%.%Product%.%idSegment%.Orchestration.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - netstandard2.0 - Library - false - false - <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration - <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration - - - <%= $CLI_PARAM_localEnvRelativePath %>\BusinessTier - - - ..\Release - - - - - \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/%Tenant%Orchestration.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/%Tenant%Orchestration.cs deleted file mode 100644 index 1a57a4282..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/%Tenant%Orchestration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration -{ - public static class <%= $CLI_PARAM_Tenant %>Orchestration - { - private const string OBJECT_TYPE_NAME = "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration.<%= $CLI_PARAM_Tenant %>ManagementOrchestration"; - } -} diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/InputObjects/.gitkeep b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/InputObjects/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/OutputObjects/.gitkeep b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/OutputObjects/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/Properties/AssemblyInfo.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/Properties/AssemblyInfo.cs deleted file mode 100644 index 9994a3637..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4f4342a5-3d64-4d54-b83b-368f768e2a95")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/app.config b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/app.config deleted file mode 100644 index d6e686130..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Orchestration/app.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/%Org%.%Product%.%idSegment%.Services.csproj b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/%Org%.%Product%.%idSegment%.Services.csproj deleted file mode 100644 index 6ee05ed19..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/%Org%.%Product%.%idSegment%.Services.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - netstandard2.0 - Library - false - false - <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services - <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services - - - <%= $CLI_PARAM_localEnvRelativePath %>\BusinessTier - - - ..\Release - - - - - \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/%Tenant%Controller.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/%Tenant%Controller.cs deleted file mode 100644 index d0e21bca1..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/%Tenant%Controller.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace <%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services -{ - /// - /// <%= $CLI_PARAM_Tenant %> Services - /// - [ApiController] - [Route("api/[controller]/[action]")] - public class <%= $CLI_PARAM_Tenant %>Controller : ControllerBase - { - private const string OBJECT_TYPE_NAME = "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services.<%= $CLI_PARAM_Tenant %>Management"; - } -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/Properties/AssemblyInfo.cs b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/Properties/AssemblyInfo.cs deleted file mode 100644 index ad180bd86..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("fa684ab7-3bb6-47cb-acd8-48ca53f2dcef")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/app.config b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/app.config deleted file mode 100644 index c920e93ac..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/%Org%.%Product%.Services/app.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/Business.sln b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/Business.sln deleted file mode 100644 index 563029475..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/Business.sln +++ /dev/null @@ -1,43 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common", "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.Common\<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Common.csproj", "{6C3D698D-7F9E-4E39-A571-DEB63582CA52}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services", "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.Services\<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Services.csproj", "{FA684AB7-3BB6-47CB-ACD8-48CA53F2DCEF}" - ProjectSection(ProjectDependencies) = postProject - {4F4342A5-3D64-4D54-B83B-368F768E2A95} = {4F4342A5-3D64-4D54-B83B-368F768E2A95} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration", "<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.Orchestration\<%= $CLI_PARAM_Organization %>.<%= $CLI_PARAM_Product %>.<%= $CLI_PARAM_idSegment %>.Orchestration.csproj", "{4F4342A5-3D64-4D54-B83B-368F768E2A95}" - ProjectSection(ProjectDependencies) = postProject - {6C3D698D-7F9E-4E39-A571-DEB63582CA52} = {6C3D698D-7F9E-4E39-A571-DEB63582CA52} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6C3D698D-7F9E-4E39-A571-DEB63582CA52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6C3D698D-7F9E-4E39-A571-DEB63582CA52}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6C3D698D-7F9E-4E39-A571-DEB63582CA52}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6C3D698D-7F9E-4E39-A571-DEB63582CA52}.Release|Any CPU.Build.0 = Release|Any CPU - {FA684AB7-3BB6-47CB-ACD8-48CA53F2DCEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA684AB7-3BB6-47CB-ACD8-48CA53F2DCEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA684AB7-3BB6-47CB-ACD8-48CA53F2DCEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA684AB7-3BB6-47CB-ACD8-48CA53F2DCEF}.Release|Any CPU.Build.0 = Release|Any CPU - {4F4342A5-3D64-4D54-B83B-368F768E2A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F4342A5-3D64-4D54-B83B-368F768E2A95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F4342A5-3D64-4D54-B83B-368F768E2A95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F4342A5-3D64-4D54-B83B-368F768E2A95}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9DB2EC4C-B3DB-4A52-9748-BD2E6472D456} - EndGlobalSection -EndGlobal diff --git a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/cmfpackage.json b/cmf-cli/resources/template_feed/business/upto8x/Business.Package/cmfpackage.json deleted file mode 100644 index 348a025f8..000000000 --- a/cmf-cli/resources/template_feed/business/upto8x/Business.Package/cmfpackage.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "packageId": "<%= $CLI_PARAM_CustomPackageName %>", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "description": "<%= $CLI_PARAM_Organization %> <%= $CLI_PARAM_Product %> <%= $CLI_PARAM_Tenant %> <%= $CLI_PARAM_CustomPackageName %> Package", - "packageType": "Business", - "isInstallable": true, - "isUniqueInstall": false, - "contentToPack": [ - { - "source": "Release/*.dll", - "target": "" - } - ] -} diff --git a/cmf-cli/resources/template_feed/help/upTo9x/.template.config/template.json b/cmf-cli/resources/template_feed/help/upTo9x/.template.config/template.json deleted file mode 100644 index b33f08f1f..000000000 --- a/cmf-cli/resources/template_feed/help/upTo9x/.template.config/template.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/template", - "author": "Critical Manufacturing", - "classifications": [ - "cli" - ], - "description": "Generate a new help/documentation package", - "name": "Help Package", - "identity": "cmf-cli.new.help", - "groupIdentity": "cmf-cli.new.help", - "shortName": "help", - // You can create the project using this short name instead of the one above. - "tags": { - "language": "C#", - // Specify that this template is in C#. - "type": "project" - }, - "sourceName": "Help.Package", - // Will replace the string 'MyProject.StarterWeb' with the value provided via -n. - "preferNameDirectory": true, - "symbols": { - "name": { - "type": "parameter", - "datatype": "string", - "description": "The custom package name", - "displayName": "Package Name", - "replaces": "<%= $CLI_PARAM_CustomPackageName %>" - }, - "packageVersion": { - "type": "parameter", - "datatype": "string", - "description": "The custom package version", - "displayName": "Package Version", - "replaces": "<%= $CLI_PARAM_CustomPackageVersion %>", - "fileRename": "%version%" - }, - "Tenant": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Tenant %>", - "fileRename": "%Tenant%" - }, - "idSegment": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_idSegment %>", - "fileRename": "%idSegment%" - }, - "rootRelativePath": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_rootRelativePath %>" - } - } -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/help/upTo9x/Help.Package/.nvmrc b/cmf-cli/resources/template_feed/help/upTo9x/Help.Package/.nvmrc deleted file mode 100644 index 76c257078..000000000 --- a/cmf-cli/resources/template_feed/help/upTo9x/Help.Package/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v12.20.2 diff --git a/cmf-cli/resources/template_feed/help/upTo9x/Help.Package/cmfpackage.json b/cmf-cli/resources/template_feed/help/upTo9x/Help.Package/cmfpackage.json deleted file mode 100644 index 090058113..000000000 --- a/cmf-cli/resources/template_feed/help/upTo9x/Help.Package/cmfpackage.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "packageId": "<%= $CLI_PARAM_CustomPackageName %>", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "description": "Cmf Custom <%= $CLI_PARAM_Tenant %> <%= $CLI_PARAM_CustomPackageName %> Package", - "packageType": "Help", - "isInstallable": true, - "isUniqueInstall": false, - "contentToPack": [ - { - "source": "src/packages/*", - "target": "node_modules", - "ignoreFiles": [ - ".npmignore" - ] - } - ] -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/helpSrcPkg/.template.config/template.json b/cmf-cli/resources/template_feed/helpSrcPkg/.template.config/template.json index 3b4f1d20e..81e2813aa 100644 --- a/cmf-cli/resources/template_feed/helpSrcPkg/.template.config/template.json +++ b/cmf-cli/resources/template_feed/helpSrcPkg/.template.config/template.json @@ -70,30 +70,6 @@ "type": "parameter", "datatype": "string", "replaces": "<%= $CLI_PARAM_DFPackageNamePascalCase %>" - }, - "v10metadata": { - "type": "parameter", - "datatype": "bool", - "defaultValue": false, - "description": "Generates MES v10 metadata if true, v9 if false" - } - }, - "sources": [ - { - "modifiers": [ - { - "condition": "!v10metadata", - "exclude": [ - "Help.Src.Package/metadata/src/lib/**" - ] - }, - { - "condition": "v10metadata", - "exclude": [ - "Help.Src.Package/src/*.ts" - ] - } - ] } - ] + } } \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/helpSrcPkg/Help.Src.Package/src/%packageName%.metadata.ts b/cmf-cli/resources/template_feed/helpSrcPkg/Help.Src.Package/src/%packageName%.metadata.ts deleted file mode 100644 index 09a4af532..000000000 --- a/cmf-cli/resources/template_feed/helpSrcPkg/Help.Src.Package/src/%packageName%.metadata.ts +++ /dev/null @@ -1,116 +0,0 @@ -// #region Import statements - -/** Core */ -import { PackageMetadata, Framework } from 'cmf.core/src/core' -import { MenuItem } from 'cmf.core/src/domain/metadata/menu' - -/** i18n */ -import i18n from './i18n/main.default' - -declare var SystemJS: { import: any } - -// #endregion - -function applyConfig (packageName: string) { - const config: PackageMetadata = { - version: '', - name: `${packageName}`, - components: [ - // Below this line all components are attached automatically during build - // inject:components - // endinject:components - ], - directives: [ - // Below this line all directives are attached automatically during build - // inject:directives - // endinject:directives - ], - pipes: [ - // Below this line all pipes are attached automatically during build - // inject:pipes - // endinject:pipes - ], - i18n: [ - // Below this line all i18n are attached automatically during build - // inject:i18n - // endinject:i18n - ], - widgets: [ - // Below this line all widgets are attached automatically during build - // inject:widgets - // endinject:widgets - ], - dataSources: [ - // Below this line all dataSources are attached automatically during build - // inject:dataSources - // endinject:dataSources - ], - converters: [ - // Below this line all converters are attached automatically during build - // inject:converters - // endinject:converters - ], - metadataLoadedHandler: () => { - // Place here the specific module loader configs to load the dependencies of this package - }, - flex: { - actionButtonGroups: [], - actionButtons: [], - actions: [], - menuGroups: [ - { - position: 2000, - id: 'Shell.<%= $CLI_PARAM_DFPackageName %>', - iconClass: 'icon-docs-st-lg-userguide', - route: '<%= $CLI_PARAM_DFPackageName %>', - itemsGenerator: class MenuGen { - public items (framework: Framework): Promise { - return SystemJS.import('./node_modules/<%= $CLI_PARAM_CustomPackageName %>/assets/__generatedMenuItems.json').then((jsonContent) => { - return jsonContent - }) - } - }.prototype, - title: '<%= $CLI_PARAM_Tenant %>' - }], - menuItems: [ - { - id: '<%= $CLI_PARAM_DFPackageName %>.index', - menuGroupId: 'Shell.<%= $CLI_PARAM_DFPackageName %>', - title: 'Index', - actionId: '' - }, - { - id: '<%= $CLI_PARAM_DFPackageName %>.techspec', - menuGroupId: 'Shell.<%= $CLI_PARAM_DFPackageName %>', - title: 'Technical Specification', - actionId: '' - }, - { - id: '<%= $CLI_PARAM_DFPackageName %>.userguide', - menuGroupId: 'Shell.<%= $CLI_PARAM_DFPackageName %>', - title: 'User Guide', - actionId: '' - }, - { - id: '<%= $CLI_PARAM_DFPackageName %>.releasenotes', - menuGroupId: 'Shell.<%= $CLI_PARAM_DFPackageName %>', - title: 'Release Notes', - actionId: '' - }, - { - id: '<%= $CLI_PARAM_DFPackageName %>.faq', - menuGroupId: 'Shell.<%= $CLI_PARAM_DFPackageName %>', - title: 'FAQ', - actionId: '' - } - ], - entityTypes: [], - routes: [{ - routeConfig: [] - }] - } - } - return config -} - -export default applyConfig diff --git a/cmf-cli/resources/template_feed/html/upto9x/.template.config/template.json b/cmf-cli/resources/template_feed/html/upto9x/.template.config/template.json deleted file mode 100644 index bdfbcd044..000000000 --- a/cmf-cli/resources/template_feed/html/upto9x/.template.config/template.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/template", - "author": "Critical Manufacturing", - "classifications": [ - "cli" - ], - "description": "Generate a new HTML package", - "name": "HTML Package", - "identity": "cmf-cli.new.html", - "groupIdentity": "cmf-cli.new.html", - "shortName": "html", - // You can create the project using this short name instead of the one above. - "tags": { - "language": "C#", - // Specify that this template is in C#. - "type": "project" - }, - "sourceName": "HTML.Package", - // Will replace the string 'MyProject.StarterWeb' with the value provided via -n. - "preferNameDirectory": true, - "symbols": { - "name": { - "type": "parameter", - "datatype": "string", - "description": "The custom package name", - "displayName": "Package Name", - "replaces": "<%= $CLI_PARAM_CustomPackageName %>" - }, - "packageVersion": { - "type": "parameter", - "datatype": "string", - "description": "The custom package version", - "displayName": "Package Version", - "replaces": "<%= $CLI_PARAM_CustomPackageVersion %>", - "fileRename": "%version%" - }, - "Tenant": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Tenant %>", - "fileRename": "%Tenant%" - }, - "Product": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Product %>", - "fileRename": "%Product%" - }, - "Organization": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Organization %>", - "fileRename": "%Org%" - }, - "idSegment": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_idSegment %>", - "fileRename": "%idSegment%" - }, - "rootRelativePath": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_rootRelativePath %>" - }, - "baseWebPackage": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_baseWebPackage %>" - } - } -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/html/upto9x/HTML.Package/.nvmrc b/cmf-cli/resources/template_feed/html/upto9x/HTML.Package/.nvmrc deleted file mode 100644 index 76c257078..000000000 --- a/cmf-cli/resources/template_feed/html/upto9x/HTML.Package/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v12.20.2 diff --git a/cmf-cli/resources/template_feed/html/upto9x/HTML.Package/cmfpackage.json b/cmf-cli/resources/template_feed/html/upto9x/HTML.Package/cmfpackage.json deleted file mode 100644 index ad97e589d..000000000 --- a/cmf-cli/resources/template_feed/html/upto9x/HTML.Package/cmfpackage.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "packageId": "<%= $CLI_PARAM_CustomPackageName %>", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "description": "<%= $CLI_PARAM_Organization %> <%= $CLI_PARAM_Product %> <%= $CLI_PARAM_Tenant %> <%= $CLI_PARAM_CustomPackageName %> Package", - "packageType": "Html", - "isInstallable": true, - "isUniqueInstall": false, - "contentToPack": [ - { - "source": "src/packages/*", - "target": "node_modules", - "ignoreFiles": [ - ".npmignore" - ] - }, - { - "source": "apps/customization.web/node_modules/<%= $CLI_PARAM_baseWebPackage %>/bundles", - "target": "" - }, - { - "source": "<%= $CLI_PARAM_rootRelativePath %>/Libs/LBOs/TypeScript/APIReference*", - "target": "node_modules/cmf.lbos" - }, - { - "source": "<%= $CLI_PARAM_rootRelativePath %>/Libs/LBOs/TypeScript/cmf.lbos.*", - "target": "node_modules/cmf.lbos" - }, - { - "source": "<%= $CLI_PARAM_rootRelativePath %>/Libs/LBOs/TypeScript/package.json", - "target": "node_modules/cmf.lbos" - } - ] -} diff --git a/cmf-cli/resources/template_feed/init/.template.config/template.json b/cmf-cli/resources/template_feed/init/.template.config/template.json index 5455e9562..af8ebda82 100644 --- a/cmf-cli/resources/template_feed/init/.template.config/template.json +++ b/cmf-cli/resources/template_feed/init/.template.config/template.json @@ -638,12 +638,6 @@ "assets/**", "assets/" ] - }, - { - "condition": "MESVersion-Major < 10", - "exclude": [ - ".devcontainer/*" - ] } ] } diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/.template.config/template.json b/cmf-cli/resources/template_feed/iot/upTo9x/.template.config/template.json deleted file mode 100644 index 442015a3d..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/.template.config/template.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/template", - "author": "Critical Manufacturing", - "classifications": [ - "cli" - ], - "description": "Generate a new IoT package", - "name": "IoT Package", - "identity": "cmf-cli.new.iot", - "groupIdentity": "cmf-cli.new.iot", - "shortName": "iot-upto9x", - // You can create the project using this short name instead of the one above. - "tags": { - "language": "C#", - // Specify that this template is in C#. - "type": "project" - }, - "sourceName": "IoT.Package", - // Will replace the string 'MyProject.StarterWeb' with the value provided via -n. - "preferNameDirectory": true, - "symbols": { - "name": { - "type": "parameter", - "datatype": "string", - "description": "The custom package name", - "displayName": "Package Name", - "replaces": "<%= $CLI_PARAM_CustomPackageName %>" - }, - "packageVersion": { - "type": "parameter", - "datatype": "string", - "description": "The custom package version", - "displayName": "Package Version", - "replaces": "<%= $CLI_PARAM_CustomPackageVersion %>", - "fileRename": "%version%" - }, - "Tenant": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_Tenant %>", - "fileRename": "%Tenant%" - }, - "idSegment": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_idSegment %>", - "fileRename": "%idSegment%" - }, - "rootInnerRelativePath": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_rootInnerRelativePath %>" - }, - "DevTasksVersion": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_DevTasksVersion %>" - }, - "npmRegistry": { - "type": "parameter", - "datatype": "string", - "replaces": "<%= $CLI_PARAM_NPMRegistry %>" - }, - "repositoryType": { - "type": "parameter", - "datatype": "string", - "description": "The type of repository this package will be included in", - "displayName": "Repository Type" - } - } -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/AutomationWorkFlows/.gitkeep b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/AutomationWorkFlows/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/MasterData/%version%/.gitkeep b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/MasterData/%version%/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/cmfpackage.json b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/cmfpackage.json deleted file mode 100644 index 95c77f317..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTData/cmfpackage.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "packageId": "<%= $CLI_PARAM_CustomPackageName %>.Data", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "description": "Cmf Custom <%= $CLI_PARAM_Tenant %> <%= $CLI_PARAM_CustomPackageName %>.Data Package", - "packageType": "IoTData", - "isInstallable": true, - "isUniqueInstall": true, - "contentToPack": [ - { - "source": "MasterData/$(version)/*", - "target": "MasterData/$(version)", - "contentType": "MasterData" - }, - { - "source": "AutomationWorkFlows/*", - "target": "AutomationWorkFlows", - "contentType": "AutomationWorkFlows" - } - ] -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/.dev-tasks.json b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/.dev-tasks.json deleted file mode 100644 index 7f3f1e0d5..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/.dev-tasks.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "isWebAppCompilable": false, - "dependencies": [ - ], - "packages": [ - ], - "registry": "<%= $CLI_PARAM_NPMRegistry %>", - "channel": "*" -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/.gitignore b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/.gitignore deleted file mode 100644 index 3a264e904..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/.gitignore +++ /dev/null @@ -1 +0,0 @@ -**/*.tgz \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/cmfpackage.json b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/cmfpackage.json deleted file mode 100644 index aa7f0e035..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/cmfpackage.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "packageId": "<%= $CLI_PARAM_CustomPackageName %>.Packages", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "description": "Cmf Custom <%= $CLI_PARAM_Tenant %> <%= $CLI_PARAM_CustomPackageName %>.Packages Package", - "packageType": "IoT", - "isInstallable": true, - "isUniqueInstall": false, - "contentToPack": [ - { - "source": "src/*", - "target": "node_modules", - "ignoreFiles": [ - ".npmignore" - ] - } - ], - "xmlInjection": [ - "ui.xml" - ] -} diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/gulpfile.js b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/gulpfile.js deleted file mode 100644 index b91c93188..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/gulpfile.js +++ /dev/null @@ -1,203 +0,0 @@ -var gulp = require('gulp'), - rootUtils = require("@criticalmanufacturing/dev-tasks/root.main"), - childProcess = require('child_process'), - pluginRunSequence = require('run-sequence'), - pluginYargs = require('yargs').argv, - _config = require('./.dev-tasks.json'), - _packagesPath = './src/', //note the ending / - _dependenciesPath = './dependencies/', - _framework = _config.framework, - //NOTE: order matters in these arrays! - _dependencies = _config.dependencies, - _packages = _config.packages, - _apps = [`${_config.webAppPrefix}.web`], - tasks = null, - pluginUtil = require('gulp-util'); -applyOps = null; - -if (typeof _framework === "string" && _framework !== "") { - tasks = require("./src/" + _framework + "/gulpfile.js")(gulp, _framework); -} -if (_dependencies != null && _dependencies.length > 0) { - _dependencies.forEach(function (dep) { - require(_dependenciesPath + dep + "/gulpfile.js")(gulp, dep); - }); -} -if (_packages != null && _packages.length > 0) { - _packages.forEach(function (pkg) { - require(_packagesPath + pkg + "/gulpfile.js")(gulp, pkg); - }); -} - -//require(`./apps/${_config.webAppPrefix}.web/gulpfile.js`)(gulp, `${_config.webAppPrefix}.web`); - -applyOps = function (actions) { - if (!Array.isArray(actions)) { actions = [actions]; } - var operations = []; - var dependencyOperations = []; - var packageOperations = []; - if (_dependencies != null && _dependencies.length > 0) { - _dependencies.forEach(function (dep) { - actions.forEach(function (action) { - operations.push(dep + ">" + action); - }); - }); - } - - actions.forEach(function (action) { - if (typeof _framework === "string" && _framework !== "") { - operations.push(_framework + '>' + action); - } - }) - - _packages.forEach(function (mod) { - actions.forEach(function (action) { - operations.push(mod + ">" + action) - }); - }); - - return operations; -}; - -/* - * Build all - */ -gulp.task('build', function (callback) { - if (pluginYargs.server) { - var isWebAppCompilable = true; - rootUtils.runOperation(__dirname, _dependencies, _framework, _packages, _apps, "build", callback, typeof _framework === "string" && _framework !== "", isWebAppCompilable); - } else { - var ops = [] - if (pluginYargs.parallelBuild !== false) { - pluginUtil.log(pluginUtil.colors.yellow(`building in parallel`)); - if (Number.isInteger(pluginYargs.parallelBuild)) { - pluginUtil.log(pluginUtil.colors.yellow(`Using ${pluginYargs.parallelBuild} tasks in parallel`)); - // split in tasks - var opsToSliceArray = applyOps('build'); - for (i = 0; i < opsToSliceArray.length; i += pluginYargs.parallelBuild) { - ops.push(opsToSliceArray.slice(i, i + pluginYargs.parallelBuild)); - } - } else { - // all the tasks at the same time! - ops = [applyOps('build')] - } - } else { - ops = applyOps('build'); - } - // On customized projects we would only require to compile the web if the project defined a framework on their own - var isWebAppCompilable = _config.isWebAppCompilable; - if (isWebAppCompilable === true) { - ops = ops.concat([`${_config.webAppPrefix}.web>build`]); - } - - if (ops.length > 0 && ops[0].length > 0) { - ops = ops.concat(callback); - pluginRunSequence.apply(this, ops); - } else { - callback(); - } - } - -}); - -/* - * start running the tests - */ -gulp.task('cliTest', function (callback) { - - let pkgPromises = _packages.map(pkg => { - return new Promise((resolve, reject) => { - try { - childProcess.execSync("npm run test", { stdio: ['inherit', 'inherit', 'pipe'], cwd: `src\\${pkg}` }); - resolve(); - } catch (e) { - reject(e); - } - }) - }); - - Promise.allSettled(pkgPromises).then((results) => { - - let stacks = ""; - for (const result of results) { - - if (result.status === "rejected" && typeof (result.reason.stderr) != "undefined" && - !result.reason.stderr.toString().includes("Error: No test files found")) { - stacks = stacks + result.reason.stack; - } - } - if (stacks !== "") { - throw new Error(stacks); - } - }); -}); - -/* - * Install all - */ -gulp.task('install', function (callback) { - - if (pluginYargs.server) { - rootUtils.runOperation(__dirname, _dependencies, _framework, _packages, _apps, "install", callback, typeof _framework === "string" && _framework !== "", true); - - } else { - var ops = applyOps(['install']); - - if (ops.length > 0) { - ops = ops.concat(callback); - pluginRunSequence.apply(this, ops); - } else { - callback(); - } - } -}); - -/* - * Install and build apps - */ -gulp.task('apps', function (callback) { pluginRunSequence.apply(this, ['build', `${_config.webAppPrefix}.web>build`, callback]); }); - -/* - * start serving the web app - */ -gulp.task('start', function (callback) { pluginRunSequence(`${_config.webAppPrefix}.web>start`); }); - -/* - * start running the tests - */ -gulp.task('test', function (callback) { pluginRunSequence.apply(this, applyOps('test').concat(callback)); }); - -/* - * clean the workspace - */ -gulp.task('clean', function (callback) { pluginRunSequence.apply(this, applyOps('clean').concat(callback)); }) - -gulp.task('clean-libs', function (callback) { pluginRunSequence.apply(this, applyOps('clean-libs').concat(callback)); }) - -gulp.task('purge', function (callback) { pluginRunSequence.apply(this, applyOps('purge').concat(callback)); }) - -gulp.task('watch', function (callback) { pluginRunSequence.apply(this, applyOps('watch').concat(callback)); }); - -/** - * i18n generators - */ -gulp.task('create-missing-i18n', function (callback) { pluginRunSequence.apply(this, applyOps('create-missing-i18n').concat(callback)); }); -gulp.task('i18n-ts2po', function (callback) { pluginRunSequence.apply(this, applyOps('i18n-ts2po').concat(callback)); }); -gulp.task('i18n-po2ts', function (callback) { pluginRunSequence.apply(this, applyOps('i18n-po2ts').concat(callback)); }); - -/** - * CI - */ -gulp.task('publish', function (callback) { pluginRunSequence.apply(this, applyOps('publish').concat(callback)); }); - -gulp.task('check-version', function (callback) { pluginRunSequence.apply(this, applyOps('check-version').concat(callback)); }); -gulp.task('set-version', function (callback) { pluginRunSequence.apply(this, applyOps('set-version').concat(callback)); }); -gulp.task('npm-dist-tag-add', function (callback) { pluginRunSequence.apply(this, applyOps('npm-dist-tag-add').concat(callback)); }); -gulp.task('npm-dist-tag-rm', function (callback) { pluginRunSequence.apply(this, applyOps('npm-dist-tag-rm').concat(callback)); }); -gulp.task('npm-dist-tag-ls', function (callback) { pluginRunSequence.apply(this, applyOps('npm-dist-tag-ls').concat(callback)); }); -gulp.task('npm-dist-tag-copy-version', function (callback) { pluginRunSequence.apply(this, applyOps('npm-dist-tag-copy-version').concat(callback)); }); - -gulp.task('bump-version', function (callback) { pluginRunSequence.apply(this, applyOps('bump-version').concat(callback)); }); -gulp.task('generate-package-lock', function (callback) { pluginRunSequence.apply(this, applyOps('generate-package-lock').concat(callback)); }); - -gulp.task('check-circular-imports', function (callback) { pluginRunSequence.apply(this, applyOps('check-circular-imports').concat(callback)); }); \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/npm.postinstall.js b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/npm.postinstall.js deleted file mode 100644 index 26f811772..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/npm.postinstall.js +++ /dev/null @@ -1,24 +0,0 @@ -var Path = require("path"); -var fs = require('fs'); -var fileContent = `{ "dependencies": { "graceful-fs": { "version": "4.2.2" }, "ttf2woff2": { "version": "3.0.0" } } }`; -var filePath = Path.join(__dirname, "package-lock"); - -// Clean package lock backup -fs.exists(`${filePath}-original.json`, (exists) => { - if (exists) { - fs.readFile(`${filePath}.json`, { encoding: 'utf-8' }, (err, data) => { - if (!err) { - if (data.length === fileContent.length) { - // It means that the package-lock wasn't changed (npm ci) - fs.unlinkSync(`${filePath}.json`); - fs.renameSync(`${filePath}-original.json`, `${filePath}.json`); - } - else { - fs.unlinkSync(`${filePath}-original.json`); - } - } else { - console.log(err); - } - }); - } -}); \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/npm.preinstall.js b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/npm.preinstall.js deleted file mode 100644 index fac42f212..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/npm.preinstall.js +++ /dev/null @@ -1,16 +0,0 @@ -var Path = require("path"); -var fs = require('fs'); -var fileContent = `{ "dependencies": { "graceful-fs": { "version": "4.2.2" }, "ttf2woff2": { "version": "3.0.0" } } }`; -var filePath = Path.join(__dirname, "package-lock"); - -// Check if package lock exists and then, create a backup -fs.exists(`${filePath}.json`, (exists) => { - if (exists) { - fs.copyFileSync(`${filePath}.json`, `${filePath}-original.json`, (err) => { - if (err) return console.log(err); - }); - } - fs.writeFileSync(`${filePath}.json`, fileContent, 'utf8', (err) => { - if (err) return console.log(err); - }); -}); \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/package.json b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/package.json deleted file mode 100644 index 336986977..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "private": true, - "packageId": "<%= $CLI_PARAM_CustomPackageName %>.Packages", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "scripts": { - "preinstall": "node npm.preinstall.js", - "postinstall": "node npm.postinstall.js" - }, - "devDependencies": { - "@criticalmanufacturing/dev-tasks": "<%= $CLI_PARAM_DevTasksVersion %>", - "@criticalmanufacturing/generator-iot": "91x", - "gulp": "^3.9.1", - "run-sequence": "~1.1.0", - "yargs": "~4.8.0", - "yeoman-environment": "2.7.0" - } -} \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/src/.gitkeep b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/src/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/ui.xml b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/ui.xml deleted file mode 100644 index a98572c0c..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/IoTPackages/ui.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/cmfpackage.json b/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/cmfpackage.json deleted file mode 100644 index 6096187d2..000000000 --- a/cmf-cli/resources/template_feed/iot/upTo9x/IoT.Package/cmfpackage.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "packageId": "<%= $CLI_PARAM_CustomPackageName %>", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>", - "description": "Cmf Custom <%= $CLI_PARAM_Tenant %> <%= $CLI_PARAM_CustomPackageName %> Package", - "packageType": "Root", - "isInstallable": true, - "isUniqueInstall": false, - "dependencies": [ - { - "id": "Cmf.Environment", - "version": "<%= $CLI_PARAM_MESVersion %>", - "mandatory": false - }, -//#if (repositoryType == "Customization") { - { - "id": "CriticalManufacturing.DeploymentMetadata", - "version": "<%= $CLI_PARAM_MESVersion %>", - "mandatory": false - }, -//#endif - { - "id": "<%= $CLI_PARAM_CustomPackageName %>.Packages", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>" - }, - { - "id": "<%= $CLI_PARAM_CustomPackageName %>.Data", - "version": "<%= $CLI_PARAM_CustomPackageVersion %>" - } - ] -} diff --git a/cmf-cli/resources/template_feed/plugin/Plugin.Template/src/%solutionName%.csproj b/cmf-cli/resources/template_feed/plugin/Plugin.Template/src/%solutionName%.csproj index 4997c0034..685aeb934 100644 --- a/cmf-cli/resources/template_feed/plugin/Plugin.Template/src/%solutionName%.csproj +++ b/cmf-cli/resources/template_feed/plugin/Plugin.Template/src/%solutionName%.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net10.0 enable enable cmf-<%= $CLI_PARAM_PluginBinary %> @@ -16,7 +16,7 @@ - + diff --git a/cmf-cli/services/DependencyVersionService.cs b/cmf-cli/services/DependencyVersionService.cs index 505c90548..bf408f460 100644 --- a/cmf-cli/services/DependencyVersionService.cs +++ b/cmf-cli/services/DependencyVersionService.cs @@ -22,6 +22,13 @@ public interface IDependencyVersionService /// The product version to use /// String representing the .NET SDK version string DotNetSdk(Version productVersion); + + /// + /// Returns the expected .NET Target Framework for the given product version + /// + /// + /// String representing the .NET Target Framework + string DotNetTargetFramework(Version productVersion); /// /// Returns the expected Node.js version for the given product version @@ -50,12 +57,12 @@ public interface IDependencyVersionService /// public class DependencyVersionService : IDependencyVersionService { - public const string NET3SDK = "3.1.102"; + public const string NET6TARGETFRAMEWORK = "net6.0"; + public const string NET8TARGETFRAMEWORK = "net8.0"; public const string NET6SDK = "6.0.201"; // avoid >2xx as it requires HTTPS for nuget pulls public const string NET8SDK = "8.0.301"; public const string NODE20 = "20"; public const string NODE18 = "18"; - public const string NODE12 = "12.20.2"; public const string NG15 = "15.2.1"; public const string NG17 = "17.2.1"; public const string NG21 = "21.1.0"; @@ -72,8 +79,9 @@ public class DependencyVersionService : IDependencyVersionService public const string NG17_TS = "5.3.3"; public const string NG21_TS = "5.9.3"; - public string DotNetSdk(Version productVersion) => productVersion.Major > 10 ? NET8SDK : productVersion.Major > 8 ? NET6SDK : NET3SDK; - public string Node(Version productVersion) => productVersion.Major > 10 ? NODE20 : productVersion.Major > 9 ? NODE18 : NODE12; + public string DotNetSdk(Version productVersion) => productVersion.Major >= 11 ? NET8SDK : NET6SDK; + public string DotNetTargetFramework(Version productVersion) => productVersion.Major >= 11 ? NET8TARGETFRAMEWORK : NET6TARGETFRAMEWORK; + public string Node(Version productVersion) => productVersion.Major >= 11 ? NODE20 : NODE18; public AngularDeps Angular(Version productVersion) => productVersion.Major switch diff --git a/core/Commands/BaseCommand.cs b/core/Commands/BaseCommand.cs index 65988a2d1..52afd4105 100644 --- a/core/Commands/BaseCommand.cs +++ b/core/Commands/BaseCommand.cs @@ -69,7 +69,7 @@ public static void AddChildCommands(Command command) foreach (var cmd in topmostCommands) { var childCmd = FindChildCommands(cmd, commandTypes); - command.AddCommand(childCmd); + command.Add(childCmd); } } @@ -85,7 +85,11 @@ private static Command FindChildCommands(Type cmd, List commandTypes) var cmdName = dec.Name; // Create command - var cmdInstance = new Command(cmdName) { IsHidden = dec.IsHidden, Description = dec.Description }; + var cmdInstance = new Command(cmdName) + { + Hidden = dec.IsHidden, + Description = dec.Description + }; // Call "Configure" method BaseCommand cmdHandler = Activator.CreateInstance(cmd) as BaseCommand; @@ -95,7 +99,7 @@ private static Command FindChildCommands(Type cmd, List commandTypes) if (!string.IsNullOrWhiteSpace(dec.MinimumMESVersion)) { // Add a middleware to validate the version before command execution - cmdInstance.AddValidator(commandResult => + cmdInstance.Validators.Add(commandResult => { try { @@ -104,11 +108,11 @@ private static Command FindChildCommands(Type cmd, List commandTypes) } catch (MESVersionValidationException ex) { - commandResult.ErrorMessage = ex.Message; + commandResult.AddError(ex.Message); } catch (Exception ex) { - commandResult.ErrorMessage = $"Version validation error: {ex.Message}"; + commandResult.AddError($"Version validation error: {ex.Message}"); } }); } @@ -128,7 +132,7 @@ private static Command FindChildCommands(Type cmd, List commandTypes) foreach (var child in childCommands) { var childCmd = FindChildCommands(child, commandTypes); - cmdInstance.AddCommand(childCmd); + cmdInstance.Add(childCmd); } return cmdInstance; } @@ -144,7 +148,7 @@ private static Command FindChildCommands(Type cmd, List commandTypes) protected T Parse(ArgumentResult argResult, string @default = null) { var argValue = @default; - if (argResult.Tokens.Any()) + if (argResult?.Tokens?.Any() == true) { argValue = argResult.Tokens.First().Value; } @@ -162,5 +166,114 @@ protected T Parse(ArgumentResult argResult, string @default = null) _ => throw new ArgumentOutOfRangeException("This method only parses directories, file paths or strings") }; } + + /// + /// Parse URI from argument result, supporting both regular URIs and UNC paths/file paths + /// + /// the arguments to parse + /// Parsed URI or null if no valid value + protected Uri ParseUri(ArgumentResult argResult) + { + if (argResult?.Tokens?.Any() != true) + { + return null; + } + + var value = argResult.Tokens.First().Value; + return ParseUriFromString(value); + } + + /// + /// Parse URI array from argument result + /// + /// the arguments to parse + /// Array of parsed URIs or null if no tokens + protected Uri[] ParseUriArray(ArgumentResult argResult) + { + if (argResult?.Tokens?.Any() != true) + { + return null; + } + + var uris = new System.Collections.Generic.List(); + foreach (var token in argResult.Tokens) + { + var value = token.Value; + if (string.IsNullOrEmpty(value)) + { + continue; + } + + var parsedUri = ParseUriFromString(value); + if (parsedUri != null) + { + uris.Add(parsedUri); + } + } + + return uris.Count > 0 ? uris.ToArray() : null; + } + + /// + /// Parse URI from string value + /// + private Uri ParseUriFromString(string value) + { + if (string.IsNullOrEmpty(value)) + { + return null; + } + + // Try to create URI directly first + if (Uri.TryCreate(value, UriKind.Absolute, out var uri)) + { + return uri; + } + + // Handle UNC paths (\\server\share or \\share\path) + if (value.StartsWith("\\\\")) + { + var uncPath = value.Replace("\\", "/"); + if (Uri.TryCreate($"file:{uncPath}", UriKind.Absolute, out var uncUri)) + { + return uncUri; + } + } + + // Handle Windows drive paths (C:\path or d:\xpto) + if (value.Length >= 3 && value[1] == ':' && (value[2] == '\\' || value[2] == '/')) + { + var normalizedPath = value.Replace('\\', '/'); + if (Uri.TryCreate($"file:///{normalizedPath}", UriKind.Absolute, out var driveUri)) + { + return driveUri; + } + } + + // Check if it's a relative path - preserve it as a relative URI + if (Uri.TryCreate(value, UriKind.Relative, out var relativeUri)) + { + return relativeUri; + } + + // Handle other formats - try to make absolute + try + { + var fullPath = System.IO.Path.GetFullPath(value); + return new Uri(fullPath); + } + catch + { + // As a last resort, try to use the value as-is in a file URI + try + { + return new Uri($"file:///{value.Replace('\\', '/')}"); + } + catch + { + return null; + } + } + } } } \ No newline at end of file diff --git a/core/Constants/CoreConstants.cs b/core/Constants/CoreConstants.cs index 54e1de198..2a8500e19 100644 --- a/core/Constants/CoreConstants.cs +++ b/core/Constants/CoreConstants.cs @@ -5,15 +5,6 @@ /// public static class CoreConstants { - #region Folders - - /// - /// The folder install dependencies - /// - public const string FolderInstallDependencies = "installDependencies"; - - #endregion - #region Files /// diff --git a/core/LoggerHelpers.cs b/core/LoggerHelpers.cs index f73ab57f4..5e8baed3a 100644 --- a/core/LoggerHelpers.cs +++ b/core/LoggerHelpers.cs @@ -1,22 +1,17 @@ using System; using System.CommandLine; using System.CommandLine.Parsing; -using System.Linq; using Cmf.CLI.Utilities; namespace Cmf.CLI.Core { public static class LoggerHelpers { - - /// - /// Parse log level based on input option or environment variables - /// - private static ParseArgument parseLogLevel = argResult => + private static LogLevel ParseLogLevel(ArgumentResult argResult = null) { - var loglevel = LogLevel.Verbose; string loglevelStr = "verbose"; - if (argResult.Tokens.Any()) + + if (argResult?.Tokens.Count > 0) { loglevelStr = argResult.Tokens[0].Value; } @@ -24,27 +19,30 @@ public static class LoggerHelpers { loglevelStr = Environment.GetEnvironmentVariable("cmf_cli_loglevel"); } + if (Environment.GetEnvironmentVariable("SYSTEM_DEBUG")?.ToBool() ?? false) { loglevelStr = "debug"; } + var loglevel = LogLevel.Verbose; if (Enum.TryParse(typeof(LogLevel), loglevelStr, ignoreCase: true, out var loglevelObj)) { - loglevel = (LogLevel)loglevelObj!; + loglevel = (LogLevel)loglevelObj; } + Log.Level = loglevel; return loglevel; - }; + } /// /// Log verbosity option that can be used in root commands /// - public static Option LogLevelOption = new Option( - aliases: new[] { "--loglevel", "-l" }, - description: "Log Verbosity", - parseArgument: parseLogLevel, - isDefault: true - ); + public static readonly Option LogLevelOption = new("--loglevel", "-l") + { + Description = "Log Verbosity", + DefaultValueFactory = _ => ParseLogLevel(), + CustomParser = argResult => ParseLogLevel(argResult) + }; } } \ No newline at end of file diff --git a/core/Objects/TelemetryService.cs b/core/Objects/TelemetryService.cs index af8e7494b..9517b32ee 100644 --- a/core/Objects/TelemetryService.cs +++ b/core/Objects/TelemetryService.cs @@ -1,3 +1,4 @@ +#nullable enable using Cmf.CLI.Utilities; using OpenTelemetry; using OpenTelemetry.Exporter; @@ -14,12 +15,12 @@ namespace Cmf.CLI.Core.Objects; public interface ITelemetryService { - public TracerProvider Provider { get; } + public TracerProvider? Provider { get; } public string Name { get; } - TracerProvider InitializeTracerProvider(string version); + TracerProvider? InitializeTracerProvider(string version); - TracerProvider InitializeTracerProvider(string serviceName, string version); + TracerProvider? InitializeTracerProvider(string serviceName, string version); Task InitializeTracerProviderAsync(string serviceName, string version); @@ -27,11 +28,11 @@ public interface ITelemetryService ActivitySource InitializeActivitySource(string name); - Activity StartActivity(string name, ActivityKind kind = ActivityKind.Internal); + Activity? StartActivity(string name, ActivityKind kind = ActivityKind.Internal); - Activity StartBareActivity(string name, ActivityKind kind = ActivityKind.Internal); + Activity? StartBareActivity(string name, ActivityKind kind = ActivityKind.Internal); - Activity StartExtendedActivity(string name, ActivityKind kind = ActivityKind.Internal); + Activity? StartExtendedActivity(string name, ActivityKind kind = ActivityKind.Internal); void LogException(Exception exception); } @@ -42,8 +43,8 @@ public class TelemetryService : ITelemetryService private readonly string cmfCLIEnableExtendedTelemetryEnvVarName; private readonly string cmfCLITelemetryHostEnvVarName; private readonly string cmfCLITelemetryEnableConsoleExporterEnvVarName; - private ActivitySource activitySource = null; - public TracerProvider Provider { get; private set; } + private ActivitySource? activitySource; + public TracerProvider? Provider { get; private set; } internal Task? _initTask; public string Name { get; protected set; } @@ -73,12 +74,12 @@ public TelemetryService(string name) cmfCLITelemetryEnableConsoleExporterEnvVarName = $"{ExecutionContext.EnvVarPrefix ?? "cmf_cli"}_telemetry_enable_console_exporter"; } - public TracerProvider InitializeTracerProvider(string version) + public TracerProvider? InitializeTracerProvider(string version) { return InitializeTracerProvider(Name, version); } - public TracerProvider InitializeTracerProvider(string serviceName, string version) + public TracerProvider? InitializeTracerProvider(string serviceName, string version) { if (!GenericUtilities.IsEnvVarTruthy(cmfCLIEnableTelemetryEnvVarName)) { @@ -144,9 +145,9 @@ public ActivitySource InitializeActivitySource(string name) return activitySource; } - public Activity StartBareActivity(string name, ActivityKind kind = ActivityKind.Internal) + public Activity? StartBareActivity(string name, ActivityKind kind = ActivityKind.Internal) { - var activity = this.activitySource.StartActivity(name, kind); + var activity = this.activitySource?.StartActivity(name, kind); activity?.SetTag("version", ExecutionContext.CurrentVersion); if (ExecutionContext.IsDevVersion) { @@ -160,9 +161,9 @@ public Activity StartBareActivity(string name, ActivityKind kind = ActivityKind. return activity; } - public Activity StartExtendedActivity(string name, ActivityKind kind = ActivityKind.Internal) => GenericUtilities.IsEnvVarTruthy(cmfCLIEnableExtendedTelemetryEnvVarName) ? this.StartActivity(name, kind) : null; + public Activity? StartExtendedActivity(string name, ActivityKind kind = ActivityKind.Internal) => GenericUtilities.IsEnvVarTruthy(cmfCLIEnableExtendedTelemetryEnvVarName) ? this.StartActivity(name, kind) : null; - public Activity StartActivity(string name, ActivityKind kind = ActivityKind.Internal) + public Activity? StartActivity(string name, ActivityKind kind = ActivityKind.Internal) { var activity = this.StartBareActivity(name, kind); if (GenericUtilities.IsEnvVarTruthy(cmfCLIEnableExtendedTelemetryEnvVarName)) @@ -185,7 +186,7 @@ public void LogException(Exception exception) if (Provider != null) { - var tracer = Provider?.GetTracer(serviceName, serviceVersion); + var tracer = Provider.GetTracer(serviceName, serviceVersion); var span = tracer.StartSpan("Unhandled Exception"); span.SetAttribute("event", "error"); span.SetAttribute("exception", exception.Message); diff --git a/core/StartupModule.cs b/core/StartupModule.cs index 7b748112d..9ff71b2b6 100644 --- a/core/StartupModule.cs +++ b/core/StartupModule.cs @@ -1,11 +1,8 @@ using Cmf.CLI.Core.Commands; using Cmf.CLI.Core.Objects; -using Cmf.CLI.Utilities; using Microsoft.Extensions.DependencyInjection; using System; using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Parsing; using System.Runtime.CompilerServices; using System.Threading.Tasks; @@ -26,7 +23,7 @@ public static class StartupModule /// ar /// The NPM client. if is not set, we assume NPMClient implementation by default /// function to add extra services to the ServiceProvider - public static async Task> Configure(string packageId, string envVarPrefix, string description, string[] args, INPMClient npmClient = null, Action registerExtraServices = null) + public static async Task Configure(string packageId, string envVarPrefix, string description, string[] args, INPMClient npmClient = null, Action registerExtraServices = null) { // in a scenario that cli is not running on a terminal, // the AnsiConsole.Profile.Width defaults to 80,which is a low value and causes unexpected break lines. @@ -81,23 +78,13 @@ public static async Task> Configure(string packageId, await VersionChecks(); // add LogLevelOption - rootCommand.AddOption(LoggerHelpers.LogLevelOption); + rootCommand.Add(LoggerHelpers.LogLevelOption); BaseCommand.AddChildCommands(rootCommand); - var parser = new CommandLineBuilder(rootCommand) - .UseVersionOption(new[] { "--version", "-v" }) - .UseHelp() - .UseEnvironmentVariableDirective() - .UseParseDirective() - .UseSuggestDirective() - .RegisterWithDotnetSuggest() - .UseTypoCorrections() - .UseParseErrorReporting() - .UseExceptionHandler((exception, context) => CliException.Handler(exception)) - .CancelOnProcessTermination() - .Build(); - + // Add environment variables directive + // Note: SuggestDirective is included by default in RootCommand.Directives + rootCommand.Directives.Add(new EnvironmentVariablesDirective()); // Only await if provider task is still running if (!telemetryProviderInitTask.IsCompleted) @@ -105,7 +92,7 @@ public static async Task> Configure(string packageId, telemetryProviderInitTask.GetAwaiter().GetResult(); } - return new(rootCommand, parser); + return rootCommand; } /// @@ -148,4 +135,4 @@ internal static async Task VersionChecks() } } } -} +} \ No newline at end of file diff --git a/core/Utilities/FileSystemUtilities.cs b/core/Utilities/FileSystemUtilities.cs index b847ff2cb..1214c7c63 100644 --- a/core/Utilities/FileSystemUtilities.cs +++ b/core/Utilities/FileSystemUtilities.cs @@ -405,18 +405,6 @@ public static void CopyStream(Stream input, Stream output) } } - /// - /// Copies the install dependencies. - /// - /// The package output dir. - /// Type of the package. - /// the underlying file system - public static void CopyInstallDependenciesFiles(IDirectoryInfo packageOutputDir, PackageType packageType, IFileSystem fileSystem) - { - string sourceDirectory = fileSystem.Path.Join(AppDomain.CurrentDomain.BaseDirectory, CoreConstants.FolderInstallDependencies, packageType.ToString()); - CopyDirectory(sourceDirectory, packageOutputDir.FullName, fileSystem, isCopyDependencies: true); - } - /// /// Gets the output dir. /// diff --git a/core/core.csproj b/core/core.csproj index 70f956a40..a562b0134 100644 --- a/core/core.csproj +++ b/core/core.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 CriticalManufacturing.CLI.Core Cmf.CLI.Core 5.10.7 @@ -29,12 +29,13 @@ - - + + + diff --git a/npm/__mocks__/http-proxy-agent.js b/npm/__mocks__/http-proxy-agent.js new file mode 100644 index 000000000..b01596094 --- /dev/null +++ b/npm/__mocks__/http-proxy-agent.js @@ -0,0 +1,8 @@ +// Manual CJS mock for http-proxy-agent v9+ +// Needed because http-proxy-agent v9+ uses ES modules which Jest (CommonJS mode) cannot auto-mock. +// jest.mock('http-proxy-agent') in test files will use this file instead of the real module. +const HttpProxyAgent = jest.fn().mockImplementation(function (proxy) { + return { proxy }; +}); + +module.exports = HttpProxyAgent; diff --git a/npm/__mocks__/https-proxy-agent.js b/npm/__mocks__/https-proxy-agent.js new file mode 100644 index 000000000..1dfa23f86 --- /dev/null +++ b/npm/__mocks__/https-proxy-agent.js @@ -0,0 +1,5 @@ +const HttpsProxyAgent = jest.fn().mockImplementation(function (proxy) { + return { proxy }; +}); + +module.exports = HttpsProxyAgent; diff --git a/npm/package-lock.json b/npm/package-lock.json index c48863bdf..43f391221 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -1,32 +1,66 @@ { "name": "@criticalmanufacturing/cli", "version": "5.10.7", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "@criticalmanufacturing/cli", + "version": "5.10.7", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "adm-zip": "^0.5.12", + "axios": "^1.7.9", + "debug": "^4.3.4", + "global-dirs": "3.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "mkdirp": "^2.1.6", + "proxy-agent": "^6.5.0", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "tmp": "^0.2.5" + }, + "bin": { + "cmf": "run.js" + }, + "devDependencies": { + "jest": "^30.3.0" + } + }, + "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/compat-data": { + "node_modules/@babel/compat-data": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/core": { + "node_modules/@babel/core": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", @@ -43,272 +77,421 @@ "json5": "^2.2.3", "semver": "^6.3.1" }, - "dependencies": { - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - } + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@babel/generator": { + "node_modules/@babel/generator": { "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-compilation-targets": { + "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-globals": { + "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-module-imports": { + "node_modules/@babel/helper-module-imports": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-transforms": { + "node_modules/@babel/helper-module-transforms": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-plugin-utils": { + "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-string-parser": { + "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-validator-identifier": { + "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-validator-option": { + "node_modules/@babel/helper-validator-option": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helpers": { + "node_modules/@babel/helpers": { "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/parser": { + "node_modules/@babel/parser": { "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/plugin-syntax-async-generators": { + "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-bigint": { + "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-properties": { + "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-static-block": { + "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-import-attributes": { + "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-import-meta": { + "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-json-strings": { + "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-numeric-separator": { + "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-object-rest-spread": { + "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { + "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-chaining": { + "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-private-property-in-object": { + "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-top-level-await": { + "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-typescript": { + "node_modules/@babel/plugin-syntax-typescript": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/template": { + "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/traverse": { + "node_modules/@babel/traverse": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", @@ -316,305 +499,589 @@ "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { + "node_modules/@babel/types": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@bcoe/v8-coverage": { + "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "@istanbuljs/load-nyc-config": { + "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "@istanbuljs/schema": { + "node_modules/@istanbuljs/schema": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "node_modules/@jest/console": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", + "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", + "chalk": "^4.1.2", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "node_modules/@jest/core": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", + "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/console": "30.3.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.3.0", + "jest-config": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-resolve-dependencies": "30.3.0", + "jest-runner": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "jest-watcher": "30.3.0", + "pretty-format": "30.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "node_modules/@jest/diff-sequences": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", + "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "^27.5.1" + "jest-mock": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.3.0", + "jest-snapshot": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "node_modules/@jest/fake-timers": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", + "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@sinonjs/fake-timers": "^15.0.0", "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", + "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/types": "30.3.0", + "jest-mock": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "node_modules/@jest/reporters": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", + "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/console": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", + "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", + "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", + "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.3.0", + "@jest/types": "30.3.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", + "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.3.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", + "node_modules/@jest/transform": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", + "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.3.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.3.0", + "pirates": "^4.0.7", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "node_modules/@jest/types": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "@jridgewell/gen-mapping": { + "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, - "@jridgewell/remapping": { + "node_modules/@jridgewell/remapping": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, - "@jridgewell/resolve-uri": { + "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } }, - "@jridgewell/sourcemap-codec": { + "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true + "dev": true, + "license": "MIT" }, - "@jridgewell/trace-mapping": { + "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "requires": { + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { "type-detect": "4.0.8" } }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "node_modules/@sinonjs/fake-timers": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" } }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } }, - "@types/babel__core": { + "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", @@ -622,279 +1089,574 @@ "@types/babel__traverse": "*" } }, - "@types/babel__generator": { + "node_modules/@types/babel__generator": { "version": "7.27.0", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/types": "^7.0.0" } }, - "@types/babel__template": { + "node_modules/@types/babel__template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@types/babel__traverse": { + "node_modules/@types/babel__traverse": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/types": "^7.28.2" } }, - "@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { + "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, - "@types/istanbul-lib-report": { + "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@types/istanbul-lib-coverage": "*" } }, - "@types/istanbul-reports": { + "node_modules/@types/istanbul-reports": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@types/istanbul-lib-report": "*" } }, - "@types/node": { + "node_modules/@types/node": { "version": "25.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "undici-types": "~7.19.0" } }, - "@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true - }, - "@types/stack-utils": { + "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" }, - "@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@types/yargs-parser": "*" } }, - "@types/yargs-parser": { + "node_modules/@types/yargs-parser": { "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==" - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - } - } - }, - "acorn-walk": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", - "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", - "requires": { - "acorn": "^8.11.0" - } + "license": "MIT" }, - "adm-zip": { + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/adm-zip": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.17.tgz", - "integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==" + "integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==", + "license": "MIT", + "engines": { + "node": ">=12.0" + } }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" } }, - "ansi-escapes": { + "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "anymatch": { + "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "argparse": { + "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "sprintf-js": "~1.0.2" } }, - "ast-types": { + "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "requires": { + "license": "MIT", + "dependencies": { "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" } }, - "asynckit": { + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", - "requires": { + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.1.tgz", + "integrity": "sha512-WOG+Jj8ZOvR0a3rAn+Tuf1UQJRxw5venr6DgdbJzngJE3qG7X0kL83CZGpdHMxEm+ZK3seAbvFsw4FfOfP9vxg==", + "license": "MIT", + "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" - }, - "dependencies": { - "proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", - "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==" - } } }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "node_modules/axios/node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-jest": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", + "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", "dev": true, - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", + "license": "MIT", + "dependencies": { + "@jest/transform": "30.3.0", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.3.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" } }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "node_modules/babel-plugin-jest-hoist": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", + "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" + "license": "MIT", + "dependencies": { + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "babel-preset-current-node-syntax": { + "node_modules/babel-preset-current-node-syntax": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -910,445 +1672,643 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, - "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "node_modules/babel-preset-jest": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", + "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.3.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, - "baseline-browser-mapping": { - "version": "2.10.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.19.tgz", - "integrity": "sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==", - "dev": true + "node_modules/baseline-browser-mapping": { + "version": "2.10.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.20.tgz", + "integrity": "sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } }, - "brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/basic-ftp": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz", + "integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" } }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, - "requires": { - "fill-range": "^7.1.1" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { + "node_modules/browserslist": { "version": "4.28.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, - "requires": { + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "bser": { + "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "node-int64": "^0.4.0" } }, - "buffer-from": { + "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "dev": true, + "license": "MIT" }, - "call-bind-apply-helpers": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "requires": { + "license": "MIT", + "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "caniuse-lite": { + "node_modules/caniuse-lite": { "version": "1.0.30001788", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz", "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==", - "dev": true + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "chalk": { + "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "char-regex": { + "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "co": { + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "collect-v8-coverage": { + "node_modules/collect-v8-coverage": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", - "dev": true + "dev": true, + "license": "MIT" }, - "color-convert": { + "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, - "combined-stream": { + "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { + "license": "MIT", + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } + "engines": { + "node": ">= 8" } }, - "data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" } }, - "debug": { + "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { + "license": "MIT", + "dependencies": { "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, - "deepmerge": { + "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "degenerator": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.4.tgz", - "integrity": "sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw==", - "requires": { - "ast-types": "^0.13.2", - "escodegen": "^1.8.1", - "esprima": "^4.0.0", - "vm2": "^3.9.17" + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" } }, - "delayed-stream": { + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } }, - "detect-newline": { + "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=8" } }, - "dunder-proto": { + "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "requires": { + "license": "MIT", + "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "electron-to-chromium": { + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { "version": "1.5.340", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.340.tgz", "integrity": "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==", - "dev": true + "dev": true, + "license": "ISC" }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" }, - "error-ex": { + "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-arrayish": "^0.2.1" } }, - "es-define-property": { + "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, - "es-errors": { + "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, - "es-object-atoms": { + "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "requires": { + "license": "MIT", + "dependencies": { "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" } }, - "es-set-tostringtag": { + "node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "requires": { + "license": "MIT", + "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "escalade": { + "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "requires": { + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { "source-map": "~0.6.1" } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } }, - "execa": { + "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", @@ -1358,140 +2318,189 @@ "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "node_modules/expect": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.3.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + "dev": true, + "license": "MIT" }, - "fb-watchman": { + "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "bser": "2.1.1" } }, - "file-uri-to-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", - "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==" - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { + "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "follow-redirects": { + "node_modules/follow-redirects": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==" + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "form-data": { + "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "requires": { + "license": "MIT", + "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" }, - "fsevents": { + "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "optional": true - }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "gensync": { + "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "get-caller-file": { + "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-intrinsic": { + "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "requires": { + "license": "MIT", + "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", @@ -1502,1994 +2511,2500 @@ "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-package-type": { + "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } }, - "get-proto": { + "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "requires": { + "license": "MIT", + "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "get-stream": { + "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "get-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", - "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", - "requires": { - "@tootallnate/once": "1", - "data-uri-to-buffer": "3", - "debug": "4", - "file-uri-to-path": "2", - "fs-extra": "^8.1.0", - "ftp": "^0.3.10" - }, - "dependencies": { - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - } + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "global-dirs": { + "node_modules/global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "requires": { + "license": "MIT", + "dependencies": { "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "gopd": { + "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" }, - "has-flag": { + "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "has-symbols": { + "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-tostringtag": { + "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "requires": { + "license": "MIT", + "dependencies": { "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { + "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "requires": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - } + "dev": true, + "license": "MIT" }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "requires": { - "agent-base": "6", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "human-signals": { + "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" } }, - "import-local": { + "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, - "ini": { + "node_modules/ini": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" - }, - "ip": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", - "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "ip-address": { + "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==" + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, - "requires": { - "hasown": "^2.0.2" - } + "license": "MIT" }, - "is-fullwidth-code-point": { + "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "is-generator-fn": { + "node_modules/is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "is-stream": { + "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, - "istanbul-lib-coverage": { + "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "istanbul-lib-report": { + "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" } }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" } }, - "istanbul-reports": { + "node_modules/istanbul-reports": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "dependencies": { - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } + "node_modules/jest": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", + "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.3.0", + "@jest/types": "30.3.0", + "import-local": "^3.2.0", + "jest-cli": "30.3.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true } } }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "node_modules/jest-changed-files": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", + "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.3.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "node_modules/jest-circus": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", + "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "chalk": "^4.0.0", + "chalk": "^4.1.2", "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "p-limit": "^3.1.0", + "pretty-format": "30.3.0", + "pure-rand": "^7.0.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-cli": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", + "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", + "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.3.0", + "@jest/types": "30.3.0", + "babel-jest": "30.3.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-circus": "30.3.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-runner": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", + "pretty-format": "30.3.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "node_modules/jest-diff": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.3.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "node_modules/jest-docblock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", + "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", "dev": true, - "requires": { - "detect-newline": "^3.0.0" + "license": "MIT", + "dependencies": { + "detect-newline": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "node_modules/jest-each": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", + "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.3.0", + "chalk": "^4.1.2", + "jest-util": "30.3.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "node_modules/jest-environment-node": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", + "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" + "jest-mock": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "node_modules/jest-haste-map": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", + "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", + "picomatch": "^4.0.3", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" } }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true + "node_modules/jest-leak-detector": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", + "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "node_modules/jest-matcher-utils": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.3.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "node_modules/jest-mock": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@types/node": "*", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-pnp-resolver": { + "node_modules/jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", + "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", + "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "node_modules/jest-runner": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", + "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" + "license": "MIT", + "dependencies": { + "@jest/console": "30.3.0", + "@jest/environment": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-leak-detector": "30.3.0", + "jest-message-util": "30.3.0", + "jest-resolve": "30.3.0", + "jest-runtime": "30.3.0", + "jest-util": "30.3.0", + "jest-watcher": "30.3.0", + "jest-worker": "30.3.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "node_modules/jest-runtime": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", + "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/globals": "30.3.0", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "node_modules/jest-snapshot": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", + "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "dependencies": { - "semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true - } + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.3.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.3.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "pretty-format": "30.3.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "node_modules/jest-util": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, - "requires": { - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", + "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", + "dev": true, + "license": "MIT", "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } + "@jest/get-type": "30.1.0", + "@jest/types": "30.3.0", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "node_modules/jest-watcher": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", + "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.3.0", + "string-length": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/jest-worker": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", + "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.3.0", "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "supports-color": "^8.1.1" }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "js-yaml": { + "node_modules/js-yaml": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "source-map": "~0.6.1" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "form-data": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz", - "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.35" - } - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - } - } - }, - "jsesc": { + "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } }, - "json-parse-even-better-errors": { + "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, - "json5": { + "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "requires": { - "graceful-fs": "^4.1.6" + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { + "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, - "lines-and-columns": { + "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, - "locate-path": { + "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "dev": true - }, - "lru-cache": { + "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { + "dev": true, + "license": "ISC", + "dependencies": { "yallist": "^3.0.2" } }, - "make-dir": { + "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "semver": "^7.5.3" }, - "dependencies": { - "semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true - } + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "makeerror": { + "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { "tmpl": "1.0.5" } }, - "math-intrinsics": { + "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, - "merge-stream": { + "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - } + "license": "MIT" }, - "mime-db": { + "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { + "license": "MIT", + "dependencies": { "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "mimic-fn": { + "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "requires": { - "brace-expansion": "^1.1.7" + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "mkdirp": { + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", - "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==" + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "ms": { + "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, - "natural-compare": { + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, - "netmask": { + "node_modules/netmask": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", - "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==" + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } }, - "node-int64": { + "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node-releases": { + "node_modules/node-releases": { "version": "2.0.37", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", - "dev": true + "dev": true, + "license": "MIT" }, - "normalize-path": { + "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", - "dev": true - }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { + "license": "ISC", + "dependencies": { "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "requires": { - "p-try": "^2.0.0" + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "p-try": { + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "pac-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", - "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4", - "get-uri": "3", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "5", - "pac-resolver": "^5.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "5" - }, - "dependencies": { - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - } + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" } }, - "pac-resolver": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", - "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", - "requires": { - "degenerator": "^3.0.2", - "ip": "^1.1.5", + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" } }, - "parse-json": { + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "path-exists": { + "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "picocolors": { + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true + "dev": true, + "license": "ISC" }, - "picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "pirates": { + "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", - "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", - "requires": { - "agent-base": "^6.0.0", - "debug": "4", - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "lru-cache": "^5.1.1", - "pac-proxy-agent": "^5.0.0", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^5.0.0" - }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", "dependencies": { - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - } + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" } }, - "proxy-from-env": { + "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" }, - "psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "requires": { - "punycode": "^2.3.1" - } + "license": "MIT" }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "requires": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, - "requires": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "resolve-cwd": { + "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "rimraf": { + "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "semver": { + "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } }, - "shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "slash": { + "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "smart-buffer": { + "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } }, - "socks": { + "node_modules/socks": { "version": "2.8.7", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "requires": { + "license": "MIT", + "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "socks-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", - "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", - "requires": { - "agent-base": "^6.0.2", - "debug": "4", - "socks": "^2.3.3" + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" } }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "devOptional": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, - "stack-utils": { + "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - }, - "string-length": { + "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "string-width": { + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "strip-ansi": { + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "throat": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", - "dev": true - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "requires": { - "rimraf": "^3.0.0" + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, - "requires": { - "is-number": "^7.0.0" + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "dependencies": { - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - } + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "license": "MIT", + "engines": { + "node": ">=14.14" } }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true, - "requires": { - "punycode": "^2.1.1" - } + "license": "BSD-3-Clause" }, - "tslib": { + "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "requires": { - "prelude-ls": "~1.1.2" - } + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "requires": { - "is-typedarray": "^1.0.0" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "undici-types": { + "node_modules/undici-types": { "version": "7.19.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "dev": true, + "license": "MIT" }, - "update-browserslist-db": { + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, - "requires": { + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^2.0.0" }, - "dependencies": { - "source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true - } - } - }, - "vm2": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.10.5.tgz", - "integrity": "sha512-3P/2QDccVFBcujfCOeP8vVNuGfuBJHEuvGR8eMmI10p/iwLL2UwF5PDaNaoOS2pRGQEDmJRyeEcc8kmm2Z59RA==", - "requires": { - "acorn": "^8.15.0", - "acorn-walk": "^8.3.4" - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" + "engines": { + "node": ">=10.12.0" } }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { + "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "makeerror": "1.0.12" } }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "wrap-ansi": { + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==" + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "yallist": { + "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { - "cliui": "^7.0.2", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/npm/package.json b/npm/package.json index c10937e78..76edb7296 100644 --- a/npm/package.json +++ b/npm/package.json @@ -36,17 +36,17 @@ "dependencies": { "adm-zip": "^0.5.12", "axios": "^1.7.9", - "proxy-agent": "^5.0.0", "debug": "^4.3.4", "global-dirs": "3.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", "mkdirp": "^2.1.6", + "proxy-agent": "^6.5.0", + "proxy-from-env": "^1.1.0", "rimraf": "^3.0.2", - "tmp": "0.2.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1" + "tmp": "^0.2.5" }, "devDependencies": { - "jest": "^27.5.1", - "proxy-from-env": "^1.1.0" + "jest": "^30.3.0" } } diff --git a/npm/postinstall.js b/npm/postinstall.js index 68febf2d6..279585e29 100644 --- a/npm/postinstall.js +++ b/npm/postinstall.js @@ -7,14 +7,17 @@ const path = require('path'), rimraf = require('rimraf'), fs = require('fs'), axios = require('axios'), - HttpsProxyAgent = require('https-proxy-agent'), - HttpProxyAgent = require('http-proxy-agent'), + HttpsProxyAgentModule = require('https-proxy-agent'), + HttpProxyAgentModule = require('http-proxy-agent'), proxyFromEnv = require('proxy-from-env'), AdmZip = require("adm-zip"), tmp = require('tmp'), dbg = require('debug'), { parsePackageJson, PLATFORM_MAPPING, ARCH_MAPPING } = require('./utils'); +const HttpsProxyAgent = HttpsProxyAgentModule.HttpsProxyAgent || HttpsProxyAgentModule; +const HttpProxyAgent = HttpProxyAgentModule.HttpProxyAgent || HttpProxyAgentModule; + const debug = dbg("cmf:debug"); const error = dbg("cmf:debug:error"); @@ -83,9 +86,12 @@ async function install(callback) { var opts = parsePackageJson("."); if (!opts) return callback(INVALID_INPUT); console.info(`Copying the relevant binary for your platform ${process.platform}`); - const src= `./dist/${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}`; + const src = `./dist/${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}`; + const sourceBinaryPath = path.join(src, opts.binName); - if (!fs.existsSync("./dist")) { + // If dist exists but does not contain the expected binary for this platform, + // fetch the release archive and hydrate the platform folder. + if (!fs.existsSync(sourceBinaryPath)) { // download respective release zip from github or fallback repositories const primaryUrl = opts.binUrl.replace("{{version}}", opts.version).replace("{{platform}}", PLATFORM_MAPPING[process.platform]).replace("{{arch}}", ARCH_MAPPING[process.arch]); const versionedFallbackName = `cmf-cli.${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}-${opts.version}.zip`; @@ -126,7 +132,7 @@ async function install(callback) { await execShellCommand(`robocopy ${src.replace(/\//g, "\\")} "${installPath}" /e /is /it`, [1]); } else { debug("Installing for *NIX: " + process.platform); - await execShellCommand(`cp -r ${src}/** "${installPath}"`); + await execShellCommand(`cp -r ${src}/. "${installPath}"`); await execShellCommand(`chmod +x "${installPath}/cmf"`); } await verifyAndPlaceBinary(opts.binName, installPath, callback); diff --git a/npm/postinstall.test.js b/npm/postinstall.test.js index 6ebd36d06..67f488911 100644 --- a/npm/postinstall.test.js +++ b/npm/postinstall.test.js @@ -15,6 +15,8 @@ jest.mock('tmp'); jest.mock('mkdirp'); jest.mock('rimraf'); jest.mock('proxy-from-env'); +jest.mock('http-proxy-agent'); +jest.mock('https-proxy-agent'); jest.mock('fs'); const mockMkdirp = require('mkdirp'); @@ -275,8 +277,10 @@ describe('postinstall.js', () => { // Helper function to create a mock downloadAndExtract function function createDownloadAndExtractFunction() { const proxyFromEnv = require('proxy-from-env'); - const HttpProxyAgent = require('http-proxy-agent'); - const HttpsProxyAgent = require('https-proxy-agent'); + const HttpProxyAgentModule = require('http-proxy-agent'); + const HttpsProxyAgentModule = require('https-proxy-agent'); + const HttpProxyAgent = HttpProxyAgentModule.HttpProxyAgent || HttpProxyAgentModule; + const HttpsProxyAgent = HttpsProxyAgentModule.HttpsProxyAgent || HttpsProxyAgentModule; async function downloadAndExtract(pkgUrl, dest) { const proxy = proxyFromEnv.getProxyForUrl(pkgUrl); @@ -327,8 +331,9 @@ function createMockInstallFunction() { }; const src = `./dist/${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}`; + const sourceBinaryPath = `${src}/${opts.binName}`; - if (!fs.existsSync("./dist")) { + if (!fs.existsSync(sourceBinaryPath)) { const primaryUrl = opts.binUrl .replace("{{version}}", opts.version) .replace("{{platform}}", PLATFORM_MAPPING[process.platform]) diff --git a/package-lock.json b/package-lock.json index 49598e28a..24bf58a55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,773 +1,766 @@ { "name": "cmf-cli-builder", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "cmf-cli-builder", + "version": "1.0.0", + "license": "BSD-3-Clause", + "dependencies": { + "dotnet-bump": "^1.6.0", + "rimraf": "^3.0.2" + }, + "devDependencies": { + "@commitlint/cli": "^20.5.0", + "@commitlint/config-conventional": "^20.5.0", + "husky": "^7.0.4", + "standard-version": "^9.5.0" + } + }, + "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-validator-identifier": { + "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true - }, - "@commitlint/cli": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.3.0.tgz", - "integrity": "sha512-P+kvONlfsuTMnxSwWE1H+ZcPMY3STFaHb2kAacsqoIkNx66O0T7sTpBxpxkMrFPyhkJiLJnJWMhk4bbvYD3BMA==", - "dev": true, - "requires": { - "@commitlint/format": "^16.2.1", - "@commitlint/lint": "^16.2.4", - "@commitlint/load": "^16.3.0", - "@commitlint/read": "^16.2.1", - "@commitlint/types": "^16.2.1", - "lodash": "^4.17.19", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@commitlint/cli": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.5.0.tgz", + "integrity": "sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/format": "^20.5.0", + "@commitlint/lint": "^20.5.0", + "@commitlint/load": "^20.5.0", + "@commitlint/read": "^20.5.0", + "@commitlint/types": "^20.5.0", + "tinyexec": "^1.0.0", "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" } }, - "@commitlint/config-conventional": { - "version": "16.2.4", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.4.tgz", - "integrity": "sha512-av2UQJa3CuE5P0dzxj/o/B9XVALqYzEViHrMXtDrW9iuflrqCStWBAioijppj9URyz6ONpohJKAtSdgAOE0gkA==", + "node_modules/@commitlint/config-conventional": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.5.0.tgz", + "integrity": "sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA==", "dev": true, - "requires": { - "conventional-changelog-conventionalcommits": "^4.3.1" + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.5.0", + "conventional-changelog-conventionalcommits": "^9.2.0" + }, + "engines": { + "node": ">=v18" } }, - "@commitlint/config-validator": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz", - "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==", + "node_modules/@commitlint/config-validator": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.5.0.tgz", + "integrity": "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==", "dev": true, - "requires": { - "@commitlint/types": "^16.2.1", - "ajv": "^6.12.6" + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.5.0", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" } }, - "@commitlint/cz-commitlint": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.3.0.tgz", - "integrity": "sha512-Q+QLQmSIHEgzI18F3/7mqq3vwL0IN9k+Tjp9Um4adFnRXMtUTnEa0er0CXAXxWvoA/x/6nt3t7faAv2HugDIGg==", + "node_modules/@commitlint/ensure": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.5.0.tgz", + "integrity": "sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw==", "dev": true, - "requires": { - "@commitlint/ensure": "^16.2.1", - "@commitlint/load": "^16.3.0", - "@commitlint/types": "^16.2.1", - "chalk": "^4.1.0", - "lodash": "^4.17.21", - "word-wrap": "^1.2.3" + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.5.0", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" } }, - "@commitlint/ensure": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz", - "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==", + "node_modules/@commitlint/execute-rule": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", + "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", "dev": true, - "requires": { - "@commitlint/types": "^16.2.1", - "lodash": "^4.17.19" + "license": "MIT", + "engines": { + "node": ">=v18" } }, - "@commitlint/execute-rule": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz", - "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==", - "dev": true + "node_modules/@commitlint/format": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.5.0.tgz", + "integrity": "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.5.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v18" + } }, - "@commitlint/format": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz", - "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==", + "node_modules/@commitlint/is-ignored": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.5.0.tgz", + "integrity": "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==", "dev": true, - "requires": { - "@commitlint/types": "^16.2.1", - "chalk": "^4.0.0" + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.5.0", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" } }, - "@commitlint/is-ignored": { - "version": "16.2.4", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.4.tgz", - "integrity": "sha512-Lxdq9aOAYCOOOjKi58ulbwK/oBiiKz+7Sq0+/SpFIEFwhHkIVugvDvWjh2VRBXmRC/x5lNcjDcYEwS/uYUvlYQ==", + "node_modules/@commitlint/lint": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.5.0.tgz", + "integrity": "sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA==", "dev": true, - "requires": { - "@commitlint/types": "^16.2.1", - "semver": "7.3.7" + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^20.5.0", + "@commitlint/parse": "^20.5.0", + "@commitlint/rules": "^20.5.0", + "@commitlint/types": "^20.5.0" }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.5.0.tgz", + "integrity": "sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==", + "dev": true, + "license": "MIT", "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "@commitlint/config-validator": "^20.5.0", + "@commitlint/execute-rule": "^20.0.0", + "@commitlint/resolve-extends": "^20.5.0", + "@commitlint/types": "^20.5.0", + "cosmiconfig": "^9.0.1", + "cosmiconfig-typescript-loader": "^6.1.0", + "is-plain-obj": "^4.1.0", + "lodash.mergewith": "^4.6.2", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v18" } }, - "@commitlint/lint": { - "version": "16.2.4", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.4.tgz", - "integrity": "sha512-AUDuwOxb2eGqsXbTMON3imUGkc1jRdtXrbbohiLSCSk3jFVXgJLTMaEcr39pR00N8nE9uZ+V2sYaiILByZVmxQ==", - "dev": true, - "requires": { - "@commitlint/is-ignored": "^16.2.4", - "@commitlint/parse": "^16.2.1", - "@commitlint/rules": "^16.2.4", - "@commitlint/types": "^16.2.1" - } - }, - "@commitlint/load": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.3.0.tgz", - "integrity": "sha512-3tykjV/iwbkv2FU9DG+NZ/JqmP0Nm3b7aDwgCNQhhKV5P74JAuByULkafnhn+zsFGypG1qMtI5u+BZoa9APm0A==", - "dev": true, - "requires": { - "@commitlint/config-validator": "^16.2.1", - "@commitlint/execute-rule": "^16.2.1", - "@commitlint/resolve-extends": "^16.2.1", - "@commitlint/types": "^16.2.1", - "@types/node": ">=12", - "chalk": "^4.0.0", - "cosmiconfig": "^7.0.0", - "cosmiconfig-typescript-loader": "^2.0.0", - "lodash": "^4.17.19", - "resolve-from": "^5.0.0", - "typescript": "^4.4.3" - } - }, - "@commitlint/message": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz", - "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==", - "dev": true - }, - "@commitlint/parse": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz", - "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==", - "dev": true, - "requires": { - "@commitlint/types": "^16.2.1", - "conventional-changelog-angular": "^5.0.11", - "conventional-commits-parser": "^3.2.2" - } - }, - "@commitlint/read": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz", - "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==", - "dev": true, - "requires": { - "@commitlint/top-level": "^16.2.1", - "@commitlint/types": "^16.2.1", - "fs-extra": "^10.0.0", - "git-raw-commits": "^2.0.0" - } - }, - "@commitlint/resolve-extends": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz", - "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==", - "dev": true, - "requires": { - "@commitlint/config-validator": "^16.2.1", - "@commitlint/types": "^16.2.1", - "import-fresh": "^3.0.0", - "lodash": "^4.17.19", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" - } - }, - "@commitlint/rules": { - "version": "16.2.4", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.4.tgz", - "integrity": "sha512-rK5rNBIN2ZQNQK+I6trRPK3dWa0MtaTN4xnwOma1qxa4d5wQMQJtScwTZjTJeallFxhOgbNOgr48AMHkdounVg==", - "dev": true, - "requires": { - "@commitlint/ensure": "^16.2.1", - "@commitlint/message": "^16.2.1", - "@commitlint/to-lines": "^16.2.1", - "@commitlint/types": "^16.2.1", - "execa": "^5.0.0" - } - }, - "@commitlint/to-lines": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz", - "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==", - "dev": true - }, - "@commitlint/top-level": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz", - "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } + "node_modules/@commitlint/message": { + "version": "20.4.3", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.3.tgz", + "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" } }, - "@commitlint/types": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz", - "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==", + "node_modules/@commitlint/parse": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.5.0.tgz", + "integrity": "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==", "dev": true, - "requires": { - "chalk": "^4.0.0" + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.5.0", + "conventional-changelog-angular": "^8.2.0", + "conventional-commits-parser": "^6.3.0" + }, + "engines": { + "node": ">=v18" } }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@commitlint/read": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.5.0.tgz", + "integrity": "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==", "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^20.4.3", + "@commitlint/types": "^20.5.0", + "git-raw-commits": "^5.0.0", + "minimist": "^1.2.8", + "tinyexec": "^1.0.0" + }, + "engines": { + "node": ">=v18" } }, - "@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true + "node_modules/@commitlint/resolve-extends": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.5.0.tgz", + "integrity": "sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^20.5.0", + "@commitlint/types": "^20.5.0", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true + "node_modules/@commitlint/rules": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.5.0.tgz", + "integrity": "sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^20.5.0", + "@commitlint/message": "^20.4.3", + "@commitlint/to-lines": "^20.0.0", + "@commitlint/types": "^20.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz", + "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "20.4.3", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.3.tgz", + "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0" + }, + "engines": { + "node": ">=v18" + } }, - "@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true + "node_modules/@commitlint/types": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.5.0.tgz", + "integrity": "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-parser": "^6.3.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@conventional-changelog/git-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.7.0.tgz", + "integrity": "sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@simple-libs/child-process-utils": "^1.0.0", + "@simple-libs/stream-utils": "^1.2.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.4.0" + }, + "peerDependenciesMeta": { + "conventional-commits-filter": { + "optional": true + }, + "conventional-commits-parser": { + "optional": true + } + } }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "license": "Apache-2.0", + "engines": { + "node": ">=6.9.0" } }, - "@redis/bloom": { + "node_modules/@redis/bloom": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.12.1.tgz", - "integrity": "sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==" + "integrity": "sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==", + "license": "MIT", + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } }, - "@redis/client": { + "node_modules/@redis/client": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.12.1.tgz", "integrity": "sha512-7aPGWeqA3uFm43o19umzdl16CEjK/JQGtSXVPevplTaOU3VJA/rseBC1QvYUz9lLDIMBimc4SW/zrW4S89BaCA==", - "requires": { + "license": "MIT", + "dependencies": { "cluster-key-slot": "1.1.2" + }, + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@node-rs/xxhash": "^1.1.0", + "@opentelemetry/api": ">=1 <2" + }, + "peerDependenciesMeta": { + "@node-rs/xxhash": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + } } }, - "@redis/json": { + "node_modules/@redis/json": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.12.1.tgz", - "integrity": "sha512-eOze75esLve4vfqDel7aMX08CNaiLLQS2fV8mpRN9NxPe1rVR4vQyYiW/OgtGUysF6QOr9ANhfxABKNOJfXdKg==" + "integrity": "sha512-eOze75esLve4vfqDel7aMX08CNaiLLQS2fV8mpRN9NxPe1rVR4vQyYiW/OgtGUysF6QOr9ANhfxABKNOJfXdKg==", + "license": "MIT", + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } }, - "@redis/search": { + "node_modules/@redis/search": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.12.1.tgz", - "integrity": "sha512-ItlxbxC9cKI6IU1TLWoczwJCRb6TdmkEpWv05UrPawqaAnWGRu3rcIqsc5vN483T2fSociuyV1UkWIL5I4//2w==" + "integrity": "sha512-ItlxbxC9cKI6IU1TLWoczwJCRb6TdmkEpWv05UrPawqaAnWGRu3rcIqsc5vN483T2fSociuyV1UkWIL5I4//2w==", + "license": "MIT", + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } }, - "@redis/time-series": { + "node_modules/@redis/time-series": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.12.1.tgz", - "integrity": "sha512-c6JL6E3EcZJuNqKFz+KM+l9l5mpcQiKvTwgA3blt5glWJ8hjDk0yeHN3beE/MpqYIQ8UEX44ItQzgkE/gCBELQ==" - }, - "@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-c6JL6E3EcZJuNqKFz+KM+l9l5mpcQiKvTwgA3blt5glWJ8hjDk0yeHN3beE/MpqYIQ8UEX44ItQzgkE/gCBELQ==", + "license": "MIT", + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "node_modules/@simple-libs/child-process-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", + "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" + } }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "node_modules/@simple-libs/stream-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", + "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" + } }, - "@types/minimist": { + "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true + "dev": true, + "license": "MIT" }, - "@types/node": { + "node_modules/@types/node": { "version": "25.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "dev": true, - "requires": { + "license": "MIT", + "peer": true, + "dependencies": { "undici-types": "~7.19.0" } }, - "@types/normalize-package-data": { + "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true - }, - "acorn-walk": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", - "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", "dev": true, - "requires": { - "acorn": "^8.11.0" - } + "license": "MIT" }, - "add-stream": { + "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "after": { + "node_modules/after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==" + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", + "license": "MIT" }, - "ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, + "license": "MIT", "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "ansi-regex": { + "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { - "color-convert": "^2.0.1" + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" }, - "array-ify": { + "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true + "dev": true, + "license": "MIT" }, - "arrify": { + "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "assembly-source": { + "node_modules/assembly-source": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assembly-source/-/assembly-source-1.0.0.tgz", "integrity": "sha512-G54OWV9A4xBC1iuUjOGAtNHr2R+IDS6MV+EuNyZLKb4NmRkOVTLhbAHfg0dDKTNWsco81aSMDMKHLnjytr62mw==", - "requires": { + "license": "MIT", + "dependencies": { "esprima": "^4.0.0", "is-options": "^1.0.1", "pascal-case": "^3.1.1" + }, + "engines": { + "node": ">=10" } }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "b4a": { + "node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", - "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==" + "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "requires": { + "license": "MIT", + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "requires": { - "fill-range": "^7.1.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { + "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", - "dev": true + "dev": true, + "license": "MIT" }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==" + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "camelcase-keys": { + "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } }, - "classifier": { + "node_modules/classifier": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/classifier/-/classifier-0.1.0.tgz", "integrity": "sha512-lHoacZqTxberxbsaT/bDkvUicTl6nVTqnM5X6PhCTCg6Y3uhd/lWqbtMvHwe0W0vGkPWCVw5NTUTi3SOlccaSA==", - "requires": { + "deprecated": "Package no longer supported. Contact support@npmjs.com for more info.", + "dependencies": { "redis": ">=0.7.0", "underscore": ">=1.1.0" + }, + "engines": { + "node": "*" } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true - }, - "cliui": { + "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true - }, - "cluster-key-slot": { + "node_modules/cluster-key-slot": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { - "color-name": "~1.1.4" + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commitizen": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.1.tgz", - "integrity": "sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==", - "dev": true, - "requires": { - "cachedir": "2.3.0", - "cz-conventional-changelog": "3.3.0", - "dedent": "0.7.0", - "detect-indent": "6.1.0", - "find-node-modules": "^2.1.2", - "find-root": "1.1.0", - "fs-extra": "9.1.0", - "glob": "7.2.3", - "inquirer": "8.2.5", - "is-utf8": "^0.2.1", - "lodash": "4.17.21", - "minimist": "1.2.7", - "strip-bom": "4.0.0", - "strip-json-comments": "3.1.1" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true - } - } + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" }, - "common-roots": { + "node_modules/common-roots": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/common-roots/-/common-roots-0.0.2.tgz", "integrity": "sha512-ZnqiSLPHOR+KheKcg1K4y31iVx8N3lmflfEtLUztmMR4bLE+0dSH9Notp31vZBpnCVdnmW8FycfKKW8NKFo1tg==", - "requires": { + "license": "MIT", + "dependencies": { "find-file-up": "~1.0.2", "path-is-inside": "~1.0.2" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=2.0.0" } }, - "compare-func": { + "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, - "concat-stream": { + "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, - "requires": { + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, - "conventional-changelog": { + "node_modules/conventional-changelog": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "conventional-changelog-angular": "^5.0.12", "conventional-changelog-atom": "^2.0.8", "conventional-changelog-codemirror": "^2.0.8", @@ -779,59 +772,77 @@ "conventional-changelog-jquery": "^3.0.11", "conventional-changelog-jshint": "^2.0.9", "conventional-changelog-preset-loader": "^2.3.4" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "node_modules/conventional-changelog-angular": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz", + "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==", "dev": true, - "requires": { - "compare-func": "^2.0.0", - "q": "^1.5.1" + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" } }, - "conventional-changelog-atom": { + "node_modules/conventional-changelog-atom": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-codemirror": { + "node_modules/conventional-changelog-codemirror": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-config-spec": { + "node_modules/conventional-changelog-config-spec": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "conventional-changelog-conventionalcommits": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", - "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "node_modules/conventional-changelog-conventionalcommits": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz", + "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==", "dev": true, - "requires": { - "compare-func": "^2.0.0", - "lodash": "^4.17.15", - "q": "^1.5.1" + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" } }, - "conventional-changelog-core": { + "node_modules/conventional-changelog-core": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "add-stream": "^1.0.0", "conventional-changelog-writer": "^5.0.0", "conventional-commits-parser": "^3.2.0", @@ -847,502 +858,1043 @@ "read-pkg-up": "^3.0.0", "through2": "^4.0.0" }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - } - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } + "engines": { + "node": ">=10" } }, - "conventional-changelog-ember": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", - "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "node_modules/conventional-changelog-core/node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-eslint": { - "version": "3.0.9", + "license": "MIT", + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-core/node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-changelog-core/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-core/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-changelog-core/node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-core/node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-changelog-core/node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-core/node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/conventional-changelog-core/node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-core/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/conventional-changelog-core/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "license": "ISC", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-eslint": { + "version": "3.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "q": "^1.5.1" + }, + "engines": { + "node": ">=10" } }, - "conventional-changelog-express": { + "node_modules/conventional-changelog-express": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "license": "ISC", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-writer/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-changelog-writer/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-writer/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-changelog-writer/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-changelog-writer/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-writer/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-writer/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-changelog-writer/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-writer/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/conventional-changelog-writer/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/conventional-changelog-writer/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/conventional-changelog-writer/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog/node_modules/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog/node_modules/conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz", + "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0", + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", "q": "^1.5.1" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-recommended-bump/node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-recommended-bump/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-recommended-bump/node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-recommended-bump/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-recommended-bump/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-recommended-bump/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-recommended-bump/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-recommended-bump/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/conventional-recommended-bump/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" } }, - "conventional-changelog-jquery": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", - "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "node_modules/conventional-recommended-bump/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, - "requires": { - "q": "^1.5.1" + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "conventional-changelog-jshint": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", - "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "node_modules/conventional-recommended-bump/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "requires": { - "compare-func": "^2.0.0", - "q": "^1.5.1" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" } }, - "conventional-changelog-preset-loader": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", - "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", - "dev": true - }, - "conventional-changelog-writer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", - "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "node_modules/conventional-recommended-bump/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "requires": { - "conventional-commits-filter": "^2.0.7", - "dateformat": "^3.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^4.0.0" - }, + "license": "BSD-2-Clause", "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "conventional-commit-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", - "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", - "dev": true - }, - "conventional-commits-filter": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", - "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "node_modules/conventional-recommended-bump/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" } }, - "conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "node_modules/conventional-recommended-bump/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "conventional-recommended-bump": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", - "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "node_modules/conventional-recommended-bump/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "requires": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^2.3.4", - "conventional-commits-filter": "^2.0.7", - "conventional-commits-parser": "^3.2.0", - "git-raw-commits": "^2.0.8", - "git-semver-tags": "^4.1.1", - "meow": "^8.0.0", - "q": "^1.5.1" + "license": "ISC", + "engines": { + "node": ">=10" } }, - "core-util-is": { + "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } + "license": "MIT" }, - "cosmiconfig-typescript-loader": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-2.0.2.tgz", - "integrity": "sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==", + "node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, - "requires": { - "cosmiconfig": "^7", - "ts-node": "^10.8.1" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true } } }, - "cz-conventional-changelog": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", - "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", - "dev": true, - "requires": { - "@commitlint/load": ">6.1.1", - "chalk": "^2.4.1", - "commitizen": "^4.0.3", - "conventional-commit-types": "^3.0.0", - "lodash.map": "^4.5.1", - "longest": "^2.0.1", - "word-wrap": "^1.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.3.0.tgz", + "integrity": "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "2.6.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" } }, - "dargs": { + "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "dateformat": { + "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } }, - "decamelize": { + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "decamelize-keys": { + "node_modules/decamelize-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, - "requires": { - "clone": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true - }, - "detect-indent": { + "node_modules/detect-indent": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "detect-newline": { + "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "dot-prop": { + "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "dotgitignore": { + "node_modules/dotgitignore": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "find-up": "^3.0.0", "minimatch": "^3.0.4" }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "license": "MIT", "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotgitignore/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, - "dotnet-bump": { + "node_modules/dotnet-bump": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/dotnet-bump/-/dotnet-bump-1.6.0.tgz", "integrity": "sha512-ILccmPZu2NmQ4Q1nIHDmILGsIbUsS0CbN4hW7SKMVcsOIQGP89kHIdpM3Z8BfRWYd+xz8+RMfkcQ3jlMiFcH8Q==", - "requires": { + "license": "MIT", + "dependencies": { "after": "0.8.2", "assembly-source": "^1.0.0", "common-roots": "0.0.2", @@ -1358,56 +1910,96 @@ "saxophonist": "^2.0.0", "semver": "^7.3.2", "vssln-parser": "0.1.4" + }, + "bin": { + "dotnet-bump": "cli.js" + }, + "engines": { + "node": ">=10" } }, - "duplexer": { + "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" }, - "emoji-regex": { + "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, - "error-ex": { + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-arrayish": "^0.2.1" } }, - "es-errors": { + "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, - "escalade": { + "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "event-stream": { + "node_modules/event-stream": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", - "requires": { + "license": "MIT", + "dependencies": { "duplexer": "^0.1.1", "from": "^0.1.7", "map-stream": "0.0.7", @@ -1417,1388 +2009,1877 @@ "through": "^2.3.8" } }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "expand-tilde": { + "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "requires": { + "license": "MIT", + "dependencies": { "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "extend": { + "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-file-up": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-1.0.2.tgz", + "integrity": "sha512-spzIszRVDalArjm9/ZVRK1q9YW6WdX92RUIni/VqmhUqSvTkq6H+TgCarqvaJHOVt5fLpeIKJgb0L0pbCK2/9g==", + "license": "MIT", + "dependencies": { + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/get-pkg-repo/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "node_modules/get-pkg-repo/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/get-pkg-repo/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "requires": { - "to-regex-range": "^5.0.1" + "license": "ISC", + "engines": { + "node": ">=10" } }, - "find-file-up": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-1.0.2.tgz", - "integrity": "sha512-spzIszRVDalArjm9/ZVRK1q9YW6WdX92RUIni/VqmhUqSvTkq6H+TgCarqvaJHOVt5fLpeIKJgb0L0pbCK2/9g==", - "requires": { - "resolve-dir": "^1.0.0" + "node_modules/git-raw-commits": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", + "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@conventional-changelog/git-client": "^2.6.0", + "meow": "^13.0.0" + }, + "bin": { + "git-raw-commits": "src/cli.js" + }, + "engines": { + "node": ">=18" } }, - "find-node-modules": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", - "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", "dev": true, - "requires": { - "findup-sync": "^4.0.0", - "merge": "^2.1.1" + "license": "MIT", + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" } }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true + "node_modules/git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } }, - "find-up": { + "node_modules/git-semver-tags/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "node_modules/git-semver-tags/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - } + "license": "ISC" }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + "node_modules/git-semver-tags/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/git-semver-tags/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "node_modules/git-semver-tags/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true + "node_modules/git-semver-tags/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "node_modules/git-semver-tags/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } }, - "get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "node_modules/git-semver-tags/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, - "requires": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-semver-tags/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/git-semver-tags/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "node_modules/git-semver-tags/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } }, - "git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "node_modules/git-semver-tags/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, - "requires": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" } }, - "git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "node_modules/git-semver-tags/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "requires": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "git-semver-tags": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", - "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "node_modules/git-semver-tags/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "requires": { - "meow": "^8.0.0", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } + "license": "ISC", + "engines": { + "node": ">=10" } }, - "gitconfiglocal": { + "node_modules/gitconfiglocal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", "dev": true, - "requires": { + "license": "BSD", + "dependencies": { "ini": "^1.3.2" } }, - "glob": { + "node_modules/gitconfiglocal/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, - "requires": { - "ini": "^1.3.4" + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "global-modules": { + "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "requires": { + "license": "MIT", + "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "global-prefix": { + "node_modules/global-prefix": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "requires": { + "license": "MIT", + "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" } }, - "graceful-fs": { + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, - "handlebars": { + "node_modules/handlebars": { "version": "4.7.9", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", - "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "hard-rejection": { + "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "homedir-polyfill": { + "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "requires": { + "license": "MIT", + "dependencies": { "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "hosted-git-info": { + "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "husky": { + "node_modules/husky": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "license": "MIT", + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "import-fresh": { + "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "indent-string": { + "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "inquirer": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", - "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { + "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "is-glob": { + "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "is-obj": { + "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "is-options": { + "node_modules/is-options": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-options/-/is-options-1.0.2.tgz", "integrity": "sha512-u+Ai74c8Q74aS8BuHwPdI1jptGOT1FQXgCq8/zv0xRuE+wRgSMEJLj8lVO8Zp9BeGb29BXY6AsNPinfqjkr7Fg==", - "requires": { + "license": "MIT", + "dependencies": { "b4a": "^1.1.1" } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-text-path": { + "node_modules/is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-windows": { + "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "isarray": { + "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, - "json-parse-better-errors": { + "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "license": "MIT" }, - "json-parse-even-better-errors": { + "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" }, - "json-stringify-safe": { + "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "dev": true, + "license": "ISC" }, - "json5": { + "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "jsonparse": { + "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } }, - "kind-of": { + "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "language-classifier": { + "node_modules/language-classifier": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/language-classifier/-/language-classifier-0.0.1.tgz", "integrity": "sha512-myU10NLx/dfATa7b0NJiycU4jlU15fMLcnfXYEO6NPMhH1vHYKMp9eoRZaQMDTu3bz25bD31Q9klsf26oOW1BQ==", - "requires": { + "dependencies": { "classifier": "~0.1.0" } }, - "language-detect": { + "node_modules/language-detect": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/language-detect/-/language-detect-1.1.0.tgz", "integrity": "sha512-2kXHOATTovlwlh1LJE21DLyGiuvX6bK8CYw9kEyui2FeNBV3EYD2OE9h1ChuWNGXe/TGcm7PqpK/32S614R1Kg==", - "requires": { + "license": "MIT", + "dependencies": { "language-classifier": "0.0.1" } }, - "lines-and-columns": { + "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, - "load-json-file": { + "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - } + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, - "requires": { - "p-locate": "^4.1.0" + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash": { + "node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" }, - "lodash.ismatch": { + "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true + "dev": true, + "license": "MIT" }, - "lodash.map": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", - "dev": true + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } + "license": "MIT" }, - "longest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", - "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", - "dev": true + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" }, - "lower-case": { + "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { + "license": "MIT", + "dependencies": { "tslib": "^2.0.3" } }, - "lru-cache": { + "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "map-obj": { + "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" - }, - "meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "merge": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", - "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "node_modules/map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", + "license": "MIT" }, - "micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "min-indent": { + "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "requires": { + "license": "ISC", + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "minimist-options": { + "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" } }, - "modify-values": { + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "neo-async": { + "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, - "no-case": { + "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { + "license": "MIT", + "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, - "normalize-package-data": { + "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, - "requires": { + "license": "BSD-2-Clause", + "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" } }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { + "license": "ISC", + "dependencies": { "wrappy": "1" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "requires": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "requires": { - "p-try": "^2.0.0" + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "requires": { - "p-limit": "^2.2.0" + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-try": { + "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "parent-module": { + "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-git-status": { + "node_modules/parse-git-status": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/parse-git-status/-/parse-git-status-0.1.0.tgz", - "integrity": "sha512-ngjxaxWtYrNIDYUWrCDcSAgtai3sELojyTauZVMyawYf+J9Cd6BvGQ/clGXrpmmFXkXj81E5zbOkGt8afsb+dw==" + "integrity": "sha512-ngjxaxWtYrNIDYUWrCDcSAgtai3sELojyTauZVMyawYf+J9Cd6BvGQ/clGXrpmmFXkXj81E5zbOkGt8afsb+dw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "parse-json": { + "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parse-passwd": { + "node_modules/parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==" + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "pascal-case": { + "node_modules/pascal-case": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "requires": { + "license": "MIT", + "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, - "path-exists": { + "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "path-is-inside": { + "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "license": "(WTFPL OR MIT)" }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "pause-stream": { + "node_modules/pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "requires": { + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { "through": "~2.3" } }, - "picocolors": { + "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true + "dev": true, + "license": "ISC" }, - "pify": { + "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "process-nextick-args": { + "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, + "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "readable-stream": { + "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { + "license": "MIT", + "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "redent": { + "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "redis": { + "node_modules/redis": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/redis/-/redis-5.12.1.tgz", "integrity": "sha512-LDsoVvb/CpoV9EN3FXvgvSHNJWuCIzl9MiO3ppOevuGLpSGJhwfQjpEwfFJcQvNSddHADDdZaWx0HnmMxRXG7g==", - "requires": { + "license": "MIT", + "dependencies": { "@redis/bloom": "5.12.1", "@redis/client": "5.12.1", "@redis/json": "5.12.1", "@redis/search": "5.12.1", "@redis/time-series": "5.12.1" + }, + "engines": { + "node": ">= 18.19.0" } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-dir": { + "node_modules/resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "requires": { + "license": "MIT", + "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", "dev": true, - "requires": { - "global-dirs": "^0.1.1" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "rimraf": { + "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-series": { + "node_modules/run-series": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", - "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==" - }, - "rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, - "sax": { + "node_modules/sax": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", - "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==" + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, - "saxophonist": { + "node_modules/saxophonist": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/saxophonist/-/saxophonist-2.0.0.tgz", "integrity": "sha512-giWxUqGm3VdFxO4LaD+BTgec8dEEmm8Ysh6hRHn4r3VOw4yoz7hfOZWPteFu7vSXdK2BY5qAXdcwtAeziRH5OQ==", - "requires": { + "license": "MIT", + "dependencies": { "inherits": "^2.0.1", "readable-stream": "^3.5.0", "sax": "^1.1.4" } }, - "semver": { + "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { + "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "dev": true, + "license": "CC-BY-3.0" }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, - "split": { + "node_modules/split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { + "license": "MIT", + "dependencies": { "through": "2" + }, + "engines": { + "node": "*" } }, - "split2": { + "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "readable-stream": "^3.0.0" } }, - "standard-version": { + "node_modules/standard-version": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "chalk": "^2.4.2", "conventional-changelog": "3.1.25", "conventional-changelog-config-spec": "2.1.0", @@ -2814,434 +3895,429 @@ "stringify-package": "^1.0.1", "yargs": "^16.0.0" }, + "bin": { + "standard-version": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/standard-version/node_modules/conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" } }, - "stream-combiner": { + "node_modules/stream-combiner": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", - "requires": { + "license": "MIT", + "dependencies": { "duplexer": "~0.1.1", "through": "~2.3.4" } }, - "string-width": { + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-package": { + "node_modules/stringify-package": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", - "dev": true + "deprecated": "This module is not used anymore, and has been replaced by @npmcli/package-json", + "dev": true, + "license": "ISC" }, - "strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "strip-indent": { + "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { - "has-flag": "^4.0.0" + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "supports-preserve-symlinks-flag": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "text-extensions": { + "node_modules/text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" }, - "through2": { + "node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "readable-stream": "3" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/tinyexec": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz", + "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==", "dev": true, - "requires": { - "is-number": "^7.0.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "trim-newlines": { + "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tslib": { + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, - "type-fest": { + "node_modules/type-fest": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "dev": true, + "license": "MIT" }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } }, - "uglify-js": { + "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, - "optional": true + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } }, - "underscore": { + "node_modules/underscore": { "version": "1.13.8", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", - "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==" + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "license": "MIT" }, - "undici-types": { + "node_modules/undici-types": { "version": "7.19.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", - "dev": true - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { - "punycode": "^2.1.0" - } + "license": "MIT", + "peer": true }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "vssln-parser": { + "node_modules/vssln-parser": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/vssln-parser/-/vssln-parser-0.1.4.tgz", "integrity": "sha512-5t0IDc03/pKFY1iC5LTv0DLQgvo5Oa9e9FoqvuyisJwqxH4FepzcSen+/xmaBMsZNjKWzKnIpMeFzKQiL7TpWA==", - "requires": { + "license": "MIT", + "dependencies": { "camelcase": "^3.0.0", "event-stream": "^3.3.4", "extend": "^3.0.0" } }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { + "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { + "license": "ISC", + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "wordwrap": { + "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "dev": true, + "license": "MIT" }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "wrappy": { + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yaml": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", - "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", - "dev": true + "dev": true, + "license": "ISC" }, - "yargs": { + "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -3250,32 +4326,32 @@ "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, - "dependencies": { - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index ebcd419ba..d645ee6d7 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "bump:patch": "npm run bump:npm:patch && npm run bump:dotnet:patch && npm run gen:changelog", "bump:feature": "npm run bump:npm:feature && npm run bump:dotnet:feature && npm run gen:changelog", "bump:breaking": "npm run bump:npm:breaking && npm run bump:dotnet:breaking && npm run gen:changelog", - "build:prod": "npm run build:clean && npm run build:prod:win && npm run build:prod:linux && npm run build:prod:osx", + "build:prod": "npm run build:clean && npm run build:prod:win && npm run build:prod:linux", "build:prod:singlefile": "npm run build:clean && npm run build:prod:singlefile:win && npm run build:prod:singlefile:linux && npm run build:prod:singlefile:osx", "build:prod:win": "dotnet publish ./cmf-cli/cmf.csproj -c Release -r win-x64 -o dist/win-x64 --self-contained /p:IncludeSourceRevisionInInformationalVersion=false", "build:prod:linux": "dotnet publish ./cmf-cli/cmf.csproj -c Release -r linux-x64 -o dist/linux-x64 --self-contained /p:IncludeSourceRevisionInInformationalVersion=false", @@ -45,11 +45,6 @@ "gen:changelog": "cd npm && standard-version && cd ..", "commit": "git-cz" }, - "config": { - "commitizen": { - "path": "@commitlint/cz-commitlint" - } - }, "author": "Marco Silva", "license": "BSD-3-Clause", "dependencies": { @@ -57,10 +52,8 @@ "rimraf": "^3.0.2" }, "devDependencies": { - "@commitlint/cli": "^16.3.0", - "@commitlint/config-conventional": "^16.2.4", - "@commitlint/cz-commitlint": "^16.3.0", - "commitizen": "^4.2.5", + "@commitlint/cli": "^20.5.0", + "@commitlint/config-conventional": "^20.5.0", "husky": "^7.0.4", "standard-version": "^9.5.0" } diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 000000000..8216247bd --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,10 @@ +{ + "version": 1, + "skills": { + "dotnet-best-practices": { + "source": "github/awesome-copilot", + "sourceType": "github", + "computedHash": "9ef94db7f06c167d544369817e5a4415eeb7886dcff0d47026837a1aada260e3" + } + } +} diff --git a/tests/Fixtures/new/.project-config.json b/tests/Fixtures/new/.project-config.json index 7e16fdf01..cf10701bf 100644 --- a/tests/Fixtures/new/.project-config.json +++ b/tests/Fixtures/new/.project-config.json @@ -8,13 +8,13 @@ "DefaultDomain": "DOMAIN", "RESTPort": "1234", "Tenant": "tenant", - "MESVersion": "8.2.0", - "DevTasksVersion": "8.1.0", - "HTMLStarterVersion": "8.0.0", - "YoGeneratorVersion": "8.1.0", + "MESVersion": "11.2.2", + "DevTasksVersion": "10.1.0", + "HTMLStarterVersion": "10.0.0", + "YoGeneratorVersion": "10.1.0", "NGXSchematicsVersion": "10.0.0", - "NugetVersion": "8.2.0", - "TestScenariosNugetVersion": "8.2.0", + "NugetVersion": "10.2.0", + "TestScenariosNugetVersion": "10.2.0", "IsSslEnabled": "True", "vmHostname": "app_server_address", "DBReplica1": "server1\\instance", diff --git a/tests/Fixtures/pack/app/.project-config.json b/tests/Fixtures/pack/app/.project-config.json index 718987470..4af58cbda 100644 --- a/tests/Fixtures/pack/app/.project-config.json +++ b/tests/Fixtures/pack/app/.project-config.json @@ -3,15 +3,14 @@ "NPMRegistry": "http://npm_registry/", "RepositoryType": "App", "BaseLayer": "Core", - "NuGetRegistry": "htt://nuget_registry/", - "RepositoryURL": "https://repo_url/collection/project/_git/repo", + "NuGetRegistry": "http://nuget_registry/", "EnvironmentName": "system_name", "DefaultDomain": "DOMAIN", "RESTPort": "1234", "Tenant": "tenant", "MESVersion": "10.2.1", - "NugetVersion": "10.0.0", - "TestScenariosNugetVersion": "10.0.0", + "NGXSchematicsVersion": "10.0.0", + "TestScenariosNugetVersion": "8.2.0", "IsSslEnabled": "True", "vmHostname": "app_server_address", "DBReplica1": "server1\\instance", diff --git a/tests/Fixtures/pack/securityPortal/.project-config.json b/tests/Fixtures/pack/securityPortal/.project-config.json index 67c1282af..db321b2f8 100644 --- a/tests/Fixtures/pack/securityPortal/.project-config.json +++ b/tests/Fixtures/pack/securityPortal/.project-config.json @@ -10,12 +10,12 @@ "DefaultDomain": "DOMAIN", "RESTPort": "1234", "Tenant": "tenant", - "MESVersion": "8.2.0", - "DevTasksVersion": "8.1.0", - "HTMLStarterVersion": "8.0.0", - "YoGeneratorVersion": "8.1.0", - "NugetVersion": "8.2.0", - "TestScenariosNugetVersion": "8.2.0", + "MESVersion": "10.0.0", + "DevTasksVersion": "10.0.0", + "HTMLStarterVersion": "10.0.0", + "YoGeneratorVersion": "10.0.0", + "NugetVersion": "10.0.0", + "TestScenariosNugetVersion": "10.0.0", "IsSslEnabled": "True", "vmHostname": "app_server_address", "DBReplica1": "server1\\instance", diff --git a/tests/Fixtures/pack/securityPortalV2/.project-config.json b/tests/Fixtures/pack/securityPortalV2/.project-config.json index 9080288a7..708610425 100644 --- a/tests/Fixtures/pack/securityPortalV2/.project-config.json +++ b/tests/Fixtures/pack/securityPortalV2/.project-config.json @@ -11,11 +11,11 @@ "RESTPort": "1234", "Tenant": "tenant", "MESVersion": "10.2.0", - "DevTasksVersion": "8.1.0", - "HTMLStarterVersion": "8.0.0", - "YoGeneratorVersion": "8.1.0", - "NugetVersion": "8.2.0", - "TestScenariosNugetVersion": "8.2.0", + "DevTasksVersion": "10.1.0", + "HTMLStarterVersion": "10.0.0", + "YoGeneratorVersion": "10.1.0", + "NugetVersion": "10.2.0", + "TestScenariosNugetVersion": "10.2.0", "IsSslEnabled": "True", "vmHostname": "app_server_address", "DBReplica1": "server1\\instance", diff --git a/tests/Fixtures/prodPkg/Cmf.Documentation.9.9.9.zip b/tests/Fixtures/prodPkg/Cmf.Documentation.9.9.9.zip deleted file mode 100644 index 75b26e2c0..000000000 Binary files a/tests/Fixtures/prodPkg/Cmf.Documentation.9.9.9.zip and /dev/null differ diff --git a/tests/Fixtures/prodPkg/Cmf.Presentation.HTML.9.9.9.zip b/tests/Fixtures/prodPkg/Cmf.Presentation.HTML.9.9.9.zip deleted file mode 100644 index 0a97c89a6..000000000 Binary files a/tests/Fixtures/prodPkg/Cmf.Presentation.HTML.9.9.9.zip and /dev/null differ diff --git a/tests/Objects/MockPackage.cs b/tests/Objects/MockPackage.cs index 0523f0be4..a8b8e422e 100644 --- a/tests/Objects/MockPackage.cs +++ b/tests/Objects/MockPackage.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO.Abstractions.TestingHelpers; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace tests.Objects { @@ -13,9 +9,28 @@ internal static class MockPackage { { MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData( @"{ - ""MESVersion"": ""9.0.0"" + ""MESVersion"": ""10.0.0"" }") }, + { MockUnixSupport.Path(@"c:\ui\angular.json"), new MockFileData( + $@"{{ + ""$schema"": ""./node_modules/@angular/cli/lib/config/schema.json"", + ""version"": 1, + ""newProjectRoot"": ""projects"", + ""projects"": {{ + ""Cmf.Custom.HTML"": {{ + ""projectType"": ""application"", + ""schematics"": {{ + ""@schematics/angular:component"": {{ + ""style"": ""less"" + }} + }}, + ""root"": """", + ""sourceRoot"": ""src"", + }} + }} + }}") + }, { MockUnixSupport.Path(@"c:\ui\src\packages\customization.common\package.json"), new MockFileData( @"{ ""name"": ""customization.package"" @@ -53,7 +68,7 @@ internal static class MockPackage }")}, { MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData( @"{ - ""MESVersion"": ""9.0.0"" + ""MESVersion"": ""10.0.0"" }") }, { MockUnixSupport.Path(@"c:\ui\package.json"), new MockFileData( @@ -95,7 +110,7 @@ internal static class MockPackage { { MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData( @"{ - ""MESVersion"": ""9.0.0"" + ""MESVersion"": ""10.0.0"" }") }, { MockUnixSupport.Path(@"c:\ui\package.json"), new MockFileData( @@ -121,7 +136,24 @@ internal static class MockPackage }} ] }}") - } + }, + { MockUnixSupport.Path(@"c:\ui\angular.json"), new MockFileData( + $@"{{ + ""$schema"": ""./node_modules/@angular/cli/lib/config/schema.json"", + ""version"": 1, + ""newProjectRoot"": ""projects"", + ""projects"": {{ + ""Cmf.Custom.HTML"": {{ + ""projectType"": ""application"", + ""schematics"": {{ + ""@schematics/angular:component"": {{ + ""style"": ""less"" + }} + }} + }} + }} + }}") + }, }); internal static readonly MockFileSystem Html_EmptyContentToPack = new MockFileSystem(new Dictionary diff --git a/tests/Specs/Assemble.cs b/tests/Specs/Assemble.cs index 88ad6b2bd..8df83122a 100644 --- a/tests/Specs/Assemble.cs +++ b/tests/Specs/Assemble.cs @@ -771,19 +771,24 @@ public void Assemble_ConfigureCommand() var parseResult = cmd.Parse("dir --outputDir output"); cmd.Options.Should().HaveCount(4); - cmd.Options.Should().Contain(o => o.Aliases.Contains("--cirepo")); - cmd.Options.Should().Contain(o => o.Aliases.Contains("--repo")); - cmd.Options.Should().Contain(o => o.Aliases.Contains("--includeTestPackages")); - cmd.Options.Should().Contain(o => o.Aliases.Contains("--outputDir")); + cmd.Options.Should().Contain(o => o.Name == "--outputDir" || o.Aliases.Any(a => a == "--outputDir")); + cmd.Options.Should().Contain(o => o.Name == "--cirepo" || o.Aliases.Any(a => a == "--cirepo")); + cmd.Options.Should().Contain(o => o.Name == "--repo" || o.Aliases.Any(a => a == "--repo" || a == "--repos")); + cmd.Options.Should().Contain(o => o.Name == "--includeTestPackages" || o.Aliases.Any(a => a == "--includeTestPackages")); cmd.Arguments.Should().HaveCount(1); cmd.Arguments.Should().Contain(a => a.Name == "workingDir"); - cmd.Handler.Should().NotBeNull(); - + // In beta5, Command.Handler property was removed - handlers are managed differently + // The handler is set internally via SetHandler, but there's no public Handler property to check + // cmd.Handler.Should().NotBeNull(); // Removed in beta5 + parseResult.Should().NotBeNull(); - parseResult.GetValueForArgument(cmd.Arguments.ElementAt(0)).ToString().Should().Be("dir"); - parseResult.GetValueForOption(cmd.Options.First(o=> o.Aliases.Contains("--outputDir"))).ToString().Should().Be("output"); + // In beta5, GetValueForArgument/GetValueForOption signatures changed - use GetValue() with explicit type + var workingDirArg = cmd.Arguments.ElementAt(0) as Argument; + var outputDirOption = cmd.Options.First(o=> o.Name == "--outputDir" || o.Aliases.Any(a => a == "--outputDir")) as Option; + parseResult.GetValue(workingDirArg)?.Name.Should().Be("dir"); + parseResult.GetValue(outputDirOption)?.Name.Should().Be("output"); } [Fact] diff --git a/tests/Specs/BaseCommand.cs b/tests/Specs/BaseCommand.cs new file mode 100644 index 000000000..f70a9b589 --- /dev/null +++ b/tests/Specs/BaseCommand.cs @@ -0,0 +1,213 @@ +using Cmf.CLI.Core.Commands; +using FluentAssertions; +using System; +using System.CommandLine; +using System.IO.Abstractions.TestingHelpers; +using Xunit; + +namespace tests.Specs; + +public class BaseCommandTests +{ + /// + /// Minimal concrete subclass that exposes ParseUri and ParseUriArray + /// through options, so they can be triggered via command parsing. + /// + private class TestableBaseCommand : BaseCommand + { + public Option UriOption { get; } = new Option("--uri") { Required = false }; + public Option UriArrayOption { get; } = new Option("--uris") + { + Arity = ArgumentArity.ZeroOrMore, + AllowMultipleArgumentsPerToken = true, + Required = false + }; + + public TestableBaseCommand() : base(new MockFileSystem()) { } + + public override void Configure(Command cmd) + { + UriOption.CustomParser = argResult => ParseUri(argResult); + UriArrayOption.CustomParser = argResult => ParseUriArray(argResult); + cmd.Add(UriOption); + cmd.Add(UriArrayOption); + } + + /// Parse a single --uri value and return the result. + public Uri InvokeParseUri(string value) + { + var root = new Command("test"); + Configure(root); + var parseResult = root.Parse(value != null ? new[] { "--uri", value } : Array.Empty()); + return parseResult.GetValue(UriOption); + } + + /// Parse one or more --uris values and return the result. + public Uri[] InvokeParseUriArray(params string[] values) + { + var root = new Command("test"); + Configure(root); + var args = new System.Collections.Generic.List { "--uris" }; + args.AddRange(values); + var parseResult = root.Parse(args.ToArray()); + return parseResult.GetValue(UriArrayOption); + } + } + + // ------------------------------------------------------------------------- + // ParseUri — no token + // ------------------------------------------------------------------------- + + [Fact] + public void ParseUri_NoToken_ReturnsNull() + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUri(null); + result.Should().BeNull(); + } + + // ------------------------------------------------------------------------- + // ParseUri — standard absolute URIs + // ------------------------------------------------------------------------- + + [Theory] + [InlineData("https://example.com", "https://example.com/")] + [InlineData("https://example.com/path/to/feed", "https://example.com/path/to/feed")] + [InlineData("http://registry.example.com:4873/", "http://registry.example.com:4873/")] + public void ParseUri_AbsoluteUrl_ReturnsAbsoluteUri(string input, string expected) + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUri(input); + result.Should().NotBeNull(); + result.IsAbsoluteUri.Should().BeTrue(); + result.ToString().Should().Be(expected); + } + + // ------------------------------------------------------------------------- + // ParseUri — UNC paths + // ------------------------------------------------------------------------- + + [Theory] + [InlineData(@"\\server\share", "file://server/share")] + [InlineData(@"\\server\share\sub", "file://server/share/sub")] + public void ParseUri_UncPath_ReturnsFileUri(string input, string expected) + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUri(input); + result.Should().NotBeNull(); + result.IsAbsoluteUri.Should().BeTrue(); + result.Scheme.Should().Be("file"); + result.ToString().Should().Be(expected); + } + + // ------------------------------------------------------------------------- + // ParseUri — Windows drive paths + // ------------------------------------------------------------------------- + + [Theory] + [InlineData(@"C:\path\to\dir", "file:///C:/path/to/dir")] + [InlineData(@"D:\packages", "file:///D:/packages")] + public void ParseUri_WindowsDrivePath_ReturnsFileUri(string input, string expected) + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUri(input); + result.Should().NotBeNull(); + result.IsAbsoluteUri.Should().BeTrue(); + result.Scheme.Should().Be("file"); + result.ToString().Should().Be(expected); + } + + // ------------------------------------------------------------------------- + // ParseUri — relative paths + // ------------------------------------------------------------------------- + + [Theory] + [InlineData("./relative/path")] + [InlineData("relative/path")] + public void ParseUri_RelativePath_ReturnsRelativeUri(string input) + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUri(input); + result.Should().NotBeNull(); + result.IsAbsoluteUri.Should().BeFalse(); + } + + // ------------------------------------------------------------------------- + // ParseUriArray — no tokens + // ------------------------------------------------------------------------- + + [Fact] + public void ParseUriArray_OptionNotProvided_ReturnsEmpty() + { + // When the option is absent entirely, CustomParser is not invoked; + // the framework returns the type default (empty array). + var root = new Command("test"); + var sut = new TestableBaseCommand(); + sut.Configure(root); + var parseResult = root.Parse(Array.Empty()); + var result = parseResult.GetValue(sut.UriArrayOption); + result.Should().BeNullOrEmpty(); + } + + // ------------------------------------------------------------------------- + // ParseUriArray — single token + // ------------------------------------------------------------------------- + + [Fact] + public void ParseUriArray_SingleUrl_ReturnsSingleElementArray() + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUriArray("https://example.com"); + result.Should().NotBeNull(); + result.Should().HaveCount(1); + result[0].ToString().Should().Be("https://example.com/"); + } + + // ------------------------------------------------------------------------- + // ParseUriArray — multiple tokens + // ------------------------------------------------------------------------- + + [Fact] + public void ParseUriArray_MultipleUrls_ReturnsAllUris() + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUriArray("https://feed1.example.com", "https://feed2.example.com"); + result.Should().NotBeNull(); + result.Should().HaveCount(2); + result[0].ToString().Should().Be("https://feed1.example.com/"); + result[1].ToString().Should().Be("https://feed2.example.com/"); + } + + // ------------------------------------------------------------------------- + // ParseUriArray — multiple tokens with some empty + // ------------------------------------------------------------------------- + + [Fact] + public void ParseUriArray_MultipleUrlsWithEmptyToken_IsIgnored() + { + var sut = new TestableBaseCommand(); + var inputs = new[] { "https://example.com", "", "https://example.org" }; + var result = sut.InvokeParseUriArray(inputs); + + result.Should().NotBeNull(); + result.Should().HaveCount(2); + result[0].ToString().Should().Be("https://example.com/"); + result[1].ToString().Should().Be("https://example.org/"); + } + + + // ------------------------------------------------------------------------- + // ParseUriArray — mixed absolute and UNC + // ------------------------------------------------------------------------- + + [Fact] + public void ParseUriArray_MixedInputs_ParsesAll() + { + var sut = new TestableBaseCommand(); + var result = sut.InvokeParseUriArray("https://example.com", @"\\server\share"); + result.Should().NotBeNull(); + result.Should().HaveCount(2); + result[0].Scheme.Should().Be("https"); + result[1].Scheme.Should().Be("file"); + } +} diff --git a/tests/Specs/Build.cs b/tests/Specs/Build.cs index 3c6c51637..a7803e155 100644 --- a/tests/Specs/Build.cs +++ b/tests/Specs/Build.cs @@ -207,7 +207,7 @@ public void BusinessBuildWith_TestFromInputTrue_CommandWithTestFalse() ""DefaultDomain"": ""DOMAIN"", ""RESTPort"": ""1234"", ""Tenant"": ""tenant"", - ""MESVersion"": ""8.2.0"", + ""MESVersion"": ""10.2.0"", ""DevTasksVersion"": ""8.1.0"", ""HTMLStarterVersion"": ""8.0.0"", ""YoGeneratorVersion"": ""8.1.0"", @@ -305,7 +305,7 @@ public void BusinessBuildWith_TestFromInputTrue_CommandWithTestTrue() ""DefaultDomain"": ""DOMAIN"", ""RESTPort"": ""1234"", ""Tenant"": ""tenant"", - ""MESVersion"": ""8.2.0"", + ""MESVersion"": ""10.2.0"", ""DevTasksVersion"": ""8.1.0"", ""HTMLStarterVersion"": ""8.0.0"", ""YoGeneratorVersion"": ""8.1.0"", @@ -403,7 +403,7 @@ public void BusinessBuildWith_TestFromInputFalse_CommandWithTestTrue() ""DefaultDomain"": ""DOMAIN"", ""RESTPort"": ""1234"", ""Tenant"": ""tenant"", - ""MESVersion"": ""8.2.0"", + ""MESVersion"": ""10.2.0"", ""DevTasksVersion"": ""8.1.0"", ""HTMLStarterVersion"": ""8.0.0"", ""YoGeneratorVersion"": ""8.1.0"", @@ -765,14 +765,11 @@ public void GenericBuildWith_BuildSteps() [Theory] [InlineData("10.0.0")] // MES version > 9: uses projects/cmf-docs-area-* layout - [InlineData("9.0.0")] // MES version <= 9: uses src/packages/cmf.docs.area.* layout public void GenerateMenuItems_FilesAreOrderedAlphabetically(string mesVersion) { - bool isNewLayout = new Version(mesVersion).Major > 9; - // Build the package directory prefix based on MES version layout - string packageDirName = isNewLayout ? "cmf-docs-area-cmf-custom-help" : "cmf.docs.area.cmf.custom.help"; - string packagesRoot = isNewLayout ? "/help/projects" : "/help/src/packages"; + string packageDirName = "cmf-docs-area-cmf-custom-help"; + string packagesRoot = "/help/projects"; string packageDir = $"{packagesRoot}/{packageDirName}"; string assetsDir = $"{packageDir}/assets"; string topicDir = $"{assetsDir}/equipment"; @@ -825,13 +822,10 @@ public void GenerateMenuItems_FilesAreOrderedAlphabetically(string mesVersion) [Theory] [InlineData("10.0.0")] // MES version > 9: uses projects/cmf-docs-area-* layout - [InlineData("9.0.0")] // MES version <= 9: uses src/packages/cmf.docs.area.* layout public void GenerateMenuItems_FoldersAreOrderedAlphabetically(string mesVersion) { - bool isNewLayout = new Version(mesVersion).Major > 9; - - string packageDirName = isNewLayout ? "cmf-docs-area-cmf-custom-help" : "cmf.docs.area.cmf.custom.help"; - string packagesRoot = isNewLayout ? "/help/projects" : "/help/src/packages"; + string packageDirName = "cmf-docs-area-cmf-custom-help"; + string packagesRoot = "/help/projects"; string packageDir = $"{packagesRoot}/{packageDirName}"; string assetsDir = $"{packageDir}/assets"; diff --git a/tests/Specs/Bump.cs b/tests/Specs/Bump.cs index f858089ad..2b81531a7 100644 --- a/tests/Specs/Bump.cs +++ b/tests/Specs/Bump.cs @@ -15,95 +15,6 @@ namespace tests.Specs; public class Bump { - [Theory] - [InlineData("'", "1.0.0")] - [InlineData("\"", "1.0.0")] - [InlineData("'", "")] - public void Bump_MetadataWithAnyQuoteType(string quoteType, string version) - { - // files - string cmfPackageJson = $"help/{CliConstants.CmfPackageFileName}"; - string npmPackageJson = "/help/package.json"; - string metadataTS = - "/help/src/packages/cmf.docs.area.cmf.custom.help/src/cmf.docs.area.cmf.custom.help.metadata.ts"; - - string bumpVersion = "1.0.1"; - - var fileSystem = new MockFileSystem(new Dictionary - { - { - MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData( - @"{ - ""MESVersion"": ""9.0.0"" - }") - }, - { - cmfPackageJson, new MockFileData( - @$"{{ - ""packageId"": ""Cmf.Custom.Help"", - ""version"": ""{version}"", - ""description"": ""Cmf Custom Cmf.Custom.Help Package"", - ""packageType"": ""Help"", - ""isInstallable"": true, - ""isUniqueInstall"": false, - ""contentToPack"": [ - {{ - ""source"": ""src/packages/*"", - ""target"": ""node_modules"", - ""ignoreFiles"": [ - "".npmignore"" - ] - }} - ] - }}") - }, - { - npmPackageJson, new MockFileData( - @$"{{ - ""name"": ""cmf.docs.area"", - ""version"": ""{version}"", - ""description"": ""Help customization package"", - ""private"": true, - ""scripts"": {{ - ""preinstall"": ""node npm.preinstall.js"", - ""postinstall"": ""node npm.postinstall.js"" - }}, - ""repository"": {{ - ""type"": ""git"", - ""url"": ""https://url/git"" - }} - }}") - }, - { - metadataTS, new MockFileData( - @$" - (...) - function applyConfig (packageName: string) {{ - const config: PackageMetadata = {{ - version: {quoteType}{version}{quoteType}, - (...) - ") - } - }); - - ExecutionContext.ServiceProvider = (new ServiceCollection()) - .AddSingleton(new ProjectConfigService()) - .BuildServiceProvider(); - ExecutionContext.Initialize(fileSystem); - - IFileInfo cmfpackageFile = fileSystem.FileInfo.New(cmfPackageJson); - IPackageTypeHandler packageTypeHandler = PackageTypeFactory.GetPackageTypeHandler(cmfpackageFile); - packageTypeHandler.Bump(bumpVersion, ""); - - string cmfPackageVersion = (packageTypeHandler as HelpGulpPackageTypeHandler).CmfPackage.Version; - dynamic packageFile = JsonConvert.DeserializeObject(fileSystem.File.ReadAllText(npmPackageJson)); - string packageFileVersion = packageFile.version; - string metadataFile = fileSystem.File.ReadAllText(metadataTS); - - cmfPackageVersion.Should().Be(bumpVersion); - packageFileVersion.Should().Be(bumpVersion); - metadataFile.Should().Contain($"version: \"{bumpVersion}\""); - } [Theory] [InlineData("alpha.1")] @@ -115,8 +26,7 @@ public void Bump_PreRelease(string preRelease) // files string cmfPackageJson = $"help/{CliConstants.CmfPackageFileName}"; string npmPackageJson = "/help/package.json"; - string metadataTS = - "/help/src/packages/cmf.docs.area.cmf.custom.help/src/cmf.docs.area.cmf.custom.help.metadata.ts"; + string angularJson = "/help/angular.json"; string bumpVersion = "1.0.1"; string expectedVersion = $"{bumpVersion}-{preRelease}"; @@ -126,7 +36,7 @@ public void Bump_PreRelease(string preRelease) { MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData( @"{ - ""MESVersion"": ""9.0.0"" + ""MESVersion"": ""11.0.0"" }") }, { @@ -152,7 +62,7 @@ public void Bump_PreRelease(string preRelease) { npmPackageJson, new MockFileData( @$"{{ - ""name"": ""cmf.docs.area"", + ""name"": ""documentation-portal"", ""version"": ""1.0.0"", ""description"": ""Help customization package"", ""private"": true, @@ -167,18 +77,20 @@ public void Bump_PreRelease(string preRelease) }}") }, { - metadataTS, new MockFileData( - @$" - (...) - function applyConfig (packageName: string) {{ - const config: PackageMetadata = {{ - version: ""1.0.0"", - (...) - ") + angularJson, new MockFileData( + @$"{{ + ""version"": 1, + ""projects"": {{ + ""cmf.docs.area.cmf.custom.help"": {{ + ""projectType"": ""library"", + ""schematics"": ""./src/schematics/collection.json"" + }} + }} + }}") } }); - ExecutionContext.ServiceProvider = (new ServiceCollection()) + ExecutionContext.ServiceProvider = new ServiceCollection() .AddSingleton(new ProjectConfigService()) .BuildServiceProvider(); ExecutionContext.Initialize(fileSystem); @@ -187,14 +99,12 @@ function applyConfig (packageName: string) {{ IPackageTypeHandler packageTypeHandler = PackageTypeFactory.GetPackageTypeHandler(cmfpackageFile); packageTypeHandler.Bump(bumpVersion, preRelease); - string cmfPackageVersion = (packageTypeHandler as HelpGulpPackageTypeHandler).CmfPackage.Version; + string cmfPackageVersion = (packageTypeHandler as HelpNgCliPackageTypeHandler).CmfPackage.Version; dynamic packageFile = JsonConvert.DeserializeObject(fileSystem.File.ReadAllText(npmPackageJson)); string packageFileVersion = packageFile.version; - string metadataFile = fileSystem.File.ReadAllText(metadataTS); cmfPackageVersion.Should().Be(expectedVersion); packageFileVersion.Should().Be(expectedVersion); - metadataFile.Should().Contain($"version: \"{expectedVersion}\""); } [Theory] diff --git a/tests/Specs/DEEValidator.cs b/tests/Specs/DEEValidator.cs index a8353e2ed..1aadb3428 100644 --- a/tests/Specs/DEEValidator.cs +++ b/tests/Specs/DEEValidator.cs @@ -1,7 +1,6 @@ using Cmf.CLI.Commands; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.IO; using System.IO.Abstractions.TestingHelpers; using tests.Objects; using Xunit; @@ -142,9 +141,10 @@ public void Data_DEEValidator_HappyPath() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error == null || string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed {console.Error.ToString()}"); } @@ -215,9 +215,10 @@ public void Data_DEEValidator_AlternateTags(string startConditionTag, string end buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(string.IsNullOrEmpty(console.Error.ToString()) == !shouldError, $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); Assert.True(console.Error.ToString().Contains("Missing indicators:") == shouldError, $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); @@ -297,9 +298,10 @@ public void Data_DEEValidator_FailPath_Indicators(bool noStartCondition, bool no buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(!string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); Assert.True(console.Error.ToString().Contains("Missing indicators:"), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); @@ -355,9 +357,10 @@ public void Data_DEEValidator_FailPath_UseReference() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(!string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); Assert.True(console.Error.ToString().Contains("UseReference contains a whitespace, please refer to the valid format UseReference"), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); @@ -417,9 +420,10 @@ public void Data_DEEValidator_DetailedMissingIndicators() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); var errorOutput = console.Error.ToString(); @@ -432,4 +436,4 @@ public void Data_DEEValidator_DetailedMissingIndicators() "Error message should specify the missing end code indicator"); } } -} +} \ No newline at end of file diff --git a/tests/Specs/Init.cs b/tests/Specs/Init.cs index b138ec0f7..dcfed78d7 100644 --- a/tests/Specs/Init.cs +++ b/tests/Specs/Init.cs @@ -8,8 +8,6 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.IO; -using System.CommandLine.Parsing; using System.IO; using System.Linq; using Cmf.CLI.Services; @@ -33,13 +31,13 @@ public Init() newCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new[] { + var parseResult = cmd.Parse(new[] { "--reset" - }, console); + }); + parseResult.Invoke(console); } [Theory] - [InlineData("8.2.0", DependencyVersionService.NET3SDK)] [InlineData("10.2.0", DependencyVersionService.NET6SDK)] [InlineData("11.0.0", DependencyVersionService.NET8SDK)] public void Init_(string baseVersionStr, string dotnetSDKVersion) @@ -157,7 +155,7 @@ public void Init_Fail_MissingMandatoryArgumentsAndOptions() } [Fact] - public void Init_Fail_MissingOptionsForLTv10() + public void Init_Fail_ForLTv10() { var console = new TestConsole(); var tmp = TestUtilities.GetTmpDirectory(); @@ -184,13 +182,11 @@ public void Init_Fail_MissingOptionsForLTv10() "--nugetRegistry", "http://nuget.example/feed", "--npmRegistry", "http://npm.example/feed", "--ISOLocation", "dummy", + "--ngxSchematicsVersion", "1.3.7", "--deploymentDir", deploymentDir, }, console); - Assert.Contains("DevTasksVersion is required", console.Error.ToString()); - Assert.Contains("HTMLStarterVersion is required", console.Error.ToString()); - Assert.Contains("yoGeneratorVersion is required", console.Error.ToString()); - console.Error.ToString().Should().NotContain("ngxSchematicsVersion is required"); + console.Error.ToString().Should().Contain("MES Versions under 10 are no longer supported with the newest version of the CLI. Please use cmf-cli 5.8.0 or lower."); } finally { @@ -230,7 +226,7 @@ public void Init_Fail_MissingOptionsForGTv10() "--deploymentDir", deploymentDir, }, console); - Assert.Contains("ngxSchematicsVersion is required", console.Error.ToString()); + Assert.Contains("--ngxSchematicsVersion is missing, please specify it.", console.Error.ToString()); console.Error.ToString().Should().NotContain("DevTasksVersion is required"); console.Error.ToString().Should().NotContain("HTMLStarterVersion is required"); console.Error.ToString().Should().NotContain("yoGeneratorVersion is required"); @@ -559,16 +555,17 @@ public void Init_With_Unknown_Option_Instead_Of_Argument() projectName, "--infra", TestUtilities.GetFixturePath("init", "infrastructure.json"), "-c", TestUtilities.GetFixturePath("init", "config.json"), - "--MESVersion", "8.2.0", - "--DevTasksVersion", "8.1.0", - "--HTMLStarterVersion", "8.0.0", - "--yoGeneratorVersion", "8.1.0", - "--nugetVersion", "8.2.0", - "--testScenariosNugetVersion", "8.2.0", + "--MESVersion", "10.2.0", + "--DevTasksVersion", "10.2.0", + "--HTMLStarterVersion", "10.2.0", + "--yoGeneratorVersion", "10.2.0", + "--nugetVersion", "10.2.0", + "--testScenariosNugetVersion", "10.2.0", "--deploymentDir", deploymentDir, "--ISOLocation", isoLocation, "--version", pkgVersion, - "--UnknownOption", "RandomValue" + "--UnknownOption", "RandomValue", + "--ngxSchematicsVersion", "10.2.0" }, console); console.Error.ToString().Should().BeEmpty(); @@ -607,15 +604,16 @@ public void Init_With_Env_Without_Domain() projectName, "--infra", TestUtilities.GetFixturePath("init", "infrastructure.json"), "-c", TestUtilities.GetFixturePath("init", "config_no_AD.json"), - "--MESVersion", "8.2.0", - "--DevTasksVersion", "8.1.0", - "--HTMLStarterVersion", "8.0.0", - "--yoGeneratorVersion", "8.1.0", - "--nugetVersion", "8.2.0", - "--testScenariosNugetVersion", "8.2.0", + "--MESVersion", "10.2.0", + "--DevTasksVersion", "10.2.0", + "--HTMLStarterVersion", "10.0.0", + "--yoGeneratorVersion", "10.1.0", + "--nugetVersion", "10.2.0", + "--testScenariosNugetVersion", "10.2.0", "--deploymentDir", deploymentDir, "--ISOLocation", isoLocation, "--version", pkgVersion, + "--ngxSchematicsVersion", "10.2.0", "Cmf.Custom.Package", tmp }, console); @@ -1251,4 +1249,4 @@ public void Init_TenantCommandLineOverridesConfigFile_NoDuplicateKeyError() } } } -} +} \ No newline at end of file diff --git a/tests/Specs/JsonValidator.cs b/tests/Specs/JsonValidator.cs index 0ec7f01a4..8da5d79e0 100644 --- a/tests/Specs/JsonValidator.cs +++ b/tests/Specs/JsonValidator.cs @@ -1,7 +1,6 @@ using Cmf.CLI.Commands; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.IO; using System.IO.Abstractions.TestingHelpers; using tests.Objects; using Xunit; @@ -72,10 +71,10 @@ public void Data_JsonValidator_HappyPath() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); - + }); + parseResult.Invoke(console); Assert.True(console.Error == null || string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed {console.Error.ToString()}"); } @@ -141,9 +140,10 @@ public void Data_JsonValidator_FailData() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error != null && !string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed for Data Package: {console.Error.ToString()}"); } @@ -248,9 +248,10 @@ public void IoTData_JsonValidator_FailData() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error != null && !string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed for IoT Data Package: {console.Error.ToString()}"); } @@ -355,9 +356,10 @@ public void IoTData_Workflow_JsonValidator_FailData() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(!string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed for IoT Data Workflow Package: {console.Error.ToString()}"); } @@ -434,9 +436,10 @@ public void Data_JsonValidator_HappyPath_Workflow() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error == null || string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed {console.Error.ToString()}"); } @@ -513,9 +516,10 @@ public void Data_JsonValidator_Fail_BackSlash() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(!string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); Assert.True(console.Error.ToString().Contains("Please normalize all slashes to be forward slashes"), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); @@ -1021,9 +1025,10 @@ public void Data_JsonValidator_HappyPath_SubWorkflow() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error == null || string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed {console.Error.ToString()}"); } @@ -1528,9 +1533,10 @@ public void Data_JsonValidator_FailPath_SubWorkflow_NotFoundFile() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(!string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); Assert.True(console.Error.ToString().Contains("Could not find the path Error for the Workflow"), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); @@ -2036,9 +2042,10 @@ public void Data_JsonValidator_FailPath_SubWorkflow_NotFoundWorkflow() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(!string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); Assert.True(console.Error.ToString().Contains("The subworkflow Error is mentioned but there is no workflow declared with that name"), $"Json Validator did not fail for IoT Data Workflow Package: {console.Error.ToString()}"); @@ -2114,9 +2121,10 @@ public void Data_JsonValidator_HappyPath_EmptyIsFile() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/Data/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error == null || string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed with empty IsFile: {console.Error?.ToString()}"); } @@ -2250,9 +2258,10 @@ public void Data_JsonValidator_Repeated_Keys_IoT_Event_Definition() buildCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new string[] { + var parseResult = cmd.Parse(new string[] { "test/" - }, console); + }); + parseResult.Invoke(console); Assert.True(console.Error == null || string.IsNullOrEmpty(console.Error.ToString()), $"Json Validator failed with repeated keys on different levels in arrays: {console.Error?.ToString()}"); } diff --git a/tests/Specs/ListDependencies.cs b/tests/Specs/ListDependencies.cs index ca21834cf..5f58ae2bd 100644 --- a/tests/Specs/ListDependencies.cs +++ b/tests/Specs/ListDependencies.cs @@ -2,9 +2,7 @@ using System.IO.Abstractions.TestingHelpers; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.NamingConventionBinder; -using System.CommandLine.IO; -using System.CommandLine.Parsing; +using System.Threading.Tasks; using System.IO; using System.IO.Abstractions; using System.Linq; @@ -13,7 +11,6 @@ using Cmf.CLI.Commands; using Cmf.CLI.Utilities; -using Cmf.Common.Cli.TestUtilities; using tests.Objects; using Assert = tests.AssertWithMessage; using Xunit; @@ -227,17 +224,21 @@ public void Args_MultiRepo() var cmd = new Command("ls"); listDependenciesCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, repos) => - { - _workingDir = workingDir.Name; - _repos = repos?.Select(uri => uri.OriginalString).ToArray(); - }); + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var reposOpt = cmd.Options.FirstOrDefault(o => o.Name == "repos" || o.Aliases.Any(a => a == "--repos" || a == "-r")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => + { + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _repos = parseResult.GetValue(reposOpt)?.Select(uri => uri.OriginalString).ToArray(); + return Task.FromResult(0); + }); var console = new TestConsole(); - cmd.Invoke(new[] { - "-r", "d:\\xpto", "-r", "e:\\packages" - }, console); + var parseResult = cmd.Parse(new string[] { + "-r", "d:\\xpto", "-r", "e:\\packages" + }); + parseResult.Invoke(console); var curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.Equal(curDir.Name, _workingDir, "working dir does not match expected"); @@ -256,17 +257,22 @@ public void Args_MultiRepo_UrlLocalMix() var cmd = new Command("ls"); listDependenciesCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, repos) => - { - _workingDir = workingDir.Name; - _repos = repos; - }); + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var reposOpt = cmd.Options.FirstOrDefault(o => o.Name == "repos" || o.Aliases.Any(a => a == "--repos" || a == "-r")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => + { + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _repos = parseResult.GetValue(reposOpt); + return Task.FromResult(0); + }); var console = new TestConsole(); - cmd.Invoke(new[] { - "-r", "d:\\xpto", "-r", "http://repository.example" - }, console); + + var parseResult = cmd.Parse(new string[] { + "-r", "d:\\xpto", "-r", "http://repository.example" + }); + parseResult.Invoke(console); var curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.Equal(curDir.Name, _workingDir, "working dir does not match expected"); @@ -287,18 +293,21 @@ public void Args_MultiRepo_RelativeDirectory() var cmd = new Command("ls"); listDependenciesCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, repos) => - { - _workingDir = workingDir.Name; - _repos = repos; - }); + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var reposOpt = cmd.Options.FirstOrDefault(o => o.Name == "repos" || o.Aliases.Any(a => a == "--repos" || a == "-r")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => + { + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _repos = parseResult.GetValue(reposOpt); + return Task.FromResult(0); + }); var console = new TestConsole(); - cmd.Invoke(new[] { + var parseResult = cmd.Parse(new string[] { "-r", "..\\xpto", "-r", "\\root_dir" - }, console); - + }); + parseResult.Invoke(console); var curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.Equal(curDir.Name, _workingDir, "working dir does not match expected"); Assert.Equal(2, _repos.Length, "Expecting 2 repositories"); @@ -317,18 +326,21 @@ public void Args_SingleRepo() var cmd = new Command("ls"); listDependenciesCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, repos) => - { - _workingDir = workingDir.Name; - _repos = repos?.Select(uri => uri.OriginalString).ToArray(); - }); + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var reposOpt = cmd.Options.FirstOrDefault(o => o.Name == "repos" || o.Aliases.Any(a => a == "--repos" || a == "-r")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => + { + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _repos = parseResult.GetValue(reposOpt)?.Select(uri => uri.OriginalString).ToArray(); + return Task.FromResult(0); + }); var console = new TestConsole(); - cmd.Invoke(new[] { + var parseResult = cmd.Parse(new string[] { "-r", "d:\\xpto" - }, console); - + }); + parseResult.Invoke(console); var curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.Equal(curDir.Name, _workingDir, "working dir does not match expected"); Assert.Equal(1, _repos.Length, "Expecting 2 repositories"); diff --git a/tests/Specs/Logging.cs b/tests/Specs/Logging.cs index f8c905fab..2d1647bb5 100644 --- a/tests/Specs/Logging.cs +++ b/tests/Specs/Logging.cs @@ -28,7 +28,11 @@ public StringWriter GetLogStringWriter() _writer = new StringWriter(); Environment.SetEnvironmentVariable("cmf_cli_loglevel", null); - LoggerHelpers.LogLevelOption.Parse(""); // reset to default log level + // In beta5, Option.Parse() doesn't exist - use a temporary command to parse and trigger default value + var tempCmd = new Command("temp"); + tempCmd.Add(LoggerHelpers.LogLevelOption); + tempCmd.Parse(Array.Empty()); + Log.AnsiConsole = AnsiConsole.Create(new AnsiConsoleSettings { Ansi = AnsiSupport.Yes, @@ -72,7 +76,11 @@ public void LogDebug_WhenDebug_Assign() public void LogDebug_WhenDebug_Option() { // System.Environment.SetEnvironmentVariable("cmf:cli:loglevel", "debug"); - LoggerHelpers.LogLevelOption.Parse("--loglevel debug"); + // In beta5, Option.Parse() doesn't exist - use a temporary command to parse + var tempCmd = new Command("temp"); + tempCmd.Add(LoggerHelpers.LogLevelOption); + var parseResult = tempCmd.Parse(new[] { "--loglevel", "debug" }); + parseResult.GetValue(LoggerHelpers.LogLevelOption); // trigger the custom parser // Log.Level = LogLevel.Debug; // var root = Program.Main(new string[] { "--loglevel", "debug", "ls" }); @@ -86,7 +94,11 @@ public void LogDebug_WhenDebug_Option() public void LogDebug_WhenDebug_Environment() { System.Environment.SetEnvironmentVariable("cmf_cli_loglevel", "debug"); - LoggerHelpers.LogLevelOption.Parse(""); // invoke rootCommand option parser to set environment value + // In beta5, Option.Parse() doesn't exist - use a temporary command to parse and trigger default value + var tempCmd = new Command("temp"); + tempCmd.Add(LoggerHelpers.LogLevelOption); + var parseResult = tempCmd.Parse(Array.Empty()); + parseResult.GetValue(LoggerHelpers.LogLevelOption); // trigger the custom parser to read env var // --loglevel debug // Log.Level = LogLevel.Debug; diff --git a/tests/Specs/MESVersionCommandValidation.cs b/tests/Specs/MESVersionCommandValidation.cs index 083cf63ff..0b317a8d2 100644 --- a/tests/Specs/MESVersionCommandValidation.cs +++ b/tests/Specs/MESVersionCommandValidation.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO.Abstractions.TestingHelpers; -using Cmf.CLI.Core; using Cmf.CLI.Core.Attributes; using Cmf.CLI.Core.Commands; using Cmf.CLI.Core.Objects; @@ -35,7 +33,7 @@ private class TestCommand : BaseCommand public override void Configure(Command cmd) { - cmd.SetHandler(() => { Executed = true; }); + cmd.SetAction(_ => { Executed = true; }); } } @@ -53,7 +51,7 @@ public void CommandWithMinimumVersion_CurrentVersionMeets_ShouldExecute() var attr = typeof(TestCommand).GetCustomAttributes(typeof(CmfCommandAttribute), false)[0] as CmfCommandAttribute; if (!string.IsNullOrWhiteSpace(attr.MinimumMESVersion)) { - testCmd.AddValidator(commandResult => + testCmd.Validators.Add(commandResult => { try { @@ -62,20 +60,19 @@ public void CommandWithMinimumVersion_CurrentVersionMeets_ShouldExecute() } catch (MESVersionValidationException ex) { - commandResult.ErrorMessage = ex.Message; + commandResult.AddError(ex.Message); } catch (Exception ex) { - commandResult.ErrorMessage = $"Version validation error: {ex.Message}"; + commandResult.AddError($"Version validation error: {ex.Message}"); } }); } - rootCmd.AddCommand(testCmd); - var parser = new Parser(rootCmd); + rootCmd.Add(testCmd); // Act - var result = parser.Parse("test-command"); + var result = rootCmd.Parse("test-command"); // Assert result.Errors.Should().BeEmpty(); @@ -95,7 +92,7 @@ public void CommandWithMinimumVersion_CurrentVersionBelowRequired_ShouldFail() var attr = typeof(TestCommand).GetCustomAttributes(typeof(CmfCommandAttribute), false)[0] as CmfCommandAttribute; if (!string.IsNullOrWhiteSpace(attr.MinimumMESVersion)) { - testCmd.AddValidator(commandResult => + testCmd.Validators.Add(commandResult => { try { @@ -104,20 +101,19 @@ public void CommandWithMinimumVersion_CurrentVersionBelowRequired_ShouldFail() } catch (MESVersionValidationException ex) { - commandResult.ErrorMessage = ex.Message; + commandResult.AddError(ex.Message); } catch (Exception ex) { - commandResult.ErrorMessage = $"Version validation error: {ex.Message}"; + commandResult.AddError($"Version validation error: {ex.Message}"); } }); } - rootCmd.AddCommand(testCmd); - var parser = new Parser(rootCmd); + rootCmd.Add(testCmd); // Act - var result = parser.Parse("test-command"); + var result = rootCmd.Parse("test-command"); // Assert result.Errors.Should().HaveCount(1); diff --git a/tests/Specs/New.cs b/tests/Specs/New.cs index 147f1213f..320d598c6 100644 --- a/tests/Specs/New.cs +++ b/tests/Specs/New.cs @@ -11,8 +11,6 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.IO; -using System.CommandLine.Parsing; using System.IO; using System.IO.Abstractions; using System.IO.Abstractions.TestingHelpers; @@ -37,7 +35,7 @@ public class NpmLoginFixture : IAsyncLifetime { internal const string NPM_USER_ENV_VAR = "CRITICALMANUFACTURING_IO_USER"; internal const string NPM_TOKEN_ENV_VAR = "CRITICALMANUFACTURING_IO_TOKEN"; - internal static string NPM_REGISTRY => System.Environment.GetEnvironmentVariable("CRITICALMANUFACTURING_NPM_REGISTRY") ?? "https://dev.criticalmanufacturing.io/repository/npm-public/"; + internal static string NPM_REGISTRY => Environment.GetEnvironmentVariable("CRITICALMANUFACTURING_NPM_REGISTRY") ?? "https://dev.criticalmanufacturing.io/repository/npm-public/"; public Task InitializeAsync() { @@ -53,7 +51,7 @@ public Task DisposeAsync() private void NpmLogin() { // Set log level to default to print any npm command logs - LoggerHelpers.LogLevelOption.Parse(""); + Log.Level = LogLevel.Verbose; Spectre.Console.AnsiConsole.Console.MarkupLine("Building service provider..."); @@ -69,23 +67,23 @@ private void NpmLogin() .AddSingleton(RepositoryAuthStore.FromEnvironmentConfig(fs)) .BuildServiceProvider(); - Spectre.Console.AnsiConsole.Console.MarkupLine("Finished building tests' service provider."); + AnsiConsole.Console.MarkupLine("Finished building tests' service provider."); - var npmUser = System.Environment.GetEnvironmentVariable(NPM_USER_ENV_VAR); - var npmToken = System.Environment.GetEnvironmentVariable(NPM_TOKEN_ENV_VAR); + var npmUser = Environment.GetEnvironmentVariable(NPM_USER_ENV_VAR); + var npmToken = Environment.GetEnvironmentVariable(NPM_TOKEN_ENV_VAR); if (!NPM_REGISTRY.IsNullOrEmpty() && !npmUser.IsNullOrEmpty() && !npmToken.IsNullOrEmpty()) { - Spectre.Console.AnsiConsole.Console.MarkupLine($"Running cmf login command for '{NPM_REGISTRY}'..."); + AnsiConsole.Console.MarkupLine($"Running cmf login command for '{NPM_REGISTRY}'..."); // We just want to login into NPM // If we log onto Portal then the command will attempt to login into all the derived credentials as well var loginCmd = new LoginCommand(); loginCmd.Execute( - Cmf.CLI.Core.Repository.Credentials.RepositoryCredentialsType.NPM, NPM_REGISTRY, - Cmf.CLI.Core.Repository.Credentials.AuthType.Basic, null, + RepositoryCredentialsType.NPM, NPM_REGISTRY, + AuthType.Basic, null, npmUser, npmToken, null, null, false, true); - Spectre.Console.AnsiConsole.Console.MarkupLine($"Successfully logged in on '{NPM_REGISTRY}'."); + AnsiConsole.Console.MarkupLine($"Successfully logged in on '{NPM_REGISTRY}'."); } } } @@ -96,16 +94,19 @@ public class New : IClassFixture public New(NpmLoginFixture npmLoginFixture) { - System.Environment.SetEnvironmentVariable("cmf_cli_internal_disable_projectconfig_cache", "1"); + Environment.SetEnvironmentVariable("cmf_cli_internal_disable_projectconfig_cache", "1"); + Environment.SetEnvironmentVariable("NPM_CONFIG_YES", "true"); var newCommand = new NewCommand(); var cmd = new Command("x"); newCommand.Configure(cmd); var console = new TestConsole(); - cmd.Invoke(new[] { + var parseResult = cmd.Parse(new string[] { "--reset" - }, console); + }); + parseResult.Invoke(console); + } [Theory, Trait("TestCategory", "Integration")] @@ -119,7 +120,7 @@ public void Business(BaseLayer layer, RepositoryType repositoryType = Repository RunNew(new BusinessCommand(), "Cmf.Custom.Business", repositoryType: repositoryType, - mesVersion: "9.1.0", + mesVersion: "10.2.5", baseLayer: layer, extraArguments: appContext ? new[] { "--addApplicationVersionAssembly" } : null, extraAsserts: args => @@ -225,22 +226,27 @@ public void Data_WithBusiness() }); } - [Theory, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node12"), Trait("TestCategory", "Integration")] - [InlineData(BaseLayer.MES)] - [InlineData(BaseLayer.Core)] - public void UI(BaseLayer layer) + [Theory, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18"), Trait("TestCategory", "Integration")] + [InlineData(BaseLayer.MES, "10.2.10", "1.3.7")] + [InlineData(BaseLayer.Core, "10.2.10", "1.3.7")] + public void UI_v10(BaseLayer layer, string mesVersion, string ngxSchematicsVersion) { - UI_internal(null, layer); + UI_internal(null, layer, mesVersion, ngxSchematicsVersion); } - private void UI_internal(string scaffoldingDir, BaseLayer layer) + [Theory, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node20"), Trait("TestCategory", "Integration")] + [InlineData(BaseLayer.MES, "11.2.5", "11.0.14")] + [InlineData(BaseLayer.Core, "11.2.5", "11.0.14")] + public void UI_v11(BaseLayer layer, string mesVersion, string ngxSchematicsVersion) { - RunNew(new HTMLCommand(), "Cmf.Custom.HTML", scaffoldingDir: scaffoldingDir, baseLayer: layer, extraArguments: new string[] - { - "--htmlPkg", TestUtilities.GetFixturePath("prodPkg", "Cmf.Presentation.HTML.9.9.9.zip"), - }, extraAsserts: args => + UI_internal(null, layer, mesVersion, ngxSchematicsVersion); + } + + private void UI_internal(string scaffoldingDir, BaseLayer layer, string mesVersion, string ngxSchematicsVersion) + { + RunNew(new HTMLCommand(), "Cmf.Custom.HTML", scaffoldingDir: scaffoldingDir, mesVersion: mesVersion, ngxSchematicsVersion: ngxSchematicsVersion, baseLayer: layer, extraAsserts: args => { - var configJson = File.ReadAllText("Cmf.Custom.HTML/apps/customization.web/config.json"); + var configJson = File.ReadAllText("Cmf.Custom.HTML/src/assets/config.json"); try { JsonConvert.DeserializeObject(configJson); @@ -249,124 +255,66 @@ private void UI_internal(string scaffoldingDir, BaseLayer layer) { Assert.Fail($"config.json is malformed: {e.Message}"); } - Assert.True(File.Exists($"Cmf.Custom.HTML/.dev-tasks.json"), "dev-tasks file is missing or has wrong name. Was cloning HTML-starter unsuccessful?"); - Assert.True(File.ReadAllText("Cmf.Custom.HTML/.dev-tasks.json").Contains("\"isWebAppCompilable\": true"), "Web app is not compilable"); - Assert.True(Directory.Exists($"Cmf.Custom.HTML/apps/customization.web"), "WebApp dir is missing or has wrong name. Was running the application generator unsuccessful?"); - Assert.True(File.Exists($"Cmf.Custom.HTML/apps/customization.web/config.json"), "Config file is missing or has wrong name"); - Assert.True(configJson.Contains("test.package"), "Product package is not in config.json"); - Assert.True(File.Exists($"Cmf.Custom.HTML/apps/customization.web/index.html"), "Index file is missing or has wrong name"); - if (layer == BaseLayer.Core) + Assert.True(Directory.Exists($"Cmf.Custom.HTML/src/app"), "WebApp dir is missing or has wrong name. Was running the application generator unsuccessful?"); + Assert.True(File.Exists($"Cmf.Custom.HTML/src/assets/config.json"), "Config file is missing or has wrong name"); + Assert.True(File.ReadAllText("Cmf.Custom.HTML/src/assets/config.json").Contains(mesVersion), $"Version {mesVersion} is not in config.json"); + Assert.True(File.Exists($"Cmf.Custom.HTML/src/index.html"), "Index file is missing or has wrong name"); + Assert.True(File.ReadAllText("Cmf.Custom.HTML/src/index.html").Contains("MES"), "Index content is not expected"); + Assert.True(File.ReadAllText("Cmf.Custom.HTML/src/index.html").Contains(""), "Index base path was not changed correctly"); + if(new Version(mesVersion) < new Version(11,0,0)) { - configJson - .Should().Contain("core-ui-web", "wrong base package in config.json"); - File.ReadAllText($"Cmf.Custom.HTML/apps/customization.web/package.json").Should() - .Contain("@criticalmanufacturing/core-ui-web"); - File.ReadAllText($"Cmf.Custom.HTML/cmfpackage.json").Should() - .Contain("node_modules/@criticalmanufacturing/core-ui-web/bundles"); - configJson - .Should().NotContain("cmf.mes", "config.json should not have any MES packages"); - } - else - { - configJson - .Should().Contain("mes-ui-web", "wrong base package in config.json"); - File.ReadAllText($"Cmf.Custom.HTML/apps/customization.web/package.json").Should() - .Contain("@criticalmanufacturing/mes-ui-web"); - File.ReadAllText($"Cmf.Custom.HTML/cmfpackage.json").Should() - .Contain("node_modules/@criticalmanufacturing/mes-ui-web/bundles"); - configJson - .Should().Contain("cmf.mes", "config.json should not have a MES packages"); + if (layer == BaseLayer.Core) + { + File.ReadAllText($"Cmf.Custom.HTML/src/app/app.module.ts").Should() + .Contain("import { CoreUIModule } from 'cmf-core-ui';"); + } + else + { + File.ReadAllText($"Cmf.Custom.HTML/src/app/app.module.ts").Should() + .Contain("import { MesUIModule } from 'cmf-mes-ui';"); + } } }); } - [Theory, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node12"), Trait("TestCategory", "Integration")] - [InlineData("8.2.0", false)] - [InlineData("9.1.0", true)] - public void UI_WithAppsPackage(string mesVersion, bool isCoreAppPresent) + [Theory, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18"), Trait("TestCategory", "Integration")] + [InlineData("10.2.10", "1.3.7")] + public void Help_v10(string mesVersion, string ngxSchematicsVersion) { - RunNew(new HTMLCommand(), "Cmf.Custom.HTML", mesVersion: mesVersion, extraArguments: new string[] - { - "--htmlPkg", TestUtilities.GetFixturePath("prodPkg", "Cmf.Presentation.HTML.9.9.9.zip"), - }, extraAsserts: args => - { - Assert.True(File.Exists($"Cmf.Custom.HTML/.dev-tasks.json"), "dev-tasks file is missing or has wrong name. Was cloning HTML-starter unsuccessful?"); - Assert.True(File.ReadAllText("Cmf.Custom.HTML/.dev-tasks.json").Contains("\"isWebAppCompilable\": true"), "Web app is not compilable"); - Assert.True(Directory.Exists($"Cmf.Custom.HTML/apps/customization.web"), "WebApp dir is missing or has wrong name. Was running the application generator unsuccessful?"); - Assert.True(File.Exists($"Cmf.Custom.HTML/apps/customization.web/config.json"), "Config file is missing or has wrong name"); - Assert.True(File.ReadAllText("Cmf.Custom.HTML/apps/customization.web/config.json").Contains("test.package"), "Product package is not in config.json"); - File.ReadAllText("Cmf.Custom.HTML/apps/customization.web/config.json").Contains("cmf.core.app").Should() - .Be(isCoreAppPresent, $"Apps package {(isCoreAppPresent ? "is not" : "is")} in config.json even though we are targeting {mesVersion}"); - Assert.True(File.Exists($"Cmf.Custom.HTML/apps/customization.web/index.html"), "Index file is missing or has wrong name"); - }); - } - - [Theory, Trait("TestCategory", "Integration")] - [InlineData("9.0.0", true)] - [InlineData("10.0.0", false), Trait("TestCategory", "LongRunning")] - public void UI_FailNoPackage(string mesVersion, bool shouldDisplayError) - { - var console = RunNew(new HTMLCommand(), "Cmf.Custom.HTML", defaultAsserts: false, mesVersion: mesVersion); - var stderr = console.Error.ToString(); - if (shouldDisplayError) - { - (stderr ?? "").Trim() - .Should().Contain("--htmlPkg option is required for MES versions up to 9.x", - "Should exit with missing package error"); - } - else - { - (stderr ?? "").Trim() - .Should().NotContain("--htmlPkg option is required for MES versions up to 9.x", - "Should exit with missing package error"); - } + Help_internal(mesVersion: mesVersion, ngxSchematicsVersion: ngxSchematicsVersion); } - [Fact, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node12"), Trait("TestCategory", "Integration")] - public void Help() + [Theory, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node20"), Trait("TestCategory", "Integration")] + [InlineData("11.2.5", "11.0.14")] + public void Help_v11(string mesVersion, string ngxSchematicsVersion) { - Help_internal(); + Help_internal(mesVersion: mesVersion, ngxSchematicsVersion: ngxSchematicsVersion); } - private void Help_internal(string scaffoldingDir = null) + private void Help_internal(string mesVersion, string ngxSchematicsVersion, string scaffoldingDir = null) { - RunNew(new Cmf.CLI.Commands.New.HelpCommand(), "Cmf.Custom.Help", scaffoldingDir: scaffoldingDir, extraArguments: new string[] { - "--docPkg", TestUtilities.GetFixturePath("prodPkg", "Cmf.Documentation.9.9.9.zip"), - }, extraAsserts: args => + RunNew(new Cmf.CLI.Commands.New.HelpCommand(), "Cmf.Custom.Help", scaffoldingDir: scaffoldingDir, mesVersion: mesVersion, ngxSchematicsVersion: ngxSchematicsVersion, extraAsserts: args => { - Assert.True(File.Exists($"Cmf.Custom.Help/.dev-tasks.json"), "dev-tasks file is missing or has wrong name. Was cloning HTML-starter unsuccessful?"); - Assert.True(Directory.Exists($"Cmf.Custom.Help/apps/cmf.docs.area.web"), "WebApp dir is missing or has wrong name. Was running the application generator unsuccessful?"); - Assert.True(File.Exists($"Cmf.Custom.Help/apps/cmf.docs.area.web/config.json"), "Config file is missing or has wrong name"); - Assert.True(File.ReadAllText("Cmf.Custom.Help/apps/cmf.docs.area.web/config.json").Contains("test.package"), "Product package is not in config.json"); - Assert.True(File.Exists($"Cmf.Custom.Help/apps/cmf.docs.area.web/index.html"), "Index file is missing or has wrong name"); - Assert.True(File.ReadAllText("Cmf.Custom.Help/apps/cmf.docs.area.web/index.html").Contains("Documentation website"), "Index content is not expected"); - Assert.True(File.ReadAllText("Cmf.Custom.Help/apps/cmf.docs.area.web/index.html").Contains(""), "Index base path was not changed correctly"); + Assert.True(Directory.Exists($"Cmf.Custom.Help/src/app"), "WebApp dir is missing or has wrong name. Was running the application generator unsuccessful?"); + Assert.True(File.Exists($"Cmf.Custom.Help/src/assets/config.json"), "Config file is missing or has wrong name"); + Assert.True(File.ReadAllText("Cmf.Custom.Help/src/assets/config.json").Contains(mesVersion), $"Version {mesVersion} is not in config.json"); + Assert.True(File.Exists($"Cmf.Custom.Help/src/index.html"), "Index file is missing or has wrong name"); + Assert.True(File.ReadAllText("Cmf.Custom.Help/src/index.html").Contains("DocumentationPortal"), "Index content is not expected"); + Assert.True(File.ReadAllText("Cmf.Custom.Help/src/index.html").Contains(""), "Index base path was not changed correctly"); }); } [Theory, Trait("TestCategory", "Integration")] - [InlineData("9.0.0", true)] - [InlineData("10.0.0", false), Trait("TestCategory", "LongRunning")] - public void Help_FailNoPackage(string mesVersion, bool shouldDisplayError) + [InlineData("10.2.10"), Trait("TestCategory", "LongRunning")] + public void Help_FailNoPackage(string mesVersion) { var console = RunNew(new Cmf.CLI.Commands.New.HelpCommand(), "Cmf.Custom.Help", defaultAsserts: false, mesVersion: mesVersion); var stderr = console.Error.ToString(); - if (shouldDisplayError) - { - (stderr ?? "").Trim() - .Should().Contain("--docPkg option is required for MES versions up to 9.x", - "Should exit with missing package error"); - } - else - { - (stderr ?? "").Trim() - .Should().NotContain("--docPkg option is required for MES versions up to 9.x", - "Should exit with missing package error"); - } + (stderr ?? "").Trim() + .Should().BeEmpty(); } [Theory, Trait("TestCategory", "Integration")] - [InlineData("9.0.0")] [InlineData("10.2.5", true), Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18")] [InlineData("10.2.5", true, true), Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18")] [InlineData("10.2.7", true, true), Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18")] @@ -377,20 +325,16 @@ public void IoT(string mesVersion, bool htmlPackageLocationFullPath = false, boo string packageId = "Cmf.Custom.IoT"; string packageIdPackages = "Cmf.Custom.IoT.Packages"; - string packageFolderPackages = mesVersion == "9.0.0" ? "IoTPackages" : packageIdPackages; + string packageFolderPackages = packageIdPackages; string packageIdData = "Cmf.Custom.IoT.Data"; - string packageFolderData = mesVersion == "9.0.0" ? "IoTData" : packageIdData; + string packageFolderData = packageIdData; // Before v10.2.7, all packages were Angular packages, even if the flag was not passed explicitly bool isAngularPackage = isAngularPackageFlag || Version.Parse(mesVersion) < new Version(10, 2, 7); CopyNewFixture(dir, mesVersion: mesVersion); - if (mesVersion == "9.0.0") - { - RunNew(new IoTCommand(), packageId, scaffoldingDir: dir); - } - else if (isAngularPackage) + if (isAngularPackage) { var htmlPackageName = "Cmf.Custom.HTML"; var targetDir = new DirectoryInfo(dir); @@ -427,36 +371,28 @@ public void IoT(string mesVersion, bool htmlPackageLocationFullPath = false, boo Directory.Exists($"{packageId}/{packageFolderData}/MasterData").Should().BeTrue(); Directory.Exists($"{packageId}/{packageFolderData}/AutomationWorkFlows").Should().BeTrue(); - if (mesVersion == "9.0.0") + Directory.Exists($"{packageId}/{packageFolderPackages}/.vscode").Should().BeTrue(); + File.Exists($"{packageId}/{packageFolderPackages}/.vscode/extensions.json").Should().BeTrue(); + File.Exists($"{packageId}/{packageFolderPackages}/.vscode/launch.json").Should().BeTrue(); + File.Exists($"{packageId}/{packageFolderPackages}/.vscode/settings.json").Should().BeTrue(); + File.Exists($"{packageId}/{packageFolderPackages}/.vscode/tasks.json").Should().BeTrue(); + + if (isAngularPackage) { - File.Exists($"{packageId}/{packageFolderPackages}/.dev-tasks.json").Should().BeTrue(); - Directory.Exists($"{packageId}/{packageFolderPackages}/src").Should().BeTrue(); + var relatedPackages = TestUtilities.GetPackage($"{packageId}/{packageFolderPackages}/cmfpackage.json").GetProperty("relatedPackages")[0]; + relatedPackages.GetProperty("path").GetString().Should().Be(MockUnixSupport.Path("..\\..\\Cmf.Custom.HTML")); + relatedPackages.GetProperty("preBuild").GetBoolean().Should().BeFalse(); + relatedPackages.GetProperty("postBuild").GetBoolean().Should().BeTrue(); + relatedPackages.GetProperty("prePack").GetBoolean().Should().BeFalse(); + relatedPackages.GetProperty("postPack").GetBoolean().Should().BeTrue(); + + File.Exists($"{packageId}/{packageFolderPackages}/angular.json").Should().BeTrue(); } - else { - Directory.Exists($"{packageId}/{packageFolderPackages}/.vscode").Should().BeTrue(); - File.Exists($"{packageId}/{packageFolderPackages}/.vscode/extensions.json").Should().BeTrue(); - File.Exists($"{packageId}/{packageFolderPackages}/.vscode/launch.json").Should().BeTrue(); - File.Exists($"{packageId}/{packageFolderPackages}/.vscode/settings.json").Should().BeTrue(); - File.Exists($"{packageId}/{packageFolderPackages}/.vscode/tasks.json").Should().BeTrue(); - File.Exists($"{packageId}/{packageFolderPackages}/.gitattributes").Should().BeTrue(); - - if (isAngularPackage) - { - var relatedPackages = TestUtilities.GetPackage($"{packageId}/{packageFolderPackages}/cmfpackage.json").GetProperty("relatedPackages")[0]; - relatedPackages.GetProperty("path").GetString().Should().Be(MockUnixSupport.Path("..\\..\\Cmf.Custom.HTML")); - relatedPackages.GetProperty("preBuild").GetBoolean().Should().BeFalse(); - relatedPackages.GetProperty("postBuild").GetBoolean().Should().BeTrue(); - relatedPackages.GetProperty("prePack").GetBoolean().Should().BeFalse(); - relatedPackages.GetProperty("postPack").GetBoolean().Should().BeTrue(); - - File.Exists($"{packageId}/{packageFolderPackages}/angular.json").Should().BeTrue(); - } - else - { - File.Exists($"{packageId}/{packageFolderPackages}/angular.json").Should().BeFalse(); - File.Exists($"{packageId}/{packageFolderPackages}/.eslintrc.json").Should().BeTrue(); - File.Exists($"{packageId}/{packageFolderPackages}/ui.xml").Should().BeTrue(); - } + else + { + File.Exists($"{packageId}/{packageFolderPackages}/angular.json").Should().BeFalse(); + File.Exists($"{packageId}/{packageFolderPackages}/.eslintrc.json").Should().BeTrue(); + File.Exists($"{packageId}/{packageFolderPackages}/ui.xml").Should().BeTrue(); } } @@ -884,7 +820,7 @@ public void Features_RootPackageWithFeature() } RunFeature_WithoutPrefix(scaffoldingDir: dir); - var console = RunNew(new BusinessCommand(), "Cmf.Custom.Business", scaffoldingDir: dir, defaultAsserts: false); + RunNew(new BusinessCommand(), "Cmf.Custom.Business", scaffoldingDir: dir, defaultAsserts: false); // TODO: logger isn't using IConsole. This means we can only catch errors coming from Exception, which is not the case here //string errors = console.Error.ToString().Trim(); //Assert.True(errors.Contains("Cannot create a root-level layer package when features already exist."), "Expected to find specific error in console but instead found: {0}", errors); @@ -926,7 +862,7 @@ public void Features_Business() var pkgDir = Path.Join(dir, "Features", "TestFeature"); const string packageId = "Cmf.Custom.TestFeature.Business"; - var console = RunNew(new BusinessCommand(), packageId, scaffoldingDir: pkgDir, extraAsserts: args => + var console = RunNew(new BusinessCommand(), packageId, scaffoldingDir: pkgDir, mesVersion: "10.2.10", extraAsserts: args => { var (pkgVersion, _) = args; Assert.True(File.Exists(Path.Join(dir, "Features/TestFeature", $"{packageId}/Cmf.Custom.Common/tenantConstants.cs")), "Constants file is missing or has wrong name"); @@ -944,7 +880,7 @@ public void Features_Business() } } - [Fact, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node12"), Trait("TestCategory", "Integration")] + [Fact, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18"), Trait("TestCategory", "Integration")] public void Features_Help() { var dir = TestUtilities.GetTmpDirectory(); @@ -960,6 +896,7 @@ public void Features_Help() TestUtilities.CopyFixture("new", new DirectoryInfo(dir)); TestUtilities.CopyFixture("featureBase", new DirectoryInfo(dir)); + ReplaceConfigForFeaturesTest(dir, mesVersion: "10.2.10"); var projCfg = Path.Join(dir, ".project-config.json"); if (File.Exists(projCfg)) { @@ -972,12 +909,10 @@ public void Features_Help() var pkgDir = Path.Join(dir, "Features", "TestFeature"); const string packageId = "Cmf.Custom.TestFeature.Help"; - var console = RunNew(new Cmf.CLI.Commands.New.HelpCommand(), packageId, extraArguments: new string[] { - "--docPkg", TestUtilities.GetFixturePath("prodPkg", "Cmf.Documentation.9.9.9.zip"), - }, scaffoldingDir: pkgDir, extraAsserts: args => + var console = RunNew(new Cmf.CLI.Commands.New.HelpCommand(), packageId, scaffoldingDir: pkgDir, mesVersion: "10.2.10", extraAsserts: args => { var (pkgVersion, _) = args; - Assert.True(Directory.Exists(Path.Join(dir, "Features/TestFeature", $"{packageId}/src/packages/cmf.docs.area.{packageId.ToLowerInvariant()}")), "Help package is missing or has wrong name"); + Assert.True(Directory.Exists(Path.Join(dir, "Features/TestFeature", $"{packageId}/projects/cmf-docs-area-cmf-custom-testfeature-help")), "Help package is missing or has wrong name"); }); } finally @@ -999,7 +934,7 @@ public void Features_Help() } } - [Fact, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node12"), Trait("TestCategory", "Integration")] + [Fact, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Node18"), Trait("TestCategory", "Integration")] public void Features_UI() { var dir = TestUtilities.GetTmpDirectory(); @@ -1014,6 +949,8 @@ public void Features_UI() Directory.SetCurrentDirectory(dir); TestUtilities.CopyFixture("new", new DirectoryInfo(dir)); TestUtilities.CopyFixture("featureBase", new DirectoryInfo(dir)); + + ReplaceConfigForFeaturesTest(dir, mesVersion: "10.2.10"); var projCfg = Path.Join(dir, ".project-config.json"); if (File.Exists(projCfg)) { @@ -1026,9 +963,7 @@ public void Features_UI() var pkgDir = Path.Join(dir, "Features", "TestFeature"); const string packageId = "Cmf.Custom.TestFeature.HTML"; - var console = RunNew(new Cmf.CLI.Commands.New.HTMLCommand(), packageId, extraArguments: new string[] { - "--htmlPkg", TestUtilities.GetFixturePath("prodPkg", "Cmf.Presentation.HTML.9.9.9.zip"), - }, scaffoldingDir: pkgDir); + RunNew(new HTMLCommand(), packageId, scaffoldingDir: pkgDir, mesVersion: "10.2.10"); } finally { @@ -1076,31 +1011,9 @@ public void SecurityPortal() Assert.True(File.Exists($"{dir}/Cmf.Custom.SecurityPortal/config.json"), "Package config.json is missing"); } - [Fact, Trait("TestCategory", "LongRunning"), Trait("TestCategory", "Integration"), Trait("TestCategory", "Node18")] - public void UI_v10() - { - UI_internal_v10(); - } - - private void UI_internal_v10() - { - RunNew(new HTMLCommand(), "Cmf.Custom.HTML", mesVersion: "10.1.2", extraAsserts: args => - { - var configJson = File.ReadAllText("Cmf.Custom.HTML/src/assets/config.json"); - try - { - JsonConvert.DeserializeObject(configJson); - } - catch (Exception e) - { - Assert.Fail($"config.json is malformed: {e.Message}"); - } - }); - } - private TestConsole RunNew(T newCommand, string packageId, string scaffoldingDir = null, string[] extraArguments = null, bool defaultAsserts = true, Action<(string, string)> extraAsserts = null, - string mesVersion = "8.2.0", + string mesVersion = "11.2.2", string ngxSchematicsVersion = NGX_SCHEMATICS_VERSION, BaseLayer baseLayer = BaseLayer.MES, RepositoryType repositoryType = RepositoryType.Customization) where T : TemplateCommand @@ -1122,6 +1035,11 @@ private TestConsole RunNew(T newCommand, string packageId, string scaffolding CopyNewFixture(dir, mesVersion, ngxSchematicsVersion, baseLayer, repositoryType); } + if (File.Exists(Path.Join(dir, ".project-config.json"))) + { + Console.WriteLine(File.ReadAllText(Path.Join(dir, ".project-config.json"))); + } + ExecutionContext.Initialize(new FileSystem()); var cmd = new Command("x"); @@ -1179,7 +1097,7 @@ private TestConsole RunNew(T newCommand, string packageId, string scaffolding } private void CopyNewFixture(string dir, - string mesVersion = "8.2.0", + string mesVersion = "11.2.2", string ngxSchematicsVersion = NGX_SCHEMATICS_VERSION, BaseLayer baseLayer = BaseLayer.MES, RepositoryType repositoryType = RepositoryType.Customization) @@ -1189,7 +1107,7 @@ private void CopyNewFixture(string dir, if (File.Exists(projCfg)) { File.WriteAllText(projCfg, File.ReadAllText(projCfg) - .Replace(@"""MESVersion"": ""8.2.0""", $@"""MESVersion"": ""{mesVersion}""") + .Replace(@"""MESVersion"": ""11.2.2""", $@"""MESVersion"": ""{mesVersion}""") .Replace(@"""BaseLayer"": ""MES""", $@"""BaseLayer"": ""{baseLayer}""") .Replace(@"""RepositoryType"": ""Customization""", $@"""RepositoryType"": ""{repositoryType}""") .Replace(@"""NGXSchematicsVersion"": ""10.0.0""", $@"""NGXSchematicsVersion"": ""{ngxSchematicsVersion}""") @@ -1205,5 +1123,18 @@ private void CopyNewFixture(string dir, TestUtilities.CopyFixture("app", new DirectoryInfo(dir)); } } + + private void ReplaceConfigForFeaturesTest(string dir, string mesVersion, string ngxSchematicsVersion = NGX_SCHEMATICS_VERSION) + { + var projCfg = Path.Join(dir, ".project-config.json"); + if (File.Exists(projCfg)) + { + File.WriteAllText(projCfg, File.ReadAllText(projCfg) + .Replace(@"""MESVersion"": ""11.2.2""", $@"""MESVersion"": ""{mesVersion}""") + .Replace(@"""NPMRegistry"": ""http://npm_registry/""", $@"""NPMRegistry"": ""{NpmLoginFixture.NPM_REGISTRY}""") + .Replace(@"""NGXSchematicsVersion"": ""10.0.0""", $@"""NGXSchematicsVersion"": ""{ngxSchematicsVersion}""") + ); + } + } } } \ No newline at end of file diff --git a/tests/Specs/NodeVersionUtilities.cs b/tests/Specs/NodeVersionUtilities.cs index d032f902b..494b43975 100644 --- a/tests/Specs/NodeVersionUtilities.cs +++ b/tests/Specs/NodeVersionUtilities.cs @@ -22,8 +22,6 @@ public void GetInstalledNodeVersion_ReturnsVersion_WhenNodeIsInstalled() } [Theory] - [InlineData("8.0.0", "12")] // MES v8.x requires Node.js v12 - [InlineData("9.0.0", "12")] // MES v9.x requires Node.js v12 [InlineData("10.0.0", "18")] // MES v10.x requires Node.js v18 [InlineData("11.0.0", "20")] // MES v11.x requires Node.js v20 [InlineData("12.0.0", "20")] // MES v12.x and later require Node.js v20 diff --git a/tests/Specs/Pack.cs b/tests/Specs/Pack.cs index f4a5cd633..634d2b59b 100644 --- a/tests/Specs/Pack.cs +++ b/tests/Specs/Pack.cs @@ -16,8 +16,7 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.IO; -using System.CommandLine.NamingConventionBinder; +using System.Threading.Tasks; using System.IO; using System.IO.Abstractions; using System.IO.Abstractions.TestingHelpers; @@ -29,6 +28,7 @@ using tests.Objects; using Xunit; + namespace tests.Specs { public class Pack @@ -55,18 +55,24 @@ public void Args_Paths_BothSpecified() var cmd = new Command("pack"); packCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, outputDir, repo, force, skipDependencies) => + // Get the arguments/options that were configured + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var outputDirOpt = cmd.Options.FirstOrDefault(o => o.Name == "outputDir" || o.Aliases.Any(a => a == "--outputDir" || a == "-o")) as Option; + var forceOpt = cmd.Options.FirstOrDefault(o => o.Name == "force" || o.Aliases.Any(a => a == "--force" || a == "-f")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => { - _workingDir = workingDir.Name; - _outputDir = outputDir.Name; - _force = force; + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _outputDir = parseResult.GetValue(outputDirOpt)?.Name; + _force = parseResult.GetValue(forceOpt); + return Task.FromResult(0); }); var console = new TestConsole(); - cmd.Invoke(new[] { + var parseResult = cmd.Parse(new string[] { "-o", "test_package_dir", "working_dir" - }, console); + }); + parseResult.Invoke(console); Assert.Equal("working_dir", _workingDir); Assert.Equal("test_package_dir", _outputDir); @@ -85,18 +91,23 @@ public void Args_Paths_WorkDirSpecified() var cmd = new Command("pack"); packCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, outputDir, repo, force, skipDependencies) => + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var outputDirOpt = cmd.Options.FirstOrDefault(o => o.Name == "outputDir" || o.Aliases.Any(a => a == "--outputDir" || a == "-o")) as Option; + var forceOpt = cmd.Options.FirstOrDefault(o => o.Name == "force" || o.Aliases.Any(a => a == "--force" || a == "-f")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => { - _workingDir = workingDir.Name; - _outputDir = outputDir.Name; - _force = force; + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _outputDir = parseResult.GetValue(outputDirOpt)?.Name; + _force = parseResult.GetValue(forceOpt); + return Task.FromResult(0); }); var console = new TestConsole(); - cmd.Invoke(new[] { - "working_dir" - }, console); + var parseResult = cmd.Parse(new string[] { + "working_dir" + }); + parseResult.Invoke(console); Assert.Equal("working_dir", _workingDir); Assert.Equal("Package", _outputDir); @@ -115,18 +126,23 @@ public void Args_Paths_OutDirSpecified() var cmd = new Command("pack"); packCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, outputDir, repo, force, skipDependencies) => + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var outputDirOpt = cmd.Options.FirstOrDefault(o => o.Name == "outputDir" || o.Aliases.Any(a => a == "--outputDir" || a == "-o")) as Option; + var forceOpt = cmd.Options.FirstOrDefault(o => o.Name == "force" || o.Aliases.Any(a => a == "--force" || a == "-f")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => { - _workingDir = workingDir.Name; - _outputDir = outputDir.Name; - _force = force; + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _outputDir = parseResult.GetValue(outputDirOpt)?.Name; + _force = parseResult.GetValue(forceOpt); + return Task.FromResult(0); }); var console = new TestConsole(); - cmd.Invoke(new[] { - "-o", "test_package_dir" - }, console); + var parseResult = cmd.Parse(new string[] { + "-o", "test_package_dir" + }); + parseResult.Invoke(console); var curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.Equal(curDir.Name, _workingDir); @@ -146,18 +162,22 @@ public void Args_Paths_NoneSpecified() var cmd = new Command("pack"); packCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, outputDir, repo, force, skipDependencies) => + var workingDirArg = cmd.Arguments.FirstOrDefault(a => a.Name == "workingDir") as Argument; + var outputDirOpt = cmd.Options.FirstOrDefault(o => o.Name == "outputDir" || o.Aliases.Any(a => a == "--outputDir" || a == "-o")) as Option; + var forceOpt = cmd.Options.FirstOrDefault(o => o.Name == "force" || o.Aliases.Any(a => a == "--force" || a == "-f")) as Option; + + cmd.SetAction((parseResult, cancellationToken) => { - _workingDir = workingDir.Name; - _outputDir = outputDir.Name; - _force = force; + _workingDir = parseResult.GetValue(workingDirArg)?.Name; + _outputDir = parseResult.GetValue(outputDirOpt)?.Name; + _force = parseResult.GetValue(forceOpt); + return Task.FromResult(0); }); - var console = new TestConsole(); - cmd.Invoke(new string[] { - }, console); + var console = new TestConsole(); + var parseResult = cmd.Parse(new string[]{}); + parseResult.Invoke(console); var curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.Equal(curDir.Name, _workingDir); @@ -273,7 +293,6 @@ public void HTML() List expectedFiles = new() { - "config.json", "manifest.xml", "node_modules/customization.package/package.json", "node_modules/customization.package/customization.common.js" @@ -337,10 +356,11 @@ public void CheckThatContentWasPacked_DoNothingBecauseContentWasAlreadyPacked() var fileSystem = MockPackage.Html; var outputDir = fileSystem.DirectoryInfo.New("output"); - var packCommand = new PackCommand(fileSystem); - packCommand.Execute(fileSystem.DirectoryInfo.New(MockUnixSupport.Path("c:\\ui")), outputDir, false, false); + var firstPackCommand = new PackCommand(fileSystem); + firstPackCommand.Execute(fileSystem.DirectoryInfo.New(MockUnixSupport.Path("c:\\ui")), outputDir, false, false); IEnumerable assembledFiles = fileSystem.DirectoryInfo.New("output").EnumerateFiles("Cmf.Custom.HTML.1.1.0.zip").ToList(); - packCommand.Execute(fileSystem.DirectoryInfo.New(MockUnixSupport.Path("c:\\ui")), outputDir, false, false); + var secondPackCommand = new PackCommand(fileSystem); + secondPackCommand.Execute(fileSystem.DirectoryInfo.New(MockUnixSupport.Path("c:\\ui")), outputDir, false, false); IEnumerable assembledFilesOnSecondRun = fileSystem.DirectoryInfo.New("output").EnumerateFiles("Cmf.Custom.HTML.1.1.0.zip").ToList(); assembledFilesOnSecondRun.Should().HaveCount(1); @@ -392,9 +412,8 @@ public void Pack_SecurityPortal() packCommand.Configure(cmd); TestConsole console = new TestConsole(); - cmd.Invoke(new string[] { - }, console); - + var parseResult = cmd.Parse(new string[]{}); + parseResult.Invoke(console); DirectoryInfo curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); Assert.True(Directory.Exists($"{dir}/Package"), "Package folder is missing"); @@ -440,8 +459,8 @@ public void Pack_App() packCommand.Configure(cmd); TestConsole console = new(); - cmd.Invoke(Array.Empty(), console); - + var parseResult = cmd.Parse(Array.Empty()); + parseResult.Invoke(console); DirectoryInfo curDir = new(System.IO.Directory.GetCurrentDirectory()); Assert.True(Directory.Exists($"{dir}/Package"), "Package folder is missing"); @@ -528,7 +547,8 @@ public void Pack_AppFeature() packCommand.Configure(cmd); TestConsole console = new(); - cmd.Invoke(Array.Empty(), console); + var parseResult = cmd.Parse(Array.Empty()); + parseResult.Invoke(console); DirectoryInfo curDir = new(System.IO.Directory.GetCurrentDirectory()); @@ -577,8 +597,9 @@ public void Pack_SecurityPortalV2() packCommand.Configure(cmd); TestConsole console = new TestConsole(); - cmd.Invoke(new string[] { - }, console); + + var parseResult = cmd.Parse(new string[] {}); + parseResult.Invoke(console); DirectoryInfo curDir = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory()); @@ -599,35 +620,6 @@ public void Pack_SecurityPortalV2() Assert.Contains("", manifestXMLContent); } - [Theory] - [InlineData("8.1.0", new[] { StepType.DeployRepositoryFiles, StepType.GenerateRepositoryIndex })] - [InlineData("9.1.0", new StepType[0])] - public void IoTDFStepsForVersion(string version, StepType[] forbiddenStepTypes) - { - var mockFS = new MockFileSystem(new Dictionary - {{ MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData( - $@"{{ - ""MESVersion"": ""{version}"" - }}") - }, { - MockUnixSupport.Path(@"c:\.pkg.json"), new MockFileData( - $@"{{ - ""type"": ""{PackageType.IoT}"", - ""packageId"": ""xxxxx"", - ""version"": ""9.9.9"", - ""contentToPack"": [{{}}] - }}") - }}); - - ExecutionContext.Initialize(mockFS); - var pkg = CmfPackage.Load(mockFS.FileSystem.FileInfo.New(MockUnixSupport.Path(@"c:\.pkg.json")), true, - mockFS); - var _ = new IoTPackageTypeHandler(pkg); - - pkg.Steps.Any(step => forbiddenStepTypes.ToList().Contains(step.Type ?? StepType.Generic)).Should() - .BeFalse(); - } - [Theory] [InlineData("10.2.7", StepType.IoTAutomationTaskLibrariesSync)] public void IoTATLDFNoStepsForVersion(string version, StepType mustNotHave) @@ -851,7 +843,6 @@ public void IoTATLAndBizScenariosDFStepsForVersion(string version) } [Theory] - [InlineData("Html", "1.1.0")] [InlineData("IoT", null)] public void GeneratePresentationConfigFile(string packageType, string version) { @@ -859,10 +850,11 @@ public void GeneratePresentationConfigFile(string packageType, string version) var fileSystem = new MockFileSystem(new Dictionary { + { $"output/assets", new MockDirectoryData() }, // project config file { ".project-config.json", new MockFileData( @$"{{ - ""MESVersion"": ""9.0.0"" + ""MESVersion"": ""10.0.0"" }}")}, // root cmfpackage file @@ -899,6 +891,27 @@ public void GeneratePresentationConfigFile(string packageType, string version) ] }}")}, + // angular file (html case) + { $"Cmf.Custom.{packageType}/angular.json", new MockFileData( + $@"{{ + ""$schema"": ""./node_modules/@angular/cli/lib/config/schema.json"", + ""version"": 1, + ""newProjectRoot"": ""projects"", + ""projects"": {{ + ""Cmf.Custom.HTML"": {{ + ""projectType"": ""application"", + ""schematics"": {{ + ""@schematics/angular:component"": {{ + ""style"": ""less"" + }} + }}, + ""root"": """", + ""sourceRoot"": ""src"", + }} + }} + }}") + }, + // js package { $"Cmf.Custom.{packageType}/src/packages/customization.common/package.json", new MockFileData(@"{""name"": ""customization.package""}")}, { $"Cmf.Custom.{packageType}/src/packages/customization.common/customization.common.js", new MockFileData("")}, @@ -911,11 +924,16 @@ public void GeneratePresentationConfigFile(string packageType, string version) ExecutionContext.Initialize(fileSystem); IFileInfo cmfpackageFile = fileSystem.FileInfo.New($"Cmf.Custom.{packageType}/cmfpackage.json"); - PresentationPackageTypeHandler packageTypeHandler = PackageTypeFactory.GetPackageTypeHandler(cmfpackageFile, true) as PresentationPackageTypeHandler; + Cmf.CLI.Handlers.IoTPackageTypeHandler packageTypeHandler = PackageTypeFactory.GetPackageTypeHandler(cmfpackageFile, true) as Cmf.CLI.Handlers.IoTPackageTypeHandler; packageTypeHandler.GeneratePresentationConfigFile(fileSystem.DirectoryInfo.New("output")); + string htmlPath = MockUnixSupport.Path(@"output\\assets\\config.json").Replace("\\", "\\\\"); IFileInfo configJsonFile = fileSystem.FileInfo.New(MockUnixSupport.Path(@"output\\config.json").Replace("\\", "\\\\")); + if(packageType.Equals("Html")) + { + configJsonFile = fileSystem.FileInfo.New(htmlPath); + } dynamic configJsonFileContent = JsonConvert.DeserializeObject(fileSystem.File.ReadAllText(configJsonFile.FullName)); string customizationVersion = configJsonFileContent.customizationVersion?.ToString(); @@ -1478,14 +1496,11 @@ public void DryRun_Option_IsParsed() var cmd = new Command("pack"); packCommand.Configure(cmd); - cmd.Handler = CommandHandler.Create( - (workingDir, outputDir, force, dryRun) => - { - _dryRun = dryRun; - }); - - var console = new TestConsole(); - cmd.Invoke(new[] { "--dry-run" }, console); + var dryRunOption = cmd.Options + .OfType>() + .Single(o => !o.Aliases.Contains("--force") && !o.Aliases.Contains("-f")); + var parseResult = cmd.Parse(new[] { "--dry-run" }); + _dryRun = parseResult.GetValue(dryRunOption); Assert.NotNull(_dryRun); Assert.True(_dryRun ?? false); @@ -1494,7 +1509,6 @@ public void DryRun_Option_IsParsed() [Fact] public void DryRun_Html_DoesNotCreatePackage() { - // Arrange: Html package (MES 9.x → HtmlGulpPackageTypeHandler) with a JS sub-package // Use a fresh MockFileSystem (not the shared static) to avoid state pollution from other tests var fileSystem = new MockFileSystem(new Dictionary { @@ -1518,6 +1532,25 @@ public void DryRun_Html_DoesNotCreatePackage() }} ] }}") }, + { MockUnixSupport.Path(@"c:\ui\angular.json"), new MockFileData( + $@"{{ + ""$schema"": ""./node_modules/@angular/cli/lib/config/schema.json"", + ""version"": 1, + ""newProjectRoot"": ""projects"", + ""projects"": {{ + ""Cmf.Custom.HTML"": {{ + ""projectType"": ""application"", + ""schematics"": {{ + ""@schematics/angular:component"": {{ + ""style"": ""less"" + }} + }}, + ""root"": """", + ""sourceRoot"": ""src"", + }} + }} + }}") + }, }); var packCommand = new PackCommand(fileSystem); var outputDir = fileSystem.DirectoryInfo.New("output"); diff --git a/tests/Specs/PackageTypeHandler.cs b/tests/Specs/PackageTypeHandler.cs index 3191cda7d..7f2dcce82 100644 --- a/tests/Specs/PackageTypeHandler.cs +++ b/tests/Specs/PackageTypeHandler.cs @@ -39,7 +39,7 @@ public void GetContentToPack_WithNonExistentIgnoreFiles() try { var cmfPackage = fileSystem.FileInfo.New(CliConstants.CmfPackageFileName); - var packageTypeHandler = PackageTypeFactory.GetPackageTypeHandler(cmfPackage) as PresentationPackageTypeHandler; + Cmf.CLI.Handlers.PackageTypeHandler packageTypeHandler = PackageTypeFactory.GetPackageTypeHandler(cmfPackage) as Cmf.CLI.Handlers.PackageTypeHandler; packageTypeHandler.GetContentToPack(fileSystem.DirectoryInfo.New("output")); } diff --git a/tests/Specs/ProgramTests.cs b/tests/Specs/ProgramTests.cs new file mode 100644 index 000000000..57f616ffe --- /dev/null +++ b/tests/Specs/ProgramTests.cs @@ -0,0 +1,32 @@ +using Cmf.CLI; +using Cmf.CLI.Utilities; +using Xunit; + + +namespace tests.Specs +{ + public class ProgramTests + { + [Theory] + [InlineData(10)] + [InlineData(11)] + public void Should_NotThrow_For_Valid_Versions(int version) + { + Program.ValidateMesVersion(version); + } + + [Theory] + [InlineData(0)] + [InlineData(9)] + public void Should_Throw_For_Invalid_Versions(int version) + { + Assert.Throws(() => Program.ValidateMesVersion(version)); + } + + [Fact] + public void Should_NotThrow_When_Version_Is_Null() + { + Program.ValidateMesVersion(null); + } + } +} diff --git a/tests/Specs/ProjectConfig.cs b/tests/Specs/ProjectConfig.cs deleted file mode 100644 index 0a121f316..000000000 --- a/tests/Specs/ProjectConfig.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Collections.Generic; -using System.IO.Abstractions.TestingHelpers; -using Cmf.CLI.Core.Objects; -using FluentAssertions; -using Xunit; - -namespace tests.Specs; - -public class ProjectConfig -{ - const string projCfgTpl = @"{ - ""ProjectName"": ""ExampleProject"", - ""NPMRegistry"": ""http://npmrepo/"", - ""NuGetRegistry"": ""https://nuget-repo/"", - ""AzureDevopsCollectionURL"": ""https://azuredevops.server/ExampleCollection"", - ""AgentPool"": ""ExamplePool"", - - ""RepositoryURL"": ""https://azuredevops.server/ExampleCollection/ExampleProject/_git/ExampleRepo"", - ""EnvironmentName"": ""ExampleIntegration"", - ""DefaultDomain"": ""AD"", - ""RESTPort"": ""443"", - ""Tenant"": ""ExampleClient"", - ""MESVersion"": ""9.0.5"", - ""DevTasksVersion"": ""{DEV_TASKS_VERSION}"", - ""HTMLStarterVersion"": ""8.0.0"", - ""YoGeneratorVersion"": ""8.1.1"", - ""NugetVersion"": ""9.0.5"", - ""TestScenariosNugetVersion"": ""9.0.5"", - ""IsSslEnabled"": ""True"", - ""vmHostname"": ""exampleintegration.int.local"", - ""DBReplica1"": ""SERV\\INSTANCE"", - ""DBReplica2"": ""SERV\\INSTANCE"", - ""DBServerOnline"": ""SERV\\INSTANCE"", - ""DBServerODS"": ""SERV\\INSTANCE"", - ""DBServerDWH"": ""SERV\\INSTANCE"", - ""ReportServerURI"": ""http://serv/Reports"", - ""AlwaysOn"": ""False"", - ""InstallationPath"": """", - ""DBBackupPath"": """", - ""TemporaryPath"": """", - ""HTMLPort"": ""443"", - ""GatewayPort"": ""443"", - ""ReleaseEnvironmentConfig"": ""ExampleIntegration_Development_parameters.json"" - }"; - - [Theory] - [InlineData("9.0.0")] - [InlineData("9.0.0-5")] - [InlineData("9.0.0-pre.5")] - public void ClassicProjectConfig(string devTasksVersion) - { - var projConfig = projCfgTpl.Replace("{DEV_TASKS_VERSION}", devTasksVersion); - - var fileSystem = new MockFileSystem(new Dictionary - { - { "/.project-config.json", new MockFileData(projConfig)} - }); - - var pc = (new ProjectConfigService()).Load(fileSystem); - - pc.Should().NotBeNull("project config was not loaded"); - pc.HTMLPort.Should().Be(443, "could not load HTML port"); - pc.AlwaysOn.Should().BeFalse("AlwaysOn should be false"); - pc.IsSslEnabled.Should().BeTrue("IsSslEnabled should be true"); - } -} \ No newline at end of file diff --git a/tests/Specs/Publish.cs b/tests/Specs/Publish.cs index a61fb17b4..4d8fef040 100644 --- a/tests/Specs/Publish.cs +++ b/tests/Specs/Publish.cs @@ -1,12 +1,10 @@ using System; using Xunit; using System.CommandLine; -using System.CommandLine.Invocation; using System.IO.Abstractions; using Moq; using Cmf.CLI.Commands; -using System.CommandLine.NamingConventionBinder; -using System.CommandLine.IO; +using System.Threading.Tasks; using System.Collections.Generic; using System.Formats.Tar; using System.IO.Abstractions.TestingHelpers; @@ -23,6 +21,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using tests.Mocks; +using System.Linq; namespace tests.Specs; @@ -40,20 +39,24 @@ public void Repository_Arg_ParsedCorrectly(string expectedHost, string inputRepo var cmd = new Command("publish"); publishCommand.Configure(cmd); + var fileArg = cmd.Arguments.FirstOrDefault(a => a.Name == "file") as Argument; + var repositoryOpt = cmd.Options.OfType>().FirstOrDefault(); + IFileInfo _file = null; Uri _repository = null; - cmd.Handler = CommandHandler.Create(( - file, repository) => + + cmd.SetAction((parseResult, cancellationToken) => { - _file = file; - _repository = repository; - } - ); + _file = parseResult.GetValue(fileArg); + _repository = parseResult.GetValue(repositoryOpt); + return Task.FromResult(0); + }); var console = new TestConsole(); - cmd.Invoke(new[] { + var parseResult = cmd.Parse(new[] { inputFile, "--repository", inputRepository - }, console); + }); + parseResult.Invoke(console); Assert.Equal(inputFile, _file.FullName); Assert.Equal(inputRepository, _repository.OriginalString); diff --git a/tests/Specs/Telemetry.cs b/tests/Specs/Telemetry.cs index 87c455d7e..a7cbdceee 100644 --- a/tests/Specs/Telemetry.cs +++ b/tests/Specs/Telemetry.cs @@ -175,7 +175,8 @@ public async Task SimulatePluginTelemetryBehavior() mockNpmClient.Setup(c => c.GetLatestVersion(false)).Returns(() => Task.FromResult("2.0.0")); // Call Configure to initialize DI and telemetry - var (rootCommand, parser) = await StartupModule.Configure( + // In beta5, Configure returns just RootCommand (not a tuple) + var rootCommand = await StartupModule.Configure( packageId: "plugin-test", envVarPrefix: "plugin_test", description: "Plugin Test", diff --git a/tests/Specs/ValidateStartAndEndMethods.cs b/tests/Specs/ValidateStartAndEndMethods.cs index e1b0d4d71..c4e56ca90 100644 --- a/tests/Specs/ValidateStartAndEndMethods.cs +++ b/tests/Specs/ValidateStartAndEndMethods.cs @@ -98,8 +98,23 @@ public void Process_MissingArgument_ShouldLogMissingParameterAndIncorrectNumberO processor.Process(); // Assert - logger.Verify(x => x.Warning(string.Format(ErrorMessages.MethodParameterMissingOrIncorrectlyNamed, "StartMethod", _baseClassName, _baseMethodName, "NewParameterType")), Times.Once); - logger.Verify(x => x.Warning(string.Format(ErrorMessages.MethodHasIncorrectNumberOfParameters, "StartMethod", _baseClassName, _baseMethodName, 3, 4)), Times.Once); + var missingParamMessage = string.Format( + ErrorMessages.MethodParameterMissingOrIncorrectlyNamed, + "StartMethod", + _baseClassName, + _baseMethodName, + "NewParameterType"); + + var incorrectCountMessage = string.Format( + ErrorMessages.MethodHasIncorrectNumberOfParameters, + "StartMethod", + _baseClassName, + _baseMethodName, + 3, + 4); + + logger.Verify(x => x.Warning(missingParamMessage), Times.Once); + logger.Verify(x => x.Warning(incorrectCountMessage), Times.Once); logger.Verify(x => x.Warning(It.IsAny()), Times.Exactly(2)); } @@ -125,8 +140,20 @@ public void Process_MethodNameWrongAndOutputNameWrong_ShouldLogInputObjectOutput processor.Process(); // Assert - logger.Verify(x => x.Warning(string.Format(ErrorMessages.InputOutputMethodDoNotCoincide, _baseClassName, wrongMethodName)), Times.Once); - logger.Verify(x => x.Warning(string.Format(ErrorMessages.MethodParameterMissingOrIncorrectlyNamed, "EndMethod", _baseClassName, wrongMethodName, _baseOutputType)), Times.Once); + var methodDontCoincideMessage = string.Format( + ErrorMessages.InputOutputMethodDoNotCoincide, + _baseClassName, + wrongMethodName); + + var missingParamMessage = string.Format( + ErrorMessages.MethodParameterMissingOrIncorrectlyNamed, + "EndMethod", + _baseClassName, + wrongMethodName, + _baseOutputType); + + logger.Verify(x => x.Warning(methodDontCoincideMessage), Times.Once); + logger.Verify(x => x.Warning(missingParamMessage), Times.Once); logger.Verify(x => x.Warning(It.IsAny()), Times.Exactly(2)); } diff --git a/tests/TestConsole.cs b/tests/TestConsole.cs new file mode 100644 index 000000000..ff36e7f2f --- /dev/null +++ b/tests/TestConsole.cs @@ -0,0 +1,98 @@ +using System.CommandLine; +using System.IO; + +namespace tests +{ + /// + /// Test console implementation for System.CommandLine beta5+ + /// Replaces the removed IConsole/TestConsole from beta4 + /// + public class TestConsole + { + private readonly StringWriter _out; + private readonly StringWriter _error; + + public TestConsole() + { + _out = new StringWriter(); + _error = new StringWriter(); + } + + public StringWriter Out => _out; + public StringWriter Error => _error; + } + + /// + /// Command wrapper to support beta4-style Invoke(args, console) pattern + /// + public class CommandWrapper + { + private readonly Command _command; + + public CommandWrapper(Command command) + { + _command = command; + } + + public int Invoke(string args) + { + return _command.Parse(args).Invoke(); + } + + public int Invoke(string[] args, TestConsole console) + { + var parseResult = _command.Parse(args); + return parseResult.Invoke(console); + } + + public async System.Threading.Tasks.Task InvokeAsync(string[] args, TestConsole console) + { + var parseResult = _command.Parse(args); + return await parseResult.InvokeAsync(console); + } + } + + /// + /// Extension methods for ParseResult to support TestConsole + /// + public static class ParseResultExtensions + { + public static int Invoke(this ParseResult parseResult, TestConsole console) + { + // In beta5, we need to redirect Console.Out and Console.Error temporarily + var originalOut = System.Console.Out; + var originalError = System.Console.Error; + + try + { + System.Console.SetOut(console.Out); + System.Console.SetError(console.Error); + return parseResult.Invoke(); + } + finally + { + System.Console.SetOut(originalOut); + System.Console.SetError(originalError); + } + } + + public static async System.Threading.Tasks.Task InvokeAsync(this ParseResult parseResult, TestConsole console) + { + // In beta5, we need to redirect Console.Out and Console.Error temporarily + var originalOut = System.Console.Out; + var originalError = System.Console.Error; + + try + { + System.Console.SetOut(console.Out); + System.Console.SetError(console.Error); + return await parseResult.InvokeAsync(); + } + finally + { + System.Console.SetOut(originalOut); + System.Console.SetError(originalError); + } + } + } +} diff --git a/tests/Utilities/TestUtilities.cs b/tests/Utilities/TestUtilities.cs index a86611899..ba2537243 100644 --- a/tests/Utilities/TestUtilities.cs +++ b/tests/Utilities/TestUtilities.cs @@ -1,22 +1,18 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.IO; -using System.CommandLine.Parsing; using System.Diagnostics; using System.IO; using System.IO.Abstractions; using System.IO.Compression; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; using System.Text.Json; using System.Threading.Tasks; using Cmf.CLI.Commands; using Cmf.CLI.Core.Attributes; using FluentAssertions; -using Xunit; +using tests; namespace Cmf.Common.Cli.TestUtilities { @@ -147,25 +143,18 @@ public static List GetFileEntriesFromZip(string packageFile) } /// - /// Create a minimal parser to invoke commands with - /// The default parser brings a lot of extras that we don't require in the tests + /// Returns a CommandWrapper that supports beta4-style Invoke(args, console) pattern /// /// /// - public static Parser GetParser(Command cmd) + public static CommandWrapper GetParser(Command cmd) { - return new CommandLineBuilder(cmd) - .UseEnvironmentVariableDirective() - .UseParseDirective() - .UseParseErrorReporting() - .UseExceptionHandler() - .CancelOnProcessTermination() - .Build(); + // In beta5, wrap the command to support the old Parser.Invoke(args, console) pattern + return new CommandWrapper(cmd); } /// - /// Create a minimal parser to invoke commands with - /// The default parser brings a lot of extras that we don't require in the tests + /// Invoke command with test console /// /// /// @@ -177,7 +166,8 @@ public static void TestInvoke(T cmd, string[] args) var root = new Command("cmf"); cmd.Configure(root); - var result = GetParser(root).Invoke(args, console); + var parseResult = root.Parse(args); + var result = parseResult.Invoke(console); if (result != 0) { @@ -186,8 +176,7 @@ public static void TestInvoke(T cmd, string[] args) } /// - /// Create a minimal parser to invoke commands with - /// The default parser brings a lot of extras that we don't require in the tests + /// Invoke command asynchronously with test console /// /// /// @@ -197,7 +186,8 @@ public static async Task TestInvokeAsync(T cmd, string[] args, bool setupPare var console = new TestConsole(); var attr = cmd.GetType().GetCustomAttributes(false).First(); - var root= new Command(attr.Name) { IsHidden = attr.IsHidden, Description = attr.Description }; + var root= new Command(attr.Name) { Description = attr.Description }; + // Note: IsHidden property was removed in System.CommandLine beta5 cmd.Configure(root); if (setupParents) @@ -217,8 +207,9 @@ public static async Task TestInvokeAsync(T cmd, string[] args, bool setupPare currentCmd = parentCmd; // Create command - var cmdInstance = new Command(parentCmd.attribute.Name) { IsHidden = parentCmd.attribute.IsHidden, Description = parentCmd.attribute.Description }; - cmdInstance.AddCommand(root); + var cmdInstance = new Command(parentCmd.attribute.Name) { Description = parentCmd.attribute.Description }; + // Note: IsHidden property was removed in System.CommandLine beta5 + cmdInstance.Add(root); root = cmdInstance; // Call "Configure" method @@ -228,7 +219,8 @@ public static async Task TestInvokeAsync(T cmd, string[] args, bool setupPare } } - var result = await GetParser(root).InvokeAsync(args, console); + var parseResult = root.Parse(args); + var result = await parseResult.InvokeAsync(console); if (result != 0) { diff --git a/tests/tests.csproj b/tests/tests.csproj index d39c4e756..74c50094d 100644 --- a/tests/tests.csproj +++ b/tests/tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net10.0 @@ -14,6 +14,7 @@ + @@ -21,6 +22,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + +