diff --git a/tooling/license/license.sh b/tooling/license/license.sh deleted file mode 100644 index 1eabc75d6..000000000 --- a/tooling/license/license.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -e - -if [ "$NODE_ENV" = "production" ]; then - exit 0 -fi - -GIT_USER=$(git config user.name) -GIT_EMAIL=$(git config user.email) - -if [ -z "$GIT_USER" ]; then - echo "Please set the git user name with the command 'git config user.name '. The username needs to match the username in your Makerkit organization." - exit 1 -fi - -STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "https://makerkit.dev/api/license/check?username=$GIT_USER&email=$GIT_EMAIL") - -if [ "$STATUS_CODE" = "200" ]; then - exit 0 -fi - -exit 1 \ No newline at end of file diff --git a/tooling/license/main.sh b/tooling/license/main.sh deleted file mode 100644 index f910cab8b..000000000 --- a/tooling/license/main.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -set -e - -sh visibility.sh -sh license.sh \ No newline at end of file diff --git a/tooling/license/package.json b/tooling/license/package.json index 01d16156c..008501833 100644 --- a/tooling/license/package.json +++ b/tooling/license/package.json @@ -3,6 +3,6 @@ "private": true, "version": "0.1.0", "scripts": { - "dev": "sh main.sh" + "dev": "node src/index.js" } } diff --git a/tooling/license/src/index.js b/tooling/license/src/index.js new file mode 100644 index 000000000..dd225f62f --- /dev/null +++ b/tooling/license/src/index.js @@ -0,0 +1,99 @@ +import { execSync } from 'child_process'; + +async function checkLicense() { + let gitUser, gitEmail; + + try { + gitUser = execSync('git config user.name').toString().trim(); + gitEmail = execSync('git config user.email').toString().trim(); + } catch (error) { + console.error('Error getting git config:', error.message); + process.exit(1); + } + + if (!gitUser) { + console.error( + "Please set the git user name with the command 'git config user.name '. The username needs to match the username in your Makerkit organization.", + ); + + process.exit(1); + } + + const res = await fetch( + `https://makerkit.dev/api/license/check?username=${encodeURIComponent(gitUser)}&email=${encodeURIComponent(gitEmail)}`, + ); + if (res.status === 200) { + return Promise.resolve(); + } else { + return Promise.reject( + new Error(`License check failed with status code: ${res.status}`), + ); + } +} + +function checkVisibility() { + let remoteUrl; + + try { + remoteUrl = execSync('git config --get remote.origin.url') + .toString() + .trim(); + } catch (error) { + console.error('Error getting git remote URL:', error.message); + process.exit(1); + } + + if (!remoteUrl.includes('github.com')) { + return Promise.resolve(); + } + + let ownerRepo; + if (remoteUrl.startsWith('https://github.com/')) { + ownerRepo = remoteUrl.slice('https://github.com/'.length); + } else if (remoteUrl.startsWith('git@github.com:')) { + ownerRepo = remoteUrl.slice('git@github.com:'.length); + } else { + console.error('Unsupported GitHub URL format'); + process.exit(1); + } + + ownerRepo = ownerRepo.replace(/\.git$/, ''); + + return fetch(`https://api.github.com/repos/${ownerRepo}`) + .then((res) => { + if (res.status === 200) { + return res.json(); + } else if (res.status === 404) { + return Promise.resolve(); + } else { + return Promise.reject( + new Error( + `GitHub API request failed with status code: ${res.status}`, + ), + ); + } + }) + .then((data) => { + if (data && !data.private) { + console.error( + 'The repository has been LEAKED on GitHub. Please delete the repository. A DMCA Takedown Request will automatically be requested in the coming hours.', + ); + process.exit(1); + } + }); +} + +async function main() { + if (process.env.NODE_ENV === 'production') { + return; + } + + try { + await checkVisibility(); + await checkLicense(); + } catch (error) { + process.exit(1); + } +} + +void main(); diff --git a/tooling/license/visibility.sh b/tooling/license/visibility.sh deleted file mode 100644 index a3fd0d82b..000000000 --- a/tooling/license/visibility.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -e - -remote_url=$(git config --get remote.origin.url) - -if [[ $remote_url == *"github.com"* ]]; then - if [[ $remote_url == https://github.com/* ]]; then - owner_repo=${remote_url#https://github.com/} - elif [[ $remote_url == git@github.com:* ]]; then - owner_repo=${remote_url#git@github.com:} - else - echo "Unsupported GitHub URL format" - exit 1 - fi - owner_repo=${owner_repo%.git} - - api_url="https://api.github.com/repos/$owner_repo" - response=$(curl -s -o /dev/null -w "%{http_code}" $api_url) - - if [ $response -eq 200 ]; then - visibility=$(curl -s $api_url | grep -o '"private": \(true\|false\)' | awk '{print $2}') - if [ "$visibility" = "false" ]; then - echo "The repository has been LEAKED on GitHub. Please delete the repository. A DMCA Takedown Request will automatically be requested in the coming hours." - exit 1 - else - exit 0 - fi - elif [ $response -eq 404 ]; then - exit 0 - else - exit 1 - fi -else - exit 0 -fi \ No newline at end of file diff --git a/turbo/generators/config.ts b/turbo/generators/config.ts index db2f690c7..19c4b8c32 100644 --- a/turbo/generators/config.ts +++ b/turbo/generators/config.ts @@ -3,6 +3,7 @@ import type { PlopTypes } from '@turbo/gen'; import { createEnvironmentVariablesGenerator } from './templates/env/generator'; import { createKeystaticAdminGenerator } from './templates/keystatic/generator'; import { createPackageGenerator } from './templates/package/generator'; +import { createSetupGenerator } from './templates/setup/generator'; import { createEnvironmentVariablesValidatorGenerator } from './templates/validate-env/generator'; // List of generators to be registered @@ -11,6 +12,7 @@ const generators = [ createKeystaticAdminGenerator, createEnvironmentVariablesGenerator, createEnvironmentVariablesValidatorGenerator, + createSetupGenerator, ]; export default function generator(plop: PlopTypes.NodePlopAPI): void { diff --git a/turbo/generators/templates/setup/generator.ts b/turbo/generators/templates/setup/generator.ts new file mode 100644 index 000000000..0922fe55d --- /dev/null +++ b/turbo/generators/templates/setup/generator.ts @@ -0,0 +1,72 @@ +import type { PlopTypes } from '@turbo/gen'; +import { execSync } from 'node:child_process'; + +export function createSetupGenerator(plop: PlopTypes.NodePlopAPI) { + plop.setGenerator('setup', { + description: 'Setup your Makerkit project', + prompts: [ + { + type: 'input', + name: 'projectName', + message: 'What is the name of the project?', + }, + ], + actions: [ + { + type: 'modify', + path: 'package.json', + async transform(content, answers) { + const pkg = JSON.parse(content); + + // Update project name in package.json + pkg.name = answers.projectName; + + return JSON.stringify(pkg, null, 2); + }, + }, + async () => { + try { + setupRemote(); + + return 'Project setup complete'; + } catch (error) { + console.error('Project setup failed. Aborting package generation.'); + process.exit(1); + } + }, + ], + }); +} + +function setupRemote() { + // Setup remote upstream + const getRemoteUrl = execSync('git remote get-url origin', { + stdio: 'inherit', + }); + + const currentRemote = getRemoteUrl.toString().trim(); + + console.log(`Setting upstream remote to ${currentRemote} ...`); + + if (currentRemote && currentRemote.includes('github.com')) { + execSync(`git remote delete origin`, { + stdio: 'inherit', + }); + + execSync(`git remote set-url upstream ${currentRemote}`, { + stdio: 'inherit', + }); + } else { + console.error('Your current remote is not GitHub'); + } + + // Run license script + try { + execSync('turbo run --filter license dev', { + stdio: 'inherit', + }); + } catch (error) { + console.error('License script failed. Aborting package generation.'); + process.exit(1); + } +}