@zintrust/core 0.1.0 → 0.1.1

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 (80) hide show
  1. package/README.md +214 -0
  2. package/package.json +4 -34
  3. package/public/index.html +535 -0
  4. package/src/builder/BundleOptimizer.d.ts.map +1 -1
  5. package/src/builder/BundleOptimizer.js +20 -26
  6. package/src/cache/Cache.d.ts.map +1 -1
  7. package/src/cache/Cache.js +4 -2
  8. package/src/cache/drivers/KVDriver.d.ts.map +1 -1
  9. package/src/cache/drivers/KVDriver.js +2 -1
  10. package/src/cache/drivers/MemoryDriver.d.ts.map +1 -1
  11. package/src/cache/drivers/MemoryDriver.js +5 -0
  12. package/src/cli/CLI.d.ts.map +1 -1
  13. package/src/cli/CLI.js +11 -14
  14. package/src/cli/ErrorHandler.d.ts.map +1 -1
  15. package/src/cli/ErrorHandler.js +2 -4
  16. package/src/cli/commands/AddCommand.d.ts +81 -0
  17. package/src/cli/commands/AddCommand.d.ts.map +1 -1
  18. package/src/cli/commands/AddCommand.js +23 -4
  19. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  20. package/src/cli/commands/ConfigCommand.js +27 -23
  21. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  22. package/src/cli/commands/D1MigrateCommand.js +3 -2
  23. package/src/cli/commands/FixCommand.d.ts.map +1 -1
  24. package/src/cli/commands/FixCommand.js +1 -0
  25. package/src/cli/commands/LogsCommand.d.ts.map +1 -1
  26. package/src/cli/commands/LogsCommand.js +3 -5
  27. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  28. package/src/cli/commands/MigrateCommand.js +3 -3
  29. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  30. package/src/cli/commands/NewCommand.js +3 -1
  31. package/src/cli/commands/QACommand.d.ts.map +1 -1
  32. package/src/cli/commands/QACommand.js +5 -6
  33. package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -1
  34. package/src/cli/scaffolding/ControllerGenerator.js +10 -9
  35. package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -1
  36. package/src/cli/scaffolding/MigrationGenerator.js +10 -9
  37. package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
  38. package/src/cli/scaffolding/ModelGenerator.js +10 -9
  39. package/src/cli/scaffolding/ProjectScaffolder.js +1 -1
  40. package/src/cli/scaffolding/ResponseFactoryGenerator.js +1 -1
  41. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  42. package/src/cli/scaffolding/RouteGenerator.js +14 -13
  43. package/src/cli/scaffolding/SeederGenerator.js +1 -1
  44. package/src/cli/scaffolding/ServiceIntegrationTestGenerator.d.ts.map +1 -1
  45. package/src/cli/scaffolding/ServiceIntegrationTestGenerator.js +6 -5
  46. package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts +1 -1
  47. package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts.map +1 -1
  48. package/src/cli/scaffolding/ServiceRequestFactoryGenerator.js +2 -2
  49. package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
  50. package/src/cli/scaffolding/ServiceScaffolder.js +11 -10
  51. package/src/cli/scaffolding/TemplateEngine.d.ts +10 -3
  52. package/src/cli/scaffolding/TemplateEngine.d.ts.map +1 -1
  53. package/src/cli/scaffolding/TemplateEngine.js +15 -285
  54. package/src/config/SecretsManager.d.ts.map +1 -1
  55. package/src/config/SecretsManager.js +11 -11
  56. package/src/functions/lambda.d.ts.map +1 -1
  57. package/src/functions/lambda.js +6 -1
  58. package/src/http/Request.d.ts +1 -1
  59. package/src/http/Request.d.ts.map +1 -1
  60. package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -1
  61. package/src/microservices/MicroserviceBootstrap.js +6 -5
  62. package/src/microservices/MicroserviceManager.d.ts.map +1 -1
  63. package/src/microservices/MicroserviceManager.js +9 -10
  64. package/src/microservices/PostgresAdapter.d.ts.map +1 -1
  65. package/src/microservices/PostgresAdapter.js +4 -3
  66. package/src/microservices/ServiceBundler.js +3 -3
  67. package/src/microservices/ServiceHealthMonitor.d.ts.map +1 -1
  68. package/src/microservices/ServiceHealthMonitor.js +6 -2
  69. package/src/performance/Benchmark.d.ts.map +1 -1
  70. package/src/performance/Benchmark.js +3 -0
  71. package/src/performance/Optimizer.d.ts.map +1 -1
  72. package/src/performance/Optimizer.js +7 -5
  73. package/src/runtime/RuntimeDetector.d.ts.map +1 -1
  74. package/src/runtime/RuntimeDetector.js +1 -0
  75. package/src/runtime/adapters/DenoAdapter.js +9 -7
  76. package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
  77. package/src/runtime/adapters/FargateAdapter.js +4 -4
  78. package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
  79. package/src/runtime/adapters/NodeServerAdapter.js +7 -7
  80. package/src/templates/project/basic/config/SecretsManager.ts.tpl +22 -14
