1- import { mkdir } from "fs/promises" ;
2- import { logRaw , space , status , updateStatus } from "@cloudflare/cli" ;
1+ import { space , updateStatus } from "@cloudflare/cli" ;
32import { brandColor , dim } from "@cloudflare/cli/colors" ;
43import { inputPrompt , spinner } from "@cloudflare/cli/interactive" ;
54import {
65 ApiError ,
76 DeploymentMutationError ,
87 OpenAPI ,
98} from "@cloudflare/containers-shared" ;
10- import { version as wranglerVersion } from "../../package.json" ;
9+ import {
10+ addAuthorizationHeaderIfUnspecified ,
11+ addUserAgent ,
12+ } from "../cfetch/internal" ;
1113import { readConfig } from "../config" ;
12- import { getConfigCache , purgeConfigCaches } from "../config-cache" ;
13- import { containersScope } from "../containers" ;
1414import { getCloudflareApiBaseUrl } from "../environment-variables/misc-variables" ;
1515import { UserError } from "../errors" ;
1616import { isNonInteractiveOrCI } from "../is-interactive" ;
1717import { logger } from "../logger" ;
18- import {
19- DefaultScopeKeys ,
20- getAccountFromCache ,
21- getAccountId ,
22- getAPIToken ,
23- getAuthFromEnv ,
24- getScopes ,
25- logout ,
26- reinitialiseAuthTokens ,
27- requireAuth ,
28- setLoginScopeKeys ,
29- } from "../user" ;
18+ import { requireApiToken , requireAuth } from "../user" ;
3019import { parseByteSize } from "./../parse" ;
3120import { wrap } from "./helpers/wrap" ;
3221import { idToLocationName , loadAccount } from "./locations" ;
3322import type { Config } from "../config" ;
3423import type { CloudchamberConfig , ContainerApp } from "../config/environment" ;
35- import type { Scope } from "../user " ;
24+ import type { containersScope } from "../containers " ;
3625import type {
3726 CommonYargsOptions ,
3827 StrictYargsOptionsToInterfaceJSON ,
@@ -45,7 +34,7 @@ import type {
4534 NetworkParameters ,
4635} from "@cloudflare/containers-shared" ;
4736
48- export const cloudchamberScope : Scope = "cloudchamber:write" ;
37+ export const cloudchamberScope = "cloudchamber:write" as const ;
4938
5039export type CommonCloudchamberConfiguration = { json : boolean } ;
5140
@@ -107,7 +96,7 @@ export function handleFailure<
10796 : never ,
10897> (
10998 cb : ( args : CommandArgumentsObject , config : Config ) => Promise < void > ,
110- scope : Scope
99+ scope : typeof cloudchamberScope | typeof containersScope
111100) : (
112101 args : CommonYargsOptions &
113102 CommandArgumentsObject &
@@ -146,21 +135,15 @@ export async function loadAccountSpinner({ json }: { json?: boolean }) {
146135 * Gets the API URL depending if the user is using old/admin based authentication.
147136 *
148137 */
149- async function getAPIUrl ( config : Config , scope : Scope ) {
138+ async function getAPIUrl (
139+ config : Config ,
140+ accountId : string ,
141+ scope : typeof cloudchamberScope | typeof containersScope
142+ ) {
150143 const api = getCloudflareApiBaseUrl ( config ) ;
151- // This one will probably be cache'd already so it won't ask for the accountId again
152- const accountId = config . account_id || ( await getAccountId ( config ) ) ;
153- const endpoint =
154- scope === cloudchamberScope
155- ? "cloudchamber"
156- : scope === containersScope
157- ? "containers"
158- : null ;
159- if ( endpoint === null ) {
160- throw new UserError (
161- "unexpected scope for command: " + JSON . stringify ( scope )
162- ) ;
163- }
144+
145+ const endpoint = scope === cloudchamberScope ? "cloudchamber" : "containers" ;
146+
164147 return `${ api } /accounts/${ accountId } /${ endpoint } ` ;
165148}
166149
@@ -190,83 +173,19 @@ export async function promiseSpinner<T>(
190173export async function fillOpenAPIConfiguration (
191174 config : Config ,
192175 json : boolean ,
193- scope : Scope
176+ scope : typeof containersScope | typeof cloudchamberScope
194177) {
195178 const headers : Record < string , string > =
196179 OpenAPI . HEADERS !== undefined ? { ...OpenAPI . HEADERS } : { } ;
197180
198- // if the config cache folder doesn't exist, it means that there is not a node_modules folder in the tree
199- if ( Object . keys ( getConfigCache ( "wrangler-account.json" ) ) . length === 0 ) {
200- await wrap ( mkdir ( "node_modules" , { } ) ) ;
201- purgeConfigCaches ( ) ;
202- }
203-
204- const scopes = getScopes ( ) ;
205- const needsToken = ! scopes ?. some ( ( s ) => s === scope ) ;
206- const neededScopes : Scope [ ] = [ scope ] ;
207- const scopesToSet : Scope [ ] =
208- scopes == undefined
209- ? neededScopes . concat ( DefaultScopeKeys )
210- : neededScopes . concat ( scopes ) ;
211-
212- if ( getAuthFromEnv ( ) && needsToken ) {
213- setLoginScopeKeys ( scopesToSet ) ;
214- // Wrangler will try to retrieve the oauth token and refresh it
215- // for its internal fetch call even if we have AuthFromEnv.
216- // Let's mock it
217- reinitialiseAuthTokens ( {
218- expiration_time : "2300-01-01:00:00:00+00:00" ,
219- oauth_token : "_" ,
220- } ) ;
221- } else {
222- if ( needsToken && scopes ) {
223- logRaw (
224- status . warning +
225- " We need to re-authenticate to add a required token..."
226- ) ;
227- // cache account id
228- await getAccountId ( config ) ;
229- const account = getAccountFromCache ( ) ;
230- config . account_id = account ?. id ?? config . account_id ;
231- await promiseSpinner ( logout ( ) , { json, message : "Revoking token" } ) ;
232- purgeConfigCaches ( ) ;
233- reinitialiseAuthTokens ( { } ) ;
234- }
235-
236- setLoginScopeKeys ( scopesToSet ) ;
237-
238- // Require either login, or environment variables being set to authenticate
239- //
240- // This will prompt the user for an accountId being chosen if they haven't configured the account id yet
241- const [ , err ] = await wrap ( requireAuth ( config ) ) ;
242- if ( err ) {
243- throw new UserError (
244- `authenticating with the Cloudflare API: ${ err . message } `
245- ) ;
246- }
247- }
248-
249- // Get the loaded API token
250- const token = getAPIToken ( ) ;
251- if ( ! token ) {
252- throw new UserError ( "unexpected apiToken not existing in credentials" ) ;
253- }
254-
255- const val = "apiToken" in token ? token . apiToken : null ;
256- // Don't try to support this method of authentication
257- if ( ! val ) {
258- throw new UserError (
259- "we don't allow for authKey/email credentials, use `wrangler login` or CLOUDFLARE_API_TOKEN env variable to authenticate"
260- ) ;
261- }
181+ const accountId = await requireAuth ( config ) ;
182+ const auth = requireApiToken ( ) ;
183+ addAuthorizationHeaderIfUnspecified ( headers , auth ) ;
184+ addUserAgent ( headers ) ;
262185
263- headers [ "Authorization" ] = `Bearer ${ val } ` ;
264- // These are being set by the internal fetch of wrangler, but we are not using it
265- // due to our OpenAPI codegenerated client.
266- headers [ "User-Agent" ] = `wrangler/${ wranglerVersion } ` ;
267186 OpenAPI . CREDENTIALS = "omit" ;
268187 if ( OpenAPI . BASE . length === 0 ) {
269- const [ base , errApiURL ] = await wrap ( getAPIUrl ( config , scope ) ) ;
188+ const [ base , errApiURL ] = await wrap ( getAPIUrl ( config , accountId , scope ) ) ;
270189 if ( errApiURL ) {
271190 throw new UserError ( "getting the API url: " + errApiURL . message ) ;
272191 }
0 commit comments