@unwarkz/n8n-nodes-outline-wiki 1.0.1
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.
- package/README.md +223 -0
- package/dist/credentials/OutlineApi.credentials.js +43 -0
- package/dist/nodes/outline/Outline.node.js +1641 -0
- package/dist/nodes/outline/OutlineAiTools.node.js +1506 -0
- package/dist/nodes/outline/outline.svg +7 -0
- package/index.js +3 -0
- package/package.json +51 -0
|
@@ -0,0 +1,1641 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Outline = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
|
|
6
|
+
// ── Shared HTTP helpers ──────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
async function outlineApiRequest(ctx, endpoint, body) {
|
|
9
|
+
const credentials = await ctx.getCredentials('outlineApi');
|
|
10
|
+
const baseUrl = (credentials.baseUrl || 'https://app.getoutline.com').replace(/\/$/, '');
|
|
11
|
+
const apiKey = credentials.apiKey;
|
|
12
|
+
const options = {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
url: `${baseUrl}/api${endpoint}`,
|
|
15
|
+
headers: {
|
|
16
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
'Accept': 'application/json',
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify(body || {}),
|
|
21
|
+
json: true,
|
|
22
|
+
};
|
|
23
|
+
try {
|
|
24
|
+
return await ctx.helpers.request(options);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
throw new n8n_workflow_1.NodeApiError(ctx.getNode(), error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function outlineApiRequestMultipart(ctx, endpoint, formData) {
|
|
31
|
+
const credentials = await ctx.getCredentials('outlineApi');
|
|
32
|
+
const baseUrl = (credentials.baseUrl || 'https://app.getoutline.com').replace(/\/$/, '');
|
|
33
|
+
const apiKey = credentials.apiKey;
|
|
34
|
+
const options = {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
url: `${baseUrl}/api${endpoint}`,
|
|
37
|
+
headers: {
|
|
38
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
39
|
+
'Accept': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
formData,
|
|
42
|
+
json: true,
|
|
43
|
+
};
|
|
44
|
+
try {
|
|
45
|
+
return await ctx.helpers.request(options);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw new n8n_workflow_1.NodeApiError(ctx.getNode(), error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function guessMimeType(filePath) {
|
|
52
|
+
const ext = (filePath || '').split('.').pop().toLowerCase();
|
|
53
|
+
const map = {
|
|
54
|
+
md: 'text/markdown', markdown: 'text/markdown',
|
|
55
|
+
txt: 'text/plain', html: 'text/html', htm: 'text/html',
|
|
56
|
+
csv: 'text/csv', tsv: 'text/tab-separated-values',
|
|
57
|
+
pdf: 'application/pdf',
|
|
58
|
+
doc: 'application/msword',
|
|
59
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
60
|
+
xls: 'application/vnd.ms-excel',
|
|
61
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
62
|
+
ppt: 'application/vnd.ms-powerpoint',
|
|
63
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
64
|
+
jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif',
|
|
65
|
+
webp: 'image/webp', svg: 'image/svg+xml',
|
|
66
|
+
zip: 'application/zip', json: 'application/json',
|
|
67
|
+
};
|
|
68
|
+
return map[ext] || 'application/octet-stream';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ── Node class ───────────────────────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
class Outline {
|
|
74
|
+
constructor() {
|
|
75
|
+
this.description = {
|
|
76
|
+
displayName: 'Outline Wiki',
|
|
77
|
+
name: 'outline',
|
|
78
|
+
icon: 'file:outline.svg',
|
|
79
|
+
group: ['transform'],
|
|
80
|
+
version: 1,
|
|
81
|
+
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
|
|
82
|
+
description: 'Interact with the Outline Wiki API — documents, collections, comments, attachments, users, shares',
|
|
83
|
+
defaults: { name: 'Outline Wiki' },
|
|
84
|
+
inputs: ['main'],
|
|
85
|
+
outputs: ['main'],
|
|
86
|
+
credentials: [{ name: 'outlineApi', required: true }],
|
|
87
|
+
codex: {
|
|
88
|
+
categories: ['Productivity', 'Utility'],
|
|
89
|
+
subcategories: {
|
|
90
|
+
Productivity: ['Documentation', 'Wiki'],
|
|
91
|
+
},
|
|
92
|
+
resources: {
|
|
93
|
+
primaryDocumentation: [{ url: 'https://www.getoutline.com/developers' }],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
properties: [
|
|
97
|
+
// ── Resource ──────────────────────────────────────────────────────
|
|
98
|
+
{
|
|
99
|
+
displayName: 'Resource',
|
|
100
|
+
name: 'resource',
|
|
101
|
+
type: 'options',
|
|
102
|
+
noDataExpression: true,
|
|
103
|
+
options: [
|
|
104
|
+
{ name: 'Attachment', value: 'attachment', description: 'Manage file attachments' },
|
|
105
|
+
{ name: 'Collection', value: 'collection', description: 'Manage document collections' },
|
|
106
|
+
{ name: 'Comment', value: 'comment', description: 'Manage document comments' },
|
|
107
|
+
{ name: 'Document', value: 'document', description: 'Create, read, update and delete documents' },
|
|
108
|
+
{ name: 'Share', value: 'share', description: 'Manage public share links' },
|
|
109
|
+
{ name: 'User', value: 'user', description: 'Manage workspace users' },
|
|
110
|
+
],
|
|
111
|
+
default: 'document',
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
// ── Document Operations ──────────────────────────────────────────
|
|
115
|
+
{
|
|
116
|
+
displayName: 'Operation',
|
|
117
|
+
name: 'operation',
|
|
118
|
+
type: 'options',
|
|
119
|
+
noDataExpression: true,
|
|
120
|
+
displayOptions: { show: { resource: ['document'] } },
|
|
121
|
+
options: [
|
|
122
|
+
{ name: 'Answer Question', value: 'answerQuestion', description: 'Answer a natural-language question using AI (requires AI answers feature)', action: 'Answer a question using AI' },
|
|
123
|
+
{ name: 'Archive', value: 'archive', description: 'Archive a document (restorable)', action: 'Archive a document' },
|
|
124
|
+
{ name: 'Create', value: 'create', description: 'Create a new document', action: 'Create a document' },
|
|
125
|
+
{ name: 'Delete', value: 'delete', description: 'Move a document to trash or permanently destroy it', action: 'Delete a document' },
|
|
126
|
+
{ name: 'Export', value: 'export', description: 'Export a document as Markdown (returned as binary data)', action: 'Export a document' },
|
|
127
|
+
{ name: 'Get', value: 'get', description: 'Retrieve a document by ID or URL slug', action: 'Get a document' },
|
|
128
|
+
{ name: 'Import', value: 'import', description: 'Import a file (Markdown, HTML, DOCX, CSV…) as a new document', action: 'Import a document from file' },
|
|
129
|
+
{ name: 'List', value: 'list', description: 'List documents with optional filters', action: 'List documents' },
|
|
130
|
+
{ name: 'Move', value: 'move', description: 'Move a document to a different collection or parent', action: 'Move a document' },
|
|
131
|
+
{ name: 'Restore', value: 'restore', description: 'Restore an archived or deleted document', action: 'Restore a document' },
|
|
132
|
+
{ name: 'Search', value: 'search', description: 'Full-text search across all documents', action: 'Search documents' },
|
|
133
|
+
{ name: 'Search Titles', value: 'searchTitles', description: 'Fast title-only search', action: 'Search document titles' },
|
|
134
|
+
{ name: 'Update', value: 'update', description: 'Update a document title, body, or publish status', action: 'Update a document' },
|
|
135
|
+
],
|
|
136
|
+
default: 'get',
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
// ── Collection Operations ────────────────────────────────────────
|
|
140
|
+
{
|
|
141
|
+
displayName: 'Operation',
|
|
142
|
+
name: 'operation',
|
|
143
|
+
type: 'options',
|
|
144
|
+
noDataExpression: true,
|
|
145
|
+
displayOptions: { show: { resource: ['collection'] } },
|
|
146
|
+
options: [
|
|
147
|
+
{ name: 'Create', value: 'create', description: 'Create a new collection', action: 'Create a collection' },
|
|
148
|
+
{ name: 'Delete', value: 'delete', description: 'Delete a collection and ALL its documents (irreversible)', action: 'Delete a collection' },
|
|
149
|
+
{ name: 'Export', value: 'export', description: 'Trigger a bulk export of a collection', action: 'Export a collection' },
|
|
150
|
+
{ name: 'Get', value: 'get', description: 'Retrieve collection details by UUID', action: 'Get a collection' },
|
|
151
|
+
{ name: 'Get Document Tree', value: 'getDocuments', description: 'Get the document hierarchy/tree for a collection', action: 'Get collection document tree' },
|
|
152
|
+
{ name: 'List', value: 'list', description: 'List all accessible collections', action: 'List collections' },
|
|
153
|
+
{ name: 'Update', value: 'update', description: 'Update a collection name, description, or settings', action: 'Update a collection' },
|
|
154
|
+
],
|
|
155
|
+
default: 'list',
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
// ── Comment Operations ───────────────────────────────────────────
|
|
159
|
+
{
|
|
160
|
+
displayName: 'Operation',
|
|
161
|
+
name: 'operation',
|
|
162
|
+
type: 'options',
|
|
163
|
+
noDataExpression: true,
|
|
164
|
+
displayOptions: { show: { resource: ['comment'] } },
|
|
165
|
+
options: [
|
|
166
|
+
{ name: 'Create', value: 'create', description: 'Add a comment to a document', action: 'Create a comment' },
|
|
167
|
+
{ name: 'Delete', value: 'delete', description: 'Delete a comment and all its replies', action: 'Delete a comment' },
|
|
168
|
+
{ name: 'List', value: 'list', description: 'List comments on a document or within a collection', action: 'List comments' },
|
|
169
|
+
{ name: 'Update', value: 'update', description: 'Edit an existing comment', action: 'Update a comment' },
|
|
170
|
+
],
|
|
171
|
+
default: 'list',
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
// ── Attachment Operations ────────────────────────────────────────
|
|
175
|
+
{
|
|
176
|
+
displayName: 'Operation',
|
|
177
|
+
name: 'operation',
|
|
178
|
+
type: 'options',
|
|
179
|
+
noDataExpression: true,
|
|
180
|
+
displayOptions: { show: { resource: ['attachment'] } },
|
|
181
|
+
options: [
|
|
182
|
+
{ name: 'Delete', value: 'delete', description: 'Permanently delete an attachment', action: 'Delete an attachment' },
|
|
183
|
+
{ name: 'Upload', value: 'upload', description: 'Upload a file as an Outline attachment (returns attachment URL)', action: 'Upload an attachment' },
|
|
184
|
+
],
|
|
185
|
+
default: 'upload',
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
// ── User Operations ──────────────────────────────────────────────
|
|
189
|
+
{
|
|
190
|
+
displayName: 'Operation',
|
|
191
|
+
name: 'operation',
|
|
192
|
+
type: 'options',
|
|
193
|
+
noDataExpression: true,
|
|
194
|
+
displayOptions: { show: { resource: ['user'] } },
|
|
195
|
+
options: [
|
|
196
|
+
{ name: 'Get', value: 'get', description: 'Get details for a specific user', action: 'Get a user' },
|
|
197
|
+
{ name: 'List', value: 'list', description: 'List workspace users', action: 'List users' },
|
|
198
|
+
],
|
|
199
|
+
default: 'list',
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
// ── Share Operations ─────────────────────────────────────────────
|
|
203
|
+
{
|
|
204
|
+
displayName: 'Operation',
|
|
205
|
+
name: 'operation',
|
|
206
|
+
type: 'options',
|
|
207
|
+
noDataExpression: true,
|
|
208
|
+
displayOptions: { show: { resource: ['share'] } },
|
|
209
|
+
options: [
|
|
210
|
+
{ name: 'Create', value: 'create', description: 'Create a public share link for a document', action: 'Create a share link' },
|
|
211
|
+
{ name: 'List', value: 'list', description: 'List existing share links', action: 'List share links' },
|
|
212
|
+
{ name: 'Revoke', value: 'revoke', description: 'Revoke a share link', action: 'Revoke a share link' },
|
|
213
|
+
],
|
|
214
|
+
default: 'list',
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
// ════════════════════════════════════════════════════════════════
|
|
218
|
+
// DOCUMENT PARAMETERS
|
|
219
|
+
// ════════════════════════════════════════════════════════════════
|
|
220
|
+
|
|
221
|
+
// Document ID — used by get/update/delete/archive/restore/move/export/answerQuestion
|
|
222
|
+
{
|
|
223
|
+
displayName: 'Document ID',
|
|
224
|
+
name: 'documentId',
|
|
225
|
+
type: 'string',
|
|
226
|
+
default: '',
|
|
227
|
+
required: true,
|
|
228
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
229
|
+
description: 'Document UUID or URL slug (urlId)',
|
|
230
|
+
displayOptions: {
|
|
231
|
+
show: {
|
|
232
|
+
resource: ['document'],
|
|
233
|
+
operation: ['get', 'update', 'delete', 'archive', 'restore', 'move', 'export'],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
displayName: 'Document ID',
|
|
239
|
+
name: 'documentId',
|
|
240
|
+
type: 'string',
|
|
241
|
+
default: '',
|
|
242
|
+
required: false,
|
|
243
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
244
|
+
description: 'UUID of a specific document to search within (optional)',
|
|
245
|
+
displayOptions: {
|
|
246
|
+
show: {
|
|
247
|
+
resource: ['document'],
|
|
248
|
+
operation: ['answerQuestion'],
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
// Title — create, update
|
|
254
|
+
{
|
|
255
|
+
displayName: 'Title',
|
|
256
|
+
name: 'title',
|
|
257
|
+
type: 'string',
|
|
258
|
+
default: '',
|
|
259
|
+
required: true,
|
|
260
|
+
placeholder: 'My Document',
|
|
261
|
+
description: 'The document title',
|
|
262
|
+
displayOptions: {
|
|
263
|
+
show: {
|
|
264
|
+
resource: ['document'],
|
|
265
|
+
operation: ['create'],
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// Body — create (optional), update (optional)
|
|
271
|
+
{
|
|
272
|
+
displayName: 'Body (Markdown)',
|
|
273
|
+
name: 'text',
|
|
274
|
+
type: 'string',
|
|
275
|
+
typeOptions: { rows: 8 },
|
|
276
|
+
default: '',
|
|
277
|
+
description: 'Document body in Markdown format',
|
|
278
|
+
displayOptions: {
|
|
279
|
+
show: {
|
|
280
|
+
resource: ['document'],
|
|
281
|
+
operation: ['create'],
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
// Collection ID — required for create (unless parent given), list filter, import, move, search filter
|
|
287
|
+
{
|
|
288
|
+
displayName: 'Collection ID',
|
|
289
|
+
name: 'collectionId',
|
|
290
|
+
type: 'string',
|
|
291
|
+
default: '',
|
|
292
|
+
required: false,
|
|
293
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
294
|
+
description: 'UUID of the collection. Required for Create unless Parent Document ID is set.',
|
|
295
|
+
displayOptions: {
|
|
296
|
+
show: {
|
|
297
|
+
resource: ['document'],
|
|
298
|
+
operation: ['create', 'list', 'move'],
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
displayName: 'Collection ID',
|
|
304
|
+
name: 'collectionId',
|
|
305
|
+
type: 'string',
|
|
306
|
+
default: '',
|
|
307
|
+
required: false,
|
|
308
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
309
|
+
description: 'UUID of the collection to import the document into. Required unless Parent Document ID is set.',
|
|
310
|
+
displayOptions: {
|
|
311
|
+
show: {
|
|
312
|
+
resource: ['document'],
|
|
313
|
+
operation: ['import'],
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
// Publish — create, import, update
|
|
319
|
+
{
|
|
320
|
+
displayName: 'Publish',
|
|
321
|
+
name: 'publish',
|
|
322
|
+
type: 'boolean',
|
|
323
|
+
default: false,
|
|
324
|
+
description: 'Whether to immediately publish (true) or save as draft (false)',
|
|
325
|
+
displayOptions: {
|
|
326
|
+
show: {
|
|
327
|
+
resource: ['document'],
|
|
328
|
+
operation: ['create', 'import'],
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
// Search query
|
|
334
|
+
{
|
|
335
|
+
displayName: 'Query',
|
|
336
|
+
name: 'query',
|
|
337
|
+
type: 'string',
|
|
338
|
+
default: '',
|
|
339
|
+
required: true,
|
|
340
|
+
placeholder: 'meeting notes',
|
|
341
|
+
description: 'The search query',
|
|
342
|
+
displayOptions: {
|
|
343
|
+
show: {
|
|
344
|
+
resource: ['document'],
|
|
345
|
+
operation: ['search', 'searchTitles'],
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
displayName: 'Question',
|
|
351
|
+
name: 'query',
|
|
352
|
+
type: 'string',
|
|
353
|
+
default: '',
|
|
354
|
+
required: true,
|
|
355
|
+
placeholder: 'What is our vacation policy?',
|
|
356
|
+
description: 'A natural-language question to ask the AI against your knowledge base',
|
|
357
|
+
displayOptions: {
|
|
358
|
+
show: {
|
|
359
|
+
resource: ['document'],
|
|
360
|
+
operation: ['answerQuestion'],
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
// Binary Property for import
|
|
366
|
+
{
|
|
367
|
+
displayName: 'Binary Property',
|
|
368
|
+
name: 'binaryPropertyName',
|
|
369
|
+
type: 'string',
|
|
370
|
+
default: 'data',
|
|
371
|
+
required: true,
|
|
372
|
+
description: 'Name of the binary property containing the file to import (Markdown, HTML, DOCX, CSV…)',
|
|
373
|
+
displayOptions: {
|
|
374
|
+
show: {
|
|
375
|
+
resource: ['document'],
|
|
376
|
+
operation: ['import'],
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
// Output binary property for export
|
|
382
|
+
{
|
|
383
|
+
displayName: 'Output Binary Property',
|
|
384
|
+
name: 'outputBinaryPropertyName',
|
|
385
|
+
type: 'string',
|
|
386
|
+
default: 'data',
|
|
387
|
+
description: 'Name of the binary property to store the exported Markdown file',
|
|
388
|
+
displayOptions: {
|
|
389
|
+
show: {
|
|
390
|
+
resource: ['document'],
|
|
391
|
+
operation: ['export'],
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
// Additional Fields for document: create
|
|
397
|
+
{
|
|
398
|
+
displayName: 'Additional Fields',
|
|
399
|
+
name: 'additionalFields',
|
|
400
|
+
type: 'collection',
|
|
401
|
+
placeholder: 'Add Field',
|
|
402
|
+
default: {},
|
|
403
|
+
displayOptions: {
|
|
404
|
+
show: {
|
|
405
|
+
resource: ['document'],
|
|
406
|
+
operation: ['create'],
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
options: [
|
|
410
|
+
{
|
|
411
|
+
displayName: 'Parent Document ID',
|
|
412
|
+
name: 'parentDocumentId',
|
|
413
|
+
type: 'string',
|
|
414
|
+
default: '',
|
|
415
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
416
|
+
description: 'UUID of a parent document to create this as a child document under',
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
displayName: 'Template ID',
|
|
420
|
+
name: 'templateId',
|
|
421
|
+
type: 'string',
|
|
422
|
+
default: '',
|
|
423
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
424
|
+
description: 'UUID of a template to use as the basis for this document',
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
},
|
|
428
|
+
|
|
429
|
+
// Additional Fields for document: update
|
|
430
|
+
{
|
|
431
|
+
displayName: 'Update Fields',
|
|
432
|
+
name: 'updateFields',
|
|
433
|
+
type: 'collection',
|
|
434
|
+
placeholder: 'Add Field',
|
|
435
|
+
default: {},
|
|
436
|
+
displayOptions: {
|
|
437
|
+
show: {
|
|
438
|
+
resource: ['document'],
|
|
439
|
+
operation: ['update'],
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
options: [
|
|
443
|
+
{
|
|
444
|
+
displayName: 'Title',
|
|
445
|
+
name: 'title',
|
|
446
|
+
type: 'string',
|
|
447
|
+
default: '',
|
|
448
|
+
description: 'New document title',
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
displayName: 'Body (Markdown)',
|
|
452
|
+
name: 'text',
|
|
453
|
+
type: 'string',
|
|
454
|
+
typeOptions: { rows: 8 },
|
|
455
|
+
default: '',
|
|
456
|
+
description: 'New document body in Markdown (replaces existing content)',
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
displayName: 'Publish',
|
|
460
|
+
name: 'publish',
|
|
461
|
+
type: 'boolean',
|
|
462
|
+
default: true,
|
|
463
|
+
description: 'Whether to publish (true) or unpublish (false) the document',
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
displayName: 'Full Width',
|
|
467
|
+
name: 'fullWidth',
|
|
468
|
+
type: 'boolean',
|
|
469
|
+
default: false,
|
|
470
|
+
description: 'Whether to display the document in full-width layout',
|
|
471
|
+
},
|
|
472
|
+
],
|
|
473
|
+
},
|
|
474
|
+
|
|
475
|
+
// Additional Fields for document: delete
|
|
476
|
+
{
|
|
477
|
+
displayName: 'Additional Fields',
|
|
478
|
+
name: 'additionalFields',
|
|
479
|
+
type: 'collection',
|
|
480
|
+
placeholder: 'Add Field',
|
|
481
|
+
default: {},
|
|
482
|
+
displayOptions: {
|
|
483
|
+
show: {
|
|
484
|
+
resource: ['document'],
|
|
485
|
+
operation: ['delete'],
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
options: [
|
|
489
|
+
{
|
|
490
|
+
displayName: 'Permanent',
|
|
491
|
+
name: 'permanent',
|
|
492
|
+
type: 'boolean',
|
|
493
|
+
default: false,
|
|
494
|
+
description: 'Whether to permanently destroy the document (no recovery). Default: false (moves to trash).',
|
|
495
|
+
},
|
|
496
|
+
],
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
// Additional Fields for document: list
|
|
500
|
+
{
|
|
501
|
+
displayName: 'Filters',
|
|
502
|
+
name: 'filters',
|
|
503
|
+
type: 'collection',
|
|
504
|
+
placeholder: 'Add Filter',
|
|
505
|
+
default: {},
|
|
506
|
+
displayOptions: {
|
|
507
|
+
show: {
|
|
508
|
+
resource: ['document'],
|
|
509
|
+
operation: ['list'],
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
options: [
|
|
513
|
+
{
|
|
514
|
+
displayName: 'Parent Document ID',
|
|
515
|
+
name: 'parentDocumentId',
|
|
516
|
+
type: 'string',
|
|
517
|
+
default: '',
|
|
518
|
+
description: 'UUID of the parent document to list children of',
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
displayName: 'Status Filter',
|
|
522
|
+
name: 'statusFilter',
|
|
523
|
+
type: 'options',
|
|
524
|
+
options: [
|
|
525
|
+
{ name: 'All', value: '' },
|
|
526
|
+
{ name: 'Draft', value: 'draft' },
|
|
527
|
+
{ name: 'Published', value: 'published' },
|
|
528
|
+
{ name: 'Archived', value: 'archived' },
|
|
529
|
+
],
|
|
530
|
+
default: '',
|
|
531
|
+
description: 'Filter by document status',
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
displayName: 'Limit',
|
|
535
|
+
name: 'limit',
|
|
536
|
+
type: 'number',
|
|
537
|
+
default: 25,
|
|
538
|
+
description: 'Maximum number of results to return',
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
displayName: 'Offset',
|
|
542
|
+
name: 'offset',
|
|
543
|
+
type: 'number',
|
|
544
|
+
default: 0,
|
|
545
|
+
description: 'Offset for pagination',
|
|
546
|
+
},
|
|
547
|
+
],
|
|
548
|
+
},
|
|
549
|
+
|
|
550
|
+
// Additional Fields for document: search / searchTitles
|
|
551
|
+
{
|
|
552
|
+
displayName: 'Filters',
|
|
553
|
+
name: 'filters',
|
|
554
|
+
type: 'collection',
|
|
555
|
+
placeholder: 'Add Filter',
|
|
556
|
+
default: {},
|
|
557
|
+
displayOptions: {
|
|
558
|
+
show: {
|
|
559
|
+
resource: ['document'],
|
|
560
|
+
operation: ['search', 'searchTitles'],
|
|
561
|
+
},
|
|
562
|
+
},
|
|
563
|
+
options: [
|
|
564
|
+
{
|
|
565
|
+
displayName: 'Collection ID',
|
|
566
|
+
name: 'collectionId',
|
|
567
|
+
type: 'string',
|
|
568
|
+
default: '',
|
|
569
|
+
description: 'Limit search to a specific collection UUID',
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
displayName: 'Status Filter',
|
|
573
|
+
name: 'statusFilter',
|
|
574
|
+
type: 'options',
|
|
575
|
+
options: [
|
|
576
|
+
{ name: 'Published (default)', value: '' },
|
|
577
|
+
{ name: 'Draft', value: 'draft' },
|
|
578
|
+
{ name: 'Archived', value: 'archived' },
|
|
579
|
+
],
|
|
580
|
+
default: '',
|
|
581
|
+
description: 'Filter results by document status',
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
displayName: 'Date Filter',
|
|
585
|
+
name: 'dateFilter',
|
|
586
|
+
type: 'options',
|
|
587
|
+
options: [
|
|
588
|
+
{ name: 'All Time', value: '' },
|
|
589
|
+
{ name: 'Past Day', value: 'day' },
|
|
590
|
+
{ name: 'Past Week', value: 'week' },
|
|
591
|
+
{ name: 'Past Month', value: 'month' },
|
|
592
|
+
{ name: 'Past Year', value: 'year' },
|
|
593
|
+
],
|
|
594
|
+
default: '',
|
|
595
|
+
description: 'Only return documents updated within this period',
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
displayName: 'Limit',
|
|
599
|
+
name: 'limit',
|
|
600
|
+
type: 'number',
|
|
601
|
+
default: 25,
|
|
602
|
+
description: 'Maximum number of results to return',
|
|
603
|
+
},
|
|
604
|
+
],
|
|
605
|
+
},
|
|
606
|
+
|
|
607
|
+
// Additional Fields for document: import
|
|
608
|
+
{
|
|
609
|
+
displayName: 'Additional Fields',
|
|
610
|
+
name: 'additionalFields',
|
|
611
|
+
type: 'collection',
|
|
612
|
+
placeholder: 'Add Field',
|
|
613
|
+
default: {},
|
|
614
|
+
displayOptions: {
|
|
615
|
+
show: {
|
|
616
|
+
resource: ['document'],
|
|
617
|
+
operation: ['import'],
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
options: [
|
|
621
|
+
{
|
|
622
|
+
displayName: 'Parent Document ID',
|
|
623
|
+
name: 'parentDocumentId',
|
|
624
|
+
type: 'string',
|
|
625
|
+
default: '',
|
|
626
|
+
description: 'UUID of a parent document to import as a child of (required unless Collection ID is set)',
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
displayName: 'Filename Override',
|
|
630
|
+
name: 'filenameOverride',
|
|
631
|
+
type: 'string',
|
|
632
|
+
default: '',
|
|
633
|
+
placeholder: 'notes.md',
|
|
634
|
+
description: 'Override filename (with extension). Uses binary metadata filename if not set.',
|
|
635
|
+
},
|
|
636
|
+
],
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
// Additional Fields for document: move
|
|
640
|
+
{
|
|
641
|
+
displayName: 'Additional Fields',
|
|
642
|
+
name: 'additionalFields',
|
|
643
|
+
type: 'collection',
|
|
644
|
+
placeholder: 'Add Field',
|
|
645
|
+
default: {},
|
|
646
|
+
displayOptions: {
|
|
647
|
+
show: {
|
|
648
|
+
resource: ['document'],
|
|
649
|
+
operation: ['move'],
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
options: [
|
|
653
|
+
{
|
|
654
|
+
displayName: 'Parent Document ID',
|
|
655
|
+
name: 'parentDocumentId',
|
|
656
|
+
type: 'string',
|
|
657
|
+
default: '',
|
|
658
|
+
description: 'UUID of the new parent document (omit to move to collection root)',
|
|
659
|
+
},
|
|
660
|
+
],
|
|
661
|
+
},
|
|
662
|
+
|
|
663
|
+
// Additional Fields for document: restore
|
|
664
|
+
{
|
|
665
|
+
displayName: 'Additional Fields',
|
|
666
|
+
name: 'additionalFields',
|
|
667
|
+
type: 'collection',
|
|
668
|
+
placeholder: 'Add Field',
|
|
669
|
+
default: {},
|
|
670
|
+
displayOptions: {
|
|
671
|
+
show: {
|
|
672
|
+
resource: ['document'],
|
|
673
|
+
operation: ['restore'],
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
options: [
|
|
677
|
+
{
|
|
678
|
+
displayName: 'Target Collection ID',
|
|
679
|
+
name: 'collectionId',
|
|
680
|
+
type: 'string',
|
|
681
|
+
default: '',
|
|
682
|
+
description: 'UUID of the collection to restore the document into',
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
displayName: 'Revision ID',
|
|
686
|
+
name: 'revisionId',
|
|
687
|
+
type: 'string',
|
|
688
|
+
default: '',
|
|
689
|
+
description: 'UUID of a specific revision to restore to (optional)',
|
|
690
|
+
},
|
|
691
|
+
],
|
|
692
|
+
},
|
|
693
|
+
|
|
694
|
+
// Additional Fields for document: export
|
|
695
|
+
{
|
|
696
|
+
displayName: 'Additional Fields',
|
|
697
|
+
name: 'additionalFields',
|
|
698
|
+
type: 'collection',
|
|
699
|
+
placeholder: 'Add Field',
|
|
700
|
+
default: {},
|
|
701
|
+
displayOptions: {
|
|
702
|
+
show: {
|
|
703
|
+
resource: ['document'],
|
|
704
|
+
operation: ['export'],
|
|
705
|
+
},
|
|
706
|
+
},
|
|
707
|
+
options: [
|
|
708
|
+
{
|
|
709
|
+
displayName: 'Output Filename',
|
|
710
|
+
name: 'outputFilename',
|
|
711
|
+
type: 'string',
|
|
712
|
+
default: 'document.md',
|
|
713
|
+
description: 'Filename for the exported Markdown file',
|
|
714
|
+
},
|
|
715
|
+
],
|
|
716
|
+
},
|
|
717
|
+
|
|
718
|
+
// Additional Fields for document: answerQuestion
|
|
719
|
+
{
|
|
720
|
+
displayName: 'Filters',
|
|
721
|
+
name: 'filters',
|
|
722
|
+
type: 'collection',
|
|
723
|
+
placeholder: 'Add Filter',
|
|
724
|
+
default: {},
|
|
725
|
+
displayOptions: {
|
|
726
|
+
show: {
|
|
727
|
+
resource: ['document'],
|
|
728
|
+
operation: ['answerQuestion'],
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
options: [
|
|
732
|
+
{
|
|
733
|
+
displayName: 'Collection ID',
|
|
734
|
+
name: 'collectionId',
|
|
735
|
+
type: 'string',
|
|
736
|
+
default: '',
|
|
737
|
+
description: 'UUID of the collection to search within (optional)',
|
|
738
|
+
},
|
|
739
|
+
],
|
|
740
|
+
},
|
|
741
|
+
|
|
742
|
+
// ════════════════════════════════════════════════════════════════
|
|
743
|
+
// COLLECTION PARAMETERS
|
|
744
|
+
// ════════════════════════════════════════════════════════════════
|
|
745
|
+
|
|
746
|
+
{
|
|
747
|
+
displayName: 'Collection ID',
|
|
748
|
+
name: 'collectionId',
|
|
749
|
+
type: 'string',
|
|
750
|
+
default: '',
|
|
751
|
+
required: true,
|
|
752
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
753
|
+
description: 'Collection UUID',
|
|
754
|
+
displayOptions: {
|
|
755
|
+
show: {
|
|
756
|
+
resource: ['collection'],
|
|
757
|
+
operation: ['get', 'update', 'delete', 'getDocuments', 'export'],
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
displayName: 'Name',
|
|
763
|
+
name: 'name',
|
|
764
|
+
type: 'string',
|
|
765
|
+
default: '',
|
|
766
|
+
required: true,
|
|
767
|
+
placeholder: 'My Collection',
|
|
768
|
+
description: 'Collection name',
|
|
769
|
+
displayOptions: {
|
|
770
|
+
show: {
|
|
771
|
+
resource: ['collection'],
|
|
772
|
+
operation: ['create'],
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
displayName: 'Additional Fields',
|
|
778
|
+
name: 'additionalFields',
|
|
779
|
+
type: 'collection',
|
|
780
|
+
placeholder: 'Add Field',
|
|
781
|
+
default: {},
|
|
782
|
+
displayOptions: {
|
|
783
|
+
show: {
|
|
784
|
+
resource: ['collection'],
|
|
785
|
+
operation: ['create'],
|
|
786
|
+
},
|
|
787
|
+
},
|
|
788
|
+
options: [
|
|
789
|
+
{
|
|
790
|
+
displayName: 'Description',
|
|
791
|
+
name: 'description',
|
|
792
|
+
type: 'string',
|
|
793
|
+
typeOptions: { rows: 3 },
|
|
794
|
+
default: '',
|
|
795
|
+
description: 'A brief description (Markdown supported)',
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
displayName: 'Permission',
|
|
799
|
+
name: 'permission',
|
|
800
|
+
type: 'options',
|
|
801
|
+
options: [
|
|
802
|
+
{ name: 'Read Only', value: 'read' },
|
|
803
|
+
{ name: 'Read & Write', value: 'read_write' },
|
|
804
|
+
],
|
|
805
|
+
default: 'read_write',
|
|
806
|
+
description: 'Default permission for members',
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
displayName: 'Allow Public Sharing',
|
|
810
|
+
name: 'sharing',
|
|
811
|
+
type: 'boolean',
|
|
812
|
+
default: false,
|
|
813
|
+
description: 'Whether public sharing of documents is allowed',
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
displayName: 'Color',
|
|
817
|
+
name: 'color',
|
|
818
|
+
type: 'color',
|
|
819
|
+
default: '',
|
|
820
|
+
description: 'Hex color code for the collection icon (e.g., #FF5733)',
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
displayName: 'Icon',
|
|
824
|
+
name: 'icon',
|
|
825
|
+
type: 'string',
|
|
826
|
+
default: '',
|
|
827
|
+
description: 'Icon name from outline-icons or an emoji character',
|
|
828
|
+
},
|
|
829
|
+
],
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
displayName: 'Update Fields',
|
|
833
|
+
name: 'updateFields',
|
|
834
|
+
type: 'collection',
|
|
835
|
+
placeholder: 'Add Field',
|
|
836
|
+
default: {},
|
|
837
|
+
displayOptions: {
|
|
838
|
+
show: {
|
|
839
|
+
resource: ['collection'],
|
|
840
|
+
operation: ['update'],
|
|
841
|
+
},
|
|
842
|
+
},
|
|
843
|
+
options: [
|
|
844
|
+
{
|
|
845
|
+
displayName: 'Name',
|
|
846
|
+
name: 'name',
|
|
847
|
+
type: 'string',
|
|
848
|
+
default: '',
|
|
849
|
+
description: 'New collection name',
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
displayName: 'Description',
|
|
853
|
+
name: 'description',
|
|
854
|
+
type: 'string',
|
|
855
|
+
typeOptions: { rows: 3 },
|
|
856
|
+
default: '',
|
|
857
|
+
description: 'New description (Markdown supported)',
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
displayName: 'Permission',
|
|
861
|
+
name: 'permission',
|
|
862
|
+
type: 'options',
|
|
863
|
+
options: [
|
|
864
|
+
{ name: 'Read Only', value: 'read' },
|
|
865
|
+
{ name: 'Read & Write', value: 'read_write' },
|
|
866
|
+
],
|
|
867
|
+
default: 'read_write',
|
|
868
|
+
description: 'Default permission for members',
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
displayName: 'Allow Public Sharing',
|
|
872
|
+
name: 'sharing',
|
|
873
|
+
type: 'boolean',
|
|
874
|
+
default: false,
|
|
875
|
+
description: 'Whether public sharing of documents is allowed',
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
displayName: 'Color',
|
|
879
|
+
name: 'color',
|
|
880
|
+
type: 'color',
|
|
881
|
+
default: '',
|
|
882
|
+
description: 'Hex color code for the collection icon',
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
displayName: 'Icon',
|
|
886
|
+
name: 'icon',
|
|
887
|
+
type: 'string',
|
|
888
|
+
default: '',
|
|
889
|
+
description: 'Icon name or emoji',
|
|
890
|
+
},
|
|
891
|
+
],
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
displayName: 'Filters',
|
|
895
|
+
name: 'filters',
|
|
896
|
+
type: 'collection',
|
|
897
|
+
placeholder: 'Add Filter',
|
|
898
|
+
default: {},
|
|
899
|
+
displayOptions: {
|
|
900
|
+
show: {
|
|
901
|
+
resource: ['collection'],
|
|
902
|
+
operation: ['list'],
|
|
903
|
+
},
|
|
904
|
+
},
|
|
905
|
+
options: [
|
|
906
|
+
{
|
|
907
|
+
displayName: 'Limit',
|
|
908
|
+
name: 'limit',
|
|
909
|
+
type: 'number',
|
|
910
|
+
default: 25,
|
|
911
|
+
description: 'Maximum number of results to return',
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
displayName: 'Offset',
|
|
915
|
+
name: 'offset',
|
|
916
|
+
type: 'number',
|
|
917
|
+
default: 0,
|
|
918
|
+
description: 'Offset for pagination',
|
|
919
|
+
},
|
|
920
|
+
],
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
displayName: 'Export Format',
|
|
924
|
+
name: 'exportFormat',
|
|
925
|
+
type: 'options',
|
|
926
|
+
options: [
|
|
927
|
+
{ name: 'Outline Markdown', value: 'outline-markdown' },
|
|
928
|
+
{ name: 'JSON', value: 'json' },
|
|
929
|
+
{ name: 'HTML', value: 'html' },
|
|
930
|
+
],
|
|
931
|
+
default: 'outline-markdown',
|
|
932
|
+
description: 'Format for the collection export',
|
|
933
|
+
displayOptions: {
|
|
934
|
+
show: {
|
|
935
|
+
resource: ['collection'],
|
|
936
|
+
operation: ['export'],
|
|
937
|
+
},
|
|
938
|
+
},
|
|
939
|
+
},
|
|
940
|
+
|
|
941
|
+
// ════════════════════════════════════════════════════════════════
|
|
942
|
+
// COMMENT PARAMETERS
|
|
943
|
+
// ════════════════════════════════════════════════════════════════
|
|
944
|
+
|
|
945
|
+
{
|
|
946
|
+
displayName: 'Document ID',
|
|
947
|
+
name: 'documentId',
|
|
948
|
+
type: 'string',
|
|
949
|
+
default: '',
|
|
950
|
+
required: true,
|
|
951
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
952
|
+
description: 'UUID of the document to comment on',
|
|
953
|
+
displayOptions: {
|
|
954
|
+
show: {
|
|
955
|
+
resource: ['comment'],
|
|
956
|
+
operation: ['create'],
|
|
957
|
+
},
|
|
958
|
+
},
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
displayName: 'Comment ID',
|
|
962
|
+
name: 'commentId',
|
|
963
|
+
type: 'string',
|
|
964
|
+
default: '',
|
|
965
|
+
required: true,
|
|
966
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
967
|
+
description: 'Comment UUID',
|
|
968
|
+
displayOptions: {
|
|
969
|
+
show: {
|
|
970
|
+
resource: ['comment'],
|
|
971
|
+
operation: ['update', 'delete'],
|
|
972
|
+
},
|
|
973
|
+
},
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
displayName: 'Text',
|
|
977
|
+
name: 'text',
|
|
978
|
+
type: 'string',
|
|
979
|
+
typeOptions: { rows: 4 },
|
|
980
|
+
default: '',
|
|
981
|
+
required: true,
|
|
982
|
+
description: 'Comment body in Markdown format',
|
|
983
|
+
displayOptions: {
|
|
984
|
+
show: {
|
|
985
|
+
resource: ['comment'],
|
|
986
|
+
operation: ['create', 'update'],
|
|
987
|
+
},
|
|
988
|
+
},
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
displayName: 'Filters',
|
|
992
|
+
name: 'filters',
|
|
993
|
+
type: 'collection',
|
|
994
|
+
placeholder: 'Add Filter',
|
|
995
|
+
default: {},
|
|
996
|
+
displayOptions: {
|
|
997
|
+
show: {
|
|
998
|
+
resource: ['comment'],
|
|
999
|
+
operation: ['list'],
|
|
1000
|
+
},
|
|
1001
|
+
},
|
|
1002
|
+
options: [
|
|
1003
|
+
{
|
|
1004
|
+
displayName: 'Document ID',
|
|
1005
|
+
name: 'documentId',
|
|
1006
|
+
type: 'string',
|
|
1007
|
+
default: '',
|
|
1008
|
+
description: 'UUID of the document to list comments for',
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
displayName: 'Collection ID',
|
|
1012
|
+
name: 'collectionId',
|
|
1013
|
+
type: 'string',
|
|
1014
|
+
default: '',
|
|
1015
|
+
description: 'UUID of the collection to list all comments within',
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
displayName: 'Limit',
|
|
1019
|
+
name: 'limit',
|
|
1020
|
+
type: 'number',
|
|
1021
|
+
default: 25,
|
|
1022
|
+
description: 'Maximum number of results to return',
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
displayName: 'Offset',
|
|
1026
|
+
name: 'offset',
|
|
1027
|
+
type: 'number',
|
|
1028
|
+
default: 0,
|
|
1029
|
+
description: 'Offset for pagination',
|
|
1030
|
+
},
|
|
1031
|
+
],
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
displayName: 'Additional Fields',
|
|
1035
|
+
name: 'additionalFields',
|
|
1036
|
+
type: 'collection',
|
|
1037
|
+
placeholder: 'Add Field',
|
|
1038
|
+
default: {},
|
|
1039
|
+
displayOptions: {
|
|
1040
|
+
show: {
|
|
1041
|
+
resource: ['comment'],
|
|
1042
|
+
operation: ['create'],
|
|
1043
|
+
},
|
|
1044
|
+
},
|
|
1045
|
+
options: [
|
|
1046
|
+
{
|
|
1047
|
+
displayName: 'Parent Comment ID',
|
|
1048
|
+
name: 'parentCommentId',
|
|
1049
|
+
type: 'string',
|
|
1050
|
+
default: '',
|
|
1051
|
+
description: 'UUID of the parent comment to reply to (for threaded replies)',
|
|
1052
|
+
},
|
|
1053
|
+
],
|
|
1054
|
+
},
|
|
1055
|
+
|
|
1056
|
+
// ════════════════════════════════════════════════════════════════
|
|
1057
|
+
// ATTACHMENT PARAMETERS
|
|
1058
|
+
// ════════════════════════════════════════════════════════════════
|
|
1059
|
+
|
|
1060
|
+
{
|
|
1061
|
+
displayName: 'Binary Property',
|
|
1062
|
+
name: 'binaryPropertyName',
|
|
1063
|
+
type: 'string',
|
|
1064
|
+
default: 'data',
|
|
1065
|
+
required: true,
|
|
1066
|
+
description: 'Name of the binary property containing the file to upload',
|
|
1067
|
+
displayOptions: {
|
|
1068
|
+
show: {
|
|
1069
|
+
resource: ['attachment'],
|
|
1070
|
+
operation: ['upload'],
|
|
1071
|
+
},
|
|
1072
|
+
},
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
displayName: 'Attachment ID',
|
|
1076
|
+
name: 'attachmentId',
|
|
1077
|
+
type: 'string',
|
|
1078
|
+
default: '',
|
|
1079
|
+
required: true,
|
|
1080
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
1081
|
+
description: 'Attachment UUID to delete',
|
|
1082
|
+
displayOptions: {
|
|
1083
|
+
show: {
|
|
1084
|
+
resource: ['attachment'],
|
|
1085
|
+
operation: ['delete'],
|
|
1086
|
+
},
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
displayName: 'Additional Fields',
|
|
1091
|
+
name: 'additionalFields',
|
|
1092
|
+
type: 'collection',
|
|
1093
|
+
placeholder: 'Add Field',
|
|
1094
|
+
default: {},
|
|
1095
|
+
displayOptions: {
|
|
1096
|
+
show: {
|
|
1097
|
+
resource: ['attachment'],
|
|
1098
|
+
operation: ['upload'],
|
|
1099
|
+
},
|
|
1100
|
+
},
|
|
1101
|
+
options: [
|
|
1102
|
+
{
|
|
1103
|
+
displayName: 'Document ID',
|
|
1104
|
+
name: 'documentId',
|
|
1105
|
+
type: 'string',
|
|
1106
|
+
default: '',
|
|
1107
|
+
description: 'UUID of the document to associate this attachment with (optional)',
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
displayName: 'Filename Override',
|
|
1111
|
+
name: 'filenameOverride',
|
|
1112
|
+
type: 'string',
|
|
1113
|
+
default: '',
|
|
1114
|
+
placeholder: 'photo.png',
|
|
1115
|
+
description: 'Override filename (with extension). Uses binary metadata filename if not set.',
|
|
1116
|
+
},
|
|
1117
|
+
],
|
|
1118
|
+
},
|
|
1119
|
+
|
|
1120
|
+
// ════════════════════════════════════════════════════════════════
|
|
1121
|
+
// USER PARAMETERS
|
|
1122
|
+
// ════════════════════════════════════════════════════════════════
|
|
1123
|
+
|
|
1124
|
+
{
|
|
1125
|
+
displayName: 'User ID',
|
|
1126
|
+
name: 'userId',
|
|
1127
|
+
type: 'string',
|
|
1128
|
+
default: '',
|
|
1129
|
+
required: true,
|
|
1130
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
1131
|
+
description: 'User UUID',
|
|
1132
|
+
displayOptions: {
|
|
1133
|
+
show: {
|
|
1134
|
+
resource: ['user'],
|
|
1135
|
+
operation: ['get'],
|
|
1136
|
+
},
|
|
1137
|
+
},
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
displayName: 'Filters',
|
|
1141
|
+
name: 'filters',
|
|
1142
|
+
type: 'collection',
|
|
1143
|
+
placeholder: 'Add Filter',
|
|
1144
|
+
default: {},
|
|
1145
|
+
displayOptions: {
|
|
1146
|
+
show: {
|
|
1147
|
+
resource: ['user'],
|
|
1148
|
+
operation: ['list'],
|
|
1149
|
+
},
|
|
1150
|
+
},
|
|
1151
|
+
options: [
|
|
1152
|
+
{
|
|
1153
|
+
displayName: 'Query',
|
|
1154
|
+
name: 'query',
|
|
1155
|
+
type: 'string',
|
|
1156
|
+
default: '',
|
|
1157
|
+
description: 'Filter users by name or email',
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
displayName: 'Limit',
|
|
1161
|
+
name: 'limit',
|
|
1162
|
+
type: 'number',
|
|
1163
|
+
default: 25,
|
|
1164
|
+
description: 'Maximum number of results to return',
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
displayName: 'Offset',
|
|
1168
|
+
name: 'offset',
|
|
1169
|
+
type: 'number',
|
|
1170
|
+
default: 0,
|
|
1171
|
+
description: 'Offset for pagination',
|
|
1172
|
+
},
|
|
1173
|
+
],
|
|
1174
|
+
},
|
|
1175
|
+
|
|
1176
|
+
// ════════════════════════════════════════════════════════════════
|
|
1177
|
+
// SHARE PARAMETERS
|
|
1178
|
+
// ════════════════════════════════════════════════════════════════
|
|
1179
|
+
|
|
1180
|
+
{
|
|
1181
|
+
displayName: 'Document ID',
|
|
1182
|
+
name: 'documentId',
|
|
1183
|
+
type: 'string',
|
|
1184
|
+
default: '',
|
|
1185
|
+
required: true,
|
|
1186
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
1187
|
+
description: 'UUID of the document to share',
|
|
1188
|
+
displayOptions: {
|
|
1189
|
+
show: {
|
|
1190
|
+
resource: ['share'],
|
|
1191
|
+
operation: ['create'],
|
|
1192
|
+
},
|
|
1193
|
+
},
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
displayName: 'Share ID',
|
|
1197
|
+
name: 'shareId',
|
|
1198
|
+
type: 'string',
|
|
1199
|
+
default: '',
|
|
1200
|
+
required: true,
|
|
1201
|
+
placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
1202
|
+
description: 'Share UUID to revoke',
|
|
1203
|
+
displayOptions: {
|
|
1204
|
+
show: {
|
|
1205
|
+
resource: ['share'],
|
|
1206
|
+
operation: ['revoke'],
|
|
1207
|
+
},
|
|
1208
|
+
},
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
displayName: 'Additional Fields',
|
|
1212
|
+
name: 'additionalFields',
|
|
1213
|
+
type: 'collection',
|
|
1214
|
+
placeholder: 'Add Field',
|
|
1215
|
+
default: {},
|
|
1216
|
+
displayOptions: {
|
|
1217
|
+
show: {
|
|
1218
|
+
resource: ['share'],
|
|
1219
|
+
operation: ['create'],
|
|
1220
|
+
},
|
|
1221
|
+
},
|
|
1222
|
+
options: [
|
|
1223
|
+
{
|
|
1224
|
+
displayName: 'Include Child Documents',
|
|
1225
|
+
name: 'includeChildDocuments',
|
|
1226
|
+
type: 'boolean',
|
|
1227
|
+
default: false,
|
|
1228
|
+
description: 'Whether to include child documents in the share',
|
|
1229
|
+
},
|
|
1230
|
+
],
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
displayName: 'Filters',
|
|
1234
|
+
name: 'filters',
|
|
1235
|
+
type: 'collection',
|
|
1236
|
+
placeholder: 'Add Filter',
|
|
1237
|
+
default: {},
|
|
1238
|
+
displayOptions: {
|
|
1239
|
+
show: {
|
|
1240
|
+
resource: ['share'],
|
|
1241
|
+
operation: ['list'],
|
|
1242
|
+
},
|
|
1243
|
+
},
|
|
1244
|
+
options: [
|
|
1245
|
+
{
|
|
1246
|
+
displayName: 'Limit',
|
|
1247
|
+
name: 'limit',
|
|
1248
|
+
type: 'number',
|
|
1249
|
+
default: 25,
|
|
1250
|
+
description: 'Maximum number of results to return',
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
displayName: 'Offset',
|
|
1254
|
+
name: 'offset',
|
|
1255
|
+
type: 'number',
|
|
1256
|
+
default: 0,
|
|
1257
|
+
description: 'Offset for pagination',
|
|
1258
|
+
},
|
|
1259
|
+
],
|
|
1260
|
+
},
|
|
1261
|
+
],
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
async execute() {
|
|
1266
|
+
const items = this.getInputData();
|
|
1267
|
+
const returnData = [];
|
|
1268
|
+
|
|
1269
|
+
for (let i = 0; i < items.length; i++) {
|
|
1270
|
+
try {
|
|
1271
|
+
const resource = this.getNodeParameter('resource', i);
|
|
1272
|
+
const operation = this.getNodeParameter('operation', i);
|
|
1273
|
+
let responseData;
|
|
1274
|
+
|
|
1275
|
+
// ════════════════════════════════════════════════════════════════
|
|
1276
|
+
// DOCUMENT
|
|
1277
|
+
// ════════════════════════════════════════════════════════════════
|
|
1278
|
+
if (resource === 'document') {
|
|
1279
|
+
|
|
1280
|
+
if (operation === 'get') {
|
|
1281
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1282
|
+
responseData = await outlineApiRequest(this, '/documents.info', { id });
|
|
1283
|
+
|
|
1284
|
+
} else if (operation === 'create') {
|
|
1285
|
+
const title = this.getNodeParameter('title', i);
|
|
1286
|
+
const text = this.getNodeParameter('text', i, '');
|
|
1287
|
+
const collectionId = this.getNodeParameter('collectionId', i, '');
|
|
1288
|
+
const publish = this.getNodeParameter('publish', i, false);
|
|
1289
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1290
|
+
const body = { title };
|
|
1291
|
+
if (text) body.text = text;
|
|
1292
|
+
if (collectionId) body.collectionId = collectionId;
|
|
1293
|
+
if (af.parentDocumentId) body.parentDocumentId = af.parentDocumentId;
|
|
1294
|
+
if (af.templateId) body.templateId = af.templateId;
|
|
1295
|
+
body.publish = publish;
|
|
1296
|
+
if (!collectionId && !af.parentDocumentId) {
|
|
1297
|
+
throw new Error('Either Collection ID or Parent Document ID is required');
|
|
1298
|
+
}
|
|
1299
|
+
responseData = await outlineApiRequest(this, '/documents.create', body);
|
|
1300
|
+
|
|
1301
|
+
} else if (operation === 'update') {
|
|
1302
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1303
|
+
const uf = this.getNodeParameter('updateFields', i, {});
|
|
1304
|
+
const body = { id };
|
|
1305
|
+
if (uf.title !== undefined && uf.title !== '') body.title = uf.title;
|
|
1306
|
+
if (uf.text !== undefined && uf.text !== '') body.text = uf.text;
|
|
1307
|
+
if (uf.publish !== undefined) body.publish = uf.publish;
|
|
1308
|
+
if (uf.fullWidth !== undefined) body.fullWidth = uf.fullWidth;
|
|
1309
|
+
responseData = await outlineApiRequest(this, '/documents.update', body);
|
|
1310
|
+
|
|
1311
|
+
} else if (operation === 'delete') {
|
|
1312
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1313
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1314
|
+
const body = { id };
|
|
1315
|
+
if (af.permanent !== undefined) body.permanent = af.permanent;
|
|
1316
|
+
responseData = await outlineApiRequest(this, '/documents.delete', body);
|
|
1317
|
+
|
|
1318
|
+
} else if (operation === 'list') {
|
|
1319
|
+
const collectionId = this.getNodeParameter('collectionId', i, '');
|
|
1320
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1321
|
+
const body = {};
|
|
1322
|
+
if (collectionId) body.collectionId = collectionId;
|
|
1323
|
+
if (filters.parentDocumentId) body.parentDocumentId = filters.parentDocumentId;
|
|
1324
|
+
if (filters.statusFilter) body.statusFilter = [filters.statusFilter];
|
|
1325
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1326
|
+
if (filters.offset) body.offset = filters.offset;
|
|
1327
|
+
responseData = await outlineApiRequest(this, '/documents.list', body);
|
|
1328
|
+
|
|
1329
|
+
} else if (operation === 'search') {
|
|
1330
|
+
const query = this.getNodeParameter('query', i);
|
|
1331
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1332
|
+
const body = { query };
|
|
1333
|
+
if (filters.collectionId) body.collectionId = filters.collectionId;
|
|
1334
|
+
if (filters.statusFilter) body.statusFilter = [filters.statusFilter];
|
|
1335
|
+
if (filters.dateFilter) body.dateFilter = filters.dateFilter;
|
|
1336
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1337
|
+
responseData = await outlineApiRequest(this, '/documents.search', body);
|
|
1338
|
+
|
|
1339
|
+
} else if (operation === 'searchTitles') {
|
|
1340
|
+
const query = this.getNodeParameter('query', i);
|
|
1341
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1342
|
+
const body = { query };
|
|
1343
|
+
if (filters.collectionId) body.collectionId = filters.collectionId;
|
|
1344
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1345
|
+
responseData = await outlineApiRequest(this, '/documents.search_titles', body);
|
|
1346
|
+
|
|
1347
|
+
} else if (operation === 'archive') {
|
|
1348
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1349
|
+
responseData = await outlineApiRequest(this, '/documents.archive', { id });
|
|
1350
|
+
|
|
1351
|
+
} else if (operation === 'restore') {
|
|
1352
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1353
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1354
|
+
const body = { id };
|
|
1355
|
+
if (af.collectionId) body.collectionId = af.collectionId;
|
|
1356
|
+
if (af.revisionId) body.revisionId = af.revisionId;
|
|
1357
|
+
responseData = await outlineApiRequest(this, '/documents.restore', body);
|
|
1358
|
+
|
|
1359
|
+
} else if (operation === 'move') {
|
|
1360
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1361
|
+
const collectionId = this.getNodeParameter('collectionId', i, '');
|
|
1362
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1363
|
+
const body = { id };
|
|
1364
|
+
if (collectionId) body.collectionId = collectionId;
|
|
1365
|
+
if (af.parentDocumentId) body.parentDocumentId = af.parentDocumentId;
|
|
1366
|
+
responseData = await outlineApiRequest(this, '/documents.move', body);
|
|
1367
|
+
|
|
1368
|
+
} else if (operation === 'answerQuestion') {
|
|
1369
|
+
const query = this.getNodeParameter('query', i);
|
|
1370
|
+
const documentId = this.getNodeParameter('documentId', i, '');
|
|
1371
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1372
|
+
const body = { query };
|
|
1373
|
+
if (documentId) body.documentId = documentId;
|
|
1374
|
+
if (filters.collectionId) body.collectionId = filters.collectionId;
|
|
1375
|
+
responseData = await outlineApiRequest(this, '/documents.answerQuestion', body);
|
|
1376
|
+
|
|
1377
|
+
} else if (operation === 'export') {
|
|
1378
|
+
const id = this.getNodeParameter('documentId', i);
|
|
1379
|
+
const outputBinaryProp = this.getNodeParameter('outputBinaryPropertyName', i, 'data');
|
|
1380
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1381
|
+
const outputFilename = (af.outputFilename) || 'document.md';
|
|
1382
|
+
const res = await outlineApiRequest(this, '/documents.export', { id });
|
|
1383
|
+
const markdown = (res && res.data) ? res.data : JSON.stringify(res);
|
|
1384
|
+
const buffer = Buffer.from(typeof markdown === 'string' ? markdown : JSON.stringify(markdown), 'utf-8');
|
|
1385
|
+
const binaryOutput = await this.helpers.prepareBinaryData(buffer, outputFilename, 'text/markdown');
|
|
1386
|
+
returnData.push({
|
|
1387
|
+
json: { id, filename: outputFilename, mimeType: 'text/markdown', sizeBytes: buffer.length },
|
|
1388
|
+
binary: { [outputBinaryProp]: binaryOutput },
|
|
1389
|
+
pairedItem: { item: i },
|
|
1390
|
+
});
|
|
1391
|
+
continue;
|
|
1392
|
+
|
|
1393
|
+
} else if (operation === 'import') {
|
|
1394
|
+
const binaryProp = this.getNodeParameter('binaryPropertyName', i, 'data');
|
|
1395
|
+
const collectionId = this.getNodeParameter('collectionId', i, '');
|
|
1396
|
+
const publish = this.getNodeParameter('publish', i, false);
|
|
1397
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1398
|
+
|
|
1399
|
+
if (!collectionId && !af.parentDocumentId) {
|
|
1400
|
+
throw new Error('Either Collection ID or Parent Document ID is required for import');
|
|
1401
|
+
}
|
|
1402
|
+
const binaryData = items[i].binary;
|
|
1403
|
+
if (!binaryData || !binaryData[binaryProp]) {
|
|
1404
|
+
throw new Error(`No binary data found in property "${binaryProp}"`);
|
|
1405
|
+
}
|
|
1406
|
+
const buffer = await this.helpers.getBinaryDataBuffer(i, binaryProp);
|
|
1407
|
+
const resolvedFilename = af.filenameOverride || binaryData[binaryProp].fileName || 'document.md';
|
|
1408
|
+
const contentType = binaryData[binaryProp].mimeType || guessMimeType(resolvedFilename);
|
|
1409
|
+
|
|
1410
|
+
const formData = {
|
|
1411
|
+
file: {
|
|
1412
|
+
value: buffer,
|
|
1413
|
+
options: { filename: resolvedFilename, contentType },
|
|
1414
|
+
},
|
|
1415
|
+
};
|
|
1416
|
+
if (collectionId) formData.collectionId = collectionId;
|
|
1417
|
+
if (af.parentDocumentId) formData.parentDocumentId = af.parentDocumentId;
|
|
1418
|
+
formData.publish = String(publish);
|
|
1419
|
+
responseData = await outlineApiRequestMultipart(this, '/documents.import', formData);
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
// ════════════════════════════════════════════════════════════════
|
|
1423
|
+
// COLLECTION
|
|
1424
|
+
// ════════════════════════════════════════════════════════════════
|
|
1425
|
+
} else if (resource === 'collection') {
|
|
1426
|
+
|
|
1427
|
+
if (operation === 'list') {
|
|
1428
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1429
|
+
const body = {};
|
|
1430
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1431
|
+
if (filters.offset) body.offset = filters.offset;
|
|
1432
|
+
responseData = await outlineApiRequest(this, '/collections.list', body);
|
|
1433
|
+
|
|
1434
|
+
} else if (operation === 'get') {
|
|
1435
|
+
const id = this.getNodeParameter('collectionId', i);
|
|
1436
|
+
responseData = await outlineApiRequest(this, '/collections.info', { id });
|
|
1437
|
+
|
|
1438
|
+
} else if (operation === 'create') {
|
|
1439
|
+
const name = this.getNodeParameter('name', i);
|
|
1440
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1441
|
+
const body = { name };
|
|
1442
|
+
if (af.description) body.description = af.description;
|
|
1443
|
+
if (af.permission) body.permission = af.permission;
|
|
1444
|
+
if (af.sharing !== undefined) body.sharing = af.sharing;
|
|
1445
|
+
if (af.color) body.color = af.color;
|
|
1446
|
+
if (af.icon) body.icon = af.icon;
|
|
1447
|
+
responseData = await outlineApiRequest(this, '/collections.create', body);
|
|
1448
|
+
|
|
1449
|
+
} else if (operation === 'update') {
|
|
1450
|
+
const id = this.getNodeParameter('collectionId', i);
|
|
1451
|
+
const uf = this.getNodeParameter('updateFields', i, {});
|
|
1452
|
+
const body = { id };
|
|
1453
|
+
if (uf.name) body.name = uf.name;
|
|
1454
|
+
if (uf.description !== undefined) body.description = uf.description;
|
|
1455
|
+
if (uf.permission) body.permission = uf.permission;
|
|
1456
|
+
if (uf.sharing !== undefined) body.sharing = uf.sharing;
|
|
1457
|
+
if (uf.color) body.color = uf.color;
|
|
1458
|
+
if (uf.icon) body.icon = uf.icon;
|
|
1459
|
+
responseData = await outlineApiRequest(this, '/collections.update', body);
|
|
1460
|
+
|
|
1461
|
+
} else if (operation === 'delete') {
|
|
1462
|
+
const id = this.getNodeParameter('collectionId', i);
|
|
1463
|
+
responseData = await outlineApiRequest(this, '/collections.delete', { id });
|
|
1464
|
+
|
|
1465
|
+
} else if (operation === 'getDocuments') {
|
|
1466
|
+
const id = this.getNodeParameter('collectionId', i);
|
|
1467
|
+
responseData = await outlineApiRequest(this, '/collections.documents', { id });
|
|
1468
|
+
|
|
1469
|
+
} else if (operation === 'export') {
|
|
1470
|
+
const id = this.getNodeParameter('collectionId', i);
|
|
1471
|
+
const format = this.getNodeParameter('exportFormat', i, 'outline-markdown');
|
|
1472
|
+
responseData = await outlineApiRequest(this, '/collections.export', { id, format });
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
// ════════════════════════════════════════════════════════════════
|
|
1476
|
+
// COMMENT
|
|
1477
|
+
// ════════════════════════════════════════════════════════════════
|
|
1478
|
+
} else if (resource === 'comment') {
|
|
1479
|
+
|
|
1480
|
+
if (operation === 'list') {
|
|
1481
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1482
|
+
const body = {};
|
|
1483
|
+
if (filters.documentId) body.documentId = filters.documentId;
|
|
1484
|
+
if (filters.collectionId) body.collectionId = filters.collectionId;
|
|
1485
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1486
|
+
if (filters.offset) body.offset = filters.offset;
|
|
1487
|
+
responseData = await outlineApiRequest(this, '/comments.list', body);
|
|
1488
|
+
|
|
1489
|
+
} else if (operation === 'create') {
|
|
1490
|
+
const documentId = this.getNodeParameter('documentId', i);
|
|
1491
|
+
const text = this.getNodeParameter('text', i);
|
|
1492
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1493
|
+
const body = { documentId, text };
|
|
1494
|
+
if (af.parentCommentId) body.parentCommentId = af.parentCommentId;
|
|
1495
|
+
responseData = await outlineApiRequest(this, '/comments.create', body);
|
|
1496
|
+
|
|
1497
|
+
} else if (operation === 'update') {
|
|
1498
|
+
const id = this.getNodeParameter('commentId', i);
|
|
1499
|
+
const text = this.getNodeParameter('text', i);
|
|
1500
|
+
// Outline API uses a nested data object for comment updates
|
|
1501
|
+
responseData = await outlineApiRequest(this, '/comments.update', { id, data: { text } });
|
|
1502
|
+
|
|
1503
|
+
} else if (operation === 'delete') {
|
|
1504
|
+
const id = this.getNodeParameter('commentId', i);
|
|
1505
|
+
responseData = await outlineApiRequest(this, '/comments.delete', { id });
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
// ════════════════════════════════════════════════════════════════
|
|
1509
|
+
// ATTACHMENT
|
|
1510
|
+
// ════════════════════════════════════════════════════════════════
|
|
1511
|
+
} else if (resource === 'attachment') {
|
|
1512
|
+
|
|
1513
|
+
if (operation === 'upload') {
|
|
1514
|
+
const binaryProp = this.getNodeParameter('binaryPropertyName', i, 'data');
|
|
1515
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1516
|
+
|
|
1517
|
+
const binaryData = items[i].binary;
|
|
1518
|
+
if (!binaryData || !binaryData[binaryProp]) {
|
|
1519
|
+
throw new Error(`No binary data found in property "${binaryProp}"`);
|
|
1520
|
+
}
|
|
1521
|
+
const buffer = await this.helpers.getBinaryDataBuffer(i, binaryProp);
|
|
1522
|
+
const resolvedFilename = af.filenameOverride || binaryData[binaryProp].fileName || 'file';
|
|
1523
|
+
const contentType = binaryData[binaryProp].mimeType || guessMimeType(resolvedFilename);
|
|
1524
|
+
const sizeBytes = buffer.length;
|
|
1525
|
+
|
|
1526
|
+
// Step 1: Create attachment record and get signed upload URL
|
|
1527
|
+
const createBody = {
|
|
1528
|
+
name: resolvedFilename,
|
|
1529
|
+
contentType,
|
|
1530
|
+
size: sizeBytes,
|
|
1531
|
+
};
|
|
1532
|
+
if (af.documentId) createBody.documentId = af.documentId;
|
|
1533
|
+
|
|
1534
|
+
const createRes = await outlineApiRequest(this, '/attachments.create', createBody);
|
|
1535
|
+
if (!createRes || !createRes.data) {
|
|
1536
|
+
throw new Error('Failed to create attachment record: ' + JSON.stringify(createRes));
|
|
1537
|
+
}
|
|
1538
|
+
const { uploadUrl, form, attachment } = createRes.data;
|
|
1539
|
+
|
|
1540
|
+
// Step 2: Upload the file to the signed URL (S3/GCS signed POST)
|
|
1541
|
+
const uploadFormData = {};
|
|
1542
|
+
if (form && typeof form === 'object') {
|
|
1543
|
+
Object.assign(uploadFormData, form);
|
|
1544
|
+
}
|
|
1545
|
+
uploadFormData.file = {
|
|
1546
|
+
value: buffer,
|
|
1547
|
+
options: { filename: resolvedFilename, contentType },
|
|
1548
|
+
};
|
|
1549
|
+
await this.helpers.request({
|
|
1550
|
+
method: 'POST',
|
|
1551
|
+
url: uploadUrl,
|
|
1552
|
+
formData: uploadFormData,
|
|
1553
|
+
json: false,
|
|
1554
|
+
});
|
|
1555
|
+
|
|
1556
|
+
responseData = {
|
|
1557
|
+
ok: true,
|
|
1558
|
+
data: {
|
|
1559
|
+
id: attachment && attachment.id,
|
|
1560
|
+
url: attachment && attachment.url,
|
|
1561
|
+
name: resolvedFilename,
|
|
1562
|
+
contentType,
|
|
1563
|
+
size: sizeBytes,
|
|
1564
|
+
},
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1567
|
+
} else if (operation === 'delete') {
|
|
1568
|
+
const id = this.getNodeParameter('attachmentId', i);
|
|
1569
|
+
responseData = await outlineApiRequest(this, '/attachments.delete', { id });
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
// ════════════════════════════════════════════════════════════════
|
|
1573
|
+
// USER
|
|
1574
|
+
// ════════════════════════════════════════════════════════════════
|
|
1575
|
+
} else if (resource === 'user') {
|
|
1576
|
+
|
|
1577
|
+
if (operation === 'list') {
|
|
1578
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1579
|
+
const body = {};
|
|
1580
|
+
if (filters.query) body.query = filters.query;
|
|
1581
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1582
|
+
if (filters.offset) body.offset = filters.offset;
|
|
1583
|
+
responseData = await outlineApiRequest(this, '/users.list', body);
|
|
1584
|
+
|
|
1585
|
+
} else if (operation === 'get') {
|
|
1586
|
+
const id = this.getNodeParameter('userId', i);
|
|
1587
|
+
responseData = await outlineApiRequest(this, '/users.info', { id });
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
// ════════════════════════════════════════════════════════════════
|
|
1591
|
+
// SHARE
|
|
1592
|
+
// ════════════════════════════════════════════════════════════════
|
|
1593
|
+
} else if (resource === 'share') {
|
|
1594
|
+
|
|
1595
|
+
if (operation === 'list') {
|
|
1596
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1597
|
+
const body = {};
|
|
1598
|
+
if (filters.limit) body.limit = filters.limit;
|
|
1599
|
+
if (filters.offset) body.offset = filters.offset;
|
|
1600
|
+
responseData = await outlineApiRequest(this, '/shares.list', body);
|
|
1601
|
+
|
|
1602
|
+
} else if (operation === 'create') {
|
|
1603
|
+
const documentId = this.getNodeParameter('documentId', i);
|
|
1604
|
+
const af = this.getNodeParameter('additionalFields', i, {});
|
|
1605
|
+
const body = { documentId };
|
|
1606
|
+
if (af.includeChildDocuments !== undefined) body.includeChildDocuments = af.includeChildDocuments;
|
|
1607
|
+
responseData = await outlineApiRequest(this, '/shares.create', body);
|
|
1608
|
+
|
|
1609
|
+
} else if (operation === 'revoke') {
|
|
1610
|
+
const id = this.getNodeParameter('shareId', i);
|
|
1611
|
+
responseData = await outlineApiRequest(this, '/shares.revoke', { id });
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
// Push JSON result
|
|
1616
|
+
if (responseData !== undefined) {
|
|
1617
|
+
const json = (responseData && typeof responseData === 'object')
|
|
1618
|
+
? responseData
|
|
1619
|
+
: { result: responseData };
|
|
1620
|
+
returnData.push({
|
|
1621
|
+
json,
|
|
1622
|
+
pairedItem: { item: i },
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
} catch (error) {
|
|
1627
|
+
if (this.continueOnFail()) {
|
|
1628
|
+
returnData.push({
|
|
1629
|
+
json: { error: error.message },
|
|
1630
|
+
pairedItem: { item: i },
|
|
1631
|
+
});
|
|
1632
|
+
continue;
|
|
1633
|
+
}
|
|
1634
|
+
throw error;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
return [returnData];
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
exports.Outline = Outline;
|