frontend-hamroun 1.2.17 → 1.2.18

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.
Files changed (2) hide show
  1. package/bin/cli.js +167 -149
  2. package/package.json +6 -1
package/bin/cli.js CHANGED
@@ -397,275 +397,293 @@ async function generateApiRoute(name, directory) {
397
397
  const serverDeps = {
398
398
  "express": "^4.18.2",
399
399
  "cors": "^2.8.5",
400
- };"mongodb": "^5.7.0", // Add MongoDB support
400
+ "mongodb": "^5.7.0", // Add MongoDB support
401
401
  "jsonwebtoken": "^9.0.2", // Add JWT support for auth
402
- const devDeps = {.4.3" // Add password hashing support
403
- "@types/express": "^4.17.17",
404
- "@types/cors": "^2.8.13"
405
- };nst devDeps = {
402
+ "bcryptjs": "^2.4.3" // Add password hashing support
403
+ };
404
+
405
+ const devDeps = {
406
406
  "@types/express": "^4.17.17",
407
+ "@types/cors": "^2.8.13",
408
+ "@types/mongodb": "^4.0.7",
409
+ "@types/jsonwebtoken": "^9.0.3",
410
+ "@types/bcryptjs": "^2.4.4"
411
+ };
412
+
407
413
  // Add dependencies if needed
408
414
  pkg.dependencies = pkg.dependencies || {};
409
415
  for (const [dep, version] of Object.entries(serverDeps)) {
410
416
  if (!pkg.dependencies[dep]) {
411
417
  pkg.dependencies[dep] = version;
412
418
  needsUpdate = true;
413
- }Add dependencies if needed
414
- }kg.dependencies = pkg.dependencies || {};
415
- for (const [dep, version] of Object.entries(serverDeps)) {
419
+ }
420
+ }
421
+
416
422
  // Add dev dependencies if needed
417
423
  pkg.devDependencies = pkg.devDependencies || {};
418
424
  for (const [dep, version] of Object.entries(devDeps)) {
419
425
  if (!pkg.devDependencies[dep]) {
420
426
  pkg.devDependencies[dep] = version;
421
427
  needsUpdate = true;
422
- }Add dev dependencies if needed
423
- }kg.devDependencies = pkg.devDependencies || {};
424
- for (const [dep, version] of Object.entries(devDeps)) {
428
+ }
429
+ }
430
+
425
431
  // Add start script if it doesn't exist
426
- pkg.scripts = pkg.scripts || {};ersion;
432
+ pkg.scripts = pkg.scripts || {};
427
433
  if (!pkg.scripts.start) {
428
434
  pkg.scripts.start = "node server.js";
429
435
  needsUpdate = true;
430
436
  }
431
- // Add start script if it doesn't exist
432
- // Save changes if needed || {};
433
- if (needsUpdate) {tart) {
437
+
438
+ // Save changes if needed
439
+ if (needsUpdate) {
434
440
  await fs.writeJson(pkgPath, pkg, { spaces: 2 });
435
441
  console.log(chalk.green('Updated package.json with server dependencies'));
436
442
  }
437
443
  }
438
- } catch (error) {es if needed
444
+ } catch (error) {
439
445
  console.warn(chalk.yellow('Could not update package.json:', error.message));
440
- } await fs.writeJson(pkgPath, pkg, { spaces: 2 });
441
- } console.log(chalk.green('Updated package.json with server dependencies'));
442
- }
446
+ }
447
+ }
448
+
443
449
  spinner.success({ text: `API route ${chalk.green(name)} generated successfully!` });
444
- } catch (error) {
445
- console.log('\nFile created:');Could not update package.json:', error.message));
450
+
451
+ console.log('\nFile created:');
446
452
  console.log(chalk.cyan(` ${path.join(directory, routePath)}.ts`));
447
- }
453
+
448
454
  } catch (error) {
449
- spinner.error({ text: 'Failed to generate API route' });generated successfully!` });
455
+ spinner.error({ text: 'Failed to generate API route' });
450
456
  console.error(chalk.red(error));
451
- process.exit(1);ile created:');
452
- } console.log(chalk.cyan(` ${path.join(directory, routePath)}.ts`));
453
- }
454
- } catch (error) {
455
- // Add a server template for Express generate API route' });
456
- const SERVER_TEMPLATE = `import { server } from 'frontend-hamroun';
457
457
  process.exit(1);
458
+ }
459
+ }
460
+
461
+ // Add a server template for Express
462
+ const SERVER_TEMPLATE = `import { server } from 'frontend-hamroun';
463
+
458
464
  async function startServer() {
459
465
  try {
460
466
  // Dynamically import server module
461
467
  const { Server } = await server.getServer();
462
- t SERVER_TEMPLATE = `import { server } from 'frontend-hamroun';
468
+
463
469
  // Create and configure the server
