@hesed/conni 0.1.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.
Files changed (49) hide show
  1. package/README.md +449 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/commands/conni/auth/add.d.ts +14 -0
  7. package/dist/commands/conni/auth/add.js +55 -0
  8. package/dist/commands/conni/auth/test.d.ts +10 -0
  9. package/dist/commands/conni/auth/test.js +32 -0
  10. package/dist/commands/conni/auth/update.d.ts +14 -0
  11. package/dist/commands/conni/auth/update.js +77 -0
  12. package/dist/commands/conni/content/attachment-download.d.ts +13 -0
  13. package/dist/commands/conni/content/attachment-download.js +44 -0
  14. package/dist/commands/conni/content/attachment.d.ts +13 -0
  15. package/dist/commands/conni/content/attachment.js +40 -0
  16. package/dist/commands/conni/content/comment-delete.d.ts +12 -0
  17. package/dist/commands/conni/content/comment-delete.js +29 -0
  18. package/dist/commands/conni/content/comment-update.d.ts +13 -0
  19. package/dist/commands/conni/content/comment-update.js +35 -0
  20. package/dist/commands/conni/content/comment.d.ts +13 -0
  21. package/dist/commands/conni/content/comment.js +35 -0
  22. package/dist/commands/conni/content/create.d.ts +11 -0
  23. package/dist/commands/conni/content/create.js +50 -0
  24. package/dist/commands/conni/content/delete.d.ts +12 -0
  25. package/dist/commands/conni/content/delete.js +29 -0
  26. package/dist/commands/conni/content/get.d.ts +12 -0
  27. package/dist/commands/conni/content/get.js +29 -0
  28. package/dist/commands/conni/content/search.d.ts +14 -0
  29. package/dist/commands/conni/content/search.js +34 -0
  30. package/dist/commands/conni/content/update.d.ts +12 -0
  31. package/dist/commands/conni/content/update.js +35 -0
  32. package/dist/commands/conni/space/get.d.ts +12 -0
  33. package/dist/commands/conni/space/get.js +29 -0
  34. package/dist/commands/conni/space/list.d.ts +9 -0
  35. package/dist/commands/conni/space/list.js +26 -0
  36. package/dist/config.d.ts +10 -0
  37. package/dist/config.js +18 -0
  38. package/dist/conni/conni-api.d.ts +88 -0
  39. package/dist/conni/conni-api.js +447 -0
  40. package/dist/conni/conni-client.d.ts +88 -0
  41. package/dist/conni/conni-client.js +148 -0
  42. package/dist/format.d.ts +4 -0
  43. package/dist/format.js +10 -0
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +1 -0
  46. package/dist/utils.d.ts +1 -0
  47. package/dist/utils.js +1 -0
  48. package/oclif.manifest.json +667 -0
  49. package/package.json +107 -0
