@@ -27,10 +27,10 @@ class CommandEdit extends CommandPolykey {
2727 const secretPath = fullSecretPath [ 1 ] ?? '/' ;
2828 const os = await import ( 'os' ) ;
2929 const { spawn } = await import ( 'child_process' ) ;
30- const vaultsErrors = await import ( 'polykey/dist/vaults/errors' ) ;
3130 const { default : PolykeyClient } = await import (
3231 'polykey/dist/PolykeyClient'
3332 ) ;
33+ const { never } = await import ( 'polykey/dist/utils' ) ;
3434 const clientOptions = await binProcessors . processClientOptions (
3535 options . nodePath ,
3636 options . nodeId ,
@@ -65,40 +65,58 @@ class CommandEdit extends CommandPolykey {
6565 const tmpFile = path . join ( tmpDir , path . basename ( secretPath ) ) ;
6666 const secretExists = await binUtils . retryAuthentication (
6767 async ( auth ) => {
68- let exists = true ;
69- const response = await pkClient . rpcClient . methods . vaultsSecretsGet ( {
68+ let exists = false ;
69+ const response =
70+ await pkClient . rpcClient . methods . vaultsSecretsCat ( ) ;
71+ const writer = response . writable . getWriter ( ) ;
72+ await writer . write ( {
7073 nameOrId : vaultName ,
7174 secretName : secretPath ,
7275 metadata : auth ,
7376 } ) ;
77+ await writer . close ( ) ;
78+ const fd = await fs . promises . open ( tmpFile , 'a' ) ;
7479 try {
75- let rawSecretContent : string = '' ;
76- for await ( const chunk of response ) {
77- rawSecretContent += chunk . secretContent ;
78- }
79- const secretContent = Buffer . from ( rawSecretContent , 'binary' ) ;
80- await this . fs . promises . writeFile ( tmpFile , secretContent ) ;
81- } catch ( e ) {
82- const [ cause , _ ] = binUtils . remoteErrorCause ( e ) ;
83- if ( cause instanceof vaultsErrors . ErrorSecretsSecretUndefined ) {
84- exists = false ;
85- } else if (
86- cause instanceof vaultsErrors . ErrorSecretsIsDirectory
87- ) {
88- // First, write the inline error to standard error like other
89- // secrets commands do.
90- process . stderr . write (
91- `edit: ${ secretPath } : No such file or directory\n` ,
92- ) ;
93- // Then, throw an error to get the non-zero exit code. As this
94- // command is Polykey-specific, the code doesn't really matter
95- // that much.
96- throw new errors . ErrorPolykeyCLIEditSecret (
97- 'Failed to edit secret' ,
98- ) ;
99- } else {
100- throw e ;
80+ for await ( const chunk of response . readable ) {
81+ const type = chunk . type ;
82+ switch ( type ) {
83+ case 'SuccessMessage' :
84+ exists = true ;
85+ await fd . write ( Buffer . from ( chunk . secretContent , 'binary' ) ) ;
86+ break ;
87+ case 'ErrorMessage' :
88+ switch ( chunk . code ) {
89+ case 'ENOENT' :
90+ // Do nothing if we get ENOENT. We need a case to avoid
91+ // this value hitting the default case.
92+ break ;
93+ case 'EISDIR' :
94+ // First, write the inline error to standard error like
95+ // other secrets commands do.
96+ process . stderr . write (
97+ `edit: ${ secretPath } : No such file or directory\n` ,
98+ ) ;
99+ // Then, throw an error to get the non-zero exit code.
100+ // As this command is Polykey-specific, the code doesn't
101+ // really matter that much.
102+ throw new errors . ErrorPolykeyCLIEditSecret (
103+ 'The specified secret cannot be edited' ,
104+ ) ;
105+ default :
106+ throw new errors . ErrorPolykeyCLIEditSecret (
107+ `Unexpected error value returned: ${ chunk . code } ` ,
108+ ) ;
109+ }
110+ break ;
111+ default :
112+ never (
113+ `Expected "SuccessMessage" or "ContentMessage", got ${ type } ` ,
114+ ) ;
115+ }
101116 }
117+ } finally {
118+ await fd . close ( ) ;
119+ if ( ! exists ) await fs . promises . rm ( tmpFile ) ;
102120 }
103121 return exists ;
104122 } ,
0 commit comments