@hesed/conni 0.2.1 → 0.4.0

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 CHANGED
@@ -26,7 +26,7 @@ $ npm install -g @hesed/conni
26
26
  $ conni COMMAND
27
27
  running command...
28
28
  $ conni (--version)
29
- @hesed/conni/0.2.1 linux-x64 node-v22.22.0
29
+ @hesed/conni/0.4.0 darwin-arm64 node-v22.14.0
30
30
  $ conni --help [COMMAND]
31
31
  USAGE
32
32
  $ conni COMMAND
@@ -59,12 +59,12 @@ Add Atlassian authentication
59
59
 
60
60
  ```
61
61
  USAGE
62
- $ conni conni auth add -e <value> -t <value> -u <value> [--json]
62
+ $ conni conni auth add [--json] [-e <value>] [-t <value>] [-u <value>]
63
63
 
64
64
  FLAGS
65
- -e, --email=<value> (required) Account email:
66
- -t, --token=<value> (required) API Token:
67
- -u, --url=<value> (required) Atlassian URL (start with https://):
65
+ -e, --email=<value> Account email:
66
+ -t, --token=<value> API Token:
67
+ -u, --url=<value> Atlassian URL (start with https://):
68
68
 
69
69
  GLOBAL FLAGS
70
70
  --json Format output as json.
@@ -76,7 +76,7 @@ EXAMPLES
76
76
  $ conni conni auth add
77
77
  ```
78
78
 
79
- _See code: [src/commands/conni/auth/add.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/auth/add.ts)_
79
+ _See code: [src/commands/conni/auth/add.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/auth/add.ts)_
80
80
 
81
81
  ## `conni conni auth test`
82
82
 
@@ -96,7 +96,7 @@ EXAMPLES
96
96
  $ conni conni auth test
97
97
  ```
98
98
 
99
- _See code: [src/commands/conni/auth/test.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/auth/test.ts)_
99
+ _See code: [src/commands/conni/auth/test.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/auth/test.ts)_
100
100
 
101
101
  ## `conni conni auth update`
102
102
 
@@ -104,12 +104,12 @@ Update existing authentication
104
104
 
105
105
  ```
106
106
  USAGE
107
- $ conni conni auth update -e <value> -t <value> -u <value> [--json]
107
+ $ conni conni auth update [--json] [-e <value>] [-t <value>] [-u <value>]
108
108
 
109
109
  FLAGS
