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:
@@ -16,6 +16,11 @@ Resources:
|
||||
- Delete
|
||||
- Rename
|
||||
- List Files
|
||||
- **Property**
|
||||
- Set
|
||||
- Read
|
||||
- Remove
|
||||
- List
|
||||
- **Daily Note**
|
||||
- Append
|
||||
- Prepend
|
||||
@@ -51,6 +56,29 @@ Raw command example:
|
||||
["vault=work", "read", "path=Inbox/Note.md"]
|
||||
```
|
||||
|
||||
## Properties / frontmatter
|
||||
The official Obsidian CLI supports property/frontmatter commands. The n8n node exposes them as the **Property** resource:
|
||||
|
||||
- **Set** sends `property:set path=<note> name=<property> value=<value> type=<type>`
|
||||
- **Read** sends `property:read path=<note> name=<property>`
|
||||
- **Remove** sends `property:remove path=<note> name=<property>`
|
||||
- **List** sends `properties name=<optional> format=<yaml|json|tsv>`
|
||||
|
||||
Examples:
|
||||
```text
|
||||
path=00 Kontext/Feedback Browser CLI Tests.md
|
||||
name=tags
|
||||
value=kontext, feedback-browser-cli-tests
|
||||
type=list
|
||||
```
|
||||
|
||||
```text
|
||||
path=00 Kontext/Feedback Browser CLI Tests.md
|
||||
name=date
|
||||
value=2026-06-24
|
||||
type=date
|
||||
```
|
||||
|
||||
## Local install in self-hosted n8n
|
||||
From this repo:
|
||||
```bash
|
||||
|
||||
@@ -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':
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "n8n-nodes-obsidian-cli-api",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "n8n-nodes-obsidian-cli-api",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.5",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "n8n-nodes-obsidian-cli-api",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.5",
|
||||
"description": "n8n community nodes for the Obsidian API Docker service backed by the official Obsidian CLI.",
|
||||
"license": "MIT",
|
||||
"homepage": "https://git.yiprawr.dev/Docker/obsidian-api",
|
||||
|
||||
Reference in New Issue
Block a user