Skip to content

Commit

Permalink
feat: generate token
Browse files Browse the repository at this point in the history
  • Loading branch information
RostiMelk committed Nov 26, 2024
1 parent 7b065c4 commit 21493b9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
applyEnvVariables,
applyPackageName,
downloadAndExtractRepo,
generateSanityApiReadToken,
getMonoRepo,
isNextJsTemplate,
type RepoInfo,
Expand Down Expand Up @@ -42,13 +43,14 @@ export async function bootstrapRemoteTemplate(
debug('Downloading and extracting repo to %s', outputPath)
await downloadAndExtractRepo(outputPath, repoInfo, bearerToken)

debug('Checking if template is NextJS')
debug('Applying environment variables')
const readToken = await generateSanityApiReadToken(variables.projectId, apiClient)
const isNext = await isNextJsTemplate(outputPath)
const envName = isNext ? '.env.local' : '.env'

debug('Applying environment variables to %s', envName)
for (const folder of packages ?? ['']) {
await applyEnvVariables(join(outputPath, folder), variables, envName)
const path = join(outputPath, folder)
await applyEnvVariables(path, {...variables, readToken}, envName)
}

debug('Setting package name to %s', packageName)
Expand Down
49 changes: 35 additions & 14 deletions packages/@sanity/cli/src/util/remoteTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {type ReadableStream} from 'node:stream/web'

import {x} from 'tar'
import {parse as parseYaml} from 'yaml'
import {type CliApiClient} from '../types'

const ENV_VAR = {
PROJECT_ID: /SANITY(?:_STUDIO)?_PROJECT_ID/, // Matches SANITY_PROJECT_ID and SANITY_STUDIO_PROJECT_ID
Expand All @@ -22,6 +23,13 @@ const ENV_FILE = {

const ENV_TEMPLATE_FILES = [ENV_FILE.TEMPLATE, ENV_FILE.EXAMPLE, ENV_FILE.LOCAL_EXAMPLE] as const

type EnvData = {
projectId: string
dataset: string
readToken?: string
apiVersion?: string
}

type GithubUrlString =
| `https://github.com/${string}/${string}`
| `https://www.github.com/${string}/${string}`
Expand All @@ -33,12 +41,6 @@ export type RepoInfo = {
filePath: string
}

export type EnvData = {
projectId: string
dataset: string
apiVersion?: string
}

function isGithubRepoShorthand(value: string): boolean {
if (URL.canParse(value)) {
return false
Expand Down Expand Up @@ -440,30 +442,36 @@ export async function applyEnvVariables(

try {
const templateContent = await readFile(join(root, templatePath), 'utf8')
const {projectId, dataset, apiVersion = 'vX'} = envData

const findAndReplaceVariable = (content: string, varRegex: RegExp | string, value: string) => {
const {projectId, dataset, readToken = '', apiVersion = 'vX'} = envData

const findAndReplaceVariable = (
content: string,
varRegex: RegExp | string,
value: string,
useQuotes: boolean,
) => {
const pattern = varRegex instanceof RegExp ? varRegex : new RegExp(`${varRegex}=.*$`, 'm')
const match = content.match(pattern)
if (!match) return content

const varName = match[0].split('=')[0]
const hasQuotes = match[0].includes('"')
return content.replace(
new RegExp(`${varName}=.*$`, 'm'),
`${varName}=${hasQuotes ? `"${value}"` : value}`,
`${varName}=${useQuotes ? `"${value}"` : value}`,
)
}

let envContent = templateContent
const vars = [
{pattern: ENV_VAR.PROJECT_ID, value: projectId},
{pattern: ENV_VAR.DATASET, value: dataset},
{pattern: ENV_VAR.READ_TOKEN, value: readToken},
{pattern: ENV_VAR.API_VERSION, value: apiVersion},
]
const useQuotes = templateContent.includes('="')

for (const {pattern, value} of vars) {
envContent = findAndReplaceVariable(envContent, pattern, value)
envContent = findAndReplaceVariable(envContent, pattern, value, useQuotes)
}

await writeFile(join(root, targetName), envContent)
Expand All @@ -484,6 +492,19 @@ export async function applyPackageName(root: string, name: string): Promise<void
}
}

export function generateSanityApiReadToken() {
throw new Error('Not implemented')
export async function generateSanityApiReadToken(
projectId: string,
apiClient: CliApiClient,
): Promise<string> {
const response = await apiClient({requireProject: false, requireUser: true})
.config({apiVersion: 'v2021-06-07'})
.request<{key: string}>({
uri: `/projects/${projectId}/tokens`,
method: 'POST',
body: {
label: `API Read Token (${Date.now()})`,
roleName: 'viewer',
},
})
return response.key
}

0 comments on commit 21493b9

Please sign in to comment.