@stacksjs/ts-cloud 0.5.26 → 0.5.28

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 (79) hide show
  1. package/dist/bin/cli.js +1223 -7366
  2. package/dist/deploy/dashboard-data-server.d.ts +27 -5
  3. package/dist/deploy/dashboard-database.d.ts +38 -0
  4. package/dist/deploy/dashboard-database.test.d.ts +1 -0
  5. package/dist/deploy/dashboard-operations.d.ts +48 -0
  6. package/dist/deploy/dashboard-operations.test.d.ts +1 -0
  7. package/dist/deploy/index.d.ts +1 -0
  8. package/dist/deploy/local-dashboard-server.d.ts +31 -0
  9. package/dist/deploy/management-dashboard.d.ts +21 -1
  10. package/dist/deploy/site-config-editor.d.ts +37 -0
  11. package/dist/deploy/site-target.d.ts +3 -1
  12. package/dist/deploy/ssh-config-editor.d.ts +22 -0
  13. package/dist/deploy/ssh-config-editor.test.d.ts +1 -0
  14. package/dist/drivers/factory.d.ts +4 -0
  15. package/dist/drivers/index.d.ts +1 -0
  16. package/dist/drivers/local-box/driver.d.ts +20 -0
  17. package/dist/drivers/shared/compute-deploy.d.ts +2 -0
  18. package/dist/drivers/shared/deploy-script.d.ts +28 -12
  19. package/dist/drivers/shared/rpx-gateway.d.ts +99 -2
  20. package/dist/index.d.ts +2 -0
  21. package/dist/index.js +3381 -210
  22. package/dist/ui/index.html +83 -1
  23. package/dist/ui/server/actions.html +1193 -0
  24. package/dist/ui/server/activity.html +1132 -0
  25. package/dist/ui/server/backups.html +57 -1
  26. package/dist/ui/server/database.html +1208 -0
  27. package/dist/ui/server/deployments.html +79 -1
  28. package/dist/ui/server/diagnostics.html +1132 -0
  29. package/dist/ui/server/logs.html +1165 -0
  30. package/dist/ui/server/metrics.html +1 -1
  31. package/dist/ui/server/security.html +1132 -0
  32. package/dist/ui/server/services.html +57 -1
  33. package/dist/ui/server/sites.html +141 -1
  34. package/dist/ui/server/ssh-keys.html +58 -1
  35. package/dist/ui/server/workers.html +57 -1
  36. package/dist/ui/serverless/assets.html +1 -1
  37. package/dist/ui/serverless/cost.html +1 -1
  38. package/dist/ui/serverless/data.html +1 -1
  39. package/dist/ui/serverless/deployments.html +1 -1
  40. package/dist/ui/serverless/firewall.html +1 -1
  41. package/dist/ui/serverless/functions.html +1 -1
  42. package/dist/ui/serverless/logs.html +1165 -0
  43. package/dist/ui/serverless/metrics.html +1 -1
  44. package/dist/ui/serverless/queues.html +1 -1
  45. package/dist/ui/serverless/scheduler.html +1 -1
  46. package/dist/ui/serverless/secrets.html +1 -1
  47. package/dist/ui/serverless.html +1 -1
  48. package/dist/ui-src/package.json +5 -0
  49. package/dist/ui-src/pages/index.stx +308 -0
  50. package/dist/ui-src/pages/partials/head.stx +294 -0
  51. package/dist/ui-src/pages/partials/nav.stx +54 -0
  52. package/dist/ui-src/pages/partials/op-confirm.stx +7 -0
  53. package/dist/ui-src/pages/server/actions.stx +60 -0
  54. package/dist/ui-src/pages/server/activity.stx +55 -0
  55. package/dist/ui-src/pages/server/backups.stx +91 -0
  56. package/dist/ui-src/pages/server/database.stx +119 -0
  57. package/dist/ui-src/pages/server/deployments.stx +106 -0
  58. package/dist/ui-src/pages/server/diagnostics.stx +88 -0
  59. package/dist/ui-src/pages/server/logs.stx +84 -0
  60. package/dist/ui-src/pages/server/metrics.stx +183 -0
  61. package/dist/ui-src/pages/server/security.stx +127 -0
  62. package/dist/ui-src/pages/server/services.stx +82 -0
  63. package/dist/ui-src/pages/server/sites.stx +143 -0
  64. package/dist/ui-src/pages/server/ssh-keys.stx +93 -0
  65. package/dist/ui-src/pages/server/workers.stx +99 -0
  66. package/dist/ui-src/pages/serverless/assets.stx +66 -0
  67. package/dist/ui-src/pages/serverless/cost.stx +149 -0
  68. package/dist/ui-src/pages/serverless/data.stx +76 -0
  69. package/dist/ui-src/pages/serverless/deployments.stx +56 -0
  70. package/dist/ui-src/pages/serverless/firewall.stx +58 -0
  71. package/dist/ui-src/pages/serverless/functions.stx +118 -0
  72. package/dist/ui-src/pages/serverless/logs.stx +84 -0
  73. package/dist/ui-src/pages/serverless/metrics.stx +76 -0
  74. package/dist/ui-src/pages/serverless/queues.stx +81 -0
  75. package/dist/ui-src/pages/serverless/scheduler.stx +60 -0
  76. package/dist/ui-src/pages/serverless/secrets.stx +55 -0
  77. package/dist/ui-src/pages/serverless.stx +222 -0
  78. package/dist/ui-src/src/charts.ts +17333 -0
  79. package/package.json +3 -3