464
- const app = new Server({ {
470
+ const app = new Server({
465
471
  port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
466
- apiDir: './api',ort server module
467
- staticDir: './public', server.getServer();
472
+ apiDir: './api',
473
+ staticDir: './public',
468
474
 
469
- // Enable CORSr
470
- enableCors: true,t app = new Server({
471
- corsOptions: { process.env.PORT ? parseInt(process.env.PORT) : 3000,
475
+ // Enable CORS
476
+ enableCors: true,
477
+ corsOptions: {
472
478
  origin: process.env.CORS_ORIGIN || '*', // Set to specific domain in production
473
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],lic',
479
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
474
480
  allowedHeaders: ['Content-Type', 'Authorization']
475
- }, Uncomment to enable database
481
+ },
482
+
483
+ // Uncomment to enable database
476
484
  /*
477
- // Uncomment to enable database (choose one)
478
- /*url: process.env.DATABASE_URL || 'mongodb://localhost:27017/my_app',
479
- db: { 'mongodb'
485
+ db: {
480
486
  // MongoDB
481
487
  url: process.env.MONGODB_URL || 'mongodb://localhost:27017/my_app',
482
488
  type: 'mongodb'
483
- Uncomment to enable authentication
484
- // MySQL*
485
- // url: process.env.MYSQL_URL || 'mysql://user:password@localhost:3306/my_db', auth: {
486
- // type: 'mysql'.env.JWT_SECRET || 'your-secret-key',
487
- '
488
- // PostgreSQL }
489
+
490
+ // MySQL
491
+ // url: process.env.MYSQL_URL || 'mysql://user:password@localhost:3306/my_db',
492
+ // type: 'mysql'
493
+
494
+ // PostgreSQL
489
495
  // url: process.env.POSTGRES_URL || 'postgres://user:password@localhost:5432/my_db',
490
496
  // type: 'postgres'
491
497
  },
492
498
  */
493
499
 
494
500
  // Uncomment to enable authentication
495
- /* running at http://localhost:' +
496
- auth: {T || 3000));
501
+ /*
502
+ auth: {
497
503
  secret: process.env.JWT_SECRET || 'your-secret-key',
498
- expiresIn: '7d'ful shutdown
504
+ expiresIn: '7d'
499
505
  }
500
- */hutting down server...');
501
- }); await app.stop();
502
- process.exit(0);
503
- // Connect to database if configured });
504
- if (app.getDatabase()) {or) {
505
- await app.getDatabase().connect(); console.error('Failed to start server:', error);
506
- console.log('Connected to database'); process.exit(1);
506
+ */
507
+ });
508
+
509
+ // Connect to database if configured
510
+ if (app.getDatabase()) {
511
+ await app.getDatabase().connect();
512
+ console.log('Connected to database');
507
513
  }
508
514
 
509
515
  // Start the server
510
- await app.start();rver();
516
+ await app.start();
511
517
 
512
518
  console.log('Server running at http://localhost:' +
513
- (process.env.PORT || 3000));c function addDockerfile(isSSR) {
514
- ockerfile...').start();
519
+ (process.env.PORT || 3000));
520
+
515
521
  // Handle graceful shutdown
516
522
  process.on('SIGINT', async () => {
517
- console.log('Shutting down server...');PLATE : DOCKERFILE_TEMPLATE;
518
- if (app.getDatabase()) {ath.join(process.cwd(), 'Dockerfile');
523
+ console.log('Shutting down server...');
524
+ if (app.getDatabase()) {
519
525
  await app.getDatabase().disconnect();
520
526
  console.log('Database connection closed');
521
- }xists(targetPath)) {
522
- await app.stop();ner.stop();
523
- console.log('Server stopped');const { overwrite } = await inquirer.prompt([{
524
- process.exit(0);,
527
+ }
528
+ await app.stop();
529
+ console.log('Server stopped');
530
+ process.exit(0);
525
531
  });
526
- } catch (error) {: 'Dockerfile already exists. Overwrite?',
527
- console.error('Failed to start server:', error); default: false
528
- process.exit(1);}]);
532
+ } catch (error) {
533
+ console.error('Failed to start server:', error);
534
+ process.exit(1);
529
535
  }
530
- } if (!overwrite) {
531
- console.log(chalk.yellow('Operation cancelled.'));
536
+ }
537
+
532
538
  startServer();
533
539
  `;
534
-
540
+
535
541
  async function addDockerfile(isSSR) {
536
- const spinner = createSpinner('Adding Dockerfile...').start();}
542
+ const spinner = createSpinner('Adding Dockerfile...').start();
537
543
 
538
544
  try {
539
545
  const dockerContent = isSSR ? SSR_DOCKERFILE_TEMPLATE : DOCKERFILE_TEMPLATE;
540
546
  const targetPath = path.join(process.cwd(), 'Dockerfile');
541
- ({ text: 'Dockerfile added successfully!' });
547
+
542
548
  // Check if Dockerfile already exists
543
- if (await fs.pathExists(targetPath)) {Docker image:');
544
- spinner.stop();k.cyan(' docker build -t my-app .'));
545
- const { overwrite } = await inquirer.prompt([{ console.log(chalk.cyan(' docker run -p 3000:' + (isSSR ? '3000' : '80') + ' my-app'));
546
- type: 'confirm',
547
- name: 'overwrite', } catch (error) {
548
- message: 'Dockerfile already exists. Overwrite?','Failed to add Dockerfile' });
549
+ if (await fs.pathExists(targetPath)) {
550
+ spinner.stop();
551
+ const { overwrite } = await inquirer.prompt([{
552
+ type: 'confirm',
553
+ name: 'overwrite',
554
+ message: 'Dockerfile already exists. Overwrite?',
549
555
  default: false
550
- }]); process.exit(1);
556
+ }]);
551
557
 
552
558
  if (!overwrite) {
553
559
  console.log(chalk.yellow('Operation cancelled.'));
554
- return;lates
555
- }quest, Response } from 'express';
560
+ return;
561
+ }
556
562
 
557
- spinner.start();port const get = (req: Request, res: Response) => {
558
- } res.json({
563
+ spinner.start();
564
+ }
559
565
 
560
- // Write Dockerfileeq.query,
566
+ // Write Dockerfile
561
567
  await fs.writeFile(targetPath, dockerContent);
562
568
 
563
569
  spinner.success({ text: 'Dockerfile added successfully!' });
564
570
 
565
- console.log('\nTo build and run Docker image:');port const post = (req: Request, res: Response) => {
566
- console.log(chalk.cyan(' docker build -t my-app .')); res.json({
571
+ console.log('\nTo build and run Docker image:');
572
+ console.log(chalk.cyan(' docker build -t my-app .'));
567
573
  console.log(chalk.cyan(' docker run -p 3000:' + (isSSR ? '3000' : '80') + ' my-app'));
568
- q.body,
569
- } catch (error) {)
574
+
575
+ } catch (error) {
570
576
  spinner.error({ text: 'Failed to add Dockerfile' });
571
577
  console.error(chalk.red(error));
572
578
  process.exit(1);
573
- }port const put = (req: Request, res: Response) => {
574
- } res.json({
579
+ }
580
+ }
575
581
 
576
- // Add API route templatesq.body,
582
+ // Add API route templates
577
583
  const API_ROUTE_TEMPLATE = `import { Request, Response } from 'express';
578
584
 
579
585
  export const get = (req: Request, res: Response) => {
580
586
  res.json({
581
- message: 'This is a GET endpoint',export const delete_ = (req: Request, res: Response) => {
587
+ message: 'This is a GET endpoint',
582
588
  query: req.query,
583
- timestamp: new Date().toISOString()ETE endpoint',
584
- });().toISOString()
589
+ timestamp: new Date().toISOString()
590
+ });
585
591
  };