110
- -e, --email=<value> (required) Account email
111
- -t, --token=<value> (required) API Token
112
- -u, --url=<value> (required) Atlassian instance URL (start with https://)
110
+ -e, --email=<value> Account email
111
+ -t, --token=<value> API Token
112
+ -u, --url=<value> Atlassian instance URL (start with https://)
113
113
 
114
114
  GLOBAL FLAGS
115
115
  --json Format output as json.
@@ -121,7 +121,7 @@ EXAMPLES
121
121
  $ conni conni auth update
122
122
  ```
123
123
 
124
- _See code: [src/commands/conni/auth/update.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/auth/update.ts)_
124
+ _See code: [src/commands/conni/auth/update.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/auth/update.ts)_
125
125
 
126
126
  ## `conni conni content attachment PAGEID FILE`
127
127
 
@@ -145,7 +145,7 @@ EXAMPLES
145
145
  $ conni conni content attachment 123456 ./document.pdf
146
146
  ```
147
147
 
148
- _See code: [src/commands/conni/content/attachment.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/attachment.ts)_
148
+ _See code: [src/commands/conni/content/attachment.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/attachment.ts)_
149
149
 
150
150
  ## `conni conni content attachment-download ATTACHMENTID [OUTPUTPATH]`
151
151
 
@@ -171,7 +171,7 @@ EXAMPLES
171
171
  $ conni conni content attachment-download att12345 ./document.pdf
172
172
  ```
173
173
 
174
- _See code: [src/commands/conni/content/attachment-download.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/attachment-download.ts)_
174
+ _See code: [src/commands/conni/content/attachment-download.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/attachment-download.ts)_
175
175
 
176
176
  ## `conni conni content comment PAGEID BODY`
177
177
 
@@ -204,7 +204,7 @@ EXAMPLES
204
204
  $ conni conni content comment 123456 "$(cat content.md)"
205
205
  ```
206
206
 
207
- _See code: [src/commands/conni/content/comment.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/comment.ts)_
207
+ _See code: [src/commands/conni/content/comment.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/comment.ts)_
208
208
 
209
209
  ## `conni conni content comment-delete ID`
210
210
 
@@ -227,7 +227,7 @@ EXAMPLES
227
227
  $ conni conni content comment-delete 1544224770
228
228
  ```
229
229
 
230
- _See code: [src/commands/conni/content/comment-delete.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/comment-delete.ts)_
230
+ _See code: [src/commands/conni/content/comment-delete.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/comment-delete.ts)_
231
231
 
232
232
  ## `conni conni content comment-update ID BODY`
233
233
 
@@ -260,7 +260,7 @@ EXAMPLES
260
260
  $ conni conni content comment-update 1544224770 "$(cat content.md)"
261
261
  ```
262
262
 
263
- _See code: [src/commands/conni/content/comment-update.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/comment-update.ts)_
263
+ _See code: [src/commands/conni/content/comment-update.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/comment-update.ts)_
264
264
 
265
265
  ## `conni conni content create`
266
266
 
@@ -268,9 +268,10 @@ Create a new Confluence page
268
268
 
269
269
  ```
270
270
  USAGE
271
- $ conni conni content create --fields <value>... [--toon]
271
+ $ conni conni content create --fields <value>... [--attach <value>...] [--toon]
272
272
 
273
273
  FLAGS
274
+ --attach=<value>... Path to a file to upload and embed inline (can be used multiple times)
274
275
  --fields=<value>... (required) Content fields in key=value format
275
276
  --toon Format output as toon
276
277
 
@@ -289,13 +290,20 @@ EXAMPLES
289
290
  ls -a
290
291
  ```'
291
292
 
293
+ $ conni conni content create --fields spaceKey="DEV" title="Child page" body="Content" parentId="123456"
294
+
295
+ $ conni conni content create --fields spaceKey="DEV" title="Page with image" body="See the diagram:
296
+ ![diagram](./diagram.png)" --attach ./diagram.png
297
+
298
+ $ conni conni content create --fields spaceKey="DEV" title="Page with files" body="Content" --attach ./image.png --attach ./report.pdf
299
+
292
300
  FLAG DESCRIPTIONS
293
301
  --fields=<value>... Content fields in key=value format
294
302
 
295
303
  Minimum fields required: spaceKey, title & body
296
304
  ```
297
305
 
298
- _See code: [src/commands/conni/content/create.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/create.ts)_
306
+ _See code: [src/commands/conni/content/create.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/create.ts)_
299
307
 
300
308
  ## `conni conni content delete PAGEID`
301
309
 
@@ -318,7 +326,7 @@ EXAMPLES
318
326
  $ conni conni content delete 1543634992
319
327
  ```
320
328
 
321
- _See code: [src/commands/conni/content/delete.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/delete.ts)_
329
+ _See code: [src/commands/conni/content/delete.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/delete.ts)_
322
330
 
323
331
  ## `conni conni content get PAGEID`
324
332
 
@@ -341,7 +349,7 @@ EXAMPLES
341
349
  $ conni conni content get 1544060948
342
350
  ```
343
351
 
344
- _See code: [src/commands/conni/content/get.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/get.ts)_
352
+ _See code: [src/commands/conni/content/get.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/get.ts)_
345
353
 
346
354
  ## `conni conni content search CQL`
347
355
 
@@ -368,7 +376,7 @@ EXAMPLES
368
376
  $ conni conni content search 'created > startOfMonth()' --limit=5 --expand=body,version
369
377
  ```
370
378
 
371
- _See code: [src/commands/conni/content/search.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/search.ts)_
379
+ _See code: [src/commands/conni/content/search.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/search.ts)_
372
380
 
373
381
  ## `conni conni content update PAGEID`
374
382
 
@@ -402,7 +410,7 @@ EXAMPLES
402
410
  $ conni conni content update 1076199489 --fields body="$(cat content.md)"
403
411
  ```
404
412
 
405
- _See code: [src/commands/conni/content/update.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/content/update.ts)_
413
+ _See code: [src/commands/conni/content/update.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/content/update.ts)_
406
414
 
407
415
  ## `conni conni space get SPACEKEY`
408
416
 
@@ -425,7 +433,7 @@ EXAMPLES
425
433
  $ conni conni space get DEV
426
434
  ```
427
435
 
428
- _See code: [src/commands/conni/space/get.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/space/get.ts)_
436
+ _See code: [src/commands/conni/space/get.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/space/get.ts)_
429
437
 
430
438
  ## `conni conni space list`
431
439
 
@@ -445,5 +453,5 @@ EXAMPLES
445
453
  $ conni conni space list
446
454
  ```
447
455
 
448
- _See code: [src/commands/conni/space/list.ts](https://github.com/hesedcasa/conni/blob/v0.2.1/src/commands/conni/space/list.ts)_
456
+ _See code: [src/commands/conni/space/list.ts](https://github.com/hesedcasa/conni/blob/v0.4.0/src/commands/conni/space/list.ts)_
449
457
  <!-- commandsstop -->
@@ -4,6 +4,7 @@ export default class ContentCreate extends Command {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
+ attach: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  fields: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
8
9
  toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
10
  };
@@ -1,6 +1,6 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
2
  import { readConfig } from '../../../config.js';
3
- import { clearClients, createPage } from '../../../conni/conni-client.js';
3
+ import { clearClients, createPage, createPageWithMedia } from '../../../conni/conni-client.js';
4
4
  import { formatAsToon } from '../../../format.js';
5
5
  export default class ContentCreate extends Command {
6
6
  static args = {};
@@ -8,8 +8,16 @@ export default class ContentCreate extends Command {
8
8
  static examples = [
9
9
  '<%= config.bin %> <%= command.id %> --fields spaceKey="DEV" title="New title" body="New description" status="draft"',
10
10
  '<%= config.bin %> <%= command.id %> --fields spaceKey="DEV" title="New title" body=\'\n# Header\n## Sub-header\n- Item 1\n- Item 2\n```bash\nls -a\n```\'',
11
+ '<%= config.bin %> <%= command.id %> --fields spaceKey="DEV" title="Child page" body="Content" parentId="123456"',
12
+ '<%= config.bin %> <%= command.id %> --fields spaceKey="DEV" title="Page with image" body="See the diagram:\n![diagram](./diagram.png)" --attach ./diagram.png',
13
+ '<%= config.bin %> <%= command.id %> --fields spaceKey="DEV" title="Page with files" body="Content" --attach ./image.png --attach ./report.pdf',
11
14
  ];
12
15
  static flags = {
16
+ attach: Flags.string({
17
+ description: 'Path to a file to upload and embed inline (can be used multiple times)',
18
+ multiple: true,
19
+ required: false,
20
+ }),
13
21
  fields: Flags.string({
14
22
  description: 'Minimum fields required: spaceKey, title & body',
15
23
  multiple: true,
@@ -38,7 +46,9 @@ export default class ContentCreate extends Command {
38
46
  this.error(`Required field "${required}" is missing`);
39
47
  }
40
48
  }
41
- const result = await createPage(config.auth, fields);
49
+ const result = flags.attach
50
+ ? await createPageWithMedia(config.auth, fields, flags.attach)
51
+ : await createPage(config.auth, fields);
42
52
  clearClients();
43
53
  if (flags.toon) {
44
54
  this.log(formatAsToon(result));
@@ -36,6 +36,12 @@ export declare class ConniApi {
36
36
  * Create a new page
37
37
  */
38
38
  createPage(fields: Record<string, unknown>): Promise<ApiResult>;
39
+ /**
40
+ * Create a new page with inline media attachments.
41
+ * Creates the page first to obtain a page ID, then uploads attachments and
42
+ * patches the ADF body to embed them by file ID before updating the page.
43
+ */
44
+ createPageWithMedia(fields: Record<string, unknown>, filePaths: string[]): Promise<ApiResult>;
39
45
  /**
40
46
  * Delete a comment from a page
41
47
  */
@@ -80,4 +86,7 @@ export declare class ConniApi {
80
86
  * Update an existing page
81
87
  */
82
88
  updateContent(pageId: string, fields: Record<string, unknown>): Promise<ApiResult>;
89
+ private buildPageBody;
90
+ private collectExternalMedia;
91
+ private patchMediaNodes;
83
92
  }
@@ -106,38 +106,70 @@ export class ConniApi {
106
106
  async createPage(fields) {
107
107
  try {
108
108
  const client = this.getClient();
109
- // Convert Markdown body to Confluence ADF
110
- // eslint-disable-next-line unicorn/prefer-string-replace-all
111
- const bodyContent = markdownToAdf(fields.body.replace(/\\n/g, '\n'));
112
- const spaceKey = fields.spaceKey;
113
- const title = fields.title;
114
- const parentId = fields.parentId;
115
- const status = fields.status;
116
- const contentBody = {
117
- body: {
118
- storage: {
119
- representation: 'atlas_doc_format',
120
- value: JSON.stringify(bodyContent),
121
- },
122
- },
123
- parentId,
124
- space: { key: spaceKey },
125
- status,
109
+ const { contentPayload } = this.buildPageBody(fields);
110
+ const response = await client.content.createContent(contentPayload);
111
+ return { data: response, success: true };
112
+ }
113
+ catch (error) {
114
+ const errorMessage = typeof error === 'object' ? String(error.message) : String(error);
115
+ return { error: errorMessage, success: false };
116
+ }
117
+ }
118
+ /**
119
+ * Create a new page with inline media attachments.
120
+ * Creates the page first to obtain a page ID, then uploads attachments and
121
+ * patches the ADF body to embed them by file ID before updating the page.
122
+ */
123
+ async createPageWithMedia(fields, filePaths) {
124
+ try {
125
+ const client = this.getClient();
126
+ const { bodyContent, contentPayload } = this.buildPageBody(fields);
127
+ const { title } = contentPayload;
128
+ const externalMediaByBasename = new Map();
129
+ this.collectExternalMedia(bodyContent.content, externalMediaByBasename);
130
+ const inlinePaths = [];
131
+ const trailingPaths = [];
132
+ for (const f of filePaths) {
133
+ if (externalMediaByBasename.has(path.basename(f))) {
134
+ inlinePaths.push(f);
135
+ }
136
+ else {
137
+ trailingPaths.push(f);
138
+ }
139
+ }
140
+ // Create the page first to get a page ID for attachment uploads.
141
+ const page = await client.content.createContent(contentPayload);
142
+ const pageId = page.id;
143
+ if (!pageId) {
144
+ return { error: 'Failed to get page ID from creation response', success: false };
145
+ }
146
+ const uploadResults = await Promise.all(filePaths.map((filePath) => this.addAttachment(pageId, filePath)));
147
+ const firstFailure = uploadResults.find((r) => !r.success);
148
+ if (firstFailure)
149
+ return firstFailure;
150
+ const fileInfoByPath = new Map();
151
+ for (const [i, filePath] of filePaths.entries()) {
152
+ const uploadData = uploadResults[i].data;
153
+ const att = uploadData?.results?.[0];
154
+ const fileId = att?.extensions?.fileId;
155
+ const collectionName = att?.extensions?.collectionName ?? '';
156
+ if (fileId) {
157
+ fileInfoByPath.set(filePath, { collection: collectionName, id: fileId });
158
+ }
159
+ }
160
+ this.patchMediaNodes(bodyContent.content, inlinePaths, trailingPaths, fileInfoByPath, externalMediaByBasename);
161
+ const updatedPage = await client.content.updateContent({
162
+ body: { storage: { representation: 'atlas_doc_format', value: JSON.stringify(bodyContent) } },
163
+ id: pageId,
126
164
  title,
127
165
  type: 'page',
128
- };
129
- const response = await client.content.createContent(contentBody);
130
- return {
131
- data: response,
132
- success: true,
133
- };
166
+ version: { number: 2 },
167
+ });
168
+ return { data: updatedPage, success: true };
134
169
  }
135
170
  catch (error) {
136
171
  const errorMessage = typeof error === 'object' ? String(error.message) : String(error);
137
- return {
138
- error: errorMessage,
139
- success: false,
140
- };
172
+ return { error: errorMessage, success: false };
141
173
  }
142
174
  }
143
175
  /**
@@ -444,4 +476,64 @@ export class ConniApi {
444
476
  };
445
477
  }
446
478
  }
479
+ buildPageBody(fields) {
480
+ // eslint-disable-next-line unicorn/prefer-string-replace-all
481
+ const bodyContent = markdownToAdf(fields.body.replace(/\\n/g, '\n'));
482
+ const spaceKey = fields.spaceKey;
483
+ const title = fields.title;
484
+ const parentId = fields.parentId;
485
+ const status = fields.status;
486
+ return {
487
+ bodyContent,
488
+ contentPayload: {
489
+ ancestors: parentId ? [{ id: parentId }] : undefined,
490
+ body: { storage: { representation: 'atlas_doc_format', value: JSON.stringify(bodyContent) } },
491
+ space: { key: spaceKey },
492
+ status,
493
+ title,
494
+ type: 'page',
495
+ },
496
+ };
497
+ }
498
+ collectExternalMedia(nodes, map) {
499
+ for (const node of nodes) {
500
+ const content = node.content;
501
+ const media = node.type === 'mediaSingle' ? content?.[0] : undefined;
502
+ const attrs = media?.type === 'media' ? media.attrs : undefined;
503
+ if (attrs?.type === 'external' && typeof attrs.url === 'string') {
504
+ const base = path.basename(attrs.url);
505
+ if (!map.has(base))
506
+ map.set(base, []);
507
+ map.get(base).push(attrs);
508
+ continue;
509
+ }
510
+ if (content)
511
+ this.collectExternalMedia(content, map);
512
+ }
513
+ }
514
+ /* eslint-disable max-params */
515
+ patchMediaNodes(bodyNodes, inlinePaths, trailingPaths, fileInfoByPath, externalMediaByBasename) {
516
+ for (const filePath of inlinePaths) {
517
+ const info = fileInfoByPath.get(filePath);
518
+ if (!info)
519
+ continue;
520
+ for (const attrs of externalMediaByBasename.get(path.basename(filePath)) ?? []) {
521
+ delete attrs.url;
522
+ delete attrs.alt;
523
+ attrs.collection = info.collection;
524
+ attrs.id = info.id;
525
+ attrs.type = 'file';
526
+ }
527
+ }
528
+ for (const filePath of trailingPaths) {
529
+ const info = fileInfoByPath.get(filePath);
530
+ if (!info)
531
+ continue;
532
+ bodyNodes.push({
533
+ attrs: { layout: 'center' },
534
+ content: [{ attrs: { collection: info.collection, id: info.id, type: 'file' }, type: 'media' }],
535
+ type: 'mediaSingle',
536
+ });
537
+ }
538
+ }
447
539
  }
@@ -30,6 +30,13 @@ export declare function getContent(config: Config, pageId: string): Promise<ApiR
30
30
  * @param fields - Page fields (spaceKey, title, body, parentId)
31
31
  */
32
32
  export declare function createPage(config: Config, fields: Record<string, unknown>): Promise<ApiResult>;
33
+ /**
34
+ * Create a new page with inline media attachments
35
+ * @param config - Confluence configuration
36
+ * @param fields - Page fields (spaceKey, title, body, parentId)
37
+ * @param filePaths - Local file paths to upload and embed inline
38
+ */
39
+ export declare function createPageWithMedia(config: Config, fields: Record<string, unknown>, filePaths: string[]): Promise<ApiResult>;
33
40
  /**
34
41
  * Update an existing page
35
42
  * @param config - Confluence configuration
@@ -61,6 +61,16 @@ export async function createPage(config, fields) {
61
61
  const conni = await initConni(config);
62
62
  return conni.createPage(fields);
63
63
  }
64
+ /**
65
+ * Create a new page with inline media attachments
66
+ * @param config - Confluence configuration
67
+ * @param fields - Page fields (spaceKey, title, body, parentId)
68
+ * @param filePaths - Local file paths to upload and embed inline
69
+ */
70
+ export async function createPageWithMedia(config, fields, filePaths) {
71
+ const conni = await initConni(config);
72
+ return conni.createPageWithMedia(fields, filePaths);
73
+ }
64
74
  /**
65
75
  * Update an existing page
66
76
  * @param config - Confluence configuration
@@ -19,7 +19,7 @@
19
19
  "char": "e",
20
20
  "description": "Account email:",
21
21
  "name": "email",
22
- "required": true,
22
+ "required": false,
23
23
  "hasDynamicHelp": false,
24
24
  "multiple": false,
25
25
  "type": "option"
@@ -28,7 +28,7 @@
28
28
  "char": "t",
29
29
  "description": "API Token:",
30
30
  "name": "token",
31
- "required": true,
31
+ "required": false,
32
32
  "hasDynamicHelp": false,
33
33
  "multiple": false,
34
34
  "type": "option"
@@ -37,7 +37,7 @@
37
37
  "char": "u",
38
38
  "description": "Atlassian URL (start with https://):",
39
39
  "name": "url",
40
- "required": true,
40
+ "required": false,
41
41
  "hasDynamicHelp": false,
42
42
  "multiple": false,
43
43
  "type": "option"
@@ -112,7 +112,7 @@
112
112
  "char": "e",
113
113
  "description": "Account email",
114
114
  "name": "email",
115
- "required": true,
115
+ "required": false,
116
116
  "hasDynamicHelp": false,
117
117
  "multiple": false,
118
118
  "type": "option"
@@ -121,7 +121,7 @@
121
121
  "char": "t",
122
122
  "description": "API Token",
123
123
  "name": "token",
124
- "required": true,
124
+ "required": false,
125
125
  "hasDynamicHelp": false,
126
126
  "multiple": false,
127
127
  "type": "option"
@@ -130,7 +130,7 @@
130
130
  "char": "u",
131
131
  "description": "Atlassian instance URL (start with https://)",
132
132
  "name": "url",
133
- "required": true,
133
+ "required": false,
134
134
  "hasDynamicHelp": false,
135
135
  "multiple": false,
136
136
  "type": "option"
@@ -153,78 +153,6 @@
153
153
  "update.js"
154
154
  ]
155
155
  },
156
- "conni:space:get": {
157
- "aliases": [],
158
- "args": {
159
- "spaceKey": {
160
- "description": "Space key",
161
- "name": "spaceKey",
162
- "required": true
163
- }
164
- },
165
- "description": "Get details of a Confluence space",
166
- "examples": [
167
- "<%= config.bin %> <%= command.id %> DEV"
168
- ],
169
- "flags": {
170
- "toon": {
171
- "description": "Format output as toon",
172
- "name": "toon",
173
- "required": false,
174
- "allowNo": false,
175
- "type": "boolean"
176
- }
177
- },
178
- "hasDynamicHelp": false,
179
- "hiddenAliases": [],
180
- "id": "conni:space:get",
181
- "pluginAlias": "@hesed/conni",
182
- "pluginName": "@hesed/conni",
183
- "pluginType": "core",
184
- "strict": true,
185
- "enableJsonFlag": false,
186
- "isESM": true,
187
- "relativePath": [
188
- "dist",
189
- "commands",
190
- "conni",
191
- "space",
192
- "get.js"
193
- ]
194
- },
195
- "conni:space:list": {
196
- "aliases": [],
197
- "args": {},
198
- "description": "List all Confluence spaces",
199
- "examples": [
200
- "<%= config.bin %> <%= command.id %>"
201
- ],
202
- "flags": {
203
- "toon": {
204
- "description": "Format output as toon",
205
- "name": "toon",
206
- "required": false,
207
- "allowNo": false,
208
- "type": "boolean"
209
- }
210
- },
211
- "hasDynamicHelp": false,
212
- "hiddenAliases": [],
213
- "id": "conni:space:list",
214
- "pluginAlias": "@hesed/conni",
215
- "pluginName": "@hesed/conni",
216
- "pluginType": "core",
217
- "strict": true,
218
- "enableJsonFlag": false,
219
- "isESM": true,
220
- "relativePath": [
221
- "dist",
222
- "commands",
223
- "conni",
224
- "space",
225
- "list.js"
226
- ]
227
- },
228
156
  "conni:content:attachment-download": {
229
157
  "aliases": [],
230
158
  "args": {
@@ -449,9 +377,20 @@
449
377
  "description": "Create a new Confluence page",
450
378
  "examples": [
451
379
  "<%= config.bin %> <%= command.id %> --fields spaceKey=\"DEV\" title=\"New title\" body=\"New description\" status=\"draft\"",
452
- "<%= config.bin %> <%= command.id %> --fields spaceKey=\"DEV\" title=\"New title\" body='\n# Header\n## Sub-header\n- Item 1\n- Item 2\n```bash\nls -a\n```'"
380
+ "<%= config.bin %> <%= command.id %> --fields spaceKey=\"DEV\" title=\"New title\" body='\n# Header\n## Sub-header\n- Item 1\n- Item 2\n```bash\nls -a\n```'",
381
+ "<%= config.bin %> <%= command.id %> --fields spaceKey=\"DEV\" title=\"Child page\" body=\"Content\" parentId=\"123456\"",
382
+ "<%= config.bin %> <%= command.id %> --fields spaceKey=\"DEV\" title=\"Page with image\" body=\"See the diagram:\n![diagram](./diagram.png)\" --attach ./diagram.png",
383
+ "<%= config.bin %> <%= command.id %> --fields spaceKey=\"DEV\" title=\"Page with files\" body=\"Content\" --attach ./image.png --attach ./report.pdf"
453
384
  ],
454
385
  "flags": {
386
+ "attach": {
387
+ "description": "Path to a file to upload and embed inline (can be used multiple times)",
388
+ "name": "attach",
389
+ "required": false,
390
+ "hasDynamicHelp": false,
391
+ "multiple": true,
392
+ "type": "option"
393
+ },
455
394
  "fields": {
456
395
  "description": "Minimum fields required: spaceKey, title & body",
457
396
  "name": "fields",
@@ -661,7 +600,79 @@
661
600
  "content",
662
601
  "update.js"
663
602
  ]
603
+ },
604
+ "conni:space:get": {
605
+ "aliases": [],
606
+ "args": {
607
+ "spaceKey": {
608
+ "description": "Space key",
609
+ "name": "spaceKey",
610
+ "required": true
611
+ }
612
+ },
613
+ "description": "Get details of a Confluence space",
614
+ "examples": [
615
+ "<%= config.bin %> <%= command.id %> DEV"
616
+ ],
617
+ "flags": {
618
+ "toon": {
619
+ "description": "Format output as toon",
620
+ "name": "toon",
621
+ "required": false,
622
+ "allowNo": false,
623
+ "type": "boolean"
624
+ }
625
+ },
626
+ "hasDynamicHelp": false,
627
+ "hiddenAliases": [],
628
+ "id": "conni:space:get",
629
+ "pluginAlias": "@hesed/conni",
630
+ "pluginName": "@hesed/conni",
631
+ "pluginType": "core",
632
+ "strict": true,
633
+ "enableJsonFlag": false,
634
+ "isESM": true,
635
+ "relativePath": [
636
+ "dist",
637
+ "commands",
638
+ "conni",
639
+ "space",
640
+ "get.js"
641
+ ]
642
+ },
643
+ "conni:space:list": {
644
+ "aliases": [],
645
+ "args": {},
646
+ "description": "List all Confluence spaces",
647
+ "examples": [
648
+ "<%= config.bin %> <%= command.id %>"
649
+ ],
650
+ "flags": {
651
+ "toon": {
652
+ "description": "Format output as toon",
653
+ "name": "toon",
654
+ "required": false,
655
+ "allowNo": false,
656
+ "type": "boolean"
657
+ }
658
+ },
659
+ "hasDynamicHelp": false,
660
+ "hiddenAliases": [],
661
+ "id": "conni:space:list",
662
+ "pluginAlias": "@hesed/conni",
663
+ "pluginName": "@hesed/conni",
664
+ "pluginType": "core",
665
+ "strict": true,
666
+ "enableJsonFlag": false,
667
+ "isESM": true,
668
+ "relativePath": [
669
+ "dist",
670
+ "commands",
671
+ "conni",
672
+ "space",
673
+ "list.js"
674
+ ]
664
675
  }
665
676
  },
666
- "version": "0.2.1"
677
+ "version": "0.4.0"
667
678
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hesed/conni",
3
3
  "description": "CLI for Confluence API interaction",
4
- "version": "0.2.1",
4
+ "version": "0.4.0",
5
5
  "author": "Hesed",
6
6
  "bin": {
7
7
  "conni": "./bin/run.js"
@@ -16,7 +16,7 @@
16
16
  "marklassian": "^1.1.0"
17
17
  },
18
18
  "devDependencies": {
19
- "@eslint/compat": "^1",
19
+ "@eslint/compat": "^2",
20
20
  "@oclif/prettier-config": "^0.2.1",
21
21
  "@oclif/test": "^4",
22
22
  "@types/chai": "^5",