create-gardener 2.0.5 โ†’ 2.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 ADDED
@@ -0,0 +1,187 @@
1
+ # Gardener Web Application Template
2
+
3
+ A modern full-stack web application template created with **create-gardener**. This project provides a production-ready setup with TypeScript, Express.js backend, EJS templating, and Tailwind CSS for styling.
4
+
5
+ ## ๐Ÿš€ Features
6
+
7
+ - **TypeScript Backend** - Type-safe Express.js server with modern ES modules
8
+ - **EJS Templating** - Server-side rendering with EJS view engine
9
+ - **Tailwind CSS** - Utility-first CSS framework with JIT compilation
10
+ - **Hot Reload Development** - Live reload for both backend and frontend during development
11
+ - **Production Ready** - Optimized build process with minification
12
+ - **Testing Setup** - Jest configuration for unit and integration tests
13
+ - **Image Processing** - Sharp integration for image optimization
14
+ - **Validation** - Zod schema validation
15
+ - **Environment Configuration** - dotenv support for environment variables
16
+
17
+ ## ๐Ÿ“‹ Prerequisites
18
+
19
+ - Node.js (v18 or higher recommended)
20
+ - pnpm (preferred) or npm
21
+
22
+ ## ๐Ÿ› ๏ธ Installation
23
+
24
+ ```bash
25
+ # Install dependencies
26
+ pnpm install
27
+ # or
28
+ npm install
29
+ ```
30
+
31
+ ## ๐Ÿƒ Getting Started
32
+
33
+ ### Development Mode
34
+
35
+ Start the development server with hot reload:
36
+
37
+ ```bash
38
+ pnpm dev
39
+ # or
40
+ npm run dev
41
+ ```
42
+
43
+ This will:
44
+ - Start the TypeScript backend server with watch mode on port 3000 (or PORT from .env)
45
+ - Run Tailwind CSS in watch mode for live style updates
46
+
47
+ ### Production Build
48
+
49
+ Build the application for production:
50
+
51
+ ```bash
52
+ pnpm build
53
+ # or
54
+ npm run build
55
+ ```
56
+
57
+ This will:
58
+ 1. Compile and minify Tailwind CSS
59
+ 2. Transpile TypeScript to JavaScript
60
+ 3. Copy frontend assets to the build directory
61
+ 4. Generate production configuration
62
+
63
+ ### Start Production Server
64
+
65
+ ```bash
66
+ pnpm start
67
+ # or
68
+ npm start
69
+ ```
70
+
71
+ Runs the compiled production build from the `build` directory.
72
+
73
+ ** Refer to docs.md for full docs **
74
+
75
+ ## ๐Ÿงช Testing
76
+
77
+ Run tests with Jest:
78
+
79
+ ```bash
80
+ pnpm test
81
+ # or
82
+ npm test
83
+ ```
84
+
85
+ ## ๐Ÿ“ Project Structure
86
+
87
+ ```
88
+ .
89
+ โ”œโ”€โ”€ src/
90
+ โ”‚ โ”œโ”€โ”€ backend/ # Backend TypeScript code
91
+ โ”‚ โ”‚ โ”œโ”€โ”€ controllers/ # Route controllers
92
+ โ”‚ โ”‚ โ”œโ”€โ”€ routes/ # Express routes
93
+ โ”‚ โ”‚ โ”œโ”€โ”€ libs/ # Utility libraries
94
+ โ”‚ โ”‚ โ””โ”€โ”€ server.ts # Main server file
95
+ โ”‚ โ””โ”€โ”€ frontend/ # Frontend assets
96
+ โ”‚ โ”œโ”€โ”€ views/ # EJS templates
97
+ โ”‚ โ”œโ”€โ”€ static/ # Static files (CSS, JS, images)
98
+ โ”‚ โ”œโ”€โ”€ assets/ # Source assets
99
+ โ”‚ โ”œโ”€โ”€ template/ # Frontend templates
100
+ โ”‚ โ””โ”€โ”€ tailwind.css # Tailwind source file
101
+ โ”œโ”€โ”€ build/ # Production build output
102
+ โ”œโ”€โ”€ buildHelper.js # Build utility script
103
+ โ”œโ”€โ”€ jest.config.js # Jest configuration
104
+ โ”œโ”€โ”€ tsconfig.json # TypeScript configuration
105
+ โ”œโ”€โ”€ package.json # Project dependencies
106
+ โ””โ”€โ”€ .env # Environment variables
107
+ ```
108
+
109
+ ## โš™๏ธ Configuration
110
+
111
+ ### Environment Variables
112
+
113
+ Create a `.env` file in the root directory:
114
+
115
+ ```env
116
+ PORT=3000
117
+ NODE_ENV=development
118
+ ```
119
+
120
+ ### TypeScript
121
+
122
+ The project uses strict TypeScript configuration with:
123
+ - ES modules (`"module": "nodenext"`)
124
+ - Strict type checking
125
+ - Source maps for debugging
126
+ - Declaration files generation
127
+
128
+ ### Tailwind CSS
129
+
130
+ Tailwind CSS v4 is configured with:
131
+ - JIT (Just-In-Time) compilation
132
+ - Minification in production builds
133
+ - Custom styles in `src/frontend/tailwind.css`
134
+
135
+ ## ๐Ÿ“ฆ Dependencies
136
+
137
+ ### Production
138
+ - **express** - Fast, minimalist web framework
139
+ - **ejs** - Embedded JavaScript templating
140
+ - **tailwindcss** - Utility-first CSS framework
141
+ - **sharp** - High-performance image processing
142
+ - **zod** - TypeScript-first schema validation
143
+ - **dotenv** - Environment variable management
144
+
145
+ ### Development
146
+ - **typescript** - TypeScript compiler
147
+ - **tsx** - TypeScript execution and REPL
148
+ - **jest** - Testing framework
149
+ - **concurrently** - Run multiple commands concurrently
150
+ - **cross-env** - Cross-platform environment variables
151
+
152
+ ## ๐Ÿ”ง Build Process
153
+
154
+ The `buildHelper.js` script handles:
155
+ 1. Copying frontend files to the build directory
156
+ 2. Generating production configuration (`gardenerConfig.js`)
157
+ 3. Cleaning up unnecessary template files
158
+
159
+ ## ๐Ÿ“ Scripts
160
+
161
+ | Script | Description |
162
+ |--------|-------------|
163
+ | `pnpm dev` | Start development server with hot reload |
164
+ | `pnpm build` | Build for production |
165
+ | `pnpm start` | Start production server |
166
+ | `pnpm test` | Run Jest tests |
167
+
168
+ ## ๐Ÿค Contributing
169
+
170
+ This is a template project created by create-gardener. Feel free to modify it according to your needs.
171
+
172
+ ## ๐Ÿ“„ License
173
+
174
+ MIT
175
+
176
+ ## ๐Ÿ‘ค Author
177
+
178
+ ritishDas
179
+
180
+ ## ๐Ÿ”— Links
181
+
182
+ - [Gardener Homepage](https://gardener.ritish.site)
183
+ - [GitHub Repository](https://github.com/ritishDas/gardener)
184
+
185
+ ---
186
+
187
+ Created with [create-gardener](https://www.npmjs.com/package/create-gardener) ๐ŸŒฑ
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "https://github.com/ritishDas/gardener"
7
7
  },
8
- "version": "2.0.5",
8
+ "version": "2.0.7",
9
9
  "description": "A dom gardener converting dom elements into json and vice versa",
10
10
  "main": "index.js",
11
11
  "bin": {
@@ -1,18 +1,19 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
 
4
- async function buildHelper() {
4
+ export default async function buildHelper() {
5
5
  const src = path.resolve('src', 'frontend');
6
6
  const dest = path.resolve('build', 'frontend');
7
7
 
8
8
  await fs.cp(src, dest, { recursive: true });
9
9
 
10
- await fs.writeFile(path.join(dest, 'static', 'gardenerConfig.js'), "export const
11
- mode = 'prod'; ", 'utf8');
10
+ await fs.writeFile(path.join(dest, 'static', 'gardenerConfig.js'), "export const mode = 'prod'; ", 'utf8');
12
11
 
13
12
  await fs.rm(path.join(dest, 'template'), { recursive: true });
14
13
 
15
14
  }
16
15
 
17
- buildHelper();
16
+ if (import.meta.url === `file://${process.argv[1]}`) {
17
+ buildHelper();
18
+ }
18
19
 
@@ -0,0 +1,78 @@
1
+ import { jest } from '@jest/globals';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+
5
+ jest.mock('fs/promises');
6
+
7
+ describe('buildHelper', () => {
8
+ beforeEach(() => {
9
+ jest.clearAllMocks();
10
+
11
+ fs.cp = jest.fn().mockResolvedValue(undefined);
12
+ fs.writeFile = jest.fn().mockResolvedValue(undefined);
13
+ fs.rm = jest.fn().mockResolvedValue(undefined);
14
+ });
15
+
16
+ test('copies frontend directory', async () => {
17
+ const { default: buildHelper } = await import('./buildHelper.js');
18
+ await buildHelper();
19
+
20
+ expect(fs.cp).toHaveBeenCalledWith(
21
+ path.resolve('src', 'frontend'),
22
+ path.resolve('build', 'frontend'),
23
+ { recursive: true }
24
+ );
25
+ });
26
+
27
+ test('writes gardenerConfig.js', async () => {
28
+ const { default: buildHelper } = await import('./buildHelper.js');
29
+ await buildHelper();
30
+
31
+ expect(fs.writeFile).toHaveBeenCalledWith(
32
+ path.join(path.resolve('build', 'frontend'), 'static', 'gardenerConfig.js'),
33
+ "export const mode = 'prod'; ",
34
+ 'utf8'
35
+ );
36
+ });
37
+
38
+ test('removes template directory', async () => {
39
+ const { default: buildHelper } = await import('./buildHelper.js');
40
+ await buildHelper();
41
+
42
+ expect(fs.rm).toHaveBeenCalledWith(
43
+ path.join(path.resolve('build', 'frontend'), 'template'),
44
+ { recursive: true }
45
+ );
46
+ });
47
+
48
+ test('runs operations in correct order', async () => {
49
+ const operations = [];
50
+
51
+ fs.cp.mockImplementation(async () => operations.push('cp'));
52
+ fs.writeFile.mockImplementation(async () => operations.push('writeFile'));
53
+ fs.rm.mockImplementation(async () => operations.push('rm'));
54
+
55
+ const { default: buildHelper } = await import('./buildHelper.js');
56
+ await buildHelper();
57
+
58
+ expect(operations).toEqual(['cp', 'writeFile', 'rm']);
59
+ });
60
+
61
+ test('fails early if copy fails', async () => {
62
+ fs.cp.mockRejectedValue(new Error('Copy failed'));
63
+
64
+ const { default: buildHelper } = await import('./buildHelper.js');
65
+
66
+ await expect(buildHelper()).rejects.toThrow('Copy failed');
67
+ expect(fs.writeFile).not.toHaveBeenCalled();
68
+ });
69
+
70
+ test('fails if write fails and skips rm', async () => {
71
+ fs.writeFile.mockRejectedValue(new Error('Write failed'));
72
+
73
+ const { default: buildHelper } = await import('./buildHelper.js');
74
+
75
+ await expect(buildHelper()).rejects.toThrow('Write failed');
76
+ expect(fs.rm).not.toHaveBeenCalled();
77
+ });
78
+ });
@@ -0,0 +1,13 @@
1
+ export default {
2
+ testEnvironment: 'node',
3
+ transform: {},
4
+ testMatch: ['**/*.test.js'],
5
+ moduleNameMapper: {
6
+ '^(\\.{1,2}/.*)\\.js$': '$1',
7
+ },
8
+ collectCoverageFrom: [
9
+ '*.js',
10
+ '!jest.config.js',
11
+ '!*.test.js',
12
+ ],
13
+ };
@@ -7,7 +7,7 @@
7
7
  "start": "cross-env NODE_ENV=production node build/backend/server.js",
8
8
  "dev": "concurrently \"cross-env NODE_ENV=development tsx watch src/backend/server.ts\" \"tailwindcss -w -i src/frontend/tailwind.css -o src/frontend/static/style.css\"",
9
9
  "build": "tailwindcss -i src/frontend/tailwind.css -o src/frontend/static/style.css --minify && tsc && node buildHelper.js",
10
- "test": "echo \"Error: no test specified\" && exit 1"
10
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
11
11
  },
12
12
  "keywords": [],
13
13
  "author": "ritishDas",
@@ -21,11 +21,14 @@
21
21
  "zod": "^4.3.6"
22
22
  },
23
23
  "devDependencies": {
24
+ "@jest/globals": "^30.3.0",
24
25
  "@types/ejs": "^3.1.5",
25
26
  "@types/express": "^5.0.6",
26
27
  "@types/node": "^25.0.2",
27
28
  "concurrently": "^9.2.1",
28
29
  "cross-env": "^10.1.0",
30
+ "jest": "^30.3.0",
31
+ "jest-environment-jsdom": "^30.3.0",
29
32
  "tailwindcss": "^4.1.18",
30
33
  "tsx": "^4.21.0",
31
34
  "typescript": "^5.9.3"