Skip to content

Commit

Permalink
teach: adjust regexp validator
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 25, 2020
1 parent ba9795d commit 5565ff9
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 62 deletions.
47 changes: 6 additions & 41 deletions packages/plugin-teach/src/database/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Context, extendDatabase, Message } from 'koishi-core'
import { clone, defineProperty, Observed, pick } from 'koishi-utils'
import { Dialogue, DialogueTest } from '../utils'
import { escape } from 'mysql'
import { RegExpError } from '../internal'
import { format } from 'util'
import MysqlDatabase from 'koishi-plugin-mysql/dist/database'

Expand All @@ -12,30 +11,6 @@ declare module 'koishi-core/dist/context' {
}
}

declare module 'koishi-core/dist/plugins/message' {
namespace Message {
export namespace Teach {
let WhitespaceCharset: string
let NonspaceCharset: string
let UnsupportedCharset: string
let UnsupportedWordBoundary: string
let UnsupportedNongreedy: string
let UnsupportedLookaround: string
let UnsupportedNoncapturing: string
let UnsupportedNamedGroup: string
}
}
}

Message.Teach.WhitespaceCharset = '问题中的空白字符会被自动删除,你无需使用 \\s。'
Message.Teach.NonspaceCharset = '问题中的空白字符会被自动删除,请使用 . 代替 \\S。'
Message.Teach.UnsupportedCharset = '目前不支持在正则表达式中使用 \\%s,请使用 [%s] 代替。'
Message.Teach.UnsupportedWordBoundary = '目前不支持在正则表达式中使用单词边界。'
Message.Teach.UnsupportedNongreedy = '目前不支持在正则表达式中使用非捕获组。'
Message.Teach.UnsupportedLookaround = '目前不支持在正则表达式中使用断言。'
Message.Teach.UnsupportedNoncapturing = '目前不支持在正则表达式中使用非捕获组。'
Message.Teach.UnsupportedNamedGroup = '目前不支持在正则表达式中使用具名组。'

extendDatabase<typeof MysqlDatabase>('koishi-plugin-mysql', {
async getDialoguesById(ids, fields) {
if (!ids.length) return []
Expand Down Expand Up @@ -124,32 +99,22 @@ extendDatabase<typeof MysqlDatabase>('koishi-plugin-mysql', ({ listFields }) =>
export default function apply(ctx: Context, config: Dialogue.Config) {
config.validateRegExp = {
onEscapeCharacterSet(start, end, kind, negate) {
// eslint-disable-next-line curly
if (kind === 'space') throw negate
? new RegExpError(Message.Teach.WhitespaceCharset)
: new RegExpError(Message.Teach.NonspaceCharset)
let chars = kind === 'digit' ? '0-9' : '_0-9a-z'
let source = kind === 'digit' ? 'd' : 'w'
if (negate) {
chars = '^' + chars
source = source.toUpperCase()
}
throw new RegExpError(format(Message.Teach.UnsupportedCharset, source, chars))
throw new SyntaxError('unsupported escape character set')
},
onQuantifier(start, end, min, max, greedy) {
if (!greedy) throw new RegExpError(Message.Teach.UnsupportedNongreedy)
if (!greedy) throw new SyntaxError('unsupported non-greedy quantifier')
},
onWordBoundaryAssertion() {
throw new RegExpError(Message.Teach.UnsupportedWordBoundary)
throw new SyntaxError('unsupported word boundary assertion')
},
onLookaroundAssertionEnter() {
throw new RegExpError(Message.Teach.UnsupportedLookaround)
throw new SyntaxError('unsupported lookaround assertion')
},
onGroupEnter() {
throw new RegExpError(Message.Teach.UnsupportedNoncapturing)
throw new SyntaxError('unsupported non-capturing group')
},
onCapturingGroupEnter(start, name) {
if (name) throw new RegExpError(Message.Teach.UnsupportedNamedGroup)
if (name) throw new SyntaxError('unsupported named capturing group')
},
}

Expand Down
25 changes: 5 additions & 20 deletions packages/plugin-teach/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Context, Message } from 'koishi-core'
import { Dialogue } from './utils'
import { update } from './update'
import { RegExpValidator } from 'regexpp'
import { defineProperty, Logger } from 'koishi-utils'
import { defineProperty } from 'koishi-utils'
import { formatQuestionAnswers } from './search'
import { format, types } from 'util'
import { format } from 'util'
import leven from 'leven'

declare module 'koishi-core/dist/plugins/message' {
Expand All @@ -30,14 +30,7 @@ Message.Teach.IllegalRegExp = '问题含有错误的或不支持的正则表达
Message.Teach.MayModifyAnswer = '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。'
Message.Teach.MaybeRegExp = '推测你想%s的问题是正则表达式。发送空行或句号以添加 -x 选项,使用 -i 选项以忽略本提示。'

export class RegExpError extends Error {
name = 'RegExpError'
}

const validator = new RegExpValidator()

export default function apply(ctx: Context, config: Dialogue.Config) {
const logger = new Logger('teach')
defineProperty(ctx.app, 'teachHistory', {})

ctx.command('teach')
Expand Down Expand Up @@ -86,6 +79,8 @@ export default function apply(ctx: Context, config: Dialogue.Config) {
return question.startsWith('^') || question.endsWith('$')
}

const validator = new RegExpValidator(config.validateRegExp)

ctx.on('dialogue/before-modify', async (argv) => {
const { options, session, target, dialogues } = argv
const { question, answer, ignoreHint, regexp } = options
Expand Down Expand Up @@ -121,17 +116,7 @@ export default function apply(ctx: Context, config: Dialogue.Config) {
try {
questions.map(q => validator.validatePattern(q))
} catch (error) {
if (!types.isNativeError(error)) {
logger.warn(question, error)
return Message.Teach.IllegalRegExp
} else if (error.name === 'RegExpError') {
return error.message
} else {
if (!error.message.startsWith('SyntaxError')) {
logger.warn(question, error.stack)
}
return Message.Teach.IllegalRegExp
}
return Message.Teach.IllegalRegExp
}
}
})
Expand Down
4 changes: 3 additions & 1 deletion packages/plugin-teach/tests/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ describe('koishi-plugin-teach', () => {
await session1.shouldHaveReply('# foo bar', '问答已存在,编号为 1,如要修改请尝试使用 #1 指令。')
await session1.shouldHaveReply('# foo bar -P 1', '修改了已存在的问答,编号为 1。')
await session1.shouldHaveReply('#1 -P 1', '问答 1 没有发生改动。')
await session1.shouldHaveReply('#1 ~ baz', '问答 1 已成功修改。')
await session1.shouldHaveReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。')
await session1.shouldHaveReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。')
await session1.shouldHaveReply('.', '问答 1 已成功修改。')
await session1.shouldHaveReply('foo', 'baz')
})

Expand Down

0 comments on commit 5565ff9

Please sign in to comment.