@serve.zone/catalog 2.1.0 → 2.3.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,362 @@
1
+ import {
2
+ DeesElement,
3
+ customElement,
4
+ html,
5
+ css,
6
+ cssManager,
7
+ state,
8
+ type TemplateResult,
9
+ } from '@design.estate/dees-element';
10
+ import type { DeesAppui } from '@design.estate/dees-catalog';
11
+ import type { IRouteConfig } from './sz-route-card.js';
12
+ import './index.js';
13
+
14
+ declare global {
15
+ interface HTMLElementTagNameMap {
16
+ 'sz-demo-view-routes': SzDemoViewRoutes;
17
+ }
18
+ }
19
+
20
+ @customElement('sz-demo-view-routes')
21
+ export class SzDemoViewRoutes extends DeesElement {
22
+ private appui: DeesAppui | null = null;
23
+
24
+ @state()
25
+ private accessor currentTab: 'all' | 'https' | 'email' | 'dns' = 'all';
26
+
27
+ private demoRoutes: IRouteConfig[] = [
28
+ // 1. HTTPS with TLS termination + auto cert
29
+ {
30
+ id: 'route-1',
31
+ name: 'Web Frontend',
32
+ description: 'Main website with TLS termination and automatic certificates',
33
+ enabled: true,
34
+ priority: 10,
35
+ tags: ['web', 'https', 'production'],
36
+ match: {
37
+ ports: 443,
38
+ domains: ['serve.zone', 'www.serve.zone'],
39
+ protocol: 'http',
40
+ },
41
+ action: {
42
+ type: 'forward',
43
+ targets: [{ host: '10.0.0.10', port: 3000 }],
44
+ tls: { mode: 'terminate', certificate: 'auto' },
45
+ },
46
+ },
47
+ // 2. HTTP to HTTPS redirect
48
+ {
49
+ id: 'route-2',
50
+ name: 'HTTP Redirect',
51
+ description: 'Redirects all HTTP traffic to HTTPS',
52
+ enabled: true,
53
+ priority: 100,
54
+ tags: ['web', 'http', 'redirect'],
55
+ match: {
56
+ ports: 80,
57
+ domains: ['serve.zone', 'www.serve.zone'],
58
+ protocol: 'http',
59
+ },
60
+ action: {
61
+ type: 'socket-handler',
62
+ },
63
+ },
64
+ // 3. Email SMTP route
65
+ {
66
+ id: 'route-3',
67
+ name: 'SMTP Inbound',
68
+ description: 'Inbound email relay for serve.zone domain',
69
+ enabled: true,
70
+ tags: ['email', 'smtp', 'production'],
71
+ match: {
72
+ ports: 25,
73
+ domains: 'mail.serve.zone',
74
+ },
75
+ action: {
76
+ type: 'forward',
77
+ targets: [{ host: '10.0.1.5', port: 25 }],
78
+ tls: { mode: 'terminate', certificate: 'auto' },
79
+ },
80
+ },
81
+ // 4. API gateway with path matching, rate limiting, CORS
82
+ {
83
+ id: 'route-4',
84
+ name: 'API Gateway',
85
+ description: 'API gateway with rate limiting, CORS headers, and load balancing',
86
+ enabled: true,
87
+ priority: 20,
88
+ tags: ['web', 'api', 'https', 'production'],
89
+ match: {
90
+ ports: 443,
91
+ domains: 'api.serve.zone',
92
+ path: '/v2/*',
93
+ protocol: 'http',
94
+ },
95
+ action: {
96
+ type: 'forward',
97
+ targets: [
98
+ { host: ['10.0.0.20', '10.0.0.21', '10.0.0.22'], port: 8080 },
99
+ ],
100
+ tls: { mode: 'terminate', certificate: 'auto' },
101
+ loadBalancing: { algorithm: 'round-robin' },
102
+ },
103
+ security: {
104
+ rateLimit: { enabled: true, maxRequests: 200, window: 60 },
105
+ maxConnections: 5000,
106
+ },
107
+ headers: {
108
+ response: {
109
+ 'Access-Control-Allow-Origin': '*',
110
+ 'X-Request-Id': '{{requestId}}',
111
+ },
112
+ },
113
+ },
114
+ // 5. WebSocket route
115
+ {
116
+ id: 'route-5',
117
+ name: 'WebSocket Realtime',
118
+ description: 'Real-time WebSocket connections for live updates',
119
+ enabled: true,
120
+ tags: ['web', 'https', 'websocket'],
121
+ match: {
122
+ ports: 443,
123
+ domains: 'ws.serve.zone',
124
+ path: '/ws/*',
125
+ protocol: 'http',
126
+ },
127
+ action: {
128
+ type: 'forward',
129
+ targets: [{ host: '10.0.0.30', port: 9090 }],
130
+ tls: { mode: 'terminate', certificate: 'auto' },
131
+ websocket: { enabled: true },
132
+ },
133
+ },
134
+ // 6. Wildcard domain route
135
+ {
136
+ id: 'route-6',
137
+ name: 'Tenant Wildcard',
138
+ description: 'Multi-tenant wildcard routing for customer subdomains',
139
+ enabled: true,
140
+ priority: 50,
141
+ tags: ['web', 'https', 'multi-tenant'],
142
+ match: {
143
+ ports: 443,
144
+ domains: '*.customers.serve.zone',
145
+ protocol: 'http',
146
+ },
147
+ action: {
148
+ type: 'forward',
149
+ targets: [{ host: '10.0.0.40', port: 8080 }],
150
+ tls: { mode: 'terminate', certificate: 'auto' },
151
+ },
152
+ security: {
153
+ ipAllowList: ['10.0.0.0/8', '172.16.0.0/12'],
154
+ },
155
+ },
156
+ // 7. Load-balanced route with health check
157
+ {
158
+ id: 'route-7',
159
+ name: 'Microservices LB',
160
+ description: 'Load-balanced microservices backend with IP-hash affinity',
161
+ enabled: true,
162
+ tags: ['web', 'https', 'production'],
163
+ match: {
164
+ ports: [443, 8443],
165
+ domains: 'services.serve.zone',
166
+ protocol: 'http',
167
+ },
168
+ action: {
169
+ type: 'forward',
170
+ targets: [
171
+ { host: ['10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4'], port: 3000 },
172
+ ],
173
+ tls: { mode: 'terminate-and-reencrypt', certificate: 'auto' },
174
+ loadBalancing: { algorithm: 'ip-hash' },
175
+ },
176
+ },
177
+ // 8. DNS-over-HTTPS route
178
+ {
179
+ id: 'route-8',
180
+ name: 'DNS over HTTPS',
181
+ description: 'DNS-over-HTTPS resolver endpoint',
182
+ enabled: true,
183
+ tags: ['dns', 'https'],
184
+ match: {
185
+ ports: 443,
186
+ domains: 'dns.serve.zone',
187
+ path: '/dns-query',
188
+ protocol: 'http',
189
+ },
190
+ action: {
191
+ type: 'forward',
192
+ targets: [{ host: '10.0.3.1', port: 8053 }],
193
+ tls: { mode: 'terminate', certificate: 'auto' },
194
+ },
195
+ },
196
+ // 9. NFTables high-performance route
197
+ {
198
+ id: 'route-9',
199
+ name: 'High-Perf TCP Proxy',
200
+ description: 'NFTables-accelerated TCP proxy for game servers',
201
+ enabled: true,
202
+ tags: ['tcp', 'nftables', 'production'],
203
+ match: {
204
+ ports: [{ from: 27000, to: 27050 }],
205
+ protocol: 'tcp',
206
+ },
207
+ action: {
208
+ type: 'forward',
209
+ targets: [{ host: '10.0.4.1', port: 'preserve' }],
210
+ forwardingEngine: 'nftables',
211
+ },
212
+ },
213
+ // 10. Disabled maintenance route
214
+ {
215
+ id: 'route-10',
216
+ name: 'Legacy Admin Panel',
217
+ description: 'Deprecated admin panel — disabled for maintenance',
218
+ enabled: false,
219
+ tags: ['web', 'https', 'deprecated'],
220
+ match: {
221
+ ports: 443,
222
+ domains: 'admin-old.serve.zone',
223
+ protocol: 'http',
224
+ },
225
+ action: {
226
+ type: 'socket-handler',
227
+ },
228
+ security: {
229
+ ipBlockList: ['0.0.0.0/0'],
230
+ },
231
+ },
232
+ ];
233
+
234
+ private get filteredRoutes(): IRouteConfig[] {
235
+ if (this.currentTab === 'all') return this.demoRoutes;
236
+ if (this.currentTab === 'https') {
237
+ return this.demoRoutes.filter((r) =>
238
+ r.tags?.some((t) => ['web', 'https', 'http'].includes(t))
239
+ );
240
+ }
241
+ if (this.currentTab === 'email') {
242
+ return this.demoRoutes.filter((r) =>
243
+ r.tags?.some((t) => ['email', 'smtp'].includes(t))
244
+ );
245
+ }
246
+ if (this.currentTab === 'dns') {
247
+ return this.demoRoutes.filter((r) =>
248
+ r.tags?.some((t) => ['dns'].includes(t))
249
+ );
250
+ }
251
+ return this.demoRoutes;
252
+ }
253
+
254
+ async onActivate(context: { appui: DeesAppui; viewId: string }) {
255
+ this.appui = context.appui;
256
+
257
+ this.appui.setContentTabs([
258
+ {
259
+ key: 'All Routes',
260
+ action: () => {
261
+ this.currentTab = 'all';
262
+ this.updateSecondaryMenu();
263
+ },
264
+ },
265
+ {
266
+ key: 'HTTP/S',
267
+ action: () => {
268
+ this.currentTab = 'https';
269
+ this.updateSecondaryMenu();
270
+ },
271
+ },
272
+ {
273
+ key: 'Email',
274
+ action: () => {
275
+ this.currentTab = 'email';
276
+ this.updateSecondaryMenu();
277
+ },
278
+ },
279
+ {
280
+ key: 'DNS',
281
+ action: () => {
282
+ this.currentTab = 'dns';
283
+ this.updateSecondaryMenu();
284
+ },
285
+ },
286
+ ]);
287
+
288
+ this.updateSecondaryMenu();
289
+ }
290
+
291
+ private updateSecondaryMenu() {
292
+ if (!this.appui) return;
293
+
294
+ const total = this.demoRoutes.length;
295
+ const active = this.demoRoutes.filter((r) => r.enabled !== false).length;
296
+ const forwardCount = this.demoRoutes.filter((r) => r.action.type === 'forward').length;
297
+
298
+ this.appui.setSecondaryMenu({
299
+ heading: 'Routes',
300
+ groups: [
301
+ {
302
+ name: 'Actions',
303
+ items: [
304
+ {
305
+ type: 'action',
306
+ key: 'Refresh',
307
+ iconName: 'lucide:RefreshCw',
308
+ action: () => {
309
+ console.log('Refresh routes');
310
+ },
311
+ },
312
+ {
313
+ type: 'action',
314
+ key: 'Add Route',
315
+ iconName: 'lucide:Plus',
316
+ action: () => {
317
+ console.log('Add route');
318
+ },
319
+ },
320
+ ],
321
+ },
322
+ {
323
+ name: 'Statistics',
324
+ items: [
325
+ { type: 'header' as const, label: `${total} Total Routes` },
326
+ { type: 'header' as const, label: `${active} Active` },
327
+ { type: 'header' as const, label: `${forwardCount} Forward` },
328
+ { type: 'header' as const, label: `${total - forwardCount} Socket Handler` },
329
+ ],
330
+ },
331
+ ],
332
+ });
333
+ }
334
+
335
+ onDeactivate() {
336
+ // Cleanup if needed
337
+ }
338
+
339
+ public static styles = [
340
+ cssManager.defaultStyles,
341
+ css`
342
+ :host {
343
+ display: block;
344
+ padding: 24px;
345
+ height: 100%;
346
+ overflow-y: auto;
347
+ box-sizing: border-box;
348
+ }
349
+ `,
350
+ ];
351
+
352
+ public render(): TemplateResult {
353
+ return html`
354
+ <sz-route-list-view
355
+ .routes=${this.filteredRoutes}
356
+ @route-click=${(e: CustomEvent<IRouteConfig>) => {
357
+ console.log('Route clicked:', e.detail.name);
358
+ }}
359
+ ></sz-route-list-view>
360
+ `;
361
+ }
362
+ }