@geekmidas/cli 10.0.0-alpha.3 → 10.0.0-alpha.31
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/README.md +25 -48
- package/bin/adjacent-tsconfig.mjs +97 -0
- package/bin/gkm.mjs +7 -1
- package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-BZFGYYVA.cjs} +21 -22
- package/dist/HostingerProvider-BZFGYYVA.cjs.map +1 -0
- package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-GF6NAZAK.mjs} +20 -21
- package/dist/HostingerProvider-GF6NAZAK.mjs.map +1 -0
- package/dist/{LocalStateProvider-Db9SEjyH.cjs → LocalStateProvider-7HR6SS2t.cjs} +11 -6
- package/dist/LocalStateProvider-7HR6SS2t.cjs.map +1 -0
- package/dist/{LocalStateProvider-Bn6tS-oL.mjs → LocalStateProvider-D7QyJoLM.mjs} +10 -4
- package/dist/LocalStateProvider-D7QyJoLM.mjs.map +1 -0
- package/dist/{openapi-c9bpieI5.cjs → OpenApiTsGenerator-D1nhN98m.cjs} +135 -298
- package/dist/OpenApiTsGenerator-D1nhN98m.cjs.map +1 -0
- package/dist/{openapi-CY9xFkTH.mjs → OpenApiTsGenerator-hDINScnz.mjs} +106 -250
- package/dist/OpenApiTsGenerator-hDINScnz.mjs.map +1 -0
- package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-Cvj40A8I.mjs} +12 -12
- package/dist/Route53Provider-Cvj40A8I.mjs.map +1 -0
- package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-DVILBsvV.cjs} +20 -21
- package/dist/Route53Provider-DVILBsvV.cjs.map +1 -0
- package/dist/{SSMStateProvider-BRt2py-A.mjs → SSMStateProvider-B0Hu1MKZ.mjs} +13 -4
- package/dist/SSMStateProvider-B0Hu1MKZ.mjs.map +1 -0
- package/dist/{SSMStateProvider-DyX8s9HI.cjs → SSMStateProvider-VrQ-yeqd.cjs} +17 -9
- package/dist/SSMStateProvider-VrQ-yeqd.cjs.map +1 -0
- package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-BmhIO_Yr.cjs} +21 -19
- package/dist/backup-provisioner-BmhIO_Yr.cjs.map +1 -0
- package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-DIVCbfee.mjs} +10 -7
- package/dist/backup-provisioner-DIVCbfee.mjs.map +1 -0
- package/dist/{bundler-BY1OmV1e.cjs → bundler-CYF5mWi9.cjs} +10 -28
- package/dist/bundler-CYF5mWi9.cjs.map +1 -0
- package/dist/{bundler-Be8Zg4Wd.mjs → bundler-D9IPNvDt.mjs} +9 -26
- package/dist/bundler-D9IPNvDt.mjs.map +1 -0
- package/dist/{config-CzWnfcXM.mjs → config-BH3Ki69F.mjs} +49 -89
- package/dist/config-BH3Ki69F.mjs.map +1 -0
- package/dist/{config-BholeD-0.cjs → config-URVD4bTj.cjs} +101 -148
- package/dist/config-URVD4bTj.cjs.map +1 -0
- package/dist/config.cjs +5 -5
- package/dist/config.d.cts +25 -17
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +25 -17
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +3 -5
- package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
- package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
- package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
- package/dist/deploy/sniffer-hooks.cjs +13 -7
- package/dist/deploy/sniffer-hooks.cjs.map +1 -1
- package/dist/deploy/sniffer-hooks.d.cts +1 -2
- package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
- package/dist/deploy/sniffer-hooks.d.mts +1 -2
- package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
- package/dist/deploy/sniffer-hooks.mjs +9 -2
- package/dist/deploy/sniffer-hooks.mjs.map +1 -1
- package/dist/deploy/sniffer-loader.cjs +16 -7
- package/dist/deploy/sniffer-loader.cjs.map +1 -1
- package/dist/deploy/sniffer-loader.d.cts +1 -1
- package/dist/deploy/sniffer-loader.d.mts +1 -1
- package/dist/deploy/sniffer-loader.mjs +13 -2
- package/dist/deploy/sniffer-loader.mjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.cjs +11 -11
- package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
- package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
- package/dist/deploy/sniffer-routes-worker.mjs +3 -3
- package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
- package/dist/deploy/sniffer-worker.cjs +15 -6
- package/dist/deploy/sniffer-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-worker.d.cts +1 -3
- package/dist/deploy/sniffer-worker.d.cts.map +1 -1
- package/dist/deploy/sniffer-worker.d.mts +1 -3
- package/dist/deploy/sniffer-worker.d.mts.map +1 -1
- package/dist/deploy/sniffer-worker.mjs +15 -4
- package/dist/deploy/sniffer-worker.mjs.map +1 -1
- package/dist/{discover-CAlFgYec.mjs → discover-CMxesskG.mjs} +66 -22
- package/dist/discover-CMxesskG.mjs.map +1 -0
- package/dist/{discover-DTmFeloL.cjs → discover-CroTIm0K.cjs} +117 -66
- package/dist/discover-CroTIm0K.cjs.map +1 -0
- package/dist/{emit-CbcRolsa.cjs → emit-BdoPFjZf.cjs} +53 -36
- package/dist/emit-BdoPFjZf.cjs.map +1 -0
- package/dist/{emit-CiZS_5Ub.mjs → emit-Bzq7JsMP.mjs} +24 -6
- package/dist/emit-Bzq7JsMP.mjs.map +1 -0
- package/dist/github-B2fis34P.cjs +216 -0
- package/dist/github-B2fis34P.cjs.map +1 -0
- package/dist/github-BrDmlm1x.mjs +216 -0
- package/dist/github-BrDmlm1x.mjs.map +1 -0
- package/dist/{index-CHB4tSzX.d.cts → index-p89EzILa.d.mts} +4 -23
- package/dist/index-p89EzILa.d.mts.map +1 -0
- package/dist/{index-BThUzEIp.d.mts → index-rU9u761a.d.cts} +4 -23
- package/dist/index-rU9u761a.d.cts.map +1 -0
- package/dist/index.cjs +6028 -4452
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +5922 -4367
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BuCx7tIv.cjs +498 -0
- package/dist/migrate-BuCx7tIv.cjs.map +1 -0
- package/dist/migrate-CBICVMAi.mjs +493 -0
- package/dist/migrate-CBICVMAi.mjs.map +1 -0
- package/dist/openapi.cjs +197 -8
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +47 -14
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +47 -14
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +191 -5
- package/dist/openapi.mjs.map +1 -0
- package/dist/ready-CvP3JVEw.mjs +355 -0
- package/dist/ready-CvP3JVEw.mjs.map +1 -0
- package/dist/ready-DXtNfk7v.cjs +390 -0
- package/dist/ready-DXtNfk7v.cjs.map +1 -0
- package/dist/reconcile/public.cjs +4 -4
- package/dist/reconcile/public.d.cts +27 -26
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +27 -26
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +3 -4
- package/dist/reconcile-BxZTV2vl.cjs +332 -0
- package/dist/reconcile-BxZTV2vl.cjs.map +1 -0
- package/dist/reconcile-yNq6Shau.mjs +279 -0
- package/dist/reconcile-yNq6Shau.mjs.map +1 -0
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
- package/dist/ssm-BKN1Cg4z.mjs +60 -0
- package/dist/ssm-BKN1Cg4z.mjs.map +1 -0
- package/dist/ssm-FxeSAt35.cjs +60 -0
- package/dist/ssm-FxeSAt35.cjs.map +1 -0
- package/dist/{storage-Bi24WfoW.mjs → storage-BjTLjDDp.mjs} +22 -22
- package/dist/storage-BjTLjDDp.mjs.map +1 -0
- package/dist/{storage-BJmzYxt8.cjs → storage-C2JC31V9.cjs} +65 -84
- package/dist/storage-C2JC31V9.cjs.map +1 -0
- package/dist/types-CzK6hsXP.d.mts +6286 -0
- package/dist/types-CzK6hsXP.d.mts.map +1 -0
- package/dist/types-DOOAevjG.d.cts +6287 -0
- package/dist/types-DOOAevjG.d.cts.map +1 -0
- package/dist/vitest.cjs +61 -0
- package/dist/vitest.cjs.map +1 -0
- package/dist/vitest.d.cts +28 -0
- package/dist/vitest.d.cts.map +1 -0
- package/dist/vitest.d.mts +28 -0
- package/dist/vitest.d.mts.map +1 -0
- package/dist/vitest.mjs +61 -0
- package/dist/vitest.mjs.map +1 -0
- package/dist/workspace/index.cjs +3 -4
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +2 -3
- package/dist/workspace-Bav3TVrP.cjs +6710 -0
- package/dist/workspace-Bav3TVrP.cjs.map +1 -0
- package/dist/{credentials-DQmbRnr1.cjs → workspace-BhiMkRuA.cjs} +2076 -1963
- package/dist/workspace-BhiMkRuA.cjs.map +1 -0
- package/dist/{credentials-BZcp3CGx.mjs → workspace-C97QUCIf.mjs} +1957 -1837
- package/dist/workspace-C97QUCIf.mjs.map +1 -0
- package/dist/workspace-T4IVGSoB.mjs +6538 -0
- package/dist/workspace-T4IVGSoB.mjs.map +1 -0
- package/package.json +45 -38
- package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
- package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
- package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
- package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
- package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
- package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
- package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
- package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
- package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
- package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
- package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
- package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
- package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
- package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
- package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
- package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
- package/dist/bundler-BY1OmV1e.cjs.map +0 -1
- package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
- package/dist/chunk-Duj1WY3L.mjs +0 -7
- package/dist/config-BholeD-0.cjs.map +0 -1
- package/dist/config-CzWnfcXM.mjs.map +0 -1
- package/dist/credentials-B5zRHdAl.mjs +0 -141
- package/dist/credentials-B5zRHdAl.mjs.map +0 -1
- package/dist/credentials-BZcp3CGx.mjs.map +0 -1
- package/dist/credentials-BapzjyV5.cjs +0 -195
- package/dist/credentials-BapzjyV5.cjs.map +0 -1
- package/dist/credentials-DQmbRnr1.cjs.map +0 -1
- package/dist/discover-CAlFgYec.mjs.map +0 -1
- package/dist/discover-DTmFeloL.cjs.map +0 -1
- package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
- package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
- package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
- package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
- package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
- package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
- package/dist/emit-CbcRolsa.cjs.map +0 -1
- package/dist/emit-CiZS_5Ub.mjs.map +0 -1
- package/dist/encryption-C6jaU0hE.cjs +0 -54
- package/dist/encryption-C6jaU0hE.cjs.map +0 -1
- package/dist/encryption-CHzzeR8a.cjs +0 -4
- package/dist/encryption-CQUncu7v.mjs +0 -3
- package/dist/encryption-D-abyhZx.mjs +0 -42
- package/dist/encryption-D-abyhZx.mjs.map +0 -1
- package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
- package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
- package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
- package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
- package/dist/generator-CNzBw7g5.cjs +0 -289
- package/dist/generator-CNzBw7g5.cjs.map +0 -1
- package/dist/generator-VE2JrFlY.mjs +0 -253
- package/dist/generator-VE2JrFlY.mjs.map +0 -1
- package/dist/index-BThUzEIp.d.mts.map +0 -1
- package/dist/index-CHB4tSzX.d.cts.map +0 -1
- package/dist/openapi-CY9xFkTH.mjs.map +0 -1
- package/dist/openapi-c9bpieI5.cjs.map +0 -1
- package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
- package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
- package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
- package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
- package/dist/openapi-react-query.cjs +0 -4
- package/dist/openapi-react-query.d.cts +0 -11
- package/dist/openapi-react-query.d.cts.map +0 -1
- package/dist/openapi-react-query.d.mts +0 -11
- package/dist/openapi-react-query.d.mts.map +0 -1
- package/dist/openapi-react-query.mjs +0 -4
- package/dist/reconcile-CFs8C_1a.mjs +0 -37
- package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
- package/dist/reconcile-D0pimNiy.cjs +0 -37
- package/dist/reconcile-D0pimNiy.cjs.map +0 -1
- package/dist/setup-Bc73t0ve.mjs +0 -443
- package/dist/setup-Bc73t0ve.mjs.map +0 -1
- package/dist/setup-C48C9hto.cjs +0 -473
- package/dist/setup-C48C9hto.cjs.map +0 -1
- package/dist/setup-DCuudnCl.mjs +0 -11
- package/dist/setup-fG_ivuxO.cjs +0 -11
- package/dist/storage-BJmzYxt8.cjs.map +0 -1
- package/dist/storage-BM9hGpgv.cjs +0 -7
- package/dist/storage-Bi24WfoW.mjs.map +0 -1
- package/dist/storage-CYlGwWTj.mjs +0 -3
- package/dist/sync-CmEuNZsB.mjs +0 -76
- package/dist/sync-CmEuNZsB.mjs.map +0 -1
- package/dist/sync-D306yOWu.cjs +0 -4
- package/dist/sync-SizaChmC.cjs +0 -93
- package/dist/sync-SizaChmC.cjs.map +0 -1
- package/dist/sync-hOqAWHR6.mjs +0 -3
- package/dist/types-C-arnQ1r.d.mts +0 -2184
- package/dist/types-C-arnQ1r.d.mts.map +0 -1
- package/dist/types-abJQuk7m.d.cts +0 -2184
- package/dist/types-abJQuk7m.d.cts.map +0 -1
- package/dist/workspace-7FqprxuJ.mjs +0 -4323
- package/dist/workspace-7FqprxuJ.mjs.map +0 -1
- package/dist/workspace-BO_KWohI.cjs +0 -9
- package/dist/workspace-DK4WWJIn.mjs +0 -8
- package/dist/workspace-XvqO9jIv.cjs +0 -4472
- package/dist/workspace-XvqO9jIv.cjs.map +0 -1
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
const node_crypto = require_chunk.__toESM(require("node:crypto"));
|
|
3
|
-
|
|
4
|
-
//#region src/secrets/generator.ts
|
|
5
|
-
/**
|
|
6
|
-
* Generate a secure random password using URL-safe base64 characters.
|
|
7
|
-
* @param length Password length (default: 32)
|
|
8
|
-
*/
|
|
9
|
-
function generateSecurePassword(length = 32) {
|
|
10
|
-
return (0, node_crypto.randomBytes)(Math.ceil(length * 3 / 4)).toString("base64url").slice(0, length);
|
|
11
|
-
}
|
|
12
|
-
/** Default service configurations (localhost for local dev via Docker port mapping) */
|
|
13
|
-
const SERVICE_DEFAULTS = {
|
|
14
|
-
postgres: {
|
|
15
|
-
host: "localhost",
|
|
16
|
-
port: 5432,
|
|
17
|
-
username: "app",
|
|
18
|
-
database: "app"
|
|
19
|
-
},
|
|
20
|
-
redis: {
|
|
21
|
-
host: "localhost",
|
|
22
|
-
port: 6379,
|
|
23
|
-
username: "default"
|
|
24
|
-
},
|
|
25
|
-
rabbitmq: {
|
|
26
|
-
host: "localhost",
|
|
27
|
-
port: 5672,
|
|
28
|
-
username: "app",
|
|
29
|
-
vhost: "/"
|
|
30
|
-
},
|
|
31
|
-
minio: {
|
|
32
|
-
host: "localhost",
|
|
33
|
-
port: 9e3,
|
|
34
|
-
username: "app",
|
|
35
|
-
bucket: "app"
|
|
36
|
-
},
|
|
37
|
-
mailpit: {
|
|
38
|
-
host: "localhost",
|
|
39
|
-
port: 1025,
|
|
40
|
-
username: "app"
|
|
41
|
-
},
|
|
42
|
-
localstack: {
|
|
43
|
-
host: "localhost",
|
|
44
|
-
port: 4566,
|
|
45
|
-
username: "localstack",
|
|
46
|
-
region: "us-east-1"
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
/** Default credentials for pgboss (not a Docker service, reuses postgres) */
|
|
50
|
-
const PGBOSS_DEFAULTS = {
|
|
51
|
-
host: "localhost",
|
|
52
|
-
port: 5432,
|
|
53
|
-
username: "pgboss",
|
|
54
|
-
database: "app"
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Generate credentials for a specific service.
|
|
58
|
-
*/
|
|
59
|
-
function generateServiceCredentials(service) {
|
|
60
|
-
const defaults = SERVICE_DEFAULTS[service];
|
|
61
|
-
return {
|
|
62
|
-
...defaults,
|
|
63
|
-
password: generateSecurePassword()
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Generate credentials for multiple services.
|
|
68
|
-
*/
|
|
69
|
-
function generateServicesCredentials(services) {
|
|
70
|
-
const result = {};
|
|
71
|
-
for (const service of services) result[service] = generateServiceCredentials(service);
|
|
72
|
-
return result;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Generate connection URL for PostgreSQL.
|
|
76
|
-
*/
|
|
77
|
-
function generatePostgresUrl(creds) {
|
|
78
|
-
const { username, password, host, port, database } = creds;
|
|
79
|
-
return `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Generate connection URL for Redis.
|
|
83
|
-
*/
|
|
84
|
-
function generateRedisUrl(creds) {
|
|
85
|
-
const { password, host, port } = creds;
|
|
86
|
-
return `redis://:${encodeURIComponent(password)}@${host}:${port}`;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Generate connection URL for RabbitMQ.
|
|
90
|
-
*/
|
|
91
|
-
function generateRabbitmqUrl(creds) {
|
|
92
|
-
const { username, password, host, port, vhost } = creds;
|
|
93
|
-
const encodedVhost = encodeURIComponent(vhost ?? "/");
|
|
94
|
-
return `amqp://${username}:${encodeURIComponent(password)}@${host}:${port}/${encodedVhost}`;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Generate endpoint URL for MinIO (S3-compatible).
|
|
98
|
-
*/
|
|
99
|
-
function generateMinioEndpoint(creds) {
|
|
100
|
-
const { host, port } = creds;
|
|
101
|
-
return `http://${host}:${port}`;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Generate a LocalStack-compatible access key ID.
|
|
105
|
-
* Must start with 'LSIA' prefix and be at least 20 characters.
|
|
106
|
-
* @see https://docs.localstack.cloud/aws/capabilities/config/credentials/
|
|
107
|
-
*/
|
|
108
|
-
function generateLocalStackAccessKeyId() {
|
|
109
|
-
const suffix = (0, node_crypto.randomBytes)(12).toString("base64url").slice(0, 16);
|
|
110
|
-
return `LSIA${suffix}`;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Generate connection URL for pg-boss (uses PostgreSQL protocol).
|
|
114
|
-
* Format: pgboss://user:pass@host:port/db?schema=pgboss
|
|
115
|
-
*/
|
|
116
|
-
function generatePgBossUrl(creds) {
|
|
117
|
-
const { username, password, host, port, database } = creds;
|
|
118
|
-
return `pgboss://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}?schema=pgboss`;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Generate event connection strings based on the events backend.
|
|
122
|
-
*/
|
|
123
|
-
function generateEventConnectionStrings(eventsBackend, services) {
|
|
124
|
-
switch (eventsBackend) {
|
|
125
|
-
case "pgboss": {
|
|
126
|
-
const creds = services.pgboss;
|
|
127
|
-
if (!creds) throw new Error("pgboss credentials required for pgboss events");
|
|
128
|
-
const url = generatePgBossUrl(creds);
|
|
129
|
-
return {
|
|
130
|
-
publisher: url,
|
|
131
|
-
subscriber: url
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
case "sns": {
|
|
135
|
-
const creds = services.localstack;
|
|
136
|
-
if (!creds) throw new Error("localstack credentials required for sns events");
|
|
137
|
-
const endpoint = `http://${creds.host}:${creds.port}`;
|
|
138
|
-
const region = creds.region ?? "us-east-1";
|
|
139
|
-
const accessKeyId = creds.accessKeyId ?? creds.username;
|
|
140
|
-
const secretKey = encodeURIComponent(creds.password);
|
|
141
|
-
return {
|
|
142
|
-
publisher: `sns://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`,
|
|
143
|
-
subscriber: `sqs://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
case "rabbitmq": {
|
|
147
|
-
const creds = services.rabbitmq;
|
|
148
|
-
if (!creds) throw new Error("rabbitmq credentials required for rabbitmq events");
|
|
149
|
-
const url = generateRabbitmqUrl(creds);
|
|
150
|
-
return {
|
|
151
|
-
publisher: url,
|
|
152
|
-
subscriber: url
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Generate connection URLs from service credentials.
|
|
159
|
-
*/
|
|
160
|
-
function generateConnectionUrls(services, eventsBackend) {
|
|
161
|
-
const urls = {};
|
|
162
|
-
if (services.postgres) urls.DATABASE_URL = generatePostgresUrl(services.postgres);
|
|
163
|
-
if (services.redis) urls.REDIS_URL = generateRedisUrl(services.redis);
|
|
164
|
-
if (services.rabbitmq) urls.RABBITMQ_URL = generateRabbitmqUrl(services.rabbitmq);
|
|
165
|
-
if (services.minio) urls.STORAGE_ENDPOINT = generateMinioEndpoint(services.minio);
|
|
166
|
-
if (eventsBackend) {
|
|
167
|
-
const eventUrls = generateEventConnectionStrings(eventsBackend, services);
|
|
168
|
-
urls.EVENT_PUBLISHER_CONNECTION_STRING = eventUrls.publisher;
|
|
169
|
-
urls.EVENT_SUBSCRIBER_CONNECTION_STRING = eventUrls.subscriber;
|
|
170
|
-
} else if (services.pgboss) {
|
|
171
|
-
const pgbossUrl = generatePgBossUrl(services.pgboss);
|
|
172
|
-
urls.EVENT_PUBLISHER_CONNECTION_STRING = pgbossUrl;
|
|
173
|
-
urls.EVENT_SUBSCRIBER_CONNECTION_STRING = pgbossUrl;
|
|
174
|
-
}
|
|
175
|
-
if (services.mailpit) {
|
|
176
|
-
urls.SMTP_HOST = services.mailpit.host;
|
|
177
|
-
urls.SMTP_PORT = String(services.mailpit.port);
|
|
178
|
-
}
|
|
179
|
-
return urls;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Generate LocalStack service credentials with LSIA-prefixed access key.
|
|
183
|
-
*/
|
|
184
|
-
function generateLocalStackCredentials() {
|
|
185
|
-
const defaults = SERVICE_DEFAULTS.localstack;
|
|
186
|
-
return {
|
|
187
|
-
...defaults,
|
|
188
|
-
password: generateSecurePassword(),
|
|
189
|
-
accessKeyId: generateLocalStackAccessKeyId()
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Create a new StageSecrets object with generated credentials.
|
|
194
|
-
* @param stage - The deployment stage (e.g., 'development', 'production')
|
|
195
|
-
* @param services - List of services to generate credentials for
|
|
196
|
-
* @param options - Optional configuration
|
|
197
|
-
* @param options.projectName - Project name used to derive the database name (e.g., 'myapp' → 'myapp_dev')
|
|
198
|
-
* @param options.eventsBackend - Event backend type (pgboss, sns, rabbitmq)
|
|
199
|
-
*/
|
|
200
|
-
function createStageSecrets(stage, services, options) {
|
|
201
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
202
|
-
const serviceCredentials = generateServicesCredentials(services);
|
|
203
|
-
if (options?.projectName) {
|
|
204
|
-
if (serviceCredentials.postgres) serviceCredentials.postgres.database = `${options.projectName.replace(/-/g, "_")}_dev`;
|
|
205
|
-
if (serviceCredentials.minio) {
|
|
206
|
-
serviceCredentials.minio.bucket = options.projectName;
|
|
207
|
-
serviceCredentials.minio.username = options.projectName;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (serviceCredentials.postgres && !serviceCredentials.pgboss) serviceCredentials.pgboss = {
|
|
211
|
-
...PGBOSS_DEFAULTS,
|
|
212
|
-
password: generateSecurePassword(),
|
|
213
|
-
host: serviceCredentials.postgres.host,
|
|
214
|
-
port: serviceCredentials.postgres.port,
|
|
215
|
-
database: serviceCredentials.postgres.database
|
|
216
|
-
};
|
|
217
|
-
const eventsBackend = options?.eventsBackend;
|
|
218
|
-
if (eventsBackend === "sns") serviceCredentials.localstack = generateLocalStackCredentials();
|
|
219
|
-
const urls = generateConnectionUrls(serviceCredentials, eventsBackend);
|
|
220
|
-
return {
|
|
221
|
-
stage,
|
|
222
|
-
createdAt: now,
|
|
223
|
-
updatedAt: now,
|
|
224
|
-
eventsBackend,
|
|
225
|
-
services: serviceCredentials,
|
|
226
|
-
urls,
|
|
227
|
-
custom: {}
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Rotate password for a specific service.
|
|
232
|
-
*/
|
|
233
|
-
function rotateServicePassword(secrets, service) {
|
|
234
|
-
const currentCreds = secrets.services[service];
|
|
235
|
-
if (!currentCreds) throw new Error(`Service "${service}" not configured in secrets`);
|
|
236
|
-
const newCreds = {
|
|
237
|
-
...currentCreds,
|
|
238
|
-
password: generateSecurePassword()
|
|
239
|
-
};
|
|
240
|
-
const newServices = {
|
|
241
|
-
...secrets.services,
|
|
242
|
-
[service]: newCreds
|
|
243
|
-
};
|
|
244
|
-
return {
|
|
245
|
-
...secrets,
|
|
246
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
247
|
-
services: newServices,
|
|
248
|
-
urls: generateConnectionUrls(newServices, secrets.eventsBackend)
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
//#endregion
|
|
253
|
-
Object.defineProperty(exports, 'createStageSecrets', {
|
|
254
|
-
enumerable: true,
|
|
255
|
-
get: function () {
|
|
256
|
-
return createStageSecrets;
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
Object.defineProperty(exports, 'generateConnectionUrls', {
|
|
260
|
-
enumerable: true,
|
|
261
|
-
get: function () {
|
|
262
|
-
return generateConnectionUrls;
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
Object.defineProperty(exports, 'generatePgBossUrl', {
|
|
266
|
-
enumerable: true,
|
|
267
|
-
get: function () {
|
|
268
|
-
return generatePgBossUrl;
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
Object.defineProperty(exports, 'generateSecurePassword', {
|
|
272
|
-
enumerable: true,
|
|
273
|
-
get: function () {
|
|
274
|
-
return generateSecurePassword;
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
Object.defineProperty(exports, 'generateServiceCredentials', {
|
|
278
|
-
enumerable: true,
|
|
279
|
-
get: function () {
|
|
280
|
-
return generateServiceCredentials;
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
Object.defineProperty(exports, 'rotateServicePassword', {
|
|
284
|
-
enumerable: true,
|
|
285
|
-
get: function () {
|
|
286
|
-
return rotateServicePassword;
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
//# sourceMappingURL=generator-CNzBw7g5.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generator-CNzBw7g5.cjs","names":["SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n>","PGBOSS_DEFAULTS: Omit<ServiceCredentials, 'password'>","service: ComposeServiceName","services: ComposeServiceName[]","result: StageSecrets['services']","creds: ServiceCredentials","eventsBackend: EventsBackend","services: StageSecrets['services']","eventsBackend?: EventsBackend","urls: StageSecrets['urls']","stage: string","options?: { projectName?: string; eventsBackend?: EventsBackend }","secrets: StageSecrets","newCreds: ServiceCredentials"],"sources":["../src/secrets/generator.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport type { ComposeServiceName, EventsBackend } from '../types';\nimport type { ServiceCredentials, StageSecrets } from './types';\n\n/**\n * Generate a secure random password using URL-safe base64 characters.\n * @param length Password length (default: 32)\n */\nexport function generateSecurePassword(length = 32): string {\n\treturn randomBytes(Math.ceil((length * 3) / 4))\n\t\t.toString('base64url')\n\t\t.slice(0, length);\n}\n\n/** Default service configurations (localhost for local dev via Docker port mapping) */\nconst SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n> = {\n\tpostgres: {\n\t\thost: 'localhost',\n\t\tport: 5432,\n\t\tusername: 'app',\n\t\tdatabase: 'app',\n\t},\n\tredis: {\n\t\thost: 'localhost',\n\t\tport: 6379,\n\t\tusername: 'default',\n\t},\n\trabbitmq: {\n\t\thost: 'localhost',\n\t\tport: 5672,\n\t\tusername: 'app',\n\t\tvhost: '/',\n\t},\n\tminio: {\n\t\thost: 'localhost',\n\t\tport: 9000,\n\t\tusername: 'app',\n\t\tbucket: 'app',\n\t},\n\tmailpit: {\n\t\thost: 'localhost',\n\t\tport: 1025,\n\t\tusername: 'app',\n\t},\n\tlocalstack: {\n\t\thost: 'localhost',\n\t\tport: 4566,\n\t\tusername: 'localstack',\n\t\tregion: 'us-east-1',\n\t},\n};\n\n/** Default credentials for pgboss (not a Docker service, reuses postgres) */\nconst PGBOSS_DEFAULTS: Omit<ServiceCredentials, 'password'> = {\n\thost: 'localhost',\n\tport: 5432,\n\tusername: 'pgboss',\n\tdatabase: 'app',\n};\n\n/**\n * Generate credentials for a specific service.\n */\nexport function generateServiceCredentials(\n\tservice: ComposeServiceName,\n): ServiceCredentials {\n\tconst defaults = SERVICE_DEFAULTS[service];\n\treturn {\n\t\t...defaults,\n\t\tpassword: generateSecurePassword(),\n\t};\n}\n\n/**\n * Generate credentials for multiple services.\n */\nexport function generateServicesCredentials(\n\tservices: ComposeServiceName[],\n): StageSecrets['services'] {\n\tconst result: StageSecrets['services'] = {};\n\n\tfor (const service of services) {\n\t\tresult[service] = generateServiceCredentials(service);\n\t}\n\n\treturn result;\n}\n\n/**\n * Generate connection URL for PostgreSQL.\n */\nexport function generatePostgresUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, database } = creds;\n\treturn `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;\n}\n\n/**\n * Generate connection URL for Redis.\n */\nexport function generateRedisUrl(creds: ServiceCredentials): string {\n\tconst { password, host, port } = creds;\n\treturn `redis://:${encodeURIComponent(password)}@${host}:${port}`;\n}\n\n/**\n * Generate connection URL for RabbitMQ.\n */\nexport function generateRabbitmqUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, vhost } = creds;\n\tconst encodedVhost = encodeURIComponent(vhost ?? '/');\n\treturn `amqp://${username}:${encodeURIComponent(password)}@${host}:${port}/${encodedVhost}`;\n}\n\n/**\n * Generate endpoint URL for MinIO (S3-compatible).\n */\nexport function generateMinioEndpoint(creds: ServiceCredentials): string {\n\tconst { host, port } = creds;\n\treturn `http://${host}:${port}`;\n}\n\n/**\n * Generate a LocalStack-compatible access key ID.\n * Must start with 'LSIA' prefix and be at least 20 characters.\n * @see https://docs.localstack.cloud/aws/capabilities/config/credentials/\n */\nexport function generateLocalStackAccessKeyId(): string {\n\tconst suffix = randomBytes(12).toString('base64url').slice(0, 16);\n\treturn `LSIA${suffix}`;\n}\n\n/**\n * Generate connection URL for pg-boss (uses PostgreSQL protocol).\n * Format: pgboss://user:pass@host:port/db?schema=pgboss\n */\nexport function generatePgBossUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, database } = creds;\n\treturn `pgboss://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}?schema=pgboss`;\n}\n\n/**\n * Generate event connection strings based on the events backend.\n */\nexport function generateEventConnectionStrings(\n\teventsBackend: EventsBackend,\n\tservices: StageSecrets['services'],\n): { publisher: string; subscriber: string } {\n\tswitch (eventsBackend) {\n\t\tcase 'pgboss': {\n\t\t\tconst creds = services.pgboss;\n\t\t\tif (!creds) {\n\t\t\t\tthrow new Error('pgboss credentials required for pgboss events');\n\t\t\t}\n\t\t\tconst url = generatePgBossUrl(creds);\n\t\t\treturn { publisher: url, subscriber: url };\n\t\t}\n\t\tcase 'sns': {\n\t\t\tconst creds = services.localstack;\n\t\t\tif (!creds) {\n\t\t\t\tthrow new Error('localstack credentials required for sns events');\n\t\t\t}\n\t\t\tconst endpoint = `http://${creds.host}:${creds.port}`;\n\t\t\tconst region = creds.region ?? 'us-east-1';\n\t\t\tconst accessKeyId = creds.accessKeyId ?? creds.username;\n\t\t\tconst secretKey = encodeURIComponent(creds.password);\n\t\t\treturn {\n\t\t\t\tpublisher: `sns://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`,\n\t\t\t\tsubscriber: `sqs://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`,\n\t\t\t};\n\t\t}\n\t\tcase 'rabbitmq': {\n\t\t\tconst creds = services.rabbitmq;\n\t\t\tif (!creds) {\n\t\t\t\tthrow new Error('rabbitmq credentials required for rabbitmq events');\n\t\t\t}\n\t\t\tconst url = generateRabbitmqUrl(creds);\n\t\t\treturn { publisher: url, subscriber: url };\n\t\t}\n\t}\n}\n\n/**\n * Generate connection URLs from service credentials.\n */\nexport function generateConnectionUrls(\n\tservices: StageSecrets['services'],\n\teventsBackend?: EventsBackend,\n): StageSecrets['urls'] {\n\tconst urls: StageSecrets['urls'] = {};\n\n\tif (services.postgres) {\n\t\turls.DATABASE_URL = generatePostgresUrl(services.postgres);\n\t}\n\n\tif (services.redis) {\n\t\turls.REDIS_URL = generateRedisUrl(services.redis);\n\t}\n\n\tif (services.rabbitmq) {\n\t\turls.RABBITMQ_URL = generateRabbitmqUrl(services.rabbitmq);\n\t}\n\n\tif (services.minio) {\n\t\turls.STORAGE_ENDPOINT = generateMinioEndpoint(services.minio);\n\t}\n\n\tif (eventsBackend) {\n\t\tconst eventUrls = generateEventConnectionStrings(eventsBackend, services);\n\t\turls.EVENT_PUBLISHER_CONNECTION_STRING = eventUrls.publisher;\n\t\turls.EVENT_SUBSCRIBER_CONNECTION_STRING = eventUrls.subscriber;\n\t} else if (services.pgboss) {\n\t\t// Default to pgboss when credentials exist but no explicit events backend\n\t\tconst pgbossUrl = generatePgBossUrl(services.pgboss);\n\t\turls.EVENT_PUBLISHER_CONNECTION_STRING = pgbossUrl;\n\t\turls.EVENT_SUBSCRIBER_CONNECTION_STRING = pgbossUrl;\n\t}\n\n\tif (services.mailpit) {\n\t\turls.SMTP_HOST = services.mailpit.host;\n\t\turls.SMTP_PORT = String(services.mailpit.port);\n\t}\n\n\treturn urls;\n}\n\n/**\n * Generate LocalStack service credentials with LSIA-prefixed access key.\n */\nexport function generateLocalStackCredentials(): ServiceCredentials {\n\tconst defaults = SERVICE_DEFAULTS.localstack;\n\treturn {\n\t\t...defaults,\n\t\tpassword: generateSecurePassword(),\n\t\taccessKeyId: generateLocalStackAccessKeyId(),\n\t};\n}\n\n/**\n * Create a new StageSecrets object with generated credentials.\n * @param stage - The deployment stage (e.g., 'development', 'production')\n * @param services - List of services to generate credentials for\n * @param options - Optional configuration\n * @param options.projectName - Project name used to derive the database name (e.g., 'myapp' → 'myapp_dev')\n * @param options.eventsBackend - Event backend type (pgboss, sns, rabbitmq)\n */\nexport function createStageSecrets(\n\tstage: string,\n\tservices: ComposeServiceName[],\n\toptions?: { projectName?: string; eventsBackend?: EventsBackend },\n): StageSecrets {\n\tconst now = new Date().toISOString();\n\tconst serviceCredentials = generateServicesCredentials(services);\n\n\t// Override service defaults with project-derived names if provided\n\tif (options?.projectName) {\n\t\tif (serviceCredentials.postgres) {\n\t\t\tserviceCredentials.postgres.database = `${options.projectName.replace(/-/g, '_')}_dev`;\n\t\t}\n\t\tif (serviceCredentials.minio) {\n\t\t\tserviceCredentials.minio.bucket = options.projectName;\n\t\t\tserviceCredentials.minio.username = options.projectName;\n\t\t}\n\t}\n\n\t// Always create pgboss credentials when postgres is available.\n\t// pgboss reuses postgres host/port/database but with a dedicated user,\n\t// so subscribers work out of the box without explicit events config.\n\tif (serviceCredentials.postgres && !serviceCredentials.pgboss) {\n\t\tserviceCredentials.pgboss = {\n\t\t\t...PGBOSS_DEFAULTS,\n\t\t\tpassword: generateSecurePassword(),\n\t\t\thost: serviceCredentials.postgres.host,\n\t\t\tport: serviceCredentials.postgres.port,\n\t\t\tdatabase: serviceCredentials.postgres.database,\n\t\t};\n\t}\n\n\t// Generate event-specific credentials\n\tconst eventsBackend = options?.eventsBackend;\n\tif (eventsBackend === 'sns') {\n\t\t// LocalStack credentials with LSIA-prefixed access key\n\t\tserviceCredentials.localstack = generateLocalStackCredentials();\n\t}\n\n\tconst urls = generateConnectionUrls(serviceCredentials, eventsBackend);\n\n\treturn {\n\t\tstage,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\teventsBackend,\n\t\tservices: serviceCredentials,\n\t\turls,\n\t\tcustom: {},\n\t};\n}\n\n/**\n * Rotate password for a specific service.\n */\nexport function rotateServicePassword(\n\tsecrets: StageSecrets,\n\tservice: ComposeServiceName,\n): StageSecrets {\n\tconst currentCreds = secrets.services[service];\n\tif (!currentCreds) {\n\t\tthrow new Error(`Service \"${service}\" not configured in secrets`);\n\t}\n\n\tconst newCreds: ServiceCredentials = {\n\t\t...currentCreds,\n\t\tpassword: generateSecurePassword(),\n\t};\n\n\tconst newServices = {\n\t\t...secrets.services,\n\t\t[service]: newCreds,\n\t};\n\n\treturn {\n\t\t...secrets,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tservices: newServices,\n\t\turls: generateConnectionUrls(newServices, secrets.eventsBackend),\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
import { randomBytes } from "node:crypto";
|
|
2
|
-
|
|
3
|
-
//#region src/secrets/generator.ts
|
|
4
|
-
/**
|
|
5
|
-
* Generate a secure random password using URL-safe base64 characters.
|
|
6
|
-
* @param length Password length (default: 32)
|
|
7
|
-
*/
|
|
8
|
-
function generateSecurePassword(length = 32) {
|
|
9
|
-
return randomBytes(Math.ceil(length * 3 / 4)).toString("base64url").slice(0, length);
|
|
10
|
-
}
|
|
11
|
-
/** Default service configurations (localhost for local dev via Docker port mapping) */
|
|
12
|
-
const SERVICE_DEFAULTS = {
|
|
13
|
-
postgres: {
|
|
14
|
-
host: "localhost",
|
|
15
|
-
port: 5432,
|
|
16
|
-
username: "app",
|
|
17
|
-
database: "app"
|
|
18
|
-
},
|
|
19
|
-
redis: {
|
|
20
|
-
host: "localhost",
|
|
21
|
-
port: 6379,
|
|
22
|
-
username: "default"
|
|
23
|
-
},
|
|
24
|
-
rabbitmq: {
|
|
25
|
-
host: "localhost",
|
|
26
|
-
port: 5672,
|
|
27
|
-
username: "app",
|
|
28
|
-
vhost: "/"
|
|
29
|
-
},
|
|
30
|
-
minio: {
|
|
31
|
-
host: "localhost",
|
|
32
|
-
port: 9e3,
|
|
33
|
-
username: "app",
|
|
34
|
-
bucket: "app"
|
|
35
|
-
},
|
|
36
|
-
mailpit: {
|
|
37
|
-
host: "localhost",
|
|
38
|
-
port: 1025,
|
|
39
|
-
username: "app"
|
|
40
|
-
},
|
|
41
|
-
localstack: {
|
|
42
|
-
host: "localhost",
|
|
43
|
-
port: 4566,
|
|
44
|
-
username: "localstack",
|
|
45
|
-
region: "us-east-1"
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
/** Default credentials for pgboss (not a Docker service, reuses postgres) */
|
|
49
|
-
const PGBOSS_DEFAULTS = {
|
|
50
|
-
host: "localhost",
|
|
51
|
-
port: 5432,
|
|
52
|
-
username: "pgboss",
|
|
53
|
-
database: "app"
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* Generate credentials for a specific service.
|
|
57
|
-
*/
|
|
58
|
-
function generateServiceCredentials(service) {
|
|
59
|
-
const defaults = SERVICE_DEFAULTS[service];
|
|
60
|
-
return {
|
|
61
|
-
...defaults,
|
|
62
|
-
password: generateSecurePassword()
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Generate credentials for multiple services.
|
|
67
|
-
*/
|
|
68
|
-
function generateServicesCredentials(services) {
|
|
69
|
-
const result = {};
|
|
70
|
-
for (const service of services) result[service] = generateServiceCredentials(service);
|
|
71
|
-
return result;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Generate connection URL for PostgreSQL.
|
|
75
|
-
*/
|
|
76
|
-
function generatePostgresUrl(creds) {
|
|
77
|
-
const { username, password, host, port, database } = creds;
|
|
78
|
-
return `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Generate connection URL for Redis.
|
|
82
|
-
*/
|
|
83
|
-
function generateRedisUrl(creds) {
|
|
84
|
-
const { password, host, port } = creds;
|
|
85
|
-
return `redis://:${encodeURIComponent(password)}@${host}:${port}`;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Generate connection URL for RabbitMQ.
|
|
89
|
-
*/
|
|
90
|
-
function generateRabbitmqUrl(creds) {
|
|
91
|
-
const { username, password, host, port, vhost } = creds;
|
|
92
|
-
const encodedVhost = encodeURIComponent(vhost ?? "/");
|
|
93
|
-
return `amqp://${username}:${encodeURIComponent(password)}@${host}:${port}/${encodedVhost}`;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Generate endpoint URL for MinIO (S3-compatible).
|
|
97
|
-
*/
|
|
98
|
-
function generateMinioEndpoint(creds) {
|
|
99
|
-
const { host, port } = creds;
|
|
100
|
-
return `http://${host}:${port}`;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Generate a LocalStack-compatible access key ID.
|
|
104
|
-
* Must start with 'LSIA' prefix and be at least 20 characters.
|
|
105
|
-
* @see https://docs.localstack.cloud/aws/capabilities/config/credentials/
|
|
106
|
-
*/
|
|
107
|
-
function generateLocalStackAccessKeyId() {
|
|
108
|
-
const suffix = randomBytes(12).toString("base64url").slice(0, 16);
|
|
109
|
-
return `LSIA${suffix}`;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Generate connection URL for pg-boss (uses PostgreSQL protocol).
|
|
113
|
-
* Format: pgboss://user:pass@host:port/db?schema=pgboss
|
|
114
|
-
*/
|
|
115
|
-
function generatePgBossUrl(creds) {
|
|
116
|
-
const { username, password, host, port, database } = creds;
|
|
117
|
-
return `pgboss://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}?schema=pgboss`;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Generate event connection strings based on the events backend.
|
|
121
|
-
*/
|
|
122
|
-
function generateEventConnectionStrings(eventsBackend, services) {
|
|
123
|
-
switch (eventsBackend) {
|
|
124
|
-
case "pgboss": {
|
|
125
|
-
const creds = services.pgboss;
|
|
126
|
-
if (!creds) throw new Error("pgboss credentials required for pgboss events");
|
|
127
|
-
const url = generatePgBossUrl(creds);
|
|
128
|
-
return {
|
|
129
|
-
publisher: url,
|
|
130
|
-
subscriber: url
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
case "sns": {
|
|
134
|
-
const creds = services.localstack;
|
|
135
|
-
if (!creds) throw new Error("localstack credentials required for sns events");
|
|
136
|
-
const endpoint = `http://${creds.host}:${creds.port}`;
|
|
137
|
-
const region = creds.region ?? "us-east-1";
|
|
138
|
-
const accessKeyId = creds.accessKeyId ?? creds.username;
|
|
139
|
-
const secretKey = encodeURIComponent(creds.password);
|
|
140
|
-
return {
|
|
141
|
-
publisher: `sns://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`,
|
|
142
|
-
subscriber: `sqs://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
case "rabbitmq": {
|
|
146
|
-
const creds = services.rabbitmq;
|
|
147
|
-
if (!creds) throw new Error("rabbitmq credentials required for rabbitmq events");
|
|
148
|
-
const url = generateRabbitmqUrl(creds);
|
|
149
|
-
return {
|
|
150
|
-
publisher: url,
|
|
151
|
-
subscriber: url
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Generate connection URLs from service credentials.
|
|
158
|
-
*/
|
|
159
|
-
function generateConnectionUrls(services, eventsBackend) {
|
|
160
|
-
const urls = {};
|
|
161
|
-
if (services.postgres) urls.DATABASE_URL = generatePostgresUrl(services.postgres);
|
|
162
|
-
if (services.redis) urls.REDIS_URL = generateRedisUrl(services.redis);
|
|
163
|
-
if (services.rabbitmq) urls.RABBITMQ_URL = generateRabbitmqUrl(services.rabbitmq);
|
|
164
|
-
if (services.minio) urls.STORAGE_ENDPOINT = generateMinioEndpoint(services.minio);
|
|
165
|
-
if (eventsBackend) {
|
|
166
|
-
const eventUrls = generateEventConnectionStrings(eventsBackend, services);
|
|
167
|
-
urls.EVENT_PUBLISHER_CONNECTION_STRING = eventUrls.publisher;
|
|
168
|
-
urls.EVENT_SUBSCRIBER_CONNECTION_STRING = eventUrls.subscriber;
|
|
169
|
-
} else if (services.pgboss) {
|
|
170
|
-
const pgbossUrl = generatePgBossUrl(services.pgboss);
|
|
171
|
-
urls.EVENT_PUBLISHER_CONNECTION_STRING = pgbossUrl;
|
|
172
|
-
urls.EVENT_SUBSCRIBER_CONNECTION_STRING = pgbossUrl;
|
|
173
|
-
}
|
|
174
|
-
if (services.mailpit) {
|
|
175
|
-
urls.SMTP_HOST = services.mailpit.host;
|
|
176
|
-
urls.SMTP_PORT = String(services.mailpit.port);
|
|
177
|
-
}
|
|
178
|
-
return urls;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Generate LocalStack service credentials with LSIA-prefixed access key.
|
|
182
|
-
*/
|
|
183
|
-
function generateLocalStackCredentials() {
|
|
184
|
-
const defaults = SERVICE_DEFAULTS.localstack;
|
|
185
|
-
return {
|
|
186
|
-
...defaults,
|
|
187
|
-
password: generateSecurePassword(),
|
|
188
|
-
accessKeyId: generateLocalStackAccessKeyId()
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Create a new StageSecrets object with generated credentials.
|
|
193
|
-
* @param stage - The deployment stage (e.g., 'development', 'production')
|
|
194
|
-
* @param services - List of services to generate credentials for
|
|
195
|
-
* @param options - Optional configuration
|
|
196
|
-
* @param options.projectName - Project name used to derive the database name (e.g., 'myapp' → 'myapp_dev')
|
|
197
|
-
* @param options.eventsBackend - Event backend type (pgboss, sns, rabbitmq)
|
|
198
|
-
*/
|
|
199
|
-
function createStageSecrets(stage, services, options) {
|
|
200
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
201
|
-
const serviceCredentials = generateServicesCredentials(services);
|
|
202
|
-
if (options?.projectName) {
|
|
203
|
-
if (serviceCredentials.postgres) serviceCredentials.postgres.database = `${options.projectName.replace(/-/g, "_")}_dev`;
|
|
204
|
-
if (serviceCredentials.minio) {
|
|
205
|
-
serviceCredentials.minio.bucket = options.projectName;
|
|
206
|
-
serviceCredentials.minio.username = options.projectName;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
if (serviceCredentials.postgres && !serviceCredentials.pgboss) serviceCredentials.pgboss = {
|
|
210
|
-
...PGBOSS_DEFAULTS,
|
|
211
|
-
password: generateSecurePassword(),
|
|
212
|
-
host: serviceCredentials.postgres.host,
|
|
213
|
-
port: serviceCredentials.postgres.port,
|
|
214
|
-
database: serviceCredentials.postgres.database
|
|
215
|
-
};
|
|
216
|
-
const eventsBackend = options?.eventsBackend;
|
|
217
|
-
if (eventsBackend === "sns") serviceCredentials.localstack = generateLocalStackCredentials();
|
|
218
|
-
const urls = generateConnectionUrls(serviceCredentials, eventsBackend);
|
|
219
|
-
return {
|
|
220
|
-
stage,
|
|
221
|
-
createdAt: now,
|
|
222
|
-
updatedAt: now,
|
|
223
|
-
eventsBackend,
|
|
224
|
-
services: serviceCredentials,
|
|
225
|
-
urls,
|
|
226
|
-
custom: {}
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Rotate password for a specific service.
|
|
231
|
-
*/
|
|
232
|
-
function rotateServicePassword(secrets, service) {
|
|
233
|
-
const currentCreds = secrets.services[service];
|
|
234
|
-
if (!currentCreds) throw new Error(`Service "${service}" not configured in secrets`);
|
|
235
|
-
const newCreds = {
|
|
236
|
-
...currentCreds,
|
|
237
|
-
password: generateSecurePassword()
|
|
238
|
-
};
|
|
239
|
-
const newServices = {
|
|
240
|
-
...secrets.services,
|
|
241
|
-
[service]: newCreds
|
|
242
|
-
};
|
|
243
|
-
return {
|
|
244
|
-
...secrets,
|
|
245
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
246
|
-
services: newServices,
|
|
247
|
-
urls: generateConnectionUrls(newServices, secrets.eventsBackend)
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
//#endregion
|
|
252
|
-
export { createStageSecrets, generateConnectionUrls, generatePgBossUrl, generateSecurePassword, generateServiceCredentials, rotateServicePassword };
|
|
253
|
-
//# sourceMappingURL=generator-VE2JrFlY.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generator-VE2JrFlY.mjs","names":["SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n>","PGBOSS_DEFAULTS: Omit<ServiceCredentials, 'password'>","service: ComposeServiceName","services: ComposeServiceName[]","result: StageSecrets['services']","creds: ServiceCredentials","eventsBackend: EventsBackend","services: StageSecrets['services']","eventsBackend?: EventsBackend","urls: StageSecrets['urls']","stage: string","options?: { projectName?: string; eventsBackend?: EventsBackend }","secrets: StageSecrets","newCreds: ServiceCredentials"],"sources":["../src/secrets/generator.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport type { ComposeServiceName, EventsBackend } from '../types';\nimport type { ServiceCredentials, StageSecrets } from './types';\n\n/**\n * Generate a secure random password using URL-safe base64 characters.\n * @param length Password length (default: 32)\n */\nexport function generateSecurePassword(length = 32): string {\n\treturn randomBytes(Math.ceil((length * 3) / 4))\n\t\t.toString('base64url')\n\t\t.slice(0, length);\n}\n\n/** Default service configurations (localhost for local dev via Docker port mapping) */\nconst SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n> = {\n\tpostgres: {\n\t\thost: 'localhost',\n\t\tport: 5432,\n\t\tusername: 'app',\n\t\tdatabase: 'app',\n\t},\n\tredis: {\n\t\thost: 'localhost',\n\t\tport: 6379,\n\t\tusername: 'default',\n\t},\n\trabbitmq: {\n\t\thost: 'localhost',\n\t\tport: 5672,\n\t\tusername: 'app',\n\t\tvhost: '/',\n\t},\n\tminio: {\n\t\thost: 'localhost',\n\t\tport: 9000,\n\t\tusername: 'app',\n\t\tbucket: 'app',\n\t},\n\tmailpit: {\n\t\thost: 'localhost',\n\t\tport: 1025,\n\t\tusername: 'app',\n\t},\n\tlocalstack: {\n\t\thost: 'localhost',\n\t\tport: 4566,\n\t\tusername: 'localstack',\n\t\tregion: 'us-east-1',\n\t},\n};\n\n/** Default credentials for pgboss (not a Docker service, reuses postgres) */\nconst PGBOSS_DEFAULTS: Omit<ServiceCredentials, 'password'> = {\n\thost: 'localhost',\n\tport: 5432,\n\tusername: 'pgboss',\n\tdatabase: 'app',\n};\n\n/**\n * Generate credentials for a specific service.\n */\nexport function generateServiceCredentials(\n\tservice: ComposeServiceName,\n): ServiceCredentials {\n\tconst defaults = SERVICE_DEFAULTS[service];\n\treturn {\n\t\t...defaults,\n\t\tpassword: generateSecurePassword(),\n\t};\n}\n\n/**\n * Generate credentials for multiple services.\n */\nexport function generateServicesCredentials(\n\tservices: ComposeServiceName[],\n): StageSecrets['services'] {\n\tconst result: StageSecrets['services'] = {};\n\n\tfor (const service of services) {\n\t\tresult[service] = generateServiceCredentials(service);\n\t}\n\n\treturn result;\n}\n\n/**\n * Generate connection URL for PostgreSQL.\n */\nexport function generatePostgresUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, database } = creds;\n\treturn `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;\n}\n\n/**\n * Generate connection URL for Redis.\n */\nexport function generateRedisUrl(creds: ServiceCredentials): string {\n\tconst { password, host, port } = creds;\n\treturn `redis://:${encodeURIComponent(password)}@${host}:${port}`;\n}\n\n/**\n * Generate connection URL for RabbitMQ.\n */\nexport function generateRabbitmqUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, vhost } = creds;\n\tconst encodedVhost = encodeURIComponent(vhost ?? '/');\n\treturn `amqp://${username}:${encodeURIComponent(password)}@${host}:${port}/${encodedVhost}`;\n}\n\n/**\n * Generate endpoint URL for MinIO (S3-compatible).\n */\nexport function generateMinioEndpoint(creds: ServiceCredentials): string {\n\tconst { host, port } = creds;\n\treturn `http://${host}:${port}`;\n}\n\n/**\n * Generate a LocalStack-compatible access key ID.\n * Must start with 'LSIA' prefix and be at least 20 characters.\n * @see https://docs.localstack.cloud/aws/capabilities/config/credentials/\n */\nexport function generateLocalStackAccessKeyId(): string {\n\tconst suffix = randomBytes(12).toString('base64url').slice(0, 16);\n\treturn `LSIA${suffix}`;\n}\n\n/**\n * Generate connection URL for pg-boss (uses PostgreSQL protocol).\n * Format: pgboss://user:pass@host:port/db?schema=pgboss\n */\nexport function generatePgBossUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, database } = creds;\n\treturn `pgboss://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}?schema=pgboss`;\n}\n\n/**\n * Generate event connection strings based on the events backend.\n */\nexport function generateEventConnectionStrings(\n\teventsBackend: EventsBackend,\n\tservices: StageSecrets['services'],\n): { publisher: string; subscriber: string } {\n\tswitch (eventsBackend) {\n\t\tcase 'pgboss': {\n\t\t\tconst creds = services.pgboss;\n\t\t\tif (!creds) {\n\t\t\t\tthrow new Error('pgboss credentials required for pgboss events');\n\t\t\t}\n\t\t\tconst url = generatePgBossUrl(creds);\n\t\t\treturn { publisher: url, subscriber: url };\n\t\t}\n\t\tcase 'sns': {\n\t\t\tconst creds = services.localstack;\n\t\t\tif (!creds) {\n\t\t\t\tthrow new Error('localstack credentials required for sns events');\n\t\t\t}\n\t\t\tconst endpoint = `http://${creds.host}:${creds.port}`;\n\t\t\tconst region = creds.region ?? 'us-east-1';\n\t\t\tconst accessKeyId = creds.accessKeyId ?? creds.username;\n\t\t\tconst secretKey = encodeURIComponent(creds.password);\n\t\t\treturn {\n\t\t\t\tpublisher: `sns://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`,\n\t\t\t\tsubscriber: `sqs://${accessKeyId}:${secretKey}@${creds.host}:${creds.port}?region=${region}&endpoint=${encodeURIComponent(endpoint)}`,\n\t\t\t};\n\t\t}\n\t\tcase 'rabbitmq': {\n\t\t\tconst creds = services.rabbitmq;\n\t\t\tif (!creds) {\n\t\t\t\tthrow new Error('rabbitmq credentials required for rabbitmq events');\n\t\t\t}\n\t\t\tconst url = generateRabbitmqUrl(creds);\n\t\t\treturn { publisher: url, subscriber: url };\n\t\t}\n\t}\n}\n\n/**\n * Generate connection URLs from service credentials.\n */\nexport function generateConnectionUrls(\n\tservices: StageSecrets['services'],\n\teventsBackend?: EventsBackend,\n): StageSecrets['urls'] {\n\tconst urls: StageSecrets['urls'] = {};\n\n\tif (services.postgres) {\n\t\turls.DATABASE_URL = generatePostgresUrl(services.postgres);\n\t}\n\n\tif (services.redis) {\n\t\turls.REDIS_URL = generateRedisUrl(services.redis);\n\t}\n\n\tif (services.rabbitmq) {\n\t\turls.RABBITMQ_URL = generateRabbitmqUrl(services.rabbitmq);\n\t}\n\n\tif (services.minio) {\n\t\turls.STORAGE_ENDPOINT = generateMinioEndpoint(services.minio);\n\t}\n\n\tif (eventsBackend) {\n\t\tconst eventUrls = generateEventConnectionStrings(eventsBackend, services);\n\t\turls.EVENT_PUBLISHER_CONNECTION_STRING = eventUrls.publisher;\n\t\turls.EVENT_SUBSCRIBER_CONNECTION_STRING = eventUrls.subscriber;\n\t} else if (services.pgboss) {\n\t\t// Default to pgboss when credentials exist but no explicit events backend\n\t\tconst pgbossUrl = generatePgBossUrl(services.pgboss);\n\t\turls.EVENT_PUBLISHER_CONNECTION_STRING = pgbossUrl;\n\t\turls.EVENT_SUBSCRIBER_CONNECTION_STRING = pgbossUrl;\n\t}\n\n\tif (services.mailpit) {\n\t\turls.SMTP_HOST = services.mailpit.host;\n\t\turls.SMTP_PORT = String(services.mailpit.port);\n\t}\n\n\treturn urls;\n}\n\n/**\n * Generate LocalStack service credentials with LSIA-prefixed access key.\n */\nexport function generateLocalStackCredentials(): ServiceCredentials {\n\tconst defaults = SERVICE_DEFAULTS.localstack;\n\treturn {\n\t\t...defaults,\n\t\tpassword: generateSecurePassword(),\n\t\taccessKeyId: generateLocalStackAccessKeyId(),\n\t};\n}\n\n/**\n * Create a new StageSecrets object with generated credentials.\n * @param stage - The deployment stage (e.g., 'development', 'production')\n * @param services - List of services to generate credentials for\n * @param options - Optional configuration\n * @param options.projectName - Project name used to derive the database name (e.g., 'myapp' → 'myapp_dev')\n * @param options.eventsBackend - Event backend type (pgboss, sns, rabbitmq)\n */\nexport function createStageSecrets(\n\tstage: string,\n\tservices: ComposeServiceName[],\n\toptions?: { projectName?: string; eventsBackend?: EventsBackend },\n): StageSecrets {\n\tconst now = new Date().toISOString();\n\tconst serviceCredentials = generateServicesCredentials(services);\n\n\t// Override service defaults with project-derived names if provided\n\tif (options?.projectName) {\n\t\tif (serviceCredentials.postgres) {\n\t\t\tserviceCredentials.postgres.database = `${options.projectName.replace(/-/g, '_')}_dev`;\n\t\t}\n\t\tif (serviceCredentials.minio) {\n\t\t\tserviceCredentials.minio.bucket = options.projectName;\n\t\t\tserviceCredentials.minio.username = options.projectName;\n\t\t}\n\t}\n\n\t// Always create pgboss credentials when postgres is available.\n\t// pgboss reuses postgres host/port/database but with a dedicated user,\n\t// so subscribers work out of the box without explicit events config.\n\tif (serviceCredentials.postgres && !serviceCredentials.pgboss) {\n\t\tserviceCredentials.pgboss = {\n\t\t\t...PGBOSS_DEFAULTS,\n\t\t\tpassword: generateSecurePassword(),\n\t\t\thost: serviceCredentials.postgres.host,\n\t\t\tport: serviceCredentials.postgres.port,\n\t\t\tdatabase: serviceCredentials.postgres.database,\n\t\t};\n\t}\n\n\t// Generate event-specific credentials\n\tconst eventsBackend = options?.eventsBackend;\n\tif (eventsBackend === 'sns') {\n\t\t// LocalStack credentials with LSIA-prefixed access key\n\t\tserviceCredentials.localstack = generateLocalStackCredentials();\n\t}\n\n\tconst urls = generateConnectionUrls(serviceCredentials, eventsBackend);\n\n\treturn {\n\t\tstage,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\teventsBackend,\n\t\tservices: serviceCredentials,\n\t\turls,\n\t\tcustom: {},\n\t};\n}\n\n/**\n * Rotate password for a specific service.\n */\nexport function rotateServicePassword(\n\tsecrets: StageSecrets,\n\tservice: ComposeServiceName,\n): StageSecrets {\n\tconst currentCreds = secrets.services[service];\n\tif (!currentCreds) {\n\t\tthrow new Error(`Service \"${service}\" not configured in secrets`);\n\t}\n\n\tconst newCreds: ServiceCredentials = {\n\t\t...currentCreds,\n\t\tpassword: generateSecurePassword(),\n\t};\n\n\tconst newServices = {\n\t\t...secrets.services,\n\t\t[service]: newCreds,\n\t};\n\n\treturn {\n\t\t...secrets,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tservices: newServices,\n\t\turls: generateConnectionUrls(newServices, secrets.eventsBackend),\n\t};\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,uBAAuB,SAAS,IAAY;AAC3D,QAAO,YAAY,KAAK,KAAM,SAAS,IAAK,EAAE,CAAC,CAC7C,SAAS,YAAY,CACrB,MAAM,GAAG,OAAO;AAClB;;AAGD,MAAMA,mBAGF;CACH,UAAU;EACT,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;CACV;CACD,OAAO;EACN,MAAM;EACN,MAAM;EACN,UAAU;CACV;CACD,UAAU;EACT,MAAM;EACN,MAAM;EACN,UAAU;EACV,OAAO;CACP;CACD,OAAO;EACN,MAAM;EACN,MAAM;EACN,UAAU;EACV,QAAQ;CACR;CACD,SAAS;EACR,MAAM;EACN,MAAM;EACN,UAAU;CACV;CACD,YAAY;EACX,MAAM;EACN,MAAM;EACN,UAAU;EACV,QAAQ;CACR;AACD;;AAGD,MAAMC,kBAAwD;CAC7D,MAAM;CACN,MAAM;CACN,UAAU;CACV,UAAU;AACV;;;;AAKD,SAAgB,2BACfC,SACqB;CACrB,MAAM,WAAW,iBAAiB;AAClC,QAAO;EACN,GAAG;EACH,UAAU,wBAAwB;CAClC;AACD;;;;AAKD,SAAgB,4BACfC,UAC2B;CAC3B,MAAMC,SAAmC,CAAE;AAE3C,MAAK,MAAM,WAAW,SACrB,QAAO,WAAW,2BAA2B,QAAQ;AAGtD,QAAO;AACP;;;;AAKD,SAAgB,oBAAoBC,OAAmC;CACtE,MAAM,EAAE,UAAU,UAAU,MAAM,MAAM,UAAU,GAAG;AACrD,SAAQ,eAAe,SAAS,GAAG,mBAAmB,SAAS,CAAC,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS;AAC5F;;;;AAKD,SAAgB,iBAAiBA,OAAmC;CACnE,MAAM,EAAE,UAAU,MAAM,MAAM,GAAG;AACjC,SAAQ,WAAW,mBAAmB,SAAS,CAAC,GAAG,KAAK,GAAG,KAAK;AAChE;;;;AAKD,SAAgB,oBAAoBA,OAAmC;CACtE,MAAM,EAAE,UAAU,UAAU,MAAM,MAAM,OAAO,GAAG;CAClD,MAAM,eAAe,mBAAmB,SAAS,IAAI;AACrD,SAAQ,SAAS,SAAS,GAAG,mBAAmB,SAAS,CAAC,GAAG,KAAK,GAAG,KAAK,GAAG,aAAa;AAC1F;;;;AAKD,SAAgB,sBAAsBA,OAAmC;CACxE,MAAM,EAAE,MAAM,MAAM,GAAG;AACvB,SAAQ,SAAS,KAAK,GAAG,KAAK;AAC9B;;;;;;AAOD,SAAgB,gCAAwC;CACvD,MAAM,SAAS,YAAY,GAAG,CAAC,SAAS,YAAY,CAAC,MAAM,GAAG,GAAG;AACjE,SAAQ,MAAM,OAAO;AACrB;;;;;AAMD,SAAgB,kBAAkBA,OAAmC;CACpE,MAAM,EAAE,UAAU,UAAU,MAAM,MAAM,UAAU,GAAG;AACrD,SAAQ,WAAW,SAAS,GAAG,mBAAmB,SAAS,CAAC,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS;AACxF;;;;AAKD,SAAgB,+BACfC,eACAC,UAC4C;AAC5C,SAAQ,eAAR;EACC,KAAK,UAAU;GACd,MAAM,QAAQ,SAAS;AACvB,QAAK,MACJ,OAAM,IAAI,MAAM;GAEjB,MAAM,MAAM,kBAAkB,MAAM;AACpC,UAAO;IAAE,WAAW;IAAK,YAAY;GAAK;EAC1C;EACD,KAAK,OAAO;GACX,MAAM,QAAQ,SAAS;AACvB,QAAK,MACJ,OAAM,IAAI,MAAM;GAEjB,MAAM,YAAY,SAAS,MAAM,KAAK,GAAG,MAAM,KAAK;GACpD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,cAAc,MAAM,eAAe,MAAM;GAC/C,MAAM,YAAY,mBAAmB,MAAM,SAAS;AACpD,UAAO;IACN,YAAY,QAAQ,YAAY,GAAG,UAAU,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK,UAAU,OAAO,YAAY,mBAAmB,SAAS,CAAC;IACnI,aAAa,QAAQ,YAAY,GAAG,UAAU,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK,UAAU,OAAO,YAAY,mBAAmB,SAAS,CAAC;GACpI;EACD;EACD,KAAK,YAAY;GAChB,MAAM,QAAQ,SAAS;AACvB,QAAK,MACJ,OAAM,IAAI,MAAM;GAEjB,MAAM,MAAM,oBAAoB,MAAM;AACtC,UAAO;IAAE,WAAW;IAAK,YAAY;GAAK;EAC1C;CACD;AACD;;;;AAKD,SAAgB,uBACfA,UACAC,eACuB;CACvB,MAAMC,OAA6B,CAAE;AAErC,KAAI,SAAS,SACZ,MAAK,eAAe,oBAAoB,SAAS,SAAS;AAG3D,KAAI,SAAS,MACZ,MAAK,YAAY,iBAAiB,SAAS,MAAM;AAGlD,KAAI,SAAS,SACZ,MAAK,eAAe,oBAAoB,SAAS,SAAS;AAG3D,KAAI,SAAS,MACZ,MAAK,mBAAmB,sBAAsB,SAAS,MAAM;AAG9D,KAAI,eAAe;EAClB,MAAM,YAAY,+BAA+B,eAAe,SAAS;AACzE,OAAK,oCAAoC,UAAU;AACnD,OAAK,qCAAqC,UAAU;CACpD,WAAU,SAAS,QAAQ;EAE3B,MAAM,YAAY,kBAAkB,SAAS,OAAO;AACpD,OAAK,oCAAoC;AACzC,OAAK,qCAAqC;CAC1C;AAED,KAAI,SAAS,SAAS;AACrB,OAAK,YAAY,SAAS,QAAQ;AAClC,OAAK,YAAY,OAAO,SAAS,QAAQ,KAAK;CAC9C;AAED,QAAO;AACP;;;;AAKD,SAAgB,gCAAoD;CACnE,MAAM,WAAW,iBAAiB;AAClC,QAAO;EACN,GAAG;EACH,UAAU,wBAAwB;EAClC,aAAa,+BAA+B;CAC5C;AACD;;;;;;;;;AAUD,SAAgB,mBACfC,OACAP,UACAQ,SACe;CACf,MAAM,MAAM,qBAAI,QAAO,aAAa;CACpC,MAAM,qBAAqB,4BAA4B,SAAS;AAGhE,KAAI,SAAS,aAAa;AACzB,MAAI,mBAAmB,SACtB,oBAAmB,SAAS,YAAY,EAAE,QAAQ,YAAY,QAAQ,MAAM,IAAI,CAAC;AAElF,MAAI,mBAAmB,OAAO;AAC7B,sBAAmB,MAAM,SAAS,QAAQ;AAC1C,sBAAmB,MAAM,WAAW,QAAQ;EAC5C;CACD;AAKD,KAAI,mBAAmB,aAAa,mBAAmB,OACtD,oBAAmB,SAAS;EAC3B,GAAG;EACH,UAAU,wBAAwB;EAClC,MAAM,mBAAmB,SAAS;EAClC,MAAM,mBAAmB,SAAS;EAClC,UAAU,mBAAmB,SAAS;CACtC;CAIF,MAAM,gBAAgB,SAAS;AAC/B,KAAI,kBAAkB,MAErB,oBAAmB,aAAa,+BAA+B;CAGhE,MAAM,OAAO,uBAAuB,oBAAoB,cAAc;AAEtE,QAAO;EACN;EACA,WAAW;EACX,WAAW;EACX;EACA,UAAU;EACV;EACA,QAAQ,CAAE;CACV;AACD;;;;AAKD,SAAgB,sBACfC,SACAV,SACe;CACf,MAAM,eAAe,QAAQ,SAAS;AACtC,MAAK,aACJ,OAAM,IAAI,OAAO,WAAW,QAAQ;CAGrC,MAAMW,WAA+B;EACpC,GAAG;EACH,UAAU,wBAAwB;CAClC;CAED,MAAM,cAAc;EACnB,GAAG,QAAQ;GACV,UAAU;CACX;AAED,QAAO;EACN,GAAG;EACH,WAAW,qBAAI,QAAO,aAAa;EACnC,UAAU;EACV,MAAM,uBAAuB,aAAa,QAAQ,cAAc;CAChE;AACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-BThUzEIp.d.mts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"sourcesContent":[],"mappings":";;;;;;AASA;AAoBA;AAoBA;;;cAxCa;AC0Hb;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;AAAwC,iBDvLxB,kBAAA,CCuLwB,SAAA,CAAA,EDvLO,SCuLP,CAAA,EAAA,MAAA;;;AAGlB;AA6EtB;AAA6B,iBDnPb,iBAAA,CCmPa,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;;AAjK7B;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;;;;AAGsB;AA6EtB;;;;;AAGe;AA6Bf;AAmBA;AAwBA;AAaA;AAiBA;;;;AAGY;AAuCZ;AAmCA;;;;AAIS;AAgDO,iBA3YA,eA6YqB,CAAA,oBA7Ye,UA6YT,CAAA,CAAA,MAAA,EA5YlC,cA4YkC,CA5YnB,KA4YmB,CAAA,CAAA,EA3YxC,uBA2YwC,CA3YhB,KA2YgB,CAAA;;;;iBA7W3B,kBAAA,SACP,+BAEN;;;;;iBA8Ca,wBAAA,SACP,yBAEN;;;;;iBA6Ea,aAAA,SACP,YAAY,+BAElB;;;;;;;iBA6Ba,uBAAA,YACJ;;;;;;;;;;;;iBAkBI,iBAAA,YACJ;;;;;;;iBAuBI,iBAAA,YAA6B;;iBAa7B,iBAAA,SAA0B;;;;;iBAiB1B,eAAA,YACJ,uCAET;;;;;iBAuCa,gBAAA,YAA4B;;;;;;;;;;iBAmC5B,oBAAA,YACJ,2DAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDa,mBAAA;;cAEqB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-CHB4tSzX.d.cts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"sourcesContent":[],"mappings":";;;;;;AASA;AAoBA;AAoBA;;;cAxCa;AC0Hb;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;AAAwC,iBDvLxB,kBAAA,CCuLwB,SAAA,CAAA,EDvLO,SCuLP,CAAA,EAAA,MAAA;;;AAGlB;AA6EtB;AAA6B,iBDnPb,iBAAA,CCmPa,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;;AAjK7B;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;;;;AAGsB;AA6EtB;;;;;AAGe;AA6Bf;AAmBA;AAwBA;AAaA;AAiBA;;;;AAGY;AAuCZ;AAmCA;;;;AAIS;AAgDO,iBA3YA,eA6YqB,CAAA,oBA7Ye,UA6YT,CAAA,CAAA,MAAA,EA5YlC,cA4YkC,CA5YnB,KA4YmB,CAAA,CAAA,EA3YxC,uBA2YwC,CA3YhB,KA2YgB,CAAA;;;;iBA7W3B,kBAAA,SACP,+BAEN;;;;;iBA8Ca,wBAAA,SACP,yBAEN;;;;;iBA6Ea,aAAA,SACP,YAAY,+BAElB;;;;;;;iBA6Ba,uBAAA,YACJ;;;;;;;;;;;;iBAkBI,iBAAA,YACJ;;;;;;;iBAuBI,iBAAA,YAA6B;;iBAa7B,iBAAA,SAA0B;;;;;iBAiB1B,eAAA,YACJ,uCAET;;;;;iBAuCa,gBAAA,YAA4B;;;;;;;;;;iBAmC5B,oBAAA,YACJ,2DAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDa,mBAAA;;cAEqB"}
|