Skip to content

Commit 13b5e74

Browse files
⚙️ [Maintenance]: Split module archetypes guidance (#66)
Module archetype guidance now documents Integration and Data modules with flexible transport and Context patterns. The guidance clarifies design choices for exposing or hiding transport abstractions, Context functions for targeting environments, and the ConvertFrom/ConvertTo data flow directions. ## New: Module archetype guidance PSModule modules fall into two standardized archetypes. The new Module-Types.md page documents: - **Integration (API) modules**: Wrap external services via REST or GraphQL. Commands map to resources and intents, not HTTP methods. Transport abstractions (REST/GraphQL functions) may be private, public, or combined with public Context depending on audience needs. - **Data modules**: Convert between data format representations and PowerShell objects. Conversion always flows through PSCustomObject as the neutral pivot, with ConvertFrom and ConvertTo functions moving bidirectionally. ## Changed: Transport abstraction is flexible, not prescriptive Transport, REST methods, and GraphQL functions do not have to be private. Modules now document three strategies: - **Private transport** (common): Keep REST/GraphQL helpers private. Public functions accept resolved inputs and typed objects. Follows Dependency Inversion at the network boundary. - **Public transport**: Expose REST or GraphQL functions for power users or module composition. - **Public Context**: Expose Context functions so users can configure and target specific contexts and environments directly. Module authors choose the strategy that best serves their audience. ## Changed: Context modules must expose functions and object types The Context module provides on-disk storage for user data and secrets organized by context and environment. Modules must expose functions and object types so users can programmatically target specific contexts and environments. Users need to select which environment or context their functions operate against. ## Improved: ConvertFrom/ConvertTo data flow clarity The verb vocabulary table now explicitly shows data flow directions: - **ConvertFrom-<Format>**: Format-specific input → PSCustomObject - **ConvertTo-<Format>**: PSCustomObject → Format-specific output ## Technical Details - Added `src/docs/Modules/Module-Types.md` with Integration and Data archetype guidance. - Updated `src/docs/Modules/index.md` with module section links. - Added cross-link from Repository-Defaults.md to module types. - Updated site navigation in `src/zensical.toml`. - Split from PR #61 to isolate module archetype guidance from README policy and onboarding defaults.
1 parent 24fb680 commit 13b5e74

4 files changed

Lines changed: 109 additions & 1 deletion

File tree

src/docs/Modules/Module-Types.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Module types
2+
3+
Most PSModule modules fall into one of a few archetypes. The general rules in
4+
[PowerShell module standard](Standards.md) and [PowerShell Standards](../PowerShell/Standard/index.md) always apply; this
5+
page adds the conventions that are specific to a module's type so that modules of the same kind feel
6+
the same to use.
7+
8+
Two archetypes have enough shared shape to standardize:
9+
10+
- **Integration (API) modules** wrap an external service's REST or GraphQL API.
11+
- **Data modules** convert or manage a data format or in-memory structure.
12+
13+
A module can be both (for example, an integration module that also exposes conversion helpers).
14+
Apply each relevant section.
15+
16+
## Integration (API) modules
17+
18+
Integration modules are the PowerShell face of an external service. `GitHub`, and the
19+
service-client modules such as `Anthropic`, `OpenAI`, `Bluesky`, and `Domeneshop`, are integration
20+
modules.
21+
22+
### Command naming maps to the resource, not the HTTP method
23+
24+
Name commands after the resource and the intent, using approved verbs. Never name a command after
25+
the HTTP method or the endpoint path. Map REST methods to verbs:
26+
27+
| REST method | PowerShell verb | Example |
28+
| ----------- | --------------- | ------- |
29+
| `GET` | `Get-` | `Get-GitHubRepository` |
30+
| `POST` (create) | `New-` / `Add-` | `New-GitHubRepository` |
31+
| `PUT` / `PATCH` (update) | `Set-` / `Update-` | `Set-GitHubRepository` |
32+
| `DELETE` | `Remove-` | `Remove-GitHubRepository` |
33+
| Non-CRUD action | Approved verb for the intent | `Invoke-`, `Start-`, `Stop-`, `Enable-`, ... |
34+
35+
Prefix the noun with the service's term of art (`GitHubRepository`, not `Repository`).
36+
37+
### Transport abstraction
38+
39+
Lower-level helpers own the concrete `Invoke-RestMethod` / GraphQL / HTTP calls. How you expose
40+
or hide this abstraction is a design choice:
41+
42+
- **Private transport** (common): Keep REST, GraphQL, and HTTP helpers private. Public functions
43+
accept resolved inputs and typed objects. This follows the Dependency Inversion rule from
44+
[Standards](Standards.md#solid-applied) applied to the network boundary.
45+
- **Public transport**: Expose REST or GraphQL functions publicly for power users or module
46+
composition.
47+
- **Public Context**: Expose the `Context` module as public so users can configure and manage
48+
module state, secrets, and settings directly.
49+
50+
Choose the strategy that best serves your module's audience.
51+
52+
### Use Context for user and module settings
53+
54+
Integration modules persist state with the [`Context`](https://github.com/PSModule/Context) module
55+
rather than inventing bespoke storage. Context provides on-disk storage for user data and secrets,
56+
organized by context and environment. Two kinds of state are both standard:
57+
58+
- **User settings and secrets**: accounts, tokens, sessions, and per-user configuration. Store these
59+
in a per-user context. `Context` encrypts secrets at rest (via `Sodium`), so a user can resume work
60+
without reconfiguring or logging in again when the service supports session refresh.
61+
- **Module settings**: module-wide defaults, endpoints, and feature flags that are not tied to a
62+
single user. Store these in a module-scoped context.
63+
64+
Your module must expose functions and object types so users can target specific contexts and
65+
environments. Users need to be able to read from, write to, and manage contexts programmatically,
66+
selecting which environment or context their functions operate against. Persisting both through
67+
`Context` gives every integration module the same, discoverable settings model and keeps secrets
68+
out of source, logs, and plain files.
69+
70+
## Data modules
71+
72+
Data modules convert between representations or manage an in-memory structure. `Hashtable` is the
73+
reference shape; `Base64`, `Json`, `Lua`, `Hcl`, `Sodium`, and `Uri` follow the same pattern.
74+
75+
### The neutral object is the pivot
76+
77+
Every conversion goes through the neutral PowerShell object model
78+
(`[PSCustomObject]` / `[hashtable]` / `[PSObject]`). `ConvertFrom-<Format>` parses a
79+
format-specific representation into an object; `ConvertTo-<Format>` renders an object into the
80+
format. Converting through the object as a common pivot means any format interoperates with any
81+
other, instead of writing a direct converter for every pair.
82+
83+
Always ship both directions so data can round-trip between the format and the object model.
84+
85+
### Verb vocabulary
86+
87+
| Verb pattern | Purpose |
88+
| ------------ | ------- |
89+
| `ConvertFrom-<Format>` | Format-specific text/representation → `[PSCustomObject]` / `[hashtable]` |
90+
| `ConvertTo-<Format>` | `[PSCustomObject]` / `[hashtable]` → format-specific text/representation |
91+
| `Import-<Noun>` | Read from a file or store into objects |
92+
| `Export-<Noun>` | Write objects to a file or store |
93+
| `Format-<Noun>` | Produce a normalized or pretty rendering |
94+
| `Merge-<Noun>` | Combine two structures |
95+
| `Compare-<Noun>` | Diff two structures |
96+
| `Test-<Noun>` | Validate a value or structure |
97+
| `Remove-<Noun>Entry` | Remove elements by criteria |
98+
99+
The `Hashtable` module demonstrates the full set: `ConvertFrom-Hashtable`, `ConvertTo-Hashtable`,
100+
`Import-Hashtable`, `Export-Hashtable`, `Format-Hashtable`, `Merge-Hashtable`, and
101+
`Remove-HashtableEntry`.
102+
103+
## Where this connects
104+
105+
- [PowerShell module standard](Standards.md): layout, private functions, and the mandatory context parameter.
106+
- [Repository Defaults](Repository-Defaults.md): repository files, README shape, and agent onboarding.

src/docs/Modules/Repository-Defaults.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This page defines the default repository contract for PowerShell module repositories in the PSModule organization. It describes what a newly created or maintained module repository should look like before module-specific code, tests, documentation, and managed repository files are considered.
44

5-
The implementation standard still lives in [PowerShell module standard](Standards.md). This page covers repository defaults: files, metadata, README shape, release integration, placeholder handling, shared community files, and managed-file distribution.
5+
The implementation standard still lives in [PowerShell module standard](Standards.md). Type-specific conventions for integration (API) and data modules live in [Module types](Module-Types.md). This page covers repository defaults: files, metadata, README shape, release integration, placeholder handling, shared community files, and managed-file distribution.
66

77
## Scope
88

src/docs/Modules/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This section is the local source of truth for:
1313

1414
- [Repository Defaults](Repository-Defaults.md)
1515
- [Standards](Standards.md)
16+
- [Module types](Module-Types.md)
1617
- [Test Specification](Test-Specification.md)
1718
- [Versioning](Versioning.md)
1819
- [Catalog](Catalog/index.md)

src/zensical.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ nav = [
2121
"Modules/index.md",
2222
{"Repository Defaults" = "Modules/Repository-Defaults.md"},
2323
{"Standards" = "Modules/Standards.md"},
24+
{"Module types" = "Modules/Module-Types.md"},
2425
{"Test Specification" = "Modules/Test-Specification.md"},
2526
{"Versioning" = "Modules/Versioning.md"},
2627
{"Catalog" = [

0 commit comments

Comments
 (0)