feat(obsidian): add property frontmatter commands
Build and Push Docker Container / build-and-push (push) Successful in 4m27s
Build and Push Docker Container / build-and-push (push) Successful in 4m27s
- Expose Obsidian CLI property commands via the n8n Obsidian API node - Add a new Property resource with operations: Set, Read, Remove, List - Implement correct args mapping for property:set/property:read/property:remove/properties - Return raw CLI stdout for property read/list for easier downstream parsing - Update node README with frontmatter/property usage examples - Bump package version to 0.2.5
This commit is contained in:
@@ -37,6 +37,7 @@ export class ObsidianApi implements INodeType {
|
||||
options: [
|
||||
{ name: 'Daily Note', value: 'daily' },
|
||||
{ name: 'Note', value: 'note' },
|
||||
{ name: 'Property', value: 'property' },
|
||||
{ name: 'Raw Command', value: 'raw' },
|
||||
{ name: 'Search', value: 'search' },
|
||||
{ name: 'Vault', value: 'vault' },
|
||||
@@ -129,6 +130,78 @@ export class ObsidianApi implements INodeType {
|
||||
required: true,
|
||||
},
|
||||
|
||||
// Property operations
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: { show: { resource: ['property'] } },
|
||||
options: [
|
||||
{ name: 'List', value: 'properties' },
|
||||
{ name: 'Read', value: 'propertyRead' },
|
||||
{ name: 'Remove', value: 'propertyRemove' },
|
||||
{ name: 'Set', value: 'propertySet' },
|
||||
],
|
||||
default: 'propertySet',
|
||||
},
|
||||
{
|
||||
displayName: 'Path',
|
||||
name: 'propertyPath',
|
||||
type: 'string',
|
||||
displayOptions: { show: { resource: ['property'], operation: ['propertyRead', 'propertyRemove', 'propertySet'] } },
|
||||
default: '',
|
||||
placeholder: 'Inbox/Note.md',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'propertyName',
|
||||
type: 'string',
|
||||
displayOptions: { show: { resource: ['property'], operation: ['propertyRead', 'propertyRemove', 'propertySet', 'properties'] } },
|
||||
default: '',
|
||||
placeholder: 'tags',
|
||||
description: 'Frontmatter/property name, e.g. tags, date, description',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'propertyValue',
|
||||
type: 'string',
|
||||
displayOptions: { show: { resource: ['property'], operation: ['propertySet'] } },
|
||||
default: '',
|
||||
placeholder: 'kontext, feedback-browser-cli-tests',
|
||||
description: 'Value passed to the official CLI property:set command',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'propertyType',
|
||||
type: 'options',
|
||||
displayOptions: { show: { resource: ['property'], operation: ['propertySet'] } },
|
||||
options: [
|
||||
{ name: 'Text', value: 'text' },
|
||||
{ name: 'List', value: 'list' },
|
||||
{ name: 'Number', value: 'number' },
|
||||
{ name: 'Checkbox', value: 'checkbox' },
|
||||
{ name: 'Date', value: 'date' },
|
||||
{ name: 'Date Time', value: 'datetime' },
|
||||
],
|
||||
default: 'text',
|
||||
description: 'Obsidian property type. Use List for tags and Date for date.',
|
||||
},
|
||||
{
|
||||
displayName: 'Format',
|
||||
name: 'propertiesFormat',
|
||||
type: 'options',
|
||||
displayOptions: { show: { resource: ['property'], operation: ['properties'] } },
|
||||
options: [
|
||||
{ name: 'YAML', value: 'yaml' },
|
||||
{ name: 'JSON', value: 'json' },
|
||||
{ name: 'TSV', value: 'tsv' },
|
||||
],
|
||||
default: 'yaml',
|
||||
},
|
||||
|
||||
// Search operations
|
||||
{
|
||||
displayName: 'Operation',
|
||||
@@ -247,6 +320,10 @@ export class ObsidianApi implements INodeType {
|
||||
args = buildSearchArgs(this, operation, itemIndex);
|
||||
break;
|
||||
}
|
||||
case 'property': {
|
||||
args = buildPropertyArgs(this, operation, itemIndex);
|
||||
break;
|
||||
}
|
||||
case 'vault': {
|
||||
args = buildVaultArgs(this, operation, itemIndex, additionalFields);
|
||||
break;
|
||||
@@ -293,6 +370,15 @@ export class ObsidianApi implements INodeType {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Properties: keep CLI output because read/list return useful data.
|
||||
if (resource === 'property' && (operation === 'propertyRead' || operation === 'properties')) {
|
||||
const out: any = { content: stdout };
|
||||
if (result.stderr) out.stderr = result.stderr;
|
||||
if (result.timed_out) out.timed_out = result.timed_out;
|
||||
returnData.push({ json: out, pairedItem: { item: itemIndex } });
|
||||
continue;
|
||||
}
|
||||
|
||||
// vault and vaults are parsed as structured JSON
|
||||
const parsed = (result as any).parsed_stdout;
|
||||
if (parsed) {
|
||||
@@ -370,6 +456,34 @@ function buildSearchArgs(context: IExecuteFunctions, operation: string, itemInde
|
||||
]);
|
||||
}
|
||||
|
||||
function buildPropertyArgs(context: IExecuteFunctions, operation: string, itemIndex: number): string[] {
|
||||
const path = context.getNodeParameter('propertyPath', itemIndex, '') as string;
|
||||
const name = context.getNodeParameter('propertyName', itemIndex, '') as string;
|
||||
|
||||
switch (operation) {
|
||||
case 'properties':
|
||||
return compactArgs([
|
||||
'properties',
|
||||
kv('name', name),
|
||||
kv('format', context.getNodeParameter('propertiesFormat', itemIndex) as string),
|
||||
]);
|
||||
case 'propertyRead':
|
||||
return compactArgs(['property:read', kv('path', path), kv('name', name)]);
|
||||
case 'propertyRemove':
|
||||
return compactArgs(['property:remove', kv('path', path), kv('name', name)]);
|
||||
case 'propertySet':
|
||||
return compactArgs([
|
||||
'property:set',
|
||||
kv('path', path),
|
||||
kv('name', name),
|
||||
kv('value', context.getNodeParameter('propertyValue', itemIndex) as string),
|
||||
kv('type', context.getNodeParameter('propertyType', itemIndex) as string),
|
||||
]);
|
||||
default:
|
||||
throw new NodeOperationError(context.getNode(), `Unsupported property operation: ${operation}`, { itemIndex });
|
||||
}
|
||||
}
|
||||
|
||||
function buildVaultArgs(context: IExecuteFunctions, operation: string, itemIndex: number, additionalFields: Record<string, unknown>): string[] {
|
||||
switch (operation) {
|
||||
case 'vaultInfo':
|
||||
|
||||
Reference in New Issue
Block a user