2023-10-23 23:16:24 +02:00
|
|
|
import fs from "node:fs"
|
|
|
|
import { fileURLToPath } from "node:url"
|
2021-06-09 20:31:45 +02:00
|
|
|
|
2023-10-23 23:16:24 +02:00
|
|
|
import validateProjectName from "validate-npm-package-name"
|
2021-06-09 20:31:45 +02:00
|
|
|
|
2023-10-23 23:16:24 +02:00
|
|
|
import { isExistingPath } from "../utils/isExistingPath.js"
|
|
|
|
import { template } from "./Template.js"
|
2021-06-09 20:31:45 +02:00
|
|
|
|
|
|
|
export interface ChallengeOptions {
|
|
|
|
name: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface GenerateChallengeOptions extends ChallengeOptions {
|
|
|
|
githubUser: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Challenge implements ChallengeOptions {
|
2023-10-23 23:16:24 +02:00
|
|
|
public static BASE_URL = new URL("../../challenges/", import.meta.url)
|
2021-06-09 20:31:45 +02:00
|
|
|
public name: string
|
|
|
|
public path: string
|
|
|
|
|
2022-04-24 20:27:51 +02:00
|
|
|
constructor(options: ChallengeOptions) {
|
2021-06-09 20:31:45 +02:00
|
|
|
const { name } = options
|
|
|
|
this.name = name
|
2023-01-10 23:15:36 +01:00
|
|
|
this.path = fileURLToPath(new URL(`./${name}`, Challenge.BASE_URL))
|
2021-06-09 20:31:45 +02:00
|
|
|
}
|
|
|
|
|
2023-01-05 18:29:07 +01:00
|
|
|
public static async getChallenges(): Promise<Challenge[]> {
|
2023-01-10 23:15:36 +01:00
|
|
|
const challengeNames = await fs.promises.readdir(Challenge.BASE_URL)
|
2023-01-05 18:29:07 +01:00
|
|
|
return challengeNames.map((challengeName) => {
|
|
|
|
return new Challenge({ name: challengeName })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-01-10 23:15:36 +01:00
|
|
|
public static async generate(
|
2023-10-23 23:16:24 +02:00
|
|
|
options: GenerateChallengeOptions,
|
2023-01-10 23:15:36 +01:00
|
|
|
): Promise<Challenge> {
|
2021-06-09 20:31:45 +02:00
|
|
|
const { name, githubUser } = options
|
|
|
|
const challenge = new Challenge({ name })
|
|
|
|
if (await isExistingPath(challenge.path)) {
|
|
|
|
throw new Error(`The challenge already exists: ${name}.`)
|
|
|
|
}
|
|
|
|
const isValidName = validateProjectName(name).validForNewPackages
|
|
|
|
if (!isValidName) {
|
2023-10-23 23:16:24 +02:00
|
|
|
throw new Error("Invalid challenge name.")
|
2021-06-09 20:31:45 +02:00
|
|
|
}
|
|
|
|
await fs.promises.mkdir(challenge.path)
|
|
|
|
await template.challenge({
|
|
|
|
destination: challenge.path,
|
|
|
|
githubUser,
|
2023-10-23 23:16:24 +02:00
|
|
|
name,
|
2021-06-09 20:31:45 +02:00
|
|
|
})
|
|
|
|
return challenge
|
|
|
|
}
|
|
|
|
}
|