@geekmidas/cli 1.10.16 → 1.10.17
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/CHANGELOG.md +6 -0
- package/dist/index.cjs +11 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +11 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/dev/__tests__/index.spec.ts +68 -0
- package/src/dev/index.ts +23 -15
- package/src/init/versions.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/cli",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.17",
|
|
4
4
|
"description": "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"prompts": "~2.4.2",
|
|
57
57
|
"tsx": "~4.20.3",
|
|
58
58
|
"yaml": "~2.8.2",
|
|
59
|
-
"@geekmidas/envkit": "~1.0.
|
|
59
|
+
"@geekmidas/envkit": "~1.0.4",
|
|
60
60
|
"@geekmidas/constructs": "~3.0.2",
|
|
61
|
+
"@geekmidas/errors": "~1.0.0",
|
|
61
62
|
"@geekmidas/logger": "~1.0.0",
|
|
62
|
-
"@geekmidas/schema": "~1.0.0"
|
|
63
|
-
"@geekmidas/errors": "~1.0.0"
|
|
63
|
+
"@geekmidas/schema": "~1.0.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/lodash.kebabcase": "^4.1.9",
|
|
@@ -1237,6 +1237,28 @@ describe('replacePortInUrl', () => {
|
|
|
1237
1237
|
// Only the :5432 before / should be replaced
|
|
1238
1238
|
expect(result).toBe('postgresql://app:pass5432@localhost:5433/db5432');
|
|
1239
1239
|
});
|
|
1240
|
+
|
|
1241
|
+
it('should replace port followed by query string', () => {
|
|
1242
|
+
const url = 'pgboss://pgboss:pass@localhost:5432/mydb?schema=pgboss';
|
|
1243
|
+
expect(replacePortInUrl(url, 5432, 5433)).toBe(
|
|
1244
|
+
'pgboss://pgboss:pass@localhost:5433/mydb?schema=pgboss',
|
|
1245
|
+
);
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
it('should replace port in SNS URL with query params and no path', () => {
|
|
1249
|
+
const url = 'sns://key:secret@localhost:4566?region=us-east-1';
|
|
1250
|
+
expect(replacePortInUrl(url, 4566, 4567)).toBe(
|
|
1251
|
+
'sns://key:secret@localhost:4567?region=us-east-1',
|
|
1252
|
+
);
|
|
1253
|
+
});
|
|
1254
|
+
|
|
1255
|
+
it('should replace URL-encoded port in query params', () => {
|
|
1256
|
+
const url =
|
|
1257
|
+
'sns://key:secret@localhost:4566?region=us-east-1&endpoint=http%3A%2F%2Flocalhost%3A4566';
|
|
1258
|
+
expect(replacePortInUrl(url, 4566, 4567)).toBe(
|
|
1259
|
+
'sns://key:secret@localhost:4567?region=us-east-1&endpoint=http%3A%2F%2Flocalhost%3A4567',
|
|
1260
|
+
);
|
|
1261
|
+
});
|
|
1240
1262
|
});
|
|
1241
1263
|
|
|
1242
1264
|
describe('rewriteUrlsWithPorts', () => {
|
|
@@ -1384,6 +1406,52 @@ describe('rewriteUrlsWithPorts', () => {
|
|
|
1384
1406
|
expect(result.POSTGRES_HOST).toBe('localhost');
|
|
1385
1407
|
});
|
|
1386
1408
|
|
|
1409
|
+
it('should rewrite EVENT_PUBLISHER_CONNECTION_STRING and EVENT_SUBSCRIBER_CONNECTION_STRING', () => {
|
|
1410
|
+
const secrets = {
|
|
1411
|
+
EVENT_PUBLISHER_CONNECTION_STRING:
|
|
1412
|
+
'pgboss://pgboss:pass@localhost:5432/mydb?schema=pgboss',
|
|
1413
|
+
EVENT_SUBSCRIBER_CONNECTION_STRING:
|
|
1414
|
+
'pgboss://pgboss:pass@localhost:5432/mydb?schema=pgboss',
|
|
1415
|
+
};
|
|
1416
|
+
const result = rewriteUrlsWithPorts(secrets, {
|
|
1417
|
+
dockerEnv: { POSTGRES_HOST_PORT: '5433' },
|
|
1418
|
+
ports: { POSTGRES_HOST_PORT: 5433 },
|
|
1419
|
+
mappings: [pgMapping],
|
|
1420
|
+
});
|
|
1421
|
+
expect(result.EVENT_PUBLISHER_CONNECTION_STRING).toBe(
|
|
1422
|
+
'pgboss://pgboss:pass@localhost:5433/mydb?schema=pgboss',
|
|
1423
|
+
);
|
|
1424
|
+
expect(result.EVENT_SUBSCRIBER_CONNECTION_STRING).toBe(
|
|
1425
|
+
'pgboss://pgboss:pass@localhost:5433/mydb?schema=pgboss',
|
|
1426
|
+
);
|
|
1427
|
+
});
|
|
1428
|
+
|
|
1429
|
+
it('should rewrite SNS connection strings with encoded endpoint port', () => {
|
|
1430
|
+
const localstackMapping = {
|
|
1431
|
+
service: 'localstack',
|
|
1432
|
+
envVar: 'LOCALSTACK_PORT',
|
|
1433
|
+
defaultPort: 4566,
|
|
1434
|
+
containerPort: 4566,
|
|
1435
|
+
};
|
|
1436
|
+
const secrets = {
|
|
1437
|
+
EVENT_PUBLISHER_CONNECTION_STRING:
|
|
1438
|
+
'sns://LSIAkey:secret@localhost:4566?region=us-east-1&endpoint=http%3A%2F%2Flocalhost%3A4566',
|
|
1439
|
+
EVENT_SUBSCRIBER_CONNECTION_STRING:
|
|
1440
|
+
'sqs://LSIAkey:secret@localhost:4566?region=us-east-1&endpoint=http%3A%2F%2Flocalhost%3A4566',
|
|
1441
|
+
};
|
|
1442
|
+
const result = rewriteUrlsWithPorts(secrets, {
|
|
1443
|
+
dockerEnv: { LOCALSTACK_PORT: '4567' },
|
|
1444
|
+
ports: { LOCALSTACK_PORT: 4567 },
|
|
1445
|
+
mappings: [localstackMapping],
|
|
1446
|
+
});
|
|
1447
|
+
expect(result.EVENT_PUBLISHER_CONNECTION_STRING).toBe(
|
|
1448
|
+
'sns://LSIAkey:secret@localhost:4567?region=us-east-1&endpoint=http%3A%2F%2Flocalhost%3A4567',
|
|
1449
|
+
);
|
|
1450
|
+
expect(result.EVENT_SUBSCRIBER_CONNECTION_STRING).toBe(
|
|
1451
|
+
'sqs://LSIAkey:secret@localhost:4567?region=us-east-1&endpoint=http%3A%2F%2Flocalhost%3A4567',
|
|
1452
|
+
);
|
|
1453
|
+
});
|
|
1454
|
+
|
|
1387
1455
|
it('should return empty for no mappings', () => {
|
|
1388
1456
|
const result = rewriteUrlsWithPorts(
|
|
1389
1457
|
{},
|
package/src/dev/index.ts
CHANGED
|
@@ -348,7 +348,17 @@ export function replacePortInUrl(
|
|
|
348
348
|
newPort: number,
|
|
349
349
|
): string {
|
|
350
350
|
if (oldPort === newPort) return url;
|
|
351
|
-
|
|
351
|
+
// Replace literal :port (in authority section)
|
|
352
|
+
let result = url.replace(
|
|
353
|
+
new RegExp(`:${oldPort}(?=[/?#]|$)`, 'g'),
|
|
354
|
+
`:${newPort}`,
|
|
355
|
+
);
|
|
356
|
+
// Replace URL-encoded :port (e.g., in query params like endpoint=http%3A%2F%2Flocalhost%3A4566)
|
|
357
|
+
result = result.replace(
|
|
358
|
+
new RegExp(`%3A${oldPort}(?=[%/?#&]|$)`, 'gi'),
|
|
359
|
+
`%3A${newPort}`,
|
|
360
|
+
);
|
|
361
|
+
return result;
|
|
352
362
|
}
|
|
353
363
|
|
|
354
364
|
/**
|
|
@@ -402,6 +412,7 @@ export function rewriteUrlsWithPorts(
|
|
|
402
412
|
if (
|
|
403
413
|
!key.endsWith('_URL') &&
|
|
404
414
|
!key.endsWith('_ENDPOINT') &&
|
|
415
|
+
!key.endsWith('_CONNECTION_STRING') &&
|
|
405
416
|
key !== 'DATABASE_URL'
|
|
406
417
|
)
|
|
407
418
|
continue;
|
|
@@ -2246,20 +2257,17 @@ export async function execCommand(
|
|
|
2246
2257
|
logger.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
2247
2258
|
}
|
|
2248
2259
|
|
|
2249
|
-
//
|
|
2250
|
-
const
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
Object.assign(credentials, rewritten);
|
|
2261
|
-
logger.log(`🔌 Applied ${Object.keys(ports).length} port mapping(s)`);
|
|
2262
|
-
}
|
|
2260
|
+
// Resolve actual Docker ports from running containers (not just saved state)
|
|
2261
|
+
const resolvedPorts = await resolveServicePorts(secretsRoot);
|
|
2262
|
+
if (
|
|
2263
|
+
resolvedPorts.mappings.length > 0 &&
|
|
2264
|
+
Object.keys(resolvedPorts.ports).length > 0
|
|
2265
|
+
) {
|
|
2266
|
+
const rewritten = rewriteUrlsWithPorts(credentials, resolvedPorts);
|
|
2267
|
+
Object.assign(credentials, rewritten);
|
|
2268
|
+
logger.log(
|
|
2269
|
+
`🔌 Applied ${Object.keys(resolvedPorts.ports).length} port mapping(s)`,
|
|
2270
|
+
);
|
|
2263
2271
|
}
|
|
2264
2272
|
|
|
2265
2273
|
// Inject dependency URLs (works for both frontend and backend apps)
|
package/src/init/versions.ts
CHANGED
|
@@ -35,7 +35,7 @@ export const GEEKMIDAS_VERSIONS = {
|
|
|
35
35
|
'@geekmidas/constructs': '~3.0.2',
|
|
36
36
|
'@geekmidas/db': '~1.0.0',
|
|
37
37
|
'@geekmidas/emailkit': '~1.0.0',
|
|
38
|
-
'@geekmidas/envkit': '~1.0.
|
|
38
|
+
'@geekmidas/envkit': '~1.0.4',
|
|
39
39
|
'@geekmidas/errors': '~1.0.0',
|
|
40
40
|
'@geekmidas/events': '~1.1.0',
|
|
41
41
|
'@geekmidas/logger': '~1.0.0',
|