open-notepad 1.0.4 → 1.0.6
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 +102 -27
- package/package.json +1 -1
package/bin/note.js
CHANGED
|
@@ -140,13 +140,12 @@ async function apiFetch(config, endpoint, options = {}) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// Commands
|
|
143
|
-
async function handleLogin() {
|
|
143
|
+
async function handleLogin(apiUrlArg) {
|
|
144
144
|
clearScreen();
|
|
145
145
|
log(`${colors.bgBlue}${colors.white}${colors.bold} Configure Notepad CLI ${colors.reset}\n`);
|
|
146
146
|
|
|
147
147
|
const current = await loadConfig();
|
|
148
|
-
|
|
149
|
-
const apiUrl = await ask('Enter Server API URL', current.apiUrl);
|
|
148
|
+
const apiUrl = apiUrlArg || current.apiUrl || 'https://notepad.web.id';
|
|
150
149
|
|
|
151
150
|
// Generate a random session code
|
|
152
151
|
const sessionCode = 'cli_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
@@ -179,7 +178,7 @@ async function handleLogin() {
|
|
|
179
178
|
|
|
180
179
|
// Poll for completion
|
|
181
180
|
info('Waiting for browser authorization...');
|
|
182
|
-
const maxAttempts = 120; // 2 minutes (polling every
|
|
181
|
+
const maxAttempts = 120; // 2 minutes (polling every 1.5s)
|
|
183
182
|
let attempts = 0;
|
|
184
183
|
|
|
185
184
|
while (attempts < maxAttempts) {
|
|
@@ -598,56 +597,132 @@ ${colors.bold}${colors.blue}Current Notepad Config:${colors.reset}
|
|
|
598
597
|
`);
|
|
599
598
|
}
|
|
600
599
|
|
|
600
|
+
function selectMenuOption(options, titleCallback) {
|
|
601
|
+
const hasTTY = process.stdin.isTTY && typeof process.stdin.setRawMode === 'function';
|
|
602
|
+
|
|
603
|
+
if (!hasTTY) {
|
|
604
|
+
// Non-interactive fallback
|
|
605
|
+
return new Promise((resolve) => {
|
|
606
|
+
clearScreen();
|
|
607
|
+
titleCallback();
|
|
608
|
+
options.forEach((opt, idx) => {
|
|
609
|
+
log(`${idx + 1}. ${opt}`);
|
|
610
|
+
});
|
|
611
|
+
log('');
|
|
612
|
+
ask(`Select option (1-${options.length})`).then((choice) => {
|
|
613
|
+
const val = parseInt(choice, 10) - 1;
|
|
614
|
+
if (val >= 0 && val < options.length) {
|
|
615
|
+
resolve(val);
|
|
616
|
+
} else {
|
|
617
|
+
resolve(options.length - 1); // default to exit
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
return new Promise((resolve) => {
|
|
624
|
+
let activeIndex = 0;
|
|
625
|
+
|
|
626
|
+
const render = () => {
|
|
627
|
+
clearScreen();
|
|
628
|
+
titleCallback();
|
|
629
|
+
options.forEach((opt, idx) => {
|
|
630
|
+
if (idx === activeIndex) {
|
|
631
|
+
log(`${colors.bold}${colors.blue} > ${opt}${colors.reset}`);
|
|
632
|
+
} else {
|
|
633
|
+
log(` ${colors.dim}${opt}${colors.reset}`);
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
log(`\n${colors.dim}Use Up/Down arrows to navigate, Enter to select.${colors.reset}`);
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
readline.emitKeypressEvents(process.stdin);
|
|
640
|
+
try {
|
|
641
|
+
process.stdin.setRawMode(true);
|
|
642
|
+
} catch (e) {
|
|
643
|
+
process.stdin.setRawMode(false);
|
|
644
|
+
}
|
|
645
|
+
process.stdin.resume();
|
|
646
|
+
|
|
647
|
+
const onKeypress = (str, key) => {
|
|
648
|
+
if (key && key.ctrl && key.name === 'c') {
|
|
649
|
+
try {
|
|
650
|
+
process.stdin.setRawMode(false);
|
|
651
|
+
} catch (e) {}
|
|
652
|
+
process.stdin.off('keypress', onKeypress);
|
|
653
|
+
process.exit(0);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (key && key.name === 'up') {
|
|
657
|
+
activeIndex = (activeIndex - 1 + options.length) % options.length;
|
|
658
|
+
render();
|
|
659
|
+
} else if (key && key.name === 'down') {
|
|
660
|
+
activeIndex = (activeIndex + 1) % options.length;
|
|
661
|
+
render();
|
|
662
|
+
} else if (key && (key.name === 'return' || key.name === 'enter')) {
|
|
663
|
+
try {
|
|
664
|
+
process.stdin.setRawMode(false);
|
|
665
|
+
} catch (e) {}
|
|
666
|
+
process.stdin.off('keypress', onKeypress);
|
|
667
|
+
resolve(activeIndex);
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
process.stdin.on('keypress', onKeypress);
|
|
672
|
+
render();
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
|
|
601
676
|
// Interactive Dashboard Menu (If no arguments)
|
|
602
677
|
async function startMainMenu() {
|
|
678
|
+
const options = [
|
|
679
|
+
'📁 List all notes',
|
|
680
|
+
'📖 View a note',
|
|
681
|
+
'✍️ Create a new note',
|
|
682
|
+
'✏️ Edit an existing note',
|
|
683
|
+
'❌ Delete a note',
|
|
684
|
+
'🔑 Configure / Login',
|
|
685
|
+
'🚪 Exit'
|
|
686
|
+
];
|
|
687
|
+
|
|
603
688
|
while (true) {
|
|
604
|
-
clearScreen();
|
|
605
|
-
log(`${colors.bgBlue}${colors.white}${colors.bold} Notepad CLI Menu ${colors.reset}`);
|
|
606
689
|
const config = await loadConfig();
|
|
607
|
-
|
|
690
|
+
const titleCallback = () => {
|
|
691
|
+
log(`${colors.bgBlue}${colors.white}${colors.bold} Notepad CLI Menu ${colors.reset}`);
|
|
692
|
+
log(`${colors.dim}Namespace: ${colors.reset}${config.roomId ? colors.green + config.roomId : colors.red + '(Not logged in)'}${colors.reset}\n`);
|
|
693
|
+
};
|
|
608
694
|
|
|
609
|
-
|
|
610
|
-
log(`${colors.cyan}2. 📖 View a note${colors.reset}`);
|
|
611
|
-
log(`${colors.cyan}3. ✍️ Create a new note${colors.reset}`);
|
|
612
|
-
log(`${colors.cyan}4. ✏️ Edit an existing note${colors.reset}`);
|
|
613
|
-
log(`${colors.cyan}5. ❌ Delete a note${colors.reset}`);
|
|
614
|
-
log(`${colors.cyan}6. 🔑 Configure / Login${colors.reset}`);
|
|
615
|
-
log(`${colors.cyan}7. 🚪 Exit${colors.reset}\n`);
|
|
616
|
-
|
|
617
|
-
const choice = await ask('Select option (1-7)');
|
|
695
|
+
const choice = await selectMenuOption(options, titleCallback);
|
|
618
696
|
|
|
619
697
|
switch (choice) {
|
|
620
|
-
case
|
|
698
|
+
case 0:
|
|
621
699
|
await handleList();
|
|
622
700
|
await ask('Press Enter to return to menu');
|
|
623
701
|
break;
|
|
624
|
-
case
|
|
702
|
+
case 1:
|
|
625
703
|
await handleView();
|
|
626
704
|
await ask('Press Enter to return to menu');
|
|
627
705
|
break;
|
|
628
|
-
case
|
|
706
|
+
case 2:
|
|
629
707
|
await handleCreate();
|
|
630
708
|
await ask('Press Enter to return to menu');
|
|
631
709
|
break;
|
|
632
|
-
case
|
|
710
|
+
case 3:
|
|
633
711
|
await handleEdit();
|
|
634
712
|
await ask('Press Enter to return to menu');
|
|
635
713
|
break;
|
|
636
|
-
case
|
|
714
|
+
case 4:
|
|
637
715
|
await handleDelete();
|
|
638
716
|
await ask('Press Enter to return to menu');
|
|
639
717
|
break;
|
|
640
|
-
case
|
|
718
|
+
case 5:
|
|
641
719
|
await handleLogin();
|
|
642
720
|
await ask('Press Enter to return to menu');
|
|
643
721
|
break;
|
|
644
|
-
case
|
|
722
|
+
case 6:
|
|
645
723
|
clearScreen();
|
|
646
724
|
log('Goodbye!');
|
|
647
725
|
process.exit(0);
|
|
648
|
-
default:
|
|
649
|
-
warning('Invalid option. Please choose 1-7.');
|
|
650
|
-
await new Promise(r => setTimeout(r, 1200));
|
|
651
726
|
}
|
|
652
727
|
}
|
|
653
728
|
}
|
|
@@ -663,7 +738,7 @@ async function main() {
|
|
|
663
738
|
} else {
|
|
664
739
|
switch (command) {
|
|
665
740
|
case 'login':
|
|
666
|
-
await handleLogin();
|
|
741
|
+
await handleLogin(subArg);
|
|
667
742
|
break;
|
|
668
743
|
case 'list':
|
|
669
744
|
await handleList();
|