@geekmidas/cli 1.10.30 → 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.
Files changed (67) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/bin/gkm.mjs +1 -1
  3. package/dist/{config-jsRYHOHU.mjs → config-B62g483e.mjs} +2 -2
  4. package/dist/{config-jsRYHOHU.mjs.map → config-B62g483e.mjs.map} +1 -1
  5. package/dist/{config-D3ORuiUs.cjs → config-Cuo8vFsp.cjs} +2 -2
  6. package/dist/{config-D3ORuiUs.cjs.map → config-Cuo8vFsp.cjs.map} +1 -1
  7. package/dist/config.cjs +2 -2
  8. package/dist/config.d.cts +1 -1
  9. package/dist/config.d.mts +1 -1
  10. package/dist/config.mjs +2 -2
  11. package/dist/deploy/sniffer-worker.cjs +2 -0
  12. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  13. package/dist/deploy/sniffer-worker.mjs +2 -0
  14. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  15. package/dist/{index-BkibYzso.d.cts → index-C3t5VL4R.d.cts} +2 -32
  16. package/dist/index-C3t5VL4R.d.cts.map +1 -0
  17. package/dist/{index-CY-ieuRp.d.mts → index-Dt_dZ7K4.d.mts} +2 -32
  18. package/dist/index-Dt_dZ7K4.d.mts.map +1 -0
  19. package/dist/index.cjs +65 -26
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.mjs +65 -26
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/{openapi-ClA8lIhO.cjs → openapi-BQft1jm8.cjs} +5 -22
  24. package/dist/openapi-BQft1jm8.cjs.map +1 -0
  25. package/dist/{openapi-CTARkkkn.mjs → openapi-DE8b-vin.mjs} +6 -23
  26. package/dist/openapi-DE8b-vin.mjs.map +1 -0
  27. package/dist/openapi.cjs +3 -3
  28. package/dist/openapi.mjs +3 -3
  29. package/dist/workspace/index.cjs +1 -1
  30. package/dist/workspace/index.d.cts +2 -2
  31. package/dist/workspace/index.d.mts +2 -2
  32. package/dist/workspace/index.mjs +1 -1
  33. package/dist/{workspace-D4z4A4cq.mjs → workspace-Bi4X7Yzy.mjs} +1 -6
  34. package/dist/{workspace-D4z4A4cq.mjs.map → workspace-Bi4X7Yzy.mjs.map} +1 -1
  35. package/dist/{workspace-4SP3Gx4Y.cjs → workspace-CGYykWfn.cjs} +1 -6
  36. package/dist/{workspace-4SP3Gx4Y.cjs.map → workspace-CGYykWfn.cjs.map} +1 -1
  37. package/package.json +4 -4
  38. package/src/__tests__/openapi.spec.ts +0 -315
  39. package/src/build/__tests__/manifests.spec.ts +66 -0
  40. package/src/build/index.ts +12 -1
  41. package/src/build/types.ts +5 -0
  42. package/src/deploy/__tests__/__fixtures__/env-parsers/optional-env-parser.ts +21 -0
  43. package/src/deploy/__tests__/index.spec.ts +1 -3
  44. package/src/deploy/__tests__/sniffer.spec.ts +123 -0
  45. package/src/deploy/sniffer-worker.ts +2 -1
  46. package/src/deploy/sniffer.ts +86 -12
  47. package/src/docker/compose.ts +2 -0
  48. package/src/generators/CronGenerator.ts +3 -1
  49. package/src/generators/EndpointGenerator.ts +6 -2
  50. package/src/generators/FunctionGenerator.ts +3 -1
  51. package/src/generators/SubscriberGenerator.ts +3 -1
  52. package/src/index.ts +8 -0
  53. package/src/init/generators/docker.ts +2 -2
  54. package/src/init/generators/monorepo.ts +15 -1
  55. package/src/init/index.ts +2 -4
  56. package/src/init/versions.ts +2 -2
  57. package/src/openapi.ts +1 -35
  58. package/src/types.ts +7 -0
  59. package/src/workspace/__tests__/client-generator.spec.ts +1 -485
  60. package/src/workspace/client-generator.ts +1 -145
  61. package/src/workspace/index.ts +0 -1
  62. package/src/workspace/schema.ts +0 -9
  63. package/src/workspace/types.ts +0 -29
  64. package/dist/index-BkibYzso.d.cts.map +0 -1
  65. package/dist/index-CY-ieuRp.d.mts.map +0 -1
  66. package/dist/openapi-CTARkkkn.mjs.map +0 -1
  67. package/dist/openapi-ClA8lIhO.cjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env -S npx tsx
