create-gardener 1.1.6 → 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 +7 -32
- package/template/src/backend/routes/gardener.route.ts +2 -1
- package/template/src/backend/server.ts +1 -1
- package/template/src/frontend/frontendtemplate.ejs +4 -4
- package/template/src/frontend/gardenerST.js +430 -0
- package/template/src/frontend/static/components/emailsvg.js +55 -0
- package/template/src/frontend/{components → static/components}/eyeoff.js +1 -1
- package/template/src/frontend/static/components/eyeon.js +43 -0
- package/template/src/frontend/{components → static/components}/notification.js +1 -1
- package/template/src/frontend/{components → static/components}/passwordBox.js +3 -3
- package/template/src/frontend/static/components/test.js +54 -0
- package/template/src/frontend/{gardener.js → static/gardener.js} +76 -4
- package/template/src/frontend/static/style.css +1048 -0
- package/template/src/frontend/style.css +148 -350
- package/template/src/frontend/views/_.ejs +17 -8
- package/template/src/frontend/views/_login.ejs +8 -8
- package/template/tsconfig.json +1 -1
- package/.direnv/bin/nix-direnv-reload +0 -19
- package/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc +0 -2140
- package/.envrc +0 -1
- package/template/Readme.md +0 -349
- package/template/src/frontend/components/emailsvg.js +0 -55
- package/template/src/frontend/components/eyeon.js +0 -44
- package/template/src/frontend/components/test.js +0 -54
- /package/template/src/{backend → frontend/static}/cache/gardener_500x500.webp +0 -0
- /package/template/src/frontend/{components → static/components}/nonui/api.js +0 -0
- /package/template/src/frontend/{global.js → static/global.js} +0 -0
- /package/template/src/frontend/{style2.css → static/style2.css} +0 -0
package/.envrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
use flake
|
package/template/Readme.md
DELETED
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
# Gardener 🌱
|
|
2
|
-
|
|
3
|
-
**Gardener** is a small development toolkit and micro-framework for building websites with **declarative DOM JSON**, server-rendered templates, and a **custom static site generation pipeline**.
|
|
4
|
-
|
|
5
|
-
It is designed for developers who want:
|
|
6
|
-
|
|
7
|
-
* full control over HTML structure
|
|
8
|
-
* minimal abstractions
|
|
9
|
-
* a fast local dev experience
|
|
10
|
-
* a deterministic static output for production
|
|
11
|
-
|
|
12
|
-
Gardener sits somewhere between a tiny framework and a build system.
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## What Gardener Includes
|
|
17
|
-
|
|
18
|
-
### Core
|
|
19
|
-
|
|
20
|
-
* 🌿 **gardener.js** — declarative DOM builder using JSON objects
|
|
21
|
-
* 🔁 **parser** — convert real DOM elements back into gardener-compatible JSON
|
|
22
|
-
* 📄 **EJS** for simple server-rendered views
|
|
23
|
-
* 🎨 **Tailwind CSS** for fast styling
|
|
24
|
-
|
|
25
|
-
### Dev Server
|
|
26
|
-
|
|
27
|
-
* Express-based development server
|
|
28
|
-
* Hot reload toggle (Ctrl + H)
|
|
29
|
-
* Endpoints to create pages and components at runtime (dev convenience)
|
|
30
|
-
|
|
31
|
-
### Images
|
|
32
|
-
|
|
33
|
-
* Deterministic image optimization endpoint
|
|
34
|
-
* Sharp-powered resize + WebP conversion
|
|
35
|
-
* Filesystem cache reused during static builds
|
|
36
|
-
|
|
37
|
-
### Static Site Generation (SSG)
|
|
38
|
-
|
|
39
|
-
* Render EJS views into HTML
|
|
40
|
-
* Convert route-encoded filenames into nested directories
|
|
41
|
-
* Merge frontend assets and image cache
|
|
42
|
-
* Clean temporary build artifacts
|
|
43
|
-
* Produce a deployable static directory
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Project Structure
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
src/
|
|
51
|
-
├── backend/
|
|
52
|
-
│ ├── routes/
|
|
53
|
-
│ ├── controllers/
|
|
54
|
-
│ ├── libs/
|
|
55
|
-
│ ├── cache/ # generated image cache (build artifact)
|
|
56
|
-
│ └── server.ts
|
|
57
|
-
│
|
|
58
|
-
├── frontend/
|
|
59
|
-
│ ├── views/ # EJS templates (source)
|
|
60
|
-
│ ├── assets/ # original images
|
|
61
|
-
│ ├── components/
|
|
62
|
-
│ ├── gardener.js
|
|
63
|
-
│ └── styles/
|
|
64
|
-
│
|
|
65
|
-
├── frontendStatic/ # final static output (generated)
|
|
66
|
-
└── tempfrontend/ # temporary build output (deleted after build)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## Requirements
|
|
72
|
-
|
|
73
|
-
* Node.js v16+ (v18+ recommended)
|
|
74
|
-
* pnpm (recommended) or npm
|
|
75
|
-
* Optional: PostgreSQL
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Quickstart (Development)
|
|
80
|
-
|
|
81
|
-
### 1. Install
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
git clone https://github.com/ritishDas/Gardener.git
|
|
85
|
-
cd Gardener
|
|
86
|
-
pnpm install
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### 2. Run dev server
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
pnpm run dev
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
* Server runs at **[http://localhost:3000](http://localhost:3000)**
|
|
96
|
-
* Tailwind watcher and TypeScript server run together
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Image Optimization & Caching
|
|
101
|
-
|
|
102
|
-
Gardener provides a **deterministic image optimization endpoint**.
|
|
103
|
-
|
|
104
|
-
### Route
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
GET /cache/:name
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Filename format
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
<basename>_<width>x<height>.webp
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Example
|
|
117
|
-
|
|
118
|
-
```http
|
|
119
|
-
GET /cache/hero_500x300.webp
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
HTML usage:
|
|
123
|
-
|
|
124
|
-
```html
|
|
125
|
-
<img src="/cache/hero_500x300.webp" alt="hero" />
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
### How it works
|
|
131
|
-
|
|
132
|
-
1. Parses filename to extract:
|
|
133
|
-
|
|
134
|
-
* base name
|
|
135
|
-
* width
|
|
136
|
-
* height
|
|
137
|
-
2. Checks cache:
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
src/backend/cache/
|
|
141
|
-
```
|
|
142
|
-
3. If cached → return immediately
|
|
143
|
-
4. If not cached:
|
|
144
|
-
|
|
145
|
-
* Finds source image in:
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
src/frontend/assets/
|
|
149
|
-
```
|
|
150
|
-
* Resizes and converts to WebP (Sharp)
|
|
151
|
-
* Stores result in cache
|
|
152
|
-
5. Serves the optimized image
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
### Static Build Integration
|
|
157
|
-
|
|
158
|
-
During static generation:
|
|
159
|
-
|
|
160
|
-
* All cached images under:
|
|
161
|
-
|
|
162
|
-
```
|
|
163
|
-
src/backend/cache/
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
are copied into:
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
src/frontendStatic/
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Static HTML can safely reference:
|
|
173
|
-
|
|
174
|
-
```html
|
|
175
|
-
<img src="/cache/hero_500x300.webp" />
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
No runtime image processing is required in production.
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## Static Site Generation
|
|
183
|
-
|
|
184
|
-
Gardener includes a custom static build pipeline.
|
|
185
|
-
|
|
186
|
-
### What it does
|
|
187
|
-
|
|
188
|
-
1. Renders EJS views into HTML
|
|
189
|
-
2. Writes temporary files using route-encoded filenames
|
|
190
|
-
(example: `_blog_posts_hello.html`)
|
|
191
|
-
3. Converts them into directory-based routes:
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
blog/posts/hello/index.html
|
|
195
|
-
```
|
|
196
|
-
4. Copies frontend assets
|
|
197
|
-
5. Copies image cache
|
|
198
|
-
6. Deletes temporary build directory
|
|
199
|
-
|
|
200
|
-
### Output
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
src/frontendStatic/
|
|
204
|
-
├── index.html
|
|
205
|
-
├── blog/
|
|
206
|
-
│ └── posts/
|
|
207
|
-
│ └── hello/
|
|
208
|
-
│ └── index.html
|
|
209
|
-
├── assets/
|
|
210
|
-
└── cache/
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
This directory is ready for:
|
|
214
|
-
|
|
215
|
-
* static hosting
|
|
216
|
-
* CDN deployment
|
|
217
|
-
* Nginx / Caddy / Netlify / Vercel
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Frontend API — `gardener.js`
|
|
222
|
-
|
|
223
|
-
File: `src/frontend/gardener.js`
|
|
224
|
-
|
|
225
|
-
### `gardener(obj)`
|
|
226
|
-
|
|
227
|
-
Create DOM elements from JSON.
|
|
228
|
-
|
|
229
|
-
```js
|
|
230
|
-
const el = gardener({
|
|
231
|
-
t: 'div',
|
|
232
|
-
cn: ['card', 'p-4'],
|
|
233
|
-
children: [
|
|
234
|
-
{ t: 'h2', txt: 'Title' },
|
|
235
|
-
{ t: 'p', txt: 'Content' }
|
|
236
|
-
]
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
document.body.appendChild(el);
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
### `parser(elementOrHtml, isParent = true)`
|
|
245
|
-
|
|
246
|
-
Convert DOM into gardener JSON.
|
|
247
|
-
|
|
248
|
-
```js
|
|
249
|
-
const json = parser(document.querySelector('.hero'));
|
|
250
|
-
console.log(json);
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
### `parserWindow(text)`
|
|
256
|
-
|
|
257
|
-
Dev-only UI:
|
|
258
|
-
|
|
259
|
-
* Preview parsed JSON
|
|
260
|
-
* Press **Y** to create a component file
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
### Utilities
|
|
265
|
-
|
|
266
|
-
* `imagePreloader(images)`
|
|
267
|
-
* `fetchElement(selector)`
|
|
268
|
-
* `appendElement(parent, child)`
|
|
269
|
-
* `replaceElement(original, newElem)`
|
|
270
|
-
* `createElement(type, classname)`
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## Dev-Only Endpoints ⚠️
|
|
275
|
-
|
|
276
|
-
### `POST /addcomponent`
|
|
277
|
-
|
|
278
|
-
Creates a frontend component file.
|
|
279
|
-
|
|
280
|
-
```json
|
|
281
|
-
{
|
|
282
|
-
"path": "components/MyComp.js",
|
|
283
|
-
"component": "{ t: 'div', txt: 'Hello' }"
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
Writes directly to the filesystem.
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
### `POST /addpage`
|
|
292
|
-
|
|
293
|
-
Creates an EJS page and registers a route.
|
|
294
|
-
|
|
295
|
-
```json
|
|
296
|
-
{ "page": "/my-page" }
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
* Generates a new EJS file
|
|
300
|
-
* Appends a route to the backend router
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## Security Notes
|
|
305
|
-
|
|
306
|
-
⚠️ **Important**
|
|
307
|
-
|
|
308
|
-
* `/addcomponent` and `/addpage` mutate files and routes
|
|
309
|
-
* Intended for **local development only**
|
|
310
|
-
* Do NOT expose publicly without authentication and sanitization
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
## Troubleshooting
|
|
315
|
-
|
|
316
|
-
* **Server not starting**
|
|
317
|
-
|
|
318
|
-
* Check `.env`
|
|
319
|
-
* Ensure PostgreSQL is running (if enabled)
|
|
320
|
-
* Inspect logs from `pnpm run dev`
|
|
321
|
-
|
|
322
|
-
* **Images not loading**
|
|
323
|
-
|
|
324
|
-
* Ensure source image exists in `src/frontend/assets`
|
|
325
|
-
* Filename must match `<name>_<width>x<height>.webp`
|
|
326
|
-
|
|
327
|
-
* **Tailwind not updating**
|
|
328
|
-
|
|
329
|
-
* Ensure `pnpm install` completed successfully
|
|
330
|
-
|
|
331
|
-
---
|
|
332
|
-
|
|
333
|
-
## Contributing
|
|
334
|
-
|
|
335
|
-
This is a small personal/dev-focused toolkit.
|
|
336
|
-
|
|
337
|
-
Contributions are welcome:
|
|
338
|
-
|
|
339
|
-
* bug fixes
|
|
340
|
-
* documentation improvements
|
|
341
|
-
* build pipeline enhancements
|
|
342
|
-
* security hardening
|
|
343
|
-
|
|
344
|
-
---
|
|
345
|
-
|
|
346
|
-
## License
|
|
347
|
-
|
|
348
|
-
MIT
|
|
349
|
-
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { gardener, fetchElement, replaceElement } from '../gardener.js'
|
|
3
|
-
|
|
4
|
-
export default function thisfun() {
|
|
5
|
-
return gardener({
|
|
6
|
-
"t": "span",
|
|
7
|
-
"cn": [
|
|
8
|
-
"emailsvg"
|
|
9
|
-
],
|
|
10
|
-
"children": [
|
|
11
|
-
{
|
|
12
|
-
"t": "svg",
|
|
13
|
-
"cn": [
|
|
14
|
-
"icon",
|
|
15
|
-
"icon-tabler",
|
|
16
|
-
"icons-tabler-outline",
|
|
17
|
-
"icon-tabler-mail"
|
|
18
|
-
],
|
|
19
|
-
"attr": {
|
|
20
|
-
"xmlns": "http://www.w3.org/2000/svg",
|
|
21
|
-
"width": "24",
|
|
22
|
-
"height": "24",
|
|
23
|
-
"viewBox": "0 0 24 24",
|
|
24
|
-
"fill": "none",
|
|
25
|
-
"stroke": "currentColor",
|
|
26
|
-
"stroke-width": "2",
|
|
27
|
-
"stroke-linecap": "round",
|
|
28
|
-
"stroke-linejoin": "round"
|
|
29
|
-
},
|
|
30
|
-
"children": [
|
|
31
|
-
{
|
|
32
|
-
"t": "path",
|
|
33
|
-
"attr": {
|
|
34
|
-
"stroke": "none",
|
|
35
|
-
"d": "M0 0h24v24H0z",
|
|
36
|
-
"fill": "none"
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"t": "path",
|
|
41
|
-
"attr": {
|
|
42
|
-
"d": "M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10"
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"t": "path",
|
|
47
|
-
"attr": {
|
|
48
|
-
"d": "M3 7l9 6l9 -6"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
})
|
|
55
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { gardener } from '../gardener.js'
|
|
3
|
-
|
|
4
|
-
export default function () {
|
|
5
|
-
return gardener({
|
|
6
|
-
"t": "svg",
|
|
7
|
-
"cn": [
|
|
8
|
-
"eye"
|
|
9
|
-
],
|
|
10
|
-
"attr": {
|
|
11
|
-
"xmlns": "http://www.w3.org/2000/svg",
|
|
12
|
-
"width": "24",
|
|
13
|
-
"height": "24",
|
|
14
|
-
"viewBox": "0 0 24 24",
|
|
15
|
-
"fill": "none",
|
|
16
|
-
"stroke": "currentColor",
|
|
17
|
-
"stroke-width": "2",
|
|
18
|
-
"stroke-linecap": "round",
|
|
19
|
-
"stroke-linejoin": "round"
|
|
20
|
-
},
|
|
21
|
-
"children": [
|
|
22
|
-
{
|
|
23
|
-
"t": "path",
|
|
24
|
-
"attr": {
|
|
25
|
-
"stroke": "none",
|
|
26
|
-
"d": "M0 0h24v24H0z",
|
|
27
|
-
"fill": "none"
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"t": "path",
|
|
32
|
-
"attr": {
|
|
33
|
-
"d": "M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"t": "path",
|
|
38
|
-
"attr": {
|
|
39
|
-
"d": "M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
})
|
|
44
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { gardener, fetchElement, replaceElement } from '../gardener.js'
|
|
3
|
-
|
|
4
|
-
export default function thisfun() {
|
|
5
|
-
return gardener({
|
|
6
|
-
"t": "div",
|
|
7
|
-
"attr": {
|
|
8
|
-
"id": "body"
|
|
9
|
-
},
|
|
10
|
-
"children": [
|
|
11
|
-
{
|
|
12
|
-
"t": "div",
|
|
13
|
-
"cn": [
|
|
14
|
-
"h-screen",
|
|
15
|
-
"w-screen",
|
|
16
|
-
"bg-white",
|
|
17
|
-
"loader",
|
|
18
|
-
"absolute"
|
|
19
|
-
],
|
|
20
|
-
"attr": {
|
|
21
|
-
"style": "transition: 0.4s; opacity: 0;"
|
|
22
|
-
},
|
|
23
|
-
"txt": ""
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"t": "div",
|
|
27
|
-
"cn": [
|
|
28
|
-
"hero",
|
|
29
|
-
"flex",
|
|
30
|
-
"justify-around",
|
|
31
|
-
"items-center",
|
|
32
|
-
"p-5",
|
|
33
|
-
"h-[90vh]"
|
|
34
|
-
],
|
|
35
|
-
"children": [
|
|
36
|
-
{
|
|
37
|
-
"t": "p",
|
|
38
|
-
"cn": [
|
|
39
|
-
"p-5"
|
|
40
|
-
],
|
|
41
|
-
"txt": "Gardener is a front-end library for creating and manipulating DOM elements using a declarative JavaScript object syntax. It includes a development server with features like timely reload and on-the-fly component creation from existing HTML. The server also provides dynamic image resizing and caching."
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"t": "img",
|
|
45
|
-
"attr": {
|
|
46
|
-
"src": "/cache/gardener_500x500.webp",
|
|
47
|
-
"alt": "logo"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
})
|
|
54
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|