@stone-js/starters 0.8.4 → 0.8.5

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 (55) hide show
  1. package/basic-react-declarative/app/Application.tsx +22 -7
  2. package/basic-react-declarative/assets/css/index.css +163 -18
  3. package/basic-react-declarative/package.json +8 -5
  4. package/basic-react-declarative/tests/Application.spec.ts +2 -2
  5. package/basic-react-imperative/app/Application.tsx +22 -7
  6. package/basic-react-imperative/assets/css/index.css +163 -18
  7. package/basic-react-imperative/package.json +8 -5
  8. package/basic-react-imperative/tests/Application.spec.ts +4 -2
  9. package/basic-service-declarative/app/Application.ts +18 -3
  10. package/basic-service-declarative/package.json +7 -4
  11. package/basic-service-declarative/tests/Application.spec.ts +3 -2
  12. package/basic-service-imperative/app/Application.ts +18 -3
  13. package/basic-service-imperative/package.json +7 -4
  14. package/basic-service-imperative/tests/Application.spec.ts +3 -2
  15. package/continuum-showcase/app/layouts/MainLayout.tsx +13 -7
  16. package/continuum-showcase/app/pages/BlogPostPage.tsx +5 -2
  17. package/continuum-showcase/app/pages/HomePage.tsx +19 -6
  18. package/continuum-showcase/assets/css/index.css +190 -18
  19. package/continuum-showcase/package.json +14 -8
  20. package/continuum-showcase/tests/HomePage.spec.tsx +4 -3
  21. package/full-react-declarative/app/middleware/AuthMiddleware.ts +1 -1
  22. package/full-react-declarative/app/pages/home/HomePage.tsx +22 -21
  23. package/full-react-declarative/assets/css/index.css +167 -0
  24. package/full-react-declarative/package.json +13 -10
  25. package/full-react-declarative/tests/HomePage.spec.ts +38 -0
  26. package/full-react-imperative/app/middleware/AuthMiddleware.ts +1 -1
  27. package/full-react-imperative/app/pages/home/HomePage.tsx +32 -16
  28. package/full-react-imperative/assets/css/index.css +167 -0
  29. package/full-react-imperative/package.json +13 -10
  30. package/full-react-imperative/tests/HomePage.spec.ts +45 -0
  31. package/full-service-declarative/app/handlers/WelcomeEventHandler.ts +47 -0
  32. package/full-service-declarative/app/middleware/AuthMiddleware.ts +1 -1
  33. package/full-service-declarative/package.json +12 -9
  34. package/full-service-declarative/tests/WelcomeEventHandler.spec.ts +54 -0
  35. package/full-service-imperative/app/handlers/WelcomeEventHandler.ts +51 -0
  36. package/full-service-imperative/app/middleware/AuthMiddleware.ts +1 -1
  37. package/full-service-imperative/package.json +12 -9
  38. package/full-service-imperative/tests/WelcomeEventHandler.spec.ts +31 -0
  39. package/package.json +1 -1
  40. package/standard-react-declarative/app/pages/welcome/WelcomePage.tsx +37 -5
  41. package/standard-react-declarative/assets/css/index.css +163 -18
  42. package/standard-react-declarative/package.json +11 -8
  43. package/standard-react-declarative/tests/WelcomePage.spec.ts +2 -0
  44. package/standard-react-imperative/app/pages/welcome/WelcomePage.tsx +37 -5
  45. package/standard-react-imperative/assets/css/index.css +163 -18
  46. package/standard-react-imperative/package.json +11 -8
  47. package/standard-react-imperative/tests/WelcomePage.spec.ts +2 -0
  48. package/standard-service-declarative/app/handlers/WelcomeEventHandler.ts +2 -2
  49. package/standard-service-declarative/app/services/WelcomeService.ts +28 -2
  50. package/standard-service-declarative/package.json +9 -6
  51. package/standard-service-declarative/tests/Application.spec.ts +13 -4
  52. package/standard-service-imperative/app/handlers/welcomeEventHandler.ts +2 -4
  53. package/standard-service-imperative/app/services/welcomeService.ts +28 -2
  54. package/standard-service-imperative/package.json +9 -6
  55. package/standard-service-imperative/tests/Application.spec.ts +12 -3