2
2
  import { __require } from "./chunk-Duj1WY3L.mjs";
3
- import { getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-D4z4A4cq.mjs";
4
- import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, parseModuleConfig } from "./config-jsRYHOHU.mjs";
3
+ import { getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-Bi4X7Yzy.mjs";
4
+ import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, parseModuleConfig } from "./config-B62g483e.mjs";
5
5
  import { getCredentialsPath, getDokployCredentials, getDokployRegistryId, getDokployToken, removeDokployCredentials, storeDokployCredentials, storeDokployRegistryId } from "./credentials-s1kLcIzK.mjs";
6
6
  import { createStageSecrets, generateConnectionUrls, generateDbPassword, generateDbUrl, generateFullstackCustomSecrets, generateLocalStackCredentials, generatePgBossUrl, generateSecurePassword, generateServiceCredentials, rotateServicePassword, writeDockerEnvFromSecrets } from "./fullstack-secrets-P84v8zWn.mjs";
7
7
  import { getKeyPath, maskPassword, readStageSecrets, secretsExist, setCustomSecret, toEmbeddableSecrets, writeStageSecrets } from "./storage-dbb9RyBl.mjs";
8
- import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, isPartitionedRoutes, normalizeRoutes, openapiCommand, resolveOpenApiConfig } from "./openapi-CTARkkkn.mjs";
8
+ import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, isPartitionedRoutes, normalizeRoutes, openapiCommand, resolveOpenApiConfig } from "./openapi-DE8b-vin.mjs";
9
9
  import { DokployApi } from "./dokploy-api-BIT0683o.mjs";
10
10
  import { encryptSecrets } from "./encryption-DSkIlEZ6.mjs";
11
11
  import { CachedStateProvider } from "./CachedStateProvider-C8A-cCm5.mjs";
@@ -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.29";
38
+ var version = "1.10.31";
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";
@@ -825,7 +825,7 @@ var CronGenerator = class extends ConstructGenerator {
825
825
  schedule: construct.schedule || "rate(1 hour)",
826
826
  timeout: construct.timeout,
827
827
  memorySize: construct.memorySize,
828
- environment: await construct.getEnvironment()
828
+ environment: await construct.getEnvironment({ markOptional: context.markOptional })
829
829
  });
830
830
  logger$15.log(`Generated cron handler: ${key}`);
831
831
  }
@@ -875,7 +875,7 @@ var FunctionGenerator = class extends ConstructGenerator {
875
875
  handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
876
876
  timeout: construct.timeout,
877
877
  memorySize: construct.memorySize,
878
- environment: await construct.getEnvironment()
878
+ environment: await construct.getEnvironment({ markOptional: context.markOptional })
879
879
  });
880
880
  logger$15.log(`Generated function handler: ${key}`);
881
881
  }
@@ -929,7 +929,7 @@ var SubscriberGenerator = class extends ConstructGenerator {
929
929
  subscribedEvents: construct.subscribedEvents || [],
930
930
  timeout: construct.timeout,
931
931
  memorySize: construct.memorySize,
932
- environment: await construct.getEnvironment()
932
+ environment: await construct.getEnvironment({ markOptional: context.markOptional })
933
933
  });
934
934
  logger$15.log(`Generated subscriber handler: ${key}`);
935
935
  }
@@ -2180,7 +2180,8 @@ async function buildCommand(options) {
2180
2180
  studio,
2181
2181
  hooks,
2182
2182
  production,
2183
- dockerServices
2183
+ dockerServices,
2184
+ markOptional: options.markOptional ?? false
2184
2185
  };