@@ -0,0 +1,222 @@
1
+ <script server>
2
+ // ts-cloud serverless (Vapor-style) dashboard. Real data is injected at build
3
+ // time via the TSCLOUD_DASHBOARD_DATA env var (run `cloud dashboard:build`);
4
+ // the sample values below render the design when nothing is injected. Each
5
+ // section drills into a dedicated page under /serverless/*.
6
+ let __d = null
7
+ try { __d = JSON.parse(process.env.TSCLOUD_DASHBOARD_DATA || '') }
8
+ catch { __d = null }
9
+
10
+ const app = __d?.app ?? {
11
+ name: 'acme', env: 'production', region: 'us-east-1', runtime: 'php-8.3 (fpm)',
12
+ url: 'https://acme.com', build: 'a4d63d2', deployedAt: '12m ago',
13
+ }
14
+ const maintenance = __d?.maintenance ?? { enabled: false }
15
+ const metrics = __d?.metrics ?? { invocations: 184320, errorRatePct: 0.12, p95Ms: 86, coldStartPct: 1.8, concurrency: 42, estCostUsd: 7.4 }
16
+ const functions = __d?.functions ?? [
17
+ { key: 'http', name: 'acme-production-http', memory: 1024, timeout: 28, runtime: 'provided.al2023', invocations: 171200, errors: 21, p95: 86, status: 'active' },
18
+ { key: 'queue', name: 'acme-production-queue', memory: 1024, timeout: 120, runtime: 'provided.al2023', invocations: 12840, errors: 3, p95: 240, status: 'active' },
19
+ { key: 'cli', name: 'acme-production-cli', memory: 1024, timeout: 900, runtime: 'provided.al2023', invocations: 1440, errors: 0, p95: 1100, status: 'active' },
20
+ ]
21
+ const queues = __d?.queues ?? [
22
+ { name: 'default', visible: 0, inFlight: 2, processed: 12830, dlq: 0 },
23
+ { name: 'emails', visible: 4, inFlight: 1, processed: 9210, dlq: 1 },
24
+ ]
25
+ const scheduler = __d?.scheduler ?? { enabled: true, expression: 'rate(1 minute)', lastRun: '36s ago' }
26
+ const data = [
27
+ { name: 'Aurora Serverless v2', detail: 'acme-production-db · 0.5–4 ACU', status: 'available' },
28
+ { name: 'RDS Proxy', detail: 'acme-production-proxy', status: 'available' },
29
+ { name: 'ElastiCache (redis)', detail: 'cache.t4g.micro', status: 'available' },
30
+ ]
31
+ const assets = { bucket: 'acme-production-assets', cdn: 'd2x1.cloudfront.net', assetUrl: 'https://d2x1.cloudfront.net/a4d63d2' }
32
+ const waf = { enabled: true, rules: ['rate-limit', 'common', 'sqlInjection'], blocked24h: 318 }
33
+ const deployments = [
34
+ { sha: 'a4d63d2', status: 'success', when: '12m ago', took: '41s', by: 'chris' },
35
+ { sha: '9557430', status: 'success', when: '2h ago', took: '38s', by: 'ci' },
36
+ { sha: 'c38fc09', status: 'success', when: '1d ago', took: '44s', by: 'ci' },
37
+ { sha: '5a2b284', status: 'rolled-back', when: '1d ago', took: '12s', by: 'chris' },
38
+ ]
39
+ const secrets = [
40
+ { key: 'APP_KEY', updated: '14d ago' },
41
+ { key: 'DB_PASSWORD', updated: '14d ago' },
42
+ { key: 'STRIPE_SECRET', updated: '3d ago' },
43
+ ]
44
+ function statusTone(status) {
45
+ if (status === 'active' || status === 'available' || status === 'success' || status === 'on') return 'ok'
46
+ if (status === 'failed' || status === 'stopped' || status === 'error') return 'bad'
47
+ if (status === 'rolled-back') return 'warn'
48
+ return 'warn'
49
+ }
50
+ function fmt(n) { return n >= 1000 ? `${(n / 1000).toFixed(n >= 10000 ? 0 : 1)}k` : String(n) }
51
+ </script>
52
+ <!DOCTYPE html>
53
+ <html lang="en" data-theme="dark">
54
+ <head>
55
+ @include('./partials/head', { title: 'ts-cloud — Serverless' })
56
+ </head>
57
+ <body>
58
+ @include('./partials/nav', { active: 'serverless', name: app.name, env: app.env })
59
+
60
+ <div class="wrap">
61
+ <header class="page">
62
+ <div>
63
+ <h1>Serverless Dashboard</h1>
64
+ <p>AWS Lambda · {{ app.region }} · {{ app.runtime }}</p>
65
+ <div class="server-line">
66
+ <span>URL <b><a href="{{ app.url }}" class="mono">{{ app.url }}</a></b></span>
67
+ <span>Build <b class="mono">{{ app.build }}</b></span>
68
+ <span>Deployed <b>{{ app.deployedAt }}</b></span>
69
+ </div>
70
+ </div>
71
+ <div class="cmds header-actions">
72
+ @if (maintenance.enabled)
73
+ <span class="pill warn">maintenance</span>
74
+ <span class="cmd">cloud up --env {{ app.env }}</span>
75
+ @else
76
+ <span class="ok pill">live</span>
77
+ <span class="cmd">cloud down --env {{ app.env }}</span>
78
+ @endif
79
+ <span class="accent cmd">cloud deploy:serverless --env {{ app.env }}</span>
80
+ </div>
81
+ </header>
82
+
83
+ <div class="grid cards">
84
+ <a class="panel" href="/serverless/metrics">
85
+ <h3>Invocations (24h)</h3>
86
+ <div class="stat">{{ fmt(metrics.invocations) }}</div>
87
+ <p style="color: var(--txt2); font-size: 13px; margin-top: 8px;">{{ metrics.concurrency }} concurrent now</p>
88
+ </a>
89
+ <a class="panel" href="/serverless/metrics">
90
+ <h3>Error Rate</h3>
91
+ <div class="stat">{{ metrics.errorRatePct }}%</div>
92
+ <div class="bar"><i style="width: {{ Math.min(100, metrics.errorRatePct * 10) }}%"></i></div>
93
+ </a>
94
+ <a class="panel" href="/serverless/metrics">
95
+ <h3>p95 Latency</h3>
96
+ <div class="stat">{{ metrics.p95Ms }} <small>ms</small></div>
97
+ <p style="color: var(--txt2); font-size: 13px; margin-top: 8px;">{{ metrics.coldStartPct }}% cold starts</p>
98
+ </a>
99
+ <a class="panel" href="/serverless/cost">
100
+ <h3>Est. Cost (24h)</h3>
101
+ <div class="stat">${{ metrics.estCostUsd }}</div>
102
+ <p style="color: var(--txt2); font-size: 13px; margin-top: 8px;">cost analysis →</p>
103
+ </a>
104
+ </div>
105
+
106
+ <div class="section">
107
+ <h2>Functions <a class="more" href="/serverless/functions">View all →</a></h2>
108
+ <div class="panel">
109
+ <table>
110
+ <thead>
111
+ <tr><th>Function</th><th>Name</th><th>Memory</th><th>Timeout</th><th>Invocations</th><th>Errors</th><th>p95</th><th>Status</th></tr>
112
+ </thead>
113
+ <tbody>
114
+ @foreach (functions as fn)
115
+ <tr>
116
+ <td><a href="/serverless/functions"><span class="tag">{{ fn.key }}</span></a></td>
117
+ <td class="mono">{{ fn.name }}</td>
118
+ <td>{{ fn.memory }} MB</td>
119
+ <td class="mono">{{ fn.timeout }}s</td>
120
+ <td>{{ fmt(fn.invocations) }}</td>
121
+ <td>@if (fn.errors > 0)<span class="bad pill">{{ fn.errors }}</span>@else<span style="color: var(--txt3)">0</span>@endif</td>
122
+ <td class="mono">{{ fn.p95 }}ms</td>
123
+ <td><span class="pill {{ statusTone(fn.status) }}">{{ fn.status }}</span></td>
124
+ </tr>
125
+ @endforeach
126
+ </tbody>
127
+ </table>
128
+ </div>
129
+ </div>
130
+
131
+ <div class="cols section">
132
+ <div>
133
+ <h2>Queues <a class="more" href="/serverless/queues">View all →</a></h2>
134
+ <div class="panel">
135
+ <table>
136
+ <thead>
137
+ <tr><th>Queue</th><th>Visible</th><th>In-flight</th><th>Processed</th><th>DLQ</th></tr>
138
+ </thead>
139
+ <tbody>
140
+ @foreach (queues as q)
141
+ <tr>
142
+ <td><b>{{ q.name }}</b></td>
143
+ <td>{{ q.visible }}</td>
144
+ <td>{{ q.inFlight }}</td>
145
+ <td style="color: var(--txt2)">{{ fmt(q.processed) }}</td>
146
+ <td>@if (q.dlq > 0)<span class="bad pill">{{ q.dlq }}</span>@else<span style="color: var(--txt3)">0</span>@endif</td>
147
+ </tr>
148
+ @endforeach
149
+ </tbody>
150
+ </table>
151
+ </div>
152
+ </div>
153
+ <div>
154
+ <h2>Scheduler <a class="more" href="/serverless/scheduler">Details →</a></h2>
155
+ <div class="panel">
156
+ <div class="kv"><span>state</span> @if (scheduler.enabled)<span class="ok pill">on</span>@else<span class="pill warn">off</span>@endif</div>
157
+ <div class="kv"><span>expression</span> <span class="mono">{{ scheduler.expression }}</span></div>
158
+ <div class="kv"><span>last run</span> <span style="color: var(--txt2)">{{ scheduler.lastRun }}</span></div>
159
+ </div>
160
+ <div style="height: 16px"></div>
161
+ <h2>Firewall (WAF) <a class="more" href="/serverless/firewall">Details →</a></h2>
162
+ <div class="panel">
163
+ <div class="kv"><span>state</span> @if (waf.enabled)<span class="ok pill">on</span>@else<span class="pill warn">off</span>@endif</div>
164
+ <div class="kv"><span>rules</span> <span class="mono">{{ waf.rules.join(', ') }}</span></div>
165
+ <div class="kv"><span>blocked (24h)</span> <span>{{ fmt(waf.blocked24h) }}</span></div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+
170
+ <div class="section">
171
+ <h2>Data <a class="more" href="/serverless/data">View all →</a></h2>
172
+ <div class="panel">
173
+ @foreach (data as d)
174
+ <div class="data-item">
175
+ <b>{{ d.name }}</b>
176
+ <span class="detail">{{ d.detail }}</span>
177
+ <span class="st"><span class="pill {{ statusTone(d.status) }}">{{ d.status }}</span></span>
178
+ </div>
179
+ @endforeach
180
+ </div>
181
+ </div>
182
+
183
+ <div class="cols section">
184
+ <div>
185
+ <h2>Recent Deployments <a class="more" href="/serverless/deployments">View all →</a></h2>
186
+ <div class="panel">
187
+ @foreach (deployments as d)
188
+ <div class="deploy">
189
+ <span class="pill {{ statusTone(d.status) }}">{{ d.status }}</span>
190
+ <span class="mono">{{ d.sha }}</span>
191
+ <span style="color: var(--txt2)">by {{ d.by }}</span>
192
+ <span class="when">{{ d.when }} · {{ d.took }}</span>
193
+ </div>
194
+ @endforeach
195
+ <div style="margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--panel-br);">
196
+ <span class="cmd">cloud serverless:rollback --env {{ app.env }}</span>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ <div>
201
+ <h2>Assets &amp; CDN <a class="more" href="/serverless/assets">Details →</a></h2>
202
+ <div class="panel">
203
+ <div class="kv"><span>bucket</span> <span class="mono">{{ assets.bucket }}</span></div>
204
+ <div class="kv"><span>cdn</span> <span class="mono">{{ assets.cdn }}</span></div>
205
+ <div class="kv"><span>ASSET_URL</span> <span class="mono" style="font-size: 11px">{{ assets.assetUrl }}</span></div>
206
+ </div>
207
+ <div style="height: 16px"></div>
208
+ <h2>Secrets <a class="more" href="/serverless/secrets">Manage →</a></h2>
209
+ <div class="panel">
210
+ @foreach (secrets as s)
211
+ <div class="secret">
212
+ <b class="mono">{{ s.key }}</b>
213
+ <span style="color: var(--txt3); font-size: 12px">updated {{ s.updated }}</span>
214
+ <span class="val">••••••••</span>
215
+ </div>
216
+ @endforeach
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </div>
221
+ </body>
222
+ </html>