@xeplr/cli 0.1.7 → 0.1.8

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/bin/xeplr.js CHANGED
@@ -54,7 +54,14 @@ async function main() {
54
54
 
55
55
  var session = prompt.createSession();
56
56
  try {
57
- var answers = await questions.collect(session, argv[1] && argv[1].indexOf('--') !== 0 ? argv[1] : undefined);
57
+ // A folder that already has something in it is refused NOW, before a
58
+ // single question is asked — not after the database password.
59
+ var argName = argv[1] && argv[1].indexOf('--') !== 0 ? argv[1] : undefined;
60
+ if (argName && generate.isOccupied(path.resolve(process.cwd(), argName))) {
61
+ console.error('\n ' + path.resolve(process.cwd(), argName) + ' already exists and is not empty.\n');
62
+ return 1;
63
+ }
64
+ var answers = await questions.collect(session, argName);
58
65
  console.log(plan.describe(answers));
59
66
 
60
67
  var go = await session.confirm(' Create it?', true);
@@ -226,7 +226,7 @@ function walk(dir) {
226
226
  * @returns {{ written: string[] }}
227
227
  */
228
228
  function generate(answers, target) {
229
- if (fs.existsSync(target) && fs.readdirSync(target).length > 0) {
229
+ if (isOccupied(target)) {
230
230
  throw new Error(target + ' already exists and is not empty.');
231
231
  }
232
232
 
@@ -270,4 +270,9 @@ function generate(answers, target) {
270
270
  return { written: written.sort() };
271
271
  }
272
272
 
273
- module.exports = { generate: generate, substitutions: substitutions, fill: fill };
273
+ /** A folder that exists and has something in it — generating there could overwrite work. */
274
+ function isOccupied(target) {
275
+ return fs.existsSync(target) && fs.readdirSync(target).length > 0;
276
+ }
277
+
278
+ module.exports = { isOccupied: isOccupied, generate: generate, substitutions: substitutions, fill: fill };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeplr/cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Creates a working xeplr application — API, sign-in and UI — from a few answers.",
5
5
  "license": "MIT",
6
6
  "author": "xeppie <admin@xeplr.com>",
@@ -56,3 +56,16 @@ AUTH_SUPER_ADMIN_PASSWORD=__ADMIN_PASSWORD__
56
56
  # email template can carry a token as a value but cannot build an address.
57
57
  AUTH_ACTIVATION_URL=http://localhost:__UI_PORT__/auth/activate
58
58
  AUTH_INVITE_URL=http://localhost:__UI_PORT__/auth/accept-invite
59
+
60
+ # ── Email (optional) ──
61
+ # Without it sign-in works, but activation, invite and password-reset links
62
+ # cannot be sent. The sign-in service checks it at start and says so in its
63
+ # banner: "email ✓ smtp — host:587, connected" or "✗ NOT WORKING — reason".
64
+ # Providers: smtp | brevo | aws | azure — see @xeplr/utils' README.
65
+ # EMAIL_PROVIDER=smtp
66
+ # SMTP_HOST=
67
+ # SMTP_PORT=587
68
+ # SMTP_USER=
69
+ # SMTP_PASS=
70
+ # SMTP_FROM=
71
+ # (smtp also needs `npm install nodemailer` in this folder)
@@ -28,6 +28,6 @@
28
28
  },
29
29
  "devDependencies": {
30
30
  "dotenv-cli": "^8.0.0",
31
- "@xeplr/cli": "^0.1.0"
31
+ "@xeplr/cli": "^0.1.6"
32
32
  }
33
33
  }
@@ -51,7 +51,7 @@ export default function TasksHelp() {
51
51
  new column as you publish.
52
52
  </p>
53
53
 
54
- <h3>Or by hand</h3>
54
+ <h3>Or without code</h3>
55
55
  <p>
56
56
  <strong>Configure UI → Forms → New form</strong>: label and key, design,
57
57
  publish, add to menu — no code. The full steps for a form with its own page, hooks and