zuro-cli 0.0.2-beta.11 → 0.0.2-beta.12

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/dist/index.js CHANGED
@@ -357,6 +357,32 @@ var ENV_CONFIGS = {
357
357
  { name: "BETTER_AUTH_SECRET", schema: "z.string().min(32)" },
358
358
  { name: "BETTER_AUTH_URL", schema: "z.string().url()" }
359
359
  ]
360
+ },
361
+ mailer: {
362
+ envVars: {
363
+ SMTP_HOST: "smtp.example.com",
364
+ SMTP_PORT: "587",
365
+ SMTP_USER: "your-email@example.com",
366
+ SMTP_PASS: "your-password",
367
+ MAIL_FROM: "noreply@example.com"
368
+ },
369
+ schemaFields: [
370
+ { name: "SMTP_HOST", schema: "z.string().min(1)" },
371
+ { name: "SMTP_PORT", schema: "z.coerce.number().default(587)" },
372
+ { name: "SMTP_USER", schema: "z.string().min(1)" },
373
+ { name: "SMTP_PASS", schema: "z.string().min(1)" },
374
+ { name: "MAIL_FROM", schema: "z.string().email()" }
375
+ ]
376
+ },
377
+ "mailer-resend": {
378
+ envVars: {
379
+ RESEND_API_KEY: "re_your_api_key",
380
+ MAIL_FROM: "onboarding@resend.dev"
381
+ },
382
+ schemaFields: [
383
+ { name: "RESEND_API_KEY", schema: "z.string().min(1)" },
384
+ { name: "MAIL_FROM", schema: "z.string().min(1)" }
385
+ ]
360
386
  }
361
387
  };
362
388
 
@@ -663,7 +689,8 @@ var BLOCK_SIGNATURES = {
663
689
  validator: "middleware/validate.ts",
664
690
  "error-handler": "lib/errors.ts",
665
691
  logger: "lib/logger.ts",
666
- auth: "lib/auth.ts"
692
+ auth: "lib/auth.ts",
693
+ mailer: "lib/mailer.ts"
667
694
  };