@@ -0,0 +1,535 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>ZinTrust Documentation</title>
7
+ <link rel="icon" type="image/svg+xml" href="https://zintrust.com/zintrust.svg" />
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
+ <link
12
+ href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap"
13
+ rel="stylesheet"
14
+ />
15
+ <script>
16
+ tailwind.config = {
17
+ darkMode: 'class',
18
+ theme: {
19
+ extend: {
20
+ fontFamily: {
21
+ sans: ['Plus Jakarta Sans', 'sans-serif'],
22
+ mono: ['JetBrains Mono', 'monospace'],
23
+ },
24
+ colors: {
25
+ primary: '#0ea5e9',
26
+ secondary: '#10b981',
27
+ ink: '#0b1220',
28
+ },
29
+ keyframes: {
30
+ floaty: {
31
+ '0%, 100%': { transform: 'translateY(0px)' },
32
+ '50%': { transform: 'translateY(-10px)' },
33
+ },
34
+ shimmer: {
35
+ '0%': { backgroundPosition: '0% 50%' },
36
+ '100%': { backgroundPosition: '100% 50%' },
37
+ },
38
+ cardIn: {
39
+ '0%': { opacity: '0', transform: 'translateY(10px)' },
40
+ '100%': { opacity: '1', transform: 'translateY(0px)' },
41
+ },
42
+ },
43
+ animation: {
44
+ floaty: 'floaty 7s ease-in-out infinite',
45
+ shimmer: 'shimmer 8s ease-in-out infinite',
46
+ cardIn: 'cardIn 700ms ease-out forwards',
47
+ },
48
+ },
49
+ },
50
+ };
51
+ </script>
52
+ <style>
53
+ :root {
54
+ color-scheme: light;
55
+ }
56
+ html.dark {
57
+ color-scheme: dark;
58
+ }
59
+ .mesh {
60
+ position: fixed;
61
+ inset: 0;
62
+ z-index: -1;
63
+ background:
64
+ radial-gradient(1000px 500px at 10% 10%, rgba(14, 165, 233, 0.18), transparent 55%),
65
+ radial-gradient(900px 500px at 90% 20%, rgba(16, 185, 129, 0.16), transparent 55%),
66
+ radial-gradient(900px 600px at 70% 90%, rgba(14, 165, 233, 0.1), transparent 60%),
67
+ radial-gradient(900px 600px at 0% 90%, rgba(16, 185, 129, 0.1), transparent 60%);
68
+ }
69
+ .glass {
70
+ backdrop-filter: blur(16px);
71
+ -webkit-backdrop-filter: blur(16px);
72
+ }
73
+ .noise {
74
+ position: fixed;
75
+ inset: 0;
76
+ z-index: -1;
77
+ opacity: 0.06;
78
+ mix-blend-mode: overlay;
79
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" stitchTiles="stitch"/></filter><rect width="160" height="160" filter="url(%23n)" opacity="0.5"/></svg>');
80
+ }
81
+ .lang-card {
82
+ transform-style: preserve-3d;
83
+ }
84
+ .lang-card:hover .lang-card-inner {
85
+ transform: translateY(-6px) rotateX(2deg) rotateY(-2deg);
86
+ }
87
+ .lang-card-inner {
88
+ transition:
89
+ transform 450ms cubic-bezier(0.2, 0.8, 0.2, 1),
90
+ box-shadow 450ms;
91
+ }
92
+ .glow-primary:hover {
93
+ box-shadow: 0 0 42px rgba(14, 165, 233, 0.22);
94
+ }
95
+ .glow-secondary:hover {
96
+ box-shadow: 0 0 42px rgba(16, 185, 129, 0.2);
97
+ }
98
+ .caret {
99
+ display: inline-block;
100
+ width: 8px;
101
+ height: 1.1em;
102
+ transform: translateY(2px);
103
+ background: rgba(148, 163, 184, 0.9);
104
+ animation: blink 1s steps(1) infinite;
105
+ }
106
+ @keyframes blink {
107
+ 50% {
108
+ opacity: 0;
109
+ }
110
+ }
111
+ .tab-active {
112
+ background: rgba(255, 255, 255, 0.08);
113
+ border-color: rgba(255, 255, 255, 0.14);
114
+ }
115
+ html:not(.dark) .tab-active {
116
+ background: rgba(2, 6, 23, 0.06);
117
+ border-color: rgba(2, 6, 23, 0.12);
118
+ }
119
+ </style>
120
+ </head>
121
+ <body class="antialiased font-sans">
122
+ <div class="mesh"></div>
123
+ <div class="noise"></div>
124
+
125
+ <main
126
+ class="min-h-screen px-6 py-10 md:py-14 bg-white text-slate-900 dark:bg-ink dark:text-slate-100"
127
+ >
128
+ <div class="mx-auto max-w-6xl">
129
+ <header class="flex items-center justify-between gap-4">
130
+ <a href="https://zintrust.com/doc" class="flex items-center gap-3">
131
+ <span
132
+ class="inline-flex h-10 w-10 items-center justify-center rounded-2xl border border-black/10 bg-black/5 dark:border-white/10 dark:bg-white/5"
133
+ >
134
+ <img src="https://zintrust.com/zintrust.svg" alt="ZinTrust Logo" class="h-6 w-6" />
135
+ </span>
136
+ <div>
137
+ <div class="text-sm font-semibold">ZinTrust</div>
138
+ <div class="text-xs text-slate-500 dark:text-slate-400">Documentation</div>
139
+ </div>
140
+ </a>
141
+
142
+ <div class="flex items-center gap-3">
143
+ <a
144
+ href="https://github.com/ZinTrust/ZinTrust"
145
+ class="text-sm font-semibold text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white"
146
+ target="_blank"
147
+ >
148
+ GitHub
149
+ </a>
150
+ <button
151
+ id="themeBtn"
152
+ class="inline-flex items-center gap-2 rounded-2xl border border-black/10 bg-black/5 px-4 py-2 text-sm font-semibold text-slate-700 hover:bg-black/10 dark:border-white/10 dark:bg-white/5 dark:text-slate-200 dark:hover:bg-white/10"
153
+ type="button"
154
+ >
155
+ <span id="themeIcon">☾</span>
156
+ <span class="hidden sm:inline">Theme</span>
157
+ </button>
158
+ </div>
159
+ </header>
160
+
161
+ <section class="mt-12 grid grid-cols-1 gap-10 lg:grid-cols-2 lg:items-center">
162
+ <div>
163
+ <div
164
+ class="inline-flex items-center gap-2 rounded-full border border-black/10 bg-black/5 px-4 py-2 text-xs font-bold tracking-widest text-slate-600 dark:border-white/10 dark:bg-white/5 dark:text-slate-300"
165
+ >
166
+ <span class="h-2 w-2 rounded-full bg-secondary animate-floaty"></span>
167
+ ZERO-DEPENDENCY • TYPESAFE • PRODUCTION-READY
168
+ </div>
169
+
170
+ <h1 class="mt-6 text-5xl md:text-6xl font-extrabold tracking-tight">
171
+ Build fast backends with
172
+ <span
173
+ class="bg-clip-text text-transparent bg-[linear-gradient(90deg,#10b981,#0ea5e9,#10b981)] bg-size-[200%_200%] animate-shimmer"
174
+ >ZinTrust</span
175
+ >
176
+ </h1>
177
+
178
+ <p class="mt-5 text-lg leading-relaxed text-slate-600 dark:text-slate-300">
179
+ A zero-dependency TypeScript framework built for high-performance APIs, clean
180
+ architecture, and microservices. Read the docs and ship.
181
+ </p>
182
+
183
+ <div class="mt-8 grid grid-cols-1 sm:grid-cols-3 gap-4">
184
+ <div
185
+ class="rounded-2xl border border-black/10 bg-black/5 p-4 dark:border-white/10 dark:bg-white/5"
186
+ >
187
+ <div class="text-xs font-bold text-slate-500 dark:text-slate-400">Runtime</div>
188
+ <div class="mt-1 font-semibold">Node http</div>
189
+ </div>
190
+ <div
191
+ class="rounded-2xl border border-black/10 bg-black/5 p-4 dark:border-white/10 dark:bg-white/5"
192
+ >
193
+ <div class="text-xs font-bold text-slate-500 dark:text-slate-400">Core</div>
194
+ <div class="mt-1 font-semibold">Zero deps</div>
195
+ </div>
196
+ <div
197
+ class="rounded-2xl border border-black/10 bg-black/5 p-4 dark:border-white/10 dark:bg-white/5"
198
+ >
199
+ <div class="text-xs font-bold text-slate-500 dark:text-slate-400">DX</div>
200
+ <div class="mt-1 font-semibold">ZinTrust CLI</div>
201
+ </div>
202
+ </div>
203
+
204
+ <div class="mt-10 flex flex-wrap gap-4">
205
+ <a
206
+ href="https://zintrust.com/doc/getting-started"
207
+ class="px-8 py-4 rounded-2xl bg-primary text-white font-bold text-lg hover:bg-primary/90 transition-all shadow-lg shadow-primary/20"
208
+ >
209
+ Start Reading
210
+ </a>
211
+ <a
212
+ href="https://github.com/ZinTrust/ZinTrust"
213
+ class="px-8 py-4 rounded-2xl border border-black/10 bg-black/5 dark:border-white/10 dark:bg-white/5 font-bold text-lg hover:bg-black/10 dark:hover:bg-white/10 transition-all"
214
+ target="_blank"
215
+ >
216
+ GitHub
217
+ </a>
218
+ </div>
219
+
220
+ <div class="mt-12">
221
+ <a href="https://zintrust.com/doc/getting-started" class="lang-card group block">
222
+ <div
223
+ class="lang-card-inner glow-primary rounded-3xl border border-black/10 bg-white/60 p-8 shadow-sm dark:border-white/10 dark:bg-white/5 glass"
224
+ >
225
+ <div class="flex items-center justify-between">
226
+ <div>
227
+ <div
228
+ class="text-xs font-bold tracking-widest text-slate-500 dark:text-slate-400"
229
+ >
230
+ DOCUMENTATION
231
+ </div>
232
+ <div class="mt-2 text-3xl font-bold">Start Reading</div>
233
+ <div class="mt-2 text-base text-slate-600 dark:text-slate-300">
234
+ Explore the zero-dependency TypeScript framework.
235
+ </div>
236
+ </div>
237
+ <div
238
+ class="h-16 w-16 rounded-2xl border border-primary/25 bg-primary/10 flex items-center justify-center text-primary"
239
+ >
240
+ <img
241
+ src="https://zintrust.com/zintrust.svg"
242
+ alt="ZinTrust Logo"
243
+ class="h-10 w-10"
244
+ />
245
+ </div>
246
+ </div>
247
+ <div class="mt-8 flex items-center gap-2 text-primary text-lg font-bold">
248
+ Open Documentation
249
+ <span class="transition-transform group-hover:translate-x-2">→</span>
250
+ </div>
251
+ </div>
252
+ </a>
253
+ </div>
254
+ </div>
255
+
256
+ <div class="relative">
257
+ <div
258
+ class="rounded-3xl border border-black/10 bg-white/60 shadow-sm dark:border-white/10 dark:bg-white/5 glass overflow-hidden"
259
+ >
260
+ <div
261
+ class="flex items-center justify-between px-5 py-4 border-b border-black/10 dark:border-white/10"
262
+ >
263
+ <div class="flex items-center gap-2">
264
+ <span class="h-3 w-3 rounded-full bg-red-500/60"></span>
265
+ <span class="h-3 w-3 rounded-full bg-amber-500/60"></span>
266
+ <span class="h-3 w-3 rounded-full bg-emerald-500/60"></span>
267
+ </div>
268
+ <div
269
+ class="text-[10px] font-mono font-bold tracking-widest text-slate-500 dark:text-slate-400"
270
+ id="terminalTitle"
271
+ >
272
+ TERMINAL — QUICKSTART
273
+ </div>
274
+ <button
275
+ id="copyBtn"
276
+ type="button"
277
+ class="rounded-xl border border-black/10 bg-black/5 px-3 py-1.5 text-xs font-bold text-slate-600 hover:bg-black/10 dark:border-white/10 dark:bg-white/5 dark:text-slate-300 dark:hover:bg-white/10"
278
+ >
279
+ Copy
280
+ </button>
281
+ </div>
282
+
283
+ <div class="px-5 pt-4 pb-2 flex gap-2">
284
+ <button
285
+ class="tab px-3 py-1.5 rounded-xl border border-black/10 bg-black/5 text-xs font-bold text-slate-700 dark:border-white/10 dark:bg-white/5 dark:text-slate-200"
286
+ data-script="quickstart"
287
+ type="button"
288
+ >
289
+ Setup
290
+ </button>
291
+ <button
292
+ class="tab px-3 py-1.5 rounded-xl border border-black/10 bg-black/5 text-xs font-bold text-slate-700 dark:border-white/10 dark:bg-white/5 dark:text-slate-200"
293
+ data-script="deploy"
294
+ type="button"
295
+ >
296
+ Deploy (Docker)
297
+ </button>
298
+ </div>
299
+
300
+ <div class="p-5 font-mono text-sm leading-relaxed">
301
+ <div class="text-slate-500 dark:text-slate-400">
302
+ $ <span id="typed"></span><span class="caret"></span>
303
+ </div>
304
+ <div class="mt-4 text-xs text-slate-500 dark:text-slate-400" id="hint"></div>
305
+ </div>
306
+ </div>
307
+
308
+ <div class="mt-6 grid grid-cols-1 sm:grid-cols-2 gap-4">
309
+ <div
310
+ class="rounded-2xl border border-black/10 bg-black/5 p-4 dark:border-white/10 dark:bg-white/5"
311
+ >
312
+ <div class="text-xs font-bold text-slate-500 dark:text-slate-400">Health</div>
313
+ <div class="mt-2 font-mono text-sm text-slate-700 dark:text-slate-200">
314
+ GET /health
315
+ </div>
316
+ </div>
317
+ <div
318
+ class="rounded-2xl border border-black/10 bg-black/5 p-4 dark:border-white/10 dark:bg-white/5"
319
+ >
320
+ <div class="text-xs font-bold text-slate-500 dark:text-slate-400">Debug</div>
321
+ <div class="mt-2 font-mono text-sm text-slate-700 dark:text-slate-200">
322
+ zin debug
323
+ </div>
324
+ </div>
325
+ </div>
326
+ </div>
327
+ </section>
328
+
329
+ <footer
330
+ class="mt-14 flex flex-col md:flex-row items-center justify-between gap-4 border-t border-black/10 pt-8 text-sm text-slate-500 dark:border-white/10 dark:text-slate-400"
331
+ >
332
+ <div>© <span id="year"></span> Zintrust Framework. All rights reserved.</div>
333
+ <div class="flex flex-wrap justify-center gap-x-5 gap-y-2 font-semibold">
334
+ <a
335
+ class="hover:text-slate-900 dark:hover:text-white"
336
+ href="https://zintrust.com/doc/getting-started"
337
+ >Docs</a
338
+ >
339
+ <a
340
+ class="hover:text-slate-900 dark:hover:text-white"
341
+ href="https://github.com/ZinTrust/ZinTrust"
342
+ target="_blank"
343
+ >GitHub</a
344
+ >
345
+ <a
346
+ class="hover:text-slate-900 dark:hover:text-white"
347
+ href="https://x.com/zintrust"
348
+ target="_blank"
349
+ >X</a
350
+ >
351
+ <a
352
+ class="hover:text-slate-900 dark:hover:text-white"
353
+ href="https://discord.gg/zintrust"
354
+ target="_blank"
355
+ >Discord</a
356
+ >
357
+ <a
358
+ class="hover:text-slate-900 dark:hover:text-white"
359
+ href="https://slack.zintrust.com"
360
+ target="_blank"
361
+ >Slack</a
362
+ >
363
+ <a
364
+ class="hover:text-slate-900 dark:hover:text-white"
365
+ href="https://linkedin.com/company/zintrust"
366
+ target="_blank"
367
+ >LinkedIn</a
368
+ >
369
+ </div>
370
+ <div class="mt-8 pt-8 border-t border-slate-200 dark:border-slate-800 text-center">
371
+ <p class="text-sm text-slate-500 dark:text-slate-400">
372
+ &copy; 2025 Zintrust Framework. All rights reserved.
373
+ </p>
374
+ </div>
375
+ </footer>
376
+ </div>
377
+ </main>
378
+
379
+ <script>
380
+ const STORAGE_KEY = 'ZinTrust-docs-theme';
381
+ const themeBtn = document.getElementById('themeBtn');
382
+ const themeIcon = document.getElementById('themeIcon');
383
+ const htmlEl = document.documentElement;
384
+
385
+ function applyTheme(theme) {
386
+ const useDark = theme === 'dark';
387
+ htmlEl.classList.toggle('dark', useDark);
388
+ themeIcon.textContent = useDark ? '☀' : '☾';
389
+ }
390
+
391
+ function getPreferredTheme() {
392
+ const saved = localStorage.getItem(STORAGE_KEY);
393
+ if (saved === 'dark' || saved === 'light') return saved;
394
+ return globalThis.matchMedia &&
395
+ globalThis.matchMedia('(prefers-color-scheme: dark)').matches
396
+ ? 'dark'
397
+ : 'light';
398
+ }
399
+
400
+ function toggleTheme() {
401
+ const next = htmlEl.classList.contains('dark') ? 'light' : 'dark';
402
+ localStorage.setItem(STORAGE_KEY, next);
403
+ applyTheme(next);
404
+ }
405
+
406
+ applyTheme(getPreferredTheme());
407
+ themeBtn.addEventListener('click', toggleTheme);
408
+
409
+ document.getElementById('year').textContent = String(new Date().getFullYear());
410
+
411
+ const scripts = {
412
+ quickstart: {
413
+ title: 'TERMINAL — QUICKSTART',
414
+ hint: 'Tip: run the health check to verify your service is up.',
415
+ lines: [
416
+ 'npm install',
417
+ 'npm run build',
418
+ 'npm link',
419
+ 'zin --version',
420
+ 'zin new my-api',
421
+ 'cd my-api',
422
+ 'npm run dev',
423
+ 'curl http://localhost:3000/health',
424
+ 'zin debug',
425
+ ],
426
+ },
427
+ deploy: {
428
+ title: 'TERMINAL — DEPLOY',
429
+ hint: 'Tip: bake an image, run it, then hit /health for confidence.',
430
+ lines: [
431
+ 'docker build -t my-api:latest .',
432
+ 'docker run --rm -p 3000:3000 my-api:latest',
433
+ 'curl http://localhost:3000/health',
434
+ ],
435
+ },
436
+ };
437
+
438
+ const typedEl = document.getElementById('typed');
439
+ const hintEl = document.getElementById('hint');
440
+ const terminalTitleEl = document.getElementById('terminalTitle');
441
+ const tabs = Array.from(document.querySelectorAll('.tab'));
442
+ const copyBtn = document.getElementById('copyBtn');
443
+
444
+ let activeKey = 'quickstart';
445
+ let lineIndex = 0;
446
+ let charIndex = 0;
447
+ let isDeleting = false;
448
+ let timerId = null;
449
+
450
+ function stopTyping() {
451
+ if (timerId !== null) {
452
+ globalThis.clearTimeout(timerId);
453
+ timerId = null;
454
+ }
455
+ }
456
+
457
+ async function copyText(text) {
458
+ if (navigator.clipboard && globalThis.isSecureContext === true) {
459
+ await navigator.clipboard.writeText(text);
460
+ return;
461
+ }
462
+
463
+ const textarea = document.createElement('textarea');
464
+ textarea.value = text;
465
+ textarea.setAttribute('readonly', '');
466
+ textarea.style.position = 'fixed';
467
+ textarea.style.left = '-9999px';
468
+ textarea.style.top = '0';
469
+ document.body.appendChild(textarea);
470
+ textarea.select();
471
+ const ok = document.execCommand('copy');
472
+ textarea.remove();
473
+ if (!ok) throw new Error('copy failed');
474
+ }
475
+
476
+ function setActiveTab(key) {
477
+ stopTyping();
478
+ activeKey = key;
479
+ lineIndex = 0;
480
+ charIndex = 0;
481
+ isDeleting = false;
482
+ typedEl.textContent = '';
483
+ terminalTitleEl.textContent = scripts[key].title;
484
+ hintEl.textContent = scripts[key].hint;
485
+ tabs.forEach((t) => t.classList.toggle('tab-active', t.dataset.script === key));
486
+
487
+ step();
488
+ }
489
+
490
+ function step() {
491
+ const { lines } = scripts[activeKey];
492
+ const full = lines[lineIndex % lines.length];
493
+
494
+ const targetLen = isDeleting ? charIndex - 1 : charIndex + 1;
495
+ charIndex = Math.max(0, Math.min(full.length, targetLen));
496
+ typedEl.textContent = full.slice(0, charIndex);
497
+
498
+ let delay = isDeleting ? 18 : 28;
499
+
500
+ if (!isDeleting && charIndex === full.length) {
501
+ delay = 850;
502
+ isDeleting = true;
503
+ } else if (isDeleting && charIndex === 0) {
504
+ isDeleting = false;
505
+ lineIndex++;
506
+ delay = 260;
507
+ }
508
+
509
+ timerId = globalThis.setTimeout(step, delay);
510
+ }
511
+
512
+ tabs.forEach((t) =>
513
+ t.addEventListener('click', () => {
514
+ const key = t.dataset.script;
515
+ if (!key || !(key in scripts) || key === activeKey) return;
516
+ setActiveTab(key);
517
+ })
518
+ );
519
+
520
+ copyBtn.addEventListener('click', async () => {
521
+ const text = scripts[activeKey].lines.join('\n');
522
+ try {
523
+ await copyText(text);
524
+ copyBtn.textContent = 'Copied';
525
+ globalThis.setTimeout(() => (copyBtn.textContent = 'Copy'), 900);
526
+ } catch {
527
+ copyBtn.textContent = 'Copy failed';
528
+ globalThis.setTimeout(() => (copyBtn.textContent = 'Copy'), 1100);
529
+ }
530
+ });
531
+
532
+ setActiveTab('quickstart');
533
+ </script>
534
+ </body>
535
+ </html>
@@ -1 +1 @@
1
- {"version":3,"file":"BundleOptimizer.d.ts","sourceRoot":"","sources":["../../../src/builder/BundleOptimizer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;oBACa,mBAAmB,GAAG,gBAAgB;EA0CtD,CAAC;AAkXH;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAclD"}
1
+ {"version":3,"file":"BundleOptimizer.d.ts","sourceRoot":"","sources":["../../../src/builder/BundleOptimizer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;oBACa,mBAAmB,GAAG,gBAAgB;EA0CtD,CAAC;AAyXH;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAclD"}
@@ -61,19 +61,15 @@ async function getFilesRecursive(dir) {
61
61
  if (!fs.existsSync(dir)) {
62
62
  return [];
63
63
  }
64
- const files = [];
65
64
  const entries = await fs.promises.readdir(dir, { withFileTypes: true });
66
- for (const entry of entries) {
65
+ const nested = await Promise.all(entries.map(async (entry) => {
67
66
  const fullPath = path.join(dir, entry.name);
68
67
  if (entry.isDirectory()) {
69
- const subFiles = await getFilesRecursive(fullPath);
70
- files.push(...subFiles);
68
+ return getFilesRecursive(fullPath);
71
69
  }
72
- else {
73
- files.push(fullPath);
74
- }
75
- }
76
- return files;
70
+ return [fullPath];
71
+ }));
72
+ return nested.flat();
77
73
  }
78
74
  /**
79
75
  * Generate optimization recommendations
@@ -158,9 +154,9 @@ async function analyze(distDir, options) {
158
154
  */
159
155
  async function removeUnusedAdapters(distDir, options, ...adapters) {
160
156
  const adapterDir = path.join(distDir, 'orm', 'adapters');
161
- for (const adapter of adapters) {
157
+ await Promise.all(adapters.map(async (adapter) => {
162
158
  const files = [`${adapter}Adapter.js`, `${adapter}Adapter.d.ts`];
163
- for (const file of files) {
159
+ await Promise.all(files.map(async (file) => {
164
160
  const filePath = path.join(adapterDir, file);
165
161
  if (fs.existsSync(filePath)) {
166
162
  await fs.promises.unlink(filePath);
@@ -168,8 +164,8 @@ async function removeUnusedAdapters(distDir, options, ...adapters) {
168
164
  Logger.info(` ✓ Removed ${adapter} adapter`);
169
165
  }
170
166
  }
171
- }
172
- }
167
+ }));
168
+ }));
173
169
  }
174
170
  /**
175
171
  * Remove dev dependencies from node_modules
@@ -189,7 +185,7 @@ async function removeDevDependencies(distDir, options) {
189
185
  ];
190
186
  if (!fs.existsSync(nmDir))
191
187
  return;
192
- for (const dep of devDeps) {
188
+ await Promise.all(devDeps.map(async (dep) => {
193
189
  const depPath = path.join(nmDir, dep);
194
190
  if (fs.existsSync(depPath)) {
195
191
  await fs.promises.rm(depPath, { recursive: true });
@@ -197,7 +193,7 @@ async function removeDevDependencies(distDir, options) {
197
193
  Logger.info(` ✓ Removed ${dep}`);
198
194
  }
199
195
  }
200
- }
196
+ }));
201
197
  }
202
198
  /**
203
199
  * Minify JavaScript files
@@ -207,6 +203,7 @@ async function minifyJavaScript(_aggressive = false) {
207
203
  // In production, would use esbuild or terser
208
204
  // This is a placeholder showing the pattern
209
205
  Logger.info(' ✓ JavaScript minified');
206
+ return Promise.resolve();
210
207
  }
211
208
  /**
212
209
  * Remove a specific module
@@ -240,7 +237,7 @@ async function removeUnusedMiddleware(distDir, options) {
240
237
  const optionalMiddleware = ['logging.js', 'profiling.js', 'rateLimit.js'];
241
238
  if (!fs.existsSync(middlewareDir))
242
239
  return;
243
- for (const file of optionalMiddleware) {
240
+ await Promise.all(optionalMiddleware.map(async (file) => {
244
241
  const filePath = path.join(middlewareDir, file);
245
242
  if (fs.existsSync(filePath)) {
246
243
  await fs.promises.unlink(filePath);
@@ -248,7 +245,7 @@ async function removeUnusedMiddleware(distDir, options) {
248
245
  Logger.info(` ✓ Removed middleware: ${file}`);
249
246
  }
250
247
  }
251
- }
248
+ }));
252
249
  }
253
250
  /**
254
251
  * Inline small files to reduce overhead
@@ -262,16 +259,13 @@ function inlineSmallFiles(threshold) {
262
259
  */
263
260
  async function removeFiles(distDir, options, patterns) {
264
261
  const files = await getFilesRecursive(distDir);
265
- for (const file of files) {
266
- for (const pattern of patterns) {
267
- if (file.includes(pattern)) {
268
- await fs.promises.unlink(file);
269
- if (options.verbose === true) {
270
- Logger.info(` ✓ Removed ${path.relative(distDir, file)}`);
271
- }
272
- }
262
+ const filesToRemove = files.filter((file) => patterns.some((pattern) => file.includes(pattern)));
263
+ await Promise.all(filesToRemove.map(async (file) => {
264
+ await fs.promises.unlink(file);
265
+ if (options.verbose === true) {
266
+ Logger.info(` ✓ Removed ${path.relative(distDir, file)}`);
273
267
  }
274
- }
268
+ }));
275
269
  }
276
270
  /**
277
271
  * Optimize for AWS Lambda (2-3 MB limit for direct upload)
@@ -1 +1 @@
1
- {"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA6FjD,eAAO,MAAM,KAAK;UAxCC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAOlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAO3B,WAAW;EAY/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UApDC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAOlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAO3B,WAAW;EAiBP,CAAC"}
1
+ {"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA+FjD,eAAO,MAAM,KAAK;UA1CC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;EAY/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UAtDC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;EAiBP,CAAC"}
@@ -42,7 +42,8 @@ function getDriverInstance() {
42
42
  * Get an item from the cache
43
43
  */
44
44
  const get = async (key) => {
45
- return getDriverInstance().get(key);
45
+ const value = await getDriverInstance().get(key);
46
+ return value;
46
47
  };
47
48
  /**
48
49
  * Store an item in the cache
@@ -66,7 +67,8 @@ const clear = async () => {
66
67
  * Check if an item exists in the cache
67
68
  */
68
69
  const has = async (key) => {
69
- return getDriverInstance().has(key);
70
+ const exists = await getDriverInstance().has(key);
71
+ return exists;
70
72
  };
71
73
  /**
72
74
  * Get the underlying driver instance