@stone-js/starters 0.8.4 → 0.8.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 (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 +13 -10
  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 +13 -10
  38. package/full-service-imperative/tests/WelcomeEventHandler.spec.ts +31 -0
  39. package/package.json +6 -7
  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
@@ -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-weight: 500;
13
- font-size: 3rem;
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,23 +20,26 @@
20
20
  "dependencies": {
21
21
  "react": "^19.0.0",
22
22
  "react-dom": "^19.0.0",
23
- "@stone-js/use-react": "^0.8.4",
24
- "@stone-js/browser-adapter": "^0.8.4",
25
- "@stone-js/pipeline": "^0.8.4",
26
- "@stone-js/http-core": "^0.8.4",
27
- "@stone-js/node-http-adapter": "^0.8.4",
28
- "@stone-js/router": "^0.8.4",
29
- "@stone-js/core": "^0.8.4"
23
+ "@stone-js/use-react": "^0.8.6",
24
+ "@stone-js/browser-adapter": "^0.8.6",
25
+ "@stone-js/pipeline": "^0.8.6",
26
+ "@stone-js/http-core": "^0.8.6",
27
+ "@stone-js/node-http-adapter": "^0.8.6",
28
+ "@stone-js/router": "^0.8.6",
29
+ "@stone-js/core": "^0.8.6"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@babel/plugin-proposal-decorators": "^7.25.9",
33
33
  "@babel/preset-env": "^7.26.9",
34
34
  "@babel/preset-typescript": "^7.27.0",
35
- "@stone-js/cli": "^0.8.4",
35
+ "@stone-js/cli": "^0.8.6",
36
36
  "@types/node": "^24.0.7",
37
37
  "@types/react": "^19.0.7",
38
38
  "@types/react-dom": "^19.0.3",
39
39
  "@vitest/coverage-v8": "^3.0.9",
40
40
  "vitest": "^3.0.9"
41
+ },
42
+ "overrides": {
43
+ "glob": "^13.0.0"
41
44
  }
42
45
  }
@@ -47,5 +47,7 @@ describe('WelcomePage', () => {
47
47
  // Assert
48
48
  expect(response).toContain('/logo.svg')
49
49
  expect(response).toContain('alt="Stone.js"')
50
+ expect(response).toContain('Welcome')
51
+ expect(response).toContain('Stone.js')
50
52
  })
51
53
  })
@@ -1,5 +1,5 @@
1
1
  import { EventHandler, Get } from '@stone-js/router'
2
- import { WelcomeService } from '../services/WelcomeService'
2
+ import { WelcomeService, WelcomeResponse } from '../services/WelcomeService'
3
3
  import { IncomingHttpEvent, JsonHttpResponse } from '@stone-js/http-core'
4
4
 
5
5
  /**
@@ -39,7 +39,7 @@ export class WelcomeEventHandler {
39
39
  */
40
40
  @Get('/:name?')
41
41
  @JsonHttpResponse(200)
42
- welcome (event: IncomingHttpEvent): { message: string } {
42
+ welcome (event: IncomingHttpEvent): WelcomeResponse {
43
43
  return this.welcomeService.welcome(event.get<string>('name', 'World'))
44
44
  }
45
45
  }
@@ -7,6 +7,24 @@ export interface WelcomeServiceOptions {
7
7
  logger: ILogger
8
8
  }
9
9
 
10
+ /**
11
+ * Framework information carried by the welcome payload.
12
+ */
13
+ export interface FrameworkInfo {
14
+ name: string
15
+ tagline: string
16
+ docs: string
17
+ github: string
18
+ }
19
+
20
+ /**
21
+ * The branded welcome payload returned to the client.
22
+ */
23
+ export interface WelcomeResponse {
24
+ message: string
25
+ framework: FrameworkInfo
26
+ }
27
+
10
28
  /**
11
29
  * Welcome Service
12
30
  *
@@ -31,8 +49,16 @@ export class WelcomeService {
31
49
  * @param name - The name
32
50
  * @returns A welcome message
33
51
  */
34
- welcome (name: string): { message: string } {
52
+ welcome (name: string): WelcomeResponse {
35
53
  this.logger.info(`Welcome ${name}`)
36
- return { message: `Hello ${name}!` }
54
+ return {
55
+ message: `Hello ${name}! Welcome to Stone.js.`,
56
+ framework: {
57
+ name: 'Stone.js',
58
+ tagline: 'The continuum framework',
59
+ docs: 'https://stonejs.dev',
60
+ github: 'https://github.com/stone-foundation/stone-js-framework'
61
+ }
62
+ }
37
63
  }
38
64
  }
