Repository navigation
Open
Description
I went through the current design with copilot and instructed it on how to have better cohesion between commands as well as improving the ux/dx, and I came up with this plan -- it wouldn't strictly be breaking, but I would be inclined to bump a minor version at least:
Plan: Pipeline binding improvements for CloudEvents.Sdk
Current state (src/CloudEventsPowerShell/CloudEvents.Sdk.psm1)
- 9 functions:
New-CloudEvent,Set-CloudEvent{,Json,Xml}Data,Read-CloudEvent{,Json,Xml}Data,ConvertTo-HttpMessage,ConvertFrom-HttpMessage. - Only
-CloudEventhasValueFromPipeline. No parameter usesValueFromPipelineByPropertyName(ConvertTo-/ConvertFrom-HttpMessageset it explicitly to$false). - No
[OutputType], no[Alias], no parameter sets. Output is emitted withWrite-Output.
Output → input cohesion gaps
ConvertTo-HttpMessageemits{Headers, Body}, butConvertFrom-HttpMessagecan't take it from the pipeline.Invoke-WebRequest/Invoke-RestMethodresponses exposeHeadersandContent.Bodydoesn't matchContent, so nothing binds.ConvertTo-HttpMessageoutput can't be piped intoInvoke-WebRequest. This is acceptable, but splatting should be documented.New-CloudEventparameters (Type/Source/Id/Time/DataSchema) mirror CloudEvent property names but can't take objects (CSV rows, other events, custom objects) from the pipeline.Set-CloudEvent*Datacan't take-Datafrom the pipeline.- Reading from one event and writing to another needs a manual step.
Bugs coupled to parameter metadata
Set-CloudEventData:-DataContentTypeis a[string]that is never validated or converted.- The
ContentTypeobject built withNew-Objectis unused. - It throws when
-DataContentTypeis omitted. - The raw string is assigned to
$cloudEvent.DataContentType.
Set-CloudEventXmlData:-AttributesKeysInElementAttributesis a mandatory[bool]. Changing it to a switch would be breaking, so it is deferred.- Validation attributes are inconsistent (
ValidateNotNullOrEmptyvsValidateNotNull).-BodyonConvertFrom-HttpMessageis untyped.
Improvement list (non-breaking unless noted)
ConvertFrom-HttpMessage- Add
ValueFromPipelineByPropertyName = $trueto-Headersand-Body. - Add
[Alias('Content')]on-Body. - Accept
[System.Collections.IDictionary]for-Headers, a superset ofhashtablethat handles theDictionary<string,string[]>fromInvoke-WebRequestin PS7. - Result:
ConvertTo-HttpMessage | ConvertFrom-HttpMessageandInvoke-WebRequest … | ConvertFrom-HttpMessageboth work. - Positional and named usage stays identical.
- Add
ConvertTo-HttpMessage- Remove the explicit
ByPropertyName = $false. - Add
[OutputType]and aPSTypeName(e.g.CloudEvents.HttpMessage) on the output so it is discoverable. - Emit the same
Headers/Bodyproperties.
- Remove the explicit
New-CloudEvent- Add
ValueFromPipelineByPropertyName = $trueon Type, Source, Id, Time, DataSchema. - Enables
Import-Csv | New-CloudEventand event-to-event cloning. - Make
-Idand-Timeoptional, defaulting to[guid]::NewGuid()and the current time. This is additive and doesn't break existing callers. - Add
[OutputType([CloudNative.CloudEvents.CloudEvent])].
- Add
Set-CloudEventData/Json/Xml- Add
ValueFromPipelineByPropertyNameto-Data,-DataContentTypeand-DataSchema(Json/Xml:-Dataand-DataSchema). - Keep
-CloudEventasValueFromPipeline, so by-value binding wins for CloudEvent input. - Decision:
-Databinds by property name. Mitigate the case where a pipedCloudEventbinds its ownData(via parameter sets or guard logic) and cover it with a test.
- Add
Read-CloudEvent*Data- Add
[OutputType](object/hashtable/ etc.). - Add
ValueFromPipelineByPropertyNameto-CloudEvent, so wrapper objects with aCloudEventproperty bind. - Make
-Depthdefaults consistent between Set and Read Json.
- Add
- Consistent
-CloudEventparameter- Add
[Alias('InputObject','Event')]in all 8 functions that take a CloudEvent. - Unify validation to
[ValidateNotNull()]. - Drop the redundant
= $falseattribute noise.
- Add
- Pass-through:
Set-*already emit the event, so no-PassThruis needed. Only simplifyWrite-Outputif there is no behavior change. - Bug fixes (low risk)
Set-CloudEventData: only build theContentTypewhen-DataContentTypeis supplied, and assign theContentTypeobject.- Review
-ConvertModehandling onRead-CloudEventXmlData.
- Deferred (breaking, next major)
- Make
-AttributesKeysInElementAttributesa[switch]. - Make
-ConvertModenon-mandatory with a default.
- Make
- Help and docs
- Fix help inconsistencies (
Add-CloudEvent*Data→Set-CloudEvent*Data, typos). - Add pipeline examples plus
.INPUTS/.OUTPUTS. - Add pipeline recipes to the README.
- Fix help inconsistencies (
- Tests (
test/unit/*.Tests.ps1)- Property-bound piping into
New-CloudEvent. ConvertTo-HttpMessage | ConvertFrom-HttpMessageround trip.- An IWR-shaped object (
Headers,Content) piped intoConvertFrom-HttpMessage. Set-*DatawithData/DataContentTypebound by property name.- A regression test for the
Set-CloudEventDatacontent-type bug. - Run with
test/RunTests.ps1.
- Property-bound piping into
Test policy
- Run the existing suite before changes (baseline) and after.
- If any existing test breaks because of a behavioral change, document it (test name, old vs new behavior, reason) in the PR description / CHANGELOG notes and in the final summary.
- Add new, independent Pester tests (self-contained, no shared state or ordering dependence) for every improvement.
Todos
- Implement items 1–2 (HTTP cohesion).
- Implement item 3 (
New-CloudEvent). - Implement item 4 (
Set-*data). - Implement items 5–6 (
Read-*, aliases, validation,OutputType). - Fix the item 8 bugs.
- Update docs and help (item 10).
- Add tests (item 11) and run the unit suite before and after.
Decisions made
-DataonSet-CloudEvent*Dataaccepts pipeline-by-property: yes.New-CloudEvent -Id/-Timeauto-default: yes.- New output type name
CloudEvents.HttpMessage: proposed, not yet confirmed
Metadata
Metadata
Assignees
Labels
No labels
Activity