Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
21282d9
Bump PSModule/Process-PSModule/.github/workflows/workflow.yml
dependabot[bot] Jun 2, 2026
c11d1b8
Fix README placeholders
MariusStorhaug Jul 5, 2026
35a5535
Standardize README landing page
MariusStorhaug Jul 6, 2026
d47c0c5
Require Pester 6.x in test files
MariusStorhaug Jul 7, 2026
2f02acd
Drop the GUID from the Pester requirement
MariusStorhaug Jul 7, 2026
6a28bc4
Adopt Process-PSModule v6.1.4
MariusStorhaug Jul 12, 2026
23a4a98
📖 [Docs]: Remove Contributing section from placeholder README
MariusStorhaug Jul 12, 2026
eb063ec
📖 [Docs]: Clarify documentation is not published yet for placeholder
MariusStorhaug Jul 12, 2026
6bc7a36
Add Domeneshop context auth flow
MariusStorhaug Jul 25, 2026
f32ed30
Add tests for context credential workflow
MariusStorhaug Jul 25, 2026
25200d1
Implement full Domeneshop v0 endpoint commands
MariusStorhaug Jul 25, 2026
e142777
Expand tests for all API endpoint commands
MariusStorhaug Jul 25, 2026
0b812c0
Harden Domeneshop command contracts
MariusStorhaug Jul 25, 2026
137223a
Split tests by public command
MariusStorhaug Jul 25, 2026
5983628
Document Domeneshop command groups
MariusStorhaug Jul 25, 2026
e444b23
Align baseline command help and validation
MariusStorhaug Jul 25, 2026
5f14a7e
Merge PR #11 Process-PSModule v5.5.7 update
MariusStorhaug Jul 25, 2026
6f25b85
Merge PR #13 Process-PSModule v6.1.4 and Pester 6 policy
MariusStorhaug Jul 25, 2026
311f50a
Merge PR #12 README landing page improvements
MariusStorhaug Jul 25, 2026
f177577
Merge PR #14 Domeneshop API capabilities
MariusStorhaug Jul 25, 2026
69aafaa
Merge PR #15 command standards hardening
MariusStorhaug Jul 25, 2026
39f8bb9
Require Pester 6 in split test files
MariusStorhaug Jul 25, 2026
785d8a7
Fix generated command documentation lint
MariusStorhaug Jul 25, 2026
f1090eb
Normalize generated HTTPS examples
MariusStorhaug Jul 25, 2026
643f79e
Address release review feedback
MariusStorhaug Jul 25, 2026
a7ddcd0
Preserve Windows PowerShell REST compatibility
MariusStorhaug Jul 25, 2026
0b36e9b
Align command prompts and test setup
MariusStorhaug Jul 25, 2026
eb3ec7e
Protect reserved context configuration
MariusStorhaug Jul 25, 2026
e643399
Reject empty API secrets
MariusStorhaug Jul 25, 2026
f30f681
Use portable test setup paths
MariusStorhaug Jul 25, 2026
7127901
Add interactive API secret setup
MariusStorhaug Jul 25, 2026
411039d
Address delayed release review findings
MariusStorhaug Jul 25, 2026
def7ed5
Add canonical public help links
MariusStorhaug Jul 25, 2026
175cde4
Harden context lookup and WhatIf behavior
MariusStorhaug Jul 25, 2026
6cc608e
Fix grouped public help links
MariusStorhaug Jul 25, 2026
d751c66
Align help links with grouped documentation
MariusStorhaug Jul 25, 2026
401804f
Merge concurrent release help-link update
MariusStorhaug Jul 25, 2026
d565c8c
Restore exact generated help routes
MariusStorhaug Jul 25, 2026
2affd9d
Enforce documented help URLs
MariusStorhaug Jul 25, 2026
f8591cf
Preserve generated URL trailing slashes
MariusStorhaug Jul 25, 2026
4bcdb89
Restore documented no-slash help URLs
MariusStorhaug Jul 25, 2026
066d50a
Keep help-link tests compatible with PowerShell 5.1
MariusStorhaug Jul 25, 2026
ebf7320
Target the latest PowerShell LTS
MariusStorhaug Jul 25, 2026
e7385a4
Reject whitespace domain filters
MariusStorhaug Jul 25, 2026
f8711c8
Reject whitespace-only command inputs
MariusStorhaug Jul 25, 2026
0c36880
Require the latest PowerShell LTS
MariusStorhaug Jul 25, 2026
41f39ca
Use canonical generated help routes
MariusStorhaug Jul 25, 2026
a8e167d
Keep credential prompting available without a browser
MariusStorhaug Jul 25, 2026
b866361
Update Process-PSModule to v6.1.13
MariusStorhaug Jul 25, 2026
a32219c
Group public command tests by feature
MariusStorhaug Jul 25, 2026
3e045a5
Migrate module docs configuration to Zensical
MariusStorhaug Jul 25, 2026
ec2bcca
Add PR template foldable end sections
MariusStorhaug Jul 25, 2026
bc02714
Remove pull request template
MariusStorhaug Jul 25, 2026
fe18c35
Group command tests by feature file
MariusStorhaug Jul 25, 2026
272aca4
Consolidate command tests by group
MariusStorhaug Jul 26, 2026
9834688
Merge concurrent release updates
MariusStorhaug Jul 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/Process-PSModule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ permissions:

