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 c43264b..2db6e92 100644 --- a/README.md +++ b/README.md @@ -307,7 +307,7 @@ Create a note ``` USAGE $ hackmd-cli notes create [--commentPermission ] [--content ] [-e] [-h] [--readPermission ] - [--title ] [--writePermission ] [--columns | -x] [--sort ] [--filter ] [--output + [--tags ] [--title ] [--writePermission ] [--columns | -x] [--sort ] [--filter ] [--output csv|json|yaml | | [--csv | --no-truncate]] [--no-header | ] FLAGS @@ -325,6 +325,7 @@ FLAGS --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 @@ -334,9 +335,9 @@ DESCRIPTION EXAMPLES notes create --content='# A new note' --readPermission=owner --writePermission=owner --commentPermission=disabled - ID Title User Path Team Path - ────────────────────── ──────────────────────────────── ────────────────────── ──────── - raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null + ID Title Tags User Path Team Path + ────────────────────── ──────────────────────────────── ──────── ────────────────────── ──────── + raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null Or you can pipe content via Unix pipeline: @@ -364,22 +365,30 @@ EXAMPLES ## `hackmd-cli notes update` -Update note content +Update note ``` USAGE - $ hackmd-cli notes update [--content ] [-h] [--noteId ] + $ hackmd-cli notes update [--content ] [-h] [--noteId ] [--permalink ] [--readPermission ] [--tags ] [--writePermission ] FLAGS - -h, --help Show CLI help. - --content= new note content - --noteId= HackMD note id + -h, --help Show CLI help. + --content= new note content + --noteId= HackMD note 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 --readPermission=owner --writePermission=owner + + $ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --tags=tag1,tag2 ``` ## `hackmd-cli team-notes` @@ -424,7 +433,7 @@ Create a team note ``` USAGE $ hackmd-cli team-notes create [--commentPermission ] [--content ] [-e] [-h] [--readPermission ] - [--teamPath ] [--title ] [--writePermission ] [--columns | -x] [--sort ] + [--tags ] [--teamPath ] [--title ] [--writePermission ] [--columns | -x] [--sort ] [--filter ] [--output csv|json|yaml | | [--csv | --no-truncate]] [--no-header | ] FLAGS @@ -442,6 +451,7 @@ FLAGS --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 @@ -451,9 +461,9 @@ DESCRIPTION EXAMPLES team-notes:create --teamPath=CLI-test --content='# A new note' --readPermission=owner --writePermission=owner --commentPermission=disabled - ID Title User Path Team Path - ────────────────────── ──────────────────────────────── ────────────────────── ──────── - raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null + ID Title Tags User Path Team Path + ────────────────────── ──────────────────────────────── ──────── ────────────────────── ──────── + raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null Or you can pipe content via Unix pipeline: @@ -482,23 +492,31 @@ EXAMPLES ## `hackmd-cli team-notes update` -Update team note content +Update team note ``` USAGE - $ hackmd-cli team-notes update [--content ] [-h] [--noteId ] [--teamPath ] + $ hackmd-cli team-notes update [--content ] [-h] [--noteId ] [--permalink ] [--readPermission ] [--tags ] [--teamPath ] [--writePermission ] FLAGS - -h, --help Show CLI help. - --content= new note content - --noteId= HackMD note id - --teamPath= HackMD team path + -h, --help Show CLI help. + --content= new note content + --noteId= HackMD note 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 --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 f8f3ac9..2de771f 100644 --- a/src/commands/notes/create.ts +++ b/src/commands/notes/create.ts @@ -12,6 +12,7 @@ import { editor, noteContent, notePermission, + noteTags, noteTitle, } from '../../flags' import {openEditor} from '../../open-editor' @@ -22,9 +23,9 @@ export default class CreateCommand extends HackMDCommand { static examples = [ "notes create --content='# A new note' --readPermission=owner --writePermission=owner --commentPermission=disabled", - `ID Title User Path Team Path -────────────────────── ──────────────────────────────── ────────────────────── ──────── -raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null`, + `ID Title Tags User Path Team Path +────────────────────── ──────────────────────────────── ──────── ────────────────────── ──────── +raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null`, 'Or you can pipe content via Unix pipeline:', 'cat README.md | hackmd-cli notes create', @@ -35,6 +36,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q editor, help: Flags.help({char: 'h'}), readPermission: notePermission, + tags: noteTags, title: noteTitle, writePermission: notePermission, ...ux.table.flags(), @@ -44,7 +46,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q 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, readPermission: flags.readPermission as NotePermissionRole, @@ -52,6 +54,10 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q 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() @@ -65,7 +71,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q try { const APIClient = await this.getAPIClient() - const note = await APIClient.createNote(options) + const note = await APIClient.createNote(options as CreateNoteOptions) ux.table( [note], @@ -73,6 +79,9 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q 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 5339507..87aa8b2 100644 --- a/src/commands/notes/update.ts +++ b/src/commands/notes/update.ts @@ -1,32 +1,49 @@ +import {NotePermissionRole} from '@hackmd/api/dist/type' import {Flags} from '@oclif/core' import HackMDCommand from '../../command' -import {noteContent, noteId} from '../../flags' +import { + noteContent, noteId, notePermission, noteTags, 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 --readPermission=owner --writePermission=owner', + '$ hackmd-cli notes update --noteId=WNkLM6gkS0Cg2cQ8rv7bYA --tags=tag1,tag2', ] static flags = { content: noteContent, help: Flags.help({char: 'h'}), noteId, + permalink, + readPermission: notePermission, + tags: noteTags, + writePermission: notePermission, } async run() { const {flags} = await this.parse(Update) - const {content, noteId} = flags + const {content, noteId, permalink, readPermission, tags, writePermission} = flags if (!noteId) { this.error('Flag noteId could not be empty') } + const payload: Parameters>['updateNote']>[1] & {tags?: string[]} = {} + + if (content !== undefined) payload.content = content + 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.updateNoteContent(noteId, content) + await APIClient.updateNote(noteId, payload as Parameters>['updateNote']>[1]) } 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 137ac4b..0e0f423 100644 --- a/src/commands/team-notes/create.ts +++ b/src/commands/team-notes/create.ts @@ -4,7 +4,7 @@ import fs from 'node:fs' import HackMDCommand from '../../command' import { - commentPermission, editor, noteContent, notePermission, noteTitle, teamPath, + commentPermission, editor, noteContent, notePermission, noteTags, noteTitle, teamPath, } from '../../flags' import {openEditor} from '../../open-editor' import {safeStdinRead, temporaryMD} from '../../utils' @@ -13,9 +13,9 @@ export default class Create extends HackMDCommand { static description = 'Create a team note' static examples = [ `team-notes:create --teamPath=CLI-test --content='# A new note' --readPermission=owner --writePermission=owner --commentPermission=disabled -ID Title User Path Team Path -────────────────────── ──────────────────────────────── ────────────────────── ──────── -raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null `, +ID Title Tags User Path Team Path +────────────────────── ──────────────────────────────── ──────── ────────────────────── ──────── +raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q null `, 'Or you can pipe content via Unix pipeline:', 'cat README.md | hackmd-cli notes create --teamPath=CLI-test', @@ -26,6 +26,7 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n editor, help: Flags.help({char: 'h'}), readPermission: notePermission, + tags: noteTags, teamPath, title: noteTitle, writePermission: notePermission, @@ -36,8 +37,8 @@ raUuSTetT5uQbqQfLnz9lA A new note gvfz2UB5THiKABQJQnLs6Q n const {flags} = await this.parse(Create) const pipeString = safeStdinRead() - const {commentPermission, content, readPermission, teamPath, title, writePermission} = flags - const options: CreateNoteOptions = { + const {commentPermission, content, readPermission, teamPath, tags, title, writePermission} = flags + const options: CreateNoteOptions & {tags?: string[]} = { commentPermission: commentPermission as CommentPermissionType, content: pipeString || content, readPermission: readPermission as NotePermissionRole, @@ -45,6 +46,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') } @@ -62,12 +67,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 983bd78..0bffc3c 100644 --- a/src/commands/team-notes/update.ts +++ b/src/commands/team-notes/update.ts @@ -1,23 +1,32 @@ +import {NotePermissionRole} from '@hackmd/api/dist/type' import {Flags} from '@oclif/core' import HackMDCommand from '../../command' -import {noteContent, noteId, teamPath} from '../../flags' +import { + noteContent, noteId, notePermission, noteTags, 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 --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, + permalink, + readPermission: notePermission, + tags: noteTags, teamPath, + writePermission: notePermission, } async run() { const {flags} = await this.parse(Update) - const {content, noteId, teamPath} = flags + const {content, noteId, permalink, readPermission, tags, teamPath, writePermission} = flags if (!teamPath) { this.error('Flag teamPath could not be empty') @@ -27,11 +36,19 @@ export default class Update extends HackMDCommand { this.error('Flag noteId could not be empty') } + const payload: Parameters>['updateTeamNote']>[2] & {tags?: string[]} = {} + + if (content !== undefined) payload.content = content + 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.updateTeamNoteContent(teamPath, noteId, content) + await APIClient.updateTeamNote(teamPath, noteId, payload as Parameters>['updateTeamNote']>[2]) } 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 b9a71ae..b21e842 100644 --- a/src/flags.ts +++ b/src/flags.ts @@ -23,6 +23,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',