Skip to content

Commit c50f6d7

Browse files
docs(specs): add v1 functional specification
Defines the initial public API for the PowerShellGallery module: - API metadata discovery - Package search and metadata retrieval - Listing management (hide/show) for package owners Includes naming conventions, parameter design, error handling, testing strategy, and migration notes from current stubs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent ea0734c commit c50f6d7

1 file changed

Lines changed: 270 additions & 0 deletions

File tree

docs/specs/v1.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
# PowerShellGallery v1 Specification
2+
3+
## Overview
4+
5+
`PowerShellGallery` is a PowerShell module for interacting with the [PowerShell Gallery](https://www.powershellgallery.com). Version 1 focuses on two publisher-oriented workflows:
6+
7+
1. **Discovery** — read package and API metadata from the public OData v2 endpoint.
8+
2. **Listing management** — list and unlist package versions you own, using gallery API credentials.
9+
10+
This spec defines the public API, expected behavior, error handling, and testing strategy for the v1 release.
11+
12+
## Supported PowerShell version
13+
14+
Latest PowerShell Long-Term Support (LTS) release, per the PSModule module standard. Windows PowerShell 5.1 is not a v1 target.
15+
16+
## Out of scope for v1
17+
18+
- Installing, updating, or saving packages (covered by `PowerShellGet`).
19+
- Publishing packages to the gallery.
20+
- User or organization management.
21+
- Admin-level gallery operations.
22+
- Cross-gallery support (e.g., private NuGet feeds).
23+
24+
## Naming convention
25+
26+
Public nouns are prefixed with the module term of art: `PowerShellGallery`.
27+
28+
Existing stub names `Hide-PowerShellGalleryItem` and `Show-PowerShellGalleryItem` are renamed to use the more precise noun `Package`, with backward-compatible aliases retained for the v1 major release.
29+
30+
## Public API
31+
32+
### `Get-PowerShellGalleryAPI`
33+
34+
Get metadata from the PowerShell Gallery v2 API root.
35+
36+
#### Synopsis
37+
38+
```text
39+
Get-PowerShellGalleryAPI [[-Uri] <string>] [<CommonParameters>]
40+
```
41+
42+
#### Parameters
43+
44+
| Name | Type | Mandatory | Default | Description |
45+
| ---- | ---- | --------- | ------- | ----------- |
46+
| `Uri` | `string` | No | `https://www.powershellgallery.com/api/v2/` | Base URI of the gallery OData endpoint. |
47+
48+
#### Behavior
49+
50+
- Performs an HTTP `GET` against the provided URI with `application/json` content negotiation.
51+
- Returns the raw service response (commonly an OData service document / JSON).
52+
- Throws a terminating error if the endpoint is unreachable or returns a non-success status code.
53+
54+
#### Example
55+
56+
```powershell
57+
Get-PowerShellGalleryAPI
58+
```
59+
60+
---
61+
62+
### `Find-PowerShellGalleryPackage`
63+
64+
Search for packages on the PowerShell Gallery.
65+
66+
#### Synopsis
67+
68+
```text
69+
Find-PowerShellGalleryPackage [[-Name] <string>] [-Tag <string[]>] [-IncludePrerelease] [-First <uint>]
70+
[-Skip <uint>] [-OrderBy <string>] [<CommonParameters>]
71+
```
72+
73+
#### Parameters
74+
75+
| Name | Type | Mandatory | Default | Description |
76+
| ---- | ---- | --------- | ------- | ----------- |
77+
| `Name` | `string` | No | `*` | Package ID or search term. Supports wildcards. |
78+
| `Tag` | `string[]` | No | none | Filter to packages that declare all specified tags. |
79+
| `IncludePrerelease` | `switch` | No | false | Include prerelease versions in results. |
80+
| `First` | `uint` | No | `50` | Maximum number of results to return. Capped at `1000`. |
81+
| `Skip` | `uint` | No | `0` | Number of results to skip for pagination. |
82+
| `OrderBy` | `string` | No | `DownloadCount desc` | OData `$orderby` expression. |
83+
84+
#### Behavior
85+
86+
- Queries `https://www.powershellgallery.com/api/v2/Packages()`.
87+
- Supports pipeline input for `Name`.
88+
- Returns one object per package version by default.
89+
- Use `Get-PowerShellGalleryPackage` when you need a single package/version.
90+
91+
#### Example
92+
93+
```powershell
94+
Find-PowerShellGalleryPackage -Name 'Pester' -First 5
95+
'Az.*' | Find-PowerShellGalleryPackage -First 10
96+
```
97+
98+
---
99+
100+
### `Get-PowerShellGalleryPackage`
101+
102+
Get detailed metadata for a specific package and optionally a specific version.
103+
104+
#### Synopsis
105+
106+
```text
107+
Get-PowerShellGalleryPackage [-Name] <string> [[-Version] <string>] [-IncludePrerelease]
108+
[<CommonParameters>]
109+
```
110+
111+
#### Parameters
112+
113+
| Name | Type | Mandatory | Default | Description |
114+
| ---- | ---- | --------- | ------- | ----------- |
115+
| `Name` | `string` | Yes || Exact package ID. |
116+
| `Version` | `string` | No | latest stable | Specific version to retrieve. Accepts NuGet version strings including prerelease labels. |
117+
| `IncludePrerelease` | `switch` | No | false | When `Version` is omitted, return the latest prerelease instead of the latest stable. |
118+
119+
#### Behavior
120+
121+
- If `Version` is provided, queries `Packages(Id='{Name}',Version='{Version}')`.
122+
- If `Version` is omitted, queries the package feed filtered by ID, ordered by published date, and returns the newest item.
123+
- Throws a terminating error if the package or version does not exist.
124+
125+
#### Example
126+
127+
```powershell
128+
Get-PowerShellGalleryPackage -Name 'Pester'
129+
Get-PowerShellGalleryPackage -Name 'Pester' -Version '5.5.0'
130+
```
131+
132+
---
133+
134+
### `Hide-PowerShellGalleryPackage`
135+
136+
Unlist a package version on the PowerShell Gallery.
137+
138+
#### Synopsis
139+
140+
```text
141+
Hide-PowerShellGalleryPackage [-Name] <string> [-Version] <string> [-APIKey] <string>
142+
[-WhatIf] [-Confirm] [<CommonParameters>]
143+
```
144+
145+
#### Aliases
146+
147+
- `Unlist-PowerShellGalleryPackage`
148+
149+
#### Parameters
150+
151+
| Name | Type | Mandatory | Default | Description |
152+
| ---- | ---- | --------- | ------- | ----------- |
153+
| `Name` | `string` | Yes || Exact package ID. |
154+
| `Version` | `string` | Yes || Exact version to unlist. |
155+
| `APIKey` | `string` | Yes || PowerShell Gallery API key for the package owner. |
156+
157+
#### Behavior
158+
159+
- Requires ownership of the package.
160+
- Uses the gallery listing endpoint to mark the version as unlisted.
161+
- Supports `-WhatIf` and `-Confirm` via `SupportsShouldProcess`.
162+
- Writes a non-terminating warning if the operation is not yet implemented or the gallery endpoint is unavailable.
163+
164+
#### Example
165+
166+
```powershell
167+
Hide-PowerShellGalleryPackage -Name 'MyModule' -Version '1.0.0' -APIKey $env:PSGalleryAPIKey
168+
```
169+
170+
---
171+
172+
### `Show-PowerShellGalleryPackage`
173+
174+
List a package version on the PowerShell Gallery.
175+
176+
#### Synopsis
177+
178+
```text
179+
Show-PowerShellGalleryPackage [-Name] <string> [-Version] <string> [-APIKey] <string>
180+
[-WhatIf] [-Confirm] [<CommonParameters>]
181+
```
182+
183+
#### Aliases
184+
185+
- `List-PowerShellGalleryPackage`
186+
187+
#### Parameters
188+
189+
| Name | Type | Mandatory | Default | Description |
190+
| ---- | ---- | --------- | ------- | ----------- |
191+
| `Name` | `string` | Yes || Exact package ID. |
192+
| `Version` | `string` | Yes || Exact version to list. |
193+
| `APIKey` | `string` | Yes || PowerShell Gallery API key for the package owner. |
194+
195+
#### Behavior
196+
197+
- Requires ownership of the package.
198+
- Uses the gallery listing endpoint to mark the version as listed.
199+
- Supports `-WhatIf` and `-Confirm` via `SupportsShouldProcess`.
200+
201+
#### Example
202+
203+
```powershell
204+
Show-PowerShellGalleryPackage -Name 'MyModule' -Version '1.0.0' -APIKey $env:PSGalleryAPIKey
205+
```
206+
207+
## Private helpers
208+
209+
Private functions are grouped under `src/functions/private/Gallery/`.
210+
211+
| Function | Responsibility |
212+
| -------- | -------------- |
213+
| `Invoke-PowerShellGalleryAPI` | Shared REST wrapper: handles URI building, headers, content negotiation, timeout, and error translation. |
214+
| `Get-PowerShellGalleryResource` | Generic OData resource GET (to be merged into or replaced by `Invoke-PowerShellGalleryAPI`). |
215+
| `Update-PowerShellGalleryResourceListing` | Shared POST to the gallery listing endpoint used by `Hide`/`Show`. |
216+
217+
## Return types
218+
219+
Commands return plain objects deserialized from OData JSON by default. A future release may introduce typed output classes; v1 does not.
220+
221+
## Error handling
222+
223+
- Use `ErrorAction` semantics consistently.
224+
- Wrap `Invoke-RestMethod` failures in descriptive error records where the gallery response adds useful context.
225+
- Authentication or authorization failures from listing endpoints produce clear, actionable messages.
226+
- Discovery commands must not throw on empty result sets; they return nothing.
227+
228+
## Authentication
229+
230+
- Read commands require no authentication.
231+
- Listing-management commands require a PowerShell Gallery API key with ownership of the target package.
232+
- The API key is passed via the `APIKey` parameter. Do not persist keys in the module; callers supply them per command.
233+
234+
## Logging and progress
235+
236+
- Emit `Verbose` output for URIs, pagination, and auth-skipping details.
237+
- Emit `Warning` when a listing command cannot complete because the gallery endpoint is unavailable.
238+
- Do not emit progress bars for simple HTTP calls.
239+
240+
## Testing
241+
242+
Follow the [PSModule Test Specification](https://psmodule.github.io/docs/Modules/Test-Specification/):
243+
244+
- No mocks; use real inputs and the public gallery endpoint.
245+
- Test each public command with `Describe`/`Context`/`It` hierarchy.
246+
- Discovery tests use well-known packages (e.g., `Pester`, `PowerShellGet`) to ensure stable results.
247+
- Listing-management tests validate parameter binding and `-WhatIf` behavior; they do not mutate real packages.
248+
- Code coverage target remains 50% as configured in `.github/PSModule.yml` for v1.
249+
250+
## Documentation
251+
252+
- Each public function has full comment-based help with synopsis, description, examples, and parameter help.
253+
- A `<Group>.md` overview file is added alongside public functions.
254+
- README is updated to describe v1 capabilities.
255+
256+
## Migration from current stubs
257+
258+
| Current file | v1 disposition |
259+
| ------------ | -------------- |
260+
| `Get-PSGalleryAPI.ps1` | Rename to `Get-PowerShellGalleryAPI.ps1`; keep URI default. |
261+
| `Hide-PowerShellGalleryItem.ps1` | Rename to `Hide-PowerShellGalleryPackage.ps1`; add `Unlist-PowerShellGalleryPackage` alias. |
262+
| `Show-PowerShellGalleryItem.ps1` | Rename to `Show-PowerShellGalleryPackage.ps1`; add `List-PowerShellGalleryPackage` alias. |
263+
| `Get-PSGalleryResource.ps1` | Refactor into `Invoke-PowerShellGalleryAPI` or retain as private helper. |
264+
| `Update-PSGalleryResourceListing.ps1` | Retain as private helper; fix auth and parameter handling. |
265+
266+
## Open questions
267+
268+
1. Does the gallery expose a stable, API-key-only listing endpoint, or do we need a full web-login + anti-forgery token flow?
269+
2. Should `Find-PowerShellGalleryPackage` collapse multiple versions of the same package ID by default?
270+
3. Should v1 include `Save-PowerShellGalleryPackage` (download `.nupkg`) or leave that to `PowerShellGet`?

0 commit comments

Comments
 (0)