2185
2186
  const endpointGenerator = new EndpointGenerator();
2186
2187
  const functionGenerator = new FunctionGenerator();
@@ -2207,6 +2208,7 @@ async function buildCommand(options) {
2207
2208
  const providerResult = await buildForProvider(provider, buildContext, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, resolved.enableOpenApi, options.skipBundle ?? false, options.stage);
2208
2209
  if (providerResult.masterKey) result = providerResult;
2209
2210
  }
2211
+ await generateOpenApi(config$1, { bustCache: true });
2210
2212
  return result;
2211
2213
  }
2212
2214
  async function buildForProvider(provider, context, rootOutputDir, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, endpoints, functions, crons, subscribers, enableOpenApi, skipBundle, stage) {
@@ -2341,6 +2343,7 @@ async function workspaceBuildCommand(workspace, options) {
2341
2343
  });
2342
2344
  }
2343
2345
  logger$9.log(`\n✅ Workspace build complete!`);
2346
+ await openapiCommand({ cwd: workspace.root });
2344
2347
  logger$9.log(`\n📋 Build Summary:`);
2345
2348
  for (const result of results) {
2346
2349
  const icon = result.type === "backend" ? "⚙️" : "🌐";
@@ -3123,6 +3126,7 @@ services:
3123
3126
  restart: unless-stopped
3124
3127
  environment:
3125
3128
  MP_SMTP_AUTH: \${SMTP_USER:-${imageName}}:\${SMTP_PASS:-${imageName}}
3129
+ MP_SMTP_AUTH_ALLOW_INSECURE: true
3126
3130
  ports:
3127
3131
  - "\${MAILPIT_PORT:-8025}:8025" # Web UI / API
3128
3132
  - "\${SMTP_PORT:-1025}:1025" # SMTP
@@ -3287,6 +3291,7 @@ services:
3287
3291
  restart: unless-stopped
3288
3292
  environment:
3289
3293
  MP_SMTP_AUTH: \${SMTP_USER:-${workspace.name}}:\${SMTP_PASS:-${workspace.name}}
3294
+ MP_SMTP_AUTH_ALLOW_INSECURE: true
3290
3295
  ports:
3291
3296
  - "\${MAILPIT_PORT:-8025}:8025" # Web UI / API
3292
3297
  - "\${SMTP_PORT:-1025}:1025" # SMTP
@@ -5216,11 +5221,12 @@ function resolveSnifferFile(baseName) {
5216
5221
  * @returns The sniffed environment with required variables
5217
5222
  */
5218
5223
  async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
5219
- const { logWarnings = true } = options;
5224
+ const { logWarnings = true, markOptional = false } = options;
5220
5225
  if (app.type === "frontend") {
5221
5226
  const depVars = (app.dependencies ?? []).map((dep) => `NEXT_PUBLIC_${dep.toUpperCase()}_URL`);
5222
5227
  if (app.config) {
5223
5228
  const sniffedVars = [];
5229
+ const sniffedOptional = [];
5224
5230
  const configPaths = [];
5225
5231
  if (app.config.client) configPaths.push(app.config.client);
5226
5232
  if (app.config.server) configPaths.push(app.config.server);
@@ -5228,16 +5234,20 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
5228
5234
  const result = await sniffEntryFile(configPath, app.path, workspacePath);
5229
5235
  if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Config file "${configPath}" threw error during sniffing (env vars still captured): ${result.error.message}`);
5230
5236
  sniffedVars.push(...result.envVars);
5237
+ sniffedOptional.push(...result.optionalEnvVars);
5231
5238
  }
5232
- const allVars = [...new Set([...depVars, ...sniffedVars])];
5239
+ const optionalEnvVars = [...new Set(sniffedOptional)];
5240
+ const allVars = applyMarkOptional([...new Set([...depVars, ...sniffedVars])], optionalEnvVars, markOptional);
5233
5241
  return {
5234
5242
  appName,
5235
- requiredEnvVars: allVars
5243
+ requiredEnvVars: allVars,
5244
+ optionalEnvVars
5236
5245
  };
5237
5246
  }
5238
5247
  return {
5239
5248
  appName,
5240
- requiredEnvVars: depVars
5249
+ requiredEnvVars: depVars,
5250
+ optionalEnvVars: []
5241
5251
  };
5242
5252
  }
5243
5253
  if (app.entry) {
@@ -5245,7 +5255,8 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
5245
5255
  if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Entry file threw error during sniffing (env vars still captured): ${result.error.message}`);
5246
5256
  return {
5247
5257
  appName,
5248
- requiredEnvVars: result.envVars
5258
+ requiredEnvVars: applyMarkOptional(result.envVars, result.optionalEnvVars, markOptional),
5259
+ optionalEnvVars: result.optionalEnvVars
5249
5260
  };
5250
5261
  }
5251
5262
  if (app.routes) {
@@ -5253,7 +5264,8 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
5253
5264
  if (logWarnings && result.error) console.warn(`[sniffer] ${appName}: Route sniffing threw error (env vars still captured): ${result.error.message}`);
5254
5265
  return {
5255
5266
  appName,
5256
- requiredEnvVars: result.envVars
5267
+ requiredEnvVars: applyMarkOptional(result.envVars, result.optionalEnvVars, markOptional),
5268
+ optionalEnvVars: result.optionalEnvVars
5257
5269
  };
5258
5270
  }
5259
5271
  if (app.envParser) {
@@ -5264,15 +5276,26 @@ async function sniffAppEnvironment(app, appName, workspacePath, options = {}) {
5264
5276
  }
5265
5277
  return {
5266
5278
  appName,
5267
- requiredEnvVars: result.envVars
5279
+ requiredEnvVars: applyMarkOptional(result.envVars, result.optionalEnvVars, markOptional),
5280
+ optionalEnvVars: result.optionalEnvVars
5268
5281
  };
5269
5282
  }
5270
5283
  return {
5271
5284
  appName,
5272
- requiredEnvVars: []
5285
+ requiredEnvVars: [],
5286
+ optionalEnvVars: []
5273
5287
  };
5274
5288
  }
5275
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
+ /**
5276
5299
  * Sniff an entry file by importing it in a subprocess.
5277
5300
  *
5278
5301
  * Entry apps call `config.parse()` at module load time. To capture which
@@ -5328,6 +5351,7 @@ async function sniffEntryFile(entryPath, appPath, workspacePath) {
5328
5351
  const result = JSON.parse(jsonMatch[0]);
5329
5352
  resolvePromise({
5330
5353
  envVars: result.envVars || [],
5354
+ optionalEnvVars: result.optionalEnvVars || [],
5331
5355
  error: result.error ? new Error(result.error) : void 0
5332
5356
  });
5333
5357
  return;
@@ -5335,12 +5359,14 @@ async function sniffEntryFile(entryPath, appPath, workspacePath) {
5335
5359
  } catch {}
5336
5360
  resolvePromise({
5337
5361
  envVars: [],
5362
+ optionalEnvVars: [],
5338
5363
  error: new Error(`Failed to sniff entry file (exit code ${code}): ${stderr || stdout$1 || "No output"}`)
5339
5364
  });
5340
5365
  });
5341
5366
  child.on("error", (err) => {
5342
5367
  resolvePromise({
5343
5368
  envVars: [],
5369
+ optionalEnvVars: [],
5344
5370
  error: err
5345
5371
  });
5346
5372
  });
@@ -5368,6 +5394,7 @@ async function sniffRouteFiles(routes, appPath, workspacePath) {
5368
5394
  const pattern = routesArray[0];
5369
5395
  if (!pattern) return {
5370
5396
  envVars: [],
5397
+ optionalEnvVars: [],
5371
5398
  error: new Error("No route patterns provided")
5372
5399
  };
5373
5400
  return new Promise((resolvePromise) => {
@@ -5402,6 +5429,7 @@ async function sniffRouteFiles(routes, appPath, workspacePath) {
5402
5429
  const result = JSON.parse(jsonMatch[0]);
5403
5430
  resolvePromise({
5404
5431
  envVars: result.envVars || [],
5432
+ optionalEnvVars: result.optionalEnvVars || [],
5405
5433
  error: result.error ? new Error(result.error) : void 0
5406
5434
  });
5407
5435
  return;
@@ -5409,12 +5437,14 @@ async function sniffRouteFiles(routes, appPath, workspacePath) {
5409
5437
  } catch {}
5410
5438
  resolvePromise({
5411
5439
  envVars: [],
5440
+ optionalEnvVars: [],
5412
5441
  error: new Error(`Failed to sniff route files (exit code ${code}): ${stderr || stdout$1 || "No output"}`)
5413
5442
  });
5414
5443
  });
5415
5444
  child.on("error", (err) => {
5416
5445
  resolvePromise({
5417
5446
  envVars: [],
5447
+ optionalEnvVars: [],
5418
5448
  error: err
5419
5449
  });
5420
5450
  });
@@ -5436,6 +5466,7 @@ async function sniffEnvParser(envParserPath, appPath, workspacePath) {
5436
5466
  const [modulePath, exportName = "default"] = envParserPath.split("#");
5437
5467
  if (!modulePath) return {
5438
5468
  envVars: [],
5469
+ optionalEnvVars: [],
5439
5470
  unhandledRejections: []
5440
5471
  };
5441
5472
  const fullPath = resolve(workspacePath, appPath, modulePath);
@@ -5450,6 +5481,7 @@ async function sniffEnvParser(envParserPath, appPath, workspacePath) {
5450
5481
  console.warn(`[sniffer] Failed to import SnifferEnvironmentParser: ${message}`);
5451
5482
  return {
5452
5483
  envVars: [],
5484
+ optionalEnvVars: [],
5453
5485
  unhandledRejections: []
5454
5486
  };
5455
5487
  }
@@ -6806,10 +6838,10 @@ const GEEKMIDAS_VERSIONS = {
6806
6838
  "@geekmidas/cache": "~1.1.0",
6807
6839
  "@geekmidas/client": "~4.0.4",
6808
6840
  "@geekmidas/cloud": "~1.0.0",
6809
- "@geekmidas/constructs": "~3.0.6",
6841
+ "@geekmidas/constructs": "~3.0.7",
6810
6842
  "@geekmidas/db": "~1.0.1",
6811
6843
  "@geekmidas/emailkit": "~1.0.0",
6812
- "@geekmidas/envkit": "~1.0.4",
6844
+ "@geekmidas/envkit": "~1.0.5",
6813
6845
  "@geekmidas/errors": "~1.0.0",
6814
6846
  "@geekmidas/events": "~1.1.0",
6815
6847
  "@geekmidas/logger": "~1.0.0",
@@ -7454,7 +7486,7 @@ ${volumes.join("\n")}
7454
7486
  /**
7455
7487
  * Generate .env file for docker-compose with database passwords
7456
7488
  */
7457
- function generateDockerEnv(apps, eventsBackend) {
7489
+ function generateDockerEnv(apps, _eventsBackend) {
7458
7490
  const envVars = apps.map((app) => {
7459
7491
  const envVar = `${app.name.toUpperCase()}_DB_PASSWORD`;
7460
7492
  return `${envVar}=${app.password}`;
@@ -7473,7 +7505,7 @@ ${envVars.join("\n")}
7473
7505
  * - auth user: uses auth schema with search_path=auth
7474
7506
  * - pgboss user: uses pgboss schema (when events === 'pgboss')
7475
7507
  */
7476
- function generatePostgresInitScript(apps, eventsBackend) {
7508
+ function generatePostgresInitScript(apps, _eventsBackend) {
7477
7509
  const userCreations = apps.map((app) => {
7478
7510
  const userName = app.name.replace(/-/g, "_");
7479
7511
  const envVar = `${app.name.toUpperCase()}_DB_PASSWORD`;
@@ -8068,7 +8100,7 @@ export default defineWorkspace({
8068
8100
  schema: 'zod',
8069
8101
  },
8070
8102
  },`;
8071
- if (services.db || services.cache || services.mail) {
8103
+ if (services.db || services.cache || services.mail || services.storage || services.events) {
8072
8104
  config$1 += `
8073
8105
  services: {`;
8074
8106
  if (services.db) config$1 += `
@@ -8077,6 +8109,10 @@ export default defineWorkspace({
8077
8109
  cache: true,`;
8078
8110
  if (services.mail) config$1 += `
8079
8111
  mail: true,`;
8112
+ if (services.storage) config$1 += `
8113
+ storage: true,`;
8114
+ if (services.events) config$1 += `
8115
+ events: '${services.events}',`;
8080
8116
  config$1 += `
8081
8117
  },`;
8082
8118
  }
@@ -11306,7 +11342,7 @@ async function initCommand(projectName, options = {}) {
11306
11342
  "mail",
11307
11343
  "storage"
11308
11344
  ] : answers.services || [];
11309
- const eventsBackend = options.yes ? isFullstack ? "pgboss" : void 0 : answers.eventsBackend;
11345
+ const eventsBackend = options.yes ? "pgboss" : answers.eventsBackend;
11310
11346
  const services = {
11311
11347
  db: servicesArray.includes("db"),
11312
11348
  cache: servicesArray.includes("cache"),
@@ -12235,7 +12271,7 @@ program.command("setup").description("Setup development environment (secrets, Do
12235
12271
  process.exit(1);
12236
12272
  }
12237
12273
  });
12238
- program.command("build").description("Build handlers from endpoints, functions, and crons").option("--provider <provider>", "Target provider for generated handlers (aws, server)").option("--providers <providers>", "[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)").option("--enable-openapi", "Enable OpenAPI documentation generation for server builds").option("--production", "Build for production (no dev tools, bundled output)").option("--skip-bundle", "Skip bundling step in production build").option("--stage <stage>", "Inject encrypted secrets for deployment stage").action(async (options) => {
12274
+ program.command("build").description("Build handlers from endpoints, functions, and crons").option("--provider <provider>", "Target provider for generated handlers (aws, server)").option("--providers <providers>", "[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)").option("--enable-openapi", "Enable OpenAPI documentation generation for server builds").option("--production", "Build for production (no dev tools, bundled output)").option("--skip-bundle", "Skip bundling step in production build").option("--stage <stage>", "Inject encrypted secrets for deployment stage").option("--mark-optional", "Suffix optional env vars with ? in manifest envVars field (e.g. PORT?)").action(async (options) => {
12239
12275
  try {
12240
12276
  const globalOptions = program.opts();
12241
12277
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
@@ -12246,7 +12282,8 @@ program.command("build").description("Build handlers from endpoints, functions,
12246
12282
  enableOpenApi: options.enableOpenapi || false,
12247
12283
  production: options.production || false,
12248
12284
  skipBundle: options.skipBundle || false,
12249
- stage: options.stage
12285
+ stage: options.stage,
12286
+ markOptional: options.markOptional || false
12250
12287
  });
12251
12288
  } else if (options.providers) {
12252
12289
  const providerList = [...new Set(options.providers.split(",").map((p) => p.trim()))];
@@ -12255,13 +12292,15 @@ program.command("build").description("Build handlers from endpoints, functions,
12255
12292
  enableOpenApi: options.enableOpenapi || false,
12256
12293
  production: options.production || false,
12257
12294
  skipBundle: options.skipBundle || false,
12258
- stage: options.stage
12295
+ stage: options.stage,
12296
+ markOptional: options.markOptional || false
12259
12297
  });
12260
12298
  } else await buildCommand({
12261
12299
  enableOpenApi: options.enableOpenapi || false,
12262
12300
  production: options.production || false,
12263
12301
  skipBundle: options.skipBundle || false,
12264
- stage: options.stage
12302
+ stage: options.stage,
12303
+ markOptional: options.markOptional || false
12265
12304
  });
12266
12305
  } catch (error) {
12267
12306
  console.error(formatError(error));