586
592
 
587
593
  export const post = (req: Request, res: Response) => {
588
- res.json({You can add middleware that will be applied to all methods
589
- message: 'This is a POST endpoint',port const middleware = [
590
- body: req.body,// Example middleware
591
- timestamp: new Date().toISOString() (req: Request, res: Response, next: Function) => {
594
+ res.json({
595
+ message: 'This is a POST endpoint',
596
+ body: req.body,
597
+ timestamp: new Date().toISOString()
592
598
  });
593
- }; next();
599
+ };
594
600
 
595
601
  export const put = (req: Request, res: Response) => {
596
602
  res.json({
597
603
  message: 'This is a PUT endpoint',
598
- body: req.body,TE_TEMPLATE = `import { Request, Response } from 'express';
604
+ body: req.body,
599
605
  timestamp: new Date().toISOString()
600
- });t const get = (req: Request, res: Response) => {
601
- };res.json({
602
- message: 'This is a dynamic route GET endpoint',
606
+ });
607
+ };
608
+
603
609
  export const delete_ = (req: Request, res: Response) => {
604
- res.json({eq.query,
610
+ res.json({
605
611
  message: 'This is a DELETE endpoint',
606
612
  timestamp: new Date().toISOString()
607
613
  });
608
614
  };
609
- t const put = (req: Request, res: Response) => {
610
- // You can add middleware that will be applied to all methodsres.json({
611
- export const middleware = [ message: 'This is a dynamic route PUT endpoint',
615
+
616
+ // You can add middleware that will be applied to all methods
617
+ export const middleware = [
612
618
  // Example middleware
613
- (req: Request, res: Response, next: Function) => {q.body,
619
+ (req: Request, res: Response, next: Function) => {
614
620
  console.log(\`\${req.method} \${req.url} - \${new Date().toISOString()}\`);
615
621
  next();
616
622
  }
617
623
  ];
618
- `;port const delete_ = (req: Request, res: Response) => {
619
- res.json({
620
- const DYNAMIC_API_ROUTE_TEMPLATE = `import { Request, Response } from 'express'; message: 'This is a dynamic route DELETE endpoint',
624
+ `;
625
+
626
+ const DYNAMIC_API_ROUTE_TEMPLATE = `import { Request, Response } from 'express';
621
627
 
622
- export const get = (req: Request, res: Response) => {ng()
628
+ export const get = (req: Request, res: Response) => {
623
629
  res.json({
624
630
  message: 'This is a dynamic route GET endpoint',
625
631
  params: req.params,
626
632
  query: req.query,
627
- timestamp: new Date().toISOString()template
628
- });EMPLATE = `{
633
+ timestamp: new Date().toISOString()
634
+ });
629
635
  };
630
- ,
631
- export const put = (req: Request, res: Response) => {ext",
632
- res.json({on": "NodeNext",
633
- message: 'This is a dynamic route PUT endpoint',rue,
634
- params: req.params,"outDir": "./dist",
636
+
637
+ export const post = (req: Request, res: Response) => {
638
+ res.json({
639
+ message: 'This is a dynamic route POST endpoint',
640
+ params: req.params,
635
641
  body: req.body,
636
642
  timestamp: new Date().toISOString()
637
- }); "noEmit": false,
638
- }; "strict": true,
639
-
640
-
641
-
642
-
643
-
644
-
645
-
646
-
647
-
648
-
649
-
650
-
651
-
652
-
653
-
654
-
655
-
656
-
657
-
658
-
659
-
660
-
661
-
662
-
663
-
643
+ });
644
+ };
664
645
 
646
+ export const put = (req: Request, res: Response) => {
647
+ res.json({
648
+ message: 'This is a dynamic route PUT endpoint',
649
+ params: req.params,
650
+ body: req.body,
651
+ timestamp: new Date().toISOString()
652
+ });
653
+ };
665
654
 
655
+ export const delete_ = (req: Request, res: Response) => {
656
+ res.json({
657
+ message: 'This is a dynamic route DELETE endpoint',
658
+ params: req.params,
659
+ timestamp: new Date().toISOString()
660
+ });
661
+ };
666
662
 
663
+ // You can add middleware that will be applied to all methods
664
+ export const middleware = [
665
+ // Example middleware
666
+ (req: Request, res: Response, next: Function) => {
667
+ console.log(\`\${req.method} \${req.url} - \${new Date().toISOString()}\`);
668
+ next();
669
+ }
670
+ ];
671
+ `;
667
672
 
668
- init().catch(console.error);}`; "exclude": ["node_modules", "dist", "**/*.test.ts"] "include": ["server.ts", "api/**/*.ts"], }, "skipLibCheck": true "strict": true, "noEmit": false, "sourceMap": true, "declaration": true, "outDir": "./dist", "esModuleInterop": true, "moduleResolution": "NodeNext", "module": "NodeNext", "target": "ES2020", "compilerOptions": {const TSCONFIG_SERVER_TEMPLATE = `{// Add tsconfig.server.json template`;}; }); timestamp: new Date().toISOString() params: req.params, message: 'This is a dynamic route DELETE endpoint', res.json({export const delete_ = (req: Request, res: Response) => { },
673
+ // Add tsconfig.server.json template
674
+ const TSCONFIG_SERVER_TEMPLATE = `{
675
+ "compilerOptions": {
676
+ "target": "ES2020",
677
+ "module": "NodeNext",
678
+ "moduleResolution": "NodeNext",
679
+ "esModuleInterop": true,
680
+ "outDir": "./dist",
681
+ "declaration": true,
682
+ "sourceMap": true,
683
+ "noEmit": false,
684
+ "strict": true,
685
+ "skipLibCheck": true
686
+ },
669
687
  "include": ["server.ts", "api/**/*.ts"],
670
688
  "exclude": ["node_modules", "dist", "**/*.test.ts"]
671
689
  }`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frontend-hamroun",
3
- "version": "1.2.17",
3
+ "version": "1.2.18",
4
4
  "description": "A lightweight full-stack JavaScript framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,6 +19,11 @@
19
19
  "import": "./dist/index.mjs",
20
20
  "require": "./dist/index.js",
21
21
  "default": "./dist/index.js"
22
+ },
23
+ "./server": {
24
+ "types": "./dist/server/index.d.ts",
25
+ "import": "./dist/server/index.js",
26
+ "require": "./dist/server/index.js"
22
27
  }
23
28
  },
24
29
  "bin": {