@geekmidas/cli 1.10.15 → 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 +12 -0
- package/dist/{bundler-BWsVDer6.mjs → bundler-B4AackW5.mjs} +2 -2
- package/dist/{bundler-BWsVDer6.mjs.map → bundler-B4AackW5.mjs.map} +1 -1
- package/dist/{bundler-Drh5KoN5.cjs → bundler-BhhfkI9T.cjs} +2 -2
- package/dist/{bundler-Drh5KoN5.cjs.map → bundler-BhhfkI9T.cjs.map} +1 -1
- package/dist/config.d.cts +2 -2
- package/dist/config.d.mts +2 -2
- package/dist/{fullstack-secrets-D9rjTNyx.cjs → fullstack-secrets-DOHBU4Rp.cjs} +110 -4
- package/dist/fullstack-secrets-DOHBU4Rp.cjs.map +1 -0
- package/dist/{fullstack-secrets-BIFFv4UZ.mjs → fullstack-secrets-x2Kffx7-.mjs} +99 -5
- package/dist/fullstack-secrets-x2Kffx7-.mjs.map +1 -0
- package/dist/{index-UCsZ_Vkw.d.cts → index-BkibYzso.d.cts} +15 -4
- package/dist/index-BkibYzso.d.cts.map +1 -0
- package/dist/{index-gXAGDSGu.d.mts → index-CY-ieuRp.d.mts} +15 -4
- package/dist/index-CY-ieuRp.d.mts.map +1 -0
- package/dist/index.cjs +332 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +332 -62
- package/dist/index.mjs.map +1 -1
- package/dist/openapi-BYxAWwok.cjs.map +1 -1
- package/dist/openapi-DenF-okj.mjs.map +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/{reconcile-DxTEausy.mjs → reconcile-BLh6rswz.mjs} +2 -2
- package/dist/{reconcile-DxTEausy.mjs.map → reconcile-BLh6rswz.mjs.map} +1 -1
- package/dist/{reconcile-LaaJkFlO.cjs → reconcile-Ch7sIcf8.cjs} +2 -2
- package/dist/{reconcile-LaaJkFlO.cjs.map → reconcile-Ch7sIcf8.cjs.map} +1 -1
- package/dist/{storage-Bu44pwPJ.cjs → storage-B1wvztiJ.cjs} +11 -1
- package/dist/{storage-clMAp4sc.mjs.map → storage-B1wvztiJ.cjs.map} +1 -1
- package/dist/{storage-CauTheT9.mjs → storage-Cs4WBsc4.mjs} +1 -1
- package/dist/{storage-DpqzcjQ5.cjs → storage-DOEtT2Hr.cjs} +1 -1
- package/dist/{storage-clMAp4sc.mjs → storage-dbb9RyBl.mjs} +11 -1
- package/dist/{storage-Bu44pwPJ.cjs.map → storage-dbb9RyBl.mjs.map} +1 -1
- package/dist/{sync-BkalF65h.mjs → sync-COnAugP-.mjs} +1 -1
- package/dist/sync-D1Pa30oV.cjs +4 -0
- package/dist/{sync-BeiI5rFC.cjs → sync-DGXXSk2v.cjs} +2 -2
- package/dist/{sync-BeiI5rFC.cjs.map → sync-DGXXSk2v.cjs.map} +1 -1
- package/dist/{sync-CWJ6tL0s.mjs → sync-D_NowTkZ.mjs} +2 -2
- package/dist/{sync-CWJ6tL0s.mjs.map → sync-D_NowTkZ.mjs.map} +1 -1
- package/dist/{types-DiV9Mbvc.d.mts → types-DdHfUbxk.d.cts} +13 -3
- package/dist/types-DdHfUbxk.d.cts.map +1 -0
- package/dist/{types-JvWj5Ckc.d.cts → types-OszPdw9m.d.mts} +13 -3
- package/dist/types-OszPdw9m.d.mts.map +1 -0
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace-4SP3Gx4Y.cjs.map +1 -1
- package/dist/workspace-D4z4A4cq.mjs.map +1 -1
- package/package.json +4 -4
- package/src/dev/__tests__/entry.spec.ts +3 -5
- package/src/dev/__tests__/index.spec.ts +73 -5
- package/src/dev/index.ts +33 -25
- package/src/docker/compose.ts +130 -2
- package/src/init/__tests__/generators.spec.ts +84 -0
- package/src/init/generators/docker.ts +128 -16
- package/src/init/index.ts +26 -1
- package/src/init/templates/index.ts +28 -0
- package/src/init/versions.ts +1 -1
- package/src/secrets/__tests__/generator.spec.ts +183 -0
- package/src/secrets/generator.ts +116 -4
- package/src/secrets/storage.ts +12 -0
- package/src/secrets/types.ts +11 -1
- package/src/setup/__tests__/reconcile-secrets.spec.ts +86 -0
- package/src/setup/index.ts +64 -1
- package/src/test/__tests__/index.spec.ts +1 -4
- package/src/types.ts +13 -1
- package/src/workspace/types.ts +13 -2
- package/dist/fullstack-secrets-BIFFv4UZ.mjs.map +0 -1
- package/dist/fullstack-secrets-D9rjTNyx.cjs.map +0 -1
- package/dist/index-UCsZ_Vkw.d.cts.map +0 -1
- package/dist/index-gXAGDSGu.d.mts.map +0 -1
- package/dist/sync-Bp8xRcuQ.cjs +0 -4
- package/dist/types-DiV9Mbvc.d.mts.map +0 -1
- package/dist/types-JvWj5Ckc.d.cts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -4,13 +4,13 @@ import { getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployT
|
|
|
4
4
|
import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, parseModuleConfig } from "./config-jsRYHOHU.mjs";
|
|
5
5
|
import { getCredentialsPath, getDokployCredentials, getDokployRegistryId, getDokployToken, removeDokployCredentials, storeDokployCredentials, storeDokployRegistryId } from "./credentials-s1kLcIzK.mjs";
|
|
6
6
|
import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, copyAllClients, copyClientToFrontends, generateOpenApi, getBackendOpenApiPath, isPartitionedRoutes, normalizeRoutes, openapiCommand, resolveOpenApiConfig } from "./openapi-DenF-okj.mjs";
|
|
7
|
-
import { getKeyPath, maskPassword, readStageSecrets, secretsExist, setCustomSecret, toEmbeddableSecrets, writeStageSecrets } from "./storage-
|
|
7
|
+
import { getKeyPath, maskPassword, readStageSecrets, secretsExist, setCustomSecret, toEmbeddableSecrets, writeStageSecrets } from "./storage-dbb9RyBl.mjs";
|
|
8
8
|
import { DokployApi } from "./dokploy-api-2ldYoN3i.mjs";
|
|
9
9
|
import { encryptSecrets } from "./encryption-BOH5M-f-.mjs";
|
|
10
10
|
import { CachedStateProvider } from "./CachedStateProvider-BDq5WqSy.mjs";
|
|
11
|
-
import { createStageSecrets, generateConnectionUrls, generateDbPassword, generateDbUrl, generateFullstackCustomSecrets, generateServiceCredentials, rotateServicePassword, writeDockerEnvFromSecrets } from "./fullstack-secrets-
|
|
11
|
+
import { createStageSecrets, generateConnectionUrls, generateDbPassword, generateDbUrl, generateFullstackCustomSecrets, generateLocalStackCredentials, generateSecurePassword, generateServiceCredentials, rotateServicePassword, writeDockerEnvFromSecrets } from "./fullstack-secrets-x2Kffx7-.mjs";
|
|
12
12
|
import { generateReactQueryCommand } from "./openapi-react-query-C4UdILaI.mjs";
|
|
13
|
-
import { isSSMConfigured, pullSecrets, pushSecrets } from "./sync-
|
|
13
|
+
import { isSSMConfigured, pullSecrets, pushSecrets } from "./sync-D_NowTkZ.mjs";
|
|
14
14
|
import { createRequire } from "node:module";
|
|
15
15
|
import { copyFileSync, existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
16
16
|
import { basename, dirname, join, parse, relative, resolve } from "node:path";
|
|
@@ -35,7 +35,7 @@ import prompts from "prompts";
|
|
|
35
35
|
|
|
36
36
|
//#region package.json
|
|
37
37
|
var name = "@geekmidas/cli";
|
|
38
|
-
var version = "1.10.
|
|
38
|
+
var version = "1.10.16";
|
|
39
39
|
var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
|
|
40
40
|
var private$1 = false;
|
|
41
41
|
var type = "module";
|
|
@@ -808,7 +808,9 @@ async function resolveServicePorts(workspaceRoot) {
|
|
|
808
808
|
*/
|
|
809
809
|
function replacePortInUrl(url, oldPort, newPort) {
|
|
810
810
|
if (oldPort === newPort) return url;
|
|
811
|
-
|
|
811
|
+
let result = url.replace(new RegExp(`:${oldPort}(?=[/?#]|$)`, "g"), `:${newPort}`);
|
|
812
|
+
result = result.replace(new RegExp(`%3A${oldPort}(?=[%/?#&]|$)`, "gi"), `%3A${newPort}`);
|
|
813
|
+
return result;
|
|
812
814
|
}
|
|
813
815
|
/**
|
|
814
816
|
* Rewrite connection URLs and port vars in secrets with resolved ports.
|
|
@@ -838,7 +840,7 @@ function rewriteUrlsWithPorts(secrets, resolvedPorts) {
|
|
|
838
840
|
for (const { defaultPort, resolvedPort } of portReplacements) if (value === String(defaultPort)) result[key] = String(resolvedPort);
|
|
839
841
|
}
|
|
840
842
|
for (const [key, value] of Object.entries(result)) {
|
|
841
|
-
if (!key.endsWith("_URL") && !key.endsWith("_ENDPOINT") && key !== "DATABASE_URL") continue;
|
|
843
|
+
if (!key.endsWith("_URL") && !key.endsWith("_ENDPOINT") && !key.endsWith("_CONNECTION_STRING") && key !== "DATABASE_URL") continue;
|
|
842
844
|
let rewritten = value;
|
|
843
845
|
for (const name$1 of serviceNames) rewritten = rewritten.replace(new RegExp(`@${name$1}:`, "g"), "@localhost:");
|
|
844
846
|
for (const { defaultPort, resolvedPort } of portReplacements) rewritten = replacePortInUrl(rewritten, defaultPort, resolvedPort);
|
|
@@ -1521,17 +1523,16 @@ function findSecretsRoot(startDir) {
|
|
|
1521
1523
|
* @internal
|
|
1522
1524
|
*/
|
|
1523
1525
|
function generateCredentialsInjection(secretsJsonPath) {
|
|
1524
|
-
return `import {
|
|
1525
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
1526
|
+
return `import { existsSync, readFileSync } from 'node:fs';
|
|
1526
1527
|
|
|
1527
|
-
// Inject dev secrets
|
|
1528
|
+
// Inject dev secrets via globalThis and process.env
|
|
1529
|
+
// Using globalThis.__gkm_credentials__ avoids CJS/ESM interop issues where
|
|
1530
|
+
// Object.assign on the Credentials export only mutates one module copy.
|
|
1528
1531
|
const secretsPath = '${secretsJsonPath}';
|
|
1529
1532
|
if (existsSync(secretsPath)) {
|
|
1530
1533
|
const secrets = JSON.parse(readFileSync(secretsPath, 'utf-8'));
|
|
1531
|
-
|
|
1534
|
+
globalThis.__gkm_credentials__ = secrets;
|
|
1532
1535
|
Object.assign(process.env, secrets);
|
|
1533
|
-
// Debug: uncomment to verify preload is running
|
|
1534
|
-
// console.log('[gkm preload] Injected', Object.keys(secrets).length, 'credentials');
|
|
1535
1536
|
}
|
|
1536
1537
|
`;
|
|
1537
1538
|
}
|
|
@@ -1720,13 +1721,14 @@ var EntryRunner = class {
|
|
|
1720
1721
|
*/
|
|
1721
1722
|
function generateServerEntryContent(options) {
|
|
1722
1723
|
const { secretsJsonPath, runtime = "node", enableOpenApi = false, appImportPath = "./app.js" } = options;
|
|
1723
|
-
const credentialsInjection = secretsJsonPath ? `import {
|
|
1724
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
1724
|
+
const credentialsInjection = secretsJsonPath ? `import { existsSync, readFileSync } from 'node:fs';
|
|
1725
1725
|
|
|
1726
|
-
// Inject dev secrets
|
|
1726
|
+
// Inject dev secrets via globalThis (must happen before app import)
|
|
1727
1727
|
const secretsPath = '${secretsJsonPath}';
|
|
1728
1728
|
if (existsSync(secretsPath)) {
|
|
1729
|
-
|
|
1729
|
+
const __secrets = JSON.parse(readFileSync(secretsPath, 'utf-8'));
|
|
1730
|
+
globalThis.__gkm_credentials__ = __secrets;
|
|
1731
|
+
Object.assign(process.env, __secrets);
|
|
1730
1732
|
}
|
|
1731
1733
|
|
|
1732
1734
|
` : "";
|
|
@@ -1894,19 +1896,11 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1894
1896
|
if (appName) logger$11.log(`📦 App: ${appName}`);
|
|
1895
1897
|
const secretCount = Object.keys(credentials).filter((k) => k !== "PORT").length;
|
|
1896
1898
|
if (secretCount > 0) logger$11.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
const rewritten = rewriteUrlsWithPorts(credentials, {
|
|
1903
|
-
dockerEnv: {},
|
|
1904
|
-
ports,
|
|
1905
|
-
mappings
|
|
1906
|
-
});
|
|
1907
|
-
Object.assign(credentials, rewritten);
|
|
1908
|
-
logger$11.log(`🔌 Applied ${Object.keys(ports).length} port mapping(s)`);
|
|
1909
|
-
}
|
|
1899
|
+
const resolvedPorts = await resolveServicePorts(secretsRoot);
|
|
1900
|
+
if (resolvedPorts.mappings.length > 0 && Object.keys(resolvedPorts.ports).length > 0) {
|
|
1901
|
+
const rewritten = rewriteUrlsWithPorts(credentials, resolvedPorts);
|
|
1902
|
+
Object.assign(credentials, rewritten);
|
|
1903
|
+
logger$11.log(`🔌 Applied ${Object.keys(resolvedPorts.ports).length} port mapping(s)`);
|
|
1910
1904
|
}
|
|
1911
1905
|
try {
|
|
1912
1906
|
const appInfo = await loadWorkspaceAppInfo(cwd);
|
|
@@ -2220,7 +2214,7 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
|
|
|
2220
2214
|
let masterKey;
|
|
2221
2215
|
if (context.production?.bundle && !skipBundle) {
|
|
2222
2216
|
logger$9.log(`\n📦 Bundling production server...`);
|
|
2223
|
-
const { bundleServer } = await import("./bundler-
|
|
2217
|
+
const { bundleServer } = await import("./bundler-B4AackW5.mjs");
|
|
2224
2218
|
const allConstructs = [
|
|
2225
2219
|
...endpoints.map((e) => e.construct),
|
|
2226
2220
|
...functions.map((f) => f.construct),
|
|
@@ -2884,7 +2878,8 @@ const DEFAULT_SERVICE_IMAGES = {
|
|
|
2884
2878
|
redis: "redis",
|
|
2885
2879
|
rabbitmq: "rabbitmq",
|
|
2886
2880
|
minio: "minio/minio",
|
|
2887
|
-
mailpit: "axllent/mailpit"
|
|
2881
|
+
mailpit: "axllent/mailpit",
|
|
2882
|
+
localstack: "localstack/localstack"
|
|
2888
2883
|
};
|
|
2889
2884
|
/** Default Docker image versions for services */
|
|
2890
2885
|
const DEFAULT_SERVICE_VERSIONS = {
|
|
@@ -2892,7 +2887,8 @@ const DEFAULT_SERVICE_VERSIONS = {
|
|
|
2892
2887
|
redis: "7-alpine",
|
|
2893
2888
|
rabbitmq: "3-management-alpine",
|
|
2894
2889
|
minio: "latest",
|
|
2895
|
-
mailpit: "latest"
|
|
2890
|
+
mailpit: "latest",
|
|
2891
|
+
localstack: "latest"
|
|
2896
2892
|
};
|
|
2897
2893
|
/** Get the default full image reference for a service */
|
|
2898
2894
|
function getDefaultImage(serviceName) {
|
|
@@ -2959,6 +2955,11 @@ services:
|
|
|
2959
2955
|
- SMTP_PASS=\${SMTP_PASS:-${imageName}}
|
|
2960
2956
|
- SMTP_SECURE=\${SMTP_SECURE:-false}
|
|
2961
2957
|
- MAIL_FROM=\${MAIL_FROM:-noreply@localhost}
|
|
2958
|
+
`;
|
|
2959
|
+
if (serviceMap.has("localstack")) yaml += ` - AWS_ACCESS_KEY_ID=\${AWS_ACCESS_KEY_ID:-localstack}
|
|
2960
|
+
- AWS_SECRET_ACCESS_KEY=\${AWS_SECRET_ACCESS_KEY:-localstack}
|
|
2961
|
+
- AWS_REGION=\${AWS_REGION:-us-east-1}
|
|
2962
|
+
- AWS_ENDPOINT_URL=\${AWS_ENDPOINT_URL:-http://localstack:4566}
|
|
2962
2963
|
`;
|
|
2963
2964
|
yaml += ` healthcheck:
|
|
2964
2965
|
test: ["CMD", "wget", "-q", "--spider", "http://localhost:${port}${healthCheckPath}"]
|
|
@@ -3075,6 +3076,29 @@ services:
|
|
|
3075
3076
|
retries: 5
|
|
3076
3077
|
networks:
|
|
3077
3078
|
- app-network
|
|
3079
|
+
`;
|
|
3080
|
+
const localstackImage = serviceMap.get("localstack");
|
|
3081
|
+
if (localstackImage) yaml += `
|
|
3082
|
+
localstack:
|
|
3083
|
+
image: ${localstackImage}
|
|
3084
|
+
container_name: localstack
|
|
3085
|
+
restart: unless-stopped
|
|
3086
|
+
environment:
|
|
3087
|
+
SERVICES: sns,sqs
|
|
3088
|
+
AWS_DEFAULT_REGION: \${AWS_REGION:-us-east-1}
|
|
3089
|
+
AWS_ACCESS_KEY_ID: \${AWS_ACCESS_KEY_ID:-localstack}
|
|
3090
|
+
AWS_SECRET_ACCESS_KEY: \${AWS_SECRET_ACCESS_KEY:-localstack}
|
|
3091
|
+
ports:
|
|
3092
|
+
- "\${LOCALSTACK_PORT:-4566}:4566"
|
|
3093
|
+
volumes:
|
|
3094
|
+
- localstack_data:/var/lib/localstack
|
|
3095
|
+
healthcheck:
|
|
3096
|
+
test: ["CMD", "curl", "-f", "http://localhost:4566/_localstack/health"]
|
|
3097
|
+
interval: 10s
|
|
3098
|
+
timeout: 5s
|
|
3099
|
+
retries: 5
|
|
3100
|
+
networks:
|
|
3101
|
+
- app-network
|
|
3078
3102
|
`;
|
|
3079
3103
|
yaml += `
|
|
3080
3104
|
volumes:
|
|
@@ -3086,6 +3110,8 @@ volumes:
|
|
|
3086
3110
|
if (serviceMap.has("rabbitmq")) yaml += ` rabbitmq_data:
|
|
3087
3111
|
`;
|
|
3088
3112
|
if (serviceMap.has("minio")) yaml += ` minio_data:
|
|
3113
|
+
`;
|
|
3114
|
+
if (serviceMap.has("localstack")) yaml += ` localstack_data:
|
|
3089
3115
|
`;
|
|
3090
3116
|
yaml += `
|
|
3091
3117
|
networks:
|
|
@@ -3142,6 +3168,9 @@ function generateWorkspaceCompose(workspace, options = {}) {
|
|
|
3142
3168
|
const hasRedis = services.cache !== void 0 && services.cache !== false;
|
|
3143
3169
|
const hasMail = services.mail !== void 0 && services.mail !== false;
|
|
3144
3170
|
const hasMinio = services.storage !== void 0 && services.storage !== false;
|
|
3171
|
+
const eventsBackend = services.events;
|
|
3172
|
+
const hasLocalStack = eventsBackend === "sns";
|
|
3173
|
+
const hasRabbitMQ = eventsBackend === "rabbitmq" || services.rabbitmq !== void 0;
|
|
3145
3174
|
const postgresImage = getInfraServiceImage("postgres", services.db);
|
|
3146
3175
|
const redisImage = getInfraServiceImage("redis", services.cache);
|
|
3147
3176
|
const minioImage = getInfraServiceImage("minio", services.storage);
|
|
@@ -3157,7 +3186,8 @@ services:
|
|
|
3157
3186
|
hasPostgres,
|
|
3158
3187
|
hasRedis,
|
|
3159
3188
|
hasMinio,
|
|
3160
|
-
hasMail
|
|
3189
|
+
hasMail,
|
|
3190
|
+
eventsBackend
|
|
3161
3191
|
});
|
|
3162
3192
|
if (hasPostgres) yaml += `
|
|
3163
3193
|
postgres:
|
|
@@ -3233,6 +3263,49 @@ services:
|
|
|
3233
3263
|
retries: 5
|
|
3234
3264
|
networks:
|
|
3235
3265
|
- workspace-network
|
|
3266
|
+
`;
|
|
3267
|
+
if (hasLocalStack) yaml += `
|
|
3268
|
+
localstack:
|
|
3269
|
+
image: localstack/localstack:latest
|
|
3270
|
+
container_name: ${workspace.name}-localstack
|
|
3271
|
+
restart: unless-stopped
|
|
3272
|
+
environment:
|
|
3273
|
+
SERVICES: sns,sqs
|
|
3274
|
+
AWS_DEFAULT_REGION: \${AWS_REGION:-us-east-1}
|
|
3275
|
+
AWS_ACCESS_KEY_ID: \${AWS_ACCESS_KEY_ID:-localstack}
|
|
3276
|
+
AWS_SECRET_ACCESS_KEY: \${AWS_SECRET_ACCESS_KEY:-localstack}
|
|
3277
|
+
ports:
|
|
3278
|
+
- "\${LOCALSTACK_PORT:-4566}:4566"
|
|
3279
|
+
volumes:
|
|
3280
|
+
- localstack_data:/var/lib/localstack
|
|
3281
|
+
healthcheck:
|
|
3282
|
+
test: ["CMD", "curl", "-f", "http://localhost:4566/_localstack/health"]
|
|
3283
|
+
interval: 10s
|
|
3284
|
+
timeout: 5s
|
|
3285
|
+
retries: 5
|
|
3286
|
+
networks:
|
|
3287
|
+
- workspace-network
|
|
3288
|
+
`;
|
|
3289
|
+
if (hasRabbitMQ) yaml += `
|
|
3290
|
+
rabbitmq:
|
|
3291
|
+
image: rabbitmq:3-management-alpine
|
|
3292
|
+
container_name: ${workspace.name}-rabbitmq
|
|
3293
|
+
restart: unless-stopped
|
|
3294
|
+
environment:
|
|
3295
|
+
RABBITMQ_DEFAULT_USER: \${RABBITMQ_USER:-guest}
|
|
3296
|
+
RABBITMQ_DEFAULT_PASS: \${RABBITMQ_PASSWORD:-guest}
|
|
3297
|
+
ports:
|
|
3298
|
+
- "\${RABBITMQ_HOST_PORT:-5672}:5672"
|
|
3299
|
+
- "\${RABBITMQ_MGMT_HOST_PORT:-15672}:15672"
|
|
3300
|
+
volumes:
|
|
3301
|
+
- rabbitmq_data:/var/lib/rabbitmq
|
|
3302
|
+
healthcheck:
|
|
3303
|
+
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
|
|
3304
|
+
interval: 10s
|
|
3305
|
+
timeout: 5s
|
|
3306
|
+
retries: 5
|
|
3307
|
+
networks:
|
|
3308
|
+
- workspace-network
|
|
3236
3309
|
`;
|
|
3237
3310
|
yaml += `
|
|
3238
3311
|
volumes:
|
|
@@ -3242,6 +3315,10 @@ volumes:
|
|
|
3242
3315
|
if (hasRedis) yaml += ` redis_data:
|
|
3243
3316
|
`;
|
|
3244
3317
|
if (hasMinio) yaml += ` minio_data:
|
|
3318
|
+
`;
|
|
3319
|
+
if (hasLocalStack) yaml += ` localstack_data:
|
|
3320
|
+
`;
|
|
3321
|
+
if (hasRabbitMQ) yaml += ` rabbitmq_data:
|
|
3245
3322
|
`;
|
|
3246
3323
|
yaml += `
|
|
3247
3324
|
networks:
|
|
@@ -3277,7 +3354,7 @@ function getInfraServiceImage(serviceName, config$1) {
|
|
|
3277
3354
|
* Generate a service definition for an app.
|
|
3278
3355
|
*/
|
|
3279
3356
|
function generateAppService(appName, app, allApps, options) {
|
|
3280
|
-
const { registry, projectName, hasPostgres, hasRedis, hasMinio, hasMail } = options;
|
|
3357
|
+
const { registry, projectName, hasPostgres, hasRedis, hasMinio, hasMail, eventsBackend } = options;
|
|
3281
3358
|
const imageRef = registry ? `\${REGISTRY:-${registry}}/` : "";
|
|
3282
3359
|
const healthCheckPath = app.type === "frontend" ? "/" : "/health";
|
|
3283
3360
|
const healthCheckCmd = app.type === "frontend" ? `["CMD", "wget", "-q", "--spider", "http://localhost:${app.port}/"]` : `["CMD", "wget", "-q", "--spider", "http://localhost:${app.port}${healthCheckPath}"]`;
|
|
@@ -3319,6 +3396,16 @@ function generateAppService(appName, app, allApps, options) {
|
|
|
3319
3396
|
- SMTP_SECURE=\${SMTP_SECURE:-false}
|
|
3320
3397
|
- MAIL_FROM=\${MAIL_FROM:-noreply@localhost}
|
|
3321
3398
|
`;
|
|
3399
|
+
if (eventsBackend) {
|
|
3400
|
+
yaml += ` - EVENT_PUBLISHER_CONNECTION_STRING=\${EVENT_PUBLISHER_CONNECTION_STRING}
|
|
3401
|
+
- EVENT_SUBSCRIBER_CONNECTION_STRING=\${EVENT_SUBSCRIBER_CONNECTION_STRING}
|
|
3402
|
+
`;
|
|
3403
|
+
if (eventsBackend === "sns") yaml += ` - AWS_ACCESS_KEY_ID=\${AWS_ACCESS_KEY_ID:-localstack}
|
|
3404
|
+
- AWS_SECRET_ACCESS_KEY=\${AWS_SECRET_ACCESS_KEY:-localstack}
|
|
3405
|
+
- AWS_REGION=\${AWS_REGION:-us-east-1}
|
|
3406
|
+
- AWS_ENDPOINT_URL=\${AWS_ENDPOINT_URL:-http://localstack:4566}
|
|
3407
|
+
`;
|
|
3408
|
+
}
|
|
3322
3409
|
}
|
|
3323
3410
|
yaml += ` healthcheck:
|
|
3324
3411
|
test: ${healthCheckCmd}
|
|
@@ -3332,6 +3419,8 @@ function generateAppService(appName, app, allApps, options) {
|
|
|
3332
3419
|
if (hasRedis) dependencies$1.push("redis");
|
|
3333
3420
|
if (hasMinio) dependencies$1.push("minio");
|
|
3334
3421
|
if (hasMail) dependencies$1.push("mailpit");
|
|
3422
|
+
if (eventsBackend === "sns") dependencies$1.push("localstack");
|
|
3423
|
+
if (eventsBackend === "rabbitmq") dependencies$1.push("rabbitmq");
|
|
3335
3424
|
}
|
|
3336
3425
|
if (dependencies$1.length > 0) {
|
|
3337
3426
|
yaml += ` depends_on:
|
|
@@ -6376,7 +6465,7 @@ async function deployCommand(options) {
|
|
|
6376
6465
|
dokployConfig = setupResult.config;
|
|
6377
6466
|
finalRegistry = dokployConfig.registry ?? dockerConfig.registry;
|
|
6378
6467
|
if (setupResult.serviceUrls) {
|
|
6379
|
-
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1, initStageSecrets } = await import("./storage-
|
|
6468
|
+
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1, initStageSecrets } = await import("./storage-Cs4WBsc4.mjs");
|
|
6380
6469
|
let secrets = await readStageSecrets$1(stage);
|
|
6381
6470
|
if (!secrets) {
|
|
6382
6471
|
logger$3.log(` Creating secrets file for stage "${stage}"...`);
|
|
@@ -6663,7 +6752,7 @@ const GEEKMIDAS_VERSIONS = {
|
|
|
6663
6752
|
"@geekmidas/constructs": "~3.0.2",
|
|
6664
6753
|
"@geekmidas/db": "~1.0.0",
|
|
6665
6754
|
"@geekmidas/emailkit": "~1.0.0",
|
|
6666
|
-
"@geekmidas/envkit": "~1.0.
|
|
6755
|
+
"@geekmidas/envkit": "~1.0.4",
|
|
6667
6756
|
"@geekmidas/errors": "~1.0.0",
|
|
6668
6757
|
"@geekmidas/events": "~1.1.0",
|
|
6669
6758
|
"@geekmidas/logger": "~1.0.0",
|
|
@@ -7145,11 +7234,11 @@ function generateDockerFiles(options, template, dbApps) {
|
|
|
7145
7234
|
if (isFullstack && dbApps?.length) {
|
|
7146
7235
|
files.push({
|
|
7147
7236
|
path: "docker/postgres/init.sh",
|
|
7148
|
-
content: generatePostgresInitScript(dbApps)
|
|
7237
|
+
content: generatePostgresInitScript(dbApps, options.services?.events)
|
|
7149
7238
|
});
|
|
7150
7239
|
files.push({
|
|
7151
7240
|
path: "docker/.env",
|
|
7152
|
-
content: generateDockerEnv(dbApps)
|
|
7241
|
+
content: generateDockerEnv(dbApps, options.services?.events)
|
|
7153
7242
|
});
|
|
7154
7243
|
}
|
|
7155
7244
|
}
|
|
@@ -7249,6 +7338,47 @@ function generateDockerFiles(options, template, dbApps) {
|
|
|
7249
7338
|
retries: 5`);
|
|
7250
7339
|
volumes.push(" minio_data:");
|
|
7251
7340
|
}
|
|
7341
|
+
if (options.services?.events === "sns") {
|
|
7342
|
+
services.push(` localstack:
|
|
7343
|
+
image: localstack/localstack:latest
|
|
7344
|
+
container_name: ${options.name}-localstack
|
|
7345
|
+
restart: unless-stopped
|
|
7346
|
+
environment:
|
|
7347
|
+
SERVICES: sns,sqs
|
|
7348
|
+
AWS_DEFAULT_REGION: \${AWS_REGION:-us-east-1}
|
|
7349
|
+
AWS_ACCESS_KEY_ID: \${AWS_ACCESS_KEY_ID:-localstack}
|
|
7350
|
+
AWS_SECRET_ACCESS_KEY: \${AWS_SECRET_ACCESS_KEY:-localstack}
|
|
7351
|
+
ports:
|
|
7352
|
+
- '\${LOCALSTACK_PORT:-4566}:4566'
|
|
7353
|
+
volumes:
|
|
7354
|
+
- localstack_data:/var/lib/localstack
|
|
7355
|
+
healthcheck:
|
|
7356
|
+
test: ['CMD', 'curl', '-f', 'http://localhost:4566/_localstack/health']
|
|
7357
|
+
interval: 10s
|
|
7358
|
+
timeout: 5s
|
|
7359
|
+
retries: 5`);
|
|
7360
|
+
volumes.push(" localstack_data:");
|
|
7361
|
+
}
|
|
7362
|
+
if (options.services?.events === "rabbitmq" && !hasWorker) {
|
|
7363
|
+
services.push(` rabbitmq:
|
|
7364
|
+
image: rabbitmq:3-management-alpine
|
|
7365
|
+
container_name: ${options.name}-rabbitmq
|
|
7366
|
+
restart: unless-stopped
|
|
7367
|
+
ports:
|
|
7368
|
+
- '\${RABBITMQ_HOST_PORT:-5672}:5672'
|
|
7369
|
+
- '\${RABBITMQ_MGMT_HOST_PORT:-15672}:15672'
|
|
7370
|
+
environment:
|
|
7371
|
+
RABBITMQ_DEFAULT_USER: guest
|
|
7372
|
+
RABBITMQ_DEFAULT_PASS: guest
|
|
7373
|
+
volumes:
|
|
7374
|
+
- rabbitmq_data:/var/lib/rabbitmq
|
|
7375
|
+
healthcheck:
|
|
7376
|
+
test: ['CMD', 'rabbitmq-diagnostics', 'check_running']
|
|
7377
|
+
interval: 10s
|
|
7378
|
+
timeout: 5s
|
|
7379
|
+
retries: 5`);
|
|
7380
|
+
if (!volumes.includes(" rabbitmq_data:")) volumes.push(" rabbitmq_data:");
|
|
7381
|
+
}
|
|
7252
7382
|
let dockerCompose = `# Use "gkm dev" or "gkm test" to start services.
|
|
7253
7383
|
# Running "docker compose up" directly will not inject secrets or resolve ports.
|
|
7254
7384
|
services:
|
|
@@ -7267,11 +7397,12 @@ ${volumes.join("\n")}
|
|
|
7267
7397
|
/**
|
|
7268
7398
|
* Generate .env file for docker-compose with database passwords
|
|
7269
7399
|
*/
|
|
7270
|
-
function generateDockerEnv(apps) {
|
|
7400
|
+
function generateDockerEnv(apps, eventsBackend) {
|
|
7271
7401
|
const envVars = apps.map((app) => {
|
|
7272
7402
|
const envVar = `${app.name.toUpperCase()}_DB_PASSWORD`;
|
|
7273
7403
|
return `${envVar}=${app.password}`;
|
|
7274
7404
|
});
|
|
7405
|
+
if (eventsBackend === "pgboss") envVars.push(`PGBOSS_DB_PASSWORD=pgboss-dev-password`);
|
|
7275
7406
|
return `# Auto-generated docker environment file
|
|
7276
7407
|
# Contains database passwords for docker-compose postgres init
|
|
7277
7408
|
# This file is gitignored - do not commit to version control
|
|
@@ -7279,33 +7410,50 @@ ${envVars.join("\n")}
|
|
|
7279
7410
|
`;
|
|
7280
7411
|
}
|
|
7281
7412
|
/**
|
|
7282
|
-
* Generate PostgreSQL init shell script that creates per-app users with separate schemas
|
|
7283
|
-
* Uses
|
|
7413
|
+
* Generate PostgreSQL init shell script that creates per-app users with separate schemas.
|
|
7414
|
+
* Uses idempotent DO blocks so the script can be re-run safely.
|
|
7284
7415
|
* - api user: uses public schema
|
|
7285
7416
|
* - auth user: uses auth schema with search_path=auth
|
|
7417
|
+
* - pgboss user: uses pgboss schema (when events === 'pgboss')
|
|
7286
7418
|
*/
|
|
7287
|
-
function generatePostgresInitScript(apps) {
|
|
7419
|
+
function generatePostgresInitScript(apps, eventsBackend) {
|
|
7288
7420
|
const userCreations = apps.map((app) => {
|
|
7289
7421
|
const userName = app.name.replace(/-/g, "_");
|
|
7290
7422
|
const envVar = `${app.name.toUpperCase()}_DB_PASSWORD`;
|
|
7291
7423
|
const isApi = app.name === "api";
|
|
7292
7424
|
const schemaName = isApi ? "public" : userName;
|
|
7293
7425
|
if (isApi) return `
|
|
7294
|
-
# Create ${app.name} user (uses public schema)
|
|
7426
|
+
# Create ${app.name} user (uses public schema) - idempotent
|
|
7295
7427
|
echo "Creating user ${userName}..."
|
|
7296
7428
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
7297
|
-
|
|
7429
|
+
DO \\$\\$
|
|
7430
|
+
BEGIN
|
|
7431
|
+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${userName}') THEN
|
|
7432
|
+
CREATE USER ${userName} WITH PASSWORD '$${envVar}';
|
|
7433
|
+
ELSE
|
|
7434
|
+
ALTER USER ${userName} WITH PASSWORD '$${envVar}';
|
|
7435
|
+
END IF;
|
|
7436
|
+
END
|
|
7437
|
+
\\$\\$;
|
|
7298
7438
|
GRANT ALL ON SCHEMA public TO ${userName};
|
|
7299
7439
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO ${userName};
|
|
7300
7440
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO ${userName};
|
|
7301
7441
|
EOSQL
|
|
7302
7442
|
`;
|
|
7303
7443
|
return `
|
|
7304
|
-
# Create ${app.name} user with dedicated schema
|
|
7444
|
+
# Create ${app.name} user with dedicated schema - idempotent
|
|
7305
7445
|
echo "Creating user ${userName} with schema ${schemaName}..."
|
|
7306
7446
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
7307
|
-
|
|
7308
|
-
|
|
7447
|
+
DO \\$\\$
|
|
7448
|
+
BEGIN
|
|
7449
|
+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${userName}') THEN
|
|
7450
|
+
CREATE USER ${userName} WITH PASSWORD '$${envVar}';
|
|
7451
|
+
ELSE
|
|
7452
|
+
ALTER USER ${userName} WITH PASSWORD '$${envVar}';
|
|
7453
|
+
END IF;
|
|
7454
|
+
END
|
|
7455
|
+
\\$\\$;
|
|
7456
|
+
CREATE SCHEMA IF NOT EXISTS ${schemaName} AUTHORIZATION ${userName};
|
|
7309
7457
|
ALTER USER ${userName} SET search_path TO ${schemaName};
|
|
7310
7458
|
GRANT USAGE ON SCHEMA ${schemaName} TO ${userName};
|
|
7311
7459
|
GRANT ALL ON ALL TABLES IN SCHEMA ${schemaName} TO ${userName};
|
|
@@ -7315,14 +7463,46 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
|
|
|
7315
7463
|
EOSQL
|
|
7316
7464
|
`;
|
|
7317
7465
|
});
|
|
7466
|
+
let pgbossBlock = "";
|
|
7467
|
+
if (eventsBackend === "pgboss") pgbossBlock = `
|
|
7468
|
+
# Create pgboss user with dedicated schema - idempotent
|
|
7469
|
+
echo "Creating pgboss user and schema..."
|
|
7470
|
+
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
7471
|
+
DO \\$\\$
|
|
7472
|
+
BEGIN
|
|
7473
|
+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'pgboss') THEN
|
|
7474
|
+
CREATE USER pgboss WITH PASSWORD '$PGBOSS_DB_PASSWORD';
|
|
7475
|
+
ELSE
|
|
7476
|
+
ALTER USER pgboss WITH PASSWORD '$PGBOSS_DB_PASSWORD';
|
|
7477
|
+
END IF;
|
|
7478
|
+
END
|
|
7479
|
+
\\$\\$;
|
|
7480
|
+
CREATE SCHEMA IF NOT EXISTS pgboss AUTHORIZATION pgboss;
|
|
7481
|
+
ALTER USER pgboss SET search_path TO pgboss;
|
|
7482
|
+
GRANT USAGE ON SCHEMA pgboss TO pgboss;
|
|
7483
|
+
GRANT ALL ON ALL TABLES IN SCHEMA pgboss TO pgboss;
|
|
7484
|
+
GRANT ALL ON ALL SEQUENCES IN SCHEMA pgboss TO pgboss;
|
|
7485
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA pgboss GRANT ALL ON TABLES TO pgboss;
|
|
7486
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA pgboss GRANT ALL ON SEQUENCES TO pgboss;
|
|
7487
|
+
EOSQL
|
|
7488
|
+
`;
|
|
7489
|
+
const extensions = `
|
|
7490
|
+
# Create extensions
|
|
7491
|
+
echo "Creating extensions..."
|
|
7492
|
+
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
7493
|
+
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
|
7494
|
+
CREATE EXTENSION IF NOT EXISTS citext;
|
|
7495
|
+
EOSQL
|
|
7496
|
+
`;
|
|
7318
7497
|
return `#!/bin/bash
|
|
7319
7498
|
set -e
|
|
7320
7499
|
|
|
7321
|
-
# Auto-generated PostgreSQL init script
|
|
7500
|
+
# Auto-generated PostgreSQL init script (idempotent - safe to re-run)
|
|
7322
7501
|
# Creates per-app users with separate schemas in a single database
|
|
7323
7502
|
# - api: uses public schema
|
|
7324
|
-
# - auth: uses auth schema (search_path=auth)
|
|
7325
|
-
${
|
|
7503
|
+
# - auth: uses auth schema (search_path=auth)${eventsBackend === "pgboss" ? "\n# - pgboss: uses pgboss schema for event processing" : ""}
|
|
7504
|
+
${extensions}
|
|
7505
|
+
${userCreations.join("\n")}${pgbossBlock}
|
|
7326
7506
|
echo "Database initialization complete!"
|
|
7327
7507
|
`;
|
|
7328
7508
|
}
|
|
@@ -8814,6 +8994,31 @@ const servicesChoices = [
|
|
|
8814
8994
|
}
|
|
8815
8995
|
];
|
|
8816
8996
|
/**
|
|
8997
|
+
* Event backend choices for prompts
|
|
8998
|
+
*/
|
|
8999
|
+
const eventsBackendChoices = [
|
|
9000
|
+
{
|
|
9001
|
+
title: "pg-boss",
|
|
9002
|
+
value: "pgboss",
|
|
9003
|
+
description: "PostgreSQL-based job queue (reuses postgres, no extra container)"
|
|
9004
|
+
},
|
|
9005
|
+
{
|
|
9006
|
+
title: "SNS/SQS",
|
|
9007
|
+
value: "sns",
|
|
9008
|
+
description: "AWS SNS+SQS via LocalStack for local dev"
|
|
9009
|
+
},
|
|
9010
|
+
{
|
|
9011
|
+
title: "RabbitMQ",
|
|
9012
|
+
value: "rabbitmq",
|
|
9013
|
+
description: "AMQP message broker"
|
|
9014
|
+
},
|
|
9015
|
+
{
|
|
9016
|
+
title: "None",
|
|
9017
|
+
value: void 0,
|
|
9018
|
+
description: "Skip event backend"
|
|
9019
|
+
}
|
|
9020
|
+
];
|
|
9021
|
+
/**
|
|
8817
9022
|
* Get a template by name
|
|
8818
9023
|
*/
|
|
8819
9024
|
function getTemplate(name$1) {
|
|
@@ -10921,6 +11126,13 @@ async function initCommand(projectName, options = {}) {
|
|
|
10921
11126
|
})),
|
|
10922
11127
|
hint: "- Space to select. Return to submit"
|
|
10923
11128
|
},
|
|
11129
|
+
{
|
|
11130
|
+
type: options.yes ? null : "select",
|
|
11131
|
+
name: "eventsBackend",
|
|
11132
|
+
message: "Event backend:",
|
|
11133
|
+
choices: eventsBackendChoices,
|
|
11134
|
+
initial: 0
|
|
11135
|
+
},
|
|
10924
11136
|
{
|
|
10925
11137
|
type: options.yes ? null : "select",
|
|
10926
11138
|
name: "packageManager",
|
|
@@ -10983,12 +11195,15 @@ async function initCommand(projectName, options = {}) {
|
|
|
10983
11195
|
"mail",
|
|
10984
11196
|
"storage"
|
|
10985
11197
|
] : answers.services || [];
|
|
11198
|
+
const eventsBackend = options.yes ? isFullstack ? "pgboss" : void 0 : answers.eventsBackend;
|
|
10986
11199
|
const services = {
|
|
10987
11200
|
db: servicesArray.includes("db"),
|
|
10988
11201
|
cache: servicesArray.includes("cache"),
|
|
10989
11202
|
mail: servicesArray.includes("mail"),
|
|
10990
|
-
storage: servicesArray.includes("storage")
|
|
11203
|
+
storage: servicesArray.includes("storage"),
|
|
11204
|
+
events: eventsBackend
|
|
10991
11205
|
};
|
|
11206
|
+
if (services.events === "pgboss") services.db = true;
|
|
10992
11207
|
const pkgManager = options.pm ? options.pm : options.yes ? "pnpm" : answers.packageManager ?? detectedPkgManager;
|
|
10993
11208
|
const deployTarget = options.yes ? "dokploy" : answers.deployTarget ?? "dokploy";
|
|
10994
11209
|
const database = services.db;
|
|
@@ -11071,7 +11286,12 @@ async function initCommand(projectName, options = {}) {
|
|
|
11071
11286
|
if (services.cache) secretServices.push("redis");
|
|
11072
11287
|
if (services.storage) secretServices.push("minio");
|
|
11073
11288
|
if (services.mail) secretServices.push("mailpit");
|
|
11074
|
-
|
|
11289
|
+
if (services.events === "sns") secretServices.push("localstack");
|
|
11290
|
+
if (services.events === "rabbitmq") secretServices.push("rabbitmq");
|
|
11291
|
+
const devSecrets = createStageSecrets("development", secretServices, {
|
|
11292
|
+
projectName: name$1,
|
|
11293
|
+
eventsBackend: services.events
|
|
11294
|
+
});
|
|
11075
11295
|
const customSecrets = {
|
|
11076
11296
|
NODE_ENV: "development",
|
|
11077
11297
|
PORT: "3000",
|
|
@@ -11511,10 +11731,55 @@ function reconcileSecrets(secrets, workspace) {
|
|
|
11511
11731
|
[name$1]: creds
|
|
11512
11732
|
}
|
|
11513
11733
|
};
|
|
11514
|
-
result.urls = generateConnectionUrls(result.services);
|
|
11734
|
+
result.urls = generateConnectionUrls(result.services, result.eventsBackend);
|
|
11515
11735
|
logger$1.log(` 🔄 Adding missing service credentials: ${name$1}`);
|
|
11516
11736
|
changed = true;
|
|
11517
11737
|
}
|
|
11738
|
+
const eventsBackend = workspace.services.events;
|
|
11739
|
+
if (eventsBackend && result.eventsBackend !== eventsBackend) {
|
|
11740
|
+
result.eventsBackend = eventsBackend;
|
|
11741
|
+
if (eventsBackend === "pgboss" && !result.services.pgboss) {
|
|
11742
|
+
result = {
|
|
11743
|
+
...result,
|
|
11744
|
+
services: {
|
|
11745
|
+
...result.services,
|
|
11746
|
+
pgboss: {
|
|
11747
|
+
host: result.services.postgres?.host ?? "localhost",
|
|
11748
|
+
port: result.services.postgres?.port ?? 5432,
|
|
11749
|
+
username: "pgboss",
|
|
11750
|
+
password: generateSecurePassword(),
|
|
11751
|
+
database: result.services.postgres?.database ?? "app"
|
|
11752
|
+
}
|
|
11753
|
+
}
|
|
11754
|
+
};
|
|
11755
|
+
logger$1.log(" 🔄 Adding missing service credentials: pgboss");
|
|
11756
|
+
changed = true;
|
|
11757
|
+
}
|
|
11758
|
+
if (eventsBackend === "sns" && !result.services.localstack) {
|
|
11759
|
+
result = {
|
|
11760
|
+
...result,
|
|
11761
|
+
services: {
|
|
11762
|
+
...result.services,
|
|
11763
|
+
localstack: generateLocalStackCredentials()
|
|
11764
|
+
}
|
|
11765
|
+
};
|
|
11766
|
+
logger$1.log(" 🔄 Adding missing service credentials: localstack");
|
|
11767
|
+
changed = true;
|
|
11768
|
+
}
|
|
11769
|
+
if (eventsBackend === "rabbitmq" && !result.services.rabbitmq) {
|
|
11770
|
+
result = {
|
|
11771
|
+
...result,
|
|
11772
|
+
services: {
|
|
11773
|
+
...result.services,
|
|
11774
|
+
rabbitmq: generateServiceCredentials("rabbitmq")
|
|
11775
|
+
}
|
|
11776
|
+
};
|
|
11777
|
+
logger$1.log(" 🔄 Adding missing service credentials: rabbitmq");
|
|
11778
|
+
changed = true;
|
|
11779
|
+
}
|
|
11780
|
+
result.urls = generateConnectionUrls(result.services, eventsBackend);
|
|
11781
|
+
changed = true;
|
|
11782
|
+
}
|
|
11518
11783
|
const isMultiApp = Object.keys(workspace.apps).length > 1;
|
|
11519
11784
|
if (isMultiApp) {
|
|
11520
11785
|
const expected = generateFullstackCustomSecrets(workspace);
|
|
@@ -11547,7 +11812,12 @@ async function generateFreshSecrets(stage, workspace, options) {
|
|
|
11547
11812
|
if (workspace.services.cache) serviceNames.push("redis");
|
|
11548
11813
|
if (workspace.services.storage) serviceNames.push("minio");
|
|
11549
11814
|
if (workspace.services.mail) serviceNames.push("mailpit");
|
|
11550
|
-
|
|
11815
|
+
if (workspace.services.events === "sns") serviceNames.push("localstack");
|
|
11816
|
+
if (workspace.services.events === "rabbitmq") serviceNames.push("rabbitmq");
|
|
11817
|
+
const secrets = createStageSecrets(stage, serviceNames, {
|
|
11818
|
+
projectName: workspace.name,
|
|
11819
|
+
eventsBackend: workspace.services.events
|
|
11820
|
+
});
|
|
11551
11821
|
const isMultiApp = Object.keys(workspace.apps).length > 1;
|
|
11552
11822
|
if (isMultiApp) {
|
|
11553
11823
|
const customSecrets = generateFullstackCustomSecrets(workspace);
|
|
@@ -12097,9 +12367,9 @@ program.command("secrets:push").description("Push secrets to remote provider (SS
|
|
|
12097
12367
|
const globalOptions = program.opts();
|
|
12098
12368
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12099
12369
|
const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await import("./config.mjs");
|
|
12100
|
-
const { pushSecrets: pushSecrets$1 } = await import("./sync-
|
|
12101
|
-
const { reconcileMissingSecrets } = await import("./reconcile-
|
|
12102
|
-
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await import("./storage-
|
|
12370
|
+
const { pushSecrets: pushSecrets$1 } = await import("./sync-COnAugP-.mjs");
|
|
12371
|
+
const { reconcileMissingSecrets } = await import("./reconcile-BLh6rswz.mjs");
|
|
12372
|
+
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await import("./storage-Cs4WBsc4.mjs");
|
|
12103
12373
|
const { workspace } = await loadWorkspaceConfig$1();
|
|
12104
12374
|
const secrets = await readStageSecrets$1(options.stage, workspace.root);
|
|
12105
12375
|
if (secrets) {
|
|
@@ -12122,9 +12392,9 @@ program.command("secrets:pull").description("Pull secrets from remote provider (
|
|
|
12122
12392
|
const globalOptions = program.opts();
|
|
12123
12393
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12124
12394
|
const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await import("./config.mjs");
|
|
12125
|
-
const { pullSecrets: pullSecrets$1 } = await import("./sync-
|
|
12126
|
-
const { writeStageSecrets: writeStageSecrets$1 } = await import("./storage-
|
|
12127
|
-
const { reconcileMissingSecrets } = await import("./reconcile-
|
|
12395
|
+
const { pullSecrets: pullSecrets$1 } = await import("./sync-COnAugP-.mjs");
|
|
12396
|
+
const { writeStageSecrets: writeStageSecrets$1 } = await import("./storage-Cs4WBsc4.mjs");
|
|
12397
|
+
const { reconcileMissingSecrets } = await import("./reconcile-BLh6rswz.mjs");
|
|
12128
12398
|
const { workspace } = await loadWorkspaceConfig$1();
|
|
12129
12399
|
let secrets = await pullSecrets$1(options.stage, workspace);
|
|
12130
12400
|
if (!secrets) {
|
|
@@ -12149,8 +12419,8 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
12149
12419
|
const globalOptions = program.opts();
|
|
12150
12420
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12151
12421
|
const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await import("./config.mjs");
|
|
12152
|
-
const { reconcileMissingSecrets } = await import("./reconcile-
|
|
12153
|
-
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await import("./storage-
|
|
12422
|
+
const { reconcileMissingSecrets } = await import("./reconcile-BLh6rswz.mjs");
|
|
12423
|
+
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await import("./storage-Cs4WBsc4.mjs");
|
|
12154
12424
|
const { workspace } = await loadWorkspaceConfig$1();
|
|
12155
12425
|
const secrets = await readStageSecrets$1(options.stage, workspace.root);
|
|
12156
12426
|
if (!secrets) {
|