diff --git a/client/web/src/cody/management/api/client.ts b/client/web/src/cody/management/api/client.ts index 1ade77ec737..0679f834d5f 100644 --- a/client/web/src/cody/management/api/client.ts +++ b/client/web/src/cody/management/api/client.ts @@ -45,7 +45,7 @@ export module Client { export interface Call { method: 'GET' | 'POST' | 'PATCH' | 'DELETE' urlSuffix: string - requestBody?: any + requestBody?: unknown // Unused. This will never be set, it is only to // pass along the expected response type. @@ -64,7 +64,7 @@ export interface Caller { // the current Sourcegraph instance's SSC proxy API endpoint. export class CodyProApiCaller implements Caller { // e.g. "https://sourcegraph.com" - private origin: string + private readonly origin: string constructor() { this.origin = window.location.origin diff --git a/client/web/src/cody/management/api/components/CodyProApiClient.ts b/client/web/src/cody/management/api/components/CodyProApiClient.ts index 0e65668abc3..00eb944bcc9 100644 --- a/client/web/src/cody/management/api/components/CodyProApiClient.ts +++ b/client/web/src/cody/management/api/components/CodyProApiClient.ts @@ -1,6 +1,6 @@ import { createContext } from 'react' -import { Caller, CodyProApiCaller } from '../client' +import { type Caller, CodyProApiCaller } from '../client' export interface CodyProApiClient { caller: Caller diff --git a/client/web/src/cody/management/api/hooks/useApiClient.tsx b/client/web/src/cody/management/api/hooks/useApiClient.tsx index 4c3a8400a20..5bb145a95f9 100644 --- a/client/web/src/cody/management/api/hooks/useApiClient.tsx +++ b/client/web/src/cody/management/api/hooks/useApiClient.tsx @@ -1,6 +1,6 @@ import { useEffect, useState, useContext } from 'react' -import { Call } from '../client' +import type { Call } from '../client' import { CodyProApiClientContext } from '../components/CodyProApiClient' export interface ReactFriendlyApiResponse { @@ -15,7 +15,7 @@ export interface ReactFriendlyApiResponse { // state. // // IMPORTANT: In order to avoid the same API request being made multiple times, -// you MUST ensure that the provided call is the same between repains of the +// you MUST ensure that the provided call is the same between repaints of the // calling React component. i.e. you pretty much always need to create it via // `useMemo()`. export function useApiCaller(call: Call): ReactFriendlyApiResponse { @@ -34,7 +34,7 @@ export function useApiCaller(call: Call): ReactFriendlyApiResponse { + async function callApi(): Promise { try { const callerResponse = await caller.call(call) @@ -76,7 +76,9 @@ export function useApiCaller(call: Call): ReactFriendlyApiResponse { ignore = true diff --git a/client/web/src/cody/management/api/stripeCheckout.ts b/client/web/src/cody/management/api/stripeCheckout.ts index 5c7e61f845a..7c3a5dfa295 100644 --- a/client/web/src/cody/management/api/stripeCheckout.ts +++ b/client/web/src/cody/management/api/stripeCheckout.ts @@ -1,4 +1,4 @@ -import { BillingInterval } from './teamSubscriptions' +import type { BillingInterval } from './teamSubscriptions' export interface CreateCheckoutSessionRequest { interval: BillingInterval diff --git a/client/web/src/cody/management/subscription/new/CodyProCheckoutForm.tsx b/client/web/src/cody/management/subscription/new/CodyProCheckoutForm.tsx index 89ff953ede1..8ecc84aa4b9 100644 --- a/client/web/src/cody/management/subscription/new/CodyProCheckoutForm.tsx +++ b/client/web/src/cody/management/subscription/new/CodyProCheckoutForm.tsx @@ -8,7 +8,7 @@ import { H3, LoadingSpinner, Text } from '@sourcegraph/wildcard' import { Client } from '../../api/client' import { useApiCaller } from '../../api/hooks/useApiClient' -import { CreateCheckoutSessionRequest } from '../../api/types' +import type { CreateCheckoutSessionRequest } from '../../api/types' /** * CodyProCheckoutForm is essentially an iframe that the Stripe Elements library will @@ -18,16 +18,18 @@ export const CodyProCheckoutForm: React.FunctionComponent<{ stripePromise: Promise customerEmail: string | undefined }> = ({ stripePromise, customerEmail }) => { + const [urlSearchParams] = useSearchParams() + const creatingTeam = urlSearchParams.get('team') === '1' // Optionally support the "showCouponCodeAtCheckout" URL query parameter, which, if present, // will display a "promotional code" element in the Stripe Checkout UI. - const [urlSearchParams] = useSearchParams() const showPromoCodeField = urlSearchParams.get('showCouponCodeAtCheckout') !== null // Make the API call to create the Stripe Checkout session. const call = useMemo(() => { - const req: CreateCheckoutSessionRequest = { + const requestBody: CreateCheckoutSessionRequest = { interval: 'monthly', - seats: 1, + // If creating a team, we set seatCount=0, which means the user can adjust the seat count. + seats: creatingTeam ? 0 : 1, customerEmail, showPromoCodeField, @@ -42,8 +44,8 @@ export const CodyProCheckoutForm: React.FunctionComponent<{ // some prompt, to give the backends an opportunity to sync. returnUrl: `${origin}/cody/manage?session_id={CHECKOUT_SESSION_ID}`, } - return Client.createStripeCheckoutSession(req) - }, [customerEmail, showPromoCodeField]) + return Client.createStripeCheckoutSession(requestBody) + }, [creatingTeam, customerEmail, showPromoCodeField]) const { loading, error, data } = useApiCaller(call) // Show a spinner while we wait for the Checkout session to be created. @@ -63,7 +65,7 @@ export const CodyProCheckoutForm: React.FunctionComponent<{ return (
- {data && data.clientSecret && ( + {data?.clientSecret && ( diff --git a/cmd/frontend/internal/ssc/ssc_proxy.go b/cmd/frontend/internal/ssc/ssc_proxy.go index 9cf4292ec7e..ef921cd4adb 100644 --- a/cmd/frontend/internal/ssc/ssc_proxy.go +++ b/cmd/frontend/internal/ssc/ssc_proxy.go @@ -27,7 +27,7 @@ import ( "github.com/sourcegraph/sourcegraph/schema" ) -// SSCAPIProxy is an HTTP handler that essentially proxies API requests from the +// APIProxyHandler is an HTTP handler that essentially proxies API requests from the // current Sourcegraph instance to the SSC backend, but exchanging the credentials // of the calling Sourcegraph user with an access token for their SAMS identity. // @@ -81,7 +81,7 @@ func GetSAMSOAuthContext() (*oauthutil.OAuthContext, error) { return nil, errors.New("no SAMS configuration found") } -// getUserIDFromRequest extracts the Sourcegraph User ID from the incomming request, +// getUserIDFromRequest extracts the Sourcegraph User ID from the incoming request, // or returns an error suitable for sending to the end user. func (p *APIProxyHandler) getUserIDFromContext(ctx context.Context) (int32, error) { callingActor := actor.FromContext(ctx) @@ -96,7 +96,7 @@ func (p *APIProxyHandler) getUserIDFromContext(ctx context.Context) (int32, erro return callingActor.UID, nil } -// buildProxyRequest converts the incomming HTTP request into what will be sent to the SSC backend. +// buildProxyRequest converts the incoming HTTP request into what will be sent to the SSC backend. func (p *APIProxyHandler) buildProxyRequest(sourceReq *http.Request, token string) (*http.Request, error) { // For simplicity, read the full request body before sending the proxy request. var bodyReader io.Reader