jobs:
Process-PSModule:
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@205d193f34cbbaf9992955c21d842bcf98a1859f # v5.4.6
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@da180bac16b13bfbcdf08b2e4e221b5b49e5ff28 # v6.1.4
secrets:
APIKEY: ${{ secrets.APIKEY }}
68 changes: 5 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,11 @@
# {{ NAME }}
# Domeneshop

{{ DESCRIPTION }}
Domeneshop is intended to be a PowerShell module for interacting with the Domeneshop APIs.

## Prerequisites
## Status

This uses the following external resources:
- The [PSModule framework](https://github.com/PSModule/Process-PSModule) for building, testing and publishing the module.

## Installation

To install the module from the PowerShell Gallery, you can use the following command:

```powershell
Install-PSResource -Name {{ NAME }}
Import-Module -Name {{ NAME }}
```

## Usage

Here is a list of example that are typical use cases for the module.

### Example 1: Greet an entity

Provide examples for typical commands that a user would like to do with the module.

```powershell
Greet-Entity -Name 'World'
Hello, World!
```

### Example 2

Provide examples for typical commands that a user would like to do with the module.

```powershell
Import-Module -Name PSModuleTemplate
```

### Find more examples

To find more examples of how to use the module, please refer to the [examples](examples) folder.

Alternatively, you can use the Get-Command -Module 'This module' to find more commands that are available in the module.
To find examples of each of the commands you can use Get-Help -Examples 'CommandName'.
This repository is currently a placeholder. The module source still contains scaffold code, so there are no supported commands or usage examples to document yet.
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated

## Documentation

Link to further documentation if available, or describe where in the repository users can find more detailed documentation about
the module's functions and features.

## Contributing

Coder or not, you can contribute to the project! We welcome all contributions.

### For Users

If you don't code, you still sit on valuable information that can make this project even better. If you experience that the
product does unexpected things, throw errors or is missing functionality, you can help by submitting bugs and feature requests.
Please see the issues tab on this project and submit a new issue that matches your needs.

### For Developers

If you do code, we'd love to have your contributions. Please read the [Contribution guidelines](CONTRIBUTING.md) for more information.
You can either help by picking up an existing issue or submit a new one if you have an idea for a new feature or improvement.

## Acknowledgements

Here is a list of people and projects that helped this project in some way.
Documentation is not published yet because this module is still a placeholder. Once the module is implemented, command details will live in PowerShell help and generated documentation rather than being duplicated in this README.
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
48 changes: 48 additions & 0 deletions src/functions/private/Auth/Get-DomeneshopConfig.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#Requires -Modules @{ ModuleName = 'Context'; ModuleVersion = '8.1.6' }

function Get-DomeneshopConfig {
<#
.SYNOPSIS
Get the Domeneshop module configuration.

.DESCRIPTION
Read the module configuration from the Context vault or return an in-memory default when no configuration has been stored.

.EXAMPLE
Get-DomeneshopConfig

Get the current Domeneshop module configuration.

.INPUTS
None

You can't pipe objects to Get-DomeneshopConfig.

.OUTPUTS
System.Object

The stored or default Domeneshop module configuration.

.NOTES
This read helper does not create or update Context vault entries.

.LINK
https://psmodule.io/Context/
#>
[OutputType([object])]
[CmdletBinding()]
param()

$vault = 'Domeneshop'
$id = '__Domeneshop.Config'
$config = Get-Context -ID $id -Vault $vault

if (-not $config) {
$config = [pscustomobject][ordered]@{
DefaultContext = $null
ApiBaseUri = 'https://api.domeneshop.no/v0'
}
}

$config
}
52 changes: 52 additions & 0 deletions src/functions/private/Auth/Resolve-DomeneshopContext.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
function Resolve-DomeneshopContext {
<#
.SYNOPSIS
Validate a resolved Domeneshop context.

.DESCRIPTION
Verify that a context resolved by a public command contains the credentials and API endpoint required by private helpers.

.EXAMPLE
Resolve-DomeneshopContext -Context $storedContext

Validate and emit a stored Domeneshop context.

.INPUTS
None

You can't pipe objects to Resolve-DomeneshopContext.

.OUTPUTS
System.Object

The validated Domeneshop context.

.NOTES
This helper never selects or defaults a context. Public commands own that behavior.

.LINK
https://psmodule.io/Context/
#>
[OutputType([object])]
[CmdletBinding()]
param(
# The context object selected by a public command.
[Parameter(Mandatory)]
[AllowNull()]
[object] $Context
)

if ($null -eq $Context) {
throw "No Domeneshop context found. Run 'Connect-DomeneshopAccount' first."
}

if ([string]::IsNullOrWhiteSpace([string] $Context.Token) -or -not ($Context.Secret -is [securestring])) {
throw "The Domeneshop context [$($Context.ID)] is missing valid credentials."
}

if ([string]::IsNullOrWhiteSpace([string] $Context.ApiBaseUri)) {
throw "The Domeneshop context [$($Context.ID)] is missing an API base URI."
}

$Context
}
46 changes: 46 additions & 0 deletions src/functions/private/Auth/Set-DomeneshopDefaultContext.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#Requires -Modules @{ ModuleName = 'Context'; ModuleVersion = '8.1.6' }

function Set-DomeneshopDefaultContext {
<#
.SYNOPSIS
Set the default Domeneshop context name.

.DESCRIPTION
Persist the selected default context name in the Domeneshop configuration entry.

.EXAMPLE
Set-DomeneshopDefaultContext -Context 'production'

Set production as the default Domeneshop context.

.INPUTS
None

You can't pipe objects to Set-DomeneshopDefaultContext.

.OUTPUTS
None

Set-DomeneshopDefaultContext doesn't emit output.

.NOTES
The public caller is responsible for guarding this mutation with ShouldProcess.

Comment thread
MariusStorhaug marked this conversation as resolved.
.LINK
https://psmodule.io/Context/
#>
[OutputType([void])]
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')]
param(
# The name of an existing Domeneshop context.
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $Context
Comment thread
MariusStorhaug marked this conversation as resolved.
)

$config = Get-DomeneshopConfig
$config.DefaultContext = $Context
if ($PSCmdlet.ShouldProcess('Domeneshop module configuration', "Set [$Context] as the default context")) {
$null = Set-Context -ID '__Domeneshop.Config' -Vault 'Domeneshop' -Context $config
}
Comment thread
MariusStorhaug marked this conversation as resolved.
}
50 changes: 50 additions & 0 deletions src/functions/private/Get-DomeneshopApiBaseUri.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
function Get-DomeneshopApiBaseUri {
<#
.SYNOPSIS
Get the API base URI from a resolved Domeneshop context.

.DESCRIPTION
Validate and normalize the API base URI stored on a resolved Domeneshop context.

.EXAMPLE
Get-DomeneshopApiBaseUri -Context $resolvedContext

Get the normalized API base URI for a resolved context.

.INPUTS
None

You can't pipe objects to Get-DomeneshopApiBaseUri.

.OUTPUTS
System.String

The normalized Domeneshop API base URI.

.NOTES
The caller must resolve and validate the context before invoking this helper.

.LINK
https://api.domeneshop.no/docs/
#>
[OutputType([string])]
[CmdletBinding()]
param(
# The resolved Domeneshop context containing an API base URI.
[Parameter(Mandatory)]
[ValidateNotNull()]
[object] $Context
)

$apiBaseUri = [string] $Context.ApiBaseUri
if ([string]::IsNullOrWhiteSpace($apiBaseUri)) {
throw "The Domeneshop context [$($Context.ID)] does not define an API base URI."
}

$parsedUri = $null
if (-not [uri]::TryCreate($apiBaseUri, [System.UriKind]::Absolute, [ref] $parsedUri)) {
throw "The Domeneshop context [$($Context.ID)] contains an invalid API base URI."
}

$parsedUri.AbsoluteUri.TrimEnd('/')
}
79 changes: 79 additions & 0 deletions src/functions/private/Invoke-DomeneshopApiRequest.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
function Invoke-DomeneshopApiRequest {
<#
.SYNOPSIS
Send an authenticated request to the Domeneshop API.

.DESCRIPTION
Build an HTTP Basic credential from a resolved Domeneshop context and send a REST request, optionally with a JSON body.

.EXAMPLE
Invoke-DomeneshopApiRequest -Method Get -Uri $uri -Context $resolvedContext

Send an authenticated GET request.

.EXAMPLE
Invoke-DomeneshopApiRequest -Method Post -Uri $uri -Context $resolvedContext -Body $body

Send an authenticated POST request with a JSON body.

.INPUTS
None

You can't pipe objects to Invoke-DomeneshopApiRequest.

.OUTPUTS
System.Object

The response returned by the Domeneshop API.

.NOTES
Transport errors are terminating so public callers fail fast.

.LINK
https://api.domeneshop.no/docs/
#>
[OutputType([object])]
[CmdletBinding()]
param(
# The HTTP method accepted by the Domeneshop API.
[Parameter(Mandatory)]
[ValidateSet('Get', 'Post', 'Put', 'Delete')]
[string] $Method,

# The absolute Domeneshop API endpoint URI.
[Parameter(Mandatory)]
[ValidateNotNull()]
[uri] $Uri,

# The resolved Domeneshop context containing valid credentials.
[Parameter(Mandatory)]
[ValidateNotNull()]
[object] $Context,

# The request payload to serialize as JSON.
[Parameter()]
[AllowNull()]
[object] $Body
)

$credential = [pscredential]::new(
[string] $Context.Token,
[securestring] $Context.Secret
)

$params = @{
Method = $Method
Uri = $Uri
Authentication = 'Basic'
Credential = $credential
ErrorAction = 'Stop'
}
Comment thread
MariusStorhaug marked this conversation as resolved.

if ($PSBoundParameters.ContainsKey('Body')) {
$params['ContentType'] = 'application/json'
$params['Body'] = ($Body | ConvertTo-Json -Depth 100)
}

Write-Debug "Sending $Method request to [$Uri]."
Invoke-RestMethod @params
}
8 changes: 8 additions & 0 deletions src/functions/public/Auth/Auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Auth

Public commands for storing and retrieving Domeneshop credential contexts.

## Commands

- `Connect-DomeneshopAccount`: Stores Domeneshop API credentials in the Context vault.
- `Get-DomeneshopContext`: Gets a named or default context, or lists available contexts.
Loading
Loading