quicklify 0.1.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.
Files changed (63) hide show
  1. package/.claude/settings.local.json +25 -0
  2. package/.github/workflows/ci.yml +42 -0
  3. package/LICENSE +21 -0
  4. package/README.md +305 -0
  5. package/dist/commands/init.d.ts +2 -0
  6. package/dist/commands/init.d.ts.map +1 -0
  7. package/dist/commands/init.js +82 -0
  8. package/dist/commands/init.js.map +1 -0
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +14 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/providers/base.d.ts +11 -0
  14. package/dist/providers/base.d.ts.map +1 -0
  15. package/dist/providers/base.js +2 -0
  16. package/dist/providers/base.js.map +1 -0
  17. package/dist/providers/digitalocean.d.ts +14 -0
  18. package/dist/providers/digitalocean.d.ts.map +1 -0
  19. package/dist/providers/digitalocean.js +29 -0
  20. package/dist/providers/digitalocean.js.map +1 -0
  21. package/dist/providers/hetzner.d.ts +15 -0
  22. package/dist/providers/hetzner.d.ts.map +1 -0
  23. package/dist/providers/hetzner.js +73 -0
  24. package/dist/providers/hetzner.js.map +1 -0
  25. package/dist/types/index.d.ts +33 -0
  26. package/dist/types/index.d.ts.map +1 -0
  27. package/dist/types/index.js +2 -0
  28. package/dist/types/index.js.map +1 -0
  29. package/dist/utils/cloudInit.d.ts +2 -0
  30. package/dist/utils/cloudInit.d.ts.map +1 -0
  31. package/dist/utils/cloudInit.js +30 -0
  32. package/dist/utils/cloudInit.js.map +1 -0
  33. package/dist/utils/logger.d.ts +11 -0
  34. package/dist/utils/logger.d.ts.map +1 -0
  35. package/dist/utils/logger.js +31 -0
  36. package/dist/utils/logger.js.map +1 -0
  37. package/dist/utils/prompts.d.ts +5 -0
  38. package/dist/utils/prompts.d.ts.map +1 -0
  39. package/dist/utils/prompts.js +77 -0
  40. package/dist/utils/prompts.js.map +1 -0
  41. package/jest.config.cjs +30 -0
  42. package/package.json +41 -0
  43. package/src/commands/init.ts +101 -0
  44. package/src/index.ts +18 -0
  45. package/src/providers/base.ts +11 -0
  46. package/src/providers/digitalocean.ts +37 -0
  47. package/src/providers/hetzner.ts +85 -0
  48. package/src/types/index.ts +36 -0
  49. package/src/utils/cloudInit.ts +29 -0
  50. package/src/utils/logger.ts +37 -0
  51. package/src/utils/prompts.ts +84 -0
  52. package/tests/__mocks__/axios.ts +14 -0
  53. package/tests/__mocks__/chalk.ts +15 -0
  54. package/tests/__mocks__/inquirer.ts +5 -0
  55. package/tests/__mocks__/ora.ts +16 -0
  56. package/tests/e2e/init.test.ts +190 -0
  57. package/tests/integration/hetzner.test.ts +274 -0
  58. package/tests/unit/cloudInit.test.ts +53 -0
  59. package/tests/unit/logger.test.ts +76 -0
  60. package/tests/unit/prompts.test.ts +220 -0
  61. package/tests/unit/validators.test.ts +63 -0
  62. package/tsconfig.json +19 -0
  63. package/tsconfig.test.json +10 -0
