Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: in progress of converting command having updated types #6358

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 83 additions & 90 deletions src/commands/sites/sites-create-template.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { OptionValues } from 'commander'
import inquirer from 'inquirer'
import pick from 'lodash/pick.js'
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'pars... Remove this comment to see the full error message
import parseGitHubUrl from 'parse-github-url'
import { render } from 'prettyjson'

import { chalk, error, getTerminalLink, log, logJson, warn } from '../../utils/command-helpers.js'
import { chalk, getTerminalLink } from '../../utils/command-helpers.js'
import execa from '../../utils/execa.js'
import getRepoData from '../../utils/get-repo-data.js'
import { getGitHubToken } from '../../utils/init/config-github.js'
Expand All @@ -15,22 +14,18 @@ import { track } from '../../utils/telemetry/index.js'
import BaseCommand from '../base-command.js'

import { getSiteNameInput } from './sites-create.js'
import { NetlifyLog, SelectOptions, intro, outro, select, confirm } from '../../utils/styles/index.js'

// @ts-expect-error TS(7006) FIXME: Parameter 'token' implicitly has an 'any' type.
export const fetchTemplates = async (token) => {
export const fetchTemplates = async (token: string) => {
const templatesFromGithubOrg = await getTemplatesFromGitHub(token)

return (
templatesFromGithubOrg
// @ts-expect-error TS(7006) FIXME: Parameter 'repo' implicitly has an 'any' type.
.filter((repo) => !repo.archived && !repo.disabled)
// @ts-expect-error TS(7006) FIXME: Parameter 'template' implicitly has an 'any' type.
.map((template) => ({
name: template.name,
sourceCodeUrl: template.html_url,
slug: template.full_name,
}))
)
return templatesFromGithubOrg
.filter((repo) => !repo.archived && !repo.disabled)
.map((template) => ({
name: template.name,
sourceCodeUrl: template.html_url,
slug: template.full_name,
}))
}

// @ts-expect-error TS(7031) FIXME: Binding element 'ghToken' implicitly has an 'any' ... Remove this comment to see the full error message
Expand All @@ -47,20 +42,16 @@ const getTemplateName = async ({ ghToken, options, repository }) => {

const templates = await fetchTemplates(ghToken)

log(`Choose one of our starter templates. Netlify will create a new repo for this template in your GitHub account.`)

const { templateName } = await inquirer.prompt([
{
type: 'list',
name: 'templateName',
message: 'Template:',
// @ts-expect-error TS(7006) FIXME: Parameter 'template' implicitly has an 'any' type.
choices: templates.map((template) => ({
value: template.slug,
name: template.name,
})),
},
])
const templateOptions: SelectOptions<string> = {
message:
'Choose one of our starter templates. Netlify will create a new repo for this template in your GitHub account.',
options: templates.map((template) => ({
value: template.slug,
label: template.name,
})),
}

const templateName = await select(templateOptions)

return templateName
}
Expand All @@ -69,6 +60,8 @@ const getTemplateName = async ({ ghToken, options, repository }) => {
const getGitHubLink = ({ options, templateName }) => options.url || `https://github.com/${templateName}`

export const sitesCreateTemplate = async (repository: string, options: OptionValues, command: BaseCommand) => {
!options.isChildCommand && intro('sites:create-template')

const { api } = command.netlify

await command.authenticate()
Expand All @@ -80,38 +73,37 @@ export const sitesCreateTemplate = async (repository: string, options: OptionVal
const { exists, isTemplate } = await validateTemplate({ templateName, ghToken })
if (!exists) {
const githubLink = getGitHubLink({ options, templateName })
error(
`Could not find template ${chalk.bold(templateName)}. Please verify it exists and you can ${getTerminalLink(
'access to it on GitHub',
githubLink,
)}`,
)
outro({
exit: true,
message: `Could not find template ${chalk.bold(
templateName,
)}. Please verify it exists and you can ${getTerminalLink('access to it on GitHub', githubLink)}`,
})
return
}
if (!isTemplate) {
const githubLink = getGitHubLink({ options, templateName })
error(`${getTerminalLink(chalk.bold(templateName), githubLink)} is not a valid GitHub template`)
outro({
exit: true,
message: `${getTerminalLink(chalk.bold(templateName), githubLink)} is not a valid GitHub template`,
})
return
}

const accounts = await api.listAccountsForUser()

let { accountSlug } = options

if (!accountSlug) {
const { accountSlug: accountSlugInput } = await inquirer.prompt([
{
type: 'list',
name: 'accountSlug',
message: 'Team:',
// @ts-expect-error TS(7006) FIXME: Parameter 'account' implicitly has an 'any' type.
choices: accounts.map((account) => ({
value: account.slug,
name: account.name,
})),
},
])
accountSlug = accountSlugInput
const accountSelectOptions: SelectOptions<string> = {
// @ts-expect-error TS(7006) FIXME: Parameter 'account' implicitly has an 'any' type.
options: accounts.map((account) => ({
value: account.slug,
label: account.name,
})),
message: 'Team:',
}

accountSlug = await select(accountSelectOptions)
}

const { name: nameFlag } = options
Expand All @@ -131,7 +123,7 @@ export const sitesCreateTemplate = async (repository: string, options: OptionVal

if (repoResp.errors) {
if (repoResp.errors[0].includes('Name already exists on this account')) {
warn(
NetlifyLog.warn(
`Oh no! We found already a repository with this name. It seems you have already created a template with the name ${templateName}. Please try to run the command again and provide a different name.`,
)
// @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0.
Expand All @@ -158,27 +150,25 @@ export const sitesCreateTemplate = async (repository: string, options: OptionVal
} catch (error_) {
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
if (error_.status === 422 || error_.message === 'Duplicate repo') {
warn(
NetlifyLog.warn(
`${name}.netlify.app already exists or a repository named ${name} already exists on this account. Please try a different slug.`,
)
// @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0.
await inputSiteName()
} else {
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
error(`createSiteInTeam error: ${error_.status}: ${error_.message}`)
outro({ exit: true, message: `createSiteInTeam error: ${error_.status}: ${error_.message}` })
}
}
}

await inputSiteName(nameFlag)

log()
log(chalk.greenBright.bold.underline(`Site Created`))
log()
NetlifyLog.success(chalk.greenBright.bold.underline(`Site Created`))

// @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
const siteUrl = site.ssl_url || site.url
log(
NetlifyLog.info(
render({
// @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
'Admin URL': site.admin_url,
Expand All @@ -198,55 +188,58 @@ export const sitesCreateTemplate = async (repository: string, options: OptionVal
siteUrl,
})

const { cloneConfirm } = await inquirer.prompt({
type: 'confirm',
name: 'cloneConfirm',
const cloneConfirm = await confirm({
message: `Do you want to clone the repository?`,
default: true,
initialValue: true,
})

if (cloneConfirm) {
log()
await execa('git', ['clone', repoResp.clone_url, `${repoResp.name}`])
log(`πŸš€ Repository cloned successfully. You can find it under the ${chalk.magenta(repoResp.name)} folder`)
}

if (options.withCi) {
log('Configuring CI')
NetlifyLog.info('Configuring CI')
// @ts-expect-error TS(2345) FIXME: Argument of type '{ workingDir: any; }' is not ass... Remove this comment to see the full error message
const repoData = await getRepoData({ workingDir: command.workingDir })
// @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
await configureRepo({ command, siteId: site.id, repoData, manual: options.manual })
}

if (options.json) {
logJson(
pick(site, [
'id',
'state',
'plan',
'name',
'custom_domain',
'domain_aliases',
'url',
'ssl_url',
'admin_url',
'screenshot_url',
'created_at',
'updated_at',
'user_id',
'ssl',
'force_ssl',
'managed_dns',
'deploy_url',
'account_name',
'account_slug',
'git_provider',
'deploy_hook',
'capabilities',
'id_domain',
]),
NetlifyLog.info(
render(
pick(site, [
'id',
'state',
'plan',
'name',
'custom_domain',
'domain_aliases',
'url',
'ssl_url',
'admin_url',
'screenshot_url',
'created_at',
'updated_at',
'user_id',
'ssl',
'force_ssl',
'managed_dns',
'deploy_url',
'account_name',
'account_slug',
'git_provider',
'deploy_hook',
'capabilities',
'id_domain',
]),
),
)
}

outro({
message: `πŸš€ Repository cloned successfully. You can find it under the ${chalk.magenta(repoResp.name)} folder`,
})

return site
}
2 changes: 1 addition & 1 deletion src/commands/sites/sites-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,6 @@ export const sitesCreate = async (options: OptionValues, command: BaseCommand) =
await link({ id: site.id, isChildCommand: true }, command)
}

!options.isChildCommand && outro({ exit: true, message: `Site Created` })
!options.isChildCommand && outro({ message: `Site Created` })
return site
}
5 changes: 3 additions & 2 deletions src/utils/init/config-github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { chalk, error as failAndExit, log } from '../command-helpers.js'
import { getGitHubToken as ghauth } from '../gh-auth.js'

import { createDeployKey, formatErrorMessage, getBuildSettings, saveNetlifyToml, setupSite } from './utils.js'
import { NetlifyLog } from '../styles/index.js'

/**
* @typedef Token
Expand Down Expand Up @@ -40,8 +41,8 @@ export const getGitHubToken = async ({ globalConfig }) => {
return githubToken.token
}
} catch {
log(chalk.yellow('Token is expired or invalid!'))
log('Generating a new Github token...')
NetlifyLog.warn(chalk.yellow('Token is expired or invalid!'))
NetlifyLog.info('Generating a new Github token...')
}
}

Expand Down
13 changes: 10 additions & 3 deletions src/utils/sites/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'node... Remove this comment to see the full error message
import fetch from 'node-fetch'

// @ts-expect-error TS(7006) FIXME: Parameter 'token' implicitly has an 'any' type.
export const getTemplatesFromGitHub = async (token) => {
type Template = {
name: string
html_url: string
full_name: string
archived: boolean
disabled: boolean
}

export const getTemplatesFromGitHub = async (token: string) => {
const getPublicGitHubReposFromOrg = new URL(`https://api.github.com/orgs/netlify-templates/repos`)
// GitHub returns 30 by default and we want to avoid our limit
// due to our archived repositories at any given time
Expand All @@ -19,7 +26,7 @@ export const getTemplatesFromGitHub = async (token) => {
Authorization: `token ${token}`,
},
})
const allTemplates = await templates.json()
const allTemplates = (await templates.json()) as Template[]

return allTemplates
}
Expand Down