@geekmidas/cli 1.10.31 → 1.10.32
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 +10 -0
- package/bin/gkm.mjs +1 -1
- package/dist/{CachedStateProvider-3couMAQk.cjs → CachedStateProvider-37pG1HBx.cjs} +1 -1
- package/dist/{CachedStateProvider-CQr31ups.mjs → CachedStateProvider-C8A-cCm5.mjs} +1 -1
- package/dist/{CachedStateProvider-CQr31ups.mjs.map → CachedStateProvider-C8A-cCm5.mjs.map} +1 -1
- package/dist/CachedStateProvider-CC0DyO09.mjs +3 -0
- package/dist/{CachedStateProvider-Cyn17x3x.cjs → CachedStateProvider-CxsXOKkg.cjs} +1 -1
- package/dist/{CachedStateProvider-Cyn17x3x.cjs.map → CachedStateProvider-CxsXOKkg.cjs.map} +1 -1
- package/dist/{HostingerProvider-C5oLa7N7.cjs → HostingerProvider-5KYmwoK2.cjs} +1 -1
- package/dist/{HostingerProvider-C5oLa7N7.cjs.map → HostingerProvider-5KYmwoK2.cjs.map} +1 -1
- package/dist/{HostingerProvider-YvCg3Mus.mjs → HostingerProvider-ANWchdiK.mjs} +1 -1
- package/dist/{HostingerProvider-YvCg3Mus.mjs.map → HostingerProvider-ANWchdiK.mjs.map} +1 -1
- package/dist/{LocalStateProvider-DI6n11UM.cjs → LocalStateProvider-CLifRC0Y.cjs} +1 -1
- package/dist/{LocalStateProvider-DI6n11UM.cjs.map → LocalStateProvider-CLifRC0Y.cjs.map} +1 -1
- package/dist/{LocalStateProvider-BciOhGR0.mjs → LocalStateProvider-Dp0KkRcw.mjs} +1 -1
- package/dist/{LocalStateProvider-BciOhGR0.mjs.map → LocalStateProvider-Dp0KkRcw.mjs.map} +1 -1
- package/dist/{Route53Provider-CYlDOrYO.mjs → Route53Provider-QoPgcXxn.mjs} +1 -1
- package/dist/{Route53Provider-CYlDOrYO.mjs.map → Route53Provider-QoPgcXxn.mjs.map} +1 -1
- package/dist/{Route53Provider-DISZ6E8f.cjs → Route53Provider-owQQ4pn6.cjs} +1 -1
- package/dist/{Route53Provider-DISZ6E8f.cjs.map → Route53Provider-owQQ4pn6.cjs.map} +1 -1
- package/dist/{SSMStateProvider-BljH5efc.cjs → SSMStateProvider-CT8tjl9o.cjs} +1 -1
- package/dist/{SSMStateProvider-BljH5efc.cjs.map → SSMStateProvider-CT8tjl9o.cjs.map} +1 -1
- package/dist/{SSMStateProvider-DXT1dIdI.mjs → SSMStateProvider-CksOTB8M.mjs} +1 -1
- package/dist/{SSMStateProvider-DXT1dIdI.mjs.map → SSMStateProvider-CksOTB8M.mjs.map} +1 -1
- package/dist/{backup-provisioner-CCUcj28C.mjs → backup-provisioner-BEXoHTuC.mjs} +1 -1
- package/dist/{backup-provisioner-CCUcj28C.mjs.map → backup-provisioner-BEXoHTuC.mjs.map} +1 -1
- package/dist/{backup-provisioner-CpirEvO1.cjs → backup-provisioner-C4noe75O.cjs} +1 -1
- package/dist/{backup-provisioner-CpirEvO1.cjs.map → backup-provisioner-C4noe75O.cjs.map} +1 -1
- package/dist/{bundler-CLOenWgi.cjs → bundler-BG6P249p.cjs} +2 -2
- package/dist/{bundler-CLOenWgi.cjs.map → bundler-BG6P249p.cjs.map} +1 -1
- package/dist/{bundler-E5VcXsPH.mjs → bundler-c6QvGUBM.mjs} +2 -2
- package/dist/{bundler-E5VcXsPH.mjs.map → bundler-c6QvGUBM.mjs.map} +1 -1
- package/dist/config.d.mts +2 -2
- package/dist/{dokploy-api-sfZFlWuE.mjs → dokploy-api-BIT0683o.mjs} +1 -1
- package/dist/{dokploy-api-sfZFlWuE.mjs.map → dokploy-api-BIT0683o.mjs.map} +1 -1
- package/dist/dokploy-api-BOx71j6F.cjs +3 -0
- package/dist/dokploy-api-BZGk-lkD.mjs +3 -0
- package/dist/{dokploy-api-CqOIKHme.cjs → dokploy-api-Dvyq-LsM.cjs} +1 -1
- package/dist/{dokploy-api-CqOIKHme.cjs.map → dokploy-api-Dvyq-LsM.cjs.map} +1 -1
- package/dist/{encryption-BVS7Vmzs.cjs → encryption-CipsS0KW.cjs} +1 -1
- package/dist/{encryption-CO5Q4Bhf.mjs → encryption-DSkIlEZ6.mjs} +1 -1
- package/dist/{encryption-CO5Q4Bhf.mjs.map → encryption-DSkIlEZ6.mjs.map} +1 -1
- package/dist/encryption-Db2zvGqM.mjs +3 -0
- package/dist/{encryption-MfXAiFTm.cjs → encryption-DgKS-Dv9.cjs} +1 -1
- package/dist/{encryption-MfXAiFTm.cjs.map → encryption-DgKS-Dv9.cjs.map} +1 -1
- package/dist/{index-C-_rW4KF.d.mts → index-Dt_dZ7K4.d.mts} +2 -2
- package/dist/{index-C-_rW4KF.d.mts.map → index-Dt_dZ7K4.d.mts.map} +1 -1
- package/dist/index.cjs +405 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +381 -57
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-w-_smBTO.cjs → openapi-BQft1jm8.cjs} +36 -6
- package/dist/openapi-BQft1jm8.cjs.map +1 -0
- package/dist/{openapi-DHq5r17U.mjs → openapi-DE8b-vin.mjs} +23 -5
- package/dist/openapi-DE8b-vin.mjs.map +1 -0
- package/dist/{openapi-react-query-COpH7Mmz.mjs → openapi-react-query-C4UdILaI.mjs} +1 -1
- package/dist/{openapi-react-query-COpH7Mmz.mjs.map → openapi-react-query-C4UdILaI.mjs.map} +1 -1
- package/dist/{openapi-react-query-CxyQTTdF.cjs → openapi-react-query-DYbBq-WJ.cjs} +1 -1
- package/dist/{openapi-react-query-CxyQTTdF.cjs.map → openapi-react-query-DYbBq-WJ.cjs.map} +1 -1
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +1 -2
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +1 -2
- package/dist/{reconcile-C8KIy4Uy.cjs → reconcile-CZtzdrnc.cjs} +1 -1
- package/dist/{reconcile-C8KIy4Uy.cjs.map → reconcile-CZtzdrnc.cjs.map} +1 -1
- package/dist/{reconcile-D423q2QW.mjs → reconcile-DAAKa0YR.mjs} +1 -1
- package/dist/{reconcile-D423q2QW.mjs.map → reconcile-DAAKa0YR.mjs.map} +1 -1
- package/dist/{sync-fzT5WX_y.mjs → sync-COnAugP-.mjs} +1 -1
- package/dist/sync-D1Pa30oV.cjs +4 -0
- package/dist/{sync-BWY6yoUG.cjs → sync-DGXXSk2v.cjs} +1 -1
- package/dist/{sync-BWY6yoUG.cjs.map → sync-DGXXSk2v.cjs.map} +1 -1
- package/dist/{sync-Dc-QA4Mx.mjs → sync-D_NowTkZ.mjs} +1 -1
- package/dist/{sync-Dc-QA4Mx.mjs.map → sync-D_NowTkZ.mjs.map} +1 -1
- package/dist/{types-BqAbYt5a.d.mts → types-OszPdw9m.d.mts} +1 -1
- package/dist/{types-BqAbYt5a.d.mts.map → types-OszPdw9m.d.mts.map} +1 -1
- package/dist/workspace/index.d.mts +2 -2
- package/package.json +3 -3
- package/src/build/index.ts +5 -47
- package/src/build/types.ts +5 -0
- package/src/deploy/__tests__/index.spec.ts +1 -3
- package/src/generators/CronGenerator.ts +3 -1
- package/src/generators/EndpointGenerator.ts +6 -2
- package/src/generators/FunctionGenerator.ts +3 -1
- package/src/generators/SubscriberGenerator.ts +3 -1
- package/src/init/generators/docker.ts +2 -2
- package/src/init/versions.ts +1 -1
- package/dist/CachedStateProvider-C4QqvlPE.mjs +0 -3
- package/dist/client-generator-CUVVtAOo.mjs +0 -23
- package/dist/client-generator-CUVVtAOo.mjs.map +0 -1
- package/dist/client-generator-D-T4ypQo.cjs +0 -35
- package/dist/client-generator-D-T4ypQo.cjs.map +0 -1
- package/dist/dokploy-api-BPYkG-ZZ.cjs +0 -3
- package/dist/dokploy-api-BiSzWM4v.mjs +0 -3
- package/dist/encryption-Bd_m4q3g.mjs +0 -3
- package/dist/openapi-DHq5r17U.mjs.map +0 -1
- package/dist/openapi-w-_smBTO.cjs.map +0 -1
- package/dist/sniffer-BqSVVrWA.mjs +0 -356
- package/dist/sniffer-BqSVVrWA.mjs.map +0 -1
- package/dist/sniffer-CBhzByiY.cjs +0 -386
- package/dist/sniffer-CBhzByiY.cjs.map +0 -1
- package/dist/sniffer-Cpq_cbyz.mjs +0 -4
- package/dist/sniffer-eZ13G10M.cjs +0 -4
- package/dist/sync-B2CN_KS5.cjs +0 -4
package/dist/index.cjs
CHANGED
|
@@ -5,14 +5,12 @@ const require_config = require('./config-Cuo8vFsp.cjs');
|
|
|
5
5
|
const require_credentials = require('./credentials-C8DWtnMY.cjs');
|
|
6
6
|
const require_fullstack_secrets = require('./fullstack-secrets-Bchl2MDd.cjs');
|
|
7
7
|
const require_storage = require('./storage-B1wvztiJ.cjs');
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const require_openapi_react_query = require('./openapi-react-query-CxyQTTdF.cjs');
|
|
15
|
-
const require_sync = require('./sync-BWY6yoUG.cjs');
|
|
8
|
+
const require_openapi = require('./openapi-BQft1jm8.cjs');
|
|
9
|
+
const require_dokploy_api = require('./dokploy-api-Dvyq-LsM.cjs');
|
|
10
|
+
const require_encryption = require('./encryption-DgKS-Dv9.cjs');
|
|
11
|
+
const require_CachedStateProvider = require('./CachedStateProvider-CxsXOKkg.cjs');
|
|
12
|
+
const require_openapi_react_query = require('./openapi-react-query-DYbBq-WJ.cjs');
|
|
13
|
+
const require_sync = require('./sync-DGXXSk2v.cjs');
|
|
16
14
|
const node_fs = require_chunk.__toESM(require("node:fs"));
|
|
17
15
|
const node_path = require_chunk.__toESM(require("node:path"));
|
|
18
16
|
const commander = require_chunk.__toESM(require("commander"));
|
|
@@ -32,11 +30,12 @@ const __geekmidas_constructs_subscribers = require_chunk.__toESM(require("@geekm
|
|
|
32
30
|
const pg = require_chunk.__toESM(require("pg"));
|
|
33
31
|
const node_dns_promises = require_chunk.__toESM(require("node:dns/promises"));
|
|
34
32
|
const node_module = require_chunk.__toESM(require("node:module"));
|
|
33
|
+
const node_url = require_chunk.__toESM(require("node:url"));
|
|
35
34
|
const prompts = require_chunk.__toESM(require("prompts"));
|
|
36
35
|
|
|
37
36
|
//#region package.json
|
|
38
37
|
var name = "@geekmidas/cli";
|
|
39
|
-
var version = "1.10.
|
|
38
|
+
var version = "1.10.31";
|
|
40
39
|
var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
|
|
41
40
|
var private$1 = false;
|
|
42
41
|
var type = "module";
|
|
@@ -139,7 +138,7 @@ const logger$14 = console;
|
|
|
139
138
|
* Validate Dokploy token by making a test API call
|
|
140
139
|
*/
|
|
141
140
|
async function validateDokployToken(endpoint, token) {
|
|
142
|
-
const { DokployApi: DokployApi$1 } = await Promise.resolve().then(() => require("./dokploy-api-
|
|
141
|
+
const { DokployApi: DokployApi$1 } = await Promise.resolve().then(() => require("./dokploy-api-BOx71j6F.cjs"));
|
|
143
142
|
const api = new DokployApi$1({
|
|
144
143
|
baseUrl: endpoint,
|
|
145
144
|
token
|
|
@@ -153,7 +152,7 @@ async function prompt$1(message, hidden = false) {
|
|
|
153
152
|
if (!process.stdin.isTTY) throw new Error("Interactive input required. Please provide --token option.");
|
|
154
153
|
if (hidden) {
|
|
155
154
|
process.stdout.write(message);
|
|
156
|
-
return new Promise((resolve$
|
|
155
|
+
return new Promise((resolve$4, reject) => {
|
|
157
156
|
let value = "";
|
|
158
157
|
const cleanup = () => {
|
|
159
158
|
process.stdin.setRawMode(false);
|
|
@@ -170,7 +169,7 @@ async function prompt$1(message, hidden = false) {
|
|
|
170
169
|
if (c === "\n" || c === "\r") {
|
|
171
170
|
cleanup();
|
|
172
171
|
process.stdout.write("\n");
|
|
173
|
-
resolve$
|
|
172
|
+
resolve$4(value);
|
|
174
173
|
} else if (c === "") {
|
|
175
174
|
cleanup();
|
|
176
175
|
process.stdout.write("\n");
|
|
@@ -375,15 +374,15 @@ function loadEnvFiles(envConfig, cwd = process.cwd()) {
|
|
|
375
374
|
* @internal Exported for testing
|
|
376
375
|
*/
|
|
377
376
|
async function isPortAvailable(port) {
|
|
378
|
-
return new Promise((resolve$
|
|
377
|
+
return new Promise((resolve$4) => {
|
|
379
378
|
const server = (0, node_net.createServer)();
|
|
380
379
|
server.once("error", (err) => {
|
|
381
|
-
if (err.code === "EADDRINUSE") resolve$
|
|
382
|
-
else resolve$
|
|
380
|
+
if (err.code === "EADDRINUSE") resolve$4(false);
|
|
381
|
+
else resolve$4(false);
|
|
383
382
|
});
|
|
384
383
|
server.once("listening", () => {
|
|
385
384
|
server.close();
|
|
386
|
-
resolve$
|
|
385
|
+
resolve$4(true);
|
|
387
386
|
});
|
|
388
387
|
server.listen(port);
|
|
389
388
|
});
|
|
@@ -826,7 +825,7 @@ var CronGenerator = class extends require_openapi.ConstructGenerator {
|
|
|
826
825
|
schedule: construct.schedule || "rate(1 hour)",
|
|
827
826
|
timeout: construct.timeout,
|
|
828
827
|
memorySize: construct.memorySize,
|
|
829
|
-
environment: await construct.getEnvironment()
|
|
828
|
+
environment: await construct.getEnvironment({ markOptional: context.markOptional })
|
|
830
829
|
});
|
|
831
830
|
logger$15.log(`Generated cron handler: ${key}`);
|
|
832
831
|
}
|
|
@@ -876,7 +875,7 @@ var FunctionGenerator = class extends require_openapi.ConstructGenerator {
|
|
|
876
875
|
handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
877
876
|
timeout: construct.timeout,
|
|
878
877
|
memorySize: construct.memorySize,
|
|
879
|
-
environment: await construct.getEnvironment()
|
|
878
|
+
environment: await construct.getEnvironment({ markOptional: context.markOptional })
|
|
880
879
|
});
|
|
881
880
|
logger$15.log(`Generated function handler: ${key}`);
|
|
882
881
|
}
|
|
@@ -930,7 +929,7 @@ var SubscriberGenerator = class extends require_openapi.ConstructGenerator {
|
|
|
930
929
|
subscribedEvents: construct.subscribedEvents || [],
|
|
931
930
|
timeout: construct.timeout,
|
|
932
931
|
memorySize: construct.memorySize,
|
|
933
|
-
environment: await construct.getEnvironment()
|
|
932
|
+
environment: await construct.getEnvironment({ markOptional: context.markOptional })
|
|
934
933
|
});
|
|
935
934
|
logger$15.log(`Generated subscriber handler: ${key}`);
|
|
936
935
|
}
|
|
@@ -1141,11 +1140,11 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1141
1140
|
NODE_OPTIONS: nodeOptions
|
|
1142
1141
|
}
|
|
1143
1142
|
});
|
|
1144
|
-
const exitCode = await new Promise((resolve$
|
|
1145
|
-
child.on("close", (code) => resolve$
|
|
1143
|
+
const exitCode = await new Promise((resolve$4) => {
|
|
1144
|
+
child.on("close", (code) => resolve$4(code ?? 0));
|
|
1146
1145
|
child.on("error", (error) => {
|
|
1147
1146
|
logger$12.error(`Failed to run command: ${error.message}`);
|
|
1148
|
-
resolve$
|
|
1147
|
+
resolve$4(1);
|
|
1149
1148
|
});
|
|
1150
1149
|
});
|
|
1151
1150
|
if (exitCode !== 0) process.exit(exitCode);
|
|
@@ -1647,14 +1646,14 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1647
1646
|
};
|
|
1648
1647
|
process.on("SIGINT", shutdown);
|
|
1649
1648
|
process.on("SIGTERM", shutdown);
|
|
1650
|
-
return new Promise((resolve$
|
|
1649
|
+
return new Promise((resolve$4, reject) => {
|
|
1651
1650
|
turboProcess.on("error", (error) => {
|
|
1652
1651
|
logger$11.error("❌ Turbo error:", error);
|
|
1653
1652
|
reject(error);
|
|
1654
1653
|
});
|
|
1655
1654
|
turboProcess.on("exit", (code) => {
|
|
1656
1655
|
if (code !== null && code !== 0) reject(new Error(`Turbo exited with code ${code}`));
|
|
1657
|
-
else resolve$
|
|
1656
|
+
else resolve$4();
|
|
1658
1657
|
});
|
|
1659
1658
|
});
|
|
1660
1659
|
}
|
|
@@ -1766,7 +1765,7 @@ var EntryRunner = class {
|
|
|
1766
1765
|
if (code !== null && code !== 0 && code !== 143) logger$11.error(`❌ Process exited with code ${code}`);
|
|
1767
1766
|
this.isRunning = false;
|
|
1768
1767
|
});
|
|
1769
|
-
await new Promise((resolve$
|
|
1768
|
+
await new Promise((resolve$4) => setTimeout(resolve$4, 500));
|
|
1770
1769
|
if (this.isRunning) {
|
|
1771
1770
|
logger$11.log("");
|
|
1772
1771
|
logger$11.log(` \x1b[32m✓ Ready\x1b[0m at \x1b[36mhttp://localhost:${this.port}\x1b[0m`);
|
|
@@ -1775,7 +1774,7 @@ var EntryRunner = class {
|
|
|
1775
1774
|
}
|
|
1776
1775
|
async restart() {
|
|
1777
1776
|
this.stopProcess();
|
|
1778
|
-
await new Promise((resolve$
|
|
1777
|
+
await new Promise((resolve$4) => setTimeout(resolve$4, 500));
|
|
1779
1778
|
await this.runProcess();
|
|
1780
1779
|
}
|
|
1781
1780
|
stop() {
|
|
@@ -1910,7 +1909,7 @@ var DevServer = class {
|
|
|
1910
1909
|
if (code !== null && code !== 0 && signal !== "SIGTERM") logger$11.error(`❌ Server exited with code ${code}`);
|
|
1911
1910
|
this.isRunning = false;
|
|
1912
1911
|
});
|
|
1913
|
-
await new Promise((resolve$
|
|
1912
|
+
await new Promise((resolve$4) => setTimeout(resolve$4, 1e3));
|
|
1914
1913
|
if (this.isRunning) {
|
|
1915
1914
|
const base = `http://localhost:${this.actualPort}`;
|
|
1916
1915
|
const lines = [` Local: ${base}`];
|
|
@@ -1956,7 +1955,7 @@ var DevServer = class {
|
|
|
1956
1955
|
let attempts = 0;
|
|
1957
1956
|
while (attempts < 30) {
|
|
1958
1957
|
if (await isPortAvailable(portToReuse)) break;
|
|
1959
|
-
await new Promise((resolve$
|
|
1958
|
+
await new Promise((resolve$4) => setTimeout(resolve$4, 100));
|
|
1960
1959
|
attempts++;
|
|
1961
1960
|
}
|
|
1962
1961
|
this.requestedPort = portToReuse;
|
|
@@ -2181,7 +2180,8 @@ async function buildCommand(options) {
|
|
|
2181
2180
|
studio,
|
|
2182
2181
|
hooks,
|
|
2183
2182
|
production,
|
|
2184
|
-
dockerServices
|
|
2183
|
+
dockerServices,
|
|
2184
|
+
markOptional: options.markOptional ?? false
|
|
2185
2185
|
};
|
|
2186
2186
|
const endpointGenerator = new require_openapi.EndpointGenerator();
|
|
2187
2187
|
const functionGenerator = new FunctionGenerator();
|
|
@@ -2203,25 +2203,19 @@ async function buildCommand(options) {
|
|
|
2203
2203
|
}
|
|
2204
2204
|
const rootOutputDir = (0, node_path.join)(process.cwd(), ".gkm");
|
|
2205
2205
|
await (0, node_fs_promises.mkdir)(rootOutputDir, { recursive: true });
|
|
2206
|
-
let optionalVarSet;
|
|
2207
|
-
if (options.markOptional && config.envParser) try {
|
|
2208
|
-
const { _sniffEnvParser } = await Promise.resolve().then(() => require("./sniffer-eZ13G10M.cjs"));
|
|
2209
|
-
const sniffed = await _sniffEnvParser(config.envParser, process.cwd(), process.cwd());
|
|
2210
|
-
if (sniffed.optionalEnvVars.length > 0) optionalVarSet = new Set(sniffed.optionalEnvVars);
|
|
2211
|
-
} catch {}
|
|
2212
2206
|
let result = {};
|
|
2213
2207
|
for (const provider of resolved.providers) {
|
|
2214
|
-
const providerResult = await buildForProvider(provider, buildContext, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, resolved.enableOpenApi, options.skipBundle ?? false, options.stage
|
|
2208
|
+
const providerResult = await buildForProvider(provider, buildContext, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, resolved.enableOpenApi, options.skipBundle ?? false, options.stage);
|
|
2215
2209
|
if (providerResult.masterKey) result = providerResult;
|
|
2216
2210
|
}
|
|
2217
2211
|
await require_openapi.generateOpenApi(config, { bustCache: true });
|
|
2218
2212
|
return result;
|
|
2219
2213
|
}
|
|
2220
|
-
async function buildForProvider(provider, context, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, endpoints, functions, crons, subscribers, enableOpenApi, skipBundle, stage
|
|
2214
|
+
async function buildForProvider(provider, context, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, endpoints, functions, crons, subscribers, enableOpenApi, skipBundle, stage) {
|
|
2221
2215
|
const outputDir = (0, node_path.join)(process.cwd(), ".gkm", provider);
|
|
2222
2216
|
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
2223
2217
|
logger$9.log(`\nGenerating handlers for provider: ${provider}`);
|
|
2224
|
-
const [
|
|
2218
|
+
const [routes, functionInfos, cronInfos, subscriberInfos] = await Promise.all([
|
|
2225
2219
|
endpointGenerator.build(context, endpoints, outputDir, {
|
|
2226
2220
|
provider,
|
|
2227
2221
|
enableOpenApi
|
|
@@ -2230,23 +2224,6 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
|
|
|
2230
2224
|
cronGenerator.build(context, crons, outputDir, { provider }),
|
|
2231
2225
|
subscriberGenerator.build(context, subscribers, outputDir, { provider })
|
|
2232
2226
|
]);
|
|
2233
|
-
const markEnv = optionalVarSet ? (vars) => vars?.map((v) => optionalVarSet.has(v) ? `${v}?` : v) : (vars) => vars;
|
|
2234
|
-
const routes = rawRoutes.map((r) => ({
|
|
2235
|
-
...r,
|
|
2236
|
-
environment: markEnv(r.environment)
|
|
2237
|
-
}));
|
|
2238
|
-
const functionInfos = rawFunctions.map((f) => ({
|
|
2239
|
-
...f,
|
|
2240
|
-
environment: markEnv(f.environment)
|
|
2241
|
-
}));
|
|
2242
|
-
const cronInfos = rawCrons.map((c) => ({
|
|
2243
|
-
...c,
|
|
2244
|
-
environment: markEnv(c.environment)
|
|
2245
|
-
}));
|
|
2246
|
-
const subscriberInfos = rawSubscribers.map((s) => ({
|
|
2247
|
-
...s,
|
|
2248
|
-
environment: markEnv(s.environment)
|
|
2249
|
-
}));
|
|
2250
2227
|
logger$9.log(`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`);
|
|
2251
2228
|
const manifestRoutes = assembleManifestField(routes, endpoints);
|
|
2252
2229
|
const manifestFunctions = assembleManifestField(functionInfos, functions);
|
|
@@ -2268,7 +2245,7 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
|
|
|
2268
2245
|
let masterKey;
|
|
2269
2246
|
if (context.production?.bundle && !skipBundle) {
|
|
2270
2247
|
logger$9.log(`\n📦 Bundling production server...`);
|
|
2271
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
2248
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-BG6P249p.cjs"));
|
|
2272
2249
|
const allConstructs = [
|
|
2273
2250
|
...endpoints.map((e) => e.construct),
|
|
2274
2251
|
...functions.map((f) => f.construct),
|
|
@@ -2338,7 +2315,7 @@ async function workspaceBuildCommand(workspace, options) {
|
|
|
2338
2315
|
try {
|
|
2339
2316
|
const turboCommand = getTurboCommand(pm);
|
|
2340
2317
|
logger$9.log(`Running: ${turboCommand}`);
|
|
2341
|
-
await new Promise((resolve$
|
|
2318
|
+
await new Promise((resolve$4, reject) => {
|
|
2342
2319
|
const child = (0, node_child_process.spawn)(turboCommand, {
|
|
2343
2320
|
shell: true,
|
|
2344
2321
|
cwd: workspace.root,
|
|
@@ -2349,7 +2326,7 @@ async function workspaceBuildCommand(workspace, options) {
|
|
|
2349
2326
|
}
|
|
2350
2327
|
});
|
|
2351
2328
|
child.on("close", (code) => {
|
|
2352
|
-
if (code === 0) resolve$
|
|
2329
|
+
if (code === 0) resolve$4();
|
|
2353
2330
|
else reject(new Error(`Turbo build failed with exit code ${code}`));
|
|
2354
2331
|
});
|
|
2355
2332
|
child.on("error", (err) => {
|
|
@@ -2397,7 +2374,7 @@ function getAppOutputPath(workspace, _appName, app) {
|
|
|
2397
2374
|
* Format routes for logging, handling PartitionedRoutes.
|
|
2398
2375
|
*/
|
|
2399
2376
|
function formatRoutes(routes) {
|
|
2400
|
-
if (
|
|
2377
|
+
if (require_openapi.isPartitionedRoutes(routes)) {
|
|
2401
2378
|
const paths = Array.isArray(routes.paths) ? routes.paths.join(", ") : routes.paths;
|
|
2402
2379
|
return `${paths} (partitioned)`;
|
|
2403
2380
|
}
|
|
@@ -2595,11 +2572,11 @@ async function createDnsProvider(options) {
|
|
|
2595
2572
|
if (isDnsProvider(config.provider)) return config.provider;
|
|
2596
2573
|
const provider = config.provider;
|
|
2597
2574
|
if (provider === "hostinger") {
|
|
2598
|
-
const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-
|
|
2575
|
+
const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-5KYmwoK2.cjs"));
|
|
2599
2576
|
return new HostingerProvider();
|
|
2600
2577
|
}
|
|
2601
2578
|
if (provider === "route53") {
|
|
2602
|
-
const { Route53Provider } = await Promise.resolve().then(() => require("./Route53Provider-
|
|
2579
|
+
const { Route53Provider } = await Promise.resolve().then(() => require("./Route53Provider-owQQ4pn6.cjs"));
|
|
2603
2580
|
const route53Config = config;
|
|
2604
2581
|
return new Route53Provider({
|
|
2605
2582
|
region: route53Config.region,
|
|
@@ -5070,20 +5047,20 @@ function isStateProvider(value) {
|
|
|
5070
5047
|
async function createStateProvider(options) {
|
|
5071
5048
|
const { config, workspaceRoot, workspaceName } = options;
|
|
5072
5049
|
if (!config) {
|
|
5073
|
-
const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-
|
|
5050
|
+
const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
|
|
5074
5051
|
return new LocalStateProvider(workspaceRoot);
|
|
5075
5052
|
}
|
|
5076
5053
|
if (isStateProvider(config.provider)) return config.provider;
|
|
5077
5054
|
const provider = config.provider;
|
|
5078
5055
|
if (provider === "local") {
|
|
5079
|
-
const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-
|
|
5056
|
+
const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
|
|
5080
5057
|
return new LocalStateProvider(workspaceRoot);
|
|
5081
5058
|
}
|
|
5082
5059
|
if (provider === "ssm") {
|
|
5083
5060
|
if (!workspaceName) throw new Error("Workspace name is required for SSM state provider. Set \"name\" in gkm.config.ts.");
|
|
5084
|
-
const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-
|
|
5085
|
-
const { SSMStateProvider } = await Promise.resolve().then(() => require("./SSMStateProvider-
|
|
5086
|
-
const { CachedStateProvider: CachedStateProvider$1 } = await Promise.resolve().then(() => require("./CachedStateProvider-
|
|
5061
|
+
const { LocalStateProvider } = await Promise.resolve().then(() => require("./LocalStateProvider-CLifRC0Y.cjs"));
|
|
5062
|
+
const { SSMStateProvider } = await Promise.resolve().then(() => require("./SSMStateProvider-CT8tjl9o.cjs"));
|
|
5063
|
+
const { CachedStateProvider: CachedStateProvider$1 } = await Promise.resolve().then(() => require("./CachedStateProvider-37pG1HBx.cjs"));
|
|
5087
5064
|
const ssmConfig = config;
|
|
5088
5065
|
const local = new LocalStateProvider(workspaceRoot);
|
|
5089
5066
|
const ssm = SSMStateProvider.create({
|
|
@@ -5193,6 +5170,353 @@ function generateSecretsReport(encryptedApps, sniffedApps) {
|
|
|
5193
5170
|
};
|
|
5194
5171
|
}
|
|
5195
5172
|
|
|
5173
|
+
//#endregion
|
|
5174
|
+
//#region src/deploy/sniffer.ts
|
|
5175
|
+
const __filename$1 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
5176
|
+
const __dirname$1 = (0, node_path.dirname)(__filename$1);
|
|
5177
|
+
/**
|
|
5178
|
+
* Resolve the tsx package path from the CLI package's dependencies.
|
|
5179
|
+
* This ensures tsx is available regardless of whether the target project has it installed.
|
|
5180
|
+
*/
|
|
5181
|
+
function resolveTsxPath() {
|
|
5182
|
+
const require$2 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
5183
|
+
return require$2.resolve("tsx");
|
|
5184
|
+
}
|
|
5185
|
+
/**
|
|
5186
|
+
* Resolve the path to a sniffer helper file.
|
|
5187
|
+
* Handles both dev (.ts with tsx) and production (.mjs from dist).
|
|
5188
|
+
*
|
|
5189
|
+
* In production: sniffer.ts is bundled into dist/index.mjs, but sniffer helper
|
|
5190
|
+
* files are output to dist/deploy/ as standalone modules for subprocess loading.
|
|
5191
|
+
*
|
|
5192
|
+
* In development: All files are in src/deploy/ and loaded via tsx.
|
|
5193
|
+
*/
|
|
5194
|
+
function resolveSnifferFile(baseName) {
|
|
5195
|
+
const deployMjsPath = (0, node_path.resolve)(__dirname$1, "deploy", `${baseName}.mjs`);
|
|
5196
|
+
if ((0, node_fs.existsSync)(deployMjsPath)) return deployMjsPath;
|
|
5197
|
+
const mjsPath = (0, node_path.resolve)(__dirname$1, `${baseName}.mjs`);
|
|
5198
|
+
if ((0, node_fs.existsSync)(mjsPath)) return mjsPath;
|
|
5199
|
+
const tsPath = (0, node_path.resolve)(__dirname$1, `${baseName}.ts`);
|
|
5200
|
+
if ((0, node_fs.existsSync)(tsPath)) return tsPath;
|
|
5201
|
+
return tsPath;
|
|
5202
|
+
}
|
|
5203
|
+
/**
|
|
5204
|
+
* Get required environment variables for an app.
|
|
5205
|
+
*
|
|
5206
|
+
* Detection strategy (in order):
|
|
5207
|
+
* 1. Frontend apps: Returns empty (no server secrets)
|
|
5208
|
+
* 2. Apps with `requiredEnv`: Uses explicit list from config
|
|
5209
|
+
* 3. Entry apps: Imports entry file in subprocess to capture config.parse() calls
|
|
5210
|
+
* 4. Route-based apps: Loads route files and calls getEnvironment() on each construct
|
|
5211
|
+
* 5. Apps with `envParser` (no routes): Runs SnifferEnvironmentParser to detect usage
|
|
5212
|
+
* 6. Apps with neither: Returns empty
|
|
5213
|
+
*
|
|
5214
|
+
* This function handles "fire and forget" async operations gracefully,
|
|
5215
|
+
* capturing errors and unhandled rejections without failing the build.
|
|
5216
|
+
*
|
|
5217
|
+
* @param app - The normalized app configuration
|
|
5218
|
+
* @param appName - The name of the app
|
|
5219
|
+
* @param workspacePath - Absolute path to the workspace root
|
|
5220
|
+
* @param options - Optional configuration for sniffing behavior
|
|
5221
|
+
* @returns The sniffed environment with required variables
|
|
5222
|
+
*/
|
|
5223
|
+
async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
|
|
5224
|
+
const { logWarnings = true, markOptional = false } = options;
|
|
5225
|
+
if (app.type === "frontend") {
|
|
5226
|
+
const depVars = (app.dependencies ?? []).map((dep) => `NEXT_PUBLIC_${dep.toUpperCase()}_URL`);
|
|
5227
|
+
if (app.config) {
|
|
5228
|
+
const sniffedVars = [];
|
|
5229
|
+
const sniffedOptional = [];
|
|
5230
|
+
const configPaths = [];
|
|
5231
|
+
if (app.config.client) configPaths.push(app.config.client);
|
|
5232
|
+
if (app.config.server) configPaths.push(app.config.server);
|
|
5233
|
+
for (const configPath of configPaths) {
|
|
5234
|
+
const result = await sniffEntryFile(configPath, app.path, workspacePath);
|
|
5235
|
+
if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Config file "${configPath}" threw error during sniffing (env vars still captured): ${result.error.message}`);
|
|
5236
|
+
sniffedVars.push(...result.envVars);
|
|
5237
|
+
sniffedOptional.push(...result.optionalEnvVars);
|
|
5238
|
+
}
|
|
5239
|
+
const optionalEnvVars = [...new Set(sniffedOptional)];
|
|
5240
|
+
const allVars = applyMarkOptional([...new Set([...depVars, ...sniffedVars])], optionalEnvVars, markOptional);
|
|
5241
|
+
return {
|
|
5242
|
+
appName,
|
|
5243
|
+
requiredEnvVars: allVars,
|
|
5244
|
+
optionalEnvVars
|
|
5245
|
+
};
|
|
5246
|
+
}
|
|
5247
|
+
return {
|
|
5248
|
+
appName,
|
|
5249
|
+
requiredEnvVars: depVars,
|
|
5250
|
+
optionalEnvVars: []
|
|
5251
|
+
};
|
|
5252
|
+
}
|
|
5253
|
+
if (app.entry) {
|
|
5254
|
+
const result = await sniffEntryFile(app.entry, app.path, workspacePath);
|
|
5255
|
+
if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Entry file threw error during sniffing (env vars still captured): ${result.error.message}`);
|
|
5256
|
+
return {
|
|
5257
|
+
appName,
|
|
5258
|
+
requiredEnvVars: applyMarkOptional(result.envVars, result.optionalEnvVars, markOptional),
|
|
5259
|
+
optionalEnvVars: result.optionalEnvVars
|
|
5260
|
+
};
|
|
5261
|
+
}
|
|
5262
|
+
if (app.routes) {
|
|
5263
|
+
const result = await sniffRouteFiles(require_openapi.normalizeRoutes(app.routes), app.path, workspacePath);
|
|
5264
|
+
if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Route sniffing threw error (env vars still captured): ${result.error.message}`);
|
|
5265
|
+
return {
|
|
5266
|
+
appName,
|
|
5267
|
+
requiredEnvVars: applyMarkOptional(result.envVars, result.optionalEnvVars, markOptional),
|
|
5268
|
+
optionalEnvVars: result.optionalEnvVars
|
|
5269
|
+
};
|
|
5270
|
+
}
|
|
5271
|
+
if (app.envParser) {
|
|
5272
|
+
const result = await sniffEnvParser(app.envParser, app.path, workspacePath);
|
|
5273
|
+
if (logWarnings) {
|
|
5274
|
+
if (result.error) console.warn(`[sniffer] ${appName}: envParser threw error during sniffing (env vars still captured): ${result.error.message}`);
|
|
5275
|
+
if (result.unhandledRejections.length > 0) console.warn(`[sniffer] ${appName}: Fire-and-forget rejections during sniffing (suppressed): ${result.unhandledRejections.map((e) => e.message).join(", ")}`);
|
|
5276
|
+
}
|
|
5277
|
+
return {
|
|
5278
|
+
appName,
|
|
5279
|
+
requiredEnvVars: applyMarkOptional(result.envVars, result.optionalEnvVars, markOptional),
|
|
5280
|
+
optionalEnvVars: result.optionalEnvVars
|
|
5281
|
+
};
|
|
5282
|
+
}
|
|
5283
|
+
return {
|
|
5284
|
+
appName,
|
|
5285
|
+
requiredEnvVars: [],
|
|
5286
|
+
optionalEnvVars: []
|
|
5287
|
+
};
|
|
5288
|
+
}
|
|
5289
|
+
/**
|
|
5290
|
+
* Apply the `?` suffix to optional variables in an env var list.
|
|
5291
|
+
* Only modifies the list when `markOptional` is true and there are optional vars.
|
|
5292
|
+
*/
|
|
5293
|
+
function applyMarkOptional(envVars, optionalEnvVars, markOptional) {
|
|
5294
|
+
if (!markOptional || optionalEnvVars.length === 0) return envVars;
|
|
5295
|
+
const optionalSet = new Set(optionalEnvVars);
|
|
5296
|
+
return envVars.map((v) => optionalSet.has(v) ? `${v}?` : v);
|
|
5297
|
+
}
|
|
5298
|
+
/**
|
|
5299
|
+
* Sniff an entry file by importing it in a subprocess.
|
|
5300
|
+
*
|
|
5301
|
+
* Entry apps call `config.parse()` at module load time. To capture which
|
|
5302
|
+
* env vars are accessed, we:
|
|
5303
|
+
* 1. Spawn a subprocess with a module loader hook
|
|
5304
|
+
* 2. The loader intercepts `@geekmidas/envkit` and replaces EnvironmentParser
|
|
5305
|
+
* with SnifferEnvironmentParser
|
|
5306
|
+
* 3. Import the entry file (triggers config.parse())
|
|
5307
|
+
* 4. Capture and return the accessed env var names
|
|
5308
|
+
*
|
|
5309
|
+
* This approach provides process isolation - each app is sniffed in its own
|
|
5310
|
+
* subprocess, preventing module cache pollution.
|
|
5311
|
+
*
|
|
5312
|
+
* @param entryPath - Relative path to the entry file (e.g., './src/index.ts')
|
|
5313
|
+
* @param appPath - The app's path relative to workspace (e.g., 'apps/auth')
|
|
5314
|
+
* @param workspacePath - Absolute path to workspace root
|
|
5315
|
+
* @returns EntrySniffResult with env vars and optional error
|
|
5316
|
+
*/
|
|
5317
|
+
async function sniffEntryFile(entryPath, appPath, workspacePath) {
|
|
5318
|
+
const fullEntryPath = (0, node_path.resolve)(workspacePath, appPath, entryPath);
|
|
5319
|
+
const loaderPath = resolveSnifferFile("sniffer-loader");
|
|
5320
|
+
const workerPath = resolveSnifferFile("sniffer-worker");
|
|
5321
|
+
return new Promise((resolvePromise) => {
|
|
5322
|
+
const child = (0, node_child_process.spawn)("node", [
|
|
5323
|
+
"--import",
|
|
5324
|
+
loaderPath,
|
|
5325
|
+
workerPath,
|
|
5326
|
+
fullEntryPath
|
|
5327
|
+
], {
|
|
5328
|
+
cwd: (0, node_path.resolve)(workspacePath, appPath),
|
|
5329
|
+
stdio: [
|
|
5330
|
+
"ignore",
|
|
5331
|
+
"pipe",
|
|
5332
|
+
"pipe"
|
|
5333
|
+
],
|
|
5334
|
+
env: {
|
|
5335
|
+
...process.env,
|
|
5336
|
+
NODE_OPTIONS: "--import=tsx"
|
|
5337
|
+
}
|
|
5338
|
+
});
|
|
5339
|
+
let stdout = "";
|
|
5340
|
+
let stderr = "";
|
|
5341
|
+
child.stdout.on("data", (data) => {
|
|
5342
|
+
stdout += data.toString();
|
|
5343
|
+
});
|
|
5344
|
+
child.stderr.on("data", (data) => {
|
|
5345
|
+
stderr += data.toString();
|
|
5346
|
+
});
|
|
5347
|
+
child.on("close", (code) => {
|
|
5348
|
+
try {
|
|
5349
|
+
const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
|
|
5350
|
+
if (jsonMatch) {
|
|
5351
|
+
const result = JSON.parse(jsonMatch[0]);
|
|
5352
|
+
resolvePromise({
|
|
5353
|
+
envVars: result.envVars || [],
|
|
5354
|
+
optionalEnvVars: result.optionalEnvVars || [],
|
|
5355
|
+
error: result.error ? new Error(result.error) : void 0
|
|
5356
|
+
});
|
|
5357
|
+
return;
|
|
5358
|
+
}
|
|
5359
|
+
} catch {}
|
|
5360
|
+
resolvePromise({
|
|
5361
|
+
envVars: [],
|
|
5362
|
+
optionalEnvVars: [],
|
|
5363
|
+
error: new Error(`Failed to sniff entry file (exit code ${code}): ${stderr || stdout || "No output"}`)
|
|
5364
|
+
});
|
|
5365
|
+
});
|
|
5366
|
+
child.on("error", (err) => {
|
|
5367
|
+
resolvePromise({
|
|
5368
|
+
envVars: [],
|
|
5369
|
+
optionalEnvVars: [],
|
|
5370
|
+
error: err
|
|
5371
|
+
});
|
|
5372
|
+
});
|
|
5373
|
+
});
|
|
5374
|
+
}
|
|
5375
|
+
/**
|
|
5376
|
+
* Sniff route files by loading constructs and calling getEnvironment().
|
|
5377
|
+
*
|
|
5378
|
+
* Route-based apps have endpoints, functions, crons, and subscribers that
|
|
5379
|
+
* use services. Each service's register() method accesses environment variables.
|
|
5380
|
+
*
|
|
5381
|
+
* This runs in a subprocess with tsx loader to properly handle TypeScript
|
|
5382
|
+
* compilation and path alias resolution (e.g., `src/...` imports).
|
|
5383
|
+
*
|
|
5384
|
+
* @param routes - Glob pattern(s) for route files
|
|
5385
|
+
* @param appPath - The app's path relative to workspace (e.g., 'apps/api')
|
|
5386
|
+
* @param workspacePath - Absolute path to workspace root
|
|
5387
|
+
* @returns EntrySniffResult with env vars and optional error
|
|
5388
|
+
*/
|
|
5389
|
+
async function sniffRouteFiles(routes, appPath, workspacePath) {
|
|
5390
|
+
const fullAppPath = (0, node_path.resolve)(workspacePath, appPath);
|
|
5391
|
+
const workerPath = resolveSnifferFile("sniffer-routes-worker");
|
|
5392
|
+
const tsxPath = resolveTsxPath();
|
|
5393
|
+
const routesArray = Array.isArray(routes) ? routes : [routes];
|
|
5394
|
+
const pattern = routesArray[0];
|
|
5395
|
+
if (!pattern) return {
|
|
5396
|
+
envVars: [],
|
|
5397
|
+
optionalEnvVars: [],
|
|
5398
|
+
error: new Error("No route patterns provided")
|
|
5399
|
+
};
|
|
5400
|
+
return new Promise((resolvePromise) => {
|
|
5401
|
+
const child = (0, node_child_process.spawn)("node", [
|
|
5402
|
+
"--import",
|
|
5403
|
+
tsxPath,
|
|
5404
|
+
workerPath,
|
|
5405
|
+
fullAppPath,
|
|
5406
|
+
pattern
|
|
5407
|
+
], {
|
|
5408
|
+
cwd: fullAppPath,
|
|
5409
|
+
stdio: [
|
|
5410
|
+
"ignore",
|
|
5411
|
+
"pipe",
|
|
5412
|
+
"pipe"
|
|
5413
|
+
],
|
|
5414
|
+
env: { ...process.env }
|
|
5415
|
+
});
|
|
5416
|
+
let stdout = "";
|
|
5417
|
+
let stderr = "";
|
|
5418
|
+
child.stdout.on("data", (data) => {
|
|
5419
|
+
stdout += data.toString();
|
|
5420
|
+
});
|
|
5421
|
+
child.stderr.on("data", (data) => {
|
|
5422
|
+
stderr += data.toString();
|
|
5423
|
+
});
|
|
5424
|
+
child.on("close", (code) => {
|
|
5425
|
+
if (stderr) stderr.split("\n").filter((line) => line.trim()).forEach((line) => console.warn(line));
|
|
5426
|
+
try {
|
|
5427
|
+
const jsonMatch = stdout.match(/\{[^{}]*"envVars"[^{}]*\}[^{]*$/);
|
|
5428
|
+
if (jsonMatch) {
|
|
5429
|
+
const result = JSON.parse(jsonMatch[0]);
|
|
5430
|
+
resolvePromise({
|
|
5431
|
+
envVars: result.envVars || [],
|
|
5432
|
+
optionalEnvVars: result.optionalEnvVars || [],
|
|
5433
|
+
error: result.error ? new Error(result.error) : void 0
|
|
5434
|
+
});
|
|
5435
|
+
return;
|
|
5436
|
+
}
|
|
5437
|
+
} catch {}
|
|
5438
|
+
resolvePromise({
|
|
5439
|
+
envVars: [],
|
|
5440
|
+
optionalEnvVars: [],
|
|
5441
|
+
error: new Error(`Failed to sniff route files (exit code ${code}): ${stderr || stdout || "No output"}`)
|
|
5442
|
+
});
|
|
5443
|
+
});
|
|
5444
|
+
child.on("error", (err) => {
|
|
5445
|
+
resolvePromise({
|
|
5446
|
+
envVars: [],
|
|
5447
|
+
optionalEnvVars: [],
|
|
5448
|
+
error: err
|
|
5449
|
+
});
|
|
5450
|
+
});
|
|
5451
|
+
});
|
|
5452
|
+
}
|
|
5453
|
+
/**
|
|
5454
|
+
* Run the SnifferEnvironmentParser on an envParser module to detect
|
|
5455
|
+
* which environment variables it accesses.
|
|
5456
|
+
*
|
|
5457
|
+
* This function handles "fire and forget" async operations by using
|
|
5458
|
+
* the shared sniffWithFireAndForget utility from @geekmidas/envkit.
|
|
5459
|
+
*
|
|
5460
|
+
* @param envParserPath - The envParser config (e.g., './src/config/env#envParser')
|
|
5461
|
+
* @param appPath - The app's path relative to workspace
|
|
5462
|
+
* @param workspacePath - Absolute path to workspace root
|
|
5463
|
+
* @returns SniffResult with env vars and any errors encountered
|
|
5464
|
+
*/
|
|
5465
|
+
async function sniffEnvParser(envParserPath, appPath, workspacePath) {
|
|
5466
|
+
const [modulePath, exportName = "default"] = envParserPath.split("#");
|
|
5467
|
+
if (!modulePath) return {
|
|
5468
|
+
envVars: [],
|
|
5469
|
+
optionalEnvVars: [],
|
|
5470
|
+
unhandledRejections: []
|
|
5471
|
+
};
|
|
5472
|
+
const fullPath = (0, node_path.resolve)(workspacePath, appPath, modulePath);
|
|
5473
|
+
let SnifferEnvironmentParser;
|
|
5474
|
+
let sniffWithFireAndForget;
|
|
5475
|
+
try {
|
|
5476
|
+
const envkitModule = await import("@geekmidas/envkit/sniffer");
|
|
5477
|
+
SnifferEnvironmentParser = envkitModule.SnifferEnvironmentParser;
|
|
5478
|
+
sniffWithFireAndForget = envkitModule.sniffWithFireAndForget;
|
|
5479
|
+
} catch (error) {
|
|
5480
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5481
|
+
console.warn(`[sniffer] Failed to import SnifferEnvironmentParser: ${message}`);
|
|
5482
|
+
return {
|
|
5483
|
+
envVars: [],
|
|
5484
|
+
optionalEnvVars: [],
|
|
5485
|
+
unhandledRejections: []
|
|
5486
|
+
};
|
|
5487
|
+
}
|
|
5488
|
+
const sniffer = new SnifferEnvironmentParser();
|
|
5489
|
+
return sniffWithFireAndForget(sniffer, async () => {
|
|
5490
|
+
const moduleUrl = (0, node_url.pathToFileURL)(fullPath).href;
|
|
5491
|
+
const module$1 = await import(moduleUrl);
|
|
5492
|
+
const envParser = module$1[exportName];
|
|
5493
|
+
if (typeof envParser !== "function") {
|
|
5494
|
+
console.warn(`[sniffer] Export "${exportName}" from "${modulePath}" is not a function`);
|
|
5495
|
+
return;
|
|
5496
|
+
}
|
|
5497
|
+
const result = envParser(sniffer);
|
|
5498
|
+
if (result && typeof result.parse === "function") try {
|
|
5499
|
+
result.parse();
|
|
5500
|
+
} catch {}
|
|
5501
|
+
});
|
|
5502
|
+
}
|
|
5503
|
+
/**
|
|
5504
|
+
* Sniff environment requirements for multiple apps.
|
|
5505
|
+
*
|
|
5506
|
+
* @param apps - Map of app name to app config
|
|
5507
|
+
* @param workspacePath - Absolute path to workspace root
|
|
5508
|
+
* @param options - Optional configuration for sniffing behavior
|
|
5509
|
+
* @returns Map of app name to sniffed environment
|
|
5510
|
+
*/
|
|
5511
|
+
async function sniffAllApps(apps, workspacePath, options = {}) {
|
|
5512
|
+
const results = /* @__PURE__ */ new Map();
|
|
5513
|
+
for (const [appName, app] of Object.entries(apps)) {
|
|
5514
|
+
const sniffed = await sniffAppEnvironment(app, appName, workspacePath, options);
|
|
5515
|
+
results.set(appName, sniffed);
|
|
5516
|
+
}
|
|
5517
|
+
return results;
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5196
5520
|
//#endregion
|
|
5197
5521
|
//#region src/deploy/index.ts
|
|
5198
5522
|
const logger$3 = console;
|
|
@@ -5203,7 +5527,7 @@ async function prompt(message, hidden = false) {
|
|
|
5203
5527
|
if (!process.stdin.isTTY) throw new Error("Interactive input required. Please configure manually.");
|
|
5204
5528
|
if (hidden) {
|
|
5205
5529
|
process.stdout.write(message);
|
|
5206
|
-
return new Promise((resolve$
|
|
5530
|
+
return new Promise((resolve$4) => {
|
|
5207
5531
|
let value = "";
|
|
5208
5532
|
const onData = (char) => {
|
|
5209
5533
|
const c = char.toString();
|
|
@@ -5212,7 +5536,7 @@ async function prompt(message, hidden = false) {
|
|
|
5212
5536
|
process.stdin.pause();
|
|
5213
5537
|
process.stdin.removeListener("data", onData);
|
|
5214
5538
|
process.stdout.write("\n");
|
|
5215
|
-
resolve$
|
|
5539
|
+
resolve$4(value);
|
|
5216
5540
|
} else if (c === "") {
|
|
5217
5541
|
process.stdin.setRawMode(false);
|
|
5218
5542
|
process.stdin.pause();
|
|
@@ -5687,7 +6011,7 @@ async function workspaceDeployCommand(workspace, options) {
|
|
|
5687
6011
|
logger$3.log(` ⚠️ No secrets found for stage "${stage}"`);
|
|
5688
6012
|
logger$3.log(` Run "gkm secrets:init --stage ${stage}" to create secrets`);
|
|
5689
6013
|
}
|
|
5690
|
-
const sniffedApps = await
|
|
6014
|
+
const sniffedApps = await sniffAllApps(workspace.apps, workspace.root);
|
|
5691
6015
|
const encryptedSecrets = stageSecrets ? prepareSecretsForAllApps(stageSecrets, sniffedApps) : /* @__PURE__ */ new Map();
|
|
5692
6016
|
if (stageSecrets) {
|
|
5693
6017
|
const report = generateSecretsReport(encryptedSecrets, sniffedApps);
|
|
@@ -5862,7 +6186,7 @@ async function workspaceDeployCommand(workspace, options) {
|
|
|
5862
6186
|
}
|
|
5863
6187
|
if (workspace.deploy?.backups && provisionedPostgres) {
|
|
5864
6188
|
logger$3.log("\n💾 Provisioning backup destination...");
|
|
5865
|
-
const { provisionBackupDestination } = await Promise.resolve().then(() => require("./backup-provisioner-
|
|
6189
|
+
const { provisionBackupDestination } = await Promise.resolve().then(() => require("./backup-provisioner-C4noe75O.cjs"));
|
|
5866
6190
|
const backupState = await provisionBackupDestination({
|
|
5867
6191
|
api,
|
|
5868
6192
|
projectId: project.projectId,
|
|
@@ -6517,7 +6841,7 @@ const GEEKMIDAS_VERSIONS = {
|
|
|
6517
6841
|
"@geekmidas/constructs": "~3.0.7",
|
|
6518
6842
|
"@geekmidas/db": "~1.0.1",
|
|
6519
6843
|
"@geekmidas/emailkit": "~1.0.0",
|
|
6520
|
-
"@geekmidas/envkit": "~1.0.
|
|
6844
|
+
"@geekmidas/envkit": "~1.0.5",
|
|
6521
6845
|
"@geekmidas/errors": "~1.0.0",
|
|
6522
6846
|
"@geekmidas/events": "~1.1.0",
|
|
6523
6847
|
"@geekmidas/logger": "~1.0.0",
|
|
@@ -7162,7 +7486,7 @@ ${volumes.join("\n")}
|
|
|
7162
7486
|
/**
|
|
7163
7487
|
* Generate .env file for docker-compose with database passwords
|
|
7164
7488
|
*/
|
|
7165
|
-
function generateDockerEnv(apps,
|
|
7489
|
+
function generateDockerEnv(apps, _eventsBackend) {
|
|
7166
7490
|
const envVars = apps.map((app) => {
|
|
7167
7491
|
const envVar = `${app.name.toUpperCase()}_DB_PASSWORD`;
|
|
7168
7492
|
return `${envVar}=${app.password}`;
|
|
@@ -7181,7 +7505,7 @@ ${envVars.join("\n")}
|
|
|
7181
7505
|
* - auth user: uses auth schema with search_path=auth
|
|
7182
7506
|
* - pgboss user: uses pgboss schema (when events === 'pgboss')
|
|
7183
7507
|
*/
|
|
7184
|
-
function generatePostgresInitScript(apps,
|
|
7508
|
+
function generatePostgresInitScript(apps, _eventsBackend) {
|
|
7185
7509
|
const userCreations = apps.map((app) => {
|
|
7186
7510
|
const userName = app.name.replace(/-/g, "_");
|
|
7187
7511
|
const envVar = `${app.name.toUpperCase()}_DB_PASSWORD`;
|
|
@@ -11707,7 +12031,7 @@ async function testCommand(options = {}) {
|
|
|
11707
12031
|
});
|
|
11708
12032
|
let finalCredentials = { ...result.credentials };
|
|
11709
12033
|
if (result.appInfo) {
|
|
11710
|
-
const sniffed = await
|
|
12034
|
+
const sniffed = await sniffAppEnvironment(result.appInfo.app, result.appInfo.appName, result.appInfo.workspaceRoot, { logWarnings: false });
|
|
11711
12035
|
if (sniffed.requiredEnvVars.length > 0) {
|
|
11712
12036
|
const needed = new Set(sniffed.requiredEnvVars);
|
|
11713
12037
|
const filtered = {};
|
|
@@ -11746,9 +12070,9 @@ async function testCommand(options = {}) {
|
|
|
11746
12070
|
NODE_OPTIONS: nodeOptions
|
|
11747
12071
|
}
|
|
11748
12072
|
});
|
|
11749
|
-
return new Promise((resolve$
|
|
12073
|
+
return new Promise((resolve$4, reject) => {
|
|
11750
12074
|
vitestProcess.on("close", (code) => {
|
|
11751
|
-
if (code === 0) resolve$
|
|
12075
|
+
if (code === 0) resolve$4();
|
|
11752
12076
|
else reject(new Error(`Tests failed with exit code ${code}`));
|
|
11753
12077
|
});
|
|
11754
12078
|
vitestProcess.on("error", (error) => {
|
|
@@ -12151,8 +12475,8 @@ program.command("secrets:push").description("Push secrets to remote provider (SS
|
|
|
12151
12475
|
const globalOptions = program.opts();
|
|
12152
12476
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12153
12477
|
const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
12154
|
-
const { pushSecrets: pushSecrets$1 } = await Promise.resolve().then(() => require("./sync-
|
|
12155
|
-
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-
|
|
12478
|
+
const { pushSecrets: pushSecrets$1 } = await Promise.resolve().then(() => require("./sync-D1Pa30oV.cjs"));
|
|
12479
|
+
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CZtzdrnc.cjs"));
|
|
12156
12480
|
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
|
|
12157
12481
|
const { workspace } = await loadWorkspaceConfig$1();
|
|
12158
12482
|
const secrets = await readStageSecrets$1(options.stage, workspace.root);
|
|
@@ -12176,9 +12500,9 @@ program.command("secrets:pull").description("Pull secrets from remote provider (
|
|
|
12176
12500
|
const globalOptions = program.opts();
|
|
12177
12501
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12178
12502
|
const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
12179
|
-
const { pullSecrets: pullSecrets$1 } = await Promise.resolve().then(() => require("./sync-
|
|
12503
|
+
const { pullSecrets: pullSecrets$1 } = await Promise.resolve().then(() => require("./sync-D1Pa30oV.cjs"));
|
|
12180
12504
|
const { writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
|
|
12181
|
-
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-
|
|
12505
|
+
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CZtzdrnc.cjs"));
|
|
12182
12506
|
const { workspace } = await loadWorkspaceConfig$1();
|
|
12183
12507
|
let secrets = await pullSecrets$1(options.stage, workspace);
|
|
12184
12508
|
if (!secrets) {
|
|
@@ -12203,7 +12527,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
12203
12527
|
const globalOptions = program.opts();
|
|
12204
12528
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12205
12529
|
const { loadWorkspaceConfig: loadWorkspaceConfig$1 } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
12206
|
-
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-
|
|
12530
|
+
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CZtzdrnc.cjs"));
|
|
12207
12531
|
const { readStageSecrets: readStageSecrets$1, writeStageSecrets: writeStageSecrets$1 } = await Promise.resolve().then(() => require("./storage-DOEtT2Hr.cjs"));
|
|
12208
12532
|
const { workspace } = await loadWorkspaceConfig$1();
|
|
12209
12533
|
const secrets = await readStageSecrets$1(options.stage, workspace.root);
|