open-notepad 1.0.2 → 1.0.3
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/note.js +58 -28
- package/package.json +1 -1
package/bin/note.js
CHANGED
|
@@ -285,31 +285,36 @@ async function handleView(codeArg) {
|
|
|
285
285
|
if (!code) return;
|
|
286
286
|
|
|
287
287
|
const { targetRoom, targetCode } = resolveTarget(code, config);
|
|
288
|
-
if (!targetRoom) {
|
|
289
|
-
warning('No room specified. Please run `note login` or specify room:code.');
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
288
|
|
|
293
|
-
|
|
289
|
+
// Determine if this is a room note or a guest note
|
|
290
|
+
const isGuest = !targetRoom;
|
|
291
|
+
const endpoint = isGuest
|
|
292
|
+
? `/api/notes/guest/${targetCode}`
|
|
293
|
+
: `/api/notes/room/${targetRoom}/${targetCode}`;
|
|
294
|
+
const noteLabel = isGuest
|
|
295
|
+
? `guest/${targetCode}`
|
|
296
|
+
: `/${targetRoom}/${targetCode}`;
|
|
297
|
+
|
|
298
|
+
info(`Loading note ${colors.bold}${noteLabel}${colors.reset}...`);
|
|
294
299
|
|
|
295
300
|
try {
|
|
296
301
|
// Attempt standard fetch with API key
|
|
297
|
-
let res = await apiFetch(config,
|
|
302
|
+
let res = await apiFetch(config, endpoint);
|
|
298
303
|
|
|
299
304
|
if (res.status === 404) {
|
|
300
|
-
error(`Note "${targetCode}" not found in room "${targetRoom}".`);
|
|
305
|
+
error(`Note "${targetCode}" not found${isGuest ? ' (guest)' : ` in room "${targetRoom}"`}.`);
|
|
301
306
|
return;
|
|
302
307
|
}
|
|
303
308
|
|
|
304
309
|
let noteData = await res.json();
|
|
305
310
|
|
|
306
|
-
// Check if the note needs a password
|
|
307
|
-
if (noteData.has_password && (!noteData.content || res.status === 403)) {
|
|
311
|
+
// Check if the note needs a password (room notes only)
|
|
312
|
+
if (!isGuest && noteData.has_password && (!noteData.content || res.status === 403)) {
|
|
308
313
|
const pwd = await askPassword('Enter note password');
|
|
309
314
|
|
|
310
315
|
// Note: We bypass API Key header if providing note password for private notes
|
|
311
316
|
// because backend rejects (is_api = true && private_note = true) outright.
|
|
312
|
-
res = await apiFetch(config,
|
|
317
|
+
res = await apiFetch(config, endpoint, {
|
|
313
318
|
headers: { 'x-note-password': pwd },
|
|
314
319
|
skipApiKey: true
|
|
315
320
|
});
|
|
@@ -327,7 +332,7 @@ async function handleView(codeArg) {
|
|
|
327
332
|
}
|
|
328
333
|
|
|
329
334
|
clearScreen();
|
|
330
|
-
log(`${colors.bold}${colors.blue}Note:
|
|
335
|
+
log(`${colors.bold}${colors.blue}Note: ${noteLabel}${colors.reset}`);
|
|
331
336
|
log(`${colors.dim}------------------------------------------------------------${colors.reset}`);
|
|
332
337
|
log(noteData.content || `${colors.dim}(Empty note)${colors.reset}`);
|
|
333
338
|
log(`${colors.dim}------------------------------------------------------------${colors.reset}`);
|
|
@@ -342,8 +347,30 @@ async function handleCreate(codeArg) {
|
|
|
342
347
|
if (!code) return;
|
|
343
348
|
|
|
344
349
|
const { targetRoom, targetCode } = resolveTarget(code, config);
|
|
345
|
-
|
|
346
|
-
|
|
350
|
+
const isGuest = !targetRoom;
|
|
351
|
+
|
|
352
|
+
if (isGuest) {
|
|
353
|
+
info(`Creating guest note ${colors.bold}${targetCode}${colors.reset}...`);
|
|
354
|
+
try {
|
|
355
|
+
let saveRes = await apiFetch(config, `/api/notes/guest/${targetCode}`, {
|
|
356
|
+
method: 'POST',
|
|
357
|
+
body: JSON.stringify({ content: '' })
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
if (!saveRes.ok) {
|
|
361
|
+
error(`Failed to create guest note (status: ${saveRes.status})`);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
success(`Guest note "${targetCode}" created successfully!`);
|
|
366
|
+
|
|
367
|
+
const editNow = await ask('Open editor to write content now? (y/n)', 'y');
|
|
368
|
+
if (editNow.toLowerCase().startsWith('y')) {
|
|
369
|
+
await handleEdit(targetCode);
|
|
370
|
+
}
|
|
371
|
+
} catch (e) {
|
|
372
|
+
error(e.message);
|
|
373
|
+
}
|
|
347
374
|
return;
|
|
348
375
|
}
|
|
349
376
|
|
|
@@ -409,33 +436,36 @@ async function handleEdit(codeArg) {
|
|
|
409
436
|
if (!code) return;
|
|
410
437
|
|
|
411
438
|
const { targetRoom, targetCode } = resolveTarget(code, config);
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
439
|
+
const isGuest = !targetRoom;
|
|
440
|
+
const endpoint = isGuest
|
|
441
|
+
? `/api/notes/guest/${targetCode}`
|
|
442
|
+
: `/api/notes/room/${targetRoom}/${targetCode}`;
|
|
443
|
+
const noteLabel = isGuest
|
|
444
|
+
? `guest/${targetCode}`
|
|
445
|
+
: `/${targetRoom}/${targetCode}`;
|
|
416
446
|
|
|
417
|
-
info(`Fetching current content of
|
|
447
|
+
info(`Fetching current content of ${noteLabel}...`);
|
|
418
448
|
|
|
419
449
|
try {
|
|
420
450
|
let notePassword = '';
|
|
421
|
-
let res = await apiFetch(config,
|
|
451
|
+
let res = await apiFetch(config, endpoint);
|
|
422
452
|
|
|
423
453
|
// If it doesn't exist, offer to create it
|
|
424
454
|
if (res.status === 404) {
|
|
425
455
|
const create = await ask('Note does not exist. Create it? (y/n)', 'y');
|
|
426
456
|
if (create.toLowerCase().startsWith('y')) {
|
|
427
|
-
await handleCreate(`${targetRoom}:${targetCode}`);
|
|
457
|
+
await handleCreate(isGuest ? targetCode : `${targetRoom}:${targetCode}`);
|
|
428
458
|
}
|
|
429
459
|
return;
|
|
430
460
|
}
|
|
431
461
|
|
|
432
462
|
let noteData = await res.json();
|
|
433
463
|
|
|
434
|
-
// If locked, request password
|
|
435
|
-
if (noteData.has_password && (!noteData.content || res.status === 403)) {
|
|
464
|
+
// If locked, request password (room notes only)
|
|
465
|
+
if (!isGuest && noteData.has_password && (!noteData.content || res.status === 403)) {
|
|
436
466
|
notePassword = await askPassword('Enter note password to edit');
|
|
437
467
|
|
|
438
|
-
res = await apiFetch(config,
|
|
468
|
+
res = await apiFetch(config, endpoint, {
|
|
439
469
|
headers: { 'x-note-password': notePassword },
|
|
440
470
|
skipApiKey: true
|
|
441
471
|
});
|
|
@@ -456,7 +486,7 @@ async function handleEdit(codeArg) {
|
|
|
456
486
|
|
|
457
487
|
// Create temp file
|
|
458
488
|
const tempDir = os.tmpdir();
|
|
459
|
-
const tempFilePath = path.join(tempDir, `note_${targetRoom}_${targetCode}.txt`);
|
|
489
|
+
const tempFilePath = path.join(tempDir, `note_${isGuest ? 'guest' : targetRoom}_${targetCode}.txt`);
|
|
460
490
|
await fs.writeFile(tempFilePath, initialContent, 'utf-8');
|
|
461
491
|
|
|
462
492
|
// Open editor
|
|
@@ -480,15 +510,15 @@ async function handleEdit(codeArg) {
|
|
|
480
510
|
info('Saving changes back to server...');
|
|
481
511
|
|
|
482
512
|
// Save note
|
|
483
|
-
const saveRes = await apiFetch(config,
|
|
513
|
+
const saveRes = await apiFetch(config, endpoint, {
|
|
484
514
|
method: 'POST',
|
|
485
515
|
headers: notePassword ? { 'x-note-password': notePassword } : {},
|
|
486
|
-
skipApiKey: !!notePassword, // Skip API key header if note password is used
|
|
516
|
+
skipApiKey: isGuest || !!notePassword, // Skip API key header if note password is used or if guest
|
|
487
517
|
body: JSON.stringify({ content: updatedContent })
|
|
488
518
|
});
|
|
489
519
|
|
|
490
520
|
if (saveRes.ok) {
|
|
491
|
-
success(`Saved
|
|
521
|
+
success(`Saved ${noteLabel} successfully!`);
|
|
492
522
|
} else {
|
|
493
523
|
error(`Failed to save changes. Server returned status: ${saveRes.status}`);
|
|
494
524
|
}
|
|
@@ -508,7 +538,7 @@ async function handleDelete(codeArg) {
|
|
|
508
538
|
|
|
509
539
|
const { targetRoom, targetCode } = resolveTarget(code, config);
|
|
510
540
|
if (!targetRoom) {
|
|
511
|
-
warning('
|
|
541
|
+
warning('Guest notes cannot be deleted via API. You can overwrite them with empty content to clear them.');
|
|
512
542
|
return;
|
|
513
543
|
}
|
|
514
544
|
|