Skip to content

Commit 4609ec2

Browse files
MariusStorhaugdependabot[bot]Copilot
authored
🌟[Major]: Domeneshop API capabilities now available (#16)
Domeneshop users gain authenticated access to the module's domain, DNS, forwarding, DDNS, and invoice capabilities through a consolidated pre-1.0 release candidate. ## New: Domeneshop API capabilities The module adds Context-based credential handling and commands for querying domains, managing DNS records and forwards, updating DDNS, and retrieving invoices. Command safety, validation, focused tests, and command-group documentation are included in the release candidate. ## New: Guided credential setup Running `Connect-DomeneshopAccount` without `-Secret` or its `-Key` alias opens the Domeneshop API settings page and securely prompts for the secret. If a browser is unavailable, the command warns and continues to the secure prompt. Explicit string and SecureString inputs remain supported, and `-WhatIf` does not open the browser, prompt, or change stored contexts. ## Changed: Release tooling and documentation The release candidate adopts Process-PSModule v6.1.13, enforces Pester 6.x across every test file, consolidates public command tests into root-level group suites, migrates the generated documentation site to Zensical, replaces README placeholders with the standard module landing page, and links each public command's help to its canonical generated documentation. --- <details> <summary>Technical details</summary> - Integrated PR #11, PR #13, the preserved pull ref for PR #12, PR #14, and stacked PR #15 in the requested order; each exact source head is verified as an ancestor of this branch. All five source PRs are now closed and their remote branches deleted. - Resolved the PR #11/PR #13 workflow overlap in favor of PR #13's Process-PSModule v6.1.4 baseline, then updated the consolidated release to latest Process-PSModule v6.1.13 at immutable commit `fb1bdb8fefd243292f779d2a856a38db6fe6daf4`. - Migrated `.github/mkdocs.yml` to `.github/zensical.toml`, satisfying v6.1.13's Zensical-only documentation pipeline. - PR #14 was merged explicitly before PR #15; PR #15's existing ancestry was retained, so only its four standards-hardening commits were introduced by the later merge. - Added an integration commit applying PR #13's exact Pester 6.x requirement to the command tests introduced by PR #15. - Uses the Standard test-layout profile: grouped public commands are covered by root-level `tests/<Group>.Tests.ps1` suites (`Auth`, `Ddns`, `Dns`, `Domains`, `Forwards`, and `Invoices`), while ungrouped and cross-cutting suites remain separate at the root. Deterministic layout coverage verifies every public command has a matching `Describe` block in its expected suite. - Added interactive credential setup as a separate micro-commit, including the exact `https://domene.shop/admin?view=api` launch, `Read-Host -AsSecureString`, `Key` alias, side-effect-free `-WhatIf` behavior, and a warning-only browser fallback that preserves secure prompting. - Added group-aware canonical links first in all 14 public function help blocks: `https://psmodule.io/Domeneshop/Functions/<FunctionName>/` for ungrouped commands and `https://psmodule.io/Domeneshop/Functions/<Group>/<FunctionName>/` for grouped commands. Deterministic tests require the exact trailing-slash route and reject missing, incorrect, or secondary-first links. - Linked clearly owned private Auth helpers to the published public commands they support while retaining useful secondary Context links. - Requires PowerShell 7.6, the latest LTS. The generated module manifest declares `PowerShellVersion = 7.6` and `CompatiblePSEditions = Core`; legacy Windows PowerShell compatibility branches are intentionally excluded. - Rejects whitespace-only API tokens, DDNS values, DNS filters, domain filters, forward hosts, and smoke-test names before state changes or URI construction. - Addressed generated-document lint, reserved context names, empty secrets, missing context diagnostics, strict WhatIf mutation boundaries, portable test paths, output contracts, and automated-review findings discovered during integration. - Local validation: 83 Pester tests pass, PSScriptAnalyzer reports zero findings across `src` and `tests`, and `git diff --check` passes. - Exact-head Process-PSModule v6.1.13 CI succeeds on `9834688` (run `30180761797`), including Build-Site and all module-local suites across Linux, macOS, and Windows. - PSModule/docs PR #86 and Process-PSModule PR #419 are merged, making latest-LTS support and ternary allowance effective on their default branches. </details> <details> <summary>Relevant issues (or links)</summary> - Fixes #2 - #11 - #12 - #13 - #14 - #15 - PSModule/docs#86 - PSModule/Process-PSModule#419 </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 37f682e commit 4609ec2

44 files changed

Lines changed: 2369 additions & 164 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/mkdocs.yml

Lines changed: 0 additions & 81 deletions
This file was deleted.

.github/workflows/Process-PSModule.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ permissions:
2727

2828
jobs:
2929
Process-PSModule:
30-
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@205d193f34cbbaf9992955c21d842bcf98a1859f # v5.4.6
30+
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@fb1bdb8fefd243292f779d2a856a38db6fe6daf4 # v6.1.13
3131
secrets:
3232
APIKEY: ${{ secrets.APIKEY }}

.github/zensical.toml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
[project]
2+
site_name = "-{{ REPO_NAME }}-"
3+
repo_name = "-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-"
4+
repo_url = "https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-"
5+
6+
[project.theme]
7+
variant = "classic"
8+
language = "en"
9+
logo = "Assets/icon.png"
10+
favicon = "Assets/icon.png"
11+
features = [
12+
"navigation.instant",
13+
"navigation.instant.progress",
14+
"navigation.indexes",
15+
"navigation.top",
16+
"navigation.tracking",
17+
"navigation.expand",
18+
"search.suggest",
19+
"search.highlight",
20+
"content.code.copy"
21+
]
22+
23+
[[project.theme.palette]]
24+
media = "(prefers-color-scheme)"
25+
toggle.icon = "lucide/sun-moon"
26+
toggle.name = "Switch to dark mode"
27+
28+
[[project.theme.palette]]
29+
media = "(prefers-color-scheme: dark)"
30+
scheme = "slate"
31+
primary = "black"
32+
accent = "green"
33+
toggle.icon = "lucide/moon"
34+
toggle.name = "Switch to light mode"
35+
36+
[[project.theme.palette]]
37+
media = "(prefers-color-scheme: light)"
38+
scheme = "default"
39+
primary = "indigo"
40+
accent = "green"
41+
toggle.icon = "lucide/sun"
42+
toggle.name = "Switch to system preference"
43+
44+
[project.theme.icon]
45+
repo = "fontawesome/brands/github"
46+
47+
[project.markdown_extensions.toc]
48+
permalink = true
49+
50+
[project.markdown_extensions.attr_list]
51+
[project.markdown_extensions.admonition]
52+
[project.markdown_extensions.md_in_html]
53+
[project.markdown_extensions.pymdownx.details]
54+
[project.markdown_extensions.pymdownx.superfences]
55+
56+
[[project.extra.social]]
57+
icon = "fontawesome/brands/discord"
58+
link = "https://discord.gg/jedJWCPAhD"
59+
name = "-{{ REPO_OWNER }}- on Discord"
60+
61+
[[project.extra.social]]
62+
icon = "fontawesome/brands/github"
63+
link = "https://github.com/-{{ REPO_OWNER }}-/"
64+
name = "-{{ REPO_OWNER }}- on GitHub"
65+
66+
[project.extra.consent]
67+
title = "Cookie consent"
68+
description = "We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better."
69+
actions = ["accept", "reject"]

README.md

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,27 @@
1-
# {{ NAME }}
1+
# Domeneshop
22

3-
{{ DESCRIPTION }}
3+
Domeneshop is a PowerShell module for interacting with the Domeneshop API.
44

5-
## Prerequisites
5+
## Status
66

7-
This uses the following external resources:
8-
- The [PSModule framework](https://github.com/PSModule/Process-PSModule) for building, testing and publishing the module.
7+
The module provides a pre-1.0 API for storing Domeneshop credentials and working with domains, DNS records, HTTP forwards, dynamic DNS, and invoices. Command names and parameters may change before v1.0.0.
98

109
## Installation
1110

12-
To install the module from the PowerShell Gallery, you can use the following command:
13-
14-
```powershell
15-
Install-PSResource -Name {{ NAME }}
16-
Import-Module -Name {{ NAME }}
17-
```
18-
19-
## Usage
20-
21-
Here is a list of example that are typical use cases for the module.
22-
23-
### Example 1: Greet an entity
24-
25-
Provide examples for typical commands that a user would like to do with the module.
26-
27-
```powershell
28-
Greet-Entity -Name 'World'
29-
Hello, World!
30-
```
31-
32-
### Example 2
33-
34-
Provide examples for typical commands that a user would like to do with the module.
35-
3611
```powershell
37-
Import-Module -Name PSModuleTemplate
12+
Install-PSResource -Name Domeneshop
13+
Import-Module -Name Domeneshop
3814
```
3915

40-
### Find more examples
41-
42-
To find more examples of how to use the module, please refer to the [examples](examples) folder.
16+
## Commands
4317

44-
Alternatively, you can use the Get-Command -Module 'This module' to find more commands that are available in the module.
45-
To find examples of each of the commands you can use Get-Help -Examples 'CommandName'.
18+
- [Authentication](src/functions/public/Auth/Auth.md): Store credentials and select a default context.
19+
- [Domains](src/functions/public/Domains/Domains.md): List domains or retrieve one by ID.
20+
- [DNS](src/functions/public/Dns/Dns.md): List, add, update, and remove DNS records.
21+
- [HTTP forwards](src/functions/public/Forwards/Forwards.md): List, add, update, and remove forwards.
22+
- [Dynamic DNS](src/functions/public/Ddns/Ddns.md): Update a hostname with a supplied or detected address.
23+
- [Invoices](src/functions/public/Invoices/Invoices.md): List invoices or retrieve one by ID.
4624

4725
## Documentation
4826

49-
Link to further documentation if available, or describe where in the repository users can find more detailed documentation about
50-
the module's functions and features.
51-
52-
## Contributing
53-
54-
Coder or not, you can contribute to the project! We welcome all contributions.
55-
56-
### For Users
57-
58-
If you don't code, you still sit on valuable information that can make this project even better. If you experience that the
59-
product does unexpected things, throw errors or is missing functionality, you can help by submitting bugs and feature requests.
60-
Please see the issues tab on this project and submit a new issue that matches your needs.
61-
62-
### For Developers
63-
64-
If you do code, we'd love to have your contributions. Please read the [Contribution guidelines](CONTRIBUTING.md) for more information.
65-
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.
66-
67-
## Acknowledgements
68-
69-
Here is a list of people and projects that helped this project in some way.
27+
Each public command includes PowerShell help. After importing the module, run `Get-Help <CommandName> -Full` for parameter details and examples.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#Requires -Modules @{ ModuleName = 'Context'; ModuleVersion = '8.1.6' }
2+
3+
function Get-DomeneshopConfig {
4+
<#
5+
.SYNOPSIS
6+
Get the Domeneshop module configuration.
7+
8+
.DESCRIPTION
9+
Read the module configuration from the Context vault or return an in-memory default when no configuration has been stored.
10+
11+
.EXAMPLE
12+
Get-DomeneshopConfig
13+
14+
Get the current Domeneshop module configuration.
15+
16+
.INPUTS
17+
None
18+
19+
You can't pipe objects to Get-DomeneshopConfig.
20+
21+
.OUTPUTS
22+
System.Object
23+
24+
The stored or default Domeneshop module configuration.
25+
26+
.NOTES
27+
This read helper does not create or update Context vault entries.
28+
29+
.LINK
30+
https://psmodule.io/Domeneshop/Functions/Auth/Get-DomeneshopContext
31+
32+
.LINK
33+
https://psmodule.io/Context/
34+
#>
35+
[OutputType([object])]
36+
[CmdletBinding()]
37+
param()
38+
39+
$vault = 'Domeneshop'
40+
$id = '__Domeneshop.Config'
41+
$config = Get-Context -ID $id -Vault $vault
42+
43+
if (-not $config) {
44+
$config = [pscustomobject][ordered]@{
45+
DefaultContext = $null
46+
ApiBaseUri = 'https://api.domeneshop.no/v0'
47+
}
48+
}
49+
50+
$config
51+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
function Resolve-DomeneshopContext {
2+
<#
3+
.SYNOPSIS
4+
Validate a resolved Domeneshop context.
5+
6+
.DESCRIPTION
7+
Verify that a context resolved by a public command contains the credentials and API endpoint required by private helpers.
8+
9+
.EXAMPLE
10+
Resolve-DomeneshopContext -Context $storedContext
11+
12+
Validate and emit a stored Domeneshop context.
13+
14+
.INPUTS
15+
None
16+
17+
You can't pipe objects to Resolve-DomeneshopContext.
18+
19+
.OUTPUTS
20+
System.Object
21+
22+
The validated Domeneshop context.
23+
24+
.NOTES
25+
This helper never selects or defaults a context. Public commands own that behavior.
26+
27+
.LINK
28+
https://psmodule.io/Domeneshop/Functions/Auth/Get-DomeneshopContext
29+
30+
.LINK
31+
https://psmodule.io/Context/
32+
#>
33+
[OutputType([object])]
34+
[CmdletBinding()]
35+
param(
36+
# The context object selected by a public command.
37+
[Parameter(Mandatory)]
38+
[AllowNull()]
39+
[object] $Context
40+
)
41+
42+
if ($null -eq $Context) {
43+
throw "No Domeneshop context found. Run 'Connect-DomeneshopAccount' first."
44+
}
45+
46+
if ([string]::IsNullOrWhiteSpace([string] $Context.Token) -or -not ($Context.Secret -is [securestring])) {
47+
throw "The Domeneshop context [$($Context.ID)] is missing valid credentials."
48+
}
49+
50+
if ([string]::IsNullOrWhiteSpace([string] $Context.ApiBaseUri)) {
51+
throw "The Domeneshop context [$($Context.ID)] is missing an API base URI."
52+
}
53+
54+
$Context
55+
}

0 commit comments

Comments
 (0)