create-tezx-app 1.0.7
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/README.md +126 -0
- package/bin +421 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# โก Create TezX
|
|
2
|
+
|
|
3
|
+
Easily scaffold a new [TezX](https://github.com/tezxjs/tezx) project using official starter templates. Whether you're building a backend with WebSocket support or a TypeScript-powered server, `create-tezx` gets you started fast.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ๐ Quick Start
|
|
8
|
+
|
|
9
|
+
Starter templates are available for common runtimes and package managers. Run one of the following commands:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# npm
|
|
13
|
+
npm create tezx@latest
|
|
14
|
+
|
|
15
|
+
# yarn
|
|
16
|
+
yarn create tezx
|
|
17
|
+
|
|
18
|
+
# pnpm
|
|
19
|
+
pnpm create tezx@latest
|
|
20
|
+
|
|
21
|
+
# bun
|
|
22
|
+
bun create tezx@latest
|
|
23
|
+
|
|
24
|
+
# deno
|
|
25
|
+
deno run -A npm:create-tezx@latest
|
|
26
|
+
````
|
|
27
|
+
|
|
28
|
+
This will launch an interactive setup. You can also skip prompts using CLI flags.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## โ๏ธ CLI Options
|
|
33
|
+
|
|
34
|
+
You can skip interactive prompts by passing options directly via the command line.
|
|
35
|
+
|
|
36
|
+
### `-t`, `--template <template>`
|
|
37
|
+
|
|
38
|
+
Use a specific template by name.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm create tezx@latest my-app -- --template minimal
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### `-i`, `--install`
|
|
47
|
+
|
|
48
|
+
Automatically install dependencies after project setup.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm create tezx@latest my-app -- --install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### `-p`, `--pm <npm|pnpm|bun|yarn>`
|
|
57
|
+
|
|
58
|
+
Choose a package manager.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm create tezx@latest my-app -- --pm bun
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### `--ts`, `-ts`
|
|
67
|
+
|
|
68
|
+
Enable TypeScript in the scaffolded project.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm create tezx@latest my-app -- --ts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### `--env`, `--runtime`, `-env`, `-runtime`
|
|
77
|
+
|
|
78
|
+
Set the runtime environment: `node`, `bun`, or `deno`.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm create tezx@latest my-app -- --runtime bun
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### `--y`, `--yes`, `-y`, `-yes`
|
|
87
|
+
|
|
88
|
+
Skip all prompts using sensible defaults.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm create tezx@latest my-app -- --yes
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## ๐ Supported Templates
|
|
97
|
+
|
|
98
|
+
> โ
More templates coming soon!
|
|
99
|
+
|
|
100
|
+
| Template | Description | Flag Example |
|
|
101
|
+
| --------------- | ------------------------------- | -------------------------- |
|
|
102
|
+
| `minimal` | Minimal TypeScript setup | `--template minimal` |
|
|
103
|
+
| `ws` | WebSocket support (Node or Bun) | `--template ws` |
|
|
104
|
+
| `google-oauth2` | Google OAuth2 integration | `--template google-oauth2` |
|
|
105
|
+
| `github-oauth2` | GitHub OAuth2 integration | `--template github-oauth2` |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## ๐งช Example Usage
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm create tezx@latest my-app -- --template ws --ts --runtime node --install
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
bun create tezx@latest auth-app -- --template google-oauth2 --pm bun --yes
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## ๐งโ๐ป Author
|
|
122
|
+
|
|
123
|
+
Built by [Rakibul Islam](https://github.com/srakib17)
|
|
124
|
+
and [TezX](https://github.com/tezxjs/tezx) contributors.
|
|
125
|
+
|
|
126
|
+
---
|
package/bin
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{execSync as B}from"node:child_process";import{mkdirSync as O,writeFileSync as H}from"node:fs";import k,{join as X,resolve as Y}from"node:path";import R from"node:readline";var g=(r,s)=>({version:s,npm:["npm install",r],bun:["bun add",r],yarn:["yarn add",r],pnpm:["pnpm add",r]});var E={content:`
|
|
3
|
+
// 1. Initialize OAuth2 client
|
|
4
|
+
const client = GitHubOauthClient({
|
|
5
|
+
clientId: process.env.GITHUB_CLIENT_ID,
|
|
6
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
|
7
|
+
redirectUri: 'http://localhost:3000/github/callback'
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// Step 1: Redirect user to GitHub login
|
|
11
|
+
app.get('/github', getGithubOAuthURL({
|
|
12
|
+
authClient: client,
|
|
13
|
+
}), (ctx) => {
|
|
14
|
+
return ctx.redirect(ctx.state.get('github_oauth_url'));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Step 2: Verify GitHub token and handle user session
|
|
18
|
+
app.get('/github/callback', verifyGithubToken({
|
|
19
|
+
authClient: client,
|
|
20
|
+
Callbacks: (ctx) => {
|
|
21
|
+
return {
|
|
22
|
+
session: async (session, user) => {
|
|
23
|
+
console.log('Session:', session);
|
|
24
|
+
console.log('User:', user);
|
|
25
|
+
return session;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}), async (ctx) => {
|
|
30
|
+
return ctx.json({ success: true });
|
|
31
|
+
});
|
|
32
|
+
`,files:[{content:`GITHUB_CLIENT_ID = 12323
|
|
33
|
+
GITHUB_CLIENT_SECRET=234234
|
|
34
|
+
`,path:".env"}],import:["import { GitHubOauthClient, getGithubOAuthURL, verifyGithubToken } from '@tezx/github-oauth2'; "],package:[g("@tezx/github-oauth2","^1.0.2")]};var I={content:`
|
|
35
|
+
// 1. Initialize OAuth2 client
|
|
36
|
+
const client = GoogleOauthClient({
|
|
37
|
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
|
38
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
39
|
+
redirectUri: 'http://localhost:3000/auth/callback',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// 2. Route to start Google login
|
|
43
|
+
app.get('/auth/google', getGoogleOAuthURL({
|
|
44
|
+
authClient: client,
|
|
45
|
+
scopes: ['openid','email','profile'],
|
|
46
|
+
}), (ctx) => {
|
|
47
|
+
return ctx.redirect(ctx.state.get('google_oauth_url'));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// 3. Callback route, verify token and establish session
|
|
51
|
+
app.get('/auth/callback', verifyGoogleToken({
|
|
52
|
+
authClient: client,
|
|
53
|
+
onError: (err) => {
|
|
54
|
+
console.error('OAuth Error:', err);
|
|
55
|
+
// handle error or redirect
|
|
56
|
+
},
|
|
57
|
+
onSuccess: (tokens) => {
|
|
58
|
+
console.log('Tokens:', tokens);
|
|
59
|
+
},
|
|
60
|
+
Callbacks: (ctx)=> {
|
|
61
|
+
return {
|
|
62
|
+
signIn: async (user) => {
|
|
63
|
+
// e.g. allow only users from a domain
|
|
64
|
+
return user.email.endsWith('@yourcompany.com');
|
|
65
|
+
},
|
|
66
|
+
jwt: async (token, user) => {
|
|
67
|
+
// attach roles or custom claims
|
|
68
|
+
token.role = user.email_verified ? 'member' : 'guest';
|
|
69
|
+
return token;
|
|
70
|
+
},
|
|
71
|
+
session: async (session, user) => {
|
|
72
|
+
// persist user profile in session
|
|
73
|
+
session.user = {
|
|
74
|
+
id: user.sub,
|
|
75
|
+
email: user.email,
|
|
76
|
+
name: user.name,
|
|
77
|
+
picture: user.picture
|
|
78
|
+
};
|
|
79
|
+
return session;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}), async (ctx) => {
|
|
84
|
+
// Now ctx.session is populated
|
|
85
|
+
return ctx.json({ success: true });
|
|
86
|
+
});
|
|
87
|
+
`,files:[{content:`GOOGLE_CLIENT_ID = 12323
|
|
88
|
+
GOOGLE_CLIENT_SECRET=234234
|
|
89
|
+
`,path:".env"}],import:['import { GoogleOauthClient, getGoogleOAuthURL, verifyGoogleToken } from "@tezx/google-oauth2";'],package:[g("@tezx/google-oauth2","^1.0.8"),g("@googleapis/oauth2","^2.0.1")]};var U=`
|
|
90
|
+
<!DOCTYPE html>
|
|
91
|
+
<html lang="en">
|
|
92
|
+
<head>
|
|
93
|
+
<meta charset="UTF-8" />
|
|
94
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
95
|
+
<title>TezX WebSocket Demo</title>
|
|
96
|
+
<style>
|
|
97
|
+
* {
|
|
98
|
+
box-sizing: border-box;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
body {
|
|
102
|
+
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
|
103
|
+
background: #f7f9fc;
|
|
104
|
+
padding: 30px;
|
|
105
|
+
color: #333;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
h1 {
|
|
109
|
+
text-align: center;
|
|
110
|
+
color: #444;
|
|
111
|
+
margin-bottom: 30px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.container {
|
|
115
|
+
max-width: 600px;
|
|
116
|
+
margin: 0 auto;
|
|
117
|
+
background: #fff;
|
|
118
|
+
border-radius: 10px;
|
|
119
|
+
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05);
|
|
120
|
+
padding: 20px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#messages {
|
|
124
|
+
border: 1px solid #ddd;
|
|
125
|
+
border-radius: 6px;
|
|
126
|
+
padding: 12px;
|
|
127
|
+
height: 250px;
|
|
128
|
+
overflow-y: auto;
|
|
129
|
+
background-color: #fafafa;
|
|
130
|
+
font-size: 14px;
|
|
131
|
+
margin-bottom: 15px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#input {
|
|
135
|
+
width: 100%;
|
|
136
|
+
padding: 10px;
|
|
137
|
+
border: 1px solid #ccc;
|
|
138
|
+
border-radius: 6px;
|
|
139
|
+
font-size: 14px;
|
|
140
|
+
margin-bottom: 10px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.buttons {
|
|
144
|
+
display: flex;
|
|
145
|
+
gap: 10px;
|
|
146
|
+
justify-content: flex-end;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
button {
|
|
150
|
+
padding: 8px 16px;
|
|
151
|
+
font-size: 14px;
|
|
152
|
+
border: none;
|
|
153
|
+
border-radius: 6px;
|
|
154
|
+
cursor: pointer;
|
|
155
|
+
transition: all 0.2s ease;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
button:hover {
|
|
159
|
+
opacity: 0.9;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
button:active {
|
|
163
|
+
transform: scale(0.97);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.send-btn {
|
|
167
|
+
background-color: #4caf50;
|
|
168
|
+
color: white;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.ping-btn {
|
|
172
|
+
background-color: #2196f3;
|
|
173
|
+
color: white;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.message {
|
|
177
|
+
margin-bottom: 8px;
|
|
178
|
+
padding: 6px 10px;
|
|
179
|
+
border-radius: 4px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.message.client {
|
|
183
|
+
background: #e8f5e9;
|
|
184
|
+
color: #2e7d32;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.message.server {
|
|
188
|
+
background: #e3f2fd;
|
|
189
|
+
color: #1565c0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.message.system {
|
|
193
|
+
background: #fff3e0;
|
|
194
|
+
color: #ef6c00;
|
|
195
|
+
font-style: italic;
|
|
196
|
+
}
|
|
197
|
+
</style>
|
|
198
|
+
</head>
|
|
199
|
+
<body>
|
|
200
|
+
<h1>TezX WebSocket Demo</h1>
|
|
201
|
+
<div class="container">
|
|
202
|
+
<div id="messages"></div>
|
|
203
|
+
<input id="input" type="text" placeholder="Type a message..." />
|
|
204
|
+
<div class="buttons">
|
|
205
|
+
<button class="send-btn" onclick="sendMessage()">Send</button>
|
|
206
|
+
<button class="ping-btn" onclick="sendPing()">Ping</button>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<script>
|
|
211
|
+
const ws = new WebSocket(\`ws://\${location.host}/ws\`);
|
|
212
|
+
const messages = document.getElementById("messages");
|
|
213
|
+
const input = document.getElementById("input");
|
|
214
|
+
|
|
215
|
+
ws.onopen = () => {
|
|
216
|
+
appendMessage("Connected to WebSocket server", "system");
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
ws.onmessage = (event) => {
|
|
220
|
+
appendMessage(\`Server: \${event.data}\`, "server");
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
ws.onclose = () => {
|
|
224
|
+
appendMessage("Disconnected from WebSocket server", "system");
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
ws.onerror = (error) => {
|
|
228
|
+
appendMessage(\`Error: \${error}\`, "system");
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
function appendMessage(message, type = "client") {
|
|
232
|
+
const div = document.createElement("div");
|
|
233
|
+
div.textContent = message;
|
|
234
|
+
div.className = \`message \${type}\`;
|
|
235
|
+
messages.appendChild(div);
|
|
236
|
+
messages.scrollTop = messages.scrollHeight;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function sendMessage() {
|
|
240
|
+
const message = input.value;
|
|
241
|
+
if (message && ws.readyState === WebSocket.OPEN) {
|
|
242
|
+
ws.send(message);
|
|
243
|
+
appendMessage(\`Client: \${message}\`, "client");
|
|
244
|
+
input.value = "";
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function sendPing() {
|
|
249
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
250
|
+
ws.send("ping");
|
|
251
|
+
appendMessage("Client: ping", "client");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
</script>
|
|
255
|
+
</body>
|
|
256
|
+
</html>
|
|
257
|
+
`,G={content:`
|
|
258
|
+
const socket = [];
|
|
259
|
+
app.get(
|
|
260
|
+
"/ws",
|
|
261
|
+
upgradeWebSocket(
|
|
262
|
+
(ctx) => {
|
|
263
|
+
return {
|
|
264
|
+
// make sure it is work with nodejs
|
|
265
|
+
open: (ws) => {
|
|
266
|
+
socket.push(ws);
|
|
267
|
+
console.log("WebSocket connected");
|
|
268
|
+
ws.send("\u{1F44B} Welcome to TezX WebSocket!");
|
|
269
|
+
},
|
|
270
|
+
message: (ws, msg) => {
|
|
271
|
+
if (typeof msg === "string" && msg === "ping") {
|
|
272
|
+
ws.send("pong \u{1F3D3}");
|
|
273
|
+
} else if (msg !== undefined) {
|
|
274
|
+
ws.send("Echo: " + msg);
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
close: (ws, data) => {
|
|
278
|
+
console.log(\`WebSocket closed: \${ data?.reason ?? "No reason provided"}\`);
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
maxPayload: 2 * 1024 * 1024, // 2MB
|
|
284
|
+
perMessageDeflate: {
|
|
285
|
+
threshold: 1024, // Compress messages > 1KB
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
),
|
|
289
|
+
(ctx) => {
|
|
290
|
+
return ctx.sendFile("public/ws.html");
|
|
291
|
+
},
|
|
292
|
+
);
|
|
293
|
+
`,files:[{content:U,path:"public/ws.html"}],import:['import { upgradeWebSocket } from "tezx/ws";']};var S={minimal:{content:"",files:[],import:[],package:[]},ws:G,"github-oauth2":E,"google-oauth2":I};import D from"node:readline";async function C(r,s,t){return new Promise(n=>{let i=0;D.emitKeypressEvents(process.stdin,r),process.stdin.isTTY&&process.stdin.setRawMode(!0);let o=()=>{process.stdout.write("\x1B[2J\x1B[0f"),console.log(s+` (Use \u2191 \u2193 arrows, Enter to confirm)
|
|
294
|
+
`),t.forEach((l,a)=>{console.log(`${a===i?"\u{1F449}":" "} ${a===i?"\x1B[36m":"\x1B[0m"}${l}\x1B[0m`)})},c=(l,a)=>{if(a.name==="up")i=(i-1+t.length)%t.length,o();else if(a.name==="down")i=(i+1)%t.length,o();else if(a.name==="return")return n(t[i])};o(),process.stdin.on("keypress",c)})}var N={reset:"\x1B[0m",bold:"\x1B[1m",underline:"\x1B[4m",gray:"\x1B[90m",white:"\x1B[97m",black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",bgRed:"\x1B[41m",bgGreen:"\x1B[42m",bgYellow:"\x1B[43m",bgBlue:"\x1B[44m",bgMagenta:"\x1B[45m",bgCyan:"\x1B[46m",bgWhite:"\x1B[47m",orange:"\x1B[38;2;255;88;30m",bgOrange:"\x1B[48;2;255;88;30m"};function e(r,s){return`${N[s]}${r}${N.reset}`}import{mkdirSync as F,writeFileSync as j}from"node:fs";import{join as T}from"node:path";var L=({ts:r,template:s,root:t,env:n,useStatic:i=!1,staticFolder:o})=>{let c=T(t,r?"src/index.ts":"src/index.js");F(T(t,"src"),{recursive:!0});let l=`
|
|
295
|
+
import { TezX } from "tezx";
|
|
296
|
+
import { ${n}Adapter ,loadEnv} from "tezx/${n}";
|
|
297
|
+
import { logger } from "tezx/middleware";
|
|
298
|
+
${s?.import?.join(`
|
|
299
|
+
`)}
|
|
300
|
+
const app = new TezX({
|
|
301
|
+
env: loadEnv(),
|
|
302
|
+
debugMode: true,
|
|
303
|
+
// Additional options
|
|
304
|
+
});
|
|
305
|
+
app.use([logger()]);
|
|
306
|
+
|
|
307
|
+
app.get("/", (ctx) => ctx.text("Hello from TezX (${n})"));
|
|
308
|
+
|
|
309
|
+
${i?`app.static("${o||"public"}");`:""}
|
|
310
|
+
${s?.content?`
|
|
311
|
+
${s?.content?.trim()}
|
|
312
|
+
`:""}
|
|
313
|
+
${n}Adapter(app).listen(3000, () => {
|
|
314
|
+
console.log("\u{1F680} TezX running on http://localhost:3000");
|
|
315
|
+
});
|
|
316
|
+
`;if(r){let a=`
|
|
317
|
+
{
|
|
318
|
+
"compilerOptions": {
|
|
319
|
+
"outDir": "./dist",
|
|
320
|
+
"module": "CommonJS",
|
|
321
|
+
"target": "ESNext",
|
|
322
|
+
"moduleResolution": "node",
|
|
323
|
+
"skipLibCheck": true,
|
|
324
|
+
"removeComments": false,
|
|
325
|
+
"esModuleInterop": true,
|
|
326
|
+
"resolveJsonModule": true,
|
|
327
|
+
"strict": true,
|
|
328
|
+
},
|
|
329
|
+
"include": [
|
|
330
|
+
"src",
|
|
331
|
+
],
|
|
332
|
+
"exclude": [
|
|
333
|
+
"node_modules",
|
|
334
|
+
"dist",
|
|
335
|
+
"tests"
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
`.trim();j(T(t,"tsconfig.json"),a)}j(c,l.trim())},M=({template:r,root:s,projectName:t,env:n,ts:i,useWS:o,choiceStep:c})=>{let l=[];Array.isArray(r?.package)&&r?.package?.forEach(d=>{let{version:x,npm:h}=d||{};l.push(`"${h?.[1]}": "${x}"`)});let a={bun:{start:"bun dist/index.js",dev:"bun run --hot --watch src/index.ts"},deno:{start:"deno run --allow-all dist/index.js",dev:"deno run --watch --allow-all --unstable-sloppy-imports src/index.ts"},node:{start:"node dist/index.js",dev:"tsx watch src/index.ts"}},p=`
|
|
339
|
+
{
|
|
340
|
+
"name": "${t||"tezx-app-example"}",
|
|
341
|
+
"version": "1.0.0",
|
|
342
|
+
"type": "module",
|
|
343
|
+
"description": "TezX is a high-performance, lightweight JavaScript framework designed for speed, scalability, and flexibility. It enables efficient routing, middleware management, and static file serving with minimal configuration. Fully compatible with Node.js, Deno, and Bun.",
|
|
344
|
+
"scripts": { ${i?`
|
|
345
|
+
"build:esm": "tsc --module ESNext --outDir dist --removeComments",
|
|
346
|
+
"build:dts": "tsc --module ESNext --outDir dist --declaration --emitDeclarationOnly",
|
|
347
|
+
"build": "${c?.build}",`:""}
|
|
348
|
+
"start": "${a?.[n]?.start}",
|
|
349
|
+
"dev": "${a?.[n]?.dev}"
|
|
350
|
+
},
|
|
351
|
+
"repository": {
|
|
352
|
+
"type": "git",
|
|
353
|
+
"url": "git+https://github.com/tezxjs/tezx-app-example"
|
|
354
|
+
},
|
|
355
|
+
"keywords": [],
|
|
356
|
+
"author": "",
|
|
357
|
+
"license": "ISC",
|
|
358
|
+
"bugs": {
|
|
359
|
+
"url": "https://github.com/tezxjs/tezx-app-example"
|
|
360
|
+
},
|
|
361
|
+
"homepage": "https://github.com/tezxjs/tezx-app-example",
|
|
362
|
+
"dependencies": {
|
|
363
|
+
${i?'"typescript": "^5.8.2",':""}
|
|
364
|
+
"tezx": "^2.0.3"${n=="node"?`,
|
|
365
|
+
"tsx": "^4.19.2"`:""}${o&&n=="node"?`,
|
|
366
|
+
"ws": "^8.18.1"`:""}${l.length?`,
|
|
367
|
+
${l?.join(`,
|
|
368
|
+
`)}`:""}
|
|
369
|
+
},
|
|
370
|
+
"devDependencies": {
|
|
371
|
+
"@types/node": "^22.13.14"
|
|
372
|
+
}
|
|
373
|
+
}`.trim();j(T(s,"package.json"),p)};var y=["npm","bun","yarn","pnpm"],f=["node","bun","deno"];function J(r){let s=0,t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=setInterval(()=>{process.stdout.write(`\r${t[s=++s%t.length]} ${r}`)},80);return()=>{clearInterval(n),process.stdout.write(`\r\u2705 Done!
|
|
374
|
+
`)}}var $=R.createInterface({input:process.stdin,output:process.stdout});R.emitKeypressEvents(process.stdin);process.stdin.isTTY&&process.stdin.setRawMode(!0);var b=(r,s="")=>new Promise(t=>{$.question(s?`${r} (${s}): `:r,n=>{t(n.trim()||s)})});async function _(r){let s=r?.directory,t=r?.options;console.log(e(`
|
|
375
|
+
\u26A1 TezX App Creator (no dependencies CLI)
|
|
376
|
+
`,"orange")),s||(s=await b(e("\u{1F4E6} Target directory: ","magenta")),s||(console.log(e("\u274C Project name required.","red")),process.exit(0)));let n=k.basename(s),i=Y(process.cwd(),s),o=!!t?.ts,c=t?.env||t?.runtime,l=f?.includes(c)?c:await C($,"\u{1F4BB} Runtime?",f),a=t?.staticFolder||"public",p=!0,d={content:"",import:[],files:[]};if(t?.t||t?.template){let m=t.t||t.template,v=S?.[m];v||(console.error(`\u274C Unknown template: "${m}"`),console.error(`\u2139\uFE0F Available templates: ${Object.keys(S).join(", ")}`),process.exit(0)),d=v}else o=!!(t?.ts||(await b("\u{1F7E6} Use TypeScript? (y/N): ")).toLowerCase()==="y"),p=!!t?.useStatic||(await b("\u{1F4C1} Use static folder? (y/N): ")).toLowerCase()==="y",a=p?t?.staticFolder||await b("\u{1F4C2} Static folder name? (default: public): "):"";let x=t?.pm||t?.p,h=y?.includes(x)?x:await C($,"\u{1F4E6} Choose your package manager",y),w=t?.i==="true"||t?.install==="true"||(await b("\u{1F4E5} Install dependencies now? (y/N): ")).toLowerCase()==="y";console.log(`
|
|
377
|
+
\u{1F4C1} Creating project: ${n}...
|
|
378
|
+
`);let W=J("Creating Project");if(O(i,{recursive:!0}),p){let m=X(i,a||"public");O(m,{recursive:!0})}let u={bun:{cd:"cd "+s,install:"bun install",dev:"bun dev",build:"bun build:cjs && bun build:esm && bun build:dts"},npm:{cd:"cd "+s,install:"npm install",dev:"npm run dev",build:"npm run build:cjs && npm run build:esm && npm run build:dts"},yarn:{cd:"cd "+s,install:"yarn",dev:"yarn dev",build:"yarn build:cjs && yarn build:esm && yarn build:dts"},pnpm:{cd:"cd "+s,install:"pnpm install",dev:"pnpm run dev",build:"pnpm run build:cjs && pnpm run build:esm && pnpm run build:dts"}}[h];L({template:d,root:i,ts:!!o,env:l,staticFolder:a,useStatic:p}),M({projectName:n,env:l,root:i,ts:!!o,template:d,choiceStep:u}),$.close(),d?.files?.forEach(m=>{let v=k.join(i,k.dirname(m?.path));O(v,{recursive:!0}),H(k.join(i,m?.path),m?.content)}),w&&B(u?.install,{cwd:i,stdio:"inherit"}),console.log(e(`
|
|
379
|
+
\u2705 TezX project "${n}" is ready!
|
|
380
|
+
`,"green")),console.log(e("\u{1F9F0} Summary of your configuration:","cyan")),console.log(`\u{1F4C1} Project Name: ${e(n,"yellow")}`);let z=t?.t||t?.template;z&&console.log(`\u{1F4C1} Template Name: ${e(z,"orange")}`),console.log(`\u{1F7E6} TypeScript: ${e(o?"Yes":"No",o?"green":"gray")}`),console.log(`\u{1F4BB} Runtime: ${e(l,"blue")}`),console.log(`\u{1F4C1} Static Folder: ${e(p?a||"public":"Not Used",p?"green":"gray")}`),console.log(`\u{1F4E6} Package Manager: ${e(h,"magenta")}`),console.log(`\u{1F4E5} Dependencies Installed: ${e(w?"Yes":"No",w?"green":"red")}
|
|
381
|
+
`),console.log(e("\u{1F449} Next Steps:","cyan")),console.log(e(` ${u?.cd}`,"white")),w||console.log(e(` ${u?.install}`,"white")),console.log(e(` ${u?.dev}`,"white")),console.log(""),W(),process.exit(0)}function A(){console.log(`
|
|
382
|
+
${e("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E","gray")}
|
|
383
|
+
${e("\u2502","gray")} ${e("\u26A1 Create TezX","yellow")} - Scaffold your next backend app ${e("\u2502","gray")}
|
|
384
|
+
${e("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F","gray")}
|
|
385
|
+
|
|
386
|
+
${e("\u{1F4E6} Usage:","cyan")}
|
|
387
|
+
${e("create-tezx","green")} ${e("[directory] [...options]","gray")}
|
|
388
|
+
|
|
389
|
+
${e("\u{1F680} Quick Start:","cyan")}
|
|
390
|
+
${e("npm","magenta")} create tezx@latest
|
|
391
|
+
${e("yarn","magenta")} create tezx
|
|
392
|
+
${e("pnpm","magenta")} create tezx@latest
|
|
393
|
+
${e("bun","magenta")} create tezx@latest
|
|
394
|
+
${e("deno","magenta")} run -A npm:create-tezx@latest
|
|
395
|
+
|
|
396
|
+
${e("\u{1F39B}\uFE0F Options:","cyan")}
|
|
397
|
+
|
|
398
|
+
${e("-t, --template <name>","green")} Use a specific starter template
|
|
399
|
+
${e("--ts, -ts","green")} Enable TypeScript setup
|
|
400
|
+
${e("--env, --runtime <env>","green")} Set runtime: node | bun | deno
|
|
401
|
+
${e("-p, --pm <manager>","green")} Package manager: npm | bun | yarn | pnpm
|
|
402
|
+
${e("-i, --install","green")} Automatically install dependencies
|
|
403
|
+
${e("-y, --yes","green")} Skip prompts using default options
|
|
404
|
+
${e("-v, --version","green")} Show CLI version
|
|
405
|
+
${e("-h, --help","green")} Display this help message
|
|
406
|
+
|
|
407
|
+
${e("\u{1F9F0} Examples:","cyan")}
|
|
408
|
+
${e("npm create tezx@latest my-app --template ws --ts --env node","gray")}
|
|
409
|
+
${e("bun create tezx@latest -- --install --pm bun","gray")}
|
|
410
|
+
|
|
411
|
+
${e("\u{1F4C1} Available Templates:","cyan")}
|
|
412
|
+
${e("minimal","yellow")} Minimal TypeScript setup
|
|
413
|
+
${e("ws","yellow")} Built-in WebSocket server
|
|
414
|
+
${e("google-oauth2","yellow")} Google OAuth2 Authentication
|
|
415
|
+
${e("github-oauth2","yellow")} GitHub OAuth2 Authentication
|
|
416
|
+
|
|
417
|
+
${e("\u{1F517} Repository:","cyan")}
|
|
418
|
+
${e("https://github.com/tezxjs/tezx","underline")}
|
|
419
|
+
|
|
420
|
+
${e("\u{1F9D1}\u200D\u{1F4BB} Author:","cyan")}
|
|
421
|
+
Rakibul Islam ${e("<https://github.com/srakib17>","blue")}`),process.exit(0)}function P(){console.log("TezX CLI v1.0.7"),process.exit(0)}(async()=>{let r="",s=(c,l)=>{if(l.name==="c"&&l.ctrl&&(process.stdin.off("keypress",s),process.stdin.isTTY&&process.stdin.setRawMode(!1),process.exit(0)),r+=l?.sequence,l.name==="return"){let a=r;return r="",a}};process.stdin.on("keypress",s);let t=process.argv.slice(2),n={},i;for(let c=0;c<t.length;c++){let l=t[c];if(l.startsWith("--")){let a=l.slice(2),p=t[c+1];p&&!p.startsWith("-")?(n[a]=p,c++):n[a]="true"}else if(l.startsWith("-")){let a=l.slice(1),p=t[c+1];p&&!p.startsWith("-")?(n[a]=p,c++):n[a]="true"}else i||(i=l)}let o={directory:i,options:n};if((n.y==="true"||n.yes==="true")&&(o.options.ts="true",o.options.useStatic="true",o.options.staticFolder="public",o.options.pm=y?.includes(o.options?.p||o?.options?.pm)?o.options?.p||o?.options?.pm:"npm",o.options.p=y?.includes(o.options?.p||o?.options?.pm)?o.options?.p||o?.options?.pm:"npm",o.options.env=f?.includes(o.options?.env||o?.options?.runtime)?o.options?.env||o?.options?.runtime:"node",o.options.runtime=f?.includes(o.options?.env||o?.options?.runtime)?o.options?.env||o?.options?.runtime:"node",o.options.install="true"),n.help||n.h){A();return}if(n.v||n.version){P();return}_(o)})();
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-tezx-app",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "TezX is a high-performance, lightweight JavaScript framework designed for speed, scalability, and flexibility. It enables efficient routing, middleware management, and static file serving with minimal configuration. Fully compatible with Node.js, Deno, and Bun.",
|
|
6
|
+
"bin": "./bin",
|
|
7
|
+
"scripts": {},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/tezxjs/TezX.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/tezxjs/TezX/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"registry": "https://registry.npmjs.org"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"server",
|
|
23
|
+
"framework",
|
|
24
|
+
"http",
|
|
25
|
+
"middleware",
|
|
26
|
+
"create",
|
|
27
|
+
"router",
|
|
28
|
+
"high-performance",
|
|
29
|
+
"node",
|
|
30
|
+
"bun",
|
|
31
|
+
"deno",
|
|
32
|
+
"typescript",
|
|
33
|
+
"web-framework"
|
|
34
|
+
],
|
|
35
|
+
"author": "SRAKIB17",
|
|
36
|
+
"license": "MIT"
|
|
37
|
+
}
|