create-tnt-stack 0.2.0 → 0.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/package.json +4 -3
- package/template/base/README.md +37 -17
- package/template/base/next.config.js +12 -0
- package/template/base/package.json +3 -1
- package/template/base/src/app/globals.css +0 -12
- package/template/base/src/app/page.tsx +79 -87
- package/template/base/tsconfig.json +21 -6
- package/dist/index.js +0 -53
- package/template/base/next.config.ts +0 -7
- package/template/base/public/file.svg +0 -1
- package/template/base/public/globe.svg +0 -1
- package/template/base/public/next.svg +0 -1
- package/template/base/public/vercel.svg +0 -1
- package/template/base/public/window.svg +0 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "create-tnt-stack",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.3",
|
4
4
|
"description": "Create web application with the TNT-Powered stack",
|
5
5
|
"license": "MIT",
|
6
6
|
"repository": {
|
@@ -18,7 +18,7 @@
|
|
18
18
|
"type": "module",
|
19
19
|
"exports": "./dist/index.js",
|
20
20
|
"bin": {
|
21
|
-
"create-tnt-stack": "dist/index.js"
|
21
|
+
"create-tnt-stack": "./dist/index.js"
|
22
22
|
},
|
23
23
|
"files": [
|
24
24
|
"dist",
|
@@ -37,7 +37,8 @@
|
|
37
37
|
"lint": "eslint . --ext .ts,.tsx",
|
38
38
|
"format": "prettier '**/*.{cjs,mjs,ts,tsx,md,json}' --ignore-path ../.gitignore --ignore-unknown --no-error-on-unmatched-pattern --write",
|
39
39
|
"typecheck": "tsc",
|
40
|
-
"clean": "rm -rf dist .turbo node_modules"
|
40
|
+
"clean": "rm -rf dist .turbo node_modules",
|
41
|
+
"release": "bun run clean build typecheck && npm version patch && npm publish --access public"
|
41
42
|
},
|
42
43
|
"dependencies": {
|
43
44
|
"@ianvs/prettier-plugin-sort-imports": "^4.4.1",
|
package/template/base/README.md
CHANGED
@@ -1,36 +1,56 @@
|
|
1
|
-
|
1
|
+
# Create TNT Stack
|
2
2
|
|
3
|
-
|
3
|
+
This is a [TNT-Powered Stack](https://create.tntstack.org/) project bootstrapped
|
4
|
+
with `create-tnt-stack`.
|
4
5
|
|
5
|
-
|
6
|
+
## Where do I go from here?
|
7
|
+
|
8
|
+
You can treat this project just as you would a regular `create-next-app`
|
9
|
+
project, but without needing to implement additional packages yourself. This
|
10
|
+
means you can start scaffolding from our base template.
|
11
|
+
|
12
|
+
To start developing simply run the following commands:
|
6
13
|
|
7
14
|
```bash
|
15
|
+
cd your-project-name
|
16
|
+
|
8
17
|
npm run dev
|
9
18
|
# or
|
10
|
-
yarn dev
|
11
|
-
# or
|
12
19
|
pnpm dev
|
13
20
|
# or
|
21
|
+
yarn dev
|
22
|
+
# or
|
14
23
|
bun dev
|
15
24
|
```
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
26
|
+
## Learn More
|
20
27
|
|
21
|
-
|
28
|
+
To learn more about the [TNT Stack](https://create.tntstack.org/), take a look
|
29
|
+
at our [documentation](https://create.tntstack.org/).
|
22
30
|
|
23
|
-
|
31
|
+
If you are not familiar with the different technologies used in this project,
|
32
|
+
please refer to the respective docs.
|
24
33
|
|
25
|
-
|
34
|
+
- [Next.js](https://nextjs.org)
|
35
|
+
- [Payload CMS](https://payloadcms.com)
|
36
|
+
- [NextAuth.js](https://next-auth.js.org)
|
37
|
+
- [Prisma](https://prisma.io)
|
38
|
+
- [Drizzle](https://orm.drizzle.team)
|
39
|
+
- [Tailwind CSS](https://tailwindcss.com)
|
26
40
|
|
27
|
-
|
28
|
-
-
|
41
|
+
You can check out the
|
42
|
+
[create-tnt-stack GitHub repository](https://github.com/SlickYeet/create-tnt-stack)
|
43
|
+
— your feedback and contributions are welcome!
|
29
44
|
|
30
|
-
|
45
|
+
## How do I deploy this?
|
31
46
|
|
32
|
-
|
47
|
+
> [!NOTE] Currently, we have a guide for deploying to
|
48
|
+
> [Vercel](https://create.tntstack.org/deployment/vercel), with more deployment
|
49
|
+
> options coming soon.
|
33
50
|
|
34
|
-
|
51
|
+
Follow our deployment guides for more information
|
35
52
|
|
36
|
-
|
53
|
+
- [Vercel](https://create.tntstack.org/deployment/vercel)
|
54
|
+
- [Netlify](https://create.tntstack.org/deployment/netlify) — Coming soon
|
55
|
+
- [Docker](https://create.tntstack.org/deployment/docker) — Coming soon
|
56
|
+
- [Cloudflare](https://create.tntstack.org/deployment/cloudflare) — Coming soon
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
|
3
|
+
* for Docker builds.
|
4
|
+
*/
|
5
|
+
import "./src/env.js"
|
6
|
+
|
7
|
+
/** @type {import("next").NextConfig} */
|
8
|
+
const nextConfig = {
|
9
|
+
/* config options here */
|
10
|
+
}
|
11
|
+
|
12
|
+
export default nextConfig
|
@@ -3,20 +3,12 @@
|
|
3
3
|
:root {
|
4
4
|
--background: #ffffff;
|
5
5
|
--foreground: #171717;
|
6
|
-
|
7
|
-
--primary: 255 60% 56%;
|
8
|
-
--accent: 189 94% 43%;
|
9
|
-
--highlight: 45 93% 47%;
|
10
6
|
}
|
11
7
|
|
12
8
|
@theme inline {
|
13
9
|
--color-background: var(--background);
|
14
10
|
--color-foreground: var(--foreground);
|
15
11
|
|
16
|
-
--color-primary: hsl(var(--primary));
|
17
|
-
--color-accent: hsl(var(--accent));
|
18
|
-
--color-highlight: hsl(var(--highlight));
|
19
|
-
|
20
12
|
--font-sans: var(--font-geist-sans);
|
21
13
|
--font-mono: var(--font-geist-mono);
|
22
14
|
}
|
@@ -25,10 +17,6 @@
|
|
25
17
|
:root {
|
26
18
|
--background: #0a0a0a;
|
27
19
|
--foreground: #ededed;
|
28
|
-
|
29
|
-
--primary: 255 60% 56%;
|
30
|
-
--accent: 189 94% 43%;
|
31
|
-
--highlight: 45 93% 47%;
|
32
20
|
}
|
33
21
|
}
|
34
22
|
|
@@ -1,114 +1,106 @@
|
|
1
|
-
import
|
1
|
+
import Link from "next/link"
|
2
2
|
|
3
3
|
export default function HomePage() {
|
4
4
|
return (
|
5
|
-
<
|
6
|
-
|
7
|
-
|
5
|
+
<main className="flex min-h-screen flex-col items-center justify-center px-4 text-center">
|
6
|
+
{/* Logo */}
|
7
|
+
<div className="mb-8">
|
8
|
+
<div className="relative flex h-24 w-24 items-center justify-center">
|
9
|
+
<div className="absolute inset-0 animate-pulse rounded-xl bg-gradient-to-r from-purple-500 to-cyan-500 opacity-20 blur-xl dark:from-purple-800 dark:to-cyan-800" />
|
8
10
|
<svg
|
9
11
|
xmlns="http://www.w3.org/2000/svg"
|
10
|
-
width="
|
11
|
-
height="
|
12
|
+
width="80"
|
13
|
+
height="80"
|
12
14
|
viewBox="0 0 24 24"
|
13
15
|
fill="none"
|
14
16
|
stroke="currentColor"
|
15
17
|
strokeWidth="2"
|
16
18
|
strokeLinecap="round"
|
17
19
|
strokeLinejoin="round"
|
18
|
-
className="
|
20
|
+
className="rounded-lg bg-gradient-to-r from-purple-500 to-cyan-500 dark:from-purple-800 dark:to-cyan-800"
|
19
21
|
>
|
20
22
|
<polyline points="4 17 10 11 4 5" />
|
21
23
|
<line x1="12" x2="20" y1="19" y2="19" />
|
22
24
|
</svg>
|
23
|
-
<span className="inline-block text-4xl font-bold">
|
24
|
-
TNT-Powered Base Template
|
25
|
-
</span>
|
26
25
|
</div>
|
26
|
+
</div>
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
<li>Save and see your changes instantly.</li>
|
37
|
-
</ol>
|
28
|
+
<div className="max-w-xl text-balance">
|
29
|
+
<h1 className="mb-8 bg-gradient-to-r from-purple-500 to-cyan-500 bg-clip-text pb-1.5 text-6xl font-bold tracking-tighter text-transparent md:text-7xl lg:text-8xl">
|
30
|
+
TNT-Powered Next.js App
|
31
|
+
</h1>
|
32
|
+
<p className="mb-12 text-xl text-neutral-700 md:text-2xl dark:text-neutral-300">
|
33
|
+
Build modern web applications with todat's most popular tools
|
34
|
+
</p>
|
35
|
+
</div>
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
43
|
-
target="_blank"
|
44
|
-
rel="noopener noreferrer"
|
45
|
-
>
|
46
|
-
<Image
|
47
|
-
className="dark:invert"
|
48
|
-
src="/vercel.svg"
|
49
|
-
alt="Vercel logomark"
|
50
|
-
width={20}
|
51
|
-
height={20}
|
52
|
-
/>
|
53
|
-
Deploy now
|
54
|
-
</a>
|
55
|
-
<a
|
56
|
-
className="flex h-10 items-center justify-center rounded-full border border-solid border-black/[.08] px-4 text-sm transition-colors hover:border-transparent hover:bg-[#f2f2f2] sm:h-12 sm:min-w-44 sm:px-5 sm:text-base dark:border-white/[.145] dark:hover:bg-[#1a1a1a]"
|
57
|
-
href="https://create.tntstack.org/docs"
|
58
|
-
target="_blank"
|
59
|
-
rel="noopener noreferrer"
|
60
|
-
>
|
61
|
-
Read our docs
|
62
|
-
</a>
|
63
|
-
</div>
|
64
|
-
</main>
|
65
|
-
<footer className="row-start-3 flex flex-wrap items-center justify-center gap-6">
|
66
|
-
<a
|
67
|
-
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
68
|
-
href="https://create.tntstack.org/docs"
|
37
|
+
<div className="mb-12 flex flex-col gap-10 sm:flex-row">
|
38
|
+
<Link
|
39
|
+
href="https://create.tntstack.org"
|
69
40
|
target="_blank"
|
70
|
-
|
41
|
+
referrerPolicy="no-referrer"
|
42
|
+
className="hover:text-primary relative flex items-center justify-center gap-2 text-lg font-medium"
|
71
43
|
>
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
44
|
+
Website
|
45
|
+
<svg
|
46
|
+
xmlns="http://www.w3.org/2000/svg"
|
47
|
+
viewBox="0 0 24 24"
|
48
|
+
strokeLinecap="round"
|
49
|
+
strokeLinejoin="round"
|
50
|
+
className="absolute top-0 -right-4 size-4 fill-none stroke-current stroke-2"
|
51
|
+
>
|
52
|
+
<path d="M7 7h10v10" />
|
53
|
+
<path d="M7 17 17 7" />
|
54
|
+
</svg>
|
55
|
+
</Link>
|
56
|
+
|
57
|
+
<Link
|
83
58
|
href="https://create.tntstack.org/docs"
|
84
59
|
target="_blank"
|
85
|
-
|
60
|
+
referrerPolicy="no-referrer"
|
61
|
+
className="hover:text-primary relative flex items-center justify-center gap-2 text-lg font-medium"
|
86
62
|
>
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
63
|
+
Docs
|
64
|
+
<svg
|
65
|
+
xmlns="http://www.w3.org/2000/svg"
|
66
|
+
viewBox="0 0 24 24"
|
67
|
+
strokeLinecap="round"
|
68
|
+
strokeLinejoin="round"
|
69
|
+
className="absolute top-0 -right-4 size-4 fill-none stroke-current stroke-2"
|
70
|
+
>
|
71
|
+
<path d="M7 7h10v10" />
|
72
|
+
<path d="M7 17 17 7" />
|
73
|
+
</svg>
|
74
|
+
</Link>
|
75
|
+
|
76
|
+
<Link
|
77
|
+
href="https://github.com/SlickYeet/create-tnt-stack"
|
99
78
|
target="_blank"
|
100
|
-
|
79
|
+
referrerPolicy="no-referrer"
|
80
|
+
className="hover:text-primary relative flex items-center justify-center gap-2 text-lg font-medium"
|
101
81
|
>
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
82
|
+
GitHub
|
83
|
+
<svg
|
84
|
+
xmlns="http://www.w3.org/2000/svg"
|
85
|
+
viewBox="0 0 24 24"
|
86
|
+
strokeLinecap="round"
|
87
|
+
strokeLinejoin="round"
|
88
|
+
className="absolute top-0 -right-4 size-4 fill-none stroke-current stroke-2"
|
89
|
+
>
|
90
|
+
<path d="M7 7h10v10" />
|
91
|
+
<path d="M7 17 17 7" />
|
92
|
+
</svg>
|
93
|
+
</Link>
|
94
|
+
</div>
|
95
|
+
|
96
|
+
<div className="mt-16 text-sm text-neutral-600 dark:text-neutral-400">
|
97
|
+
<p>
|
98
|
+
Get started by editing{" "}
|
99
|
+
<code className="rounded-md bg-neutral-200 px-2 py-1 dark:bg-neutral-800">
|
100
|
+
src/app/page.tsx
|
101
|
+
</code>
|
102
|
+
</p>
|
103
|
+
</div>
|
104
|
+
</main>
|
113
105
|
)
|
114
106
|
}
|
@@ -1,16 +1,22 @@
|
|
1
1
|
{
|
2
2
|
"compilerOptions": {
|
3
|
+
/* Base Options: */
|
4
|
+
"esModuleInterop": true,
|
5
|
+
"skipLibCheck": true,
|
3
6
|
"target": "ES2017",
|
4
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
5
7
|
"allowJs": true,
|
6
|
-
"
|
8
|
+
"resolveJsonModule": true,
|
9
|
+
"isolatedModules": true,
|
10
|
+
|
11
|
+
/* Strictness */
|
7
12
|
"strict": true,
|
13
|
+
"checkJs": true,
|
14
|
+
|
15
|
+
/* Bundled projects */
|
16
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
8
17
|
"noEmit": true,
|
9
|
-
"esModuleInterop": true,
|
10
18
|
"module": "esnext",
|
11
19
|
"moduleResolution": "bundler",
|
12
|
-
"resolveJsonModule": true,
|
13
|
-
"isolatedModules": true,
|
14
20
|
"jsx": "preserve",
|
15
21
|
"incremental": true,
|
16
22
|
"plugins": [
|
@@ -18,10 +24,19 @@
|
|
18
24
|
"name": "next"
|
19
25
|
}
|
20
26
|
],
|
27
|
+
|
28
|
+
/* Path Aliases */
|
29
|
+
"baseUrl": ".",
|
21
30
|
"paths": {
|
22
31
|
"@/*": ["./src/*"]
|
23
32
|
}
|
24
33
|
},
|
25
|
-
"include": [
|
34
|
+
"include": [
|
35
|
+
"next-env.d.ts",
|
36
|
+
"**/*.ts",
|
37
|
+
"**/*.tsx",
|
38
|
+
"**/*.js",
|
39
|
+
".next/types/**/*.ts"
|
40
|
+
],
|
26
41
|
"exclude": ["node_modules"]
|
27
42
|
}
|
package/dist/index.js
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
import ke from"path";import{execa as Ze}from"execa";import Pe from"fs-extra";import{confirm as G,input as ne,select as $}from"@inquirer/prompts";import{Command as je}from"commander";import z from"path";import{fileURLToPath as Ie}from"url";var Se=Ie(import.meta.url),Te=z.dirname(Se),g=z.join(Te,"../"),B=` ___ ___ ___ _ _____ ___ _____ _ _ _____ ___ _____ _ ___ _ __
|
3
|
-
/ __| _ \\ __| /_\\_ _| __| |_ _| \\| |_ _| / __|_ _/_\\ / __| |/ /
|
4
|
-
| (__| / _| / _ \\| | | _| | | | .\` | | | \\__ \\ | |/ _ \\ (__| ' <
|
5
|
-
\\___|_|_\\___/_/ \\_\\_| |___| |_| |_|\\_| |_| |___/ |_/_/ \\_\\___|_|\\_\\
|
6
|
-
`,k="my-tnt-stack",R="create-tnt-stack";import T from"path";import j from"fs-extra";var F=({projectDir:e,scopedAppName:t,packages:a,databaseProvider:i})=>{let n=a?.nextAuth.inUse,o=a?.prisma.inUse,r=o,l=Ce(!!n,!!o,t,i),c="";if(r?n?c="with-next-auth-db.js":c="with-db.js":n&&(c="with-next-auth.js"),c!==""){let xe=T.join(g,"template/packages/src/env",c),Ae=T.join(e,"src/env.js");j.copyFileSync(xe,Ae)}let d=T.join(e,".env"),p=T.join(e,".env.example"),f=Ee+l,b=Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString("base64"),M=l.replace('AUTH_SECRET=""',`AUTH_SECRET="${b}" # Generated by create-tnt-stack`);j.writeFileSync(d,M,"utf-8"),j.writeFileSync(p,f,"utf-8")};function Ce(e,t,a,i){let n=`
|
7
|
-
# When adding additional environment variables, the schema in "/src/env.js"
|
8
|
-
# should be updated accordingly.
|
9
|
-
`.trim().concat(`
|
10
|
-
`);return t&&(n+=`
|
11
|
-
# Prisma
|
12
|
-
# https://www.prisma.io/docs/reference/database-reference/connection-urls#env
|
13
|
-
`),t&&(i==="mysql"?n+=`DATABASE_URL="mysql://root:password@localhost:3306/${a}"`:i==="postgresql"?n+=`DATABASE_URL="postgresql://postgres:password@localhost:5432/${a}"`:i==="sqlite"&&(n+='DATABASE_URL="file:./db.sqlite"'),n+=`
|
14
|
-
`),e&&(n+=`
|
15
|
-
# Next Auth
|
16
|
-
# You can generate a new secret on the command line with:
|
17
|
-
# npx auth secret
|
18
|
-
# https://next-auth.js.org/configuration/options#secret
|
19
|
-
AUTH_SECRET=""
|
20
|
-
|
21
|
-
# Next Auth Discord Provider
|
22
|
-
AUTH_DISCORD_ID=""
|
23
|
-
AUTH_DISCORD_SECRET=""
|
24
|
-
`),!e&&!t&&(n+=`
|
25
|
-
# Example:
|
26
|
-
# SERVERVAR="foo"
|
27
|
-
# NEXT_PUBLIC_CLIENTVAR="bar"
|
28
|
-
`),n}var Ee=`
|
29
|
-
# Since the ".env" file is gitignored, you can use the ".env.example" file to
|
30
|
-
# build a new ".env" file when you clone the repo. Keep this file up-to-date
|
31
|
-
# when you add new variables to \`.env\`.
|
32
|
-
|
33
|
-
# This file will be committed to version control, so make sure not to have any
|
34
|
-
# secrets in it. If you are cloning this repo, create a copy of this file named
|
35
|
-
# ".env" and populate it with your secrets.
|
36
|
-
`.trim().concat(`
|
37
|
-
|
38
|
-
`);import y from"path";import D from"fs-extra";import K from"path";import Y from"fs-extra";import Ne from"sort-package-json";var H={"next-auth":"^4.24.11","@auth/prisma-adapter":"^2.8.0",prisma:"^6.5.0","@prisma/client":"^6.5.0"};var P=e=>{let{dependencies:t,devMode:a,projectDir:i}=e,n=Y.readJsonSync(K.join(i,"package.json"));t.forEach(r=>{let l=H[r];a&&n.devDependencies?n.devDependencies[r]=l:n.dependencies&&(n.dependencies[r]=l)});let o=Ne(n);Y.writeJsonSync(K.join(i,"package.json"),o,{spaces:2})};var Q=({projectDir:e,packages:t})=>{let a=t?.prisma.inUse,i=["next-auth"];a&&i.push("@auth/prisma-adapter"),P({projectDir:e,dependencies:i,devMode:!1});let n=y.join(g,"template/packages"),o="src/app/api/auth/[...nextauth]/route.ts",r=y.join(n,o),l=y.join(e,o),c=y.join(n,"src/server/auth/config",a?"next-auth-with-prisma.ts":"next-auth.ts"),d=y.join(e,"src/server/auth/config.ts"),p=y.join(n,"src/server/auth/next-auth.ts"),f=y.join(e,"src/server/auth/index.ts");D.copySync(r,l),D.copySync(c,d),D.copySync(p,f)};import u from"path";import h from"fs-extra";var X=({projectDir:e,packages:t,databaseProvider:a})=>{P({projectDir:e,dependencies:["prisma"],devMode:!0}),P({projectDir:e,dependencies:["@prisma/client"],devMode:!1});let i=u.join(g,"template/packages"),n=u.join(i,"prisma/schema",`${t?.nextAuth.inUse?"with-next-auth":"base"}.prisma`),o=h.readFileSync(n,"utf-8");a!=="sqlite"&&(o=o.replace('provider = "sqlite"',`provider = "${{mysql:"mysql",postgresql:"postgresql"}[a]}"`),["mysql"].includes(a)&&(o=o.replace("// @db.Text","@db.Text")));let r=u.join(e,"prisma/schema.prisma");h.mkdirSync(u.dirname(r),{recursive:!0}),h.writeFileSync(r,o);let l=u.join(i,"src/server/db/db-prisma.ts"),c=u.join(e,"src/server/db/index.ts");h.mkdirSync(u.dirname(c),{recursive:!0}),h.writeFileSync(c,h.readFileSync(l,"utf-8"));let d=u.join(e,"package.json"),p=h.readJSONSync(d);p.scripts={...p.scripts,postinstall:"prisma generate","db:push":"prisma db push","db:studio":"prisma studio","db:generate":"prisma migrate dev","db:migrate":"prisma migrate deploy"},h.writeJSONSync(d,p,{spaces:2})};var C=["sqlite","mysql","postgresql"],Z=e=>({nextAuth:{inUse:e.includes("nextAuth"),installer:Q},prisma:{inUse:e.includes("prisma"),installer:X},envVariables:{inUse:!0,installer:F}});import Oe from"path";import Me from"fs-extra";function _(){let e=Oe.join(g,"package.json");return Me.readJSONSync(e).version??"1.0.0"}var m=()=>{let e=process.env.npm_config_user_agent;return e?e.startsWith("yarn")?"yarn":e.startsWith("pnpm")?"pnpm":e.startsWith("bun")?"bun":"npm":"npm"};var x=class extends Error{constructor(t){super(t)}};import E from"chalk";var s={error(...e){console.log(E.red(...e))},warn(...e){console.log(E.yellow(...e))},info(...e){console.log(E.cyan(...e))},success(...e){console.log(E.green(...e))}};var N=e=>(e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e);var Re=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function ee(e){let t=N(e),a=t.split("/"),i=a.findIndex(o=>o.startsWith("@")),n=a[a.length-1];return a.findIndex(o=>o.startsWith("@"))!==-1&&(n=a.slice(i).join("/")),t=="."||Re.test(n??"")?!0:"App name must consist of only lowercase alphanumeric characters, '-', and '_'"}var te=e=>e.startsWith(".")||e.startsWith("/")?"Import alias can't start with '.' or '/'":!0;var w={appName:k,packages:[],flags:{noGit:!1,noInstall:!1,default:!1,CI:!1,nextAuth:!1,prisma:!1,importAlias:"@/",dbProvider:"sqlite"},databaseProvider:"sqlite"};async function ae(){let e=w,t=new je().name(R).description("CLI for scaffolding new web apps with the TNT-Powered stack").version(_(),"-v, --version","Output the current version of TNT").argument("[dir]","The name of the application, as well as the name of the directory to create").option("--noGit","Explicitly tell the CLI to not initialize a new git repo in the project",!1).option("--noInstall","Explicitly tell the CLI to not run the package manager's install command",!1).option("-y, --default","Bypass the CLI and use all default options to bootstrap a new tnt-stack",!1).option("--CI","Boolean value if we're running in CI",!1).option("--nextAuth [boolean]","Experimental: Boolean value if we should install NextAuth.js. Must be used in conjunction with `--CI`.",i=>!!i&&i!=="false").option("--prisma [boolean]","Experimental: Boolean value if we should install Prisma. Must be used in conjunction with `--CI`.",i=>!!i&&i!=="false").option("-i, --import-alias [alias]","Explicitly tell the CLI to use a custom import alias",w.flags.importAlias).option("--dbProvider [provider]",`Choose a database provider to use. Possible values: ${C.join(", ")}`,w.flags.dbProvider).parse(process.argv);process.env.npm_config_user_agent?.startsWith("yarn/3")&&s.warn(` WARNING: It looks like you are using Yarn 3. This is currently not supported,
|
39
|
-
and likely to result in a crash. Please run create-tnt-stack with another
|
40
|
-
package manager such as pnpm, npm, or Yarn Classic.
|
41
|
-
See: https://github.com/t3-oss/create-t3-app/issues/57`);let a=t.args[0];if(a&&(e.appName=a),e.flags=t.opts(),e.flags.CI)return e.flags.nextAuth&&e.packages.push("nextAuth"),e.flags.prisma&&e.packages.push("prisma"),C.includes(e.flags.dbProvider)===!1&&(s.warn(`Incompatible database provided. Use: ${C.join(", ")}. Exiting.`),process.exit(0)),e.databaseProvider=e.packages.includes("prisma")?e.flags.dbProvider:"sqlite",e;if(e.flags.default)return e;try{if(process.env.TERM_PROGRAM?.toLowerCase().includes("mintty"))throw s.warn(` WARNING: It looks like you are using MinTTY, which is non-interactive. This is most likely because you are
|
42
|
-
using Git Bash. If that's that case, please use Git Bash from another terminal, such as Windows Terminal. Alternatively, you
|
43
|
-
can provide the arguments from the CLI directly: https://create.tntstack.org/installation#experimental-usage to skip the prompts.`),new x("Non-interactive environment");let i=m(),n={};a||(n.name=await ne({message:"What will your project be called?",default:k,validate:r=>ee(r)})),n.authentication=await $({message:"What authentication provider would you like to use?",choices:[{value:"none",name:"None"},{value:"nextAuth",name:"NextAuth.js"}],default:"none"}),n.database=await $({message:"What database ORM would you like to use?",choices:[{value:"none",name:"None"},{value:"prisma",name:"Prisma"}],default:"none"}),n.database!=="none"&&(n.databaseProvider=await $({message:"What database provider would you like to use?",choices:[{value:"sqlite",name:"SQLite"},{value:"mysql",name:"MySQL"},{value:"postgresql",name:"PostgreSQL"}],default:"sqlite"})),e.flags.noGit||(n.git=await G({message:"Should we initialize a Git repository and stage the changes?",default:!w.flags.noGit})),e.flags.noInstall||(n.noInstall=await G({message:`Should we run '${i}`+(i==="yarn"?"'?":" install' for you?"),default:!w.flags.noInstall})),n.importAlias=await ne({message:"What import alias would you like to use?",default:w.flags.importAlias,validate:te});let o=[];return n.authentication==="nextAuth"&&o.push("nextAuth"),n.database==="prisma"&&o.push("prisma"),{appName:n.name??e.appName,packages:o,flags:{...e.flags,noGit:!n.git||e.flags.noGit,noInstall:!n.noInstall||e.flags.noInstall,importAlias:n.importAlias??e.flags.importAlias},databaseProvider:n.databaseProvider||"sqlite"}}catch(i){if(i instanceof x)s.warn(`${R} needs an interactive terminal to run.`),await G({message:"Continue scaffolding with default options?",default:!0})||(s.info("Exiting..."),process.exit(0)),s.info(`Scaffolding default tnt app in ./${e.appName}`);else throw i}return e}import We from"path";import ie from"chalk";import De from"ora";function oe(e){let{packages:t}=e;s.info("Adding boilerplate...");for(let[a,i]of Object.entries(t))if(i.inUse){let n=De(`Boilerplating ${a}...`).start();i.installer(e),n.succeed(ie.green(`Successfully setup boilerplate for ${ie.green.bold(a)}`))}s.info("")}import U from"path";import{confirm as Ge,select as $e}from"@inquirer/prompts";import v from"chalk";import A from"fs-extra";import Ue from"ora";async function se({projectName:e,projectDir:t,pkgManager:a,noInstall:i}){let n=U.join(g,"template/base");i?s.info(""):s.info(`
|
44
|
-
Using: ${v.cyan.bold(a)}
|
45
|
-
`);let o=Ue(`Scaffolding in: ${t}...
|
46
|
-
`).start();if(A.existsSync(t))if(A.readdirSync(t).length===0)e!=="."&&o.info(`${v.cyan.bold(e)} exists but is empty, continuing...
|
47
|
-
`);else{o.stopAndPersist();let l=await $e({message:`${v.redBright.bold("Warning:")} ${v.cyan.bold(e)} already exists and isn't empty. How would you like to proceed?`,choices:[{value:"abort",name:"Abort installation (recommended)"},{value:"clear",name:"Clear the directory and continue installation"},{value:"overwrite",name:"Continue installation and overwrite conflicting files"}],default:"abort"});l==="abort"&&(o.fail("Aborting installation..."),process.exit(1)),await Ge({message:`Are you sure you want to ${l==="clear"?"clear the directory":"overwrite conflicting files"}`,default:!1})||(o.fail("Aborting installation..."),process.exit(1)),l==="clear"&&(o.info(`Emptying ${v.cyan.bold(e)} and creating tnt app...
|
48
|
-
`),A.emptyDirSync(t))}o.start(),A.copySync(n,t),A.renameSync(U.join(t,"_gitignore"),U.join(t,".gitignore"));let r=e==="."?"App":v.cyan.bold(e);o.succeed(`${r} ${v.green.bold("scaffolded successfully!")}
|
49
|
-
`)}async function re({projectName:e,scopedAppName:t,packages:a,noInstall:i,databaseProvider:n}){let o=m(),r=We.resolve(process.cwd(),e);return await se({projectName:e,projectDir:r,pkgManager:o,scopedAppName:t,noInstall:i,databaseProvider:n}),oe({projectName:e,scopedAppName:t,projectDir:r,pkgManager:o,packages:a,noInstall:i,databaseProvider:n}),r}import{execSync as J}from"child_process";import W from"path";import{confirm as le}from"@inquirer/prompts";import I from"chalk";import{execa as S}from"execa";import ce from"fs-extra";import Je from"ora";function qe(e){try{return J("git --version",{cwd:e}),!0}catch{return!1}}function q(e){return ce.existsSync(W.join(e,".git"))}async function V(e){try{return await S("git",["rev-parse","--is-inside-work-tree"],{cwd:e,stdout:"ignore"}),!0}catch{return!1}}function Ve(){let t=J("git --version").toString().trim().split(" ")[2],a=t?.split(".")[0],i=t?.split(".")[1];return{major:Number(a),minor:Number(i)}}function Le(){return J("git config --global init.defaultBranch || echo main").toString().trim()}async function pe(e){if(s.info("Initializing Git..."),!qe(e)){s.warn("Git is not installed. Skipping Git initialization.");return}let t=Je(`Creating a new git repo...
|
50
|
-
`).start(),a=q(e),i=await V(e),n=W.parse(e).name;if(i&&a){if(t.stop(),!await le({message:`${I.redBright.bold("Warning:")} Git is already initialized in "${n}". Initializing a new git repository would delete the previous history. Would you like to continue anyways?`,default:!1})){t.info("Skipping Git initialization.");return}ce.removeSync(W.join(e,".git"))}else if(i&&!a&&(t.stop(),!await le({message:`${I.redBright.bold("Warning:")} "${n}" is already in a git worktree. Would you still like to initialize a new git repository in this directory?`,default:!1}))){t.info("Skipping Git initialization.");return}try{let o=Le(),{major:r,minor:l}=Ve();r<2||r==2&&l<28?(await S("git",["init"],{cwd:e}),await S("git",["symbolic-ref","HEAD",`refs/heads/${o}`],{cwd:e})):await S("git",["init",`--initial-branch=${o}`],{cwd:e}),await S("git",["add","."],{cwd:e}),t.succeed(`${I.green("Successfully initialized and staged")} ${I.green.bold("git")}
|
51
|
-
`)}catch{t.fail(`${I.bold.red("Failed:")} could not initialize git. Update git to the latest version!
|
52
|
-
`)}}import ze from"chalk";import{execa as me}from"execa";import de from"ora";var L=async(e,t,a)=>{let{onDataHandle:i,args:n=["install"],stdout:o="pipe"}=a,r=de(`Running ${t} install...`).start(),l=me(t,n,{cwd:e,stdout:o});return await new Promise((c,d)=>{i&&l.stdout?.on("data",i(r)),l.on("error",p=>d(p)),l.on("close",()=>c())}),r},Be=async(e,t)=>{switch(e){case"npm":return await me(e,["install"],{cwd:t,stderr:"inherit"}),null;case"pnpm":return L(t,e,{onDataHandle:a=>i=>{let n=i.toString();n.includes("Progress")&&(a.text=n.includes("|")?n.split(" | ")[1]??"":n)}});case"yarn":return L(t,e,{onDataHandle:a=>i=>{a.text=i.toString()}});case"bun":return L(t,e,{stdout:"ignore"})}},fe=async({projectDir:e})=>{s.info("Installing dependencies...");let t=m();(await Be(t,e)??de()).succeed(ze.green(`Successfully installed dependencies!
|
53
|
-
`))};var ge=async({projectName:e=k,packages:t,noInstall:a,projectDir:i,databaseProvider:n})=>{let o=m();s.info("Next steps:"),e!=="."&&s.info(` cd ${e}`),a&&(o==="yarn"?s.info(` ${o}`):s.info(` ${o} install`)),["postgresql","mysql"].includes(n)&&s.info(" Add your database connection string to .env"),t?.nextAuth.inUse&&s.info(" Fill in your .env with necessary values. See https://create.tntstack.org/usage/first-steps for more info."),["npm"].includes(o)?s.info(` ${o} run dev`):s.info(` ${o} dev`),!await V(i)&&!q(i)&&s.info(" git init"),s.info(' git commit -m "initial commit"')};import O from"fs";import Fe from"path";function ue(e,t,a){O.readdirSync(e).forEach(n=>{let o=Fe.join(e,n);if(O.statSync(o).isDirectory())ue(o,t,a);else{let l=O.readFileSync(o,"utf8").replace(new RegExp(t,"g"),a);O.writeFileSync(o,l,"utf8")}})}function he(e,t){let a=t.replace(/\*/g,"").replace(/[^\/]$/,"$&/");ue(e,"@/",a)}import ye from"path";function ve(e){let a=N(e).split("/"),i=a[a.length-1];if(i==="."){let r=ye.resolve(process.cwd());i=ye.basename(r)}let n=a.findIndex(r=>r.startsWith("@"));a.findIndex(r=>r.startsWith("@"))!==-1&&(i=a.slice(n).join("/"));let o=a.filter(r=>!r.startsWith("@")).join("/");return[i,o]}import He from"gradient-string";var Ke={magenta:"#765bc8",pink:"#a48897",yellow:"#c7b561",green:"#8bb8a0",blue:"#4b97d5",cyan:"#22b6d2"};function be(){let e=He(Object.values(Ke)),t=m();(t==="yarn"||t==="pnpm")&&console.log(""),console.log(e.multiline(B))}import{execSync as Ye}from"child_process";import Qe from"https";function _e(e){let t=_();t.includes("beta")?(s.warn(" You are using a beta version of create-tnt-stack."),s.warn(" Please report any bugs you encounter.")):t!==e&&(s.warn(" You are using an outdated version of create-tnt-stack."),s.warn(" Your version:",t+".","Latest version in the npm registry:",e),s.warn(" Please run the CLI with @latest to get the latest updates.")),console.log("")}function Xe(){return new Promise((e,t)=>{Qe.get("https://registry.npmjs.org/-/package/tnt-stack/dist-tags",a=>{if(a.statusCode===200){let i="";a.on("data",n=>i+=n),a.on("end",()=>{e(JSON.parse(i).latest)})}else t()}).on("error",()=>{t()})})}var we=()=>Xe().catch(()=>{try{return Ye("npm view create-tnt-stack version").toString().trim()}catch{return null}});async function et(){let e=await we(),t=m();be(),e&&_e(e);let{appName:a,packages:i,flags:{noGit:n,noInstall:o,importAlias:r},databaseProvider:l}=await ae(),c=Z(i),[d,p]=ve(a),f=await re({projectName:p,scopedAppName:d,packages:c,noInstall:o,databaseProvider:l}),b=Pe.readJsonSync(ke.join(f,"package.json"));b.name=d,b.ctntaMetadata={initVersion:_()};let{stdout:M}=await Ze(t,["-v"],{cwd:f});b.packageManager=`${t}@${M.trim()}`,Pe.writeJSONSync(ke.join(f,"package.json"),b,{spaces:2}),r!=="@/"&&he(f,r),o||await fe({projectDir:f}),n||await pe(f),await ge({projectDir:f,projectName:p,packages:c,noInstall:o,databaseProvider:l}),process.exit(0)}et().catch(e=>{s.error("Aborting installation..."),e instanceof Error?s.error(e.message):(s.error("An unknown error occurred. Please open an issue on GitHub with the below:"),console.error(e)),process.exit(1)});
|
@@ -1 +0,0 @@
|
|
1
|
-
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
@@ -1 +0,0 @@
|
|
1
|
-
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
@@ -1 +0,0 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
@@ -1 +0,0 @@
|
|
1
|
-
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
@@ -1 +0,0 @@
|
|
1
|
-
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|