@@ -58,11 +58,11 @@ export class Application implements IPage<ReactIncomingEvent> {
58
58
  */
59
59
  head ({ event }: PageHeadContext): Promiseable<HeadContext> {
60
60
  return {
61
- title: `Hello ${String(event.get<string>('name', 'World'))}!`,
62
- description: 'This is a simple example of a React application using Stone.js',
61
+ title: `${String(event.get<string>('name', 'World'))} · Welcome to Stone.js`,
62
+ description: 'A universal Stone.js application. Write your domain once; Stone.js is the context that runs it anywhere.',
63
63
  metas: [
64
64
  { name: 'author', content: 'Stone.js' },
65
- { name: 'keywords', content: 'stonejs,js,react,example' }
65
+ { name: 'keywords', content: 'stonejs,continuum,react,universal,framework' }
66
66
  ]
67
67
  }
68
68
  }
@@ -74,10 +74,25 @@ export class Application implements IPage<ReactIncomingEvent> {
74
74
  */
75
75
  render ({ data }: PageRenderContext<ResponseData>): JSX.Element {
76
76
  return (
77
- <section className='container'>
78
- <img src='/logo.svg' alt='Stone.js' width={96} height={96} />
79
- <h1 className='h1 text-center mt-64'>{data?.message}</h1>
80
- </section>
77
+ <main className='stone-welcome'>
78
+ <div className='glow' aria-hidden='true' />
79
+ <section className='hero'>
80
+ <img className='mark' src='/logo.svg' alt='Stone.js' width={104} height={104} />
81
+ <p className='eyebrow'>Welcome to</p>
82
+ <h1 className='title'>Stone.js</h1>
83
+ <p className='lead'>{data?.message}</p>
84
+ <p className='tagline'>
85
+ Your app is running. Write your domain once, Stone.js is the context that runs it
86
+ anywhere: server, serverless, browser, CLI and the edge.
87
+ </p>
88
+ <nav className='links'>
89
+ <a href='https://stonejs.dev/docs' target='_blank' rel='noreferrer noopener'>Documentation</a>
90
+ <a href='https://github.com/stone-foundation/stone-js-framework' target='_blank' rel='noreferrer noopener'>GitHub</a>
91
+ <span className='edit'>Edit <b>app/Application.tsx</b></span>
92
+ </nav>
93
+ </section>
94
+ <footer className='brand'><span className='dot'>●</span> Stone.js — the continuum framework</footer>
95
+ </main>
81
96
  )
82
97
  }
83
98
  }
@@ -1,26 +1,171 @@
1
- body {
2
- margin: 0;
3
- padding: 0;
4
- color: #333;
5
- font-size: 14px;
6
- line-height: 1.5;
7
- background-color: #fff;
8
- font-family: 'Roboto', sans-serif;
1
+ /**
2
+ * Stone.js starter — brand welcome screen.
3
+ * Identity: "Obsidienne & Braise" — obsidian ground, ember (braise) accent, the Portal mark.
4
+ * Theme-aware: dark by default, light under prefers-color-scheme: light.
5
+ */
6
+ :root {
7
+ --ink: #14100E;
8
+ --ink-2: #1E1815;
9
+ --cream: #F4EFE6;
10
+ --cream-dim: #B8AE9E;
11
+ --ember-1: #FFC46B;
12
+ --ember-2: #FF5A1F;
13
+ --line: rgba(244, 239, 230, 0.10);
14
+ --card: rgba(244, 239, 230, 0.04);
15
+ --bg: radial-gradient(1200px 600px at 50% -10%, #241C17 0%, var(--ink) 55%);
9
16
  }
10
- .h1 {
17
+
18
+ @media (prefers-color-scheme: light) {
19
+ :root {
20
+ --ink: #F4EFE6;
21
+ --ink-2: #ffffff;
22
+ --cream: #1B1613;
23
+ --cream-dim: #6B6154;
24
+ --line: rgba(27, 22, 19, 0.10);
25
+ --card: rgba(27, 22, 19, 0.03);
26
+ --bg: radial-gradient(1200px 600px at 50% -10%, #FFFFFF 0%, #F1E9DC 60%);
27
+ }
28
+ }
29
+
30
+ * { box-sizing: border-box; }
31
+
32
+ body {
11
33
  margin: 0;
12
- font-size: 3rem;
13
- font-weight: 500;
14
- font-weight: bold;
34
+ min-height: 100vh;
35
+ color: var(--cream);
36
+ background: var(--ink);
37
+ font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
38
+ -webkit-font-smoothing: antialiased;
15
39
  }
16
- .container {
17
- width: 100vw;
40
+
41
+ .stone-welcome {
42
+ position: relative;
43
+ min-height: 100vh;
18
44
  display: flex;
45
+ flex-direction: column;
46
+ align-items: center;
19
47
  justify-content: center;
48
+ padding: 48px 24px;
49
+ background: var(--bg);
50
+ overflow: hidden;
51
+ }
52
+
53
+ /* Ember glow behind the mark. */
54
+ .stone-welcome .glow {
55
+ position: absolute;
56
+ top: 8%;
57
+ left: 50%;
58
+ width: 520px;
59
+ height: 520px;
60
+ transform: translateX(-50%);
61
+ background: radial-gradient(circle, rgba(255, 90, 31, 0.22) 0%, rgba(255, 90, 31, 0) 68%);
62
+ filter: blur(8px);
63
+ pointer-events: none;
64
+ z-index: 0;
20
65
  }
21
- .text-center {
66
+
67
+ .stone-welcome .hero {
68
+ position: relative;
69
+ z-index: 1;
70
+ width: 100%;
71
+ max-width: 680px;
22
72
  text-align: center;
73
+ animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
74
+ }
75
+
76
+ .stone-welcome .mark {
77
+ width: 104px;
78
+ height: 104px;
79
+ filter: drop-shadow(0 8px 28px rgba(255, 90, 31, 0.35));
80
+ }
81
+
82
+ .stone-welcome .eyebrow {
83
+ margin: 22px 0 0;
84
+ font-size: 12px;
85
+ font-weight: 600;
86
+ letter-spacing: 0.28em;
87
+ text-transform: uppercase;
88
+ color: var(--cream-dim);
89
+ }
90
+
91
+ .stone-welcome .title {
92
+ margin: 8px 0 0;
93
+ font-size: clamp(44px, 8vw, 76px);
94
+ font-weight: 800;
95
+ letter-spacing: -0.03em;
96
+ line-height: 1.02;
97
+ background: linear-gradient(92deg, var(--ember-1), var(--ember-2));
98
+ -webkit-background-clip: text;
99
+ background-clip: text;
100
+ color: transparent;
101
+ }
102
+
103
+ .stone-welcome .lead {
104
+ margin: 18px auto 0;
105
+ font-size: 20px;
106
+ font-weight: 600;
107
+ color: var(--cream);
108
+ }
109
+
110
+ .stone-welcome .tagline {
111
+ margin: 10px auto 0;
112
+ max-width: 46ch;
113
+ font-size: 16px;
114
+ line-height: 1.6;
115
+ color: var(--cream-dim);
116
+ }
117
+
118
+ .stone-welcome .links {
119
+ margin-top: 34px;
120
+ display: flex;
121
+ flex-wrap: wrap;
122
+ gap: 12px;
123
+ justify-content: center;
124
+ }
125
+
126
+ .stone-welcome .links a,
127
+ .stone-welcome .links .edit {
128
+ display: inline-flex;
129
+ align-items: center;
130
+ gap: 8px;
131
+ padding: 11px 18px;
132
+ border: 1px solid var(--line);
133
+ border-radius: 12px;
134
+ background: var(--card);
135
+ color: var(--cream);
136
+ font-size: 14px;
137
+ font-weight: 600;
138
+ text-decoration: none;
139
+ transition: border-color 0.2s, transform 0.2s, background 0.2s;
140
+ }
141
+
142
+ .stone-welcome .links a:hover {
143
+ transform: translateY(-2px);
144
+ border-color: rgba(255, 90, 31, 0.6);
145
+ background: rgba(255, 90, 31, 0.08);
146
+ }
147
+
148
+ .stone-welcome .links .edit {
149
+ font-family: ui-monospace, 'SF Mono', Menlo, Monaco, Consolas, monospace;
150
+ color: var(--cream-dim);
151
+ }
152
+ .stone-welcome .links .edit b { color: var(--ember-1); font-weight: 700; }
153
+
154
+ .stone-welcome .brand {
155
+ position: relative;
156
+ z-index: 1;
157
+ margin-top: 56px;
158
+ font-size: 13px;
159
+ letter-spacing: 0.02em;
160
+ color: var(--cream-dim);
161
+ }
162
+ .stone-welcome .brand .dot { color: var(--ember-2); }
163
+
164
+ @keyframes rise {
165
+ from { opacity: 0; transform: translateY(14px); }
166
+ to { opacity: 1; transform: translateY(0); }
167
+ }
168
+
169
+ @media (prefers-reduced-motion: reduce) {
170
+ .stone-welcome .hero { animation: none; }
23
171
  }
24
- .mt-64 {
25
- margin-top: 64px;
26
- }
@@ -20,20 +20,23 @@
20
20
  "dependencies": {
21
21
  "react": "^19.0.0",
22
22
  "react-dom": "^19.0.0",
23
- "@stone-js/core": "^0.8.4",
24
- "@stone-js/use-react": "^0.8.4",
25
- "@stone-js/browser-adapter": "^0.8.4",
26
- "@stone-js/node-cli-adapter": "^0.8.4"
23
+ "@stone-js/core": "^0.8.5",
24
+ "@stone-js/use-react": "^0.8.5",
25
+ "@stone-js/browser-adapter": "^0.8.5",
26
+ "@stone-js/node-cli-adapter": "^0.8.5"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@babel/plugin-proposal-decorators": "^7.25.9",
30
30
  "@babel/preset-env": "^7.26.9",
31
31
  "@babel/preset-typescript": "^7.27.0",
32
- "@stone-js/cli": "^0.8.4",
32
+ "@stone-js/cli": "^0.8.5",
33
33
  "@types/node": "^24.0.7",
34
34
  "@types/react": "^19.0.7",
35
35
  "@types/react-dom": "^19.0.3",
36
36
  "@vitest/coverage-v8": "^3.0.9",
37
37
  "vitest": "^3.0.9"
38
+ },
39
+ "overrides": {
40
+ "glob": "^11.0.0"
38
41
  }
39
42
  }
@@ -58,7 +58,6 @@ describe('Application', () => {
58
58
 
59
59
  it('get head values', async () => {
60
60
  // Arrange
61
- const expectedMessage = 'Hello World!'
62
61
  const event = { get: () => 'World' } as unknown as ReactIncomingEvent
63
62
 
64
63
  // Act
@@ -66,7 +65,8 @@ describe('Application', () => {
66
65
 
67
66
  // Assert
68
67
  expect(head).toHaveProperty('metas')
69
- expect(head.title).toBe(expectedMessage)
68
+ expect(head.title).toContain('Welcome to Stone.js')
69
+ expect(head.title).toContain('World')
70
70
  expect(head).toHaveProperty('description')
71
71
  })
72
72
 
@@ -27,11 +27,11 @@ export const FactoryHandler = ({ logger }: AppOptions): IPage<ReactIncomingEvent
27
27
  */
28
28
  head ({ event }: PageHeadContext): Promiseable<HeadContext> {
29
29
  return {
30
- title: `Hello ${String(event.get<string>('name', 'World'))}!`,
31
- description: 'This is a simple example of a React application using Stone.js',
30
+ title: `${String(event.get<string>('name', 'World'))} · Welcome to Stone.js`,
31
+ description: 'A universal Stone.js application. Write your domain once; Stone.js is the context that runs it anywhere.',
32
32
  metas: [
33
33
  { name: 'author', content: 'Stone.js' },
34
- { name: 'keywords', content: 'stonejs,js,react,example' }
34
+ { name: 'keywords', content: 'stonejs,continuum,react,universal,framework' }
35
35
  ]
36
36
  }
37
37
  },
@@ -43,10 +43,25 @@ export const FactoryHandler = ({ logger }: AppOptions): IPage<ReactIncomingEvent
43
43
  */
44
44
  render ({ data }: PageRenderContext<ResponseData>): JSX.Element {
45
45
  return (
46
- <section className='container'>
47
- <img src='/logo.svg' alt='Stone.js' width={96} height={96} />
48
- <h1 className='h1 text-center mt-64'>{data?.message}</h1>
49
- </section>
46
+ <main className='stone-welcome'>
47
+ <div className='glow' aria-hidden='true' />
48
+ <section className='hero'>
49
+ <img className='mark' src='/logo.svg' alt='Stone.js' width={104} height={104} />
50
+ <p className='eyebrow'>Welcome to</p>
51
+ <h1 className='title'>Stone.js</h1>
52
+ <p className='lead'>{data?.message}</p>
53
+ <p className='tagline'>
54
+ Your app is running. Write your domain once, Stone.js is the context that runs it
55
+ anywhere: server, serverless, browser, CLI and the edge.
56
+ </p>
57
+ <nav className='links'>
58
+ <a href='https://stonejs.dev/docs' target='_blank' rel='noreferrer noopener'>Documentation</a>
59
+ <a href='https://github.com/stone-foundation/stone-js-framework' target='_blank' rel='noreferrer noopener'>GitHub</a>
60
+ <span className='edit'>Edit <b>app/Application.tsx</b></span>
61
+ </nav>
62
+ </section>
63
+ <footer className='brand'><span className='dot'>●</span> Stone.js — the continuum framework</footer>
64
+ </main>
50
65
  )
51
66
  }
52
67
  }
@@ -1,26 +1,171 @@
1
- body {
2
- margin: 0;
3
- padding: 0;
4
- color: #333;
5
- font-size: 14px;
6
- line-height: 1.5;
7
- background-color: #fff;
8
- font-family: 'Roboto', sans-serif;
1
+ /**
2
+ * Stone.js starter — brand welcome screen.
3
+ * Identity: "Obsidienne & Braise" — obsidian ground, ember (braise) accent, the Portal mark.
4
+ * Theme-aware: dark by default, light under prefers-color-scheme: light.
5
+ */
6
+ :root {
7
+ --ink: #14100E;
8
+ --ink-2: #1E1815;
9
+ --cream: #F4EFE6;
10
+ --cream-dim: #B8AE9E;
11
+ --ember-1: #FFC46B;
12
+ --ember-2: #FF5A1F;
13
+ --line: rgba(244, 239, 230, 0.10);
14
+ --card: rgba(244, 239, 230, 0.04);
15
+ --bg: radial-gradient(1200px 600px at 50% -10%, #241C17 0%, var(--ink) 55%);
9
16
  }
10
- .h1 {
17
+
18
+ @media (prefers-color-scheme: light) {
19
+ :root {
20
+ --ink: #F4EFE6;
21
+ --ink-2: #ffffff;
22
+ --cream: #1B1613;
23
+ --cream-dim: #6B6154;
24
+ --line: rgba(27, 22, 19, 0.10);
25
+ --card: rgba(27, 22, 19, 0.03);
26
+ --bg: radial-gradient(1200px 600px at 50% -10%, #FFFFFF 0%, #F1E9DC 60%);
27
+ }
28
+ }
29
+
30
+ * { box-sizing: border-box; }
31
+
32
+ body {
11
33
  margin: 0;
12
- font-size: 3rem;
13
- font-weight: 500;
14
- font-weight: bold;
34
+ min-height: 100vh;
35
+ color: var(--cream);
36
+ background: var(--ink);
37
+ font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
38
+ -webkit-font-smoothing: antialiased;
15
39
  }
16
- .container {
17
- width: 100vw;
40
+
41
+ .stone-welcome {
42
+ position: relative;
43
+ min-height: 100vh;
18
44
  display: flex;
45
+ flex-direction: column;
46
+ align-items: center;
19
47
  justify-content: center;
48
+ padding: 48px 24px;
49
+ background: var(--bg);
50
+ overflow: hidden;
51
+ }
52
+
53
+ /* Ember glow behind the mark. */
54
+ .stone-welcome .glow {
55
+ position: absolute;
56
+ top: 8%;
57
+ left: 50%;
58
+ width: 520px;
59
+ height: 520px;
60
+ transform: translateX(-50%);
61
+ background: radial-gradient(circle, rgba(255, 90, 31, 0.22) 0%, rgba(255, 90, 31, 0) 68%);
62
+ filter: blur(8px);
63
+ pointer-events: none;
64
+ z-index: 0;
20
65
  }
21
- .text-center {
66
+
67
+ .stone-welcome .hero {
68
+ position: relative;
69
+ z-index: 1;
70
+ width: 100%;
71
+ max-width: 680px;
22
72
  text-align: center;
73
+ animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
74
+ }
75
+
76
+ .stone-welcome .mark {
77
+ width: 104px;
78
+ height: 104px;
79
+ filter: drop-shadow(0 8px 28px rgba(255, 90, 31, 0.35));
80
+ }
81
+
82
+ .stone-welcome .eyebrow {
83
+ margin: 22px 0 0;
84
+ font-size: 12px;
85
+ font-weight: 600;
86
+ letter-spacing: 0.28em;
87
+ text-transform: uppercase;
88
+ color: var(--cream-dim);
89
+ }
90
+
91
+ .stone-welcome .title {
92
+ margin: 8px 0 0;
93
+ font-size: clamp(44px, 8vw, 76px);
94
+ font-weight: 800;
95
+ letter-spacing: -0.03em;
96
+ line-height: 1.02;
97
+ background: linear-gradient(92deg, var(--ember-1), var(--ember-2));
98
+ -webkit-background-clip: text;
99
+ background-clip: text;
100
+ color: transparent;
101
+ }
102
+
103
+ .stone-welcome .lead {
104
+ margin: 18px auto 0;
105
+ font-size: 20px;
106
+ font-weight: 600;
107
+ color: var(--cream);
108
+ }
109
+
110
+ .stone-welcome .tagline {
111
+ margin: 10px auto 0;
112
+ max-width: 46ch;
113
+ font-size: 16px;
114
+ line-height: 1.6;
115
+ color: var(--cream-dim);
116
+ }
117
+
118
+ .stone-welcome .links {
119
+ margin-top: 34px;
120
+ display: flex;
121
+ flex-wrap: wrap;
122
+ gap: 12px;
123
+ justify-content: center;
124
+ }
125
+
126
+ .stone-welcome .links a,
127
+ .stone-welcome .links .edit {
128
+ display: inline-flex;
129
+ align-items: center;
130
+ gap: 8px;
131
+ padding: 11px 18px;
132
+ border: 1px solid var(--line);
133
+ border-radius: 12px;
134
+ background: var(--card);
135
+ color: var(--cream);
136
+ font-size: 14px;
137
+ font-weight: 600;
138
+ text-decoration: none;
139
+ transition: border-color 0.2s, transform 0.2s, background 0.2s;
140
+ }
141
+
142
+ .stone-welcome .links a:hover {
143
+ transform: translateY(-2px);
144
+ border-color: rgba(255, 90, 31, 0.6);
145
+ background: rgba(255, 90, 31, 0.08);
146
+ }
147
+
148
+ .stone-welcome .links .edit {
149
+ font-family: ui-monospace, 'SF Mono', Menlo, Monaco, Consolas, monospace;
150
+ color: var(--cream-dim);
151
+ }
152
+ .stone-welcome .links .edit b { color: var(--ember-1); font-weight: 700; }
153
+
154
+ .stone-welcome .brand {
155
+ position: relative;
156
+ z-index: 1;
157
+ margin-top: 56px;
158
+ font-size: 13px;
159
+ letter-spacing: 0.02em;
160
+ color: var(--cream-dim);
161
+ }
162
+ .stone-welcome .brand .dot { color: var(--ember-2); }
163
+
164
+ @keyframes rise {
165
+ from { opacity: 0; transform: translateY(14px); }
166
+ to { opacity: 1; transform: translateY(0); }
167
+ }
168
+
169
+ @media (prefers-reduced-motion: reduce) {
170
+ .stone-welcome .hero { animation: none; }
23
171
  }
24
- .mt-64 {
25
- margin-top: 64px;
26
- }
@@ -20,20 +20,23 @@
20
20
  "dependencies": {
21
21
  "react": "^19.0.0",
22
22
  "react-dom": "^19.0.0",
23
- "@stone-js/core": "^0.8.4",
24
- "@stone-js/use-react": "^0.8.4",
25
- "@stone-js/browser-adapter": "^0.8.4",
26
- "@stone-js/node-cli-adapter": "^0.8.4"
23
+ "@stone-js/core": "^0.8.5",
24
+ "@stone-js/use-react": "^0.8.5",
25
+ "@stone-js/browser-adapter": "^0.8.5",
26
+ "@stone-js/node-cli-adapter": "^0.8.5"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@babel/plugin-proposal-decorators": "^7.25.9",
30
30
  "@babel/preset-env": "^7.26.9",
31
31
  "@babel/preset-typescript": "^7.27.0",
32
- "@stone-js/cli": "^0.8.4",
32
+ "@stone-js/cli": "^0.8.5",
33
33
  "@types/node": "^24.0.7",
34
34
  "@types/react": "^19.0.7",
35
35
  "@types/react-dom": "^19.0.3",
36
36
  "@vitest/coverage-v8": "^3.0.9",
37
37
  "vitest": "^3.0.9"
38
+ },
39
+ "overrides": {
40
+ "glob": "^11.0.0"
38
41
  }
39
42
  }
@@ -30,7 +30,6 @@ describe('Application', () => {
30
30
 
31
31
  it('get head values', async () => {
32
32
  // Arrange
33
- const expectedMessage = 'Hello World!'
34
33
  const event = { get: () => 'World' } as unknown as IncomingEvent
35
34
 
36
35
  // Act
@@ -38,7 +37,8 @@ describe('Application', () => {
38
37
 
39
38
  // Assert
40
39
  expect(head).toHaveProperty('metas')
41
- expect(head.title).toBe(expectedMessage)
40
+ expect(head.title).toContain('Welcome to Stone.js')
41
+ expect(head.title).toContain('World')
42
42
  expect(head).toHaveProperty('description')
43
43
  })
44
44
 
@@ -73,6 +73,8 @@ describe('Application', () => {
73
73
  // Assert
74
74
  expect(response).toContain('/logo.svg')
75
75
  expect(response).toContain('alt="Stone.js"')
76
+ expect(response).toContain('Welcome to')
77
+ expect(response).toContain('Stone.js')
76
78
  })
77
79
 
78
80
  it('should get config', () => {
@@ -38,13 +38,22 @@ export class Application implements IEventHandler<IncomingEvent> {
38
38
  */
39
39
  handle (event: IncomingEvent): ResponseData {
40
40
  // Get the name from the event
41
- const message = `Hello ${String(event.get<string>('name', 'World'))}!`
41
+ const name = String(event.get<string>('name', 'World'))
42
+ const message = `Hello ${name}! Welcome to Stone.js.`
42
43
 
43
44
  // Log a message
44
45
  this.logger.info(message)
45
46
 
46
- // Return a JSON response
47
- return { message }
47
+ // Return a branded JSON response
48
+ return {
49
+ message,
50
+ framework: {
51
+ name: 'Stone.js',
52
+ tagline: 'The continuum framework',
53
+ docs: 'https://stonejs.dev',
54
+ github: 'https://github.com/stone-foundation/stone-js-framework'
55
+ }
56
+ }
48
57
  }
49
58
  }
50
59
 
@@ -53,4 +62,10 @@ export class Application implements IEventHandler<IncomingEvent> {
53
62
  */
54
63
  export interface ResponseData {
55
64
  message: string
65
+ framework: {
66
+ name: string
67
+ tagline: string
68
+ docs: string
69
+ github: string
70
+ }
56
71
  }
@@ -18,17 +18,20 @@
18
18
  "test:cvg": "npm run test -- --coverage"
19
19
  },
20
20
  "dependencies": {
21
- "@stone-js/core": "^0.8.4",
22
- "@stone-js/node-cli-adapter": "^0.8.4",
23
- "@stone-js/node-http-adapter": "^0.8.4"
21
+ "@stone-js/core": "^0.8.5",
22
+ "@stone-js/node-cli-adapter": "^0.8.5",
23
+ "@stone-js/node-http-adapter": "^0.8.5"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@babel/plugin-proposal-decorators": "^7.25.9",
27
27
  "@babel/preset-env": "^7.26.9",
28
28
  "@babel/preset-typescript": "^7.27.0",
29
- "@stone-js/cli": "^0.8.4",
29
+ "@stone-js/cli": "^0.8.5",
30
30
  "@types/node": "^24.0.7",
31
31
  "@vitest/coverage-v8": "^3.0.9",
32
32
  "vitest": "^3.0.9"
33
+ },
34
+ "overrides": {
35
+ "glob": "^11.0.0"
33
36
  }
34
37
  }
@@ -47,14 +47,15 @@ describe('Application', () => {
47
47
 
48
48
  it('should handle incoming events', () => {
49
49
  // Arrange
50
- const expectedMessage = 'Hello World!'
50
+ const expectedMessage = 'Hello World! Welcome to Stone.js.'
51
51
  const event = { get: () => 'World' } as unknown as IncomingEvent
52
52
 
53
53
  // Act
54
- const response = app.handle(event) as { message: string }
54
+ const response = app.handle(event)
55
55
 
56
56
  // Assert
57
57
  expect(response.message).toBe(expectedMessage)
58
+ expect(response.framework.name).toBe('Stone.js')
58
59
  expect(mockedLogger.info).toHaveBeenCalledWith(expectedMessage)
59
60
  })
60
61
  })