@seip/blue-bird 0.6.4 → 0.7.0

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.
@@ -0,0 +1,319 @@
1
+ /* ============================================================
2
+ Blue Bird - Base Stylesheet
3
+ Vanilla CSS — no build step required.
4
+ Import this file in your Astro layout.
5
+ ============================================================ */
6
+
7
+ /* -------------------------------------------------------
8
+ Design Tokens
9
+ ------------------------------------------------------- */
10
+ :root {
11
+ --color-bg: #020617;
12
+ --color-bg-surface: #0f172a;
13
+ --color-bg-muted: #1e293b;
14
+ --color-border: rgba(255, 255, 255, 0.08);
15
+ --color-text: #f1f5f9;
16
+ --color-text-muted: #94a3b8;
17
+ --color-text-subtle: #64748b;
18
+ --color-primary: #3b82f6;
19
+ --color-primary-h: #2563eb;
20
+ --color-accent: #6366f1;
21
+
22
+ --space-xs: 0.25rem;
23
+ --space-sm: 0.5rem;
24
+ --space-md: 1rem;
25
+ --space-lg: 1.5rem;
26
+ --space-xl: 2rem;
27
+ --space-2xl: 3rem;
28
+ --space-3xl: 4rem;
29
+
30
+ --font-sans: system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
31
+ --font-mono: ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace;
32
+ --text-sm: 0.875rem;
33
+ --text-base: 1rem;
34
+ --text-lg: 1.125rem;
35
+ --text-xl: 1.25rem;
36
+ --text-2xl: 1.5rem;
37
+ --text-3xl: 1.875rem;
38
+ --text-4xl: 2.25rem;
39
+ --text-5xl: 3rem;
40
+ --text-6xl: 3.75rem;
41
+
42
+ --radius-sm: 0.375rem;
43
+ --radius-md: 0.75rem;
44
+ --radius-lg: 1rem;
45
+ --radius-xl: 1.25rem;
46
+ --radius-2xl: 1.5rem;
47
+ --radius-full: 9999px;
48
+
49
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
50
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
51
+ --shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.6);
52
+ --shadow-glow-blue: 0 0 24px rgba(59, 130, 246, 0.2);
53
+ }
54
+
55
+ /* -------------------------------------------------------
56
+ Reset & Base
57
+ ------------------------------------------------------- */
58
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
59
+ html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
60
+ body {
61
+ min-height: 100dvh;
62
+ background-color: var(--color-bg);
63
+ color: var(--color-text);
64
+ font-family: var(--font-sans);
65
+ font-size: var(--text-base);
66
+ line-height: 1.6;
67
+ -webkit-font-smoothing: antialiased;
68
+ -moz-osx-font-smoothing: grayscale;
69
+ }
70
+ ::selection { background-color: var(--color-primary); color: #fff; }
71
+
72
+ /* -------------------------------------------------------
73
+ Typography
74
+ ------------------------------------------------------- */
75
+ h1, h2, h3, h4, h5, h6 { line-height: 1.2; font-weight: 700; letter-spacing: -0.02em; }
76
+ h1 { font-size: clamp(2rem, 5vw, var(--text-6xl)); }
77
+ h2 { font-size: clamp(1.5rem, 4vw, var(--text-4xl)); }
78
+ h3 { font-size: clamp(1.25rem, 3vw, var(--text-3xl)); }
79
+ h4 { font-size: var(--text-xl); }
80
+ p { color: var(--color-text-muted); line-height: 1.75; }
81
+ a { color: var(--color-primary); text-decoration: none; transition: color 0.2s ease; }
82
+ a:hover { color: var(--color-primary-h); }
83
+
84
+ code, kbd {
85
+ font-family: var(--font-mono);
86
+ font-size: 0.875em;
87
+ background: var(--color-bg-muted);
88
+ color: var(--color-text);
89
+ padding: 0.15em 0.4em;
90
+ border-radius: var(--radius-sm);
91
+ }
92
+ pre {
93
+ font-family: var(--font-mono);
94
+ background: var(--color-bg-surface);
95
+ border: 1px solid var(--color-border);
96
+ border-radius: var(--radius-lg);
97
+ padding: var(--space-lg);
98
+ overflow-x: auto;
99
+ font-size: var(--text-sm);
100
+ }
101
+ pre code { background: none; padding: 0; font-size: inherit; }
102
+ img, svg { display: block; max-width: 100%; }
103
+
104
+ /* -------------------------------------------------------
105
+ Layout
106
+ ------------------------------------------------------- */
107
+ .container {
108
+ width: 100%;
109
+ max-width: 80rem;
110
+ margin-inline: auto;
111
+ padding-inline: var(--space-lg);
112
+ }
113
+ .flex { display: flex; }
114
+ .flex-col { flex-direction: column; }
115
+ .items-center { align-items: center; }
116
+ .justify-between { justify-content: space-between; }
117
+ .justify-center { justify-content: center; }
118
+ .flex-wrap { flex-wrap: wrap; }
119
+ .gap-sm { gap: var(--space-sm); }
120
+ .gap-md { gap: var(--space-md); }
121
+ .gap-lg { gap: var(--space-lg); }
122
+ .gap-xl { gap: var(--space-xl); }
123
+ .grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-xl); }
124
+ .grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-xl); }
125
+ .text-center { text-align: center; }
126
+ .text-muted { color: var(--color-text-muted); }
127
+ .text-subtle { color: var(--color-text-subtle); }
128
+ .text-sm { font-size: var(--text-sm); }
129
+ .text-lg { font-size: var(--text-lg); }
130
+ .font-mono { font-family: var(--font-mono); }
131
+ .font-bold { font-weight: 700; }
132
+ .uppercase { text-transform: uppercase; letter-spacing: 0.08em; }
133
+ .mt-sm { margin-top: var(--space-sm); }
134
+ .mt-md { margin-top: var(--space-md); }
135
+ .mt-lg { margin-top: var(--space-lg); }
136
+ .mt-xl { margin-top: var(--space-xl); }
137
+ .mt-2xl { margin-top: var(--space-2xl); }
138
+ .mb-sm { margin-bottom: var(--space-sm); }
139
+ .mb-md { margin-bottom: var(--space-md); }
140
+ .mb-lg { margin-bottom: var(--space-lg); }
141
+ .mb-xl { margin-bottom: var(--space-xl); }
142
+ .py-lg { padding-block: var(--space-lg); }
143
+ .py-xl { padding-block: var(--space-xl); }
144
+ .py-2xl { padding-block: var(--space-2xl); }
145
+ .py-3xl { padding-block: var(--space-3xl); }
146
+ .px-md { padding-inline: var(--space-md); }
147
+ .px-lg { padding-inline: var(--space-lg); }
148
+
149
+ /* -------------------------------------------------------
150
+ Gradient Text
151
+ ------------------------------------------------------- */
152
+ .gradient-text {
153
+ background: linear-gradient(135deg, var(--color-primary), var(--color-accent), #fff);
154
+ -webkit-background-clip: text;
155
+ -webkit-text-fill-color: transparent;
156
+ background-clip: text;
157
+ }
158
+ .gradient-text-blue {
159
+ background: linear-gradient(90deg, #60a5fa, #a5b4fc);
160
+ -webkit-background-clip: text;
161
+ -webkit-text-fill-color: transparent;
162
+ background-clip: text;
163
+ }
164
+
165
+ /* -------------------------------------------------------
166
+ Header / Nav
167
+ ------------------------------------------------------- */
168
+ .site-header {
169
+ position: sticky;
170
+ top: 0;
171
+ z-index: 50;
172
+ padding: var(--space-sm) var(--space-lg);
173
+ }
174
+ .nav-bar {
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: space-between;
178
+ background: rgba(15, 23, 42, 0.7);
179
+ backdrop-filter: blur(12px);
180
+ -webkit-backdrop-filter: blur(12px);
181
+ border: 1px solid var(--color-border);
182
+ border-radius: var(--radius-2xl);
183
+ padding: var(--space-sm) var(--space-lg);
184
+ box-shadow: var(--shadow-md);
185
+ max-width: 80rem;
186
+ margin-inline: auto;
187
+ }
188
+ .nav-brand {
189
+ display: flex;
190
+ align-items: center;
191
+ gap: var(--space-sm);
192
+ font-size: var(--text-xl);
193
+ font-weight: 700;
194
+ color: var(--color-text);
195
+ text-decoration: none;
196
+ }
197
+ .nav-brand .brand-icon {
198
+ width: 2.5rem;
199
+ height: 2.5rem;
200
+ background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
201
+ border-radius: var(--radius-md);
202
+ display: flex;
203
+ align-items: center;
204
+ justify-content: center;
205
+ box-shadow: var(--shadow-glow-blue);
206
+ }
207
+ nav.nav-links { display: flex; gap: var(--space-xl); }
208
+ .nav-links a { font-size: var(--text-sm); font-weight: 500; color: var(--color-text-muted); transition: color 0.2s ease; }
209
+ .nav-links a:hover { color: var(--color-primary); }
210
+
211
+ /* -------------------------------------------------------
212
+ Buttons
213
+ ------------------------------------------------------- */
214
+ .btn {
215
+ display: inline-flex;
216
+ align-items: center;
217
+ gap: var(--space-sm);
218
+ padding: 0.75rem 1.75rem;
219
+ border-radius: var(--radius-xl);
220
+ font-weight: 600;
221
+ font-size: var(--text-base);
222
+ cursor: pointer;
223
+ border: none;
224
+ text-decoration: none;
225
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
226
+ }
227
+ .btn:hover { transform: translateY(-2px); }
228
+ .btn:active { transform: translateY(0); }
229
+ .btn-primary {
230
+ background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
231
+ color: #fff;
232
+ box-shadow: 0 4px 20px rgba(59, 130, 246, 0.3);
233
+ }
234
+ .btn-primary:hover { color: #fff; box-shadow: 0 6px 28px rgba(59, 130, 246, 0.45); }
235
+ .btn-outline {
236
+ background: transparent;
237
+ color: var(--color-text-muted);
238
+ border: 1px solid var(--color-border);
239
+ }
240
+ .btn-outline:hover { background: var(--color-bg-surface); color: var(--color-text); }
241
+
242
+ /* -------------------------------------------------------
243
+ Cards
244
+ ------------------------------------------------------- */
245
+ .card {
246
+ background: var(--color-bg-surface);
247
+ border: 1px solid var(--color-border);
248
+ border-radius: var(--radius-2xl);
249
+ padding: var(--space-xl);
250
+ transition: transform 0.25s ease, box-shadow 0.25s ease;
251
+ }
252
+ .card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
253
+ .card-glass {
254
+ background: rgba(15, 23, 42, 0.5);
255
+ backdrop-filter: blur(16px);
256
+ -webkit-backdrop-filter: blur(16px);
257
+ border: 1px solid var(--color-border);
258
+ border-radius: var(--radius-2xl);
259
+ padding: var(--space-xl);
260
+ }
261
+
262
+ /* -------------------------------------------------------
263
+ Badge
264
+ ------------------------------------------------------- */
265
+ .badge {
266
+ display: inline-flex;
267
+ align-items: center;
268
+ padding: 0.3rem 0.9rem;
269
+ border-radius: var(--radius-full);
270
+ font-size: 0.7rem;
271
+ font-weight: 600;
272
+ letter-spacing: 0.1em;
273
+ text-transform: uppercase;
274
+ background: rgba(59, 130, 246, 0.1);
275
+ color: #60a5fa;
276
+ border: 1px solid rgba(59, 130, 246, 0.2);
277
+ }
278
+
279
+ /* -------------------------------------------------------
280
+ Hero
281
+ ------------------------------------------------------- */
282
+ .hero {
283
+ position: relative;
284
+ overflow: hidden;
285
+ padding-block: var(--space-3xl);
286
+ text-align: center;
287
+ }
288
+ .hero-glow {
289
+ position: absolute;
290
+ border-radius: 50%;
291
+ filter: blur(80px);
292
+ pointer-events: none;
293
+ z-index: 0;
294
+ }
295
+ .hero-glow-1 { width: 24rem; height: 24rem; top: -6rem; left: -6rem; background: rgba(59, 130, 246, 0.08); }
296
+ .hero-glow-2 { width: 24rem; height: 24rem; bottom: -6rem; right: -6rem; background: rgba(99, 102, 241, 0.08); }
297
+ .hero-inner { position: relative; z-index: 1; max-width: 56rem; margin-inline: auto; }
298
+
299
+ /* -------------------------------------------------------
300
+ Section / Footer
301
+ ------------------------------------------------------- */
302
+ .section { padding-block: var(--space-3xl); }
303
+ .site-footer {
304
+ border-top: 1px solid var(--color-border);
305
+ padding-block: var(--space-xl);
306
+ text-align: center;
307
+ color: var(--color-text-subtle);
308
+ font-size: var(--text-sm);
309
+ background: var(--color-bg);
310
+ margin-top: var(--space-3xl);
311
+ }
312
+
313
+ /* -------------------------------------------------------
314
+ Scrollbar (Webkit)
315
+ ------------------------------------------------------- */
316
+ ::-webkit-scrollbar { width: 6px; }
317
+ ::-webkit-scrollbar-track { background: var(--color-bg); }
318
+ ::-webkit-scrollbar-thumb { background: var(--color-bg-muted); border-radius: var(--radius-full); }
319
+ ::-webkit-scrollbar-thumb:hover { background: var(--color-primary); }
Binary file
@@ -0,0 +1,19 @@
1
+ const port = (import.meta.env.PORT || "3000").replace(/^["']|["']$/g, "");
2
+ const host = (import.meta.env.HOST || "localhost").replace(/^["']|["']$/g, "");
3
+
4
+ /**
5
+ * Builds an absolute API URL for server-side fetch calls.
6
+ *
7
+ * @param {string} [path] - API path relative to the server root (e.g. "api/users").
8
+ * @param {URL} [requestUrl] - Current request URL (pass `Astro.url` from the page). Required in production.
9
+ * @returns {string} Absolute URL ready for fetch.
10
+ */
11
+ export function apiUrl(path = "", requestUrl) {
12
+ if (import.meta.env.DEV) {
13
+ return `http://${host}:${port}/${path}`;
14
+ }
15
+ if (!requestUrl) {
16
+ throw new Error("apiUrl: requestUrl is required in production (pass Astro.url)");
17
+ }
18
+ return new URL(`/${path}`, requestUrl).href;
19
+ }
@@ -0,0 +1,20 @@
1
+ ---
2
+ import { ClientRouter } from "astro:transitions";
3
+
4
+ const { title = "Blue Bird" } = Astro.props;
5
+ ---
6
+
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8" />
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
+ <title>{title}</title>
12
+ <link rel="stylesheet" href="/css/app.css" />
13
+ <ClientRouter />
14
+ </head>
15
+ <body
16
+ class="min-h-screen bg-slate-950 text-white font-sans antialiased selection:bg-blue-500 selection:text-white"
17
+ >
18
+ <slot />
19
+ </body>
20
+ </html>
@@ -0,0 +1,54 @@
1
+ ---
2
+ import Layout from "../layouts/Layout.astro";
3
+ ---
4
+
5
+ <Layout title="About - Blue Bird">
6
+ <header class="site-header">
7
+ <div class="nav-bar">
8
+ <a href="/" class="nav-brand">
9
+ <div class="brand-icon">
10
+ <svg width="20" height="20" fill="none" stroke="white" viewBox="0 0 24 24">
11
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
12
+ d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
13
+ </svg>
14
+ </div>
15
+ Blue Bird
16
+ </a>
17
+ <nav class="nav-links">
18
+ <a href="/">Home</a>
19
+ <a href="/about">About</a>
20
+ </nav>
21
+ </div>
22
+ </header>
23
+
24
+ <main class="container py-3xl">
25
+ <a href="/" class="btn btn-outline text-sm mb-2xl" style="width:fit-content;">
26
+ &larr; Back to Home
27
+ </a>
28
+
29
+ <div class="card-glass py-3xl px-lg" style="max-width:52rem;">
30
+ <span class="badge mb-lg" style="display:inline-flex;">Framework</span>
31
+ <h1 class="gradient-text mt-md">About Blue Bird</h1>
32
+ <p class="mt-lg">
33
+ Blue Bird is an Express-based framework with native support for Astro frontend rendering.
34
+ It provides raw performance, developer efficiency, and a clean project layout — batteries
35
+ included for auth, validation, caching, Docker orchestration, and more.
36
+ </p>
37
+
38
+ <div class="grid-2 mt-2xl">
39
+ <div class="card">
40
+ <h4 class="mb-md">Express Backend</h4>
41
+ <p class="text-sm">REST APIs, JWT auth, rate limiting, CORS, and Helmet security — all preconfigured via a clean constructor API.</p>
42
+ </div>
43
+ <div class="card">
44
+ <h4 class="mb-md">Astro Frontend</h4>
45
+ <p class="text-sm">File-based routing, SSR, View Transitions, and island architecture. Use Tailwind or any CSS framework you prefer.</p>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </main>
50
+
51
+ <footer class="site-footer">
52
+ <p>Powered by Blue Bird Framework &amp; Astro. All rights reserved.</p>
53
+ </footer>
54
+ </Layout>
@@ -0,0 +1,104 @@
1
+ ---
2
+ import Layout from "../layouts/Layout.astro";
3
+ import { apiUrl } from "../http/api";
4
+
5
+ let apiData = null;
6
+ try {
7
+ const response = await fetch(apiUrl("api/", Astro.url));
8
+ apiData = await response.json();
9
+ console.log("[index.astro] /api/ response:", apiData);
10
+ } catch (err) {
11
+ console.error("[index.astro] fetch error:", err.message);
12
+ }
13
+ ---
14
+
15
+ <Layout title="Home - Blue Bird">
16
+ <header class="site-header">
17
+ <div class="nav-bar">
18
+ <a href="/" class="nav-brand">
19
+ <div class="brand-icon">
20
+ <svg
21
+ width="20"
22
+ height="20"
23
+ fill="none"
24
+ stroke="white"
25
+ viewBox="0 0 24 24"
26
+ >
27
+ <path
28
+ stroke-linecap="round"
29
+ stroke-linejoin="round"
30
+ stroke-width="2"
31
+ d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
32
+ </svg>
33
+ </div>
34
+ Blue Bird
35
+ </a>
36
+ <nav class="nav-links">
37
+ <a href="/">Home</a>
38
+ <a href="/about">About</a>
39
+ </nav>
40
+ </div>
41
+ </header>
42
+
43
+ <main class="container py-3xl">
44
+ <div class="hero">
45
+ <div class="hero-glow hero-glow-1"></div>
46
+ <div class="hero-glow hero-glow-2"></div>
47
+
48
+ <div class="hero-inner">
49
+ <span class="badge mb-xl" style="display:inline-flex;"
50
+ >Welcome to Blue Bird with Astro</span
51
+ >
52
+
53
+ <h1 class="gradient-text mt-lg">
54
+ Hello, Astro Developer!<br />Welcome to the next level.
55
+ </h1>
56
+
57
+ <p class="mt-lg" style="max-width:40rem;margin-inline:auto;">
58
+ Blue Bird is a fast, structured, and opinionated Express.js framework
59
+ for developers who want visual elegance and performance, now powered
60
+ by Astro on the frontend.
61
+ </p>
62
+
63
+ <div class="flex justify-center gap-md mt-2xl flex-wrap">
64
+ <a href="/about" class="btn btn-primary">About Us &rarr;</a>
65
+ <a
66
+ href="https://www.npmjs.com/package/@seip/blue-bird"
67
+ target="_blank"
68
+ class="btn btn-outline"
69
+ >
70
+ npm package
71
+ </a>
72
+ </div>
73
+ </div>
74
+ </div>
75
+
76
+ <section class="grid-3 mt-2xl">
77
+ <div class="card">
78
+ <h4 class="gradient-text-blue mb-md">Astro SSR</h4>
79
+ <p>
80
+ Astro (v7.0) renders pages server-side via the Node adapter in
81
+ middleware mode, mounted inside Express.
82
+ </p>
83
+ </div>
84
+ <div class="card">
85
+ <h4 class="gradient-text-blue mb-md">AES-256-GCM Auth</h4>
86
+ <p>
87
+ JWT tokens encrypted with military-grade AES-256-GCM and served
88
+ through secure signed cookies.
89
+ </p>
90
+ </div>
91
+ <div class="card">
92
+ <h4 class="gradient-text-blue mb-md">Docker CLI</h4>
93
+ <p>
94
+ One-command orchestration for local MySQL, production stacks, and
95
+ container lifecycle management.
96
+ </p>
97
+ </div>
98
+ </section>
99
+ </main>
100
+
101
+ <footer class="site-footer">
102
+ <p>Powered by Blue Bird Framework &amp; Astro. All rights reserved.</p>
103
+ </footer>
104
+ </Layout>
@@ -1,13 +1,12 @@
1
- import App from "@seip/blue-bird/core/app.js";
2
- import routerApiExample from "./routes/api.js";
3
- import routerFrontendExample from "./routes/frontend.js";
1
+ import App from "./core/app.js";
2
+ import routerApi from "./backend/routes/api.js";
4
3
 
5
4
  /**
6
5
  * Main entry point for the Blue Bird application.
7
6
  * Initializes the App instance with routes, configuration, and starts the server.
8
7
  */
9
8
  const app = new App({
10
- routes: [routerApiExample, routerFrontendExample],
9
+ routes: [routerApi],
11
10
 
12
11
  cors: [],
13
12
 
@@ -16,6 +15,14 @@ const app = new App({
16
15
  host: "http://localhost",
17
16
 
18
17
  port: process.env.PORT,
18
+
19
+ astro: {
20
+ server: true,
21
+ serverEntry: "./frontend/dist/server/entry.mjs",
22
+ client: true,
23
+ clientDir: "./frontend/dist/client",
24
+ base: "/",
25
+ },
19
26
  });
20
27
 
21
28
  app.run();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seip/blue-bird",
3
- "version": "0.6.4",
3
+ "version": "0.7.0",
4
4
  "description": "Express opinionated framework with HTML rendering, API architecture, built-in JWT auth, validation, caching, and SEO",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,8 +25,11 @@
25
25
  },
26
26
  "homepage": "https://seip25.github.io/Blue-bird/",
27
27
  "scripts": {
28
- "dev": "node --watch --env-file=.env backend/index.js",
29
- "start": "node --env-file=.env backend/index.js",
28
+ "dev": "node --watch --env-file=.env index.js",
29
+ "dev:astro": "astro dev --root frontend",
30
+ "dev:api": "node --watch --env-file=.env index.js",
31
+ "start": "node --env-file=.env index.js",
32
+ "build": "astro build --root frontend",
30
33
  "init": "node core/cli/init.js",
31
34
  "route": "node core/cli/route.js",
32
35
  "swagger-install": "node core/cli/swagger.js",
@@ -38,13 +41,18 @@
38
41
  "files": [
39
42
  "core",
40
43
  "backend",
41
- "frontend",
44
+ "frontend/src",
45
+ "frontend/public",
46
+ "frontend/astro.config.mjs",
42
47
  "docker",
43
48
  "docker-compose.yml",
44
49
  "AGENTS.md",
50
+ "index.js",
45
51
  ".env_example"
46
52
  ],
47
53
  "dependencies": {
54
+ "@astrojs/node": "^11.0.0",
55
+ "astro": "^7.0.0",
48
56
  "chalk": "^5.6.2",
49
57
  "compression": "^1.8.1",
50
58
  "cookie-parser": "^1.4.7",
@@ -1,39 +0,0 @@
1
- import Router from "@seip/blue-bird/core/router.js";
2
- import Template from "@seip/blue-bird/core/template.js";
3
- import App from "@seip/blue-bird/core/app.js";
4
-
5
- const routerFrontendExample = new Router("/", { seo: true });
6
-
7
- //routerFrontendExample.use(App.helmet());
8
-
9
- routerFrontendExample.get("/", (req, res) => {
10
- return Template.render(res, "index", {
11
- metaTags: {
12
- titleMeta: "Home - Blue Bird",
13
- descriptionMeta: "Welcome to Blue Bird Framework",
14
- keywordsMeta: "blue bird, framework, express",
15
- },
16
- });
17
- });
18
-
19
- routerFrontendExample.get("/about", (req, res) => {
20
- return Template.render(res, "about", {
21
- metaTags: {
22
- titleMeta: "About - Blue Bird",
23
- descriptionMeta: "About Blue Bird Framework",
24
- keywordsMeta: "about, blue bird, framework",
25
- },
26
- });
27
- });
28
-
29
- routerFrontendExample.get("/preact_example", (req, res) => {
30
- return Template.render(res, "preact_example", {
31
- metaTags: {
32
- titleMeta: "Preact Example - Blue Bird",
33
- descriptionMeta: "Preact Example Blue Bird Framework",
34
- keywordsMeta: "preact, example, blue bird, framework",
35
- },
36
- });
37
- });
38
-
39
- export default routerFrontendExample;