sb-convert 1.0.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.
- package/Dockerfile +9 -0
- package/README.md +37 -0
- package/bin/sb-convert-linux +0 -0
- package/bin/sb-convert-macos +0 -0
- package/bin/sb-convert-macos-arm +0 -0
- package/bin/sb-convert-win.exe +0 -0
- package/bin/sb-convert.js +78 -0
- package/docker-compose.yml +12 -0
- package/package.json +16 -0
- package/proxy.js +48 -0
package/Dockerfile
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# sb-convert
|
|
2
|
+
|
|
3
|
+
**Suburban AI Containerizer** - Turn any app into a cloud-ready stack in seconds.
|
|
4
|
+
|
|
5
|
+
## 🚀 Usage
|
|
6
|
+
|
|
7
|
+
### Run without installing (Recommended)
|
|
8
|
+
```bash
|
|
9
|
+
npx sb-convert convert .
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Install globally
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g sb-convert
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 🛠️ Commands
|
|
18
|
+
|
|
19
|
+
- `sb-convert convert .`: Analyze and containerize the current project.
|
|
20
|
+
- `sb-deploy`: Get instructions for deploying to Suburban Cloud.
|
|
21
|
+
|
|
22
|
+
## 📦 Features
|
|
23
|
+
|
|
24
|
+
- **AI Stack Detection**: Automatically detects Node.js, Go, Python, PHP, etc.
|
|
25
|
+
- **Microservices Support**: Can handle monorepos and multi-service apps.
|
|
26
|
+
- **Sidecar Stubbing**: Auto-adds Kafka, MinIO, Prometheus, and more.
|
|
27
|
+
- **AI Verification**: Built-in verification loop for high-quality Dockerfiles.
|
|
28
|
+
|
|
29
|
+
## 🌐 Office Proxy
|
|
30
|
+
|
|
31
|
+
If your office is using the centralized proxy (running in `distribution/npm`), set your endpoint:
|
|
32
|
+
```bash
|
|
33
|
+
# PowerShell
|
|
34
|
+
$env:GEMINI_API_ENDPOINT="http://YOUR_OFFICE_IP:2020"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Built by [Suburban Cloud](https://suburban.cloud).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
// Path to the Go project root (assuming we are in distribution/npm/bin)
|
|
8
|
+
const projectRoot = path.join(__dirname, '..', '..', '..');
|
|
9
|
+
|
|
10
|
+
function getBinaryName() {
|
|
11
|
+
const platform = os.platform();
|
|
12
|
+
const arch = os.arch();
|
|
13
|
+
if (platform === 'win32') {
|
|
14
|
+
return 'sb-convert-win.exe';
|
|
15
|
+
} else if (platform === 'darwin') {
|
|
16
|
+
if (arch === 'arm64') {
|
|
17
|
+
return 'sb-convert-macos-arm';
|
|
18
|
+
}
|
|
19
|
+
return 'sb-convert-macos';
|
|
20
|
+
}
|
|
21
|
+
return 'sb-convert-linux';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const binaryName = getBinaryName();
|
|
25
|
+
const binaryPath = path.join(projectRoot, binaryName);
|
|
26
|
+
|
|
27
|
+
// Check if raw Go source exists (for dev mode)
|
|
28
|
+
const mainGoPath = path.join(projectRoot, 'main.go');
|
|
29
|
+
|
|
30
|
+
const invocationName = path.basename(process.argv[1], '.js');
|
|
31
|
+
let args = process.argv.slice(2);
|
|
32
|
+
|
|
33
|
+
// If called as sb-deploy, ensure the first argument to the Go binary is 'deploy'
|
|
34
|
+
if (invocationName.includes('sb-deploy')) {
|
|
35
|
+
if (args.length === 0 || args[0] !== 'deploy') {
|
|
36
|
+
args = ['deploy', ...args];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let child;
|
|
41
|
+
|
|
42
|
+
// For development, if main.go exists in the project root, use go run
|
|
43
|
+
// In production, the binary would be bundled in a 'bin' folder relative to this script
|
|
44
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
45
|
+
const localBinaryPath = path.join(binDir, binaryName);
|
|
46
|
+
|
|
47
|
+
if (require('fs').existsSync(mainGoPath)) {
|
|
48
|
+
console.log(`[Dev] Running from source: ${mainGoPath}`);
|
|
49
|
+
child = spawn('go', ['run', 'main.go', ...args], {
|
|
50
|
+
cwd: projectRoot,
|
|
51
|
+
stdio: 'inherit',
|
|
52
|
+
shell: true
|
|
53
|
+
});
|
|
54
|
+
} else if (require('fs').existsSync(localBinaryPath)) {
|
|
55
|
+
child = spawn(localBinaryPath, args, {
|
|
56
|
+
cwd: process.cwd(),
|
|
57
|
+
stdio: 'inherit',
|
|
58
|
+
shell: true
|
|
59
|
+
});
|
|
60
|
+
} else if (require('fs').existsSync(binaryPath)) {
|
|
61
|
+
child = spawn(binaryPath, args, {
|
|
62
|
+
cwd: process.cwd(),
|
|
63
|
+
stdio: 'inherit',
|
|
64
|
+
shell: true
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
console.error(`Error: Could not find sb-convert binary. Checked: \n - ${localBinaryPath}\n - ${binaryPath}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
child.on('error', (err) => {
|
|
72
|
+
console.error(`Failed to start sb-convert: ${err.message}`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
child.on('exit', (code) => {
|
|
77
|
+
process.exit(code);
|
|
78
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
sb-proxy:
|
|
5
|
+
build: .
|
|
6
|
+
ports:
|
|
7
|
+
- "2020:8080"
|
|
8
|
+
environment:
|
|
9
|
+
- GEMINI_API_KEY=AIzaSyCt26Utwx3zt2DvW-5c5th747D875dAGWE
|
|
10
|
+
restart: always
|
|
11
|
+
|
|
12
|
+
# This proxy can be used by the office to centralize and potentially cache or log AI calls.
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sb-convert",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Suburban AI Containerizer - Turn any app into a cloud-ready stack",
|
|
5
|
+
"bin": {
|
|
6
|
+
"sb-convert": "./bin/sb-convert.js",
|
|
7
|
+
"sb-deploy": "./bin/sb-convert.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node ./bin/sb-convert.js"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=14"
|
|
15
|
+
}
|
|
16
|
+
}
|
package/proxy.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
|
|
4
|
+
const API_KEY = process.env.GEMINI_API_KEY;
|
|
5
|
+
const PORT = 8080;
|
|
6
|
+
|
|
7
|
+
if (!API_KEY) {
|
|
8
|
+
console.error('❌ ERROR: GEMINI_API_KEY environment variable is not set');
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const server = http.createServer((req, clientRes) => {
|
|
13
|
+
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
|
|
14
|
+
|
|
15
|
+
const options = {
|
|
16
|
+
hostname: 'generativelanguage.googleapis.com',
|
|
17
|
+
port: 443,
|
|
18
|
+
path: req.url,
|
|
19
|
+
method: req.method,
|
|
20
|
+
headers: {
|
|
21
|
+
...req.headers,
|
|
22
|
+
'host': 'generativelanguage.googleapis.com',
|
|
23
|
+
'x-goog-api-key': API_KEY // Inject the API key
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Remove original key if it exists to avoid conflicts
|
|
28
|
+
delete options.headers['x-goog-api-key'];
|
|
29
|
+
options.headers['x-goog-api-key'] = API_KEY;
|
|
30
|
+
|
|
31
|
+
const proxyReq = https.request(options, (remoteRes) => {
|
|
32
|
+
clientRes.writeHead(remoteRes.statusCode, remoteRes.headers);
|
|
33
|
+
remoteRes.pipe(clientRes, { end: true });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
req.pipe(proxyReq, { end: true });
|
|
37
|
+
|
|
38
|
+
proxyReq.on('error', (err) => {
|
|
39
|
+
console.error('Proxy Error:', err);
|
|
40
|
+
clientRes.writeHead(500);
|
|
41
|
+
clientRes.end('Internal Proxy Error');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
server.listen(PORT, '0.0.0.0', () => {
|
|
46
|
+
console.log(`🚀 Suburban AI Proxy running on port ${PORT}`);
|
|
47
|
+
console.log(`🔑 API Key injection active`);
|
|
48
|
+
});
|