create-turbo-kit 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.MD +7 -0
- package/README.MD +31 -0
- package/dist/{chunk-SGKVPRAI.js → chunk-2D3EEOSU.js} +41 -2
- package/dist/{chunk-SGKVPRAI.js.map → chunk-2D3EEOSU.js.map} +1 -1
- package/dist/{chunk-5F6FI7NU.js → chunk-KMVM4I6J.js} +3 -2
- package/dist/{chunk-5F6FI7NU.js.map → chunk-KMVM4I6J.js.map} +1 -1
- package/dist/{chunk-7W32JAIP.js → chunk-RB52EE5W.js} +6 -2
- package/dist/chunk-RB52EE5W.js.map +1 -0
- package/dist/{chunk-EYEU3RGM.js → chunk-WQABKQSK.js} +3 -1
- package/dist/{chunk-EYEU3RGM.js.map → chunk-WQABKQSK.js.map} +1 -1
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +20 -6
- package/dist/cli.js.map +1 -1
- package/dist/helpers/install.js +3 -2
- package/dist/helpers/scaffold.js +3 -2
- package/dist/helpers/transform.d.ts +5 -1
- package/dist/helpers/transform.js +6 -1
- package/dist/utils/package-manager.js +2 -1
- package/package.json +1 -1
- package/src/cli.ts +19 -4
- package/src/helpers/scaffold.ts +7 -1
- package/src/helpers/transform.ts +49 -0
- package/tsup.config.ts +3 -0
- package/dist/chunk-7W32JAIP.js.map +0 -1
package/LICENSE.MD
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2026 Evan Yu
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.MD
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# create-turbo-kit
|
|
2
|
+
|
|
3
|
+
This is the CLI script for quickly bootstrapping a new [Turbo Kit](https://github.com/Badbird5907/turbo-kit) project.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm create turbo-kit@latest
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## How it works
|
|
13
|
+
This script uses the `create-turbo` command under the hood to quickly scaffold a new Turbo Kit project.
|
|
14
|
+
It then applies some code transformations on top of the scaffolded project to make it ready for development.
|
|
15
|
+
|
|
16
|
+
See [transform.ts](./src/helpers/transform.ts) for more details.
|
|
17
|
+
|
|
18
|
+
## Development
|
|
19
|
+
|
|
20
|
+
Clone the repository and run the following commands:
|
|
21
|
+
```bash
|
|
22
|
+
pnpm install
|
|
23
|
+
|
|
24
|
+
pnpm build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To run the script (manually):
|
|
28
|
+
**Do not run in this directory!**
|
|
29
|
+
```bash
|
|
30
|
+
node <path-to-cli>/dist/cli.js
|
|
31
|
+
```
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
// src/helpers/transform.ts
|
|
2
4
|
import fg from "fast-glob";
|
|
3
5
|
import fs from "fs-extra";
|
|
@@ -166,12 +168,49 @@ async function configureDockerCompose(projectDir, selectedContainers) {
|
|
|
166
168
|
throw error;
|
|
167
169
|
}
|
|
168
170
|
}
|
|
171
|
+
async function removePackages(packages, packagePath, projectDir, s) {
|
|
172
|
+
const packageJsonPath = path.join(projectDir, packagePath, "package.json");
|
|
173
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
174
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
175
|
+
let hasChanges = false;
|
|
176
|
+
for (const dep of packages) {
|
|
177
|
+
if (packageJson.dependencies && packageJson.dependencies[dep]) {
|
|
178
|
+
delete packageJson.dependencies[dep];
|
|
179
|
+
hasChanges = true;
|
|
180
|
+
if (s) {
|
|
181
|
+
s.message(`Removed ${color.cyan(dep)} from ${packagePath}/package.json`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (hasChanges) {
|
|
186
|
+
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function removeReactEmail(projectDir) {
|
|
191
|
+
const s = spinner();
|
|
192
|
+
s.start("Removing react-email...");
|
|
193
|
+
try {
|
|
194
|
+
const emailPackagePath = path.join(projectDir, "packages", "email");
|
|
195
|
+
if (await fs.pathExists(emailPackagePath)) {
|
|
196
|
+
await fs.remove(emailPackagePath);
|
|
197
|
+
s.message(`Removed ${color.cyan(emailPackagePath)}`);
|
|
198
|
+
}
|
|
199
|
+
await removePackages(["@react-email/components", "@acme/email"], "packages/api", projectDir, s);
|
|
200
|
+
s.stop("Removed react-email");
|
|
201
|
+
} catch (error) {
|
|
202
|
+
s.stop("Failed to remove react-email");
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
169
206
|
|
|
170
207
|
export {
|
|
171
208
|
replaceScope,
|
|
172
209
|
setupEnv,
|
|
173
210
|
getDockerContainers,
|
|
174
211
|
deleteDockerCompose,
|
|
175
|
-
configureDockerCompose
|
|
212
|
+
configureDockerCompose,
|
|
213
|
+
removePackages,
|
|
214
|
+
removeReactEmail
|
|
176
215
|
};
|
|
177
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-2D3EEOSU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helpers/transform.ts"],"sourcesContent":["import fg from 'fast-glob';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { spinner } from '@clack/prompts';\r\nimport color from 'picocolors';\r\n\r\nconst DOCKER_CONTAINERS = {\r\n postgres: {\r\n label: 'PostgreSQL 16 (Database)',\r\n services: ['postgres'],\r\n volumes: ['postgres_data'],\r\n dependsOn: [], \r\n },\r\n pgadmin: {\r\n label: `pgAdmin 4.9 (Database management) [Depends on PostgreSQL]`,\r\n services: ['pgadmin'],\r\n volumes: [],\r\n dependsOn: ['postgres'],\r\n },\r\n redis: {\r\n label: 'Redis (Caching)',\r\n services: ['redis'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n mailpit: {\r\n label: 'Mailpit (Email testing)',\r\n services: ['mailpit'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n minio: {\r\n label: 'MinIO (S3-compatible storage)',\r\n services: ['minio', 'minio-create-bucket'],\r\n volumes: ['minio_data'],\r\n dependsOn: [],\r\n },\r\n} as const;\r\n\r\nexport type DockerContainer = keyof typeof DOCKER_CONTAINERS;\r\n\r\nexport async function replaceScope(projectDir: string, newScope: string) {\r\n const s = spinner();\r\n s.start(`Replacing scope with ${color.cyan(newScope)}...`);\r\n\r\n try {\r\n const files = await fg('**/*', {\r\n cwd: projectDir,\r\n ignore: [\r\n '**/.git/**',\r\n '**/node_modules/**',\r\n '**/.turbo/**',\r\n '**/dist/**',\r\n '**/.next/**',\r\n '**/pnpm-lock.yaml',\r\n '**/yarn.lock',\r\n '**/package-lock.json',\r\n '**/bun.lockb',\r\n ],\r\n absolute: true,\r\n });\r\n\r\n await Promise.all(\r\n files.map(async (file) => {\r\n try {\r\n const content = await fs.readFile(file, 'utf8');\r\n if (content.includes('@acme')) {\r\n const newContent = content.replace(/@acme/g, newScope);\r\n await fs.writeFile(file, newContent);\r\n }\r\n } catch (e) {\r\n }\r\n })\r\n );\r\n \r\n s.stop(`Replaced scope with ${color.cyan(newScope)}`);\r\n } catch (error) {\r\n s.stop('Failed to replace scope');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function setupEnv(projectDir: string) {\r\n const envExample = path.join(projectDir, '.env.example');\r\n const envDest = path.join(projectDir, '.env');\r\n\r\n if (await fs.pathExists(envExample)) {\r\n await fs.copy(envExample, envDest);\r\n }\r\n}\r\n\r\nexport function getDockerContainers() {\r\n return Object.entries(DOCKER_CONTAINERS).map(([value, config]) => ({\r\n value,\r\n label: config.label,\r\n }));\r\n}\r\n\r\nexport async function deleteDockerCompose(projectDir: string) {\r\n const s = spinner();\r\n s.start('Removing Docker Compose setup...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n if (await fs.pathExists(dockerComposePath)) {\r\n await fs.remove(dockerComposePath);\r\n s.message(`Removed ${color.cyan(dockerComposePath)}`);\r\n }\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir)) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)}`);\r\n }\r\n s.stop('Removed Docker Compose setup');\r\n } catch (error) {\r\n s.stop('Failed to remove Docker Compose setup');\r\n throw error;\r\n }\r\n}\r\n\r\nfunction resolveContainerDependencies(selectedContainers: string[]): string[] {\r\n const resolved = new Set<string>(selectedContainers);\r\n const queue = [...selectedContainers];\r\n\r\n while (queue.length > 0) {\r\n const current = queue.shift()!;\r\n const config = DOCKER_CONTAINERS[current as DockerContainer];\r\n \r\n if (config && config.dependsOn) {\r\n for (const dep of config.dependsOn) {\r\n if (!resolved.has(dep)) {\r\n resolved.add(dep);\r\n queue.push(dep);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return Array.from(resolved);\r\n}\r\n\r\nexport async function configureDockerCompose(projectDir: string, selectedContainers: string[]) {\r\n const s = spinner();\r\n s.start('Configuring Docker Compose...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n \r\n if (!(await fs.pathExists(dockerComposePath))) {\r\n s.stop('Docker Compose file not found');\r\n return;\r\n }\r\n\r\n const resolvedContainers = resolveContainerDependencies(selectedContainers);\r\n const addedDependencies = resolvedContainers.filter(c => !selectedContainers.includes(c));\r\n \r\n if (addedDependencies.length > 0) {\r\n s.message(`Auto-including dependencies: ${color.cyan(addedDependencies.join(', '))}`);\r\n }\r\n\r\n let content = await fs.readFile(dockerComposePath, 'utf8');\r\n\r\n const allContainers = Object.keys(DOCKER_CONTAINERS) as DockerContainer[];\r\n const containersToRemove = allContainers.filter(c => !resolvedContainers.includes(c));\r\n\r\n for (const container of containersToRemove) {\r\n const containerRegex = new RegExp(\r\n ` # -- ${container} --\\\\n[\\\\s\\\\S]*? # // ${container} //\\\\n`,\r\n 'g'\r\n );\r\n content = content.replace(containerRegex, '');\r\n\r\n // delete `./docker/<container>/`\r\n const dockerDirPath = path.join(projectDir, 'docker', container);\r\n if (await fs.pathExists(dockerDirPath)) {\r\n await fs.remove(dockerDirPath);\r\n s.message(`Removed ${color.cyan(dockerDirPath)}`);\r\n }\r\n }\r\n\r\n content = content.replace(/ # -- \\w+ --\\n/g, '');\r\n content = content.replace(/ # \\/\\/ \\w+ \\/\\/\\n/g, '');\r\n\r\n await fs.writeFile(dockerComposePath, content);\r\n\r\n // check if `./docker/` is empty\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir) && (await fs.readdir(dockerDir)).length === 0) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)} ${color.gray('(because it was empty)')}`);\r\n }\r\n \r\n s.stop(`Configured Docker Compose with ${color.cyan(resolvedContainers.length)} container(s)`);\r\n } catch (error) {\r\n s.stop('Failed to configure Docker Compose');\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/helpers/transform.ts"],"sourcesContent":["import fg from 'fast-glob';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { spinner } from '@clack/prompts';\r\nimport color from 'picocolors';\r\n\r\nconst DOCKER_CONTAINERS = {\r\n postgres: {\r\n label: 'PostgreSQL 16 (Database)',\r\n services: ['postgres'],\r\n volumes: ['postgres_data'],\r\n dependsOn: [], \r\n },\r\n pgadmin: {\r\n label: `pgAdmin 4.9 (Database management) [Depends on PostgreSQL]`,\r\n services: ['pgadmin'],\r\n volumes: [],\r\n dependsOn: ['postgres'],\r\n },\r\n redis: {\r\n label: 'Redis (Caching)',\r\n services: ['redis'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n mailpit: {\r\n label: 'Mailpit (Email testing)',\r\n services: ['mailpit'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n minio: {\r\n label: 'MinIO (S3-compatible storage)',\r\n services: ['minio', 'minio-create-bucket'],\r\n volumes: ['minio_data'],\r\n dependsOn: [],\r\n },\r\n} as const;\r\n\r\nexport type DockerContainer = keyof typeof DOCKER_CONTAINERS;\r\n\r\nexport async function replaceScope(projectDir: string, newScope: string) {\r\n const s = spinner();\r\n s.start(`Replacing scope with ${color.cyan(newScope)}...`);\r\n\r\n try {\r\n const files = await fg('**/*', {\r\n cwd: projectDir,\r\n ignore: [\r\n '**/.git/**',\r\n '**/node_modules/**',\r\n '**/.turbo/**',\r\n '**/dist/**',\r\n '**/.next/**',\r\n '**/pnpm-lock.yaml',\r\n '**/yarn.lock',\r\n '**/package-lock.json',\r\n '**/bun.lockb',\r\n ],\r\n absolute: true,\r\n });\r\n\r\n await Promise.all(\r\n files.map(async (file) => {\r\n try {\r\n const content = await fs.readFile(file, 'utf8');\r\n if (content.includes('@acme')) {\r\n const newContent = content.replace(/@acme/g, newScope);\r\n await fs.writeFile(file, newContent);\r\n }\r\n } catch (e) {\r\n }\r\n })\r\n );\r\n \r\n s.stop(`Replaced scope with ${color.cyan(newScope)}`);\r\n } catch (error) {\r\n s.stop('Failed to replace scope');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function setupEnv(projectDir: string) {\r\n const envExample = path.join(projectDir, '.env.example');\r\n const envDest = path.join(projectDir, '.env');\r\n\r\n if (await fs.pathExists(envExample)) {\r\n await fs.copy(envExample, envDest);\r\n }\r\n}\r\n\r\nexport function getDockerContainers() {\r\n return Object.entries(DOCKER_CONTAINERS).map(([value, config]) => ({\r\n value,\r\n label: config.label,\r\n }));\r\n}\r\n\r\nexport async function deleteDockerCompose(projectDir: string) {\r\n const s = spinner();\r\n s.start('Removing Docker Compose setup...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n if (await fs.pathExists(dockerComposePath)) {\r\n await fs.remove(dockerComposePath);\r\n s.message(`Removed ${color.cyan(dockerComposePath)}`);\r\n }\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir)) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)}`);\r\n }\r\n s.stop('Removed Docker Compose setup');\r\n } catch (error) {\r\n s.stop('Failed to remove Docker Compose setup');\r\n throw error;\r\n }\r\n}\r\n\r\nfunction resolveContainerDependencies(selectedContainers: string[]): string[] {\r\n const resolved = new Set<string>(selectedContainers);\r\n const queue = [...selectedContainers];\r\n\r\n while (queue.length > 0) {\r\n const current = queue.shift()!;\r\n const config = DOCKER_CONTAINERS[current as DockerContainer];\r\n \r\n if (config && config.dependsOn) {\r\n for (const dep of config.dependsOn) {\r\n if (!resolved.has(dep)) {\r\n resolved.add(dep);\r\n queue.push(dep);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return Array.from(resolved);\r\n}\r\n\r\nexport async function configureDockerCompose(projectDir: string, selectedContainers: string[]) {\r\n const s = spinner();\r\n s.start('Configuring Docker Compose...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n \r\n if (!(await fs.pathExists(dockerComposePath))) {\r\n s.stop('Docker Compose file not found');\r\n return;\r\n }\r\n\r\n const resolvedContainers = resolveContainerDependencies(selectedContainers);\r\n const addedDependencies = resolvedContainers.filter(c => !selectedContainers.includes(c));\r\n \r\n if (addedDependencies.length > 0) {\r\n s.message(`Auto-including dependencies: ${color.cyan(addedDependencies.join(', '))}`);\r\n }\r\n\r\n let content = await fs.readFile(dockerComposePath, 'utf8');\r\n\r\n const allContainers = Object.keys(DOCKER_CONTAINERS) as DockerContainer[];\r\n const containersToRemove = allContainers.filter(c => !resolvedContainers.includes(c));\r\n\r\n for (const container of containersToRemove) {\r\n const containerRegex = new RegExp(\r\n ` # -- ${container} --\\\\n[\\\\s\\\\S]*? # // ${container} //\\\\n`,\r\n 'g'\r\n );\r\n content = content.replace(containerRegex, '');\r\n\r\n // delete `./docker/<container>/`\r\n const dockerDirPath = path.join(projectDir, 'docker', container);\r\n if (await fs.pathExists(dockerDirPath)) {\r\n await fs.remove(dockerDirPath);\r\n s.message(`Removed ${color.cyan(dockerDirPath)}`);\r\n }\r\n }\r\n\r\n content = content.replace(/ # -- \\w+ --\\n/g, '');\r\n content = content.replace(/ # \\/\\/ \\w+ \\/\\/\\n/g, '');\r\n\r\n await fs.writeFile(dockerComposePath, content);\r\n\r\n // check if `./docker/` is empty\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir) && (await fs.readdir(dockerDir)).length === 0) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)} ${color.gray('(because it was empty)')}`);\r\n }\r\n \r\n s.stop(`Configured Docker Compose with ${color.cyan(resolvedContainers.length)} container(s)`);\r\n } catch (error) {\r\n s.stop('Failed to configure Docker Compose');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function removePackages(\r\n packages: string[],\r\n packagePath: string,\r\n projectDir: string,\r\n s?: ReturnType<typeof spinner>\r\n) {\r\n const packageJsonPath = path.join(projectDir, packagePath, 'package.json');\r\n if (await fs.pathExists(packageJsonPath)) {\r\n const packageJson = await fs.readJson(packageJsonPath);\r\n let hasChanges = false;\r\n\r\n for (const dep of packages) {\r\n if (packageJson.dependencies && packageJson.dependencies[dep]) {\r\n delete packageJson.dependencies[dep];\r\n hasChanges = true;\r\n if (s) {\r\n s.message(`Removed ${color.cyan(dep)} from ${packagePath}/package.json`);\r\n }\r\n }\r\n }\r\n\r\n if (hasChanges) {\r\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });\r\n }\r\n }\r\n}\r\n\r\nexport async function removeReactEmail(projectDir: string) {\r\n const s = spinner();\r\n s.start('Removing react-email...');\r\n\r\n try {\r\n // remove email package\r\n const emailPackagePath = path.join(projectDir, 'packages', 'email');\r\n if (await fs.pathExists(emailPackagePath)) {\r\n await fs.remove(emailPackagePath);\r\n s.message(`Removed ${color.cyan(emailPackagePath)}`);\r\n }\r\n\r\n // remove @react-email/components from packages/api/package.json\r\n await removePackages(['@react-email/components', '@acme/email'], 'packages/api', projectDir, s);\r\n\r\n s.stop('Removed react-email');\r\n } catch (error) {\r\n s.stop('Failed to remove react-email');\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import {
|
|
2
3
|
getInstallCommand
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WQABKQSK.js";
|
|
4
5
|
|
|
5
6
|
// src/helpers/install.ts
|
|
6
7
|
import { execa } from "execa";
|
|
@@ -45,4 +46,4 @@ export {
|
|
|
45
46
|
installDependencies,
|
|
46
47
|
initializeGit
|
|
47
48
|
};
|
|
48
|
-
//# sourceMappingURL=chunk-
|
|
49
|
+
//# sourceMappingURL=chunk-KMVM4I6J.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helpers/install.ts"],"sourcesContent":["import { execa } from 'execa';\r\nimport { spinner } from '@clack/prompts';\r\nimport { type PackageManager, getInstallCommand } from '../utils/package-manager.js';\r\nimport color from 'picocolors';\r\n\r\nexport async function installDependencies(projectDir: string, packageManager: PackageManager) {\r\n const s = spinner();\r\n s.start(`Installing dependencies with ${color.cyan(packageManager)}...`);\r\n\r\n const installCmd = getInstallCommand(packageManager);\r\n const [command = \"npm\", ...args] = installCmd.split(' ');\r\n\r\n try {\r\n await execa(command, args, {\r\n cwd: projectDir,\r\n });\r\n s.stop(`Installed dependencies`);\r\n } catch (error) {\r\n s.stop(`Failed to install dependencies`);\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function initializeGit(projectDir: string) {\r\n const s = spinner();\r\n s.start('Initializing git repository...');\r\n\r\n try {\r\n await execa('git', ['init'], {\r\n cwd: projectDir,\r\n });\r\n await execa('git', ['add', '.'], {\r\n cwd: projectDir,\r\n });\r\n await execa('git', ['commit', '-m', 'Initial commit'], {\r\n cwd: projectDir,\r\n });\r\n\r\n s.stop('Initialized git repository');\r\n } catch (error) {\r\n s.stop('Failed to initialize git repository');\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/helpers/install.ts"],"sourcesContent":["import { execa } from 'execa';\r\nimport { spinner } from '@clack/prompts';\r\nimport { type PackageManager, getInstallCommand } from '../utils/package-manager.js';\r\nimport color from 'picocolors';\r\n\r\nexport async function installDependencies(projectDir: string, packageManager: PackageManager) {\r\n const s = spinner();\r\n s.start(`Installing dependencies with ${color.cyan(packageManager)}...`);\r\n\r\n const installCmd = getInstallCommand(packageManager);\r\n const [command = \"npm\", ...args] = installCmd.split(' ');\r\n\r\n try {\r\n await execa(command, args, {\r\n cwd: projectDir,\r\n });\r\n s.stop(`Installed dependencies`);\r\n } catch (error) {\r\n s.stop(`Failed to install dependencies`);\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function initializeGit(projectDir: string) {\r\n const s = spinner();\r\n s.start('Initializing git repository...');\r\n\r\n try {\r\n await execa('git', ['init'], {\r\n cwd: projectDir,\r\n });\r\n await execa('git', ['add', '.'], {\r\n cwd: projectDir,\r\n });\r\n await execa('git', ['commit', '-m', 'Initial commit'], {\r\n cwd: projectDir,\r\n });\r\n\r\n s.stop('Initialized git repository');\r\n } catch (error) {\r\n s.stop('Failed to initialize git repository');\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":";;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,eAAe;AAExB,OAAO,WAAW;AAElB,eAAsB,oBAAoB,YAAoB,gBAAgC;AAC5F,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,gCAAgC,MAAM,KAAK,cAAc,CAAC,KAAK;AAEvE,QAAM,aAAa,kBAAkB,cAAc;AACnD,QAAM,CAAC,UAAU,OAAO,GAAG,IAAI,IAAI,WAAW,MAAM,GAAG;AAEvD,MAAI;AACF,UAAM,MAAM,SAAS,MAAM;AAAA,MACzB,KAAK;AAAA,IACP,CAAC;AACD,MAAE,KAAK,wBAAwB;AAAA,EACjC,SAAS,OAAO;AACd,MAAE,KAAK,gCAAgC;AACvC,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,cAAc,YAAoB;AACtD,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,gCAAgC;AAExC,MAAI;AACF,UAAM,MAAM,OAAO,CAAC,MAAM,GAAG;AAAA,MAC3B,KAAK;AAAA,IACP,CAAC;AACD,UAAM,MAAM,OAAO,CAAC,OAAO,GAAG,GAAG;AAAA,MAC/B,KAAK;AAAA,IACP,CAAC;AACD,UAAM,MAAM,OAAO,CAAC,UAAU,MAAM,gBAAgB,GAAG;AAAA,MACrD,KAAK;AAAA,IACP,CAAC;AAED,MAAE,KAAK,4BAA4B;AAAA,EACrC,SAAS,OAAO;AACd,MAAE,KAAK,qCAAqC;AAC5C,UAAM;AAAA,EACR;AACF;","names":[]}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import {
|
|
2
3
|
getRunner
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WQABKQSK.js";
|
|
4
5
|
|
|
5
6
|
// src/helpers/scaffold.ts
|
|
6
7
|
import { execa } from "execa";
|
|
7
8
|
import { spinner } from "@clack/prompts";
|
|
8
9
|
import color from "picocolors";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import fs from "fs-extra";
|
|
9
12
|
async function scaffoldProject({ projectName, packageManager }) {
|
|
10
13
|
const s = spinner();
|
|
11
14
|
s.start(`Scaffolding project in ${color.cyan(projectName)}...`);
|
|
@@ -23,6 +26,7 @@ async function scaffoldProject({ projectName, packageManager }) {
|
|
|
23
26
|
"--no-git",
|
|
24
27
|
projectName
|
|
25
28
|
]);
|
|
29
|
+
await fs.remove(path.join(projectName, "pnpm-lock.yaml"));
|
|
26
30
|
s.stop(`Scaffolded project in ${color.cyan(projectName)}`);
|
|
27
31
|
} catch (error) {
|
|
28
32
|
s.stop(`Failed to scaffold project`);
|
|
@@ -33,4 +37,4 @@ async function scaffoldProject({ projectName, packageManager }) {
|
|
|
33
37
|
export {
|
|
34
38
|
scaffoldProject
|
|
35
39
|
};
|
|
36
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-RB52EE5W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers/scaffold.ts"],"sourcesContent":["import { execa } from 'execa';\r\nimport { spinner } from '@clack/prompts';\r\nimport { type PackageManager, getRunner } from '../utils/package-manager.js';\r\nimport color from 'picocolors';\r\nimport path from 'path';\r\nimport fs from 'fs-extra';\r\n\r\nexport interface ScaffoldOptions {\r\n projectName: string;\r\n packageManager: PackageManager;\r\n}\r\n\r\nexport async function scaffoldProject({ projectName, packageManager }: ScaffoldOptions) {\r\n const s = spinner();\r\n s.start(`Scaffolding project in ${color.cyan(projectName)}...`);\r\n\r\n const runner = getRunner(packageManager);\r\n const [command = 'npx', ...args] = runner.split(' ');\r\n \r\n try {\r\n await execa(command, [\r\n ...args,\r\n 'create-turbo@latest',\r\n '-e',\r\n 'https://github.com/Badbird5907/turbo-kit',\r\n '--package-manager',\r\n packageManager,\r\n '--skip-install',\r\n '--no-git',\r\n projectName\r\n ]);\r\n \r\n\r\n await fs.remove(path.join(projectName, 'pnpm-lock.yaml'));\r\n // we are removing the lockfile as we may be deleting some packages\r\n\r\n s.stop(`Scaffolded project in ${color.cyan(projectName)}`);\r\n } catch (error) {\r\n s.stop(`Failed to scaffold project`);\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":";;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,eAAe;AAExB,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,OAAO,QAAQ;AAOf,eAAsB,gBAAgB,EAAE,aAAa,eAAe,GAAoB;AACtF,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,0BAA0B,MAAM,KAAK,WAAW,CAAC,KAAK;AAE9D,QAAM,SAAS,UAAU,cAAc;AACvC,QAAM,CAAC,UAAU,OAAO,GAAG,IAAI,IAAI,OAAO,MAAM,GAAG;AAEnD,MAAI;AACF,UAAM,MAAM,SAAS;AAAA,MACnB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,UAAM,GAAG,OAAO,KAAK,KAAK,aAAa,gBAAgB,CAAC;AAGxD,MAAE,KAAK,yBAAyB,MAAM,KAAK,WAAW,CAAC,EAAE;AAAA,EAC3D,SAAS,OAAO;AACd,MAAE,KAAK,4BAA4B;AACnC,UAAM;AAAA,EACR;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/package-manager.ts"],"sourcesContent":["export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\r\n\r\nexport function getRunner(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'npm':\r\n return 'npx';\r\n case 'pnpm':\r\n return 'pnpm dlx';\r\n case 'yarn':\r\n return 'yarn dlx';\r\n case 'bun':\r\n return 'bunx';\r\n default:\r\n return 'npx';\r\n }\r\n}\r\n\r\nexport function getInstallCommand(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'npm':\r\n return 'npm install';\r\n case 'pnpm':\r\n return 'pnpm install';\r\n case 'yarn':\r\n return 'yarn install';\r\n case 'bun':\r\n return 'bun install';\r\n default:\r\n return 'npm install';\r\n }\r\n}\r\n\r\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/utils/package-manager.ts"],"sourcesContent":["export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\r\n\r\nexport function getRunner(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'npm':\r\n return 'npx';\r\n case 'pnpm':\r\n return 'pnpm dlx';\r\n case 'yarn':\r\n return 'yarn dlx';\r\n case 'bun':\r\n return 'bunx';\r\n default:\r\n return 'npx';\r\n }\r\n}\r\n\r\nexport function getInstallCommand(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'npm':\r\n return 'npm install';\r\n case 'pnpm':\r\n return 'pnpm install';\r\n case 'yarn':\r\n return 'yarn install';\r\n case 'bun':\r\n return 'bun install';\r\n default:\r\n return 'npm install';\r\n }\r\n}\r\n\r\n"],"mappings":";;;AAEO,SAAS,UAAU,IAA4B;AACpD,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,kBAAkB,IAA4B;AAC5D,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { }
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
#!/usr/bin/env node
|
|
1
3
|
import {
|
|
2
4
|
initializeGit,
|
|
3
5
|
installDependencies
|
|
4
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KMVM4I6J.js";
|
|
5
7
|
import {
|
|
6
8
|
scaffoldProject
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RB52EE5W.js";
|
|
8
10
|
import {
|
|
9
11
|
configureDockerCompose,
|
|
10
12
|
deleteDockerCompose,
|
|
11
13
|
getDockerContainers,
|
|
14
|
+
removeReactEmail,
|
|
12
15
|
replaceScope,
|
|
13
16
|
setupEnv
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-2D3EEOSU.js";
|
|
18
|
+
import "./chunk-WQABKQSK.js";
|
|
16
19
|
|
|
17
20
|
// src/cli.ts
|
|
18
21
|
import { intro, outro, text, select, isCancel, cancel, confirm, multiselect } from "@clack/prompts";
|
|
@@ -132,6 +135,19 @@ Your import statements will look like this: ${importStatement}`,
|
|
|
132
135
|
} else {
|
|
133
136
|
await deleteDockerCompose(projectDir);
|
|
134
137
|
}
|
|
138
|
+
const wantsReactEmail = await confirm({
|
|
139
|
+
message: "Do you want to use react-email?",
|
|
140
|
+
initialValue: true
|
|
141
|
+
});
|
|
142
|
+
if (isCancel(wantsReactEmail)) {
|
|
143
|
+
cancel("Operation cancelled.");
|
|
144
|
+
process.exit(0);
|
|
145
|
+
}
|
|
146
|
+
if (!wantsReactEmail) {
|
|
147
|
+
await removeReactEmail(projectDir);
|
|
148
|
+
}
|
|
149
|
+
await replaceScope(projectDir, scope);
|
|
150
|
+
await setupEnv(projectDir);
|
|
135
151
|
const shouldInstall = await confirm({
|
|
136
152
|
message: "Do you want to install dependencies now?",
|
|
137
153
|
initialValue: true
|
|
@@ -140,8 +156,6 @@ Your import statements will look like this: ${importStatement}`,
|
|
|
140
156
|
cancel("Operation cancelled.");
|
|
141
157
|
process.exit(0);
|
|
142
158
|
}
|
|
143
|
-
await replaceScope(projectDir, scope);
|
|
144
|
-
await setupEnv(projectDir);
|
|
145
159
|
if (shouldInstall) {
|
|
146
160
|
await installDependencies(projectDir, packageManager);
|
|
147
161
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { intro, outro, text, select, isCancel, cancel, confirm, multiselect } from '@clack/prompts';\r\nimport { Command } from 'commander';\r\nimport color from 'picocolors';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { replaceScope, setupEnv, getDockerContainers, configureDockerCompose, deleteDockerCompose } from './helpers/transform.js';\r\nimport { installDependencies, initializeGit } from './helpers/install.js';\r\nimport { type PackageManager } from './utils/package-manager.js';\r\nimport { scaffoldProject } from './helpers/scaffold.js';\r\n\r\nasync function main() {\r\n const program = new Command();\r\n \r\n program\r\n .name('create-turbo-kit')\r\n .description('Initialize a custom turborepo template')\r\n .argument('[project-name]', 'Name of the project directory')\r\n .parse(process.argv);\r\n\r\n const args = program.args;\r\n let projectName = args[0];\r\n\r\n console.log();\r\n intro(color.bgCyan(color.black(' Create Turbo Kit ')));\r\n\r\n if (!projectName) {\r\n const pName = await text({\r\n message: 'What is your project named?',\r\n placeholder: 'my-turbo-app',\r\n validate: (value) => {\r\n if (!value) return 'Please enter a name.';\r\n if (/[^a-zA-Z0-9-_]/.test(value)) return 'Project name can only contain letters, numbers, dashes and underscores.';\r\n const projectDir = path.resolve(process.cwd(), value);\r\n if (fs.pathExistsSync(projectDir)) {\r\n return 'Project name already taken.';\r\n }\r\n return undefined;\r\n },\r\n });\r\n\r\n if (isCancel(pName)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n projectName = pName as string;\r\n }\r\n\r\n const projectDir = path.resolve(process.cwd(), projectName);\r\n\r\n if (await fs.pathExists(projectDir)) {\r\n const shouldOverwrite = await confirm({\r\n message: `Directory ${projectName} already exists. Do you want to overwrite it?`,\r\n initialValue: false,\r\n });\r\n\r\n if (isCancel(shouldOverwrite) || !shouldOverwrite) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n \r\n await fs.remove(projectDir);\r\n }\r\n\r\n const packageManager = await select({\r\n message: 'Which package manager do you want to use?',\r\n options: [\r\n { value: 'pnpm', label: 'pnpm' },\r\n { value: 'npm', label: 'npm' },\r\n { value: 'yarn', label: 'yarn' },\r\n { value: 'bun', label: 'bun' },\r\n ],\r\n });\r\n\r\n if (isCancel(packageManager)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n const getScope = async (): Promise<string> => {\r\n const scope = await text({\r\n message: 'What is your package scope?',\r\n placeholder: '@my-org',\r\n validate: (value) => {\r\n if (!value) return 'Please enter a scope.';\r\n },\r\n });\r\n \r\n if (isCancel(scope)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n const check = [\"@\", \"~\", \"$\", \"#\", \"!\"];\r\n if (!check.includes(scope[0] as string)) {\r\n // ask the user to confirm this is the correct scope\r\n const importStatement = `${color.magenta(\"import\")} ${color.yellow(\"{\")} ${color.cyan(\"example\")} ${color.yellow(\"}\")} ${color.magenta(\"from\")} ${color.cyan(`\"${scope}/example\"`)}`;\r\n const confirmScope = await confirm({\r\n message: `Is ${color.cyan(scope)} the correct scope?\\nYour import statements will look like this: ${importStatement}`,\r\n initialValue: true,\r\n });\r\n if (isCancel(confirmScope) || !confirmScope) {\r\n return await getScope();\r\n }\r\n }\r\n\r\n return scope as string;\r\n }\r\n const scope = await getScope();\r\n\r\n try {\r\n await scaffoldProject({\r\n projectName,\r\n packageManager: packageManager as PackageManager,\r\n });\r\n\r\n const wantsDocker = await confirm({\r\n message: 'Do you want to set up a local Docker Compose dev environment?',\r\n initialValue: true,\r\n });\r\n\r\n if (isCancel(wantsDocker)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n if (wantsDocker) {\r\n const dockerContainers = getDockerContainers();\r\n const containers = await multiselect({\r\n message: 'Which containers do you want to include?',\r\n options: dockerContainers,\r\n initialValues: dockerContainers.map((container) => container.value),\r\n required: false,\r\n });\r\n\r\n if (isCancel(containers)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n if (Array.isArray(containers) && containers.length > 0) {\r\n await configureDockerCompose(projectDir, containers as string[]);\r\n } else {\r\n await deleteDockerCompose(projectDir);\r\n }\r\n } else {\r\n await deleteDockerCompose(projectDir);\r\n }\r\n\r\n const shouldInstall = await confirm({\r\n message: 'Do you want to install dependencies now?',\r\n initialValue: true,\r\n });\r\n\r\n if (isCancel(shouldInstall)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n await replaceScope(projectDir, scope as string);\r\n await setupEnv(projectDir);\r\n \r\n if (shouldInstall) {\r\n await installDependencies(projectDir, packageManager as PackageManager);\r\n }\r\n\r\n await initializeGit(projectDir);\r\n\r\n outro(color.green('Project initialized successfully!'));\r\n \r\n console.log(`To get started:`);\r\n console.log(color.cyan(` cd ${projectName}`));\r\n if (!shouldInstall) {\r\n console.log(color.cyan(` ${packageManager} install`));\r\n }\r\n if (wantsDocker) {\r\n console.log(color.cyan(` docker compose up -d`));\r\n }\r\n console.log(color.cyan(` ${packageManager} run dev`));\r\n \r\n console.log();\r\n console.log(color.greenBright(\"Happy Hacking!\"))\r\n } catch (error) {\r\n console.error(color.red('An error occurred:'), error);\r\n process.exit(1);\r\n }\r\n}\r\n\r\nmain().catch(console.error);\r\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,OAAO,OAAO,MAAM,QAAQ,UAAU,QAAQ,SAAS,mBAAmB;AACnF,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,QAAQ;AACf,OAAO,UAAU;AAMjB,eAAe,OAAO;AACpB,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,kBAAkB,EACvB,YAAY,wCAAwC,EACpD,SAAS,kBAAkB,+BAA+B,EAC1D,MAAM,QAAQ,IAAI;AAErB,QAAM,OAAO,QAAQ;AACrB,MAAI,cAAc,KAAK,CAAC;AAExB,UAAQ,IAAI;AACZ,QAAM,MAAM,OAAO,MAAM,MAAM,oBAAoB,CAAC,CAAC;AAErD,MAAI,CAAC,aAAa;AAChB,UAAM,QAAQ,MAAM,KAAK;AAAA,MACvB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AACnB,YAAI,iBAAiB,KAAK,KAAK,EAAG,QAAO;AACzC,cAAMA,cAAa,KAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;AACpD,YAAI,GAAG,eAAeA,WAAU,GAAG;AACjC,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,QAAI,SAAS,KAAK,GAAG;AACnB,aAAO,sBAAsB;AAC7B,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,kBAAc;AAAA,EAChB;AAEA,QAAM,aAAa,KAAK,QAAQ,QAAQ,IAAI,GAAG,WAAW;AAE1D,MAAI,MAAM,GAAG,WAAW,UAAU,GAAG;AACnC,UAAM,kBAAkB,MAAM,QAAQ;AAAA,MACpC,SAAS,aAAa,WAAW;AAAA,MACjC,cAAc;AAAA,IAChB,CAAC;AAED,QAAI,SAAS,eAAe,KAAK,CAAC,iBAAiB;AACjD,aAAO,sBAAsB;AAC7B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,GAAG,OAAO,UAAU;AAAA,EAC5B;AAEA,QAAM,iBAAiB,MAAM,OAAO;AAAA,IAClC,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,MAC/B,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,MAC7B,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,MAC/B,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,IAC/B;AAAA,EACF,CAAC;AAED,MAAI,SAAS,cAAc,GAAG;AAC5B,WAAO,sBAAsB;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,YAA6B;AAC5C,UAAMC,SAAQ,MAAM,KAAK;AAAA,MACvB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AAAA,MACrB;AAAA,IACF,CAAC;AAED,QAAI,SAASA,MAAK,GAAG;AACnB,aAAO,sBAAsB;AAC7B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG;AACtC,QAAI,CAAC,MAAM,SAASA,OAAM,CAAC,CAAW,GAAG;AAEvC,YAAM,kBAAkB,GAAG,MAAM,QAAQ,QAAQ,CAAC,IAAI,MAAM,OAAO,GAAG,CAAC,IAAI,MAAM,KAAK,SAAS,CAAC,IAAI,MAAM,OAAO,GAAG,CAAC,IAAI,MAAM,QAAQ,MAAM,CAAC,IAAI,MAAM,KAAK,IAAIA,MAAK,WAAW,CAAC;AAClL,YAAM,eAAe,MAAM,QAAQ;AAAA,QACjC,SAAS,MAAM,MAAM,KAAKA,MAAK,CAAC;AAAA,8CAAoE,eAAe;AAAA,QACnH,cAAc;AAAA,MAChB,CAAC;AACD,UAAI,SAAS,YAAY,KAAK,CAAC,cAAc;AAC3C,eAAO,MAAM,SAAS;AAAA,MACxB;AAAA,IACF;AAEA,WAAOA;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,SAAS;AAE7B,MAAI;AACF,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,cAAc,MAAM,QAAQ;AAAA,MAChC,SAAS;AAAA,MACT,cAAc;AAAA,IAChB,CAAC;AAED,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,sBAAsB;AAC7B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,aAAa;AACf,YAAM,mBAAmB,oBAAoB;AAC7C,YAAM,aAAa,MAAM,YAAY;AAAA,QACnC,SAAS;AAAA,QACT,SAAS;AAAA,QACT,eAAe,iBAAiB,IAAI,CAAC,cAAc,UAAU,KAAK;AAAA,QAClE,UAAU;AAAA,MACZ,CAAC;AAED,UAAI,SAAS,UAAU,GAAG;AACxB,eAAO,sBAAsB;AAC7B,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,MAAM,QAAQ,UAAU,KAAK,WAAW,SAAS,GAAG;AACtD,cAAM,uBAAuB,YAAY,UAAsB;AAAA,MACjE,OAAO;AACL,cAAM,oBAAoB,UAAU;AAAA,MACtC;AAAA,IACF,OAAO;AACL,YAAM,oBAAoB,UAAU;AAAA,IACtC;AAEA,UAAM,gBAAgB,MAAM,QAAQ;AAAA,MAClC,SAAS;AAAA,MACT,cAAc;AAAA,IAChB,CAAC;AAED,QAAI,SAAS,aAAa,GAAG;AAC3B,aAAO,sBAAsB;AAC7B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,aAAa,YAAY,KAAe;AAC9C,UAAM,SAAS,UAAU;AAEzB,QAAI,eAAe;AACjB,YAAM,oBAAoB,YAAY,cAAgC;AAAA,IACxE;AAEA,UAAM,cAAc,UAAU;AAE9B,UAAM,MAAM,MAAM,mCAAmC,CAAC;AAEtD,YAAQ,IAAI,iBAAiB;AAC7B,YAAQ,IAAI,MAAM,KAAK,QAAQ,WAAW,EAAE,CAAC;AAC7C,QAAI,CAAC,eAAe;AAClB,cAAQ,IAAI,MAAM,KAAK,KAAK,cAAc,UAAU,CAAC;AAAA,IACvD;AACA,QAAI,aAAa;AACf,cAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAAA,IAClD;AACA,YAAQ,IAAI,MAAM,KAAK,KAAK,cAAc,UAAU,CAAC;AAErD,YAAQ,IAAI;AACZ,YAAQ,IAAI,MAAM,YAAY,gBAAgB,CAAC;AAAA,EACjD,SAAS,OAAO;AACd,YAAQ,MAAM,MAAM,IAAI,oBAAoB,GAAG,KAAK;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,KAAK,EAAE,MAAM,QAAQ,KAAK;","names":["projectDir","scope"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { intro, outro, text, select, isCancel, cancel, confirm, multiselect } from '@clack/prompts';\r\nimport { Command } from 'commander';\r\nimport color from 'picocolors';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { replaceScope, setupEnv, getDockerContainers, configureDockerCompose, deleteDockerCompose, removeReactEmail } from './helpers/transform.js';\r\nimport { installDependencies, initializeGit } from './helpers/install.js';\r\nimport { type PackageManager } from './utils/package-manager.js';\r\nimport { scaffoldProject } from './helpers/scaffold.js';\r\n\r\nasync function main() {\r\n const program = new Command();\r\n \r\n program\r\n .name('create-turbo-kit')\r\n .description('Initialize a custom turborepo template')\r\n .argument('[project-name]', 'Name of the project directory')\r\n .parse(process.argv);\r\n\r\n const args = program.args;\r\n let projectName = args[0];\r\n\r\n console.log();\r\n intro(color.bgCyan(color.black(' Create Turbo Kit ')));\r\n\r\n if (!projectName) {\r\n const pName = await text({\r\n message: 'What is your project named?',\r\n placeholder: 'my-turbo-app',\r\n validate: (value) => {\r\n if (!value) return 'Please enter a name.';\r\n if (/[^a-zA-Z0-9-_]/.test(value)) return 'Project name can only contain letters, numbers, dashes and underscores.';\r\n const projectDir = path.resolve(process.cwd(), value);\r\n if (fs.pathExistsSync(projectDir)) {\r\n return 'Project name already taken.';\r\n }\r\n return undefined;\r\n },\r\n });\r\n\r\n if (isCancel(pName)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n projectName = pName as string;\r\n }\r\n\r\n const projectDir = path.resolve(process.cwd(), projectName);\r\n\r\n if (await fs.pathExists(projectDir)) {\r\n const shouldOverwrite = await confirm({\r\n message: `Directory ${projectName} already exists. Do you want to overwrite it?`,\r\n initialValue: false,\r\n });\r\n\r\n if (isCancel(shouldOverwrite) || !shouldOverwrite) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n \r\n await fs.remove(projectDir);\r\n }\r\n\r\n const packageManager = await select({\r\n message: 'Which package manager do you want to use?',\r\n options: [\r\n { value: 'pnpm', label: 'pnpm' },\r\n { value: 'npm', label: 'npm' },\r\n { value: 'yarn', label: 'yarn' },\r\n { value: 'bun', label: 'bun' },\r\n ],\r\n });\r\n\r\n if (isCancel(packageManager)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n const getScope = async (): Promise<string> => {\r\n const scope = await text({\r\n message: 'What is your package scope?',\r\n placeholder: '@my-org',\r\n validate: (value) => {\r\n if (!value) return 'Please enter a scope.';\r\n },\r\n });\r\n \r\n if (isCancel(scope)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n const check = [\"@\", \"~\", \"$\", \"#\", \"!\"];\r\n if (!check.includes(scope[0] as string)) {\r\n // ask the user to confirm this is the correct scope\r\n const importStatement = `${color.magenta(\"import\")} ${color.yellow(\"{\")} ${color.cyan(\"example\")} ${color.yellow(\"}\")} ${color.magenta(\"from\")} ${color.cyan(`\"${scope}/example\"`)}`;\r\n const confirmScope = await confirm({\r\n message: `Is ${color.cyan(scope)} the correct scope?\\nYour import statements will look like this: ${importStatement}`,\r\n initialValue: true,\r\n });\r\n if (isCancel(confirmScope) || !confirmScope) {\r\n return await getScope();\r\n }\r\n }\r\n\r\n return scope as string;\r\n }\r\n const scope = await getScope();\r\n\r\n try {\r\n await scaffoldProject({\r\n projectName,\r\n packageManager: packageManager as PackageManager,\r\n });\r\n\r\n const wantsDocker = await confirm({\r\n message: 'Do you want to set up a local Docker Compose dev environment?',\r\n initialValue: true,\r\n });\r\n\r\n if (isCancel(wantsDocker)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n if (wantsDocker) {\r\n const dockerContainers = getDockerContainers();\r\n const containers = await multiselect({\r\n message: 'Which containers do you want to include?',\r\n options: dockerContainers,\r\n initialValues: dockerContainers.map((container) => container.value),\r\n required: false,\r\n });\r\n\r\n if (isCancel(containers)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n if (Array.isArray(containers) && containers.length > 0) {\r\n await configureDockerCompose(projectDir, containers as string[]);\r\n } else {\r\n await deleteDockerCompose(projectDir);\r\n }\r\n } else {\r\n await deleteDockerCompose(projectDir);\r\n }\r\n const wantsReactEmail = await confirm({\r\n message: 'Do you want to use react-email?',\r\n initialValue: true,\r\n });\r\n\r\n if (isCancel(wantsReactEmail)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n if (!wantsReactEmail) {\r\n await removeReactEmail(projectDir);\r\n }\r\n \r\n await replaceScope(projectDir, scope as string);\r\n await setupEnv(projectDir);\r\n \r\n const shouldInstall = await confirm({\r\n message: 'Do you want to install dependencies now?',\r\n initialValue: true,\r\n });\r\n\r\n if (isCancel(shouldInstall)) {\r\n cancel('Operation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n if (shouldInstall) {\r\n await installDependencies(projectDir, packageManager as PackageManager);\r\n }\r\n\r\n await initializeGit(projectDir);\r\n\r\n outro(color.green('Project initialized successfully!'));\r\n \r\n console.log(`To get started:`);\r\n console.log(color.cyan(` cd ${projectName}`));\r\n if (!shouldInstall) {\r\n console.log(color.cyan(` ${packageManager} install`));\r\n }\r\n if (wantsDocker) {\r\n console.log(color.cyan(` docker compose up -d`));\r\n }\r\n console.log(color.cyan(` ${packageManager} run dev`));\r\n \r\n console.log();\r\n console.log(color.greenBright(\"Happy Hacking!\"))\r\n } catch (error) {\r\n console.error(color.red('An error occurred:'), error);\r\n process.exit(1);\r\n }\r\n}\r\n\r\nmain().catch(console.error);\r\n"],"mappings":"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","names":["projectDir","scope"]}
|
package/dist/helpers/install.js
CHANGED
package/dist/helpers/scaffold.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { spinner } from '@clack/prompts';
|
|
2
|
+
|
|
1
3
|
declare const DOCKER_CONTAINERS: {
|
|
2
4
|
readonly postgres: {
|
|
3
5
|
readonly label: "PostgreSQL 16 (Database)";
|
|
@@ -39,5 +41,7 @@ declare function getDockerContainers(): {
|
|
|
39
41
|
}[];
|
|
40
42
|
declare function deleteDockerCompose(projectDir: string): Promise<void>;
|
|
41
43
|
declare function configureDockerCompose(projectDir: string, selectedContainers: string[]): Promise<void>;
|
|
44
|
+
declare function removePackages(packages: string[], packagePath: string, projectDir: string, s?: ReturnType<typeof spinner>): Promise<void>;
|
|
45
|
+
declare function removeReactEmail(projectDir: string): Promise<void>;
|
|
42
46
|
|
|
43
|
-
export { type DockerContainer, configureDockerCompose, deleteDockerCompose, getDockerContainers, replaceScope, setupEnv };
|
|
47
|
+
export { type DockerContainer, configureDockerCompose, deleteDockerCompose, getDockerContainers, removePackages, removeReactEmail, replaceScope, setupEnv };
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import {
|
|
2
3
|
configureDockerCompose,
|
|
3
4
|
deleteDockerCompose,
|
|
4
5
|
getDockerContainers,
|
|
6
|
+
removePackages,
|
|
7
|
+
removeReactEmail,
|
|
5
8
|
replaceScope,
|
|
6
9
|
setupEnv
|
|
7
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-2D3EEOSU.js";
|
|
8
11
|
export {
|
|
9
12
|
configureDockerCompose,
|
|
10
13
|
deleteDockerCompose,
|
|
11
14
|
getDockerContainers,
|
|
15
|
+
removePackages,
|
|
16
|
+
removeReactEmail,
|
|
12
17
|
replaceScope,
|
|
13
18
|
setupEnv
|
|
14
19
|
};
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
import { intro, outro, text, select, isCancel, cancel, confirm, multiselect } from '@clack/prompts';
|
|
2
4
|
import { Command } from 'commander';
|
|
3
5
|
import color from 'picocolors';
|
|
4
6
|
import fs from 'fs-extra';
|
|
5
7
|
import path from 'path';
|
|
6
|
-
import { replaceScope, setupEnv, getDockerContainers, configureDockerCompose, deleteDockerCompose } from './helpers/transform.js';
|
|
8
|
+
import { replaceScope, setupEnv, getDockerContainers, configureDockerCompose, deleteDockerCompose, removeReactEmail } from './helpers/transform.js';
|
|
7
9
|
import { installDependencies, initializeGit } from './helpers/install.js';
|
|
8
10
|
import { type PackageManager } from './utils/package-manager.js';
|
|
9
11
|
import { scaffoldProject } from './helpers/scaffold.js';
|
|
@@ -145,7 +147,23 @@ async function main() {
|
|
|
145
147
|
} else {
|
|
146
148
|
await deleteDockerCompose(projectDir);
|
|
147
149
|
}
|
|
150
|
+
const wantsReactEmail = await confirm({
|
|
151
|
+
message: 'Do you want to use react-email?',
|
|
152
|
+
initialValue: true,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (isCancel(wantsReactEmail)) {
|
|
156
|
+
cancel('Operation cancelled.');
|
|
157
|
+
process.exit(0);
|
|
158
|
+
}
|
|
148
159
|
|
|
160
|
+
if (!wantsReactEmail) {
|
|
161
|
+
await removeReactEmail(projectDir);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await replaceScope(projectDir, scope as string);
|
|
165
|
+
await setupEnv(projectDir);
|
|
166
|
+
|
|
149
167
|
const shouldInstall = await confirm({
|
|
150
168
|
message: 'Do you want to install dependencies now?',
|
|
151
169
|
initialValue: true,
|
|
@@ -156,9 +174,6 @@ async function main() {
|
|
|
156
174
|
process.exit(0);
|
|
157
175
|
}
|
|
158
176
|
|
|
159
|
-
await replaceScope(projectDir, scope as string);
|
|
160
|
-
await setupEnv(projectDir);
|
|
161
|
-
|
|
162
177
|
if (shouldInstall) {
|
|
163
178
|
await installDependencies(projectDir, packageManager as PackageManager);
|
|
164
179
|
}
|
package/src/helpers/scaffold.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { execa } from 'execa';
|
|
|
2
2
|
import { spinner } from '@clack/prompts';
|
|
3
3
|
import { type PackageManager, getRunner } from '../utils/package-manager.js';
|
|
4
4
|
import color from 'picocolors';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import fs from 'fs-extra';
|
|
5
7
|
|
|
6
8
|
export interface ScaffoldOptions {
|
|
7
9
|
projectName: string;
|
|
@@ -27,7 +29,11 @@ export async function scaffoldProject({ projectName, packageManager }: ScaffoldO
|
|
|
27
29
|
'--no-git',
|
|
28
30
|
projectName
|
|
29
31
|
]);
|
|
30
|
-
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
await fs.remove(path.join(projectName, 'pnpm-lock.yaml'));
|
|
35
|
+
// we are removing the lockfile as we may be deleting some packages
|
|
36
|
+
|
|
31
37
|
s.stop(`Scaffolded project in ${color.cyan(projectName)}`);
|
|
32
38
|
} catch (error) {
|
|
33
39
|
s.stop(`Failed to scaffold project`);
|
package/src/helpers/transform.ts
CHANGED
|
@@ -197,3 +197,52 @@ export async function configureDockerCompose(projectDir: string, selectedContain
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
export async function removePackages(
|
|
201
|
+
packages: string[],
|
|
202
|
+
packagePath: string,
|
|
203
|
+
projectDir: string,
|
|
204
|
+
s?: ReturnType<typeof spinner>
|
|
205
|
+
) {
|
|
206
|
+
const packageJsonPath = path.join(projectDir, packagePath, 'package.json');
|
|
207
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
208
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
209
|
+
let hasChanges = false;
|
|
210
|
+
|
|
211
|
+
for (const dep of packages) {
|
|
212
|
+
if (packageJson.dependencies && packageJson.dependencies[dep]) {
|
|
213
|
+
delete packageJson.dependencies[dep];
|
|
214
|
+
hasChanges = true;
|
|
215
|
+
if (s) {
|
|
216
|
+
s.message(`Removed ${color.cyan(dep)} from ${packagePath}/package.json`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (hasChanges) {
|
|
222
|
+
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export async function removeReactEmail(projectDir: string) {
|
|
228
|
+
const s = spinner();
|
|
229
|
+
s.start('Removing react-email...');
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
// remove email package
|
|
233
|
+
const emailPackagePath = path.join(projectDir, 'packages', 'email');
|
|
234
|
+
if (await fs.pathExists(emailPackagePath)) {
|
|
235
|
+
await fs.remove(emailPackagePath);
|
|
236
|
+
s.message(`Removed ${color.cyan(emailPackagePath)}`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// remove @react-email/components from packages/api/package.json
|
|
240
|
+
await removePackages(['@react-email/components', '@acme/email'], 'packages/api', projectDir, s);
|
|
241
|
+
|
|
242
|
+
s.stop('Removed react-email');
|
|
243
|
+
} catch (error) {
|
|
244
|
+
s.stop('Failed to remove react-email');
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
package/tsup.config.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helpers/scaffold.ts"],"sourcesContent":["import { execa } from 'execa';\r\nimport { spinner } from '@clack/prompts';\r\nimport { type PackageManager, getRunner } from '../utils/package-manager.js';\r\nimport color from 'picocolors';\r\n\r\nexport interface ScaffoldOptions {\r\n projectName: string;\r\n packageManager: PackageManager;\r\n}\r\n\r\nexport async function scaffoldProject({ projectName, packageManager }: ScaffoldOptions) {\r\n const s = spinner();\r\n s.start(`Scaffolding project in ${color.cyan(projectName)}...`);\r\n\r\n const runner = getRunner(packageManager);\r\n const [command = 'npx', ...args] = runner.split(' ');\r\n \r\n try {\r\n await execa(command, [\r\n ...args,\r\n 'create-turbo@latest',\r\n '-e',\r\n 'https://github.com/Badbird5907/turbo-kit',\r\n '--package-manager',\r\n packageManager,\r\n '--skip-install',\r\n '--no-git',\r\n projectName\r\n ]);\r\n \r\n s.stop(`Scaffolded project in ${color.cyan(projectName)}`);\r\n } catch (error) {\r\n s.stop(`Failed to scaffold project`);\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":";;;;;AAAA,SAAS,aAAa;AACtB,SAAS,eAAe;AAExB,OAAO,WAAW;AAOlB,eAAsB,gBAAgB,EAAE,aAAa,eAAe,GAAoB;AACtF,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,0BAA0B,MAAM,KAAK,WAAW,CAAC,KAAK;AAE9D,QAAM,SAAS,UAAU,cAAc;AACvC,QAAM,CAAC,UAAU,OAAO,GAAG,IAAI,IAAI,OAAO,MAAM,GAAG;AAEnD,MAAI;AACF,UAAM,MAAM,SAAS;AAAA,MACnB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,MAAE,KAAK,yBAAyB,MAAM,KAAK,WAAW,CAAC,EAAE;AAAA,EAC3D,SAAS,OAAO;AACd,MAAE,KAAK,4BAA4B;AACnC,UAAM;AAAA,EACR;AACF;","names":[]}
|