11import { appendFileSync } from "fs" ;
22
33import { Octokit } from "@octoherd/octokit" ;
4+ import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device" ;
45import chalk from "chalk" ;
56import tempy from "tempy" ;
7+ import clipboardy from "clipboardy" ;
8+ import enquirer from "enquirer" ;
69
710import { cache as octokitCachePlugin } from "./lib/octokit-plugin-cache.js" ;
811import { requestLog } from "./lib/octokit-plugin-request-log.js" ;
@@ -48,8 +51,38 @@ export async function octoherd(
4851 if ( typeof octoherdCache === "string" ) plugins . push ( octokitCachePlugin ) ;
4952 const CliOctokit = Octokit . plugin ( ...plugins ) ;
5053
54+ const authOptions = octoherdToken
55+ ? { auth : octoherdToken }
56+ : {
57+ authStrategy : createOAuthDeviceAuth ,
58+ auth : {
59+ // Octoherd's OAuth App
60+ clientId : "e93735961b3b72ca5c02" ,
61+ clientType : "oauth-app" ,
62+ scopes : [ "repo" ] ,
63+ async onVerification ( { verification_uri, user_code } ) {
64+ console . log ( "Open %s" , verification_uri ) ;
65+
66+ await clipboardy . write ( user_code ) ;
67+ console . log ( "Paste code: %s (copied to your clipboard)" , user_code ) ;
68+
69+ console . log (
70+ `\n${ chalk . gray (
71+ "To avoid this prompt, pass a token with --octoherd-token or -T"
72+ ) } \n`
73+ ) ;
74+
75+ const prompt = new enquirer . Input ( {
76+ message : "Press <enter> when ready" ,
77+ } ) ;
78+
79+ await prompt . run ( ) ;
80+ } ,
81+ } ,
82+ } ;
83+
5184 const octokit = new CliOctokit ( {
52- auth : octoherdToken ,
85+ ... authOptions ,
5386 userAgent : [ "octoherd-cli" , VERSION ] . join ( "/" ) ,
5487 octoherd : {
5588 debug : octoherdDebug ,
@@ -81,6 +114,10 @@ export async function octoherd(
81114 throw new Error ( "[octoherd] No repositories provided" ) ;
82115 }
83116
117+ // trigger OAuth Device Flow before loading repositories
118+ // It's not necessary, but a better UX
119+ await octokit . auth ( { type : "oauth-user" } ) ;
120+
84121 const state = {
85122 log : console ,
86123 octokit,
@@ -98,8 +135,8 @@ export async function octoherd(
98135 ) ;
99136
100137 try {
101- const { id, owner, name } = repository
102- octokit . log . setContext ( { repository : { id, owner, name } } )
138+ const { id, owner, name } = repository ;
139+ octokit . log . setContext ( { repository : { id, owner, name } } ) ;
103140 await octoherdScript ( octokit , repository , userOptions ) ;
104141 } catch ( error ) {
105142 if ( ! error . cancel ) throw error ;
0 commit comments