mini-tsx 1.0.0 → 1.0.2

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 CHANGED
@@ -17,36 +17,32 @@ npm install mini-tsx
17
17
 
18
18
  ## CLI (Scaffolding)
19
19
 
20
- Initialize a new project with default `tsconfig.json` and `src/index.tsx`:
20
+ Create a new project interactively:
21
21
 
22
22
  ```bash
23
23
  npx mini-tsx
24
+ # or
25
+ npx create-mini-tsx
24
26
  ```
25
27
 
26
- ## Setup (Manual)
27
-
28
- 1. **Configure `tsconfig.json`**:
29
-
30
- Ensure your `tsconfig.json` has the following compiler options to enable JSX:
31
-
32
- ```json
33
- {
34
- "compilerOptions": {
35
- "jsx": "react",
36
- "jsxFactory": "jsx",
37
- "module": "ESNext",
38
- "moduleResolution": "node"
39
- }
40
- }
41
- ```
42
-
43
- 2. **Add `type: "module"` to `package.json`**:
44
-
45
- ```json
46
- {
47
- "type": "module"
48
- }
49
- ```
28
+ The CLI handles project naming, template selection (**basic** or **blog**), and Git initialization.
29
+
30
+ ## Manual Setup
31
+
32
+ 1. **Install**: `npm install mini-tsx`
33
+ 2. **Configure `tsconfig.json`**:
34
+ ```json
35
+ {
36
+ "compilerOptions": {
37
+ "jsx": "react",
38
+ "jsxFactory": "jsx",
39
+ "module": "ESNext",
40
+ "moduleResolution": "node",
41
+ "outDir": "dist"
42
+ }
43
+ }
44
+ ```
45
+ 3. **Add `"type": "module"`** to your `package.json`.
50
46
 
51
47
  ## Usage
52
48
 
