create-gardener 1.1.7 → 1.1.8
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 +2 -313
- package/package.json +1 -1
- package/template/package.json +11 -12
- package/template/pnpm-lock.yaml +1545 -0
- package/template/src/backend/controllers/gardener.controller.ts +1 -13
- package/template/src/frontend/gardenerST.js +185 -95
- package/template/src/frontend/static/gardener.js +62 -3
- package/template/src/frontend/style.css +1045 -0
- package/template/src/frontend/views/_.ejs +11 -2
- package/template/tsconfig.json +1 -1
- package/template/Readme.md +0 -349
package/Readme.md
CHANGED
|
@@ -16,322 +16,11 @@ Use it with
|
|
|
16
16
|
`npm create-gardener filename`
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
[See Docs](https://ritish.site/Gardener)
|
|
20
|
+
[Github](https://github.com/ritishDas/Gardener)
|
|
20
21
|
|
|
21
|
-
### Core
|
|
22
22
|
|
|
23
|
-
* 🌿 **gardener.js** — declarative DOM builder using JSON objects
|
|
24
|
-
* 🔁 **parser** — convert real DOM elements back into gardener-compatible JSON
|
|
25
|
-
* 📄 **EJS** for simple server-rendered views
|
|
26
|
-
* 🎨 **Tailwind CSS** for fast styling
|
|
27
23
|
|
|
28
|
-
### Dev Server
|
|
29
|
-
|
|
30
|
-
* Express-based development server
|
|
31
|
-
* Hot reload toggle (Ctrl + H)
|
|
32
|
-
* Endpoints to create pages and components at runtime (dev convenience)
|
|
33
|
-
|
|
34
|
-
### Images
|
|
35
|
-
|
|
36
|
-
* Deterministic image optimization endpoint
|
|
37
|
-
* Sharp-powered resize + WebP conversion
|
|
38
|
-
* Filesystem cache reused during static builds
|
|
39
|
-
|
|
40
|
-
### Static Site Generation (SSG)
|
|
41
|
-
|
|
42
|
-
* Render EJS views into HTML
|
|
43
|
-
* Convert route-encoded filenames into nested directories
|
|
44
|
-
* Merge frontend assets and image cache
|
|
45
|
-
* Clean temporary build artifacts
|
|
46
|
-
* Produce a deployable static directory
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Project Structure
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
src/
|
|
54
|
-
├── backend/
|
|
55
|
-
│ ├── routes/
|
|
56
|
-
│ ├── controllers/
|
|
57
|
-
│ ├── libs/
|
|
58
|
-
│ ├── cache/ # generated image cache (build artifact)
|
|
59
|
-
│ └── server.ts
|
|
60
|
-
│
|
|
61
|
-
├── frontend/
|
|
62
|
-
│ ├── views/ # EJS templates (source)
|
|
63
|
-
│ ├── assets/ # original images
|
|
64
|
-
│ ├── components/
|
|
65
|
-
│ ├── gardener.js
|
|
66
|
-
│ ├── styles/
|
|
67
|
-
│ └── frontendtemplate.ejs #starter file to create new page
|
|
68
|
-
│
|
|
69
|
-
│
|
|
70
|
-
│
|
|
71
|
-
├── frontendStatic/ # final static output (generated)
|
|
72
|
-
└── tempfrontend/ # temporary build output (deleted after build)
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Requirements
|
|
78
|
-
|
|
79
|
-
* Node.js v16+ (v18+ recommended)
|
|
80
|
-
* pnpm (recommended) or npm
|
|
81
|
-
* Optional: PostgreSQL
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Quickstart (Development)
|
|
86
|
-
|
|
87
|
-
### 1. Install
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
git clone https://github.com/ritishDas/Gardener.git
|
|
91
|
-
cd Gardener
|
|
92
|
-
pnpm install
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### 2. Run dev server
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
pnpm run dev
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
* Server runs at **[http://localhost:3000](http://localhost:3000)**
|
|
102
|
-
* Tailwind watcher and TypeScript server run together
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Image Optimization & Caching
|
|
107
|
-
|
|
108
|
-
Gardener provides a **deterministic image optimization endpoint**.
|
|
109
|
-
put your images in ./src/frontend/assets and use /cache/[imagename]_[width]x[height].webp in img tag.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
### Filename format
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
<basename>_<width>x<height>.webp
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Example
|
|
119
|
-
|
|
120
|
-
```http
|
|
121
|
-
GET /cache/hero_500x300.webp
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
HTML usage:
|
|
125
|
-
|
|
126
|
-
```html
|
|
127
|
-
<img src="/cache/hero_500x300.webp" alt="hero" />
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
### How it works
|
|
133
|
-
|
|
134
|
-
1. Parses filename to extract:
|
|
135
|
-
|
|
136
|
-
* base name
|
|
137
|
-
* width
|
|
138
|
-
* height
|
|
139
|
-
2. Checks cache:
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
src/backend/cache/
|
|
143
|
-
```
|
|
144
|
-
3. If cached → return immediately
|
|
145
|
-
4. If not cached:
|
|
146
|
-
|
|
147
|
-
* Finds source image in:
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
src/frontend/assets/
|
|
151
|
-
```
|
|
152
|
-
* Resizes and converts to WebP (Sharp)
|
|
153
|
-
* Stores result in cache
|
|
154
|
-
5. Serves the optimized image
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
### Static Build Integration
|
|
159
|
-
|
|
160
|
-
During static generation:
|
|
161
|
-
|
|
162
|
-
* All cached images under:
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
src/backend/cache/
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
are copied into:
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
src/frontendStatic/
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Static HTML can safely reference:
|
|
175
|
-
|
|
176
|
-
```html
|
|
177
|
-
<img src="/cache/hero_500x300.webp" />
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
No runtime image processing is required in production.
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## Static Site Generation
|
|
185
|
-
|
|
186
|
-
Gardener includes a custom static build pipeline.
|
|
187
|
-
|
|
188
|
-
### What it does
|
|
189
|
-
|
|
190
|
-
1. Renders EJS views into HTML
|
|
191
|
-
2. Writes temporary files using route-encoded filenames
|
|
192
|
-
(example: `_blog_posts_hello.html`)
|
|
193
|
-
3. Converts them into directory-based routes:
|
|
194
|
-
|
|
195
|
-
```
|
|
196
|
-
blog/posts/hello/index.html
|
|
197
|
-
```
|
|
198
|
-
4. Copies frontend assets
|
|
199
|
-
5. Copies image cache
|
|
200
|
-
6. Deletes temporary build directory
|
|
201
|
-
|
|
202
|
-
### Output
|
|
203
|
-
|
|
204
|
-
```
|
|
205
|
-
src/frontendStatic/
|
|
206
|
-
├── index.html
|
|
207
|
-
├── blog/
|
|
208
|
-
│ └── posts/
|
|
209
|
-
│ └── hello/
|
|
210
|
-
│ └── index.html
|
|
211
|
-
├── assets/
|
|
212
|
-
└── cache/
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
This directory is ready for:
|
|
216
|
-
|
|
217
|
-
* static hosting
|
|
218
|
-
* CDN deployment
|
|
219
|
-
* Nginx / Caddy / Netlify / Vercel
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## Frontend API — `gardener.js`
|
|
224
|
-
|
|
225
|
-
File: `src/frontend/gardener.js`
|
|
226
|
-
|
|
227
|
-
### `gardener(obj)`
|
|
228
|
-
|
|
229
|
-
Create DOM elements from JSON.
|
|
230
|
-
|
|
231
|
-
```js
|
|
232
|
-
const el = gardener({
|
|
233
|
-
t: 'div',
|
|
234
|
-
cn: ['card', 'p-4'],
|
|
235
|
-
children: [
|
|
236
|
-
{ t: 'h2', txt: 'Title' },
|
|
237
|
-
{ t: 'p', txt: 'Content' }
|
|
238
|
-
]
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
document.body.appendChild(el);
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
### `parser(elementOrHtml, isParent = true)`
|
|
247
|
-
|
|
248
|
-
Convert DOM into gardener JSON.
|
|
249
|
-
|
|
250
|
-
```js
|
|
251
|
-
const json = parser(document.querySelector('.hero'));
|
|
252
|
-
console.log(json);
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
### `parserWindow(text)`
|
|
258
|
-
|
|
259
|
-
Dev-only UI:
|
|
260
|
-
|
|
261
|
-
* Preview parsed JSON
|
|
262
|
-
* Press **Y** to create a component file
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
### Utilities
|
|
267
|
-
|
|
268
|
-
* `imagePreloader(images)`
|
|
269
|
-
* `fetchElement(selector)`
|
|
270
|
-
* `appendElement(parent, child)`
|
|
271
|
-
* `replaceElement(original, newElem)`
|
|
272
|
-
* `createElement(type, classname)`
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## Dev-Only Endpoints ⚠️
|
|
277
|
-
|
|
278
|
-
### `POST /addcomponent`
|
|
279
|
-
|
|
280
|
-
Creates a frontend component file.
|
|
281
|
-
|
|
282
|
-
```json
|
|
283
|
-
{
|
|
284
|
-
"path": "components/MyComp.js",
|
|
285
|
-
"component": "{ t: 'div', txt: 'Hello' }"
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
Writes directly to the filesystem.
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
### `POST /addpage`
|
|
294
|
-
|
|
295
|
-
Creates an EJS page and registers a route.
|
|
296
|
-
|
|
297
|
-
```json
|
|
298
|
-
{ "page": "/my-page" }
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
* Generates a new EJS file
|
|
302
|
-
* Appends a route to the backend router
|
|
303
|
-
|
|
304
|
-
---
|
|
305
|
-
|
|
306
|
-
## Security Notes
|
|
307
|
-
|
|
308
|
-
⚠️ **Important**
|
|
309
|
-
|
|
310
|
-
* Gardener doesn't support <span>hi<span>rohan</span></span> use <span><span>hi</span><span>rohan</span></span> basically text node elements shouldn't have siblings.
|
|
311
|
-
* `/addcomponent` and `/addpage` mutate files and routes
|
|
312
|
-
* Intended for **local development only**
|
|
313
|
-
* Do NOT expose publicly without authentication and sanitization
|
|
314
|
-
|
|
315
|
-
---
|
|
316
|
-
|
|
317
|
-
## Troubleshooting
|
|
318
|
-
|
|
319
|
-
* **Server not starting**
|
|
320
|
-
|
|
321
|
-
* Check `.env`
|
|
322
|
-
* Ensure PostgreSQL is running (if enabled)
|
|
323
|
-
* Inspect logs from `pnpm run dev`
|
|
324
|
-
|
|
325
|
-
* **Images not loading**
|
|
326
|
-
|
|
327
|
-
* Ensure source image exists in `src/frontend/assets`
|
|
328
|
-
* Filename must match `<name>_<width>x<height>.webp`
|
|
329
|
-
|
|
330
|
-
* **Tailwind not updating**
|
|
331
|
-
|
|
332
|
-
* Ensure `pnpm install` completed successfully
|
|
333
|
-
|
|
334
|
-
---
|
|
335
24
|
|
|
336
25
|
## Contributing
|
|
337
26
|
|
package/package.json
CHANGED
package/template/package.json
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-gardener",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "A dom gardener converting dom elements into json and vice versa",
|
|
5
|
-
"main": "
|
|
6
|
-
"bin": {
|
|
7
|
-
"create-gardener": "./starter.js"
|
|
8
|
-
},
|
|
5
|
+
"main": "src/build/server.js",
|
|
9
6
|
"type": "module",
|
|
10
7
|
"scripts": {
|
|
8
|
+
"start": "node src/build/server.js",
|
|
11
9
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
12
|
-
"dev": "concurrently \"tsx watch src/backend/server.ts\" \"tailwindcss -w -i src/frontend/tailwind.css -o src/frontend/style.css\""
|
|
10
|
+
"dev": "concurrently \"tsx watch src/backend/server.ts\" \"tailwindcss -w -i src/frontend/tailwind.css -o src/frontend/style.css\"",
|
|
11
|
+
"build": "tsc"
|
|
13
12
|
},
|
|
14
13
|
"keywords": [],
|
|
15
14
|
"author": "ritishDas",
|
|
16
15
|
"license": "MIT",
|
|
17
|
-
"packageManager": "pnpm@10.20.0",
|
|
18
16
|
"dependencies": {
|
|
19
|
-
"@types/ejs": "^3.1.5",
|
|
20
17
|
"dotenv": "^17.2.3",
|
|
21
18
|
"ejs": "^3.1.10",
|
|
22
19
|
"express": "^5.2.1",
|
|
23
20
|
"sharp": "^0.34.5",
|
|
24
|
-
"tailwindcss": "^4.1.18",
|
|
25
21
|
"types": "^0.1.1",
|
|
26
22
|
"zod": "^4.3.6"
|
|
27
23
|
},
|
|
28
24
|
"devDependencies": {
|
|
25
|
+
"tailwindcss": "^4.1.18",
|
|
26
|
+
"tsx": "^4.21.0",
|
|
27
|
+
"@types/ejs": "^3.1.5",
|
|
29
28
|
"@types/express": "^5.0.6",
|
|
30
29
|
"@types/node": "^25.0.2",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"typescript": "^5.9.3"
|
|
30
|
+
"typescript": "^5.9.3",
|
|
31
|
+
"concurrently": "^9.2.1"
|
|
34
32
|
}
|
|
35
33
|
}
|
|
34
|
+
|