From 128b3787db8a1a15bcba57389ca81eb161579152 Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 13:14:18 +0300 Subject: [PATCH 01/36] Check for missing translations --- .github/workflows/check-translations.yml | 34 +++++++++++ scripts/check-translations.ps1 | 75 ++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 .github/workflows/check-translations.yml create mode 100644 scripts/check-translations.ps1 diff --git a/.github/workflows/check-translations.yml b/.github/workflows/check-translations.yml new file mode 100644 index 0000000000..b9bec792b5 --- /dev/null +++ b/.github/workflows/check-translations.yml @@ -0,0 +1,34 @@ +name: Check Translations + +on: + workflow_dispatch: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + check-translations: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.x + + - name: Run translation check + working-directory: vscode/microsoft-kiota + run: scripts/check-translations.ps1 + shell: pwsh + + - name: Upload untranslated strings + if: failure() + uses: actions/upload-artifact@v2 + with: + name: untranslated-strings + path: vscode/microsoft-kiota/untranslated_strings.html diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 new file mode 100644 index 0000000000..d785eff13f --- /dev/null +++ b/scripts/check-translations.ps1 @@ -0,0 +1,75 @@ +# Step 1: Find all instances of vscode.l10n.t() and extract the strings from .ts and .tsx files +Get-ChildItem -Path src -Recurse -Include *.ts, *.tsx | +Select-String -Pattern 'vscode.l10n.t\("([^"]+)"\)' | +ForEach-Object { $_.Matches.Groups[1].Value } | +Sort-Object | +Out-File -FilePath "strings.txt" + +# Step 2: Check translation files in the l10n folder +$results = @() +foreach ($file in Get-ChildItem -Path "l10n" -Filter bundle.l10n.*.json -Recurse) { + $translations = Get-Content $file.FullName | + Select-String -Pattern '"[^"]+"' | + ForEach-Object { $_.Matches.Groups[0].Value.Trim('"') } | + Sort-Object + + $missing = Compare-Object (Get-Content "strings.txt") $translations -PassThru | + Where-Object { $_.SideIndicator -eq "<=" } + + if ($missing) { + $untranslatedItems = $missing | ForEach-Object { "
  • $_
  • " } + $results += [PSCustomObject]@{ + "LanguageFile" = "$($file.Name) ($($untranslatedItems.Count) found)" + "UntranslatedStrings" = "" + } + } +} + +# Create the HTML table +$htmlTable = @" + + + + + + +

    Untranslated Strings

    + + + + + +"@ + +foreach ($result in $results) { + $htmlTable += "" +} + +$htmlTable += @" +
    Language FileUntranslated Strings
    $($result.LanguageFile)$($result.UntranslatedStrings)
    + + +"@ + +$htmlTable | Out-File -FilePath "untranslated_strings.html" + +if ($results.Count -gt 0) { + Write-Host "Untranslated strings found. See untranslated_strings.html for details." -ForegroundColor Red + exit 1 +} +else { + Write-Host "All strings have translations." -ForegroundColor Green +} From 91c669ced32ade421dcf03abbab22b15de540f9e Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 13:24:13 +0300 Subject: [PATCH 02/36] upgrade upload artifacts version --- .github/workflows/check-translations.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-translations.yml b/.github/workflows/check-translations.yml index b9bec792b5..6d2c69d243 100644 --- a/.github/workflows/check-translations.yml +++ b/.github/workflows/check-translations.yml @@ -28,7 +28,7 @@ jobs: - name: Upload untranslated strings if: failure() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: untranslated-strings path: vscode/microsoft-kiota/untranslated_strings.html From ef47c9a34166e8b1c20056945e8015904ab6b7c5 Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 13:27:16 +0300 Subject: [PATCH 03/36] Fix translation check script path in check-translations.yml --- .github/workflows/check-translations.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-translations.yml b/.github/workflows/check-translations.yml index 6d2c69d243..df3b5aa024 100644 --- a/.github/workflows/check-translations.yml +++ b/.github/workflows/check-translations.yml @@ -20,10 +20,11 @@ jobs: uses: actions/setup-node@v4 with: node-version: 18.x + - name: Run translation check working-directory: vscode/microsoft-kiota - run: scripts/check-translations.ps1 + run: ./scripts/check-translations.ps1 shell: pwsh - name: Upload untranslated strings From 03dde6ebe112a9b9bd0972c5ab91e2008b9dc937 Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 13:37:29 +0300 Subject: [PATCH 04/36] change working directories --- .github/workflows/check-translations.yml | 2 -- scripts/check-translations.ps1 | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/check-translations.yml b/.github/workflows/check-translations.yml index df3b5aa024..adf436535d 100644 --- a/.github/workflows/check-translations.yml +++ b/.github/workflows/check-translations.yml @@ -21,9 +21,7 @@ jobs: with: node-version: 18.x - - name: Run translation check - working-directory: vscode/microsoft-kiota run: ./scripts/check-translations.ps1 shell: pwsh diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 index d785eff13f..600ee2a86d 100644 --- a/scripts/check-translations.ps1 +++ b/scripts/check-translations.ps1 @@ -1,5 +1,5 @@ # Step 1: Find all instances of vscode.l10n.t() and extract the strings from .ts and .tsx files -Get-ChildItem -Path src -Recurse -Include *.ts, *.tsx | +Get-ChildItem -Path vscode/microsoft-kiota/src -Recurse -Include *.ts, *.tsx | Select-String -Pattern 'vscode.l10n.t\("([^"]+)"\)' | ForEach-Object { $_.Matches.Groups[1].Value } | Sort-Object | From c67f86b0e9915c7c10987ae5c9a89ffa5752c15a Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 13:51:29 +0300 Subject: [PATCH 05/36] correct where items are checked --- .github/workflows/check-translations.yml | 5 ++--- scripts/check-translations.ps1 | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-translations.yml b/.github/workflows/check-translations.yml index adf436535d..1515e522ea 100644 --- a/.github/workflows/check-translations.yml +++ b/.github/workflows/check-translations.yml @@ -20,14 +20,13 @@ jobs: uses: actions/setup-node@v4 with: node-version: 18.x - + - name: Run translation check run: ./scripts/check-translations.ps1 shell: pwsh - name: Upload untranslated strings - if: failure() uses: actions/upload-artifact@v4 with: name: untranslated-strings - path: vscode/microsoft-kiota/untranslated_strings.html + path: ./untranslated_strings.html diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 index 600ee2a86d..8798d9a428 100644 --- a/scripts/check-translations.ps1 +++ b/scripts/check-translations.ps1 @@ -7,7 +7,7 @@ Out-File -FilePath "strings.txt" # Step 2: Check translation files in the l10n folder $results = @() -foreach ($file in Get-ChildItem -Path "l10n" -Filter bundle.l10n.*.json -Recurse) { +foreach ($file in Get-ChildItem -Path "vscode/microsoft-kiota/l10n" -Filter bundle.l10n.*.json -Recurse) { $translations = Get-Content $file.FullName | Select-String -Pattern '"[^"]+"' | ForEach-Object { $_.Matches.Groups[0].Value.Trim('"') } | From 7eee5b5845a0c4ec5e0c58098e7bc0e39a499504 Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 14:03:45 +0300 Subject: [PATCH 06/36] No exit with errror --- scripts/check-translations.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 index 8798d9a428..2e07a93b1b 100644 --- a/scripts/check-translations.ps1 +++ b/scripts/check-translations.ps1 @@ -68,7 +68,6 @@ $htmlTable | Out-File -FilePath "untranslated_strings.html" if ($results.Count -gt 0) { Write-Host "Untranslated strings found. See untranslated_strings.html for details." -ForegroundColor Red - exit 1 } else { Write-Host "All strings have translations." -ForegroundColor Green From c3e6f4460121cddedeba710c14bdb2c371831dd5 Mon Sep 17 00:00:00 2001 From: thewahome Date: Tue, 15 Oct 2024 14:11:24 +0300 Subject: [PATCH 07/36] provide summary --- scripts/check-translations.ps1 | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 index 2e07a93b1b..8d4821925d 100644 --- a/scripts/check-translations.ps1 +++ b/scripts/check-translations.ps1 @@ -19,7 +19,8 @@ foreach ($file in Get-ChildItem -Path "vscode/microsoft-kiota/l10n" -Filter bund if ($missing) { $untranslatedItems = $missing | ForEach-Object { "
  • $_
  • " } $results += [PSCustomObject]@{ - "LanguageFile" = "$($file.Name) ($($untranslatedItems.Count) found)" + "LanguageFile" = "$($file.Name)" + "Count" = "$($untranslatedItems.Count) found" "UntranslatedStrings" = "
      $($untranslatedItems -join "`n")
    " } } @@ -55,7 +56,7 @@ $htmlTable = @" "@ foreach ($result in $results) { - $htmlTable += "$($result.LanguageFile)$($result.UntranslatedStrings)" + $htmlTable += "$($result.LanguageFile) ($($result.Count))$($result.UntranslatedStrings)" } $htmlTable += @" @@ -66,8 +67,14 @@ $htmlTable += @" $htmlTable | Out-File -FilePath "untranslated_strings.html" +# Output a summary table to the workflow log if ($results.Count -gt 0) { Write-Host "Untranslated strings found. See untranslated_strings.html for details." -ForegroundColor Red + Write-Host "| Language File | Count |" + Write-Host "|----------------------------------------|---------|" + foreach ($result in $results) { + Write-Host "| $($result.LanguageFile) | $($result.Count) |" + } } else { Write-Host "All strings have translations." -ForegroundColor Green From 2247d7a23fd5de1ac470c2d7a4fb243daf54c25e Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 15 Oct 2024 09:23:16 -0400 Subject: [PATCH 08/36] Update .github/workflows/check-translations.yml --- .github/workflows/check-translations.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-translations.yml b/.github/workflows/check-translations.yml index 1515e522ea..09b02848a1 100644 --- a/.github/workflows/check-translations.yml +++ b/.github/workflows/check-translations.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 22.x - name: Run translation check run: ./scripts/check-translations.ps1 From 2cbfb159d10ecf1fbf9abf2bfc9d60f0ca41dfd0 Mon Sep 17 00:00:00 2001 From: thewahome Date: Wed, 16 Oct 2024 09:49:21 +0300 Subject: [PATCH 09/36] translation strings unique and parameterised --- scripts/check-translations.ps1 | 46 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 index 8d4821925d..86a70da5a5 100644 --- a/scripts/check-translations.ps1 +++ b/scripts/check-translations.ps1 @@ -1,8 +1,23 @@ # Step 1: Find all instances of vscode.l10n.t() and extract the strings from .ts and .tsx files -Get-ChildItem -Path vscode/microsoft-kiota/src -Recurse -Include *.ts, *.tsx | -Select-String -Pattern 'vscode.l10n.t\("([^"]+)"\)' | -ForEach-Object { $_.Matches.Groups[1].Value } | -Sort-Object | +$withParamsPattern = 'vscode\.l10n\.t\(["' + "`'" + '`](.+?)["' + "`'" + '`],' +Get-ChildItem -Path vscode/microsoft-kiota/src -Recurse -Include *.ts, *.tsx | +Select-String -Pattern $withParamsPattern | +ForEach-Object { $_.Matches.Groups[1].Value } | +Sort-Object | +Get-Unique | +Out-File -FilePath "strings_with_params.txt" + +$withoutParamsPattern = 'vscode\.l10n\.t\(["' + "`'" + '`]([^"' + "`'" + '`]+)["' + "`'" + '`]\)' +Get-ChildItem -Path vscode/microsoft-kiota/src -Recurse -Include *.ts, *.tsx | +Select-String -Pattern $withoutParamsPattern | +ForEach-Object { $_.Matches.Groups[1].Value } | +Sort-Object | +Get-Unique | +Out-File -FilePath "strings_without_params.txt" + +Get-Content strings_with_params.txt, strings_without_params.txt | +Sort-Object | +Get-Unique | Out-File -FilePath "strings.txt" # Step 2: Check translation files in the l10n folder @@ -12,10 +27,9 @@ foreach ($file in Get-ChildItem -Path "vscode/microsoft-kiota/l10n" -Filter bund Select-String -Pattern '"[^"]+"' | ForEach-Object { $_.Matches.Groups[0].Value.Trim('"') } | Sort-Object - - $missing = Compare-Object (Get-Content "strings.txt") $translations -PassThru | + $missing = Compare-Object (Get-Content "strings.txt") $translations -PassThru | Where-Object { $_.SideIndicator -eq "<=" } - + if ($missing) { $untranslatedItems = $missing | ForEach-Object { "
  • $_
  • " } $results += [PSCustomObject]@{ @@ -32,18 +46,9 @@ $htmlTable = @" @@ -54,17 +59,14 @@ $htmlTable = @" Untranslated Strings "@ - foreach ($result in $results) { $htmlTable += "$($result.LanguageFile) ($($result.Count))$($result.UntranslatedStrings)" } - $htmlTable += @" "@ - $htmlTable | Out-File -FilePath "untranslated_strings.html" # Output a summary table to the workflow log From 75b5411edbe74090bd2ba5378c3297db99fcc4bd Mon Sep 17 00:00:00 2001 From: Charles Wahome Date: Tue, 22 Oct 2024 15:13:19 +0300 Subject: [PATCH 10/36] make regex into a continuous string Co-authored-by: Caleb Kiage <747955+calebkiage@users.noreply.github.com> --- scripts/check-translations.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-translations.ps1 b/scripts/check-translations.ps1 index 86a70da5a5..c606ec9c61 100644 --- a/scripts/check-translations.ps1 +++ b/scripts/check-translations.ps1 @@ -1,5 +1,5 @@ # Step 1: Find all instances of vscode.l10n.t() and extract the strings from .ts and .tsx files -$withParamsPattern = 'vscode\.l10n\.t\(["' + "`'" + '`](.+?)["' + "`'" + '`],' +$withParamsPattern = 'vscode\.l10n\.t\(["''`](.+?)["''`],' Get-ChildItem -Path vscode/microsoft-kiota/src -Recurse -Include *.ts, *.tsx | Select-String -Pattern $withParamsPattern | ForEach-Object { $_.Matches.Groups[1].Value } | From e810655e98cfe4c4176413fb414c5e2f74c40ef7 Mon Sep 17 00:00:00 2001 From: thewahome Date: Mon, 25 Nov 2024 13:27:19 +0300 Subject: [PATCH 11/36] move to correct location to avoid noise --- .../openApidescription/searchOrOpenApiDescriptionCommand.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts b/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts index a701f233b7..6536ded89d 100644 --- a/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts +++ b/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts @@ -63,7 +63,7 @@ export class SearchOrOpenApiDescriptionCommand extends Command { if (config.descriptionPath) { await openTreeViewWithProgress(() => this._openApiTreeProvider.setDescriptionUrl(config.descriptionPath!)); + await vscode.window.showInformationMessage(vscode.l10n.t('You can now select the required endpoints from {0}', this._openApiTreeProvider.apiTitle!)); } - await vscode.window.showInformationMessage(vscode.l10n.t('You can now select the required endpoints from {0}', this._openApiTreeProvider.apiTitle!)); } } From 5ca9725f5fdb7b5582fb7a33e404b440c096434a Mon Sep 17 00:00:00 2001 From: thewahome Date: Mon, 25 Nov 2024 14:08:59 +0300 Subject: [PATCH 12/36] show generate after loading api for the first time --- .../searchOrOpenApiDescriptionCommand.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts b/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts index 6536ded89d..5ee0859099 100644 --- a/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts +++ b/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts @@ -63,7 +63,15 @@ export class SearchOrOpenApiDescriptionCommand extends Command { if (config.descriptionPath) { await openTreeViewWithProgress(() => this._openApiTreeProvider.setDescriptionUrl(config.descriptionPath!)); - await vscode.window.showInformationMessage(vscode.l10n.t('You can now select the required endpoints from {0}', this._openApiTreeProvider.apiTitle!)); + + const generateAnswer = vscode.l10n.t("Generate"); + const response = await vscode.window.showInformationMessage( + vscode.l10n.t('Click on Generate after selecting the paths in the API Explorer'), + generateAnswer + ); + if (response === generateAnswer) { + await vscode.commands.executeCommand(`${treeViewId}.generateClient`); + } } } } From 37966c7e5b60a0c4ab574e3ded5abb13995fa67e Mon Sep 17 00:00:00 2001 From: thewahome Date: Mon, 25 Nov 2024 14:09:17 +0300 Subject: [PATCH 13/36] show regenerate after loading api from a workspace --- .../microsoft-kiota/src/commands/editPathsCommand.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vscode/microsoft-kiota/src/commands/editPathsCommand.ts b/vscode/microsoft-kiota/src/commands/editPathsCommand.ts index 311215a8ab..80d925e1ea 100644 --- a/vscode/microsoft-kiota/src/commands/editPathsCommand.ts +++ b/vscode/microsoft-kiota/src/commands/editPathsCommand.ts @@ -1,3 +1,5 @@ +import * as vscode from 'vscode'; + import { extensionId, treeViewId } from "../constants"; import { ClientOrPluginProperties } from "../kiotaInterop"; import { OpenApiTreeProvider } from "../providers/openApiTreeProvider"; @@ -27,5 +29,14 @@ export class EditPathsCommand extends Command { private async loadEditPaths(clientOrPluginKey: string, clientOrPluginObject: ClientOrPluginProperties) { await openTreeViewWithProgress(() => this._openApiTreeProvider.loadEditPaths(clientOrPluginKey, clientOrPluginObject)); + + const regenerateAnswer = vscode.l10n.t("Regenerate"); + const response = await vscode.window.showInformationMessage( + vscode.l10n.t('Click on Regenerate after selecting the paths in the API Explorer'), + regenerateAnswer + ); + if (response === regenerateAnswer) { + await vscode.commands.executeCommand(`kiota.regenerate`); + } } } From 724e74d28bd34ed3197f085034b532a21cc1c30f Mon Sep 17 00:00:00 2001 From: thewahome Date: Mon, 25 Nov 2024 15:29:43 +0300 Subject: [PATCH 14/36] add and respect do not show again option --- .../src/commands/editPathsCommand.ts | 34 +++++++++------ .../searchOrOpenApiDescriptionCommand.ts | 41 +++++++++++-------- vscode/microsoft-kiota/src/constants.ts | 1 + vscode/microsoft-kiota/src/extension.ts | 2 +- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/vscode/microsoft-kiota/src/commands/editPathsCommand.ts b/vscode/microsoft-kiota/src/commands/editPathsCommand.ts index 80d925e1ea..6be7a54c0d 100644 --- a/vscode/microsoft-kiota/src/commands/editPathsCommand.ts +++ b/vscode/microsoft-kiota/src/commands/editPathsCommand.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; -import { extensionId, treeViewId } from "../constants"; +import { extensionId, SHOW_MESSAGE_AFTER_API_LOAD, treeViewId } from "../constants"; import { ClientOrPluginProperties } from "../kiotaInterop"; import { OpenApiTreeProvider } from "../providers/openApiTreeProvider"; import { WorkspaceGenerationContext } from "../types/WorkspaceGenerationContext"; @@ -10,11 +10,11 @@ import { Command } from "./Command"; export class EditPathsCommand extends Command { - private _openApiTreeProvider: OpenApiTreeProvider; - - public constructor(openApiTreeProvider: OpenApiTreeProvider) { + constructor( + private openApiTreeProvider: OpenApiTreeProvider, + private context: vscode.ExtensionContext + ) { super(); - this._openApiTreeProvider = openApiTreeProvider; } public getName(): string { @@ -23,20 +23,28 @@ export class EditPathsCommand extends Command { public async execute({ clientOrPluginKey, clientOrPluginObject }: Partial): Promise { await this.loadEditPaths(clientOrPluginKey!, clientOrPluginObject!); - this._openApiTreeProvider.resetInitialState(); + this.openApiTreeProvider.resetInitialState(); await updateTreeViewIcons(treeViewId, false, true); } private async loadEditPaths(clientOrPluginKey: string, clientOrPluginObject: ClientOrPluginProperties) { - await openTreeViewWithProgress(() => this._openApiTreeProvider.loadEditPaths(clientOrPluginKey, clientOrPluginObject)); + await openTreeViewWithProgress(() => this.openApiTreeProvider.loadEditPaths(clientOrPluginKey, clientOrPluginObject)); const regenerateAnswer = vscode.l10n.t("Regenerate"); - const response = await vscode.window.showInformationMessage( - vscode.l10n.t('Click on Regenerate after selecting the paths in the API Explorer'), - regenerateAnswer - ); - if (response === regenerateAnswer) { - await vscode.commands.executeCommand(`kiota.regenerate`); + const showGenerateMessage = this.context.globalState.get(SHOW_MESSAGE_AFTER_API_LOAD, true); + + if (showGenerateMessage) { + const doNotShowAgainOption = vscode.l10n.t("Do not show this again"); + const response = await vscode.window.showInformationMessage( + vscode.l10n.t('Click on Regenerate after selecting the paths in the API Explorer'), + regenerateAnswer, + doNotShowAgainOption + ); + if (response === regenerateAnswer) { + await vscode.commands.executeCommand(`kiota.regenerate`); + } else if (response === doNotShowAgainOption) { + await this.context.globalState.update(SHOW_MESSAGE_AFTER_API_LOAD, false); + } } } } diff --git a/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts b/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts index 5ee0859099..4dbca1de20 100644 --- a/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts +++ b/vscode/microsoft-kiota/src/commands/openApidescription/searchOrOpenApiDescriptionCommand.ts @@ -1,7 +1,7 @@ import TelemetryReporter from "@vscode/extension-telemetry"; import * as vscode from "vscode"; -import { extensionId, treeViewId } from "../../constants"; +import { extensionId, SHOW_MESSAGE_AFTER_API_LOAD, treeViewId } from "../../constants"; import { setDeepLinkParams } from "../../handlers/deepLinkParamsHandler"; import { searchSteps } from "../../modules/steps/searchSteps"; import { OpenApiTreeProvider } from "../../providers/openApiTreeProvider"; @@ -13,13 +13,11 @@ import { searchDescription } from "./searchDescription"; export class SearchOrOpenApiDescriptionCommand extends Command { - private _openApiTreeProvider: OpenApiTreeProvider; - private _context: vscode.ExtensionContext; - - constructor(openApiTreeProvider: OpenApiTreeProvider, context: vscode.ExtensionContext) { + constructor( + private openApiTreeProvider: OpenApiTreeProvider, + private context: vscode.ExtensionContext + ) { super(); - this._openApiTreeProvider = openApiTreeProvider; - this._context = context; } public getName(): string { @@ -31,7 +29,7 @@ export class SearchOrOpenApiDescriptionCommand extends Command { if (Object.keys(searchParams).length > 0) { let [params, errorsArray] = validateDeepLinkQueryParams(searchParams); setDeepLinkParams(params); - const reporter = new TelemetryReporter(this._context.extension.packageJSON.telemetryInstrumentationKey); + const reporter = new TelemetryReporter(this.context.extension.packageJSON.telemetryInstrumentationKey); reporter.sendTelemetryEvent("DeepLinked searchOrOpenApiDescription", { "searchParameters": JSON.stringify(searchParams), "validationErrors": errorsArray.join(", ") @@ -40,7 +38,7 @@ export class SearchOrOpenApiDescriptionCommand extends Command { // proceed to enable loading of openapi description const yesAnswer = vscode.l10n.t("Yes, override it"); - if (this._openApiTreeProvider.hasChanges()) { + if (this.openApiTreeProvider.hasChanges()) { const response = await vscode.window.showWarningMessage( vscode.l10n.t( "Before adding a new API description, consider that your changes and current selection will be lost."), @@ -58,19 +56,28 @@ export class SearchOrOpenApiDescriptionCommand extends Command { title: vscode.l10n.t("Searching...") }, (progress, _) => { const settings = getExtensionSettings(extensionId); - return searchDescription(this._context, x, settings.clearCache); + return searchDescription(this.context, x, settings.clearCache); })); if (config.descriptionPath) { - await openTreeViewWithProgress(() => this._openApiTreeProvider.setDescriptionUrl(config.descriptionPath!)); + await openTreeViewWithProgress(() => this.openApiTreeProvider.setDescriptionUrl(config.descriptionPath!)); const generateAnswer = vscode.l10n.t("Generate"); - const response = await vscode.window.showInformationMessage( - vscode.l10n.t('Click on Generate after selecting the paths in the API Explorer'), - generateAnswer - ); - if (response === generateAnswer) { - await vscode.commands.executeCommand(`${treeViewId}.generateClient`); + const showGenerateMessage = this.context.globalState.get(SHOW_MESSAGE_AFTER_API_LOAD, true); + + if (showGenerateMessage) { + const doNotShowAgainOption = vscode.l10n.t("Do not show this again"); + const response = await vscode.window.showInformationMessage( + vscode.l10n.t('Click on Generate after selecting the paths in the API Explorer'), + generateAnswer, + doNotShowAgainOption + ); + + if (response === generateAnswer) { + await vscode.commands.executeCommand(`${treeViewId}.generateClient`); + } else if (response === doNotShowAgainOption) { + await this.context.globalState.update(SHOW_MESSAGE_AFTER_API_LOAD, false); + } } } } diff --git a/vscode/microsoft-kiota/src/constants.ts b/vscode/microsoft-kiota/src/constants.ts index 4c627f2e39..d8463811d1 100644 --- a/vscode/microsoft-kiota/src/constants.ts +++ b/vscode/microsoft-kiota/src/constants.ts @@ -15,3 +15,4 @@ export const APIMANIFEST = "apimanifest"; export const REMIND_ME_LATER_FLAG = 'remindMeLater'; export const API_MANIFEST_FILE = "apimanifest.json"; export const MANIFEST_KIOTA_VERSION_KEY = "x-ms-kiota-version"; +export const SHOW_MESSAGE_AFTER_API_LOAD = "show-message-after-api-load"; diff --git a/vscode/microsoft-kiota/src/extension.ts b/vscode/microsoft-kiota/src/extension.ts index d681521038..62e3aa6017 100644 --- a/vscode/microsoft-kiota/src/extension.ts +++ b/vscode/microsoft-kiota/src/extension.ts @@ -68,7 +68,7 @@ export async function activate( const removeFromSelectedEndpointsCommand = new RemoveFromSelectedEndpointsCommand(openApiTreeProvider); const filterDescriptionCommand = new FilterDescriptionCommand(openApiTreeProvider); const openDocumentationPageCommand = new OpenDocumentationPageCommand(); - const editPathsCommand = new EditPathsCommand(openApiTreeProvider); + const editPathsCommand = new EditPathsCommand(openApiTreeProvider, context); const searchOrOpenApiDescriptionCommand = new SearchOrOpenApiDescriptionCommand(openApiTreeProvider, context); const generateClientCommand = new GenerateClientCommand(openApiTreeProvider, context, dependenciesInfoProvider, setWorkspaceGenerationContext, kiotaOutputChannel); const regenerateCommand = new RegenerateCommand(context, openApiTreeProvider, kiotaOutputChannel); From ddf5474f332211784418feeb07e6f885fe5faeb8 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 25 Nov 2024 13:44:17 -0500 Subject: [PATCH 15/36] fix: single entry one/any of merging Signed-off-by: Vincent Biret --- CHANGELOG.md | 5 +- .../Extensions/OpenApiSchemaExtensions.cs | 38 +++- src/Kiota.Builder/KiotaBuilder.cs | 10 + .../Kiota.Builder.Tests/KiotaBuilderTests.cs | 176 ++++++++++++++++++ 4 files changed, 223 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17076aa315..224f085f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Fixed python generation in scenarios with opening/closing tags for code comments. [#5636](https://github.com/microsoft/kiota/issues/5636) -- Fixed Python error when a class inherits from a base class and implements an interface. [5637](https://github.com/microsoft/kiota/issues/5637) -- Fix anyOf/oneOf generation in TypeScript. [5353](https://github.com/microsoft/kiota/issues/5353) +- Fixed Python error when a class inherits from a base class and implements an interface. [#5637](https://github.com/microsoft/kiota/issues/5637) +- Fixed a bug where one/any schemas with single schema entries would be missing properties. [#5808](https://github.com/microsoft/kiota/issues/5808) +- Fixed anyOf/oneOf generation in TypeScript. [5353](https://github.com/microsoft/kiota/issues/5353) - Fixed invalid code in Php caused by "*/*/" in property description. [5635](https://github.com/microsoft/kiota/issues/5635) - Fixed TypeScript generation error when generating usings from shaken serializers. [#5634](https://github.com/microsoft/kiota/issues/5634) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index c5ed4b24e9..890231960c 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -68,9 +68,9 @@ public static bool HasAnyProperty(this OpenApiSchema? schema) { return schema?.Properties is { Count: > 0 }; } - public static bool IsInclusiveUnion(this OpenApiSchema? schema) + public static bool IsInclusiveUnion(this OpenApiSchema? schema, uint exclusiveMinimumNumberOfEntries = 1) { - return schema?.AnyOf?.Count(static x => IsSemanticallyMeaningful(x, true)) > 1; + return schema?.AnyOf?.Count(static x => IsSemanticallyMeaningful(x, true)) > exclusiveMinimumNumberOfEntries; // so we don't consider any of object/nullable as a union type } @@ -89,6 +89,36 @@ public static bool IsInherited(this OpenApiSchema? schema) return schema.MergeIntersectionSchemaEntries(schemasToExclude, true, filter); } + internal static OpenApiSchema? MergeInclusiveUnionSchemaEntries(this OpenApiSchema? schema) + { + if (schema is null || !schema.IsInclusiveUnion(0)) return null; + var result = new OpenApiSchema(schema); + result.AnyOf.Clear(); + foreach (var subSchema in schema.AnyOf) + { + foreach (var property in subSchema.Properties) + { + result.Properties.TryAdd(property.Key, property.Value); + } + } + return result; + } + + internal static OpenApiSchema? MergeExclusiveUnionSchemaEntries(this OpenApiSchema? schema) + { + if (schema is null || !schema.IsExclusiveUnion(0)) return null; + var result = new OpenApiSchema(schema); + result.OneOf.Clear(); + foreach (var subSchema in schema.OneOf) + { + foreach (var property in subSchema.Properties) + { + result.Properties.TryAdd(property.Key, property.Value); + } + } + return result; + } + internal static OpenApiSchema? MergeIntersectionSchemaEntries(this OpenApiSchema? schema, HashSet? schemasToExclude = default, bool overrideIntersection = false, Func? filter = default) { if (schema is null) return null; @@ -123,9 +153,9 @@ public static bool IsIntersection(this OpenApiSchema? schema) return meaningfulSchemas?.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) > 1 || meaningfulSchemas?.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) > 1; } - public static bool IsExclusiveUnion(this OpenApiSchema? schema) + public static bool IsExclusiveUnion(this OpenApiSchema? schema, uint exclusiveMinimumNumberOfEntries = 1) { - return schema?.OneOf?.Count(static x => IsSemanticallyMeaningful(x, true)) > 1; + return schema?.OneOf?.Count(static x => IsSemanticallyMeaningful(x, true)) > exclusiveMinimumNumberOfEntries; // so we don't consider one of object/nullable as a union type } private static readonly HashSet oDataTypes = new(StringComparer.OrdinalIgnoreCase) { diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index fd4e0887c2..40c3207ff9 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1895,6 +1895,16 @@ private CodeElement AddModelDeclarationIfDoesntExist(OpenApiUrlTreeNode currentN // multiple allOf entries that do not translate to inheritance return createdClass; } + else if (schema.MergeInclusiveUnionSchemaEntries() is { } iUMergedSchema && + AddModelClass(currentNode, iUMergedSchema, declarationName, currentNamespace, currentOperation, inheritsFrom) is CodeClass uICreatedClass) + { + return uICreatedClass; + } + else if (schema.MergeExclusiveUnionSchemaEntries() is { } eUMergedSchema && + AddModelClass(currentNode, eUMergedSchema, declarationName, currentNamespace, currentOperation, inheritsFrom) is CodeClass uECreatedClass) + { + return uECreatedClass; + } return AddModelClass(currentNode, schema, declarationName, currentNamespace, currentOperation, inheritsFrom); } return existingDeclaration; diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 606bbe5c62..a62089926f 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -8536,6 +8536,182 @@ public async Task InheritanceWithAllOfBaseClassNoAdditionalPropertiesAsync() Assert.Equal("baseDirectoryObject", link.StartBlock.Inherits.Name); } + [Fact] + public async Task ExclusiveUnionSingleEntriesMergingAsync() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await using var fs = await GetDocumentStreamAsync( +""" +openapi: 3.0.0 +info: + title: "Generator not generating oneOf if the containing schema has type: object" + version: "1.0.0" +servers: + - url: https://mytodos.doesnotexist/ +paths: + /uses-components: + post: + description: Return something + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/UsesComponents" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UsesComponents" +components: + schemas: + ExampleWithSingleOneOfWithTypeObject: + type: object + oneOf: + - $ref: "#/components/schemas/Component1" + discriminator: + propertyName: objectType + ExampleWithSingleOneOfWithoutTypeObject: + oneOf: + - $ref: "#/components/schemas/Component2" + discriminator: + propertyName: objectType + + UsesComponents: + type: object + properties: + component_with_single_oneof_with_type_object: + $ref: "#/components/schemas/ExampleWithSingleOneOfWithTypeObject" + component_with_single_oneof_without_type_object: + $ref: "#/components/schemas/ExampleWithSingleOneOfWithoutTypeObject" + + Component1: + type: object + required: + - objectType + properties: + objectType: + type: string + one: + type: string + + Component2: + type: object + required: + - objectType + properties: + objectType: + type: string + two: + type: string +"""); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + var codeModel = builder.CreateSourceModel(node); + + // Verify that all three classes referenced by the discriminator inherit from baseDirectoryObject + var withObjectClass = codeModel.FindChildByName("ExampleWithSingleOneOfWithTypeObject"); + Assert.NotNull(withObjectClass); + var oneProperty = withObjectClass.FindChildByName("one", false); + Assert.NotNull(oneProperty); + + var withoutObjectClass = codeModel.FindChildByName("Component2"); + Assert.NotNull(withObjectClass); + var twoProperty = withoutObjectClass.FindChildByName("two", false); + Assert.NotNull(twoProperty); + } + + [Fact] + public async Task InclusiveUnionSingleEntriesMergingAsync() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await using var fs = await GetDocumentStreamAsync( +""" +openapi: 3.0.0 +info: + title: "Generator not generating anyOf if the containing schema has type: object" + version: "1.0.0" +servers: + - url: https://mytodos.doesnotexist/ +paths: + /uses-components: + post: + description: Return something + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/UsesComponents" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UsesComponents" +components: + schemas: + ExampleWithSingleOneOfWithTypeObject: + type: object + anyOf: + - $ref: "#/components/schemas/Component1" + discriminator: + propertyName: objectType + ExampleWithSingleOneOfWithoutTypeObject: + anyOf: + - $ref: "#/components/schemas/Component2" + discriminator: + propertyName: objectType + + UsesComponents: + type: object + properties: + component_with_single_oneof_with_type_object: + $ref: "#/components/schemas/ExampleWithSingleOneOfWithTypeObject" + component_with_single_oneof_without_type_object: + $ref: "#/components/schemas/ExampleWithSingleOneOfWithoutTypeObject" + + Component1: + type: object + required: + - objectType + properties: + objectType: + type: string + one: + type: string + + Component2: + type: object + required: + - objectType + properties: + objectType: + type: string + two: + type: string +"""); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + var codeModel = builder.CreateSourceModel(node); + + // Verify that all three classes referenced by the discriminator inherit from baseDirectoryObject + var withObjectClass = codeModel.FindChildByName("ExampleWithSingleOneOfWithTypeObject"); + Assert.NotNull(withObjectClass); + var oneProperty = withObjectClass.FindChildByName("one", false); + Assert.NotNull(oneProperty); + + var withoutObjectClass = codeModel.FindChildByName("Component2"); + Assert.NotNull(withObjectClass); + var twoProperty = withoutObjectClass.FindChildByName("two", false); + Assert.NotNull(twoProperty); + } + [Fact] public async Task NestedIntersectionTypeAllOfAsync() { From 3174e6c6a4b94d5496220fcc4487c49fbd16fe33 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 25 Nov 2024 14:35:10 -0500 Subject: [PATCH 16/36] fix: nullable information for enum collections Signed-off-by: Vincent Biret --- src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs index 2bee2503fb..b2a97e360b 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs @@ -140,7 +140,7 @@ private void WriteFactoryMethodBodyForUnionModel(CodeMethod codeElement, CodeCla } else if (propertyType.TypeDefinition is CodeClass && propertyType.IsCollection || propertyType.TypeDefinition is null || propertyType.TypeDefinition is CodeEnum) { - var typeName = conventions.GetTypeString(propertyType, codeElement, true, false); + var typeName = conventions.GetTypeString(propertyType, codeElement, true, propertyType.TypeDefinition is CodeEnum && propertyType.CollectionKind is not CodeTypeBase.CodeTypeCollectionKind.None); var valueVarName = $"{property.Name.ToFirstCharacterLowerCase()}Value"; writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({parseNodeParameter.Name.ToFirstCharacterLowerCase()}.{GetDeserializationMethodName(propertyType, codeElement)} is {typeName} {valueVarName})"); writer.WriteBlock(lines: $"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = {valueVarName};"); @@ -161,7 +161,7 @@ private void WriteFactoryMethodBodyForIntersectionModel(CodeMethod codeElement, { if (property.Type is CodeType propertyType) { - var typeName = conventions.GetTypeString(propertyType, codeElement, true, false); + var typeName = conventions.GetTypeString(propertyType, codeElement, true, propertyType.TypeDefinition is CodeEnum && propertyType.CollectionKind is not CodeTypeBase.CodeTypeCollectionKind.None); var valueVarName = $"{property.Name.ToFirstCharacterLowerCase()}Value"; writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({parseNodeParameter.Name.ToFirstCharacterLowerCase()}.{GetDeserializationMethodName(propertyType, codeElement)} is {typeName} {valueVarName})"); writer.WriteBlock(lines: $"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = {valueVarName};"); From 6d69bcd60a087dd7d50ac11940e6f797b017155f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 25 Nov 2024 14:48:18 -0500 Subject: [PATCH 17/36] fix: cast for go enum types Signed-off-by: Vincent Biret --- src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs index 542be4f681..df2e4abd69 100644 --- a/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs @@ -195,7 +195,7 @@ private void WriteFactoryMethodBodyForIntersectionModel(CodeMethod codeElement, WriteCollectionCast(propertyTypeImportName, valueVarName, "cast", writer, isInterfaceType ? string.Empty : "*", !isInterfaceType); valueVarName = "cast"; } - else if (propertyType.TypeDefinition is CodeClass || propertyType.TypeDefinition is CodeInterface) + else if (propertyType.TypeDefinition is CodeClass || propertyType.TypeDefinition is CodeInterface || propertyType.TypeDefinition is CodeEnum) { writer.StartBlock($"if {GetTypeAssertion(valueVarName, propertyTypeImportName, "cast", "ok")}; ok {{"); valueVarName = "cast"; From 7477648e11ca1dd82e340b9d2771110eefe193da Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 25 Nov 2024 15:11:22 -0500 Subject: [PATCH 18/36] fix: missing block close Signed-off-by: Vincent Biret --- src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs index df2e4abd69..c17a8b0044 100644 --- a/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs @@ -201,7 +201,7 @@ private void WriteFactoryMethodBodyForIntersectionModel(CodeMethod codeElement, valueVarName = "cast"; } writer.WriteLine($"{ResultVarName}.{property.Setter!.Name.ToFirstCharacterUpperCase()}({valueVarName})"); - if (!propertyType.IsCollection && (propertyType.TypeDefinition is CodeClass || propertyType.TypeDefinition is CodeInterface)) + if (!propertyType.IsCollection && (propertyType.TypeDefinition is CodeClass || propertyType.TypeDefinition is CodeInterface || propertyType.TypeDefinition is CodeEnum)) writer.CloseBlock(); writer.DecreaseIndent(); } From 5d2944ed29c2bccb620db5ddd04717943e02947b Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 26 Nov 2024 13:00:22 -0500 Subject: [PATCH 19/36] fix: adds missing pointer symbol Signed-off-by: Vincent Biret --- src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs index c17a8b0044..ea026bd4c8 100644 --- a/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs @@ -197,6 +197,10 @@ private void WriteFactoryMethodBodyForIntersectionModel(CodeMethod codeElement, } else if (propertyType.TypeDefinition is CodeClass || propertyType.TypeDefinition is CodeInterface || propertyType.TypeDefinition is CodeEnum) { + if (propertyType.TypeDefinition is CodeEnum) + { + propertyTypeImportName = conventions.GetTypeString(property.Type, parentClass, false, true); + } writer.StartBlock($"if {GetTypeAssertion(valueVarName, propertyTypeImportName, "cast", "ok")}; ok {{"); valueVarName = "cast"; } From c25992eab618437b2355eea204a713df8174c557 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 13:00:17 -0500 Subject: [PATCH 20/36] chore: removes unused variable Signed-off-by: Vincent Biret --- .../Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index cd5af624ad..ae2ccc8a38 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -747,7 +747,6 @@ public async Task MergesAllOfRequestBodyAsync(string content, Action>(); var openAPIDocumentDS = new OpenApiDocumentDownloadService(_httpClient, _logger); var outputDirectory = Path.Combine(workingDirectory, "output"); var generationConfiguration = new GenerationConfiguration From 4bd8a76f887053573b8bad5c36cbd74fe4e59828 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 13:12:01 -0500 Subject: [PATCH 21/36] fix: removes invalid discriminator mappings for plugin export --- .../Plugins/PluginsGenerationService.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index 6a1e73c972..56efe89985 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -61,6 +61,7 @@ public async Task GenerateManifestAsync(CancellationToken cancellationToken = de var descriptionWriter = new OpenApiYamlWriter(fileWriter); var trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(OAIDocument); trimmedPluginDocument = InlineRequestBodyAllOf(trimmedPluginDocument); + RemoveDiscriminatorMappingEntriesReferencingAbsentSchemas(trimmedPluginDocument); trimmedPluginDocument.SerializeAsV3(descriptionWriter); descriptionWriter.Flush(); @@ -105,6 +106,28 @@ public async Task GenerateManifestAsync(CancellationToken cancellationToken = de } } + private sealed class MappingCleanupVisitor(OpenApiDocument openApiDocument) : OpenApiVisitorBase + { + private readonly OpenApiDocument _document = openApiDocument; + + public override void Visit(OpenApiSchema schema) + { + if (schema.Discriminator?.Mapping is null) + return; + var keysToRemove = schema.Discriminator.Mapping.Where(x => !_document.Components.Schemas.ContainsKey(x.Value.Split('/', StringSplitOptions.RemoveEmptyEntries)[^1])).Select(static x => x.Key).ToArray(); + foreach (var key in keysToRemove) + schema.Discriminator.Mapping.Remove(key); + base.Visit(schema); + } + } + + private static void RemoveDiscriminatorMappingEntriesReferencingAbsentSchemas(OpenApiDocument document) + { + var visitor = new MappingCleanupVisitor(document); + var walker = new OpenApiWalker(visitor); + walker.Walk(document); + } + private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDocument) { if (openApiDocument.Paths is null) return openApiDocument; From 7e438201709166c7c907e9788a8e6791422e0b9f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 13:31:02 -0500 Subject: [PATCH 22/36] fix: inlining of allOf for plugins now emits right reference fix: inlining of allOf for plugins now includes all properties Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationService.cs | 122 +++++------------- 1 file changed, 32 insertions(+), 90 deletions(-) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index 56efe89985..f1f85477e2 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -61,7 +61,9 @@ public async Task GenerateManifestAsync(CancellationToken cancellationToken = de var descriptionWriter = new OpenApiYamlWriter(fileWriter); var trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(OAIDocument); trimmedPluginDocument = InlineRequestBodyAllOf(trimmedPluginDocument); - RemoveDiscriminatorMappingEntriesReferencingAbsentSchemas(trimmedPluginDocument); + PrepareDescriptionForCopilot(trimmedPluginDocument); + // trimming a second time to remove any components that are no longer used after the inlining + trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(trimmedPluginDocument); trimmedPluginDocument.SerializeAsV3(descriptionWriter); descriptionWriter.Flush(); @@ -121,11 +123,36 @@ public override void Visit(OpenApiSchema schema) } } - private static void RemoveDiscriminatorMappingEntriesReferencingAbsentSchemas(OpenApiDocument document) + private sealed class AllOfPropertiesRetrievalVisitor : OpenApiVisitorBase { - var visitor = new MappingCleanupVisitor(document); - var walker = new OpenApiWalker(visitor); - walker.Walk(document); + public override void Visit(OpenApiSchema schema) + { + if (schema.AllOf is not { Count: > 0 }) + return; + var allPropertiesToAdd = GetAllProperties(schema).ToArray(); + foreach (var (key, value) in allPropertiesToAdd) + schema.Properties.TryAdd(key, value); + schema.AllOf.Clear(); + base.Visit(schema); + } + + private static IEnumerable> GetAllProperties(OpenApiSchema schema) + { + return schema.AllOf is not null ? + schema.AllOf.SelectMany(static x => GetAllProperties(x)).Union(schema.Properties) : + schema.Properties; + } + } + + private static void PrepareDescriptionForCopilot(OpenApiDocument document) + { + var allOfPropertiesRetrievalVisitor = new AllOfPropertiesRetrievalVisitor(); + var allOfPropertiesRetrievalWalker = new OpenApiWalker(allOfPropertiesRetrievalVisitor); + allOfPropertiesRetrievalWalker.Walk(document); + + var mappingCleanupVisitor = new MappingCleanupVisitor(document); + var mappingCleanupWalker = new OpenApiWalker(mappingCleanupVisitor); + mappingCleanupWalker.Walk(document); } private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDocument) @@ -137,8 +164,6 @@ private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDoc foreach (var contentItem in contentItems) { var schema = contentItem.Schema; - // Merge all schemas in allOf `schema.MergeAllOfSchemaEntries()` doesn't seem to do the right thing. - schema = MergeAllOfInSchema(schema); schema = SelectFirstAnyOfOrOneOf(schema); contentItem.Schema = schema; } @@ -163,89 +188,6 @@ private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDoc } return newSchema; } - static OpenApiSchema? MergeAllOfInSchema(OpenApiSchema? schema) - { - if (schema?.AllOf is not { Count: > 0 }) return schema; - var newSchema = new OpenApiSchema(); - foreach (var apiSchema in schema.AllOf) - { - if (apiSchema.Title is not null) newSchema.Title = apiSchema.Title; - if (!string.IsNullOrEmpty(apiSchema.Type)) - { - if (!string.IsNullOrEmpty(newSchema.Type) && newSchema.Type != apiSchema.Type) - { - throw new InvalidOperationException( - $"The schemas in allOf cannot have different types: '{newSchema.Type}' and '{apiSchema.Type}'."); - } - newSchema.Type = apiSchema.Type; - } - if (apiSchema.Format is not null) newSchema.Format = apiSchema.Format; - if (!string.IsNullOrEmpty(apiSchema.Description)) newSchema.Description = apiSchema.Description; - if (apiSchema.Maximum is not null) newSchema.Maximum = apiSchema.Maximum; - if (apiSchema.ExclusiveMaximum is not null) newSchema.ExclusiveMaximum = apiSchema.ExclusiveMaximum; - if (apiSchema.Minimum is not null) newSchema.Minimum = apiSchema.Minimum; - if (apiSchema.ExclusiveMinimum is not null) newSchema.ExclusiveMinimum = apiSchema.ExclusiveMinimum; - if (apiSchema.MaxLength is not null) newSchema.MaxLength = apiSchema.MaxLength; - if (apiSchema.MinLength is not null) newSchema.MinLength = apiSchema.MinLength; - if (!string.IsNullOrEmpty(apiSchema.Pattern)) newSchema.Pattern = apiSchema.Pattern; - if (apiSchema.MultipleOf is not null) newSchema.MultipleOf = apiSchema.MultipleOf; - if (apiSchema.Default is not null) newSchema.Default = apiSchema.Default; - if (apiSchema.ReadOnly) newSchema.ReadOnly = apiSchema.ReadOnly; - if (apiSchema.WriteOnly) newSchema.WriteOnly = apiSchema.WriteOnly; - if (apiSchema.Not is not null) newSchema.Not = apiSchema.Not; - if (apiSchema.Required is { Count: > 0 }) - { - foreach (var r in apiSchema.Required.Where(static r => !string.IsNullOrEmpty(r))) - { - newSchema.Required.Add(r); - } - } - if (apiSchema.Items is not null) newSchema.Items = apiSchema.Items; - if (apiSchema.MaxItems is not null) newSchema.MaxItems = apiSchema.MaxItems; - if (apiSchema.MinItems is not null) newSchema.MinItems = apiSchema.MinItems; - if (apiSchema.UniqueItems is not null) newSchema.UniqueItems = apiSchema.UniqueItems; - if (apiSchema.Properties is not null) - { - foreach (var property in apiSchema.Properties) - { - newSchema.Properties.TryAdd(property.Key, property.Value); - } - } - if (apiSchema.MaxProperties is not null) newSchema.MaxProperties = apiSchema.MaxProperties; - if (apiSchema.MinProperties is not null) newSchema.MinProperties = apiSchema.MinProperties; - if (apiSchema.AdditionalPropertiesAllowed) newSchema.AdditionalPropertiesAllowed = true; - if (apiSchema.AdditionalProperties is not null) newSchema.AdditionalProperties = apiSchema.AdditionalProperties; - if (apiSchema.Discriminator is not null) newSchema.Discriminator = apiSchema.Discriminator; - if (apiSchema.Example is not null) newSchema.Example = apiSchema.Example; - if (apiSchema.Enum is not null) - { - foreach (var enumValue in apiSchema.Enum) - { - newSchema.Enum.Add(enumValue); - } - } - if (apiSchema.Nullable) newSchema.Nullable = apiSchema.Nullable; - if (apiSchema.ExternalDocs is not null) newSchema.ExternalDocs = apiSchema.ExternalDocs; - if (apiSchema.Deprecated) newSchema.Deprecated = apiSchema.Deprecated; - if (apiSchema.Xml is not null) newSchema.Xml = apiSchema.Xml; - if (apiSchema.Extensions is not null) - { - foreach (var extension in apiSchema.Extensions) - { - newSchema.Extensions.Add(extension.Key, extension.Value); - } - } - if (apiSchema.Reference is not null) newSchema.Reference = apiSchema.Reference; - if (apiSchema.Annotations is not null) - { - foreach (var annotation in apiSchema.Annotations) - { - newSchema.Annotations.Add(annotation.Key, annotation.Value); - } - } - } - return newSchema; - } } [GeneratedRegex(@"[^a-zA-Z0-9_]+", RegexOptions.IgnoreCase | RegexOptions.Singleline, 2000)] From 72d00e56eaceea83318634e4ee5556dbfa0de175 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 14:13:01 -0500 Subject: [PATCH 23/36] fix any/oneOf selection for plugins generation Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationService.cs | 127 +++++++++++++----- 1 file changed, 91 insertions(+), 36 deletions(-) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index f1f85477e2..2af5acbe33 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -11,6 +11,7 @@ using Kiota.Builder.OpenApiExtensions; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.ApiManifest; +using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Services; using Microsoft.OpenApi.Writers; @@ -60,10 +61,10 @@ public async Task GenerateManifestAsync(CancellationToken cancellationToken = de #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var descriptionWriter = new OpenApiYamlWriter(fileWriter); var trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(OAIDocument); - trimmedPluginDocument = InlineRequestBodyAllOf(trimmedPluginDocument); PrepareDescriptionForCopilot(trimmedPluginDocument); // trimming a second time to remove any components that are no longer used after the inlining trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(trimmedPluginDocument); + trimmedPluginDocument.Info.Title = trimmedPluginDocument.Info.Title[..^9]; // removing the second ` - Subset` suffix from the title trimmedPluginDocument.SerializeAsV3(descriptionWriter); descriptionWriter.Flush(); @@ -144,8 +145,97 @@ private static IEnumerable> GetAllProperties } } + private sealed class SelectFirstAnyOneOfVisitor : OpenApiVisitorBase + { + public override void Visit(OpenApiSchema schema) + { + if (schema.AnyOf is { Count: > 0 }) + { + CopyRelevantInformation(schema.AnyOf[0], schema); + schema.AnyOf.Clear(); + } + if (schema.OneOf is { Count: > 0 }) + { + CopyRelevantInformation(schema.OneOf[0], schema); + schema.OneOf.Clear(); + } + base.Visit(schema); + } + private static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema target) + { + if (!string.IsNullOrEmpty(source.Type)) + target.Type = source.Type; + if (!string.IsNullOrEmpty(source.Format)) + target.Format = source.Format; + if (source.Items is not null) + target.Items = source.Items; + if (source.Properties is not null) + target.Properties = new Dictionary(source.Properties); + if (source.Required is not null) + target.Required = new HashSet(source.Required); + if (source.AdditionalProperties is not null) + target.AdditionalProperties = source.AdditionalProperties; + if (source.Enum is not null) + target.Enum = [.. source.Enum]; + if (source.ExclusiveMaximum is not null) + target.ExclusiveMaximum = source.ExclusiveMaximum; + if (source.ExclusiveMinimum is not null) + target.ExclusiveMinimum = source.ExclusiveMinimum; + if (source.Maximum is not null) + target.Maximum = source.Maximum; + if (source.Minimum is not null) + target.Minimum = source.Minimum; + if (source.MaxItems is not null) + target.MaxItems = source.MaxItems; + if (source.MinItems is not null) + target.MinItems = source.MinItems; + if (source.MaxLength is not null) + target.MaxLength = source.MaxLength; + if (source.MinLength is not null) + target.MinLength = source.MinLength; + if (source.Pattern is not null) + target.Pattern = source.Pattern; + if (source.MaxProperties is not null) + target.MaxProperties = source.MaxProperties; + if (source.MinProperties is not null) + target.MinProperties = source.MinProperties; + if (source.UniqueItems is not null) + target.UniqueItems = source.UniqueItems; + if (source.Nullable) + target.Nullable = true; + if (source.ReadOnly) + target.ReadOnly = true; + if (source.WriteOnly) + target.WriteOnly = true; + if (source.Deprecated) + target.Deprecated = true; + if (source.Xml is not null) + target.Xml = source.Xml; + if (source.ExternalDocs is not null) + target.ExternalDocs = source.ExternalDocs; + if (source.Example is not null) + target.Example = source.Example; + if (source.Extensions is not null) + target.Extensions = new Dictionary(source.Extensions); + if (source.Discriminator is not null) + target.Discriminator = source.Discriminator; + if (!string.IsNullOrEmpty(source.Description)) + target.Description = source.Description; + if (!string.IsNullOrEmpty(source.Title)) + target.Title = source.Title; + if (source.Default is not null) + target.Default = source.Default; + if (source.Reference is not null) + target.Reference = source.Reference; + } + } + private static void PrepareDescriptionForCopilot(OpenApiDocument document) { + var selectFirstAnyOneOfVisitor = new SelectFirstAnyOneOfVisitor(); + var selectFirstAnyOneOfWalker = new OpenApiWalker(selectFirstAnyOneOfVisitor); + selectFirstAnyOneOfWalker.Walk(document); + var allOfPropertiesRetrievalVisitor = new AllOfPropertiesRetrievalVisitor(); var allOfPropertiesRetrievalWalker = new OpenApiWalker(allOfPropertiesRetrievalVisitor); allOfPropertiesRetrievalWalker.Walk(document); @@ -155,41 +245,6 @@ private static void PrepareDescriptionForCopilot(OpenApiDocument document) mappingCleanupWalker.Walk(document); } - private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDocument) - { - if (openApiDocument.Paths is null) return openApiDocument; - var contentItems = openApiDocument.Paths.Values.Where(static x => x?.Operations is not null) - .SelectMany(static x => x.Operations.Values.Where(static x => x?.RequestBody?.Content is not null) - .SelectMany(static x => x.RequestBody.Content.Values)); - foreach (var contentItem in contentItems) - { - var schema = contentItem.Schema; - schema = SelectFirstAnyOfOrOneOf(schema); - contentItem.Schema = schema; - } - - return openApiDocument; - - static OpenApiSchema? SelectFirstAnyOfOrOneOf(OpenApiSchema? schema) - { - if (schema?.AnyOf is not { Count: > 0 } && schema?.OneOf is not { Count: > 0 }) return schema; - OpenApiSchema newSchema; - if (schema.AnyOf is { Count: > 0 }) - { - newSchema = schema.AnyOf[0]; - } - else if (schema.OneOf is { Count: > 0 }) - { - newSchema = schema.OneOf[0]; - } - else - { - newSchema = schema; - } - return newSchema; - } - } - [GeneratedRegex(@"[^a-zA-Z0-9_]+", RegexOptions.IgnoreCase | RegexOptions.Singleline, 2000)] private static partial Regex PluginNameCleanupRegex(); From 1459e8d868f53165801c0f6422cd44a3c16766f2 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 14:21:45 -0500 Subject: [PATCH 24/36] fix: remove error status description Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationService.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index 2af5acbe33..0a4b527717 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -230,8 +230,25 @@ private static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema } } + private sealed class ErrorResponsesCleanupVisitor : OpenApiVisitorBase + { + public override void Visit(OpenApiOperation operation) + { + if (operation.Responses is null) + return; + var errorResponses = operation.Responses.Where(static x => x.Key.StartsWith('4') || x.Key.StartsWith('5')).ToArray(); + foreach (var (key, value) in errorResponses) + operation.Responses.Remove(key); + base.Visit(operation); + } + } + private static void PrepareDescriptionForCopilot(OpenApiDocument document) { + var errorResponsesCleanupVisitor = new ErrorResponsesCleanupVisitor(); + var errorResponsesCleanupWalker = new OpenApiWalker(errorResponsesCleanupVisitor); + errorResponsesCleanupWalker.Walk(document); + var selectFirstAnyOneOfVisitor = new SelectFirstAnyOneOfVisitor(); var selectFirstAnyOneOfWalker = new OpenApiWalker(selectFirstAnyOneOfVisitor); selectFirstAnyOneOfWalker.Walk(document); From d150295ecec68a3f9ea06fe3044d5a3b448a17e4 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 14:29:00 -0500 Subject: [PATCH 25/36] feat: removes external documentation links Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationService.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index 0a4b527717..b5f07b3494 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -243,8 +243,40 @@ public override void Visit(OpenApiOperation operation) } } + private sealed class ExternalDocumentationCleanupVisitor : OpenApiVisitorBase + { + public override void Visit(OpenApiDocument doc) + { + if (doc.ExternalDocs is not null) + doc.ExternalDocs = null; + base.Visit(doc); + } + public override void Visit(OpenApiOperation operation) + { + if (operation.ExternalDocs is not null) + operation.ExternalDocs = null; + base.Visit(operation); + } + public override void Visit(OpenApiSchema schema) + { + if (schema.ExternalDocs is not null) + schema.ExternalDocs = null; + base.Visit(schema); + } + public override void Visit(OpenApiTag tag) + { + if (tag.ExternalDocs is not null) + tag.ExternalDocs = null; + base.Visit(tag); + } + } + private static void PrepareDescriptionForCopilot(OpenApiDocument document) { + var externalDocumentationCleanupVisitor = new ExternalDocumentationCleanupVisitor(); + var externalDocumentationCleanupWalker = new OpenApiWalker(externalDocumentationCleanupVisitor); + externalDocumentationCleanupWalker.Walk(document); + var errorResponsesCleanupVisitor = new ErrorResponsesCleanupVisitor(); var errorResponsesCleanupWalker = new OpenApiWalker(errorResponsesCleanupVisitor); errorResponsesCleanupWalker.Walk(document); From f672a59d920aa672acbc3ee7553fbd389f171dc4 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 14:51:28 -0500 Subject: [PATCH 26/36] fix: failing unit tests Signed-off-by: Vincent Biret --- src/Kiota.Builder/Plugins/PluginsGenerationService.cs | 10 ++++++---- .../Plugins/PluginsGenerationServiceTests.cs | 5 ++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index b5f07b3494..1406aa91c7 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -131,6 +131,8 @@ public override void Visit(OpenApiSchema schema) if (schema.AllOf is not { Count: > 0 }) return; var allPropertiesToAdd = GetAllProperties(schema).ToArray(); + foreach (var allOfEntry in schema.AllOf) + SelectFirstAnyOneOfVisitor.CopyRelevantInformation(allOfEntry, schema, false, false, false); foreach (var (key, value) in allPropertiesToAdd) schema.Properties.TryAdd(key, value); schema.AllOf.Clear(); @@ -161,7 +163,7 @@ public override void Visit(OpenApiSchema schema) } base.Visit(schema); } - private static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema target) + internal static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema target, bool includeProperties = true, bool includeReference = true, bool includeDiscriminator = true) { if (!string.IsNullOrEmpty(source.Type)) target.Type = source.Type; @@ -169,7 +171,7 @@ private static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema target.Format = source.Format; if (source.Items is not null) target.Items = source.Items; - if (source.Properties is not null) + if (source.Properties is not null && includeProperties) target.Properties = new Dictionary(source.Properties); if (source.Required is not null) target.Required = new HashSet(source.Required); @@ -217,7 +219,7 @@ private static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema target.Example = source.Example; if (source.Extensions is not null) target.Extensions = new Dictionary(source.Extensions); - if (source.Discriminator is not null) + if (source.Discriminator is not null && includeDiscriminator) target.Discriminator = source.Discriminator; if (!string.IsNullOrEmpty(source.Description)) target.Description = source.Description; @@ -225,7 +227,7 @@ private static void CopyRelevantInformation(OpenApiSchema source, OpenApiSchema target.Title = source.Title; if (source.Default is not null) target.Default = source.Default; - if (source.Reference is not null) + if (source.Reference is not null && includeReference) target.Reference = source.Reference; } } diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index ae2ccc8a38..652d9d1c14 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -210,7 +210,6 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; await File.WriteAllTextAsync(simpleDescriptionPath, simpleDescriptionContent); - var mockLogger = new Mock>(); var openAPIDocumentDS = new OpenApiDocumentDownloadService(_httpClient, _logger); var outputDirectory = Path.Combine(workingDirectory, "output"); var generationConfiguration = new GenerationConfiguration @@ -268,10 +267,10 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Empty(resultDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed Assert.Empty(resultDocument.Extensions); // no extension at root (unsupported extension is removed) Assert.Equal(2, resultDocument.Paths.Count); // document has only two paths - Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count, resultDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. + Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count - 1, resultDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // We removed the error response Assert.NotEmpty(resultDocument.Paths["/test"].Operations[OperationType.Get].Responses["200"].Description); // response description string is not empty Assert.Empty(resultDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // NO UNsupported extension - Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count, resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. + Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count - 1, resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. Assert.NotEmpty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Description);// response description string is not empty Assert.Single(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension still present in operation } From 3962cb79a6f6ba510edd47ed355d27ccd92fc47f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 15:17:56 -0500 Subject: [PATCH 27/36] chore: adds test data for all of cleanup Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationServiceTests.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 652d9d1c14..d2f2ac9549 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -193,6 +193,10 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() responses: '200': description: + content: + application/json: + schema: + $ref: '#/components/schemas/microsoft.graph.message' '500': description: api error response components: @@ -206,7 +210,17 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() id: type: string '@odata.type': - type: string"; + type: string + microsoft.graph.message: + allOf: + - $ref: '#/components/schemas/microsoft.graph.entity' + - type: object + title: message + properties: + subject: + type: string + body: + type: string"; var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; await File.WriteAllTextAsync(simpleDescriptionPath, simpleDescriptionContent); @@ -250,7 +264,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Description, resultingManifest.Document.Functions[0].Description);// pulls from description Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Summary, resultingManifest.Document.Functions[1].Description);// pulls from summary - Assert.Single(originalDocument.Components.Schemas);// one schema originally + Assert.Equal(2, originalDocument.Components.Schemas.Count);// one schema originally Assert.Single(originalDocument.Extensions); // single unsupported extension at root Assert.Equal(2, originalDocument.Paths.Count); // document has only two paths Assert.Equal(2, originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // 2 responses originally @@ -264,7 +278,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Empty(diagnostic.Errors); // Assertions / validations - Assert.Empty(resultDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed + Assert.Single(resultDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed Assert.Empty(resultDocument.Extensions); // no extension at root (unsupported extension is removed) Assert.Equal(2, resultDocument.Paths.Count); // document has only two paths Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count - 1, resultDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // We removed the error response @@ -273,6 +287,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count - 1, resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. Assert.NotEmpty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Description);// response description string is not empty Assert.Single(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension still present in operation + Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.AllOf); // allOf were merged } #region Security From 9482a8455e419c463c44a9a26cf234897770fa5b Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 15:20:37 -0500 Subject: [PATCH 28/36] chore: adds test data for external docs removal Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationServiceTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index d2f2ac9549..c524d7d6b1 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -171,6 +171,9 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() /test: get: description: description for test path + externalDocs: + description: external docs for test path + url: http://localhost/test x-random-extension: true responses: '200': @@ -264,6 +267,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Description, resultingManifest.Document.Functions[0].Description);// pulls from description Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Summary, resultingManifest.Document.Functions[1].Description);// pulls from summary + Assert.NotNull(originalDocument.Paths["/test"].Operations[OperationType.Get].ExternalDocs); // existing external docs Assert.Equal(2, originalDocument.Components.Schemas.Count);// one schema originally Assert.Single(originalDocument.Extensions); // single unsupported extension at root Assert.Equal(2, originalDocument.Paths.Count); // document has only two paths @@ -283,6 +287,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Equal(2, resultDocument.Paths.Count); // document has only two paths Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count - 1, resultDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // We removed the error response Assert.NotEmpty(resultDocument.Paths["/test"].Operations[OperationType.Get].Responses["200"].Description); // response description string is not empty + Assert.Null(resultDocument.Paths["/test"].Operations[OperationType.Get].ExternalDocs); // external docs are removed Assert.Empty(resultDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // NO UNsupported extension Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count - 1, resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. Assert.NotEmpty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Description);// response description string is not empty From 13c04769a3d78e7297d30bdc2583e44fbfd853ec Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 15:24:01 -0500 Subject: [PATCH 29/36] chore: adds test for any of selection Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationServiceTests.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index c524d7d6b1..b5f86312b5 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -211,7 +211,9 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() type: object properties: id: - type: string + anyOf: + - type: string + - type: integer '@odata.type': type: string microsoft.graph.message: @@ -275,6 +277,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Single(originalDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // 1 UNsupported extension Assert.Equal(2, originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // 2 responses originally Assert.Single(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension + Assert.Equal(2, originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.AllOf[0].Properties["id"].AnyOf.Count); // anyOf we selected // Validate the output open api file var resultOpenApiFile = File.OpenRead(Path.Combine(outputDirectory, OpenApiFileName)); @@ -293,6 +296,8 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.NotEmpty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Description);// response description string is not empty Assert.Single(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension still present in operation Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.AllOf); // allOf were merged + Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].AnyOf); // anyOf we selected + Assert.Equal("string", resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].Type); } #region Security From 59ffddab1254b44c56c261adc85b9622387b7a92 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 15:25:48 -0500 Subject: [PATCH 30/36] chore: adds a test for error responses removal Signed-off-by: Vincent Biret --- .../Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index b5f86312b5..6743f5c63a 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -298,6 +298,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.AllOf); // allOf were merged Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].AnyOf); // anyOf we selected Assert.Equal("string", resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].Type); + Assert.DoesNotContain("500", resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Keys, StringComparer.OrdinalIgnoreCase); // We removed the error response } #region Security From 494a05d38bc3f984840bd9e18a69ba28a965040d Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 15:28:30 -0500 Subject: [PATCH 31/36] docs: adds changelog entry for openapi plugins generation Signed-off-by: Vincent Biret --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d85163d3e4..3256dc56bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed invalid code in Php caused by "*/*/" in property description. [5635](https://github.com/microsoft/kiota/issues/5635) - Fixed a bug where discriminator property name lookup could end up in an infinite loop. [#5771](https://github.com/microsoft/kiota/issues/5771) - Fixed TypeScript generation error when generating usings from shaken serializers. [#5634](https://github.com/microsoft/kiota/issues/5634) +- Multiple fixed and improvements in OpenAPI description generation for plugins. [#5806](https://github.com/microsoft/kiota/issues/5806) ## [1.20.0] - 2024-11-07 From 84eaacca10b3d47b0a613229adc50658c4cb4e01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:38:22 +0000 Subject: [PATCH 32/36] chore(deps-dev): bump pyjwt[crypto] from 2.10.0 to 2.10.1 in /it/python Bumps [pyjwt[crypto]](https://github.com/jpadilla/pyjwt) from 2.10.0 to 2.10.1. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.10.0...2.10.1) --- updated-dependencies: - dependency-name: pyjwt[crypto] dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- it/python/requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/python/requirements-dev.txt b/it/python/requirements-dev.txt index db8bccbe26..3c170bf64a 100644 --- a/it/python/requirements-dev.txt +++ b/it/python/requirements-dev.txt @@ -122,7 +122,7 @@ portalocker==3.0.0 ; python_version >= '3.5' and platform_system == 'Windows' pycparser==2.22 -pyjwt[crypto]==2.10.0 ; python_version >= '3.7' +pyjwt[crypto]==2.10.1 ; python_version >= '3.7' python-dateutil==2.9.0.post0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' From adc188490c60cfd10dfb8837e892e4d2b185c44a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:38:59 +0000 Subject: [PATCH 33/36] chore(deps-dev): bump aiohttp from 3.11.7 to 3.11.8 in /it/python Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.11.7 to 3.11.8. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.11.7...v3.11.8) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- it/python/requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/python/requirements-dev.txt b/it/python/requirements-dev.txt index db8bccbe26..1bb5386a3c 100644 --- a/it/python/requirements-dev.txt +++ b/it/python/requirements-dev.txt @@ -66,7 +66,7 @@ yapf==0.43.0 zipp==3.21.0 ; python_version >= '3.7' -aiohttp==3.11.7 ; python_version >= '3.6' +aiohttp==3.11.8 ; python_version >= '3.6' aiosignal==1.3.1 ; python_version >= '3.7' From 1db1f62b3d3fe52526ea188f8ae1a24c0a932825 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:50:40 +0000 Subject: [PATCH 34/36] chore(deps-dev): bump @types/node in /vscode/microsoft-kiota Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.0 to 22.10.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- vscode/microsoft-kiota/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vscode/microsoft-kiota/package-lock.json b/vscode/microsoft-kiota/package-lock.json index 12305789f0..f9006f292a 100644 --- a/vscode/microsoft-kiota/package-lock.json +++ b/vscode/microsoft-kiota/package-lock.json @@ -731,9 +731,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", - "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "dependencies": { "undici-types": "~6.20.0" From 8b952588edd874cc061dee62098f70c86c48ba7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:55:05 +0000 Subject: [PATCH 35/36] chore(deps-dev): bump @types/node in /it/typescript Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.0 to 22.10.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- it/typescript/package-lock.json | 8 ++++---- it/typescript/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/it/typescript/package-lock.json b/it/typescript/package-lock.json index 712b827a99..19cd62aabc 100644 --- a/it/typescript/package-lock.json +++ b/it/typescript/package-lock.json @@ -23,7 +23,7 @@ "devDependencies": { "@es-exec/esbuild-plugin-start": "^0.0.5", "@stylistic/eslint-plugin-ts": "^2.11.0", - "@types/node": "^22.10.0", + "@types/node": "^22.10.1", "@typescript-eslint/eslint-plugin": "^8.16.0", "@typescript-eslint/parser": "^8.16.0", "esbuild": "^0.24.0", @@ -936,9 +936,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", - "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "dependencies": { "undici-types": "~6.20.0" diff --git a/it/typescript/package.json b/it/typescript/package.json index 3b66561cf9..0a98074d26 100644 --- a/it/typescript/package.json +++ b/it/typescript/package.json @@ -20,7 +20,7 @@ "devDependencies": { "@es-exec/esbuild-plugin-start": "^0.0.5", "@stylistic/eslint-plugin-ts": "^2.11.0", - "@types/node": "^22.10.0", + "@types/node": "^22.10.1", "@typescript-eslint/eslint-plugin": "^8.16.0", "@typescript-eslint/parser": "^8.16.0", "esbuild": "^0.24.0", From aa826c1c36feb3defbf4a818c4a3012b70d51c1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:11:25 +0300 Subject: [PATCH 36/36] chore(deps-dev): bump cryptography from 43.0.3 to 44.0.0 in /it/python (#5846) Bumps [cryptography](https://github.com/pyca/cryptography) from 43.0.3 to 44.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/43.0.3...44.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- it/python/requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/python/requirements-dev.txt b/it/python/requirements-dev.txt index 1bb5386a3c..ee647e87dd 100644 --- a/it/python/requirements-dev.txt +++ b/it/python/requirements-dev.txt @@ -82,7 +82,7 @@ azure-identity==1.19.0 cffi==1.17.1 -cryptography==43.0.3 ; python_version >= '3.7' +cryptography==44.0.0 ; python_version >= '3.7' frozenlist==1.5.0 ; python_version >= '3.7'