@@ -3,21 +3,52 @@
3
3
  import { writeFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { execSync } from "node:child_process";
6
+ import { createInterface } from "node:readline/promises";
6
7
 
7
- const cwd = process.cwd();
8
+ const rl = createInterface({
9
+ input: process.stdin,
10
+ output: process.stdout
11
+ });
12
+
13
+ const projectName = await rl.question("What is your project named? (mini-tsx-app) ") || "mini-tsx-app";
14
+ const template = await rl.question("Which template would you like to use? (basic/blog) ") || "basic";
15
+ const useGit = (await rl.question("Initialize a git repository? (y/n) ")).toLowerCase().startsWith("y");
16
+ rl.close();
17
+
18
+ const targetDir = join(process.cwd(), projectName);
8
19
 
9
- // 1. Initialize package.json if missing
10
- if (!existsSync(join(cwd, "package.json"))) {
11
- console.log("Initializing package.json...");
12
- execSync("npm init -y", { stdio: "inherit" });
20
+ if (existsSync(targetDir)) {
21
+ console.error(`Directory ${projectName} already exists.`);
22
+ process.exit(1);
13
23
  }
14
24
 
15
- // 2. Install mini-tsx
16
- console.log("Installing mini-tsx...");
25
+ mkdirSync(targetDir);
26
+ process.chdir(targetDir);
27
+
28
+ const cwd = process.cwd();
29
+
30
+ // 1. Initialize package.json
31
+ console.log(`Initializing ${projectName}...`);
32
+ const packageJson = {
33
+ name: projectName,
34
+ version: "1.0.0",
35
+ type: "module",
36
+ main: "dist/index.js",
37
+ scripts: {
38
+ "build": "tsc",
39
+ "start": "node dist/index.js",
40
+ "dev": "tsc -w & node --watch dist/index.js"
41
+ }
42
+ };
43
+ writeFileSync(join(cwd, "package.json"), JSON.stringify(packageJson, null, 2));
44
+
45
+ // 2. Install mini-tsx and typescript
46
+ console.log("Installing dependencies...");
17
47
  try {
18
- execSync("npm install mini-tsx", { stdio: "inherit" });
48
+ execSync("npm install mini-tsx", { stdio: "inherit" });
49
+ execSync("npm install -D typescript @types/node", { stdio: "inherit" });
19
50
  } catch (e) {
20
- console.log("Skipping install (might be local test)");
51
+ console.log("Skipping install (might be local test)");
21
52
  }
22
53
 
23
54
  // 3. Setup tsconfig.json
@@ -32,25 +63,12 @@ const requiredOptions = {
32
63
  "outDir": "dist"
33
64
  };
34
65
 
35
- let tsconfig = {
66
+ const tsconfig = {
36
67
  "compilerOptions": { ...requiredOptions },
37
68
  "include": ["src/**/*"]
38
69
  };
39
70
 
40
- if (existsSync(tsconfigPath)) {
41
- try {
42
- const existing = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
43
- tsconfig = existing;
44
- tsconfig.compilerOptions = tsconfig.compilerOptions || {};
45
- Object.assign(tsconfig.compilerOptions, requiredOptions);
46
- console.log("Updated tsconfig.json");
47
- } catch (e) {
48
- console.log("Error reading tsconfig.json, overwriting...");
49
- }
50
- } else {
51
- console.log("Created tsconfig.json");
52
- }
53
-
71
+ console.log("Created tsconfig.json");
54
72
  writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2));
55
73
 
56
74
  // 4. Create src/index.tsx
@@ -58,8 +76,57 @@ const srcDir = join(cwd, "src");
58
76
  if (!existsSync(srcDir)) mkdirSync(srcDir);
59
77
 
60
78
  const indexTsxPath = join(srcDir, "index.tsx");
61
- if (!existsSync(indexTsxPath)) {
62
- const indexTsx = `import { jsx, render } from "mini-tsx";
79
+ let indexTsx = "";
80
+
81
+ if (template === "blog") {
82
+ indexTsx = `import { jsx, render } from "mini-tsx";
83
+
84
+ const Layout = ({ title, children }: { title: string, children: any }) => (
85
+ <html lang="en">
86
+ <head>
87
+ <title>{title}</title>
88
+ <style>{\`
89
+ body { font-family: system-ui; max-width: 800px; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; }
90
+ header { border-bottom: 1px solid #eee; margin-bottom: 2rem; }
91
+ article { margin-bottom: 3rem; }
92
+ \`}</style>
93
+ </head>
94
+ <body>
95
+ <header>
96
+ <h1>My Mini TSX Blog</h1>
97
+ </header>
98
+ <main>{children}</main>
99
+ </body>
100
+ </html>
101
+ );
102
+
103
+ const Post = ({ title, date, content }: { title: string, date: string, content: string }) => (
104
+ <article>
105
+ <h2>{title}</h2>
106
+ <small>{date}</small>
107
+ <div>{content}</div>
108
+ </article>
109
+ );
110
+
111
+ const App = () => (
112
+ <Layout title="Welcome to my Blog">
113
+ <Post
114
+ title="First Post"
115
+ date="2024-03-20"
116
+ content="This is my first post using Mini TSX! It's so small and fast."
117
+ />
118
+ <Post
119
+ title="Why Mini TSX?"
120
+ date="2024-03-21"
121
+ content="Because sometimes you just need to render some HTML with JSX without the weight of a full framework."
122
+ />
123
+ </Layout>
124
+ );
125
+
126
+ render(App());
127
+ `;
128
+ } else {
129
+ indexTsx = `import { jsx, render } from "mini-tsx";
63
130
 
64
131
  const App = () => (
65
132
  <div>
@@ -70,10 +137,30 @@ const App = () => (
70
137
 
71
138
  render(App());
72
139
  `;
73
- writeFileSync(indexTsxPath, indexTsx);
74
- console.log("Created src/index.tsx");
75
- } else {
76
- console.log("src/index.tsx already exists");
77
140
  }
78
141
 
79
- console.log("\nDone! Run 'npx tsc && node dist/index.js' to build and run.");
142
+ writeFileSync(indexTsxPath, indexTsx);
143
+ console.log(`Created src/index.tsx (template: ${template})`);
144
+
145
+ // 5. Git initialization
146
+ if (useGit) {
147
+ try {
148
+ execSync("git init", { stdio: "ignore" });
149
+ writeFileSync(join(cwd, ".gitignore"), "node_modules/\ndist/\n");
150
+ console.log("Initialized git repository");
151
+ } catch (e) {
152
+ console.log("Could not initialize git repository");
153
+ }
154
+ }
155
+
156
+ console.log(`\nSuccess! Created ${projectName} at ${targetDir}`);
157
+ console.log("Inside that directory, you can run several commands:");
158
+ console.log("\n npm run build");
159
+ console.log(" Builds the project to dist/");
160
+ console.log("\n npm start");
161
+ console.log(" Runs the built project");
162
+ console.log("\n npm run dev");
163
+ console.log(" Runs the project in development mode (watch)");
164
+ console.log("\nWe suggest that you begin by typing:");
165
+ console.log(`\n cd ${projectName}`);
166
+ console.log(" npm run dev\n");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mini-tsx",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -0,0 +1,12 @@
1
+ declare global {
2
+ namespace JSX {
3
+ interface ElementChildrenAttribute {
4
+ children: {};
5
+ }
6
+ interface IntrinsicElements {
7
+ [k: string]: any;
8
+ }
9
+ }
10
+ }
11
+ export declare const jsx: (t: any, p: any, ...c: any[]) => any;
12
+ export declare const render: (b: string, f?: string) => void;
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { basename, extname, dirname, join } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ export const jsx = (t, p, ...c) => {
5
+ if (typeof t == "function")
6
+ return t({ ...p, children: c });
7
+ let s = "";
8
+ for (let k in (p || (p = {})))
9
+ s += ` ${k}="${p[k]}"`;
10
+ return `<${t}${s}>${c.flat().join("")}</${t}>`;
11
+ };
12
+ export const render = (b, f) => {
13
+ const h = `<!DOCTYPE html><meta charset="utf-8"><meta name="viewport" content="width=device-width">${b}`;
14
+ if (!f) {
15
+ const hash = createHash("md5").update(h).digest("hex").slice(0, 8);
16
+ f = join("dist", basename(process.argv[1], extname(process.argv[1])) + "." + hash + ".html");
17
+ }
18
+ mkdirSync(dirname(f), { recursive: true });
19
+ writeFileSync(f, h);
20
+ console.log(`Rendered: ${f}`);
21
+ };
package/package.json CHANGED
@@ -1,9 +1,16 @@
1
1
  {
2
2
  "name": "mini-tsx",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "create-mini-tsx"
10
+ ],
11
+ "bin": {
12
+ "mini-tsx": "create-mini-tsx/index.js"
13
+ },
7
14
  "scripts": {
8
15
  "build": "tsc"
9
16
  },
package/src/index.ts DELETED
@@ -1,22 +0,0 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
2
- import { basename, extname, dirname, join } from "node:path";
3
- import { createHash } from "node:crypto";
4
-
5
- declare global { namespace JSX { interface ElementChildrenAttribute { children: {} } interface IntrinsicElements { [k: string]: any } } }
6
-
7
- export const jsx = (t: any, p: any, ...c: any[]) => {
8
- if (typeof t == "function") return t({ ...p, children: c });
9
- let s = ""; for (let k in (p ||= {})) s += ` ${k}="${p[k]}"`;
10
- return `<${t}${s}>${c.flat().join("")}</${t}>`;
11
- };
12
-
13
- export const render = (b: string, f?: string) => {
14
- const h = `<!DOCTYPE html><meta charset="utf-8"><meta name="viewport" content="width=device-width">${b}`;
15
- if (!f) {
16
- const hash = createHash("md5").update(h).digest("hex").slice(0, 8);
17
- f = join("dist", basename(process.argv[1], extname(process.argv[1])) + "." + hash + ".html");
18
- }
19
- mkdirSync(dirname(f), { recursive: true });
20
- writeFileSync(f, h);
21
- console.log(`Rendered: ${f}`);
22
- };
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "ESNext",
5
- "jsx": "react",
6
- "jsxFactory": "jsx",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "moduleResolution": "node",
10
- "outDir": "dist",
11
- "declaration": true
12
- },
13
- "include": [
14
- "src/**/*"
15
- ]
16
- }