@@ -0,0 +1,25 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm install:*)",
5
+ "Bash(npx tsc:*)",
6
+ "Bash(git init:*)",
7
+ "Bash(git add:*)",
8
+ "Bash(npm run build:*)",
9
+ "Bash(npm run dev:*)",
10
+ "Bash(npx jest:*)",
11
+ "Bash(gh repo view:*)",
12
+ "Bash(git branch:*)",
13
+ "Bash(git remote add:*)",
14
+ "Bash(git fetch:*)",
15
+ "Bash(git pull:*)",
16
+ "Bash(git stash:*)",
17
+ "Bash(git reset:*)",
18
+ "Bash(git checkout:*)",
19
+ "Bash(git rm:*)",
20
+ "Bash(git commit -m \"$\\(cat <<''EOF''\nInitial commit: Quicklify v0.1.0\n\n- CLI tool for automated Coolify deployment\n- Hetzner Cloud provider support\n- 79 tests with 100% coverage\n- Multi-platform CI/CD \\(Ubuntu, macOS, Windows\\)\n- TypeScript + Commander.js + Inquirer.js\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
21
+ "Bash(git push:*)",
22
+ "Bash(git remote set-url:*)"
23
+ ]
24
+ }
25
+ }
@@ -0,0 +1,42 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ name: Test (${{ matrix.os }}, Node ${{ matrix.node-version }})
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-latest, macos-latest, windows-latest]
17
+ node-version: [18, 20, 22]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Setup Node.js ${{ matrix.node-version }}
23
+ uses: actions/setup-node@v4
24
+ with:
25
+ node-version: ${{ matrix.node-version }}
26
+ cache: npm
27
+
28
+ - name: Install dependencies
29
+ run: npm ci
30
+
31
+ - name: TypeScript type check
32
+ run: npx tsc --noEmit
33
+
34
+ - name: Run tests
35
+ run: npm test
36
+
37
+ - name: Run tests with coverage
38
+ if: matrix.os == 'ubuntu-latest' && matrix.node-version == 22
39
+ run: npm run test:coverage
40
+
41
+ - name: Build
42
+ run: npx tsc
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 omrfc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # quicklify
2
+
3
+ ![Tests](https://github.com/omrfc/quicklify/actions/workflows/ci.yml/badge.svg)
4
+ ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)
5
+ ![npm](https://img.shields.io/npm/v/quicklify)
6
+ ![Downloads](https://img.shields.io/npm/dw/quicklify)
7
+ ![License](https://img.shields.io/badge/license-MIT-blue)
8
+
9
+ > Deploy Coolify to any cloud VPS in 60 seconds
10
+
11
+ ## 🚀 What is Quicklify?
12
+
13
+ Quicklify is a CLI tool that automates Coolify installation on cloud VPS providers. One command to deploy your self-hosted PaaS platform.
14
+
15
+ **Before Quicklify:**
16
+
17
+ ```
18
+ Create VPS manually (5 min)
19
+ SSH into server (2 min)
20
+ Install Docker (10 min)
21
+ Configure firewall (5 min)
22
+ Install Coolify (10 min)
23
+ Total: ~30 minutes + manual work
24
+ ```
25
+
26
+ **With Quicklify:**
27
+
28
+ ```bash
29
+ npx quicklify init
30
+ # Total: ~4 minutes + zero manual work ✨
31
+ ```
32
+
33
+ ## ✨ Features
34
+
35
+ - 🎯 **One Command Deploy** - VPS + Coolify in 60 seconds
36
+ - 💰 **Cost Savings** - $50-200/mo (Vercel/Netlify) → €3.85/mo
37
+ - 🔒 **Secure by Default** - Automated security setup
38
+ - 🌍 **Multi-Cloud** - Hetzner, DigitalOcean support
39
+ - 💻 **Beautiful CLI** - Interactive prompts with validation
40
+ - 🎨 **ARM64 Ready** - Support for cost-effective ARM servers
41
+ - ⚡ **Fast Setup** - Production-ready in minutes
42
+
43
+ ## 📦 Installation
44
+
45
+ ### Using npx (Recommended)
46
+
47
+ ```bash
48
+ npx quicklify init
49
+ ```
50
+
51
+ ### Global Installation
52
+
53
+ ```bash
54
+ npm install -g quicklify
55
+ quicklify init
56
+ ```
57
+
58
+ ## 🎬 Quick Start
59
+
60
+ ### Step 1: Get API Token
61
+
62
+ **Hetzner Cloud:**
63
+
64
+ 1. Visit [Hetzner Console](https://console.hetzner.cloud/)
65
+ 2. Select your project
66
+ 3. Navigate to Security → API Tokens
67
+ 4. Click "Generate API Token"
68
+ 5. Set permissions to **Read & Write**
69
+ 6. Copy the token (shown only once!)
70
+
71
+ **DigitalOcean:** (Coming Soon)
72
+
73
+ 1. Visit [DigitalOcean API](https://cloud.digitalocean.com/account/api/tokens)
74
+ 2. Generate New Token
75
+ 3. Copy token
76
+
77
+ ### Step 2: Deploy Coolify
78
+
79
+ ```bash
80
+ npx quicklify init
81
+ ```
82
+
83
+ You'll be prompted for:
84
+
85
+ - ✅ **API Token** - Paste your cloud provider token
86
+ - ✅ **Region** - Select datacenter location
87
+ - ✅ **Server Size** - Choose VPS specs (CAX11 recommended)
88
+ - ✅ **Server Name** - Name your instance
89
+
90
+ ### Step 3: Access Coolify
91
+
92
+ After ~3 minutes:
93
+
94
+ ```
95
+ ✅ Deployment Successful!
96
+ Server IP: 123.45.67.89
97
+ Access Coolify: https://123.45.67.89:8000
98
+ ```
99
+
100
+ Visit the URL, create your admin account, and start deploying!
101
+
102
+ ## 🌐 Supported Providers
103
+
104
+ | Provider | Status | Starting Price | Architecture |
105
+ |----------|--------|----------------|--------------|
106
+ | **Hetzner Cloud** | ✅ Available | €3.85/mo | ARM64 + x86 |
107
+ | **DigitalOcean** | 🚧 Coming Soon | $4/mo | x86 |
108
+ | **Vultr** | 📋 Planned | $2.50/mo | x86 |
109
+ | **Linode** | 📋 Planned | $5/mo | x86 |
110
+
111
+ ## 💡 Use Cases
112
+
113
+ **Perfect for:**
114
+
115
+ - 🚀 Side projects and MVPs
116
+ - 💼 Client deployments (freelancers/agencies)
117
+ - 🎓 Learning DevOps and self-hosting
118
+ - 💸 Cutting cloud hosting costs
119
+ - 🏢 Small team internal tools
120
+
121
+ **When to use alternatives:**
122
+
123
+ - Large enterprise? → Coolify Cloud or enterprise PaaS
124
+ - Extreme scale? → Kubernetes + managed services
125
+
126
+ ## 📊 Cost Comparison
127
+
128
+ | Solution | Monthly Cost | Setup Time | Management |
129
+ |----------|--------------|------------|------------|
130
+ | Vercel (Hobby) | $20+ | 5 min | Easy |
131
+ | Vercel (Pro) | $50+ | 5 min | Easy |
132
+ | Netlify (Pro) | $19+ | 5 min | Easy |
133
+ | **Quicklify + Hetzner** | **€3.85** | **4 min** | **Easy** |
134
+ | Manual VPS + Coolify | €3.85 | 30+ min | Hard |
135
+
136
+ **Savings: ~$180-240/year per project!** 💰
137
+
138
+ ## 🗺️ Roadmap
139
+
140
+ ### v0.1.0 (Current)
141
+
142
+ - [x] Hetzner Cloud integration
143
+ - [x] Interactive CLI
144
+ - [x] Automated Coolify installation
145
+ - [x] ARM64 support
146
+
147
+ ### v0.2.0 (Next)
148
+
149
+ - [ ] DigitalOcean support
150
+ - [ ] Domain configuration helper
151
+ - [ ] SSL certificate automation
152
+ - [ ] Health checks & monitoring
153
+
154
+ ### Future
155
+
156
+ - [ ] Backup configuration
157
+ - [ ] Multi-server management
158
+ - [ ] Web dashboard
159
+ - [ ] GitHub Actions integration
160
+
161
+ ## 🛠️ Tech Stack
162
+
163
+ - **Runtime:** Node.js 18+
164
+ - **Language:** TypeScript
165
+ - **CLI Framework:** Commander.js
166
+ - **Interactive Prompts:** Inquirer.js
167
+ - **Styling:** Chalk (colors) + Ora (spinners)
168
+ - **HTTP Client:** Axios
169
+ - **Cloud APIs:** Hetzner Cloud API v1
170
+
171
+ ## 📖 CLI Reference
172
+
173
+ ### Commands
174
+
175
+ ```bash
176
+ # Deploy new Coolify instance
177
+ quicklify init
178
+
179
+ # Show version
180
+ quicklify --version
181
+
182
+ # Show help
183
+ quicklify --help
184
+ ```
185
+
186
+ ### Interactive Prompts
187
+
188
+ 1. **API Token** - Validated before proceeding
189
+ 2. **Region Selection** - Nearest datacenter auto-highlighted
190
+ 3. **Server Size** - Recommended option marked
191
+ 4. **Server Name** - Validates format (lowercase, alphanumeric, hyphens)
192
+ 5. **Confirmation** - Review summary before deployment
193
+
194
+ ## 🧪 Testing
195
+
196
+ ### Run Tests
197
+
198
+ ```bash
199
+ # Run all tests
200
+ npm test
201
+
202
+ # Run tests in watch mode
203
+ npm run test:watch
204
+
205
+ # Run tests with coverage report
206
+ npm run test:coverage
207
+ ```
208
+
209
+ ### Test Structure
210
+
211
+ ```
212
+ tests/
213
+ ├── __mocks__/ # Mock modules (axios, inquirer, ora, chalk)
214
+ ├── unit/ # Unit tests
215
+ │ ├── cloudInit.test.ts
216
+ │ ├── logger.test.ts
217
+ │ ├── prompts.test.ts
218
+ │ └── validators.test.ts
219
+ ├── integration/ # Integration tests (provider API calls)
220
+ │ └── hetzner.test.ts
221
+ └── e2e/ # End-to-end tests (full init flow)
222
+ └── init.test.ts
223
+ ```
224
+
225
+ ### CI/CD
226
+
227
+ Tests run automatically on every push/PR via GitHub Actions across:
228
+
229
+ - **OS:** Ubuntu, macOS, Windows
230
+ - **Node.js:** 18, 20, 22
231
+
232
+ ### Coverage
233
+
234
+ Current coverage: **100%** across all files (statements, branches, functions, lines).
235
+
236
+ ## 🔧 Troubleshooting
237
+
238
+ **"Invalid API token"**
239
+
240
+ - Ensure token has Read & Write permissions
241
+ - Check for extra spaces when copying
242
+ - Regenerate token if needed
243
+
244
+ **"Server creation failed"**
245
+
246
+ - Verify cloud account has sufficient funds
247
+ - Check account limits (new accounts may have restrictions)
248
+ - Try different region or server size
249
+
250
+ **"Cannot access Coolify UI"**
251
+
252
+ - Wait 1-2 more minutes (Coolify initialization)
253
+ - Check firewall settings (should auto-configure)
254
+ - Verify server is running in cloud console
255
+
256
+ ## 🤝 Contributing
257
+
258
+ Contributions are welcome! Here's how:
259
+
260
+ 1. Fork the repository
261
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
262
+ 3. Commit changes (`git commit -m 'Add amazing feature'`)
263
+ 4. Push to branch (`git push origin feature/amazing-feature`)
264
+ 5. Open a Pull Request
265
+
266
+ **Areas for contribution:**
267
+
268
+ - New cloud provider integrations
269
+ - CLI improvements
270
+ - Documentation
271
+ - Bug fixes
272
+
273
+ ## 📄 License
274
+
275
+ MIT © 2026 Ömer FC
276
+
277
+ See [LICENSE](LICENSE) file for details.
278
+
279
+ ## 🙏 Acknowledgments
280
+
281
+ - [Coolify](https://coolify.io/) - The amazing open-source PaaS
282
+ - [Hetzner](https://www.hetzner.com/) - Affordable, reliable cloud infrastructure
283
+ - All contributors and users!
284
+
285
+ ## 💬 Support & Community
286
+
287
+ - 🐛 **Bug Reports:** [GitHub Issues](https://github.com/omrfc/quicklify/issues)
288
+ - 💡 **Feature Requests:** [GitHub Discussions](https://github.com/omrfc/quicklify/discussions)
289
+ - 🐦 **Updates:** [@omrfc](https://twitter.com/omrfc)
290
+ - 🌐 **Website:** [quicklify.omrfc.dev](https://quicklify.omrfc.dev)
291
+
292
+ ## ⭐ Show Your Support
293
+
294
+ If Quicklify helped you, please:
295
+
296
+ - ⭐ Star this repository
297
+ - 🐦 Share on Twitter
298
+ - 📝 Write a blog post
299
+ - 💬 Tell your friends!
300
+
301
+ ---
302
+
303
+ **Made with ❤️ by [@omrfc](https://github.com/omrfc)**
304
+
305
+ *Saving developers time, one deployment at a time.* ⚡
@@ -0,0 +1,2 @@
1
+ export declare function initCommand(): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,kBA+FhC"}
@@ -0,0 +1,82 @@
1
+ import { HetznerProvider } from "../providers/hetzner.js";
2
+ import { getDeploymentConfig, confirmDeployment } from "../utils/prompts.js";
3
+ import { getCoolifyCloudInit } from "../utils/cloudInit.js";
4
+ import { logger, createSpinner } from "../utils/logger.js";
5
+ export async function initCommand() {
6
+ logger.title("Quicklify - Deploy Coolify in 60 seconds");
7
+ // For MVP, we only support Hetzner
8
+ // Later: Add provider selection prompt
9
+ logger.info("Using Hetzner Cloud (more providers coming soon!)");
10
+ const provider = new HetznerProvider(""); // Token will be set from config
11
+ // Get deployment configuration
12
+ const config = await getDeploymentConfig(provider);
13
+ // Update provider with actual token
14
+ const providerWithToken = new HetznerProvider(config.apiToken);
15
+ // Confirm deployment
16
+ const confirmed = await confirmDeployment(config, providerWithToken);
17
+ if (!confirmed) {
18
+ logger.warning("Deployment cancelled");
19
+ return;
20
+ }
21
+ try {
22
+ // Validate API token
23
+ const tokenSpinner = createSpinner("Validating API token...");
24
+ tokenSpinner.start();
25
+ const isValid = await providerWithToken.validateToken(config.apiToken);
26
+ if (!isValid) {
27
+ tokenSpinner.fail("Invalid API token");
28
+ logger.error("Please check your API token and try again");
29
+ return;
30
+ }
31
+ tokenSpinner.succeed("API token validated");
32
+ // Generate cloud-init script
33
+ const cloudInit = getCoolifyCloudInit(config.serverName);
34
+ // Create server
35
+ const serverSpinner = createSpinner("Creating VPS server...");
36
+ serverSpinner.start();
37
+ const server = await providerWithToken.createServer({
38
+ name: config.serverName,
39
+ region: config.region,
40
+ size: config.serverSize,
41
+ cloudInit,
42
+ });
43
+ serverSpinner.succeed(`Server created (ID: ${server.id})`);
44
+ // Wait for server to be running
45
+ const statusSpinner = createSpinner("Waiting for server to boot...");
46
+ statusSpinner.start();
47
+ let status = await providerWithToken.getServerStatus(server.id);
48
+ let attempts = 0;
49
+ const maxAttempts = 30;
50
+ while (status !== "running" && attempts < maxAttempts) {
51
+ await new Promise((resolve) => setTimeout(resolve, 1000));
52
+ status = await providerWithToken.getServerStatus(server.id);
53
+ attempts++;
54
+ }
55
+ if (status !== "running") {
56
+ statusSpinner.fail("Server failed to start");
57
+ logger.error("Please check your cloud provider dashboard");
58
+ return;
59
+ }
60
+ statusSpinner.succeed("Server is running");
61
+ // Installing Coolify
62
+ const installSpinner = createSpinner("Installing Coolify (this takes 3-5 minutes)...");
63
+ installSpinner.start();
64
+ // Wait for Coolify installation (cloud-init runs in background)
65
+ await new Promise((resolve) => setTimeout(resolve, 180000));
66
+ installSpinner.succeed("Coolify installation completed");
67
+ // Success message
68
+ logger.title("Deployment Successful!");
69
+ console.log();
70
+ logger.success(`Server IP: ${server.ip}`);
71
+ logger.success(`Access Coolify: https://${server.ip}:8000`);
72
+ console.log();
73
+ logger.info("Default credentials will be shown on first login");
74
+ logger.info("Please wait 1-2 more minutes for Coolify to fully initialize");
75
+ console.log();
76
+ }
77
+ catch (error) {
78
+ logger.error(`Deployment failed: ${error.message}`);
79
+ process.exit(1);
80
+ }
81
+ }
82
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { initCommand } from "./commands/init.js";
4
+ const program = new Command();
5
+ program
6
+ .name("quicklify")
7
+ .description("Automate Coolify deployment on cloud providers")
8
+ .version("0.1.0");
9
+ program
10
+ .command("init")
11
+ .description("Deploy a new Coolify instance on a cloud provider")
12
+ .action(initCommand);
13
+ program.parse();
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Region, ServerSize, ServerConfig, ServerResult } from "../types/index.js";
2
+ export interface CloudProvider {
3
+ name: string;
4
+ displayName: string;
5
+ validateToken(token: string): Promise<boolean>;
6
+ getRegions(): Region[];
7
+ getServerSizes(): ServerSize[];
8
+ createServer(config: ServerConfig): Promise<ServerResult>;
9
+ getServerStatus(serverId: string): Promise<string>;
10
+ }
11
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAExF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,IAAI,MAAM,EAAE,CAAC;IACvB,cAAc,IAAI,UAAU,EAAE,CAAC;IAC/B,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import type { CloudProvider } from "./base.js";
2
+ import type { Region, ServerSize, ServerConfig, ServerResult } from "../types/index.js";
3
+ export declare class DigitalOceanProvider implements CloudProvider {
4
+ name: string;
5
+ displayName: string;
6
+ private apiToken;
7
+ constructor(apiToken: string);
8
+ validateToken(_token: string): Promise<boolean>;
9
+ getRegions(): Region[];
10
+ getServerSizes(): ServerSize[];
11
+ createServer(_config: ServerConfig): Promise<ServerResult>;
12
+ getServerStatus(_serverId: string): Promise<string>;
13
+ }
14
+ //# sourceMappingURL=digitalocean.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digitalocean.d.ts","sourceRoot":"","sources":["../../src/providers/digitalocean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAExF,qBAAa,oBAAqB,YAAW,aAAa;IACxD,IAAI,SAAkB;IACtB,WAAW,SAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAItB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrD,UAAU,IAAI,MAAM,EAAE;IAKtB,cAAc,IAAI,UAAU,EAAE;IAKxB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAK1D,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAI1D"}
@@ -0,0 +1,29 @@
1
+ export class DigitalOceanProvider {
2
+ name = "digitalocean";
3
+ displayName = "DigitalOcean";
4
+ apiToken;
5
+ constructor(apiToken) {
6
+ this.apiToken = apiToken;
7
+ }
8
+ async validateToken(_token) {
9
+ // TODO: Implement DigitalOcean API call
10
+ return false;
11
+ }
12
+ getRegions() {
13
+ // TODO: Implement DigitalOcean regions
14
+ return [];
15
+ }
16
+ getServerSizes() {
17
+ // TODO: Implement DigitalOcean server sizes
18
+ return [];
19
+ }
20
+ async createServer(_config) {
21
+ // TODO: Implement DigitalOcean API call
22
+ throw new Error("Not implemented");
23
+ }
24
+ async getServerStatus(_serverId) {
25
+ // TODO: Implement DigitalOcean API call
26
+ return "unknown";
27
+ }
28
+ }
29
+ //# sourceMappingURL=digitalocean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digitalocean.js","sourceRoot":"","sources":["../../src/providers/digitalocean.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,oBAAoB;IAC/B,IAAI,GAAG,cAAc,CAAC;IACtB,WAAW,GAAG,cAAc,CAAC;IACrB,QAAQ,CAAS;IAEzB,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,wCAAwC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU;QACR,uCAAuC;QACvC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,cAAc;QACZ,4CAA4C;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAqB;QACtC,wCAAwC;QACxC,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB;QACrC,wCAAwC;QACxC,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { CloudProvider } from "./base.js";
2
+ import type { Region, ServerSize, ServerConfig, ServerResult } from "../types/index.js";
3
+ export declare class HetznerProvider implements CloudProvider {
4
+ name: string;
5
+ displayName: string;
6
+ private apiToken;
7
+ private baseUrl;
8
+ constructor(apiToken: string);
9
+ validateToken(token: string): Promise<boolean>;
10
+ createServer(config: ServerConfig): Promise<ServerResult>;
11
+ getServerStatus(serverId: string): Promise<string>;
12
+ getRegions(): Region[];
13
+ getServerSizes(): ServerSize[];
14
+ }
15
+ //# sourceMappingURL=hetzner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hetzner.d.ts","sourceRoot":"","sources":["../../src/providers/hetzner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAExF,qBAAa,eAAgB,YAAW,aAAa;IACnD,IAAI,SAAa;IACjB,WAAW,SAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAkC;gBAErC,QAAQ,EAAE,MAAM;IAItB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW9C,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IA+BzD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWxD,UAAU,IAAI,MAAM,EAAE;IAStB,cAAc,IAAI,UAAU,EAAE;CAQ/B"}