feat(export): add -Prefix parameter to Export-InfisicalSecrets

Adds an optional [string] -Prefix parameter that prepends the supplied
string to every emitted variable name, regardless of -Format
(Json/Yaml/Xml/Env/EnvironmentVariables). When omitted or empty the
exporter buffer is forwarded unchanged (no-op).

Implementation clones each InfisicalSecret with SecretName = Prefix +
SecretName so the caller's pipeline objects are never mutated; the
SecureString and Tags/SecretMetadata array references are shared
(read-only usage downstream).

Also updates the cmdlet help XML description + adds a -Prefix example,
and reflects the new parameter in docs/DesignSpec.md.
This commit is contained in:
GraceSolutions
2026-06-06 17:37:56 -04:00
parent 0fdafeca72
commit 318db70480
3 changed files with 44 additions and 3 deletions
@@ -37,6 +37,9 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter]
public InfisicalExportEncoding Encoding { get; set; } = InfisicalExportEncoding.UTF8;
[Parameter]
public string Prefix { get; set; }
private readonly List<InfisicalSecret> _buffer = new List<InfisicalSecret>();
protected override void ProcessRecord()
@@ -68,7 +71,7 @@ namespace PSInfisicalAPI.Cmdlets
InfisicalExportRequest request = new InfisicalExportRequest
{
Secrets = _buffer.ToArray(),
Secrets = ApplyPrefix(_buffer, Prefix),
Format = Format,
Path = Path,
Scope = Scope,
@@ -85,6 +88,38 @@ namespace PSInfisicalAPI.Cmdlets
}
}
private static InfisicalSecret[] ApplyPrefix(List<InfisicalSecret> source, string prefix)
{
if (string.IsNullOrEmpty(prefix)) { return source.ToArray(); }
InfisicalSecret[] result = new InfisicalSecret[source.Count];
for (int i = 0; i < source.Count; i++)
{
InfisicalSecret original = source[i];
result[i] = new InfisicalSecret
{
Id = original.Id,
InternalId = original.InternalId,
Workspace = original.Workspace,
Environment = original.Environment,
Version = original.Version,
Type = original.Type,
SecretName = string.Concat(prefix, original.SecretName),
SecretValue = original.SecretValue,
SecretValueHidden = original.SecretValueHidden,
SecretPath = original.SecretPath,
SecretComment = original.SecretComment,
CreatedAtUtc = original.CreatedAtUtc,
UpdatedAtUtc = original.UpdatedAtUtc,
IsRotatedSecret = original.IsRotatedSecret,
RotationId = original.RotationId,
Tags = original.Tags,
SecretMetadata = original.SecretMetadata
};
}
return result;
}
private static Encoding ResolveEncoding(InfisicalExportEncoding encoding)
{
switch (encoding)