From 80d8b2f05166d823209d48b79b48a3ff31188b4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Nov 2026 23:20:15 +0000 Subject: [PATCH 1/3] Initial plan From 809c88ee62f7f432aeb88178d8befdba5b902548 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Nov 2026 23:23:51 +0000 Subject: [PATCH 2/3] Add DataSchema support to CloudEvent creation and data setters Co-authored-by: duglin <1944671+duglin@users.noreply.github.com> --- README.md | 11 +++++ .../CloudEvents.Sdk.psm1 | 49 +++++++++++++++++-- test/unit/New-CloudEvent.Tests.ps1 | 19 ++++++- test/unit/Set-CloudEventData.Tests.ps1 | 36 ++++++++++++++ test/unit/Set-CloudEventJsonData.Tests.ps1 | 36 ++++++++++++++ 5 files changed, 147 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d255df8..ccaef3d 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,17 @@ Time : 4/26/2021 9:00:45 AM Type : com.example.object.deleted.v2 ``` +Use the optional `-DataSchema` absolute URI parameter on `New-CloudEvent`, +`Set-CloudEventData`, or `Set-CloudEventJsonData` to specify the schema for the +event data: + +```powershell +$cloudEvent | Set-CloudEventJsonData -Data @{ 'Foo' = 'Hello'; 'Bar' = 'World' } -DataSchema 'https://example.com/schema.json' +``` + +Omitting `-DataSchema` when setting data preserves any schema already set on the +event. + ### Set **XML Data** to a CloudEvent object ```powershell $cloudEvent | Set-CloudEventXmlData -Data @{ diff --git a/src/CloudEventsPowerShell/CloudEvents.Sdk.psm1 b/src/CloudEventsPowerShell/CloudEvents.Sdk.psm1 index 0da4e43..35f1696 100644 --- a/src/CloudEventsPowerShell/CloudEvents.Sdk.psm1 +++ b/src/CloudEventsPowerShell/CloudEvents.Sdk.psm1 @@ -29,6 +29,9 @@ function New-CloudEvent { .PARAMETER Time Specifies the 'time' attribute of the cloud event. + .PARAMETER DataSchema + Specifies the absolute URI of the schema that the cloud event 'data' adheres to. + .EXAMPLE New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date) @@ -55,7 +58,13 @@ function New-CloudEvent { [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [DateTime] - $Time + $Time, + + [Parameter(Mandatory = $false)] + [ValidateNotNullOrEmpty()] + [ValidateScript({ $_.IsAbsoluteUri })] + [System.Uri] + $DataSchema ) PROCESS { @@ -68,6 +77,10 @@ function New-CloudEvent { $Time, @()) + if ($PSBoundParameters.ContainsKey('DataSchema')) { + $cloudEvent.DataSchema = $DataSchema + } + Write-Output $cloudEvent } } @@ -90,6 +103,10 @@ function Set-CloudEventData { .PARAMETER DataContentType Specifies the 'datacontenttype' attribute of the cloud event. + .PARAMETER DataSchema + Specifies the absolute URI of the schema that the cloud event 'data' adheres to. + If omitted, the existing 'dataschema' attribute is preserved. + .EXAMPLE $cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date) @@ -118,7 +135,14 @@ function Set-CloudEventData { [Parameter(Mandatory = $false, ValueFromPipeline = $false)] [string] - $DataContentType) + $DataContentType, + + [Parameter(Mandatory = $false, + ValueFromPipeline = $false)] + [ValidateNotNullOrEmpty()] + [ValidateScript({ $_.IsAbsoluteUri })] + [System.Uri] + $DataSchema) PROCESS { @@ -130,6 +154,10 @@ function Set-CloudEventData { $cloudEvent.Data = $Data $cloudEvent.DataContentType = $dataContentType + if ($PSBoundParameters.ContainsKey('DataSchema')) { + $cloudEvent.DataSchema = $DataSchema + } + Write-Output $CloudEvent } @@ -155,6 +183,10 @@ function Set-CloudEventJsonData { This parameter is passed on the `-Depth` parameter of the `ConvertTo-Json` cmdlet. The default value is 3 + .PARAMETER DataSchema + Specifies the absolute URI of the schema that the cloud event 'data' adheres to. + If omitted, the existing 'dataschema' attribute is preserved. + .EXAMPLE $cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date) @@ -180,7 +212,14 @@ function Set-CloudEventJsonData { [Parameter(Mandatory = $false, ValueFromPipeline = $false)] [int] - $Depth = 3) + $Depth = 3, + + [Parameter(Mandatory = $false, + ValueFromPipeline = $false)] + [ValidateNotNullOrEmpty()] + [ValidateScript({ $_.IsAbsoluteUri })] + [System.Uri] + $DataSchema) PROCESS { @@ -193,6 +232,10 @@ function Set-CloudEventJsonData { $cloudEvent.DataContentType = $dataContentType $cloudEvent.Data = ConvertTo-Json -InputObject $Data -Depth $Depth + if ($PSBoundParameters.ContainsKey('DataSchema')) { + $cloudEvent.DataSchema = $DataSchema + } + Write-Output $CloudEvent } diff --git a/test/unit/New-CloudEvent.Tests.ps1 b/test/unit/New-CloudEvent.Tests.ps1 index be1e9b2..f846b9a 100644 --- a/test/unit/New-CloudEvent.Tests.ps1 +++ b/test/unit/New-CloudEvent.Tests.ps1 @@ -22,6 +22,7 @@ Describe "New-CloudEvent Function Tests" { $actual.Type | Should -Be $expectedType $actual.Source | Should -Be $expectedSource $actual.Id | Should -Be $expectedId + $actual.DataSchema | Should -BeNullOrEmpty } It 'Create CloudEvent with all possible parameters' { @@ -30,13 +31,15 @@ Describe "New-CloudEvent Function Tests" { $expectedSource = 'urn:test' $expectedId = 'test-id-1' $expectedTime = Get-Date -Year 2021 -Month 1 -Day 18 -Hour 12 -Minute 30 -Second 0 + $expectedDataSchema = 'https://example.com/schema.json' # Act $actual = New-CloudEvent ` -Type $expectedType ` -Source $expectedSource ` -Id $expectedId ` - -Time $expectedTime + -Time $expectedTime ` + -DataSchema $expectedDataSchema # Assert $actual | Should -Not -Be $null @@ -44,6 +47,20 @@ Describe "New-CloudEvent Function Tests" { $actual.Source | Should -Be $expectedSource $actual.Id | Should -Be $expectedId $actual.Time | Should -Be $expectedTime + $actual.DataSchema | Should -BeOfType ([System.Uri]) + $actual.DataSchema | Should -Be $expectedDataSchema + } + + It 'Rejects invalid DataSchema values' -TestCases @( + @{ DataSchema = $null } + @{ DataSchema = '' } + @{ DataSchema = 'schema.json' } + @{ DataSchema = 'http://[invalid' } + ) { + param($DataSchema) + + { New-CloudEvent -Type test -Source 'urn:test' -Id 'test-id' -DataSchema $DataSchema } | + Should -Throw } } } \ No newline at end of file diff --git a/test/unit/Set-CloudEventData.Tests.ps1 b/test/unit/Set-CloudEventData.Tests.ps1 index e22568c..d2e6d2f 100644 --- a/test/unit/Set-CloudEventData.Tests.ps1 +++ b/test/unit/Set-CloudEventData.Tests.ps1 @@ -26,6 +26,7 @@ Describe "Set-CloudEventData Function Tests" { $actual | Should -Not -Be $null $actual.DataContentType.ToString() | Should -Be $expectedDataContentType $actual.Data | Should -Be $expectedData + $actual.DataSchema | Should -BeNullOrEmpty } It 'Sets xml text data' { @@ -53,6 +54,41 @@ Describe "Set-CloudEventData Function Tests" { } + Context "Sets DataSchema" { + It 'Sets or preserves DataSchema' -TestCases @( + @{ Parameters = @{ DataSchema = 'https://example.com/schema.json' }; ExpectedDataSchema = 'https://example.com/schema.json' } + @{ Parameters = @{ DataSchema = [System.Uri]'urn:test:schema' }; ExpectedDataSchema = 'urn:test:schema' } + @{ Parameters = @{}; ExpectedDataSchema = 'https://example.com/original.json' } + ) { + param($Parameters, $ExpectedDataSchema) + + $cloudEvent = New-CloudEvent -Type test -Source 'urn:test' -Id 'test-id' + $cloudEvent.DataSchema = [System.Uri]'https://example.com/original.json' + + $actual = $cloudEvent | Set-CloudEventData -Data '{"a":"b"}' -DataContentType 'application/json' @Parameters + + $actual | Should -Be $cloudEvent + $actual.DataSchema | Should -BeOfType ([System.Uri]) + $actual.DataSchema | Should -Be $ExpectedDataSchema + $actual.Data | Should -Be '{"a":"b"}' + $actual.DataContentType.ToString() | Should -Be 'application/json' + } + + It 'Rejects invalid DataSchema values' -TestCases @( + @{ DataSchema = $null } + @{ DataSchema = '' } + @{ DataSchema = 'schema.json' } + @{ DataSchema = 'http://[invalid' } + ) { + param($DataSchema) + + $cloudEvent = New-CloudEvent -Type test -Source 'urn:test' -Id 'test-id' + + { $cloudEvent | Set-CloudEventData -Data '{}' -DataContentType 'application/json' -DataSchema $DataSchema } | + Should -Throw + } + } + Context "Errors on invalid data content type" { It 'Throws error on invalid MIME content type' { # Arrange diff --git a/test/unit/Set-CloudEventJsonData.Tests.ps1 b/test/unit/Set-CloudEventJsonData.Tests.ps1 index 089fba9..ed57b29 100644 --- a/test/unit/Set-CloudEventJsonData.Tests.ps1 +++ b/test/unit/Set-CloudEventJsonData.Tests.ps1 @@ -4,6 +4,41 @@ # ************************************************************************** Describe "Set-CloudEventJsonData Function Tests" { + Context "Sets DataSchema" { + It 'Sets or preserves DataSchema' -TestCases @( + @{ Parameters = @{ DataSchema = 'https://example.com/schema.json' }; ExpectedDataSchema = 'https://example.com/schema.json' } + @{ Parameters = @{ DataSchema = [System.Uri]'urn:test:schema' }; ExpectedDataSchema = 'urn:test:schema' } + @{ Parameters = @{}; ExpectedDataSchema = 'https://example.com/original.json' } + ) { + param($Parameters, $ExpectedDataSchema) + + $cloudEvent = New-CloudEvent -Type test -Source 'urn:test' -Id 'test-id' + $cloudEvent.DataSchema = [System.Uri]'https://example.com/original.json' + + $actual = $cloudEvent | Set-CloudEventJsonData -Data @{ 'a' = 'b' } @Parameters + + $actual | Should -Be $cloudEvent + $actual.DataSchema | Should -BeOfType ([System.Uri]) + $actual.DataSchema | Should -Be $ExpectedDataSchema + ($actual.Data | ConvertFrom-Json).a | Should -Be 'b' + $actual.DataContentType.ToString() | Should -Be 'application/json' + } + + It 'Rejects invalid DataSchema values' -TestCases @( + @{ DataSchema = $null } + @{ DataSchema = '' } + @{ DataSchema = 'schema.json' } + @{ DataSchema = 'http://[invalid' } + ) { + param($DataSchema) + + $cloudEvent = New-CloudEvent -Type test -Source 'urn:test' -Id 'test-id' + + { $cloudEvent | Set-CloudEventJsonData -Data @{} -DataSchema $DataSchema } | + Should -Throw + } + } + Context "Sets Json Data" { It 'Sets json data with depth 1' { # Arrange @@ -25,6 +60,7 @@ Describe "Set-CloudEventJsonData Function Tests" { $actual | Should -Not -Be $null $actual.DataContentType.ToString() | Should -Be 'application/json' $actual.Data | Should -Be $expectedJson + $actual.DataSchema | Should -BeNullOrEmpty } It 'Sets json data with depth 4' { From d76c35d185bec62b0dfb1567cc94190a50a7e9eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Nov 2026 23:32:43 +0000 Subject: [PATCH 3/3] Fix content type unit assertions Co-authored-by: duglin <1944671+duglin@users.noreply.github.com> --- test/unit/Set-CloudEventData.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/Set-CloudEventData.Tests.ps1 b/test/unit/Set-CloudEventData.Tests.ps1 index d2e6d2f..222b3ee 100644 --- a/test/unit/Set-CloudEventData.Tests.ps1 +++ b/test/unit/Set-CloudEventData.Tests.ps1 @@ -121,7 +121,7 @@ Describe "Set-CloudEventData Function Tests" { -CloudEvent $cloudEvent ` -Data '1' ` -DataContentType $invalidContentType } | ` - Should -Throw "*The parameter 'contentType' cannot be an empty string*" + Should -Throw "*cannot be an empty string*" } It 'Throws error on null content type' { @@ -138,7 +138,7 @@ Describe "Set-CloudEventData Function Tests" { -CloudEvent $cloudEvent ` -Data '1' ` -DataContentType $invalidContentType } | ` - Should -Throw "*The parameter 'contentType' cannot be an empty string*" + Should -Throw "*cannot be an empty string*" } } } \ No newline at end of file