@@ -229,9 +229,17 @@ export const secretPutCommand = createCommand({
229229
230230 try {
231231 await submitSecret ( ) ;
232- metrics . sendMetricsEvent ( "create encrypted variable" , {
233- sendMetrics : config . send_metrics ,
234- } ) ;
232+ metrics . sendMetricsEvent (
233+ "create encrypted variable" ,
234+ {
235+ secretOperation : "single" ,
236+ secretSource : isInteractive ? "interactive" : "stdin" ,
237+ hasEnvironment : Boolean ( args . env ) ,
238+ } ,
239+ {
240+ sendMetrics : config . send_metrics ,
241+ }
242+ ) ;
235243 } catch ( e ) {
236244 if ( isWorkerNotFoundError ( e ) ) {
237245 // create a draft worker and try again
@@ -449,12 +457,14 @@ export const secretBulkCommand = createCommand({
449457 } `
450458 ) ;
451459
452- const content = await parseBulkInputToObject ( args . file ) ;
460+ const result = await parseBulkInputToObject ( args . file ) ;
453461
454- if ( ! content ) {
462+ if ( ! result ) {
455463 return logger . error ( `🚨 No content found in file, or piped input.` ) ;
456464 }
457465
466+ const { content, secretSource, secretFormat } = result ;
467+
458468 function getSettings ( ) {
459469 const url = isServiceEnv
460470 ? `/accounts/${ accountId } /workers/services/${ scriptName } /environments/${ args . env } /settings`
@@ -487,13 +497,13 @@ export const secretBulkCommand = createCommand({
487497 } catch ( e ) {
488498 if ( isWorkerNotFoundError ( e ) ) {
489499 // create a draft worker before patching
490- const result = await createDraftWorker ( {
500+ const draftWorkerResult = await createDraftWorker ( {
491501 config,
492502 args : args ,
493503 accountId,
494504 scriptName,
495505 } ) ;
496- if ( result === null ) {
506+ if ( draftWorkerResult === null ) {
497507 return ;
498508 }
499509 existingBindings = [ ] ;
@@ -534,6 +544,18 @@ export const secretBulkCommand = createCommand({
534544 logger . log ( "" ) ;
535545 logger . log ( "Finished processing secrets file:" ) ;
536546 logger . log ( `✨ ${ upsertBindings . length } secrets successfully uploaded` ) ;
547+ metrics . sendMetricsEvent (
548+ "create encrypted variable" ,
549+ {
550+ secretOperation : "bulk" ,
551+ secretSource,
552+ secretFormat,
553+ hasEnvironment : Boolean ( args . env ) ,
554+ } ,
555+ {
556+ sendMetrics : config . send_metrics ,
557+ }
558+ ) ;
537559 } catch ( err ) {
538560 logger . log ( "" ) ;
539561 logger . log ( `🚨 Secrets failed to upload` ) ;
@@ -561,16 +583,39 @@ export function validateFileSecrets(
561583 }
562584}
563585
564- export async function parseBulkInputToObject ( input ?: string ) {
586+ /** Error thrown when no input is provided to parseBulkInputToObject */
587+ export class NoInputError extends Error {
588+ constructor ( ) {
589+ super ( "No input provided" ) ;
590+ this . name = "NoInputError" ;
591+ }
592+ }
593+
594+ /** Result from parsing bulk secret input, including metadata for analytics */
595+ export type BulkInputResult = {
596+ content : Record < string , string > ;
597+ secretSource : "file" | "stdin" ;
598+ secretFormat : "json" | "dotenv" ;
599+ } ;
600+
601+ export async function parseBulkInputToObject (
602+ input ?: string
603+ ) : Promise < BulkInputResult | undefined > {
565604 let content : Record < string , string > ;
605+ let secretSource : "file" | "stdin" ;
606+ let secretFormat : "json" | "dotenv" ;
607+
566608 if ( input ) {
609+ secretSource = "file" ;
567610 const jsonFilePath = path . resolve ( input ) ;
568611 try {
569612 const fileContent = readFileSync ( jsonFilePath ) ;
570613 try {
571614 content = parseJSON ( fileContent ) as Record < string , string > ;
615+ secretFormat = "json" ;
572616 } catch ( e ) {
573617 content = dotenvParse ( fileContent ) ;
618+ secretFormat = "dotenv" ;
574619 // dotenvParse does not error unless fileContent is undefined, no keys === error
575620 if ( Object . keys ( content ) . length === 0 ) {
576621 throw e ;
@@ -583,6 +628,7 @@ export async function parseBulkInputToObject(input?: string) {
583628 }
584629 validateFileSecrets ( content , input ) ;
585630 } else {
631+ secretSource = "stdin" ;
586632 try {
587633 const rl = readline . createInterface ( { input : process . stdin } ) ;
588634 let pipedInput = "" ;
@@ -591,8 +637,10 @@ export async function parseBulkInputToObject(input?: string) {
591637 }
592638 try {
593639 content = parseJSON ( pipedInput ) as Record < string , string > ;
640+ secretFormat = "json" ;
594641 } catch ( e ) {
595642 content = dotenvParse ( pipedInput ) ;
643+ secretFormat = "dotenv" ;
596644 // dotenvParse does not error unless fileContent is undefined, no keys === error
597645 if ( Object . keys ( content ) . length === 0 ) {
598646 throw e ;
@@ -602,5 +650,5 @@ export async function parseBulkInputToObject(input?: string) {
602650 return ;
603651 }
604652 }
605- return content ;
653+ return { content, secretSource , secretFormat } ;
606654}
0 commit comments