open-notepad 1.0.5 → 1.0.7

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.
Files changed (2) hide show
  1. package/bin/note.js +95 -82
  2. package/package.json +1 -1
package/bin/note.js CHANGED
@@ -140,103 +140,116 @@ async function apiFetch(config, endpoint, options = {}) {
140
140
  }
141
141
 
142
142
  // Commands
143
- async function handleLogin() {
144
- clearScreen();
145
- log(`${colors.bgBlue}${colors.white}${colors.bold} Configure Notepad CLI ${colors.reset}\n`);
146
-
143
+ async function handleLogin(apiUrlArg) {
147
144
  const current = await loadConfig();
145
+ const apiUrl = apiUrlArg || current.apiUrl || 'https://notepad.web.id';
148
146
 
149
- const apiUrl = await ask('Enter Server API URL', current.apiUrl);
150
-
151
- // Generate a random session code
152
- const sessionCode = 'cli_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
147
+ // Present choices
148
+ const loginOptions = [
149
+ '🌐 Sign in with Google (Browser Redirect)',
150
+ '🔑 Enter API Key (Manual)'
151
+ ];
153
152
 
154
- // Try browser-based login
155
- info('Registering CLI session...');
156
- try {
157
- const regRes = await fetch(`${apiUrl.replace(/\/$/, '')}/api/cli/session`, {
158
- method: 'POST',
159
- headers: { 'Content-Type': 'application/json' },
160
- body: JSON.stringify({ code: sessionCode })
161
- });
153
+ const titleCallback = () => {
154
+ log(`${colors.bgBlue}${colors.white}${colors.bold} Configure Notepad CLI ${colors.reset}`);
155
+ log(`${colors.dim}Select how you want to authenticate with ${colors.reset}${colors.cyan}${apiUrl}${colors.reset}\n`);
156
+ };
162
157
 
163
- if (!regRes.ok) {
164
- throw new Error(`Server returned ${regRes.status}`);
165
- }
158
+ const choice = await selectMenuOption(loginOptions, titleCallback);
166
159
 
167
- // Open browser
168
- const authPageUrl = `${apiUrl.replace(/\/$/, '')}/auth-cli-20260628dontuseforyounote?session=${sessionCode}`;
169
- info(`Opening browser for authentication...`);
170
- log(`\n${colors.dim}If browser does not open automatically, visit:${colors.reset}`);
171
- log(`${colors.bold}${colors.cyan}${authPageUrl}${colors.reset}\n`);
172
-
173
- // Platform-specific browser open
174
- const openCmd = process.platform === 'win32' ? 'start'
175
- : process.platform === 'darwin' ? 'open'
176
- : 'xdg-open';
177
- const child = spawn(openCmd, [authPageUrl], { shell: true, stdio: 'ignore', detached: true });
178
- child.unref();
179
-
180
- // Poll for completion
181
- info('Waiting for browser authorization...');
182
- const maxAttempts = 120; // 2 minutes (polling every 1s)
183
- let attempts = 0;
160
+ if (choice === 0) {
161
+ // Google Login (Browser flow)
162
+ clearScreen();
163
+ log(`${colors.bgBlue}${colors.white}${colors.bold} Google Authentication ${colors.reset}\n`);
184
164
 
185
- while (attempts < maxAttempts) {
186
- await new Promise(r => setTimeout(r, 1500));
187
- attempts++;
165
+ // Generate a random session code
166
+ const sessionCode = 'cli_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
188
167
 
189
- try {
190
- const pollRes = await fetch(`${apiUrl.replace(/\/$/, '')}/api/cli/session/${sessionCode}`);
191
-
192
- if (pollRes.status === 404) {
193
- // Session expired or not found
194
- if (attempts > 10) {
195
- error('Session expired. Please try again.');
196
- return;
197
- }
198
- continue;
199
- }
168
+ info('Registering CLI session...');
169
+ try {
170
+ const regRes = await fetch(`${apiUrl.replace(/\/$/, '')}/api/cli/session`, {
171
+ method: 'POST',
172
+ headers: { 'Content-Type': 'application/json' },
173
+ body: JSON.stringify({ code: sessionCode })
174
+ });
175
+
176
+ if (!regRes.ok) {
177
+ throw new Error(`Server returned ${regRes.status}`);
178
+ }
200
179
 
201
- if (pollRes.ok) {
202
- const data = await pollRes.json();
180
+ // Open browser
181
+ const authPageUrl = `${apiUrl.replace(/\/$/, '')}/auth-cli-20260628dontuseforyounote?session=${sessionCode}`;
182
+ info(`Opening browser for authentication...`);
183
+ log(`\n${colors.dim}If browser does not open automatically, visit:${colors.reset}`);
184
+ log(`${colors.bold}${colors.cyan}${authPageUrl}${colors.reset}\n`);
185
+
186
+ // Platform-specific browser open
187
+ const openCmd = process.platform === 'win32' ? 'start'
188
+ : process.platform === 'darwin' ? 'open'
189
+ : 'xdg-open';
190
+ const child = spawn(openCmd, [authPageUrl], { shell: true, stdio: 'ignore', detached: true });
191
+ child.unref();
192
+
193
+ // Poll for completion
194
+ info('Waiting for browser authorization...');
195
+ const maxAttempts = 120; // 2 minutes (polling every 1.5s)
196
+ let attempts = 0;
197
+
198
+ while (attempts < maxAttempts) {
199
+ await new Promise(r => setTimeout(r, 1500));
200
+ attempts++;
201
+
202
+ try {
203
+ const pollRes = await fetch(`${apiUrl.replace(/\/$/, '')}/api/cli/session/${sessionCode}`);
203
204
 
204
- if (data.status === 'completed' && data.room_id && data.api_key) {
205
- clearScreen();
206
- log(`${colors.bgBlue}${colors.white}${colors.bold} CLI Connected Successfully! ${colors.reset}\n`);
207
- await saveConfig({
208
- apiUrl,
209
- roomId: data.room_id,
210
- apiKey: data.api_key
211
- });
212
- success(`Linked to room: ${colors.bold}${data.room_id}.notepad.web.id${colors.reset}`);
213
- info('You can now use all CLI commands. Try: note list');
214
- return;
205
+ if (pollRes.status === 404) {
206
+ if (attempts > 10) {
207
+ error('Session expired. Please try again.');
208
+ return;
209
+ }
210
+ continue;
211
+ }
212
+
213
+ if (pollRes.ok) {
214
+ const data = await pollRes.json();
215
+
216
+ if (data.status === 'completed' && data.room_id && data.api_key) {
217
+ clearScreen();
218
+ log(`${colors.bgBlue}${colors.white}${colors.bold} CLI Connected Successfully! ${colors.reset}\n`);
219
+ await saveConfig({
220
+ apiUrl,
221
+ roomId: data.room_id,
222
+ apiKey: data.api_key
223
+ });
224
+ success(`Linked to room: ${colors.bold}${data.room_id}.notepad.web.id${colors.reset}`);
225
+ info('You can now use all CLI commands. Try: note list');
226
+ return;
227
+ }
215
228
  }
229
+ } catch (pollErr) {
230
+ // Silently continue polling
216
231
  }
217
- } catch (pollErr) {
218
- // Silently continue polling
219
- }
220
232
 
221
- // Progress indicator
222
- if (attempts % 4 === 0) {
223
- process.stdout.write(`\r${colors.dim} Polling... (${attempts}s elapsed, waiting for browser auth)${colors.reset} `);
233
+ if (attempts % 4 === 0) {
234
+ process.stdout.write(`\r${colors.dim} Polling... (${attempts}s elapsed, waiting for browser auth)${colors.reset} `);
235
+ }
224
236
  }
237
+
238
+ process.stdout.write('\n');
239
+ warning('Browser authorization timed out.');
240
+ } catch (e) {
241
+ error(`Browser login unavailable: ${e.message}`);
225
242
  }
243
+ } else {
244
+ // Manual API Key configuration
245
+ clearScreen();
246
+ log(`${colors.bgBlue}${colors.white}${colors.bold} Manual API Key Config ${colors.reset}\n`);
247
+
248
+ const roomId = await ask('Enter Subdomain/Room ID (e.g. "saya")', current.roomId);
249
+ const apiKey = await ask('Enter Room API Token/Key', current.apiKey);
226
250
 
227
- process.stdout.write('\n');
228
- warning('Browser authorization timed out.');
229
- info('Falling back to manual configuration...\n');
230
- } catch (e) {
231
- warning(`Browser login unavailable: ${e.message}`);
232
- info('Using manual configuration instead...\n');
251
+ await saveConfig({ apiUrl, roomId, apiKey });
233
252
  }
234
-
235
- // Fallback: manual configuration
236
- const roomId = await ask('Enter Subdomain/Room ID (e.g. "saya")', current.roomId);
237
- const apiKey = await ask('Enter Room API Token/Key', current.apiKey);
238
-
239
- await saveConfig({ apiUrl, roomId, apiKey });
240
253
  }
241
254
 
242
255
  async function handleList() {
@@ -739,7 +752,7 @@ async function main() {
739
752
  } else {
740
753
  switch (command) {
741
754
  case 'login':
742
- await handleLogin();
755
+ await handleLogin(subArg);
743
756
  break;
744
757
  case 'list':
745
758
  await handleList();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-notepad",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "CLI tool for notepad.web.id to access, edit, create, and list room notes interactively.",
5
5
  "type": "module",
6
6
  "bin": {