feat: resolve daily-note path from Obsidian config for scoped tokens
Build and Push Docker Container / build-and-push (push) Successful in 4m15s
Build and Push Docker Container / build-and-push (push) Successful in 4m15s
- Add daily_note_path_for_vault to read .obsidian/daily-notes.json - Honor configured folder and date format for daily commands - Add moment_to_strftime to translate Obsidian date tokens - Authorize pathless daily:* commands against the resolved path - Pick vault root from token vault, cwd, or default vault - Normalize n8n httpRequest response to avoid circular JSON output - Force returnFullResponse false and parse body to plain result - Bump n8n-nodes-obsidian-cli-api to 0.2.0 - Add tests for allowed and denied scoped daily commands
This commit is contained in:
@@ -61,9 +61,11 @@ export async function executeObsidianCommand(
|
||||
timeout: options.timeout,
|
||||
},
|
||||
json: true,
|
||||
returnFullResponse: false,
|
||||
};
|
||||
|
||||
const result = await context.helpers.httpRequest(request) as ObsidianCommandResult;
|
||||
const response = await context.helpers.httpRequest(request) as unknown;
|
||||
const result = normalizeCommandResult(response);
|
||||
|
||||
if (result.exit_code !== 0) {
|
||||
throw new NodeOperationError(
|
||||
@@ -75,3 +77,38 @@ export async function executeObsidianCommand(
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function normalizeCommandResult(response: unknown): ObsidianCommandResult {
|
||||
const data = extractResponseBody(response);
|
||||
const result = typeof data === 'string' ? JSON.parse(data) : data;
|
||||
|
||||
if (!isObject(result)) {
|
||||
throw new Error('Obsidian API returned a non-object response');
|
||||
}
|
||||
|
||||
return {
|
||||
id: String(result.id ?? ''),
|
||||
command: Array.isArray(result.command) ? result.command.map(String) : [],
|
||||
cwd: String(result.cwd ?? ''),
|
||||
exit_code: Number(result.exit_code ?? 0),
|
||||
stdout: String(result.stdout ?? ''),
|
||||
stderr: String(result.stderr ?? ''),
|
||||
duration_ms: Number(result.duration_ms ?? 0),
|
||||
timed_out: Boolean(result.timed_out),
|
||||
};
|
||||
}
|
||||
|
||||
function extractResponseBody(response: unknown): unknown {
|
||||
if (!isObject(response)) return response;
|
||||
|
||||
// Some n8n versions/helpers can return a full response object. Never pass that
|
||||
// through to node output because it contains circular fields like res.socket.
|
||||
if ('body' in response) return response.body;
|
||||
if ('data' in response) return response.data;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
function isObject(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user