55*
66*/
77
8+ import { error } from "log/mod.ts" ;
9+
810import { Command } from "cliffy/command/mod.ts" ;
11+ import { prompt } from "cliffy/prompt/mod.ts" ;
12+ import { Select , SelectOption } from "cliffy/prompt/select.ts" ;
13+ import { Confirm } from "cliffy/prompt/confirm.ts" ;
14+ import {
15+ authorizeNetlifyAccessToken ,
16+ kNetlifyAuthTokenVar ,
17+ netlifyAccessToken ,
18+ netlifyEnvironmentAuthToken ,
19+ } from "../../publish/netlify/account.ts" ;
920import { netlifyPublish } from "../../publish/netlify/netlify.ts" ;
1021
1122import { PublishOptions , PublishProvider } from "./provider.ts" ;
23+ import { exitWithCleanup } from "../../core/cleanup.ts" ;
24+ import { AccessToken , ApiError } from "../../publish/netlify/api/index.ts" ;
1225
1326export const netlifyProvider : PublishProvider = {
1427 name : "netlify" ,
@@ -20,14 +33,149 @@ export const netlifyProvider: PublishProvider = {
2033 await netlifyConfigure ( {
2134 path : path || Deno . cwd ( ) ,
2235 render : ! ! options . render ,
36+ prompt : ! ! options . prompt ,
2337 } ) ;
2438 } ) ;
2539 } ,
2640 configure : netlifyConfigure ,
2741} ;
2842
29- async function netlifyConfigure ( options : PublishOptions ) {
30- console . log ( "netlify" ) ;
31- console . log ( options ) ;
32- await netlifyPublish ( ) ;
43+ const kEnvToken = "env-token" ;
44+ const kAuthorizedToken = "authorized-token" ;
45+ const kAuthorize = "authorize" ;
46+
47+ async function netlifyConfigure ( options : PublishOptions ) : Promise < void > {
48+ // see what tyep of token we are going to use
49+ let token : string | undefined ;
50+ let tokenType : "env-token" | "authorized-token" | undefined ;
51+ const envToken = netlifyEnvironmentAuthToken ( ) ;
52+ const accessToken = netlifyAccessToken ( ) ;
53+ const authorizedToken = accessToken ?. access_token ;
54+
55+ // if we aren't prompting then we need to have one at the ready
56+ if ( ! options . prompt ) {
57+ token = envToken || authorizedToken ;
58+ if ( ! token ) {
59+ error (
60+ `No existing account available (account required for publish with --no-prompt)` ,
61+ ) ;
62+ }
63+ } else {
64+ // build list of selection options
65+
66+ const options : SelectOption [ ] = [ ] ;
67+ if ( envToken ) {
68+ options . push ( {
69+ name : `${ kNetlifyAuthTokenVar } ` ,
70+ value : kEnvToken ,
71+ } ) ;
72+ }
73+ if ( authorizedToken ) {
74+ options . push ( {
75+ name : `${ accessToken . email ! } ` ,
76+ value : kAuthorizedToken ,
77+ } ) ;
78+ }
79+ if ( options . length > 0 ) {
80+ options . push ( {
81+ name : "Use another account..." ,
82+ value : kAuthorize ,
83+ } ) ;
84+
85+ const result = await prompt ( [ {
86+ name : "token" ,
87+ message : "Netlify account:" ,
88+ options,
89+ type : Select ,
90+ } ] ) ;
91+ switch ( result . token ) {
92+ case kEnvToken : {
93+ token = envToken ;
94+ tokenType = kEnvToken ;
95+ break ;
96+ }
97+ case kAuthorizedToken : {
98+ token = authorizedToken ;
99+ tokenType = kAuthorizedToken ;
100+ break ;
101+ }
102+ case kAuthorize : {
103+ tokenType = kAuthorizedToken ;
104+ }
105+ }
106+ }
107+
108+ // if we don't have a token yet we need to authorize
109+ if ( ! token ) {
110+ const result = await prompt ( [ {
111+ name : "confirmed" ,
112+ message : "Authorize account" ,
113+ default : true ,
114+ hint :
115+ "In order to publish to Netlify with Quarto you need to authorize your account.\n" +
116+ " Please be sure you are logged into the correct Netlify account in your default\n" +
117+ " web browser, then press Enter to authorize." ,
118+ type : Confirm ,
119+ } ] ) ;
120+ if ( ! result . confirmed ) {
121+ exitWithCleanup ( 1 ) ;
122+ }
123+
124+ // do the authorization
125+ token = ( await authorizeNetlifyAccessToken ( ) ) ?. access_token ;
126+ }
127+ }
128+
129+ // publish if we have a token
130+ if ( token ) {
131+ try {
132+ await netlifyPublish ( {
133+ token,
134+ } ) ;
135+ } catch ( error ) {
136+ // attempt to recover from unauthorized
137+ if ( error instanceof ApiError && error . status === 401 ) {
138+ await handleUnauthorized ( tokenType ! , options , accessToken ) ;
139+ } else {
140+ throw error ;
141+ }
142+ }
143+ }
144+ }
145+
146+ async function handleUnauthorized (
147+ tokenType : string ,
148+ options : PublishOptions ,
149+ accessToken ?: AccessToken ,
150+ ) {
151+ if ( tokenType === kEnvToken ) {
152+ error (
153+ `Unable to authenticate with the provided ${ kNetlifyAuthTokenVar } . Please be sure this token is valid.` ,
154+ ) ;
155+ exitWithCleanup ( 1 ) ;
156+ } else if ( tokenType === kAuthorizedToken && accessToken ) {
157+ const result = await prompt ( [ {
158+ name : "confirmed" ,
159+ message : "Re-authorize account" ,
160+ default : true ,
161+ hint :
162+ `The authorization saved for account ${ accessToken . email } is no longer valid.\n` +
163+ " Please be sure you are logged into the correct Netlify account in your\n" +
164+ " default web browser, then press Enter to re-authorize." ,
165+ type : Confirm ,
166+ } ] ) ;
167+ if ( ! result . confirmed ) {
168+ exitWithCleanup ( 1 ) ;
169+ }
170+
171+ // do the authorization then re-try
172+ if ( ( await authorizeNetlifyAccessToken ( ) ) ) {
173+ await netlifyConfigure ( options ) ;
174+ return ;
175+ }
176+ }
177+
178+ // default error
179+ error ( "Unable to publish to Netlify (unauthorized)" ) ;
180+ exitWithCleanup ( 1 ) ;
33181}
0 commit comments