diff --git a/.gitignore b/.gitignore index fa25531..c74c0ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +package-lock.json *-debug.log *-error.log /.nyc_output diff --git a/README.md b/README.md index 700f816..d964de5 100644 --- a/README.md +++ b/README.md @@ -453,8 +453,8 @@ Create a note ``` USAGE $ hackmd-cli notes create [--commentPermission ] [--content ] [-e] [-h] [--parentFolderId ] - [--readPermission ] [--title ] [--writePermission ] [--columns | -x] [--sort ] - [--filter ] [--output csv|json|yaml | | [--csv | --no-truncate]] [--no-header | ] + [--readPermission ] [--tags ] [--title ] [--writePermission ] [--columns | -x] + [--sort ] [--filter ] [--output csv|json|yaml | | [--csv | --no-truncate]] [--no-header | ] FLAGS -e, --editor create note with $EDITOR @@ -472,6 +472,7 @@ FLAGS --parentFolderId= parent folder id --readPermission= set note permission: owner, signed_in, guest --sort= property to sort by (prepend '-' for descending) + --tags= set note tags, comma-separated (e.g. tag1,tag2) --title= new note title --writePermission= set note permission: owner, signed_in, guest @@ -515,25 +516,34 @@ EXAMPLES ## `hackmd-cli notes update` -Update note content +Update note ``` USAGE - $ hackmd-cli notes update [--content ] [-h] [--noteId ] [--parentFolderId ] + $ hackmd-cli notes update [--content ] [-h] [--noteId ] [--parentFolderId ] [--permalink ] + [--readPermission ] [--tags ] [--writePermission ] FLAGS - -h, --help Show CLI help. - --content= new note content - --noteId= HackMD note id - --parentFolderId= parent folder id + -h, --help Show CLI help. + --content= new note content + --noteId= HackMD note id + --parentFolderId= parent folder id + --permalink= note permalink + --readPermission= set note permission: owner, signed_in, guest + --tags= set note tags, comma-separated (e.g. tag1,tag2) + --writePermission= set note permission: owner, signed_in, guest DESCRIPTION - Update note content + Update note EXAMPLES $ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --content='# A new title' $ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --parentFolderId=fc7a3d48-4a07-4cbf-bf4f-e65dd896e01c --content='# A new title' + + $ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --readPermission=owner --writePermission=owner + + $ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --tags=tag1,tag2 ``` ## `hackmd-cli team-folders` @@ -719,8 +729,9 @@ Create a team note ``` USAGE $ hackmd-cli team-notes create [--commentPermission ] [--content ] [-e] [-h] [--parentFolderId ] - [--readPermission ] [--teamPath ] [--title ] [--writePermission ] [--columns | - -x] [--sort ] [--filter ] [--output csv|json|yaml | | [--csv | --no-truncate]] [--no-header | ] + [--readPermission ] [--tags ] [--teamPath ] [--title ] [--writePermission ] + [--columns | -x] [--sort ] [--filter ] [--output csv|json|yaml | | [--csv | --no-truncate]] + [--no-header | ] FLAGS -e, --editor create note with $EDITOR @@ -738,6 +749,7 @@ FLAGS --parentFolderId= parent folder id --readPermission= set note permission: owner, signed_in, guest --sort= property to sort by (prepend '-' for descending) + --tags= set note tags, comma-separated (e.g. tag1,tag2) --teamPath= HackMD team path --title= new note title --writePermission= set note permission: owner, signed_in, guest @@ -783,27 +795,35 @@ EXAMPLES ## `hackmd-cli team-notes update` -Update team note content +Update team note ``` USAGE - $ hackmd-cli team-notes update [--content ] [-h] [--noteId ] [--parentFolderId ] [--teamPath - ] + $ hackmd-cli team-notes update [--content ] [-h] [--noteId ] [--parentFolderId ] + [--permalink ] [--readPermission ] [--tags ] [--teamPath ] [--writePermission ] FLAGS - -h, --help Show CLI help. - --content= new note content - --noteId= HackMD note id - --parentFolderId= parent folder id - --teamPath= HackMD team path + -h, --help Show CLI help. + --content= new note content + --noteId= HackMD note id + --parentFolderId= parent folder id + --permalink= note permalink + --readPermission= set note permission: owner, signed_in, guest + --tags= set note tags, comma-separated (e.g. tag1,tag2) + --teamPath= HackMD team path + --writePermission= set note permission: owner, signed_in, guest DESCRIPTION - Update team note content + Update team note EXAMPLES $ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --content='# A new title' $ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --parentFolderId=fc7a3d48-4a07-4cbf-bf4f-e65dd896e01c --content='# A new title' + + $ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --readPermission=owner --writePermission=owner + + $ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --tags=tag1,tag2 ``` ## `hackmd-cli teams` diff --git a/src/commands/notes/create.ts b/src/commands/notes/create.ts index d0e9e91..f81f065 100644 --- a/src/commands/notes/create.ts +++ b/src/commands/notes/create.ts @@ -13,6 +13,7 @@ import { editor, noteContent, notePermission, + noteTags, noteTitle, parentFolderId, } from '../../flags' @@ -47,6 +48,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n help: Flags.help({char: 'h'}), parentFolderId, readPermission: notePermission, + tags: noteTags, title: noteTitle, writePermission: notePermission, ...ux.table.flags(), @@ -56,7 +58,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n const {flags} = await this.parse(CreateCommand) const pipeString = safeStdinRead() - const options: CreateNoteOptions = { + const options: CreateNoteOptions & {tags?: string[]} = { commentPermission: flags.commentPermission as CommentPermissionType, content: pipeString || flags.content, parentFolderId: flags.parentFolderId, @@ -65,6 +67,10 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n writePermission: flags.writePermission as NotePermissionRole, } + if (flags.tags !== undefined) { + options.tags = flags.tags.split(',').map((t: string) => t.trim()).filter(Boolean) + } + if (flags.editor) { try { const mdFile = temporaryMD() @@ -78,7 +84,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n try { const APIClient = await this.getAPIClient() - const note = await APIClient.createNote(options) + const note = await APIClient.createNote(options as CreateNoteOptions) ux.table( [note], @@ -86,6 +92,9 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n id: { header: 'ID', }, + tags: { + get: row => (row.tags ?? []).join(', '), + }, teamPath: { header: 'Team path', }, diff --git a/src/commands/notes/index.ts b/src/commands/notes/index.ts index e719c83..d42cc1f 100644 --- a/src/commands/notes/index.ts +++ b/src/commands/notes/index.ts @@ -28,6 +28,9 @@ raUuSTetT5uQbqQfLnz9lA CLI test note gvfz2UB5THiKABQJQnLs6Q n id: { header: 'ID', }, + tags: { + get: row => (row.tags ?? []).join(', '), + }, teamPath: { header: 'Team Path', }, diff --git a/src/commands/notes/update.ts b/src/commands/notes/update.ts index 17a30aa..e5b73e1 100644 --- a/src/commands/notes/update.ts +++ b/src/commands/notes/update.ts @@ -1,41 +1,53 @@ -import type {UpdateNoteOptions} from '@hackmd/api' +import type {NotePermissionRole, UpdateNoteOptions} from '@hackmd/api' import {Flags} from '@oclif/core' import HackMDCommand from '../../command' -import {noteContent, noteId, parentFolderId} from '../../flags' +import { + noteContent, noteId, notePermission, noteTags, parentFolderId, permalink, +} from '../../flags' export default class Update extends HackMDCommand { - static description = 'Update note content' + static description = 'Update note' static examples = [ "$ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --content='# A new title'", "$ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --parentFolderId=fc7a3d48-4a07-4cbf-bf4f-e65dd896e01c --content='# A new title'", + '$ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --readPermission=owner --writePermission=owner', + '$ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --tags=tag1,tag2', ] static flags = { content: noteContent, help: Flags.help({char: 'h'}), noteId, parentFolderId, + permalink, + readPermission: notePermission, + tags: noteTags, + writePermission: notePermission, } async run() { const {flags} = await this.parse(Update) - const {content, noteId, parentFolderId} = flags + const {content, noteId, parentFolderId, permalink, readPermission, tags, writePermission} = flags if (!noteId) { this.error('Flag noteId could not be empty') } - const payload: UpdateNoteOptions = { - content, - parentFolderId, - } + const payload: UpdateNoteOptions & {tags?: string[]} = {} + + if (content !== undefined) payload.content = content + if (parentFolderId !== undefined) payload.parentFolderId = parentFolderId + if (readPermission !== undefined) payload.readPermission = readPermission as NotePermissionRole + if (writePermission !== undefined) payload.writePermission = writePermission as NotePermissionRole + if (permalink !== undefined) payload.permalink = permalink + if (tags !== undefined) payload.tags = tags.split(',').map((t: string) => t.trim()).filter(Boolean) try { const APIClient = await this.getAPIClient() - await APIClient.updateNote(noteId, payload) + await APIClient.updateNote(noteId, payload as UpdateNoteOptions) } catch (error) { - this.log('Update note content failed') + this.log('Update note failed') this.error(error as Error) } } diff --git a/src/commands/team-notes/create.ts b/src/commands/team-notes/create.ts index 8178927..d0a76bd 100644 --- a/src/commands/team-notes/create.ts +++ b/src/commands/team-notes/create.ts @@ -5,7 +5,7 @@ import fs from 'node:fs' import HackMDCommand from '../../command' import { - commentPermission, editor, noteContent, notePermission, noteTitle, parentFolderId, teamPath, + commentPermission, editor, noteContent, notePermission, noteTags, noteTitle, parentFolderId, teamPath, } from '../../flags' import {openEditor} from '../../open-editor' import {safeStdinRead, temporaryMD} from '../../utils' @@ -38,6 +38,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n help: Flags.help({char: 'h'}), parentFolderId, readPermission: notePermission, + tags: noteTags, teamPath, title: noteTitle, writePermission: notePermission, @@ -48,8 +49,8 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n const {flags} = await this.parse(Create) const pipeString = safeStdinRead() - const {commentPermission, content, parentFolderId, readPermission, teamPath, title, writePermission} = flags - const options: CreateNoteOptions = { + const {commentPermission, content, parentFolderId, readPermission, tags, teamPath, title, writePermission} = flags + const options: CreateNoteOptions & {tags?: string[]} = { commentPermission: commentPermission as CommentPermissionType, content: pipeString || content, parentFolderId, @@ -58,6 +59,10 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n writePermission: writePermission as NotePermissionRole, } + if (tags !== undefined) { + options.tags = tags.split(',').map((t: string) => t.trim()).filter(Boolean) + } + if (!teamPath) { this.error('Flag teamPath could not be empty') } @@ -75,12 +80,15 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n try { const APIClient = await this.getAPIClient() - const note = await APIClient.createTeamNote(teamPath, options) + const note = await APIClient.createTeamNote(teamPath, options as CreateNoteOptions) ux.table([note], { id: { header: 'ID', }, + tags: { + get: row => (row.tags ?? []).join(', '), + }, teamPath: { header: 'Team path', }, diff --git a/src/commands/team-notes/index.ts b/src/commands/team-notes/index.ts index 34c9e82..fb8e7c9 100644 --- a/src/commands/team-notes/index.ts +++ b/src/commands/team-notes/index.ts @@ -33,6 +33,9 @@ BnC6gN0_TfStV2KKmPPXeg Welcome to your team's workspace null CLI-test`, id: { header: 'ID', }, + tags: { + get: row => (row.tags ?? []).join(', '), + }, teamPath: { header: 'Team path', }, diff --git a/src/commands/team-notes/update.ts b/src/commands/team-notes/update.ts index 9683772..fa2d686 100644 --- a/src/commands/team-notes/update.ts +++ b/src/commands/team-notes/update.ts @@ -1,29 +1,35 @@ -import type {UpdateNoteOptions} from '@hackmd/api' +import type {NotePermissionRole, UpdateNoteOptions} from '@hackmd/api' import {Flags} from '@oclif/core' import HackMDCommand from '../../command' import { - noteContent, noteId, parentFolderId, teamPath, + noteContent, noteId, notePermission, noteTags, parentFolderId, permalink, teamPath, } from '../../flags' export default class Update extends HackMDCommand { - static description = 'Update team note content' + static description = 'Update team note' static examples = [ "$ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --content='# A new title'", "$ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --parentFolderId=fc7a3d48-4a07-4cbf-bf4f-e65dd896e01c --content='# A new title'", + '$ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --readPermission=owner --writePermission=owner', + '$ hackmd-cli team-notes update --teamPath=CLI-test --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --tags=tag1,tag2', ] static flags = { content: noteContent, help: Flags.help({char: 'h'}), noteId, parentFolderId, + permalink, + readPermission: notePermission, + tags: noteTags, teamPath, + writePermission: notePermission, } async run() { const {flags} = await this.parse(Update) - const {content, noteId, parentFolderId, teamPath} = flags + const {content, noteId, parentFolderId, permalink, readPermission, tags, teamPath, writePermission} = flags if (!teamPath) { this.error('Flag teamPath could not be empty') @@ -33,16 +39,20 @@ export default class Update extends HackMDCommand { this.error('Flag noteId could not be empty') } - const payload: UpdateNoteOptions = { - content, - parentFolderId, - } + const payload: UpdateNoteOptions & {tags?: string[]} = {} + + if (content !== undefined) payload.content = content + if (parentFolderId !== undefined) payload.parentFolderId = parentFolderId + if (readPermission !== undefined) payload.readPermission = readPermission as NotePermissionRole + if (writePermission !== undefined) payload.writePermission = writePermission as NotePermissionRole + if (permalink !== undefined) payload.permalink = permalink + if (tags !== undefined) payload.tags = tags.split(',').map((t: string) => t.trim()).filter(Boolean) try { const APIClient = await this.getAPIClient() - await APIClient.updateTeamNote(teamPath, noteId, payload) + await APIClient.updateTeamNote(teamPath, noteId, payload as UpdateNoteOptions) } catch (error) { - this.log('Update team note content failed') + this.log('Update team note failed') this.error(error as Error) } } diff --git a/src/flags.ts b/src/flags.ts index 6915942..07382f6 100644 --- a/src/flags.ts +++ b/src/flags.ts @@ -51,6 +51,14 @@ export const commentPermission = Flags.string({ description: 'set comment permission: disabled, forbidden, owners, signed_in_users, everyone', }) +export const permalink = Flags.string({ + description: 'note permalink', +}) + +export const noteTags = Flags.string({ + description: 'set note tags, comma-separated (e.g. tag1,tag2)', +}) + export const editor = Flags.boolean({ char: 'e', description: 'create note with $EDITOR',