create-memory-soda 0.3.0 → 0.4.0
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/README.md +2 -2
- package/index.js +26 -56
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,8 +19,8 @@ what it can, and ends with a checklist of anything it could not do for you.
|
|
|
19
19
|
confirms pgvector and enables the extension. Failures name the fix and let
|
|
20
20
|
you retry, paste another URL, or skip.
|
|
21
21
|
5. **Gemini key** — checked live. Blank allowed; goes on the checklist.
|
|
22
|
-
6. **Ports
|
|
23
|
-
|
|
22
|
+
6. **Ports** — checked for use. Dashboard login starts as `admin` /
|
|
23
|
+
`open-sesame`; change it after signing in.
|
|
24
24
|
7. **Clone, `.env`, `npm ci`, migrations** — migrations run now if the database
|
|
25
25
|
passed.
|
|
26
26
|
|
package/index.js
CHANGED
|
@@ -83,15 +83,8 @@ function runWithSpinner(title, cmd, args, { cwd } = {}) {
|
|
|
83
83
|
* explicitly — everything else stays on the defaults baked into config.ts, so
|
|
84
84
|
* this file does not drift every time a new option is added there.
|
|
85
85
|
*/
|
|
86
|
-
export function renderEnv({
|
|
87
|
-
|
|
88
|
-
geminiKey,
|
|
89
|
-
adminUser,
|
|
90
|
-
adminPassword,
|
|
91
|
-
apiPort,
|
|
92
|
-
dashboardPort,
|
|
93
|
-
}) {
|
|
94
|
-
const lines = [
|
|
86
|
+
export function renderEnv({ databaseUrl, geminiKey, apiPort, dashboardPort }) {
|
|
87
|
+
return [
|
|
95
88
|
'# Generated by create-memory-soda.',
|
|
96
89
|
'# Full reference: https://github.com/alagappan17/memory-soda',
|
|
97
90
|
'',
|
|
@@ -108,15 +101,11 @@ export function renderEnv({
|
|
|
108
101
|
`CORS_ORIGIN=http://localhost:${dashboardPort}`,
|
|
109
102
|
`VITE_API_URL=http://localhost:${apiPort}`,
|
|
110
103
|
'',
|
|
111
|
-
'# Dashboard login
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// answer omits the key entirely rather than writing an empty one.
|
|
117
|
-
if (adminPassword) lines.push(`ADMIN_PASSWORD=${adminPassword}`);
|
|
118
|
-
lines.push('');
|
|
119
|
-
return lines.join('\n');
|
|
104
|
+
'# Dashboard login. Defaults to admin / open-sesame — change it in the dashboard after first sign-in.',
|
|
105
|
+
'# ADMIN_USERNAME=admin',
|
|
106
|
+
'# ADMIN_PASSWORD=open-sesame',
|
|
107
|
+
'',
|
|
108
|
+
].join('\n');
|
|
120
109
|
}
|
|
121
110
|
|
|
122
111
|
/** True if the path is safe to scaffold into: missing, or an empty directory. */
|
|
@@ -406,40 +395,35 @@ async function main() {
|
|
|
406
395
|
}
|
|
407
396
|
if (where !== 'skip') {
|
|
408
397
|
for (;;) {
|
|
409
|
-
|
|
398
|
+
// A clack spinner cannot be restarted once stopped (its timer leaks and
|
|
399
|
+
// the process never exits), so every phase gets a fresh one.
|
|
400
|
+
let s = p.spinner();
|
|
410
401
|
s.start('Checking the database');
|
|
411
402
|
let result = await checkDatabase(databaseUrl);
|
|
412
403
|
if (result?.missingDb) {
|
|
413
404
|
s.stop(`Database "${result.missingDb}" does not exist`);
|
|
414
405
|
if (
|
|
415
|
-
guard(
|
|
406
|
+
!guard(
|
|
416
407
|
await p.confirm({
|
|
417
408
|
message: `Create database "${result.missingDb}"?`,
|
|
418
409
|
initialValue: true,
|
|
419
410
|
}),
|
|
420
411
|
)
|
|
421
412
|
) {
|
|
422
|
-
s.start(`Creating database ${result.missingDb}`);
|
|
423
|
-
try {
|
|
424
|
-
await createDatabase(databaseUrl);
|
|
425
|
-
result = await checkDatabase(databaseUrl);
|
|
426
|
-
} catch (err) {
|
|
427
|
-
result = {
|
|
428
|
-
problem: `could not create database "${result.missingDb}": ${err.message}`,
|
|
429
|
-
fix: `createdb ${result.missingDb} (as a role with CREATEDB)`,
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
} else {
|
|
433
413
|
todo.push(`createdb ${result.missingDb}`);
|
|
434
414
|
break;
|
|
435
415
|
}
|
|
436
|
-
|
|
416
|
+
s = p.spinner();
|
|
417
|
+
s.start(`Creating database ${result.missingDb}`);
|
|
418
|
+
try {
|
|
419
|
+
await createDatabase(databaseUrl);
|
|
420
|
+
result = await checkDatabase(databaseUrl);
|
|
421
|
+
} catch (err) {
|
|
437
422
|
result = {
|
|
438
|
-
problem: `database "${result.missingDb}"
|
|
439
|
-
fix:
|
|
423
|
+
problem: `could not create database "${result.missingDb}": ${err.message}`,
|
|
424
|
+
fix: `createdb ${result.missingDb} (as a role with CREATEDB)`,
|
|
440
425
|
};
|
|
441
|
-
|
|
442
|
-
s.start('Checking the database');
|
|
426
|
+
}
|
|
443
427
|
}
|
|
444
428
|
if (result === null) {
|
|
445
429
|
s.stop('Database ready — connected, pgvector enabled');
|
|
@@ -504,24 +488,9 @@ async function main() {
|
|
|
504
488
|
'Set GOOGLE_GENERATIVE_AI_API_KEY in .env — the API refuses to start without it',
|
|
505
489
|
);
|
|
506
490
|
|
|
507
|
-
// ── 5
|
|
491
|
+
// ── 5. Ports
|
|
508
492
|
const apiPort = await askPort('API port', '3004');
|
|
509
493
|
const dashboardPort = await askPort('Dashboard port', '3000');
|
|
510
|
-
const adminUser = guard(
|
|
511
|
-
await p.text({
|
|
512
|
-
message: 'Dashboard admin username',
|
|
513
|
-
placeholder: 'admin',
|
|
514
|
-
defaultValue: 'admin',
|
|
515
|
-
}),
|
|
516
|
-
);
|
|
517
|
-
const adminPassword =
|
|
518
|
-
guard(
|
|
519
|
-
await p.password({
|
|
520
|
-
message: `Dashboard admin password ${chalk.dim('(leave blank to generate one at first boot)')}`,
|
|
521
|
-
mask: '•',
|
|
522
|
-
}),
|
|
523
|
-
) ?? '';
|
|
524
|
-
|
|
525
494
|
// ── 7. Install
|
|
526
495
|
await runWithSpinner(`Cloning into ${chalk.bold(dirName)}`, 'git', [
|
|
527
496
|
'clone',
|
|
@@ -535,8 +504,6 @@ async function main() {
|
|
|
535
504
|
renderEnv({
|
|
536
505
|
databaseUrl,
|
|
537
506
|
geminiKey,
|
|
538
|
-
adminUser,
|
|
539
|
-
adminPassword,
|
|
540
507
|
apiPort,
|
|
541
508
|
dashboardPort,
|
|
542
509
|
}),
|
|
@@ -596,13 +563,16 @@ async function main() {
|
|
|
596
563
|
'',
|
|
597
564
|
`Dashboard ${chalk.underline(`http://localhost:${dashboardPort}`)}`,
|
|
598
565
|
`API ${chalk.underline(`http://localhost:${apiPort}`)}`,
|
|
599
|
-
`Login ${
|
|
566
|
+
`Login ${chalk.bold('admin')} / ${chalk.bold('open-sesame')} ${chalk.dim('← change it under Settings after signing in')}`,
|
|
600
567
|
'',
|
|
601
568
|
'Then sign in, create an API key, and: npm install @memory-soda/sdk',
|
|
602
569
|
].join('\n'),
|
|
603
570
|
'Run',
|
|
604
571
|
);
|
|
605
|
-
p.outro(
|
|
572
|
+
p.outro(
|
|
573
|
+
`Thanks for trying Memory Soda — ${chalk.bold(basename(target))} is ready.`,
|
|
574
|
+
);
|
|
575
|
+
exit(0);
|
|
606
576
|
}
|
|
607
577
|
|
|
608
578
|
/**
|