@seip/blue-bird 0.4.4 → 0.4.6

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 (53) hide show
  1. package/.env_example +26 -25
  2. package/AGENTS.md +199 -199
  3. package/LICENSE +21 -0
  4. package/README.md +79 -79
  5. package/backend/index.js +13 -13
  6. package/backend/routes/api.js +31 -31
  7. package/backend/routes/frontend.js +41 -41
  8. package/backend/routes/seo.js +39 -39
  9. package/core/app.js +328 -325
  10. package/core/auth.js +114 -83
  11. package/core/cache.js +44 -44
  12. package/core/cli/component.js +42 -42
  13. package/core/cli/init.js +119 -118
  14. package/core/cli/react.js +435 -435
  15. package/core/cli/route.js +42 -42
  16. package/core/cli/scaffolding-auth.js +1037 -0
  17. package/core/config.js +48 -47
  18. package/core/debug.js +248 -248
  19. package/core/logger.js +100 -100
  20. package/core/middleware.js +27 -27
  21. package/core/router.js +333 -333
  22. package/core/seo.js +95 -100
  23. package/core/swagger.js +40 -25
  24. package/core/template.js +472 -462
  25. package/core/upload.js +76 -76
  26. package/core/validate.js +380 -380
  27. package/frontend/index.html +26 -26
  28. package/frontend/landing.html +69 -69
  29. package/frontend/resources/css/tailwind.css +17 -17
  30. package/frontend/resources/js/App.jsx +70 -70
  31. package/frontend/resources/js/Main.jsx +18 -18
  32. package/frontend/resources/js/blue-bird/components/Button.jsx +67 -67
  33. package/frontend/resources/js/blue-bird/components/Card.jsx +18 -18
  34. package/frontend/resources/js/blue-bird/components/DataTable.jsx +126 -126
  35. package/frontend/resources/js/blue-bird/components/Input.jsx +21 -21
  36. package/frontend/resources/js/blue-bird/components/Label.jsx +12 -12
  37. package/frontend/resources/js/blue-bird/components/LanguageButton.jsx +23 -23
  38. package/frontend/resources/js/blue-bird/components/Link.jsx +15 -15
  39. package/frontend/resources/js/blue-bird/components/Modal.jsx +27 -27
  40. package/frontend/resources/js/blue-bird/components/Skeleton.jsx +44 -44
  41. package/frontend/resources/js/blue-bird/components/Translate.jsx +12 -12
  42. package/frontend/resources/js/blue-bird/components/Typography.jsx +69 -69
  43. package/frontend/resources/js/blue-bird/contexts/LanguageContext.jsx +41 -41
  44. package/frontend/resources/js/blue-bird/contexts/SPAContext.jsx +239 -237
  45. package/frontend/resources/js/blue-bird/contexts/SnackbarContext.jsx +38 -38
  46. package/frontend/resources/js/blue-bird/contexts/ThemeContext.jsx +49 -49
  47. package/frontend/resources/js/blue-bird/locales/en.json +47 -47
  48. package/frontend/resources/js/blue-bird/locales/es.json +47 -47
  49. package/frontend/resources/js/components/Header.jsx +55 -55
  50. package/frontend/resources/js/pages/About.jsx +31 -31
  51. package/frontend/resources/js/pages/Home.jsx +82 -82
  52. package/package.json +57 -57
  53. package/vite.config.js +22 -22
