create-elit 3.1.6 → 3.1.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/dist/index.js +10 -309
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,11 +4,6 @@
|
|
|
4
4
|
import { mkdir, writeFile } from "fs/promises";
|
|
5
5
|
import { join, resolve } from "path";
|
|
6
6
|
import { existsSync } from "fs";
|
|
7
|
-
var templates = {
|
|
8
|
-
basic: "Basic Elit app with counter example",
|
|
9
|
-
full: "Full-stack app with dev server and API routes",
|
|
10
|
-
minimal: "Minimal setup with just DOM rendering"
|
|
11
|
-
};
|
|
12
7
|
var colors = {
|
|
13
8
|
reset: "\x1B[0m",
|
|
14
9
|
cyan: "\x1B[36m",
|
|
@@ -24,16 +19,7 @@ function getProjectName() {
|
|
|
24
19
|
const args = process.argv.slice(2);
|
|
25
20
|
return args[0] || "my-elit-app";
|
|
26
21
|
}
|
|
27
|
-
function
|
|
28
|
-
const args = process.argv.slice(2);
|
|
29
|
-
const templateArg = args.find((arg) => arg.startsWith("--template="));
|
|
30
|
-
if (templateArg) {
|
|
31
|
-
const template2 = templateArg.split("=")[1];
|
|
32
|
-
if (template2 in templates) return template2;
|
|
33
|
-
}
|
|
34
|
-
return "basic";
|
|
35
|
-
}
|
|
36
|
-
async function createProject(projectName2, template2) {
|
|
22
|
+
async function createProject(projectName2) {
|
|
37
23
|
const projectPath = resolve(process.cwd(), projectName2);
|
|
38
24
|
if (existsSync(projectPath)) {
|
|
39
25
|
log(`Error: Directory "${projectName2}" already exists!`, "red");
|
|
@@ -41,7 +27,7 @@ async function createProject(projectName2, template2) {
|
|
|
41
27
|
}
|
|
42
28
|
log(`Creating a new Elit app in ${projectPath}...`, "cyan");
|
|
43
29
|
await mkdir(projectPath, { recursive: true });
|
|
44
|
-
await generateTemplate(projectPath, projectName2
|
|
30
|
+
await generateTemplate(projectPath, projectName2);
|
|
45
31
|
log("\nSuccess! Created " + projectName2, "green");
|
|
46
32
|
log("\nInside that directory, you can run several commands:", "dim");
|
|
47
33
|
log("\n npm run dev", "cyan");
|
|
@@ -56,7 +42,7 @@ async function createProject(projectName2, template2) {
|
|
|
56
42
|
log(" npm run dev\n", "cyan");
|
|
57
43
|
log("Happy coding! \u{1F680}", "green");
|
|
58
44
|
}
|
|
59
|
-
async function generateTemplate(projectPath, projectName2
|
|
45
|
+
async function generateTemplate(projectPath, projectName2) {
|
|
60
46
|
const packageJson = {
|
|
61
47
|
name: projectName2,
|
|
62
48
|
version: "0.0.0",
|
|
@@ -67,7 +53,7 @@ async function generateTemplate(projectPath, projectName2, template2) {
|
|
|
67
53
|
preview: "elit preview"
|
|
68
54
|
},
|
|
69
55
|
dependencies: {
|
|
70
|
-
elit: "^3.1.
|
|
56
|
+
elit: "^3.1.7"
|
|
71
57
|
}
|
|
72
58
|
};
|
|
73
59
|
await writeFile(
|
|
@@ -112,7 +98,7 @@ npm install
|
|
|
112
98
|
npm run dev
|
|
113
99
|
\`\`\`
|
|
114
100
|
|
|
115
|
-
Visit http://localhost:
|
|
101
|
+
Visit http://localhost:3000 to view your app.
|
|
116
102
|
|
|
117
103
|
## Available Scripts
|
|
118
104
|
|
|
@@ -131,9 +117,9 @@ import { client } from './src/client';
|
|
|
131
117
|
|
|
132
118
|
export default {
|
|
133
119
|
dev: {
|
|
134
|
-
port:
|
|
120
|
+
port: 3000,
|
|
135
121
|
host: 'localhost',
|
|
136
|
-
open:
|
|
122
|
+
open: true,
|
|
137
123
|
logging: true,
|
|
138
124
|
clients: [{
|
|
139
125
|
root: '.',
|
|
@@ -184,24 +170,15 @@ export default {
|
|
|
184
170
|
`;
|
|
185
171
|
await writeFile(join(projectPath, "public", "index.html"), indexHtml);
|
|
186
172
|
await mkdir(join(projectPath, "src"), { recursive: true });
|
|
187
|
-
if (template2 === "basic") {
|
|
188
|
-
await generateBasicTemplate(projectPath, projectName2);
|
|
189
|
-
} else if (template2 === "full") {
|
|
190
|
-
await generateFullTemplate(projectPath, projectName2);
|
|
191
|
-
} else {
|
|
192
|
-
await generateMinimalTemplate(projectPath, projectName2);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
async function generateBasicTemplate(projectPath, projectName2) {
|
|
196
173
|
const mainTs = `import { div, h1, h2, button, p } from 'elit/el';
|
|
197
174
|
import { createState, reactive } from 'elit/state';
|
|
198
175
|
import { render } from 'elit/dom';
|
|
199
176
|
import './styles.ts';
|
|
200
177
|
|
|
201
|
-
// Create reactive state
|
|
178
|
+
// Create reactive state
|
|
202
179
|
export const count = createState(0);
|
|
203
180
|
|
|
204
|
-
// Create app
|
|
181
|
+
// Create app
|
|
205
182
|
export const app = div({ className: 'container' },
|
|
206
183
|
div({ className: 'card' },
|
|
207
184
|
h1('Welcome to Elit! \u{1F680}'),
|
|
@@ -376,289 +353,13 @@ router.get('/api/hello', async (ctx) => {
|
|
|
376
353
|
ctx.res.end(JSON.stringify({ message: 'Hello from Elit ServerRouter!' }));
|
|
377
354
|
});
|
|
378
355
|
|
|
379
|
-
export const server = router;
|
|
380
|
-
`;
|
|
381
|
-
await writeFile(join(projectPath, "src", "server.ts"), serverTs);
|
|
382
|
-
}
|
|
383
|
-
async function generateFullTemplate(projectPath, projectName2) {
|
|
384
|
-
const mainTs = `import { div, h1, h2, button, p } from 'elit/el';
|
|
385
|
-
import { createState, reactive } from 'elit/state';
|
|
386
|
-
import { render } from 'elit/dom';
|
|
387
|
-
import './styles.ts';
|
|
388
|
-
|
|
389
|
-
// Create reactive state
|
|
390
|
-
export const count = createState(0);
|
|
391
|
-
export const message = createState<string>('');
|
|
392
|
-
|
|
393
|
-
// Fetch from API
|
|
394
|
-
async function fetchMessage() {
|
|
395
|
-
try {
|
|
396
|
-
const res = await fetch('/api/hello');
|
|
397
|
-
const data = await res.json();
|
|
398
|
-
message.value = data.message;
|
|
399
|
-
} catch (err) {
|
|
400
|
-
message.value = 'Error loading message';
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Create app
|
|
405
|
-
export const app = div({ className: 'container' },
|
|
406
|
-
div({ className: 'card' },
|
|
407
|
-
h1('Elit Full-Stack App \u{1F680}'),
|
|
408
|
-
p('Counter and API integration example'),
|
|
409
|
-
|
|
410
|
-
div({ className: 'counter' },
|
|
411
|
-
h2('Counter Example'),
|
|
412
|
-
reactive(count, (value) =>
|
|
413
|
-
div({ className: 'count-display' }, \`Count: \${value}\`)
|
|
414
|
-
),
|
|
415
|
-
div({ className: 'button-group' },
|
|
416
|
-
button({
|
|
417
|
-
onclick: () => count.value--,
|
|
418
|
-
className: 'btn btn-secondary'
|
|
419
|
-
}, '- Decrement'),
|
|
420
|
-
button({
|
|
421
|
-
onclick: () => count.value = 0,
|
|
422
|
-
className: 'btn btn-secondary'
|
|
423
|
-
}, 'Reset'),
|
|
424
|
-
button({
|
|
425
|
-
onclick: () => count.value++,
|
|
426
|
-
className: 'btn btn-primary'
|
|
427
|
-
}, '+ Increment')
|
|
428
|
-
)
|
|
429
|
-
),
|
|
430
|
-
|
|
431
|
-
div({ className: 'api-section' },
|
|
432
|
-
h2('API Example'),
|
|
433
|
-
button({
|
|
434
|
-
onclick: () => fetchMessage(),
|
|
435
|
-
className: 'btn btn-primary'
|
|
436
|
-
}, 'Fetch from API'),
|
|
437
|
-
reactive(message, (msg) =>
|
|
438
|
-
msg ? p({ className: 'api-message' }, \`API says: \${msg}\`) : p('')
|
|
439
|
-
)
|
|
440
|
-
)
|
|
441
|
-
)
|
|
442
|
-
);
|
|
443
|
-
|
|
444
|
-
render('root', app);
|
|
445
|
-
console.log('[Main] App rendered');
|
|
446
|
-
`;
|
|
447
|
-
await writeFile(join(projectPath, "src", "main.ts"), mainTs);
|
|
448
|
-
const serverTs = `import { ServerRouter } from 'elit/server';
|
|
449
|
-
|
|
450
|
-
export const router = new ServerRouter();
|
|
451
|
-
|
|
452
|
-
router.get('/api/hello', async (ctx) => {
|
|
453
|
-
ctx.res.setHeader('Content-Type', 'application/json');
|
|
454
|
-
ctx.res.end(JSON.stringify({ message: 'Hello from Elit ServerRouter!' }));
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
router.get('/api/count', async (ctx) => {
|
|
458
|
-
ctx.res.setHeader('Content-Type', 'application/json');
|
|
459
|
-
ctx.res.end(JSON.stringify({ count: Math.floor(Math.random() * 100) }));
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
export const server = router;
|
|
463
|
-
`;
|
|
464
|
-
await writeFile(join(projectPath, "src", "server.ts"), serverTs);
|
|
465
|
-
const stylesTs = `import styles from 'elit/style';
|
|
466
|
-
|
|
467
|
-
// Global styles
|
|
468
|
-
styles.addTag('*', {
|
|
469
|
-
margin: 0,
|
|
470
|
-
padding: 0,
|
|
471
|
-
boxSizing: 'border-box'
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
styles.addTag('body', {
|
|
475
|
-
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
476
|
-
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
477
|
-
minHeight: '100vh',
|
|
478
|
-
display: 'flex',
|
|
479
|
-
alignItems: 'center',
|
|
480
|
-
justifyContent: 'center',
|
|
481
|
-
padding: '2rem'
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
// Container
|
|
485
|
-
styles.addClass('container', {
|
|
486
|
-
width: '100%',
|
|
487
|
-
maxWidth: '600px'
|
|
488
|
-
});
|
|
489
|
-
|
|
490
|
-
// Card
|
|
491
|
-
styles.addClass('card', {
|
|
492
|
-
background: 'white',
|
|
493
|
-
borderRadius: '16px',
|
|
494
|
-
padding: '3rem',
|
|
495
|
-
boxShadow: '0 20px 60px rgba(0, 0, 0, 0.3)'
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
// Typography
|
|
499
|
-
styles.addTag('h1', {
|
|
500
|
-
fontSize: '2.5rem',
|
|
501
|
-
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
502
|
-
WebkitBackgroundClip: 'text',
|
|
503
|
-
WebkitTextFillColor: 'transparent',
|
|
504
|
-
backgroundClip: 'text',
|
|
505
|
-
marginBottom: '1rem'
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
styles.addTag('h2', {
|
|
509
|
-
fontSize: '1.5rem',
|
|
510
|
-
color: '#333',
|
|
511
|
-
marginBottom: '1rem'
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
styles.addTag('p', {
|
|
515
|
-
color: '#666',
|
|
516
|
-
marginBottom: '2rem',
|
|
517
|
-
lineHeight: 1.6
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
// Counter section
|
|
521
|
-
styles.addClass('counter', {
|
|
522
|
-
marginTop: '2rem',
|
|
523
|
-
paddingTop: '2rem',
|
|
524
|
-
borderTop: '2px solid #f0f0f0'
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
styles.addClass('count-display', {
|
|
528
|
-
fontSize: '3rem',
|
|
529
|
-
fontWeight: 'bold',
|
|
530
|
-
color: '#667eea',
|
|
531
|
-
textAlign: 'center',
|
|
532
|
-
margin: '2rem 0'
|
|
533
|
-
});
|
|
534
|
-
|
|
535
|
-
// API section
|
|
536
|
-
styles.addClass('api-section', {
|
|
537
|
-
marginTop: '2rem',
|
|
538
|
-
paddingTop: '2rem',
|
|
539
|
-
borderTop: '2px solid #f0f0f0'
|
|
540
|
-
});
|
|
541
|
-
|
|
542
|
-
styles.addClass('api-message', {
|
|
543
|
-
marginTop: '1rem',
|
|
544
|
-
padding: '1rem',
|
|
545
|
-
background: '#f0f0f0',
|
|
546
|
-
borderRadius: '8px',
|
|
547
|
-
color: '#333',
|
|
548
|
-
textAlign: 'center'
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
// Button group
|
|
552
|
-
styles.addClass('button-group', {
|
|
553
|
-
display: 'flex',
|
|
554
|
-
gap: '1rem',
|
|
555
|
-
justifyContent: 'center'
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
// Buttons
|
|
559
|
-
styles.addClass('btn', {
|
|
560
|
-
padding: '0.75rem 1.5rem',
|
|
561
|
-
border: 'none',
|
|
562
|
-
borderRadius: '8px',
|
|
563
|
-
fontSize: '1rem',
|
|
564
|
-
fontWeight: 600,
|
|
565
|
-
cursor: 'pointer',
|
|
566
|
-
transition: 'all 0.2s'
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
styles.addClass('btn-primary', {
|
|
570
|
-
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
571
|
-
color: 'white'
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
styles.addPseudoClass('hover', {
|
|
575
|
-
transform: 'translateY(-2px)',
|
|
576
|
-
boxShadow: '0 4px 12px rgba(102, 126, 234, 0.4)'
|
|
577
|
-
}, '.btn-primary');
|
|
578
|
-
|
|
579
|
-
styles.addClass('btn-secondary', {
|
|
580
|
-
background: '#f0f0f0',
|
|
581
|
-
color: '#333'
|
|
582
|
-
});
|
|
583
|
-
|
|
584
|
-
styles.addPseudoClass('hover', {
|
|
585
|
-
background: '#e0e0e0',
|
|
586
|
-
transform: 'translateY(-2px)'
|
|
587
|
-
}, '.btn-secondary');
|
|
588
|
-
|
|
589
|
-
styles.addPseudoClass('active', {
|
|
590
|
-
transform: 'translateY(0)'
|
|
591
|
-
}, '.btn');
|
|
592
|
-
|
|
593
|
-
styles.inject('global-styles');
|
|
594
|
-
export default styles;
|
|
595
|
-
`;
|
|
596
|
-
await writeFile(join(projectPath, "src", "styles.ts"), stylesTs);
|
|
597
|
-
const clientTs = `import { div, html, head, body, title, link, script, meta } from 'elit/el';
|
|
598
|
-
|
|
599
|
-
export const client = html(
|
|
600
|
-
head(
|
|
601
|
-
title('${projectName2} - Elit Full-Stack App'),
|
|
602
|
-
link({ rel: 'icon', type: 'image/svg+xml', href: 'favicon.svg' }),
|
|
603
|
-
meta({ charset: 'UTF-8' }),
|
|
604
|
-
meta({ name: 'viewport', content: 'width=device-width, initial-scale=1.0' }),
|
|
605
|
-
meta({ name: 'description', content: 'Full-stack TypeScript framework with dev server, HMR, routing, SSR, and REST API.' })
|
|
606
|
-
),
|
|
607
|
-
body(
|
|
608
|
-
div({ id: 'root' }),
|
|
609
|
-
script({ type: 'module', src: '/src/main.js' })
|
|
610
|
-
)
|
|
611
|
-
);
|
|
612
|
-
`;
|
|
613
|
-
await writeFile(join(projectPath, "src", "client.ts"), clientTs);
|
|
614
|
-
}
|
|
615
|
-
async function generateMinimalTemplate(projectPath, projectName2) {
|
|
616
|
-
const mainTs = `import { div, h1 } from 'elit/el';
|
|
617
|
-
import { render } from 'elit/dom';
|
|
618
|
-
|
|
619
|
-
// Create app
|
|
620
|
-
export const app = div(
|
|
621
|
-
h1('Hello Elit! \u{1F44B}')
|
|
622
|
-
);
|
|
623
|
-
|
|
624
|
-
render('root', app);
|
|
625
|
-
console.log('[Main] App rendered');
|
|
626
|
-
`;
|
|
627
|
-
await writeFile(join(projectPath, "src", "main.ts"), mainTs);
|
|
628
|
-
const clientTs = `import { div, html, head, body, title, meta, script } from 'elit/el';
|
|
629
|
-
|
|
630
|
-
export const client = html(
|
|
631
|
-
head(
|
|
632
|
-
title('${projectName2}'),
|
|
633
|
-
meta({ charset: 'UTF-8' }),
|
|
634
|
-
meta({ name: 'viewport', content: 'width=device-width, initial-scale=1.0' })
|
|
635
|
-
),
|
|
636
|
-
body(
|
|
637
|
-
div({ id: 'root' }),
|
|
638
|
-
script({ type: 'module', src: '/src/main.js' })
|
|
639
|
-
)
|
|
640
|
-
);
|
|
641
|
-
`;
|
|
642
|
-
await writeFile(join(projectPath, "src", "client.ts"), clientTs);
|
|
643
|
-
const serverTs = `import { ServerRouter } from 'elit/server';
|
|
644
|
-
|
|
645
|
-
export const router = new ServerRouter();
|
|
646
|
-
|
|
647
|
-
// Add your API routes here
|
|
648
|
-
// Example:
|
|
649
|
-
// router.get('/api/hello', async (ctx) => {
|
|
650
|
-
// ctx.res.setHeader('Content-Type', 'application/json');
|
|
651
|
-
// ctx.res.end(JSON.stringify({ message: 'Hello!' }));
|
|
652
|
-
// });
|
|
653
|
-
|
|
654
356
|
export const server = router;
|
|
655
357
|
`;
|
|
656
358
|
await writeFile(join(projectPath, "src", "server.ts"), serverTs);
|
|
657
359
|
}
|
|
658
360
|
var projectName = getProjectName();
|
|
659
|
-
var template = getTemplate();
|
|
660
361
|
log("\n\u{1F680} Create Elit App\n", "cyan");
|
|
661
|
-
createProject(projectName
|
|
362
|
+
createProject(projectName).catch((err) => {
|
|
662
363
|
log(`Error: ${err.message}`, "red");
|
|
663
364
|
process.exit(1);
|
|
664
365
|
});
|