668
695
  var resolveDependencies = async (moduleDependencies, cwd) => {
669
696
  if (!moduleDependencies || moduleDependencies.length === 0) {
@@ -1039,6 +1066,9 @@ var add = async (moduleName) => {
1039
1066
  let databaseBackupPath = null;
1040
1067
  let generatedAuthSecret = false;
1041
1068
  let authDatabaseDialect = null;
1069
+ let customSmtpVars;
1070
+ let usedDefaultSmtp = false;
1071
+ let mailerProvider = "smtp";
1042
1072
  if (resolvedModuleName === "database") {
1043
1073
  const variantResponse = await (0, import_prompts2.default)({
1044
1074
  type: "select",
@@ -1099,6 +1129,103 @@ var add = async (moduleName) => {
1099
1129
  usedDefaultDbUrl = enteredUrl.length === 0;
1100
1130
  customDbUrl = validateDatabaseUrl(enteredUrl || defaultUrl, resolvedModuleName);
1101
1131
  }
1132
+ if (resolvedModuleName === "mailer") {
1133
+ const providerResponse = await (0, import_prompts2.default)({
1134
+ type: "select",
1135
+ name: "provider",
1136
+ message: "Which email provider?",
1137
+ choices: [
1138
+ { title: "SMTP (Nodemailer)", description: "Gmail, Mailtrap, any SMTP server", value: "smtp" },
1139
+ { title: "Resend", description: "API-based, easiest setup", value: "resend" }
1140
+ ]
1141
+ });
1142
+ if (providerResponse.provider === void 0) {
1143
+ console.log(import_chalk4.default.yellow("Operation cancelled."));
1144
+ return;
1145
+ }
1146
+ mailerProvider = providerResponse.provider;
1147
+ console.log(import_chalk4.default.dim(" Tip: Leave fields blank to use placeholder values and configure later\n"));
1148
+ if (mailerProvider === "smtp") {
1149
+ const smtpResponse = await (0, import_prompts2.default)([
1150
+ {
1151
+ type: "text",
1152
+ name: "host",
1153
+ message: "SMTP Host",
1154
+ initial: ""
1155
+ },
1156
+ {
1157
+ type: "text",
1158
+ name: "port",
1159
+ message: "SMTP Port",
1160
+ initial: "587"
1161
+ },
1162
+ {
1163
+ type: "text",
1164
+ name: "user",
1165
+ message: "SMTP User",
1166
+ initial: ""
1167
+ },
1168
+ {
1169
+ type: "password",
1170
+ name: "pass",
1171
+ message: "SMTP Password"
1172
+ },
1173
+ {
1174
+ type: "text",
1175
+ name: "from",
1176
+ message: "Mail From address",
1177
+ initial: ""
1178
+ }
1179
+ ]);
1180
+ if (smtpResponse.host === void 0) {
1181
+ console.log(import_chalk4.default.yellow("Operation cancelled."));
1182
+ return;
1183
+ }
1184
+ const host = smtpResponse.host?.trim() || "";
1185
+ const user = smtpResponse.user?.trim() || "";
1186
+ const pass = smtpResponse.pass?.trim() || "";
1187
+ const from = smtpResponse.from?.trim() || "";
1188
+ const port = smtpResponse.port?.trim() || "587";
1189
+ usedDefaultSmtp = !host && !user;
1190
+ if (!usedDefaultSmtp) {
1191
+ customSmtpVars = {
1192
+ SMTP_HOST: host || "smtp.example.com",
1193
+ SMTP_PORT: port,
1194
+ SMTP_USER: user || "your-email@example.com",
1195
+ SMTP_PASS: pass || "your-password",
1196
+ MAIL_FROM: from || "noreply@example.com"
1197
+ };
1198
+ }
1199
+ } else {
1200
+ const resendResponse = await (0, import_prompts2.default)([
1201
+ {
1202
+ type: "text",
1203
+ name: "apiKey",
1204
+ message: "Resend API Key",
1205
+ initial: ""
1206
+ },
1207
+ {
1208
+ type: "text",
1209
+ name: "from",
1210
+ message: "Mail From address",
1211
+ initial: ""
1212
+ }
1213
+ ]);
1214
+ if (resendResponse.apiKey === void 0) {
1215
+ console.log(import_chalk4.default.yellow("Operation cancelled."));
1216
+ return;
1217
+ }
1218
+ const apiKey = resendResponse.apiKey?.trim() || "";
1219
+ const from = resendResponse.from?.trim() || "";
1220
+ usedDefaultSmtp = !apiKey;
1221
+ if (!usedDefaultSmtp) {
1222
+ customSmtpVars = {
1223
+ RESEND_API_KEY: apiKey || "re_your_api_key",
1224
+ MAIL_FROM: from || "onboarding@resend.dev"
1225
+ };
1226
+ }
1227
+ }
1228
+ }
1102
1229
  const pm = resolvePackageManager(projectRoot);
1103
1230
  const spinner = (0, import_ora2.default)(`Checking registry for ${resolvedModuleName}...`).start();
1104
1231
  let currentStep = "package manager preflight";
@@ -1119,8 +1246,19 @@ var add = async (moduleName) => {
1119
1246
  await resolveDependencies(moduleDeps, projectRoot);
1120
1247
  currentStep = "dependency installation";
1121
1248
  spinner.start("Installing dependencies...");
1122
- await installDependencies(pm, module2.dependencies || [], projectRoot);
1123
- await installDependencies(pm, module2.devDependencies || [], projectRoot, { dev: true });
1249
+ let runtimeDeps = module2.dependencies || [];
1250
+ let devDeps = module2.devDependencies || [];
1251
+ if (resolvedModuleName === "mailer") {
1252
+ if (mailerProvider === "resend") {
1253
+ runtimeDeps = ["resend"];
1254
+ devDeps = [];
1255
+ } else {
1256
+ runtimeDeps = ["nodemailer"];
1257
+ devDeps = ["@types/nodemailer"];
1258
+ }
1259
+ }
1260
+ await installDependencies(pm, runtimeDeps, projectRoot);
1261
+ await installDependencies(pm, devDeps, projectRoot, { dev: true });
1124
1262
  spinner.succeed("Dependencies installed");
1125
1263
  currentStep = "module scaffolding";
1126
1264
  spinner.start("Scaffolding files...");
@@ -1136,6 +1274,11 @@ var add = async (moduleName) => {
1136
1274
  expectedSha256 = void 0;
1137
1275
  expectedSize = void 0;
1138
1276
  }
1277
+ if (resolvedModuleName === "mailer" && file.target === "lib/mailer.ts" && mailerProvider === "resend") {
1278
+ fetchPath = "express/lib/mailer.resend.ts";
1279
+ expectedSha256 = void 0;
1280
+ expectedSize = void 0;
1281
+ }
1139
1282
  let content = await fetchFile(fetchPath, {
1140
1283
  baseUrl: registryContext.fileBaseUrl,
1141
1284
  expectedSha256,
@@ -1175,7 +1318,11 @@ var add = async (moduleName) => {
1175
1318
  spinner.warn("Could not find app.ts - error handler needs manual setup");
1176
1319
  }
1177
1320
  }
1178
- const envConfig = ENV_CONFIGS[resolvedModuleName];
1321
+ let envConfigKey = resolvedModuleName;
1322
+ if (resolvedModuleName === "mailer" && mailerProvider === "resend") {
1323
+ envConfigKey = "mailer-resend";
1324
+ }
1325
+ const envConfig = ENV_CONFIGS[envConfigKey];
1179
1326
  if (envConfig) {
1180
1327
  currentStep = "environment configuration";
1181
1328
  spinner.start("Updating environment configuration...");
@@ -1183,6 +1330,9 @@ var add = async (moduleName) => {
1183
1330
  if (customDbUrl && isDatabaseModule(resolvedModuleName)) {
1184
1331
  envVars.DATABASE_URL = customDbUrl;
1185
1332
  }
1333
+ if (resolvedModuleName === "mailer" && customSmtpVars) {
1334
+ Object.assign(envVars, customSmtpVars);
1335
+ }
1186
1336
  if (resolvedModuleName === "auth") {
1187
1337
  const hasExistingSecret = await hasEnvVariable(projectRoot, "BETTER_AUTH_SECRET");
1188
1338
  if (!hasExistingSecret) {
@@ -1225,6 +1375,13 @@ var add = async (moduleName) => {
1225
1375
  }
1226
1376
  console.log(import_chalk4.default.yellow("\u2139 Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate"));
1227
1377
  }
1378
+ if (resolvedModuleName === "mailer") {
1379
+ if (usedDefaultSmtp) {
1380
+ console.log(import_chalk4.default.yellow("\u2139 Placeholder SMTP values added to .env \u2014 update them before sending emails."));
1381
+ } else {
1382
+ console.log(import_chalk4.default.yellow("\u2139 Review SMTP configuration in .env to ensure values are correct."));
1383
+ }
1384
+ }
1228
1385
  } catch (error) {
1229
1386
  spinner.fail(import_chalk4.default.red(`Failed during ${currentStep}.`));
1230
1387
  const errorMessage = error instanceof Error ? error.message : String(error);