package/core/seo.js CHANGED
@@ -1,100 +1,95 @@
1
- import Config from "./config.js";
2
-
3
- const props = Config.props();
4
-
5
- /**
6
- * SEO utility class for generating sitemaps and robots.txt files.
7
- */
8
- class SEO {
9
- /**
10
- * Generates a sitemap.xml string based on a provided routes configuration.
11
- * Supports multilingual routes with language-prefixed paths.
12
- *
13
- * @static
14
- * @method generateSitemap
15
- * @param {Array<Object>} routesConfig - The SEO routes configuration array.
16
- * @param {Object} [options={}] - Configuration options.
17
- * @param {Array<string>} [options.languages=[]] - List of supported languages.
18
- * @param {string} [options.defaultLanguage="en"] - The default language.
19
- * @returns {string} The generated XML sitemap.
20
- */
21
- static generateSitemap(routesConfig, options = {}) {
22
- const { languages = [], defaultLanguage = "en" } = options;
23
- const host = (props.host || "http://localhost").replace(/\/$/, "");
24
- const port = props.port && props.port !== 80 && props.port !== 443 ? `:${props.port}` : "";
25
- const baseUrl = `${host}${port}`;
26
- const date = new Date().toISOString().split("T")[0];
27
-
28
- let xml = '<?xml version="1.0" encoding="UTF-8"?>';
29
- xml +=
30
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">';
31
-
32
- routesConfig.forEach((route) => {
33
- const { path: routePath } = route;
34
-
35
- // Default path (no prefix)
36
- xml += `
37
- <url>
38
- <loc>${baseUrl}${routePath}</loc>
39
- <lastmod>${date}</lastmod>
40
- <priority>${routePath === "/" ? "1.0" : "0.8"}</priority>
41
- </url>`;
42
-
43
- // Language-prefixed paths
44
- if (languages.length > 0) {
45
- languages.forEach((lang) => {
46
- const langPath = `/${lang}${routePath === "/" ? "" : routePath}`;
47
- xml += `
48
- <url>
49
- <loc>${baseUrl}${langPath}</loc>
50
- <lastmod>${date}</lastmod>
51
- <priority>0.8</priority>
52
- </url>`;
53
- });
54
- }
55
- });
56
-
57
- xml += "\n</urlset>";
58
- return xml.trim();
59
- }
60
-
61
- /**
62
- * Generates a robots.txt string.
63
- *
64
- * @static
65
- * @method generateRobots
66
- * @returns {string} The generated robots.txt content.
67
- */
68
- static generateRobots() {
69
- const host = (props.host || "http://localhost").replace(/\/$/, "");
70
- const port = props.port && props.port !== 80 && props.port !== 443 ? `:${props.port}` : "";
71
- return `User-agent: *
72
- Allow: /
73
-
74
- Sitemap: ${host}${port}/sitemap.xml
75
- `;
76
- }
77
-
78
- /**
79
- * Registers sitemap.xml and robots.txt routes in the given Express router.
80
- *
81
- * @static
82
- * @method registerRoutes
83
- * @param {import('express').Router} expressRouter - The Express router instance.
84
- * @param {Array<Object>} routesConfig - The SEO routes configuration array.
85
- * @param {Object} [options={}] - Configuration options for sitemap generation.
86
- */
87
- static registerRoutes(expressRouter, routesConfig, options = {}) {
88
- expressRouter.get("/sitemap.xml", (req, res) => {
89
- res.header("Content-Type", "application/xml");
90
- res.send(this.generateSitemap(routesConfig, options));
91
- });
92
-
93
- expressRouter.get("/robots.txt", (req, res) => {
94
- res.header("Content-Type", "text/plain");
95
- res.send(this.generateRobots());
96
- });
97
- }
98
- }
99
-
100
- export default SEO;
1
+ import Config from "./config.js";
2
+
3
+ const props = Config.props();
4
+
5
+ /**
6
+ * SEO utility class for generating sitemaps and robots.txt files.
7
+ */
8
+ class SEO {
9
+ /**
10
+ * Generates a sitemap.xml string based on a provided routes configuration.
11
+ * Supports multilingual routes with language-prefixed paths.
12
+ *
13
+ * @static
14
+ * @method generateSitemap
15
+ * @param {Array<Object>} routesConfig - The SEO routes configuration array.
16
+ * @param {Object} [options={}] - Configuration options.
17
+ * @param {Array<string>} [options.languages=[]] - List of supported languages.
18
+ * @param {string} [options.defaultLanguage="en"] - The default language.
19
+ * @returns {string} The generated XML sitemap.
20
+ */
21
+ static generateSitemap(routesConfig, options = {}) {
22
+ const { languages = [], defaultLanguage = "en" } = options;
23
+ const host = (props.appUrl || "http://localhost").replace(/\/$/, "");
24
+ const baseUrl = `${host}`;
25
+ const date = new Date().toISOString().split("T")[0];
26
+
27
+ let xml = '<?xml version="1.0" encoding="UTF-8"?>';
28
+ xml +=
29
+ '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">';
30
+
31
+ routesConfig.forEach((route) => {
32
+ const { path: routePath } = route;
33
+
34
+ xml += `
35
+ <url>
36
+ <loc>${baseUrl}${routePath}</loc>
37
+ <lastmod>${date}</lastmod>
38
+ <priority>${routePath === "/" ? "1.0" : "0.8"}</priority>
39
+ </url>`;
40
+ if (languages.length > 0) {
41
+ languages.forEach((lang) => {
42
+ const langPath = `/${lang}${routePath === "/" ? "" : routePath}`;
43
+ xml += `
44
+ <url>
45
+ <loc>${baseUrl}${langPath}</loc>
46
+ <lastmod>${date}</lastmod>
47
+ <priority>0.8</priority>
48
+ </url>`;
49
+ });
50
+ }
51
+ });
52
+
53
+ xml += "\n</urlset>";
54
+ return xml.trim();
55
+ }
56
+
57
+ /**
58
+ * Generates a robots.txt string.
59
+ *
60
+ * @static
61
+ * @method generateRobots
62
+ * @returns {string} The generated robots.txt content.
63
+ */
64
+ static generateRobots() {
65
+ const host = (props.appUrl || "http://localhost").replace(/\/$/, "");
66
+ return `User-agent: *
67
+ Allow: /
68
+
69
+ Sitemap: ${host}/sitemap.xml
70
+ `;
71
+ }
72
+
73
+ /**
74
+ * Registers sitemap.xml and robots.txt routes in the given Express router.
75
+ *
76
+ * @static
77
+ * @method registerRoutes
78
+ * @param {import('express').Router} expressRouter - The Express router instance.
79
+ * @param {Array<Object>} routesConfig - The SEO routes configuration array.
80
+ * @param {Object} [options={}] - Configuration options for sitemap generation.
81
+ */
82
+ static registerRoutes(expressRouter, routesConfig, options = {}) {
83
+ expressRouter.get("/sitemap.xml", (req, res) => {
84
+ res.header("Content-Type", "application/xml");
85
+ res.send(this.generateSitemap(routesConfig, options));
86
+ });
87
+
88
+ expressRouter.get("/robots.txt", (req, res) => {
89
+ res.header("Content-Type", "text/plain");
90
+ res.send(this.generateRobots());
91
+ });
92
+ }
93
+ }
94
+
95
+ export default SEO;
package/core/swagger.js CHANGED
@@ -1,25 +1,40 @@
1
- import swaggerUi from "swagger-ui-express";
2
- import swaggerJSDoc from "swagger-jsdoc";
3
-
4
- class Swagger {
5
-
6
- static init(app, options) {
7
-
8
- const optionsJsDoc = {
9
- definition: {
10
- openapi: "3.0.0",
11
- info: options.info,
12
- servers: [
13
- { url: options.url }
14
- ]
15
- },
16
- apis: ["./backend/routes/*.js"]
17
- };
18
-
19
- const specs = swaggerJSDoc(optionsJsDoc);
20
-
21
- app.use("/docs", swaggerUi.serve, swaggerUi.setup(specs));
22
- }
23
- }
24
-
25
- export default Swagger;
1
+ import { execSync } from "node:child_process";
2
+
3
+ class SwaggerCli {
4
+ install() {
5
+ const dependencies = this.checkDependencies();
6
+ if (dependencies.missingDependencies.length > 0) {
7
+ console.log("Installing dependencies...");
8
+ console.log(`Installing swagger-jsdoc...`);
9
+ execSync(`npm install swagger-jsdoc@6.2.8`, { stdio: "inherit" });
10
+ console.log(`Installing swagger-ui-express...`);
11
+ execSync(`npm install swagger-ui-express@5.0.1`, { stdio: "inherit" });
12
+ }
13
+ }
14
+ checkDependencies() {
15
+ const dependencies = [
16
+ "swagger-jsdoc",
17
+ "swagger-ui-express"
18
+ ];
19
+ const missingDependencies = [];
20
+ dependencies.forEach(dependency => {
21
+ if (!this.checkDependency(dependency)) {
22
+ missingDependencies.push(dependency);
23
+ }
24
+ });
25
+ return {
26
+ missingDependencies
27
+ };
28
+ }
29
+ checkDependency(dependency) {
30
+ try {
31
+ require.resolve(dependency);
32
+ return true;
33
+ } catch (error) {
34
+ return false;
35
+ }
36
+ }
37
+ }
38
+
39
+ const swaggerExecutor = new SwaggerCli();
40
+ swaggerExecutor.install();