Skip to content

Commit 8d148a4

Browse files
State module type conventions in concrete terms
1 parent 64ffb1d commit 8d148a4

1 file changed

Lines changed: 45 additions & 45 deletions

File tree

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
11
# Module types
22

3-
Most PSModule modules fall into one of a few archetypes. The general rules in
4-
[PowerShell module standard](powershell-module-standard.md) and [MSX PowerShell Standards](https://msx.no/docs/Coding-Standards/PowerShell/) 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.
3+
Most PSModule modules use one or both of the module types below. The general rules in
4+
[PowerShell module standard](powershell-module-standard.md) and [MSX PowerShell Standards](https://msx.no/docs/Coding-Standards/PowerShell/)
5+
always apply. This page defines additional conventions for each module type.
76

8-
Two archetypes have enough shared shape to standardize:
7+
The module types are:
98

10-
- **Integration (API) modules** wrap an external service's REST or GraphQL API.
9+
- **Integration (API) modules** provide PowerShell commands for an external service's REST or GraphQL API.
1110
- **Data modules** convert or manage a data format or in-memory structure.
1211

13-
A module can be both (for example, an integration module that also exposes conversion helpers).
14-
Apply each relevant section.
12+
A module can serve both roles. For example, an integration module can also provide conversion helpers. Apply each relevant section.
1513

1614
## Integration (API) modules
1715

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.
16+
Integration modules provide PowerShell commands for an external service. `GitHub` and the
17+
service-client modules `Anthropic`, `OpenAI`, `Bluesky`, and `Domeneshop` are integration modules.
2118

2219
### Command naming maps to the resource, not the HTTP method
2320

24-
Name commands after the resource and the intent, using approved verbs. Never name a command after
21+
Name commands after the resource and the intended operation. Use approved verbs. Never name a command after
2522
the HTTP method or the endpoint path. Map REST methods to verbs:
2623

2724
| REST method | PowerShell verb | Example |
@@ -32,75 +29,78 @@ the HTTP method or the endpoint path. Map REST methods to verbs:
3229
| `DELETE` | `Remove-` | `Remove-GitHubRepository` |
3330
| Non-CRUD action | Approved verb for the intent | `Invoke-`, `Start-`, `Stop-`, `Enable-`, ... |
3431

35-
Prefix the noun with the service's term of art (`GitHubRepository`, not `Repository`).
32+
Prefix the noun with the service-specific term (`GitHubRepository`, not `Repository`).
3633

3734
### Transport abstraction
3835

39-
Lower-level helpers own the concrete `Invoke-RestMethod` / GraphQL / HTTP calls. How you expose
40-
or hide this abstraction is a design choice:
36+
Helper functions make the `Invoke-RestMethod`, GraphQL, or HTTP calls. Choose how to expose the transport and module state:
4137

4238
- **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](powershell-module-standard.md#solid-applied) applied to the network boundary.
45-
- **Public transport**: Expose REST or GraphQL functions publicly for power users or module
39+
accept resolved inputs and typed objects. This applies the Dependency Inversion rule from
40+
[Standards](powershell-module-standard.md#solid-applied) to network calls.
41+
- **Public transport**: Expose REST or GraphQL functions publicly for advanced users or module
4642
composition.
47-
- **Public Context**: Expose the `Context` module as public so users can configure and manage
43+
- **Public Context**: Expose the `Context` module so users can configure and manage
4844
module state, secrets, and settings directly.
4945

50-
Choose the strategy that best serves your module's audience.
46+
Choose the strategy for the module's intended users.
5147

5248
### Use Context for user and module settings
5349

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:
50+
Integration modules use the [`Context`](https://github.com/PSModule/Context) module to store state instead of a separate storage implementation.
51+
Context stores user data and secrets on disk, organized by context and environment. It supports two standard kinds of state:
5752

5853
- **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.
54+
in a per-user context. `Context` encrypts stored secrets with `Sodium`.
55+
If the service supports session refresh, users can resume work without new configuration or another login.
6156
- **Module settings**: module-wide defaults, endpoints, and feature flags that are not tied to a
6257
single user. Store these in a module-scoped context.
6358

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.
59+
Your module must expose functions and object types for specific contexts and environments.
60+
Users must be able to read, write, and manage contexts programmatically.
61+
They must be able to select the environment or context that their functions use.
62+
Use `Context` for both kinds of state to give integration modules the same settings model.
63+
Keep secrets out of source code, logs, and unencrypted files.
6964

7065
## Data modules
7166

7267
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.
68+
reference implementation. `Base64`, `Json`, `Lua`, `Hcl`, `Sodium`, and `Uri` follow the same pattern.
7469

75-
### The neutral object is the pivot
70+
<a id="the-neutral-object-is-the-pivot"></a>
7671

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.
72+
### Conversions use the neutral object model
8273

83-
Always ship both directions so data can round-trip between the format and the object model.
74+
Every conversion uses the neutral PowerShell object model
75+
(`[PSCustomObject]` / `[hashtable]` / `[PSObject]`) as the intermediate representation.
76+
`ConvertFrom-<Format>` parses a format-specific representation into an object.
77+
`ConvertTo-<Format>` converts an object into the target format.
78+
79+
To convert between formats, first convert the source representation to an object.
80+
Then convert the object to the target format.
81+
The common object model removes the need for a separate converter for each pair of formats.
82+
83+
Always provide both conversion directions so users can convert from a format to an object and back.
8484

8585
### Verb vocabulary
8686

8787
| Verb pattern | Purpose |
8888
| ------------ | ------- |
8989
| `ConvertFrom-<Format>` | Format-specific text/representation → `[PSCustomObject]` / `[hashtable]` |
9090
| `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 |
91+
| `Import-<Noun>` | Read objects from a file or data store |
92+
| `Export-<Noun>` | Write objects to a file or data store |
93+
| `Format-<Noun>` | Produce a normalized or human-readable representation |
9494
| `Merge-<Noun>` | Combine two structures |
95-
| `Compare-<Noun>` | Diff two structures |
95+
| `Compare-<Noun>` | Identify differences between two structures |
9696
| `Test-<Noun>` | Validate a value or structure |
97-
| `Remove-<Noun>Entry` | Remove elements by criteria |
97+
| `Remove-<Noun>Entry` | Remove elements that match specified criteria |
9898

99-
The `Hashtable` module demonstrates the full set: `ConvertFrom-Hashtable`, `ConvertTo-Hashtable`,
99+
The `Hashtable` module demonstrates `ConvertFrom-Hashtable`, `ConvertTo-Hashtable`,
100100
`Import-Hashtable`, `Export-Hashtable`, `Format-Hashtable`, `Merge-Hashtable`, and
101101
`Remove-HashtableEntry`.
102102

103103
## Where this connects
104104

105105
- [PowerShell module standard](powershell-module-standard.md): layout, private functions, and the mandatory context parameter.
106-
- [Repository Standard](repository-standard.md): repository files, README shape, and agent onboarding.
106+
- [Repository Standard](repository-standard.md): repository files, README content, and instructions for agents.

0 commit comments

Comments
 (0)