-
-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathbear-urls.ts
More file actions
134 lines (114 loc) · 4.04 KB
/
Copy pathbear-urls.ts
File metadata and controls
134 lines (114 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { spawn } from 'node:child_process';
import { BEAR_URL_SCHEME } from '../config.js';
import { logAndThrow, logger } from '../logging.js';
/**
* Parameters for Bear x-callback-url construction
*/
export interface BearUrlParams {
title?: string | undefined;
text?: string | undefined;
tags?: string | undefined;
id?: string | undefined;
header?: string | undefined;
mode?: 'append' | 'prepend' | 'replace' | 'replace_all' | undefined;
new_line?: 'yes' | 'no' | undefined;
file?: string | undefined;
filename?: string | undefined;
name?: string | undefined;
new_name?: string | undefined;
open_note?: 'yes' | 'no' | undefined;
new_window?: 'yes' | 'no' | undefined;
show_window?: 'yes' | 'no' | undefined;
}
/**
* Builds a Bear x-callback-url for various actions with proper parameter encoding.
* Includes required UX parameters for optimal user experience.
*
* @param action - Bear API action (e.g., 'create', 'add-text')
* @param params - Parameters for the specific action
* @returns Properly encoded x-callback-url string
*/
export function buildBearUrl(action: string, params: BearUrlParams = {}): string {
logger.debug(`Building Bear URL for action: ${action}`);
if (!action || typeof action !== 'string' || !action.trim()) {
logAndThrow('Bear URL error: Action parameter is required and must be a non-empty string');
}
const baseUrl = `${BEAR_URL_SCHEME}${action.trim()}`;
const urlParams = new URLSearchParams();
// Add provided parameters with proper encoding
const stringParams = [
'title',
'text',
'tags',
'id',
'header',
'file',
'filename',
'name',
'new_name',
] as const;
for (const key of stringParams) {
const value = params[key];
if (value !== undefined && value.trim()) {
urlParams.set(key, value.trim());
}
}
if (params.mode !== undefined) {
urlParams.set('mode', params.mode);
}
if (params.new_line !== undefined) {
urlParams.set('new_line', params.new_line);
}
// UX params with defaults
urlParams.set('open_note', params.open_note ?? 'yes');
urlParams.set('new_window', params.new_window ?? 'no');
urlParams.set('show_window', params.show_window ?? 'yes');
// Convert URLSearchParams to proper URL encoding (Bear expects %20 not +)
const queryString = urlParams.toString().replace(/\+/g, '%20');
const finalUrl = `${baseUrl}?${queryString}`;
logger.debug(`Built Bear URL: ${finalUrl}`);
return finalUrl;
}
/**
* Executes a Bear x-callback-url using macOS subprocess execution.
* Platform-specific function that requires macOS with Bear Notes installed.
*
* @param url - The x-callback-url to execute
* @returns Promise that resolves when the command completes successfully
* @throws Error if platform is not macOS or subprocess execution fails
*/
export function executeBearXCallbackApi(url: string): Promise<void> {
logger.debug('Executing Bear x-callback-url');
if (!url || typeof url !== 'string' || !url.trim()) {
logAndThrow('Bear URL error: URL parameter is required and must be a non-empty string');
}
return new Promise((resolve, reject) => {
logger.debug('Launching Bear Notes via x-callback-url');
const child = spawn('open', ['-g', url.trim()], {
stdio: 'pipe',
detached: false,
});
let errorOutput = '';
if (child.stderr) {
child.stderr.on('data', (data) => {
errorOutput += data.toString();
});
}
child.on('close', (code) => {
if (code === 0) {
logger.debug('Bear x-callback-url executed successfully');
resolve();
} else {
const errorMessage = `Bear URL error: Failed to execute x-callback-url (exit code: ${code})`;
const fullError = errorOutput ? `${errorMessage}. Error: ${errorOutput}` : errorMessage;
logger.error(fullError);
reject(new Error(fullError));
}
});
child.on('error', (error) => {
const errorMessage = `Bear URL error: Failed to spawn subprocess: ${error.message}`;
logger.error(errorMessage);
reject(new Error(errorMessage));
});
});
}