@@ -0,0 +1,44 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { action } from '@oclif/core/ux';
3
+ import { readConfig } from '../../../config.js';
4
+ import { clearClients, downloadAttachment } from '../../../conni/conni-client.js';
5
+ import { formatAsToon } from '../../../format.js';
6
+ export default class ContentDownloadAttachment extends Command {
7
+ static args = {
8
+ attachmentId: Args.string({ description: 'Attachment ID', required: true }),
9
+ outputPath: Args.string({ description: 'Output file path', required: false }),
10
+ };
11
+ static description = 'Download attachment from Confluence content';
12
+ static examples = [
13
+ '<%= config.bin %> <%= command.id %> att12345',
14
+ '<%= config.bin %> <%= command.id %> att12345 ./document.pdf',
15
+ ];
16
+ static flags = {
17
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
18
+ };
19
+ async run() {
20
+ const { args, flags } = await this.parse(ContentDownloadAttachment);
21
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
22
+ if (!config) {
23
+ return;
24
+ }
25
+ if (!args.outputPath) {
26
+ args.outputPath = process.cwd();
27
+ }
28
+ action.start(`Downloading attachment "${args.attachmentId}" to ""`);
29
+ const result = await downloadAttachment(config.auth, args.attachmentId, args.outputPath);
30
+ clearClients();
31
+ if (result.success) {
32
+ action.stop('✓ Successfully uploaded');
33
+ }
34
+ else {
35
+ action.stop('✗ Upload failed');
36
+ }
37
+ if (flags.toon) {
38
+ this.log(formatAsToon(result));
39
+ }
40
+ else {
41
+ this.logJson(result);
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentAttachment extends Command {
3
+ static args: {
4
+ pageId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ file: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,40 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { action } from '@oclif/core/ux';
3
+ import { readConfig } from '../../../config.js';
4
+ import { addAttachment, clearClients } from '../../../conni/conni-client.js';
5
+ import { formatAsToon } from '../../../format.js';
6
+ export default class ContentAttachment extends Command {
7
+ /* eslint-disable perfectionist/sort-objects */
8
+ static args = {
9
+ pageId: Args.string({ description: 'Page ID', required: true }),
10
+ file: Args.string({ description: 'Path to the file to upload', required: true }),
11
+ };
12
+ /* eslint-enable perfectionist/sort-objects */
13
+ static description = 'Add attachment to Confluence content';
14
+ static examples = ['<%= config.bin %> <%= command.id %> 123456 ./document.pdf'];
15
+ static flags = {
16
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
17
+ };
18
+ async run() {
19
+ const { args, flags } = await this.parse(ContentAttachment);
20
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
21
+ if (!config) {
22
+ return;
23
+ }
24
+ action.start(`Uploading attachment "${args.file}" to page ${args.pageId}`);
25
+ const result = await addAttachment(config.auth, args.pageId, args.file);
26
+ clearClients();
27
+ if (result.success) {
28
+ action.stop('✓ Successfully uploaded');
29
+ }
30
+ else {
31
+ action.stop('✗ Upload failed');
32
+ }
33
+ if (flags.toon) {
34
+ this.log(formatAsToon(result));
35
+ }
36
+ else {
37
+ this.logJson(result);
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentDeleteComment extends Command {
3
+ static args: {
4
+ id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,29 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, deleteComment } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentDeleteComment extends Command {
6
+ static args = {
7
+ id: Args.string({ description: 'Comment ID to delete', required: true }),
8
+ };
9
+ static description = 'Delete comment from Confluence content';
10
+ static examples = ['<%= config.bin %> <%= command.id %> 1544224770'];
11
+ static flags = {
12
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(ContentDeleteComment);
16
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
17
+ if (!config) {
18
+ return;
19
+ }
20
+ const result = await deleteComment(config.auth, args.id);
21
+ clearClients();
22
+ if (flags.toon) {
23
+ this.log(formatAsToon(result));
24
+ }
25
+ else {
26
+ this.logJson(result);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentUpdateComment extends Command {
3
+ static args: {
4
+ id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ body: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,35 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, updateComment } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentUpdateComment extends Command {
6
+ /* eslint-disable perfectionist/sort-objects */
7
+ static args = {
8
+ id: Args.string({ description: 'Comment ID to update', required: true }),
9
+ body: Args.string({ description: 'Comment in Markdown format', required: true }),
10
+ };
11
+ /* eslint-enable perfectionist/sort-objects */
12
+ static description = 'Update a comment';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %> 1544224770 "\n# Header\n## Sub-header\n- Item 1\n- Item 2\n```bash\nls -a\n```"',
15
+ '<%= config.bin %> <%= command.id %> 1544224770 "$(cat content.md)"',
16
+ ];
17
+ static flags = {
18
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
19
+ };
20
+ async run() {
21
+ const { args, flags } = await this.parse(ContentUpdateComment);
22
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
23
+ if (!config) {
24
+ return;
25
+ }
26
+ const result = await updateComment(config.auth, args.id, args.body);
27
+ clearClients();
28
+ if (flags.toon) {
29
+ this.log(formatAsToon(result));
30
+ }
31
+ else {
32
+ this.logJson(result);
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentAddComment extends Command {
3
+ static args: {
4
+ pageId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ body: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,35 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { addComment, clearClients } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentAddComment extends Command {
6
+ /* eslint-disable perfectionist/sort-objects */
7
+ static args = {
8
+ pageId: Args.string({ description: 'Page ID', required: true }),
9
+ body: Args.string({ description: 'Comment in Markdown format', required: true }),
10
+ };
11
+ /* eslint-enable perfectionist/sort-objects */
12
+ static description = 'Add comment to Confluence content';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %> 123456 "\n# Header\n## Sub-header\n- Item 1\n- Item 2\n```bash\nls -a\n```"',
15
+ '<%= config.bin %> <%= command.id %> 123456 "$(cat content.md)"',
16
+ ];
17
+ static flags = {
18
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
19
+ };
20
+ async run() {
21
+ const { args, flags } = await this.parse(ContentAddComment);
22
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
23
+ if (!config) {
24
+ return;
25
+ }
26
+ const result = await addComment(config.auth, args.pageId, args.body);
27
+ clearClients();
28
+ if (flags.toon) {
29
+ this.log(formatAsToon(result));
30
+ }
31
+ else {
32
+ this.logJson(result);
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentCreate extends Command {
3
+ static args: {};
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ fields: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
8
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,50 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, createPage } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentCreate extends Command {
6
+ static args = {};
7
+ static description = 'Create a new Confluence page';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> --fields spaceKey="DEV" title="New title" body="New description" status="draft"',
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
+ ];
12
+ static flags = {
13
+ fields: Flags.string({
14
+ description: 'Minimum fields required: spaceKey, title & body',
15
+ multiple: true,
16
+ required: true,
17
+ summary: 'Content fields in key=value format',
18
+ }),
19
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
20
+ };
21
+ async run() {
22
+ const { flags } = await this.parse(ContentCreate);
23
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
24
+ if (!config) {
25
+ return;
26
+ }
27
+ const fields = {};
28
+ if (flags.fields) {
29
+ for (const field of flags.fields) {
30
+ const [key, ...valueParts] = field.split('=');
31
+ const value = valueParts.join('=');
32
+ fields[key] = value;
33
+ }
34
+ }
35
+ const requiredFields = ['spaceKey', 'title', 'body'];
36
+ for (const required of requiredFields) {
37
+ if (!fields[required]) {
38
+ this.error(`Required field "${required}" is missing`);
39
+ }
40
+ }
41
+ const result = await createPage(config.auth, fields);
42
+ clearClients();
43
+ if (flags.toon) {
44
+ this.log(formatAsToon(result));
45
+ }
46
+ else {
47
+ this.logJson(result);
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentDelete extends Command {
3
+ static args: {
4
+ pageId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,29 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, deleteContent } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentDelete extends Command {
6
+ static args = {
7
+ pageId: Args.string({ description: 'Page ID to delete', required: true }),
8
+ };
9
+ static description = 'Delete a Confluence page';
10
+ static examples = ['<%= config.bin %> <%= command.id %> 1543634992'];
11
+ static flags = {
12
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(ContentDelete);
16
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
17
+ if (!config) {
18
+ return;
19
+ }
20
+ const result = await deleteContent(config.auth, args.pageId);
21
+ clearClients();
22
+ if (flags.toon) {
23
+ this.log(formatAsToon(result));
24
+ }
25
+ else {
26
+ this.logJson(result);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentGet extends Command {
3
+ static args: {
4
+ pageId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,29 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, getContent } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentGet extends Command {
6
+ static args = {
7
+ pageId: Args.string({ description: 'Page ID', required: true }),
8
+ };
9
+ static description = 'Get details of a Confluence content';
10
+ static examples = ['<%= config.bin %> <%= command.id %> 1544060948'];
11
+ static flags = {
12
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(ContentGet);
16
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
17
+ if (!config) {
18
+ return;
19
+ }
20
+ const result = await getContent(config.auth, args.pageId);
21
+ clearClients();
22
+ if (flags.toon) {
23
+ this.log(formatAsToon(result));
24
+ }
25
+ else {
26
+ this.logJson(result);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentSearch extends Command {
3
+ static args: {
4
+ cql: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ expand: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ limit: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,34 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, searchContents } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class ContentSearch extends Command {
6
+ static args = {
7
+ cql: Args.string({ description: 'CQL expression', required: true }),
8
+ };
9
+ static description = 'Search for Confluence contents using CQL';
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %> \'space=DEV AND title ~ "Implement email OTP login" AND creator=currentUser()\'',
12
+ "<%= config.bin %> <%= command.id %> 'created > startOfMonth()' --limit=5 --expand=body,version",
13
+ ];
14
+ static flags = {
15
+ expand: Flags.string({ description: 'Properties of the content to expand', required: false }),
16
+ limit: Flags.integer({ description: 'Maximum number of contents per page', required: false }),
17
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
18
+ };
19
+ async run() {
20
+ const { args, flags } = await this.parse(ContentSearch);
21
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
22
+ if (!config) {
23
+ return;
24
+ }
25
+ const result = await searchContents(config.auth, args.cql, flags.limit, flags.expand ? flags.expand.split(',') : undefined);
26
+ clearClients();
27
+ if (flags.toon) {
28
+ this.log(formatAsToon(result));
29
+ }
30
+ else {
31
+ this.logJson(result);
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ContentUpdate extends Command {
3
+ static args: {
4
+ pageId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ fields: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,35 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, updateContent } from '../../../conni/conni-client.js';
4
+ export default class ContentUpdate extends Command {
5
+ static args = {
6
+ pageId: Args.string({ description: 'Page ID', required: true }),
7
+ };
8
+ static description = 'Update an existing Confluence content';
9
+ static examples = [
10
+ "<%= config.bin %> <%= command.id %> 1076199489 --fields title='New summary' body='New description'",
11
+ "<%= config.bin %> <%= command.id %> 1076199489 --fields body='\n# Header\n## Sub-header\n- Item 1\n- Item 2\n```bash\nls -a\n```'",
12
+ '<%= config.bin %> <%= command.id %> 1076199489 --fields body="$(cat content.md)"',
13
+ ];
14
+ static flags = {
15
+ fields: Flags.string({ description: 'Content fields to update in key=value format', multiple: true, required: true }),
16
+ };
17
+ async run() {
18
+ const { args, flags } = await this.parse(ContentUpdate);
19
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
20
+ if (!config) {
21
+ return;
22
+ }
23
+ const fields = {};
24
+ if (flags.fields) {
25
+ for (const field of flags.fields) {
26
+ const [key, ...valueParts] = field.split('=');
27
+ const value = valueParts.join('=');
28
+ fields[key] = value;
29
+ }
30
+ }
31
+ const result = await updateContent(config.auth, args.pageId, fields);
32
+ clearClients();
33
+ this.logJson(result);
34
+ }
35
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class SpaceGet extends Command {
3
+ static args: {
4
+ spaceKey: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,29 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, getSpace } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class SpaceGet extends Command {
6
+ static args = {
7
+ spaceKey: Args.string({ description: 'Space key', required: true }),
8
+ };
9
+ static description = 'Get details of a Confluence space';
10
+ static examples = ['<%= config.bin %> <%= command.id %> DEV'];
11
+ static flags = {
12
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(SpaceGet);
16
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
17
+ if (!config) {
18
+ return;
19
+ }
20
+ const result = await getSpace(config.auth, args.spaceKey);
21
+ clearClients();
22
+ if (flags.toon) {
23
+ this.log(formatAsToon(result));
24
+ }
25
+ else {
26
+ this.logJson(result);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class SpaceList extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,26 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { readConfig } from '../../../config.js';
3
+ import { clearClients, listSpaces } from '../../../conni/conni-client.js';
4
+ import { formatAsToon } from '../../../format.js';
5
+ export default class SpaceList extends Command {
6
+ static description = 'List all Confluence spaces';
7
+ static examples = ['<%= config.bin %> <%= command.id %>'];
8
+ static flags = {
9
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
10
+ };
11
+ async run() {
12
+ const { flags } = await this.parse(SpaceList);
13
+ const config = await readConfig(this.config.configDir, this.log.bind(this));
14
+ if (!config) {
15
+ return;
16
+ }
17
+ const result = await listSpaces(config.auth);
18
+ clearClients();
19
+ if (flags.toon) {
20
+ this.log(formatAsToon(result));
21
+ }
22
+ else {
23
+ this.logJson(result);
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,10 @@
1
+ interface AuthConfig {
2
+ apiToken: string;
3
+ email: string;
4
+ host: string;
5
+ }
6
+ interface Config {
7
+ auth: AuthConfig;
8
+ }
9
+ export declare function readConfig(configDir: string, log: (message: string) => void): Promise<Config | undefined>;
10
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,18 @@
1
+ import { default as fs } from 'fs-extra';
2
+ import { default as path } from 'node:path';
3
+ export async function readConfig(configDir, log) {
4
+ const configPath = path.join(configDir, 'conni-config.json');
5
+ try {
6
+ return await fs.readJSON(configPath);
7
+ }
8
+ catch (error) {
9
+ const msg = error instanceof Error ? error.message : String(error);
10
+ if (msg.toLowerCase().includes('no such file or directory')) {
11
+ log('Missing authentication config');
12
+ }
13
+ else {
14
+ log(msg);
15
+ }
16
+ return undefined;
17
+ }
18
+ }