@@ -18,19 +18,22 @@
18
18
  "test:cvg": "npm run test -- --coverage"
19
19
  },
20
20
  "dependencies": {
21
- "@stone-js/pipeline": "^0.8.4",
22
- "@stone-js/http-core": "^0.8.4",
23
- "@stone-js/node-http-adapter": "^0.8.4",
24
- "@stone-js/router": "^0.8.4",
25
- "@stone-js/core": "^0.8.4"
21
+ "@stone-js/pipeline": "^0.8.6",
22
+ "@stone-js/http-core": "^0.8.6",
23
+ "@stone-js/node-http-adapter": "^0.8.6",
24
+ "@stone-js/router": "^0.8.6",
25
+ "@stone-js/core": "^0.8.6"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@babel/plugin-proposal-decorators": "^7.25.9",
29
29
  "@babel/preset-env": "^7.26.9",
30
30
  "@babel/preset-typescript": "^7.27.0",
31
- "@stone-js/cli": "^0.8.4",
31
+ "@stone-js/cli": "^0.8.6",
32
32
  "@types/node": "^24.0.7",
33
33
  "@vitest/coverage-v8": "^3.0.9",
34
34
  "vitest": "^3.0.9"
35
+ },
36
+ "overrides": {
37
+ "glob": "^13.0.0"
35
38
  }
36
39
  }
@@ -43,12 +43,19 @@ describe('WelcomeService', () => {
43
43
  service = new WelcomeService({ logger: mockedLogger })
44
44
  })
45
45
 
46
- it('should build a welcome message for the given name', () => {
46
+ it('should build a branded welcome message for the given name', () => {
47
47
  // Act
48
48
  const response = service.welcome('Stone')
49
49
 
50
50
  // Assert
51
- expect(response).toHaveProperty('message', 'Hello Stone!')
51
+ expect(response.message).toBe('Hello Stone! Welcome to Stone.js.')
52
+ expect(response.framework.name).toBe('Stone.js')
53
+ expect(response.framework).toMatchObject({
54
+ name: 'Stone.js',
55
+ tagline: 'The continuum framework',
56
+ docs: 'https://stonejs.dev',
57
+ github: 'https://github.com/stone-foundation/stone-js-framework'
58
+ })
52
59
  expect(mockedLogger.info).toHaveBeenCalledWith('Welcome Stone')
53
60
  })
54
61
  })
@@ -73,7 +80,8 @@ describe('WelcomeEventHandler', () => {
73
80
  const response = handler.welcome(event)
74
81
 
75
82
  // Assert
76
- expect(response.message).toBe('Hello World!')
83
+ expect(response.message).toBe('Hello World! Welcome to Stone.js.')
84
+ expect(response.framework.name).toBe('Stone.js')
77
85
  expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
78
86
  })
79
87
 
@@ -85,7 +93,8 @@ describe('WelcomeEventHandler', () => {
85
93
  const response = handler.welcome(event)
86
94
 
87
95
  // Assert
88
- expect(response.message).toBe('Hello World!')
96
+ expect(response.message).toBe('Hello World! Welcome to Stone.js.')
97
+ expect(response.framework.name).toBe('Stone.js')
89
98
  expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
90
99
  })
91
100
  })
@@ -1,5 +1,5 @@
1
1
  import { IncomingHttpEvent } from '@stone-js/http-core'
2
- import { WelcomeService } from '../services/welcomeService'
2
+ import { WelcomeService, WelcomeResponse } from '../services/welcomeService'
3
3
  import { defineRoute, FactoryEventHandler, FunctionalEventHandler } from '@stone-js/router'
4
4
 
5
5
  /**
@@ -12,9 +12,7 @@ export interface WelcomeEventHandlerOptions {
12
12
  /**
13
13
  * Response data
14
14
  */
15
- export interface ResponseData {
16
- message: string
17
- }
15
+ export type ResponseData = WelcomeResponse
18
16
 
19
17
  /**
20
18
  * Welcome
@@ -7,6 +7,24 @@ export interface WelcomeServiceOptions {
7
7
  logger: ILogger
8
8
  }
9
9
 
10
+ /**
11
+ * Framework information carried by the welcome payload.
12
+ */
13
+ export interface FrameworkInfo {
14
+ name: string
15
+ tagline: string
16
+ docs: string
17
+ github: string
18
+ }
19
+
20
+ /**
21
+ * The branded welcome payload returned to the client.
22
+ */
23
+ export interface WelcomeResponse {
24
+ message: string
25
+ framework: FrameworkInfo
26
+ }
27
+
10
28
  /**
11
29
  * Welcome Service Type
12
30
  */
@@ -23,9 +41,17 @@ export const WelcomeService = ({ logger }: WelcomeServiceOptions): Record<Proper
23
41
  * @param name - The name
24
42
  * @returns A welcome message
25
43
  */
26
- welcome (name: string): { message: string } {
44
+ welcome (name: string): WelcomeResponse {
27
45
  logger.info(`Welcome ${name}`)
28
- return { message: `Hello ${name}!` }
46
+ return {
47
+ message: `Hello ${name}! Welcome to Stone.js.`,
48
+ framework: {
49
+ name: 'Stone.js',
50
+ tagline: 'The continuum framework',
51
+ docs: 'https://stonejs.dev',
52
+ github: 'https://github.com/stone-foundation/stone-js-framework'
53
+ }
54
+ }
29
55
  }
30
56
  })
31
57
 
@@ -17,19 +17,22 @@
17
17
  "test:cvg": "npm run test -- --coverage"
18
18
  },
19
19
  "dependencies": {
20
- "@stone-js/pipeline": "^0.8.4",
21
- "@stone-js/http-core": "^0.8.4",
22
- "@stone-js/node-http-adapter": "^0.8.4",
23
- "@stone-js/router": "^0.8.4",
24
- "@stone-js/core": "^0.8.4"
20
+ "@stone-js/pipeline": "^0.8.6",
21
+ "@stone-js/http-core": "^0.8.6",
22
+ "@stone-js/node-http-adapter": "^0.8.6",
23
+ "@stone-js/router": "^0.8.6",
24
+ "@stone-js/core": "^0.8.6"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@babel/plugin-proposal-decorators": "^7.25.9",
28
28
  "@babel/preset-env": "^7.26.9",
29
29
  "@babel/preset-typescript": "^7.27.0",
30
- "@stone-js/cli": "^0.8.4",
30
+ "@stone-js/cli": "^0.8.6",
31
31
  "@types/node": "^24.0.7",
32
32
  "@vitest/coverage-v8": "^3.0.9",
33
33
  "vitest": "^3.0.9"
34
+ },
35
+ "overrides": {
36
+ "glob": "^13.0.0"
34
37
  }
35
38
  }
@@ -20,7 +20,14 @@ describe('WelcomeService', () => {
20
20
  const response = service.welcome('Stone')
21
21
 
22
22
  // Assert
23
- expect(response).toHaveProperty('message', 'Hello Stone!')
23
+ expect(response.message).toBe('Hello Stone! Welcome to Stone.js.')
24
+ expect(response.framework.name).toBe('Stone.js')
25
+ expect(response.framework).toMatchObject({
26
+ name: 'Stone.js',
27
+ tagline: 'The continuum framework',
28
+ docs: 'https://stonejs.dev',
29
+ github: 'https://github.com/stone-foundation/stone-js-framework'
30
+ })
24
31
  expect(mockedLogger.info).toHaveBeenCalledWith('Welcome Stone')
25
32
  })
26
33
  })
@@ -55,7 +62,8 @@ describe('WelcomeEventHandler', () => {
55
62
  const response = handler(event)
56
63
 
57
64
  // Assert
58
- expect(response.message).toBe('Hello World!')
65
+ expect(response.message).toBe('Hello World! Welcome to Stone.js.')
66
+ expect(response.framework.name).toBe('Stone.js')
59
67
  expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
60
68
  })
61
69
 
@@ -69,7 +77,8 @@ describe('WelcomeEventHandler', () => {
69
77
  const response = handler(event)
70
78
 
71
79
  // Assert
72
- expect(response.message).toBe('Hello World!')
80
+ expect(response.message).toBe('Hello World! Welcome to Stone.js.')
81
+ expect(response.framework.name).toBe('Stone.js')
73
82
  expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
74
83
  })
75
84
  })