genbox 1.0.93 → 1.0.95
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/dist/commands/create.js
CHANGED
|
@@ -54,10 +54,10 @@ const db_utils_1 = require("../db-utils");
|
|
|
54
54
|
const utils_1 = require("../utils");
|
|
55
55
|
// Credits consumed per hour for each size (matches API billing.config.ts)
|
|
56
56
|
const CREDITS_PER_HOUR = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
cx23: 1,
|
|
58
|
+
cx33: 2,
|
|
59
|
+
cx43: 4,
|
|
60
|
+
cx53: 8,
|
|
61
61
|
small: 1,
|
|
62
62
|
medium: 2,
|
|
63
63
|
large: 4,
|
package/dist/commands/init.js
CHANGED
|
@@ -194,9 +194,10 @@ function convertScanToDetected(scan, root) {
|
|
|
194
194
|
framework: app.framework,
|
|
195
195
|
framework_source: app.framework ? 'package.json dependencies' : undefined,
|
|
196
196
|
commands: app.scripts ? {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
// Use script NAMES (not raw commands) - PM2 runs `pnpm run <name>`
|
|
198
|
+
dev: app.scripts.dev ? 'dev' : undefined,
|
|
199
|
+
build: app.scripts.build ? 'build' : undefined,
|
|
200
|
+
start: app.scripts.start ? 'start' : undefined,
|
|
200
201
|
} : undefined,
|
|
201
202
|
dependencies: app.dependencies,
|
|
202
203
|
git: appGit,
|
|
@@ -214,6 +215,7 @@ function convertScanToDetected(scan, root) {
|
|
|
214
215
|
image: db.image || 'unknown',
|
|
215
216
|
port: db.ports?.[0]?.host || 0,
|
|
216
217
|
source: db.sourceFile || 'docker-compose.yml',
|
|
218
|
+
...(db.replicaSet && { replicaSet: db.replicaSet }),
|
|
217
219
|
});
|
|
218
220
|
}
|
|
219
221
|
for (const cache of scan.compose.caches || []) {
|
|
@@ -1337,11 +1339,16 @@ function generateConfig(detected, settings, repos, environments, profiles) {
|
|
|
1337
1339
|
const provides = {};
|
|
1338
1340
|
if (detected.infrastructure) {
|
|
1339
1341
|
for (const infra of detected.infrastructure) {
|
|
1340
|
-
|
|
1342
|
+
const providerConfig = {
|
|
1341
1343
|
type: infra.type,
|
|
1342
1344
|
image: infra.image,
|
|
1343
1345
|
port: infra.port,
|
|
1344
1346
|
};
|
|
1347
|
+
// Include replicaSet for MongoDB if detected
|
|
1348
|
+
if (infra.replicaSet) {
|
|
1349
|
+
providerConfig.replicaSet = infra.replicaSet;
|
|
1350
|
+
}
|
|
1351
|
+
provides[infra.name] = providerConfig;
|
|
1345
1352
|
}
|
|
1346
1353
|
}
|
|
1347
1354
|
// Build defaults
|
package/dist/profile-resolver.js
CHANGED
|
@@ -98,8 +98,8 @@ class ProfileResolver {
|
|
|
98
98
|
// Step 3: Resolve dependencies
|
|
99
99
|
const { apps, infrastructure, dependencyWarnings } = await this.resolveDependencies(config, selectedApps, options, profile);
|
|
100
100
|
warnings.push(...dependencyWarnings);
|
|
101
|
-
// Step 4: Determine database mode
|
|
102
|
-
const database = await this.resolveDatabaseMode(config, options, profile);
|
|
101
|
+
// Step 4: Determine database mode (pass infrastructure for replicaSet detection)
|
|
102
|
+
const database = await this.resolveDatabaseMode(config, options, profile, infrastructure);
|
|
103
103
|
// Step 5: Determine size
|
|
104
104
|
const size = options.size || profile.size || this.inferSize(apps, infrastructure);
|
|
105
105
|
// Step 6: Build resolved config
|
|
@@ -320,7 +320,7 @@ class ProfileResolver {
|
|
|
320
320
|
/**
|
|
321
321
|
* Resolve database mode
|
|
322
322
|
*/
|
|
323
|
-
async resolveDatabaseMode(config, options, profile) {
|
|
323
|
+
async resolveDatabaseMode(config, options, profile, infrastructure) {
|
|
324
324
|
// Load env vars from .env.genbox (where init stores MongoDB URLs)
|
|
325
325
|
const envVars = this.configLoader.loadEnvVars(process.cwd());
|
|
326
326
|
// Helper to get MongoDB URL from .env.genbox
|
|
@@ -335,6 +335,9 @@ class ProfileResolver {
|
|
|
335
335
|
// Custom environments: {NAME}_MONGODB_URL
|
|
336
336
|
return envVars[`${source.toUpperCase()}_MONGODB_URL`];
|
|
337
337
|
};
|
|
338
|
+
// Extract replicaSet from MongoDB infrastructure config if present
|
|
339
|
+
const mongoInfra = infrastructure.find(i => i.type === 'database' && i.image?.toLowerCase().includes('mongo'));
|
|
340
|
+
const replicaSet = mongoInfra?.replicaSet;
|
|
338
341
|
// CLI flag takes precedence
|
|
339
342
|
if (options.db) {
|
|
340
343
|
// Normalize 'fresh' to 'local' (fresh is the UI name, local is internal)
|
|
@@ -344,6 +347,7 @@ class ProfileResolver {
|
|
|
344
347
|
mode: dbMode,
|
|
345
348
|
source,
|
|
346
349
|
url: dbMode === 'copy' ? getMongoUrl(source) : undefined,
|
|
350
|
+
replicaSet,
|
|
347
351
|
};
|
|
348
352
|
}
|
|
349
353
|
// Profile setting
|
|
@@ -354,6 +358,7 @@ class ProfileResolver {
|
|
|
354
358
|
url: profile.database.mode === 'copy' && profile.database.source
|
|
355
359
|
? getMongoUrl(profile.database.source)
|
|
356
360
|
: undefined,
|
|
361
|
+
replicaSet,
|
|
357
362
|
};
|
|
358
363
|
}
|
|
359
364
|
// If default_connection is set, use remote
|
|
@@ -365,11 +370,13 @@ class ProfileResolver {
|
|
|
365
370
|
mode: 'remote',
|
|
366
371
|
source: profileConnection,
|
|
367
372
|
url: mongoUrl,
|
|
373
|
+
replicaSet,
|
|
368
374
|
};
|
|
369
375
|
}
|
|
370
376
|
// Interactive mode
|
|
371
377
|
if (!options.yes) {
|
|
372
|
-
|
|
378
|
+
const interactiveResult = await this.selectDatabaseModeInteractive(config);
|
|
379
|
+
return { ...interactiveResult, replicaSet };
|
|
373
380
|
}
|
|
374
381
|
// Default
|
|
375
382
|
const defaultMode = config.defaults?.database?.mode || 'local';
|
|
@@ -378,6 +385,7 @@ class ProfileResolver {
|
|
|
378
385
|
mode: defaultMode,
|
|
379
386
|
source: defaultSource,
|
|
380
387
|
url: defaultMode === 'copy' && defaultSource ? getMongoUrl(defaultSource) : undefined,
|
|
388
|
+
replicaSet,
|
|
381
389
|
};
|
|
382
390
|
}
|
|
383
391
|
/**
|
|
@@ -194,21 +194,46 @@ class ComposeParser {
|
|
|
194
194
|
return files;
|
|
195
195
|
}
|
|
196
196
|
normalizeService(name, config, root, composeDir, sourceFile) {
|
|
197
|
+
const command = this.normalizeCommand(config.command);
|
|
198
|
+
const environment = this.normalizeEnvironment(config.environment);
|
|
199
|
+
const image = config.image;
|
|
197
200
|
return {
|
|
198
201
|
name,
|
|
199
|
-
image
|
|
202
|
+
image,
|
|
200
203
|
build: this.normalizeBuild(config.build, root, composeDir),
|
|
201
204
|
ports: this.normalizePorts(config.ports),
|
|
202
|
-
environment
|
|
205
|
+
environment,
|
|
203
206
|
envFile: this.normalizeEnvFile(config.env_file),
|
|
204
207
|
dependsOn: this.normalizeDependsOn(config.depends_on),
|
|
205
208
|
volumes: this.normalizeVolumes(config.volumes),
|
|
206
209
|
healthcheck: this.normalizeHealthcheck(config.healthcheck),
|
|
207
|
-
command
|
|
210
|
+
command,
|
|
208
211
|
labels: this.normalizeLabels(config.labels),
|
|
209
212
|
sourceFile,
|
|
213
|
+
replicaSet: this.detectReplicaSet(image, command, environment),
|
|
210
214
|
};
|
|
211
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Detect MongoDB replica set configuration from command or environment
|
|
218
|
+
*/
|
|
219
|
+
detectReplicaSet(image, command, environment) {
|
|
220
|
+
// Only check MongoDB services
|
|
221
|
+
if (!image || !DATABASE_PATTERNS[0].test(image)) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
// Check command for --replSet flag
|
|
225
|
+
if (command) {
|
|
226
|
+
const replSetMatch = command.match(/--replSet[=\s]+(\S+)/);
|
|
227
|
+
if (replSetMatch) {
|
|
228
|
+
return replSetMatch[1];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Check environment for MONGO_REPLICA_SET
|
|
232
|
+
if (environment.MONGO_REPLICA_SET) {
|
|
233
|
+
return environment.MONGO_REPLICA_SET;
|
|
234
|
+
}
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
212
237
|
normalizeBuild(build, root, composeDir) {
|
|
213
238
|
if (!build)
|
|
214
239
|
return undefined;
|