diff --git a/packages/plugin-eval/package.json b/packages/plugin-eval/package.json index 1fd64c98bb..af5f5068b7 100644 --- a/packages/plugin-eval/package.json +++ b/packages/plugin-eval/package.json @@ -38,7 +38,8 @@ "optionalDependencies": { "esbuild": "^0.11.6", "json5": "^2.2.0", - "typescript": "^4.2.3" + "typescript": "^4.2.3", + "coffeescript": "^2.5.1" }, "dependencies": { "esbuild": "^0.11.6", diff --git a/packages/plugin-eval/src/loaders/coffeescript.ts b/packages/plugin-eval/src/loaders/coffeescript.ts new file mode 100644 index 0000000000..929df08ec9 --- /dev/null +++ b/packages/plugin-eval/src/loaders/coffeescript.ts @@ -0,0 +1,22 @@ +const { compile } = require('coffeescript') + +export const name = 'coffeescript' + +export function extractScript(expr: string) { + try { + compile(expr) + } catch (e) { + if (e.message !== 'unmatched }') throw e + const location = e.location + const sLines = expr.split('\n') + const row = location.first_line + const column = location.first_column - 1 + return [...sLines.slice(0, row - 1), sLines[row].slice(0, column + 1)].join('\n') + } +} + +export async function transformScript(expr: string) { + return compile(expr, { bare: true }) +} + +export const transformModule = transformScript diff --git a/packages/plugin-eval/src/worker/loader.ts b/packages/plugin-eval/src/worker/loader.ts index 5d3015547b..6422c32680 100644 --- a/packages/plugin-eval/src/worker/loader.ts +++ b/packages/plugin-eval/src/worker/loader.ts @@ -42,7 +42,7 @@ export function synthetize(identifier: string, namespace: {}, globalName?: strin return module } -const extnames = new Set(['.js', '.ts', '.json', '.yml', '.yaml']) +const extnames = new Set(['.js', '.ts', '.coffee', '.json', '.yml', '.yaml']) function* suffixes() { yield '' @@ -168,6 +168,12 @@ function resolveLoader(extension: string) { } catch {} } throw new Error('cannot resolve loader for ".ts", you should install either esbuild or typescript + json5 by yourself') + } else if (extension === '.coffee') { + try { + return require('../loaders/coffeescript') + } catch { + throw new Error('cannot resolve loader for ".coffee", you should install coffeescript by yourself') + } } else { throw new Error(`cannot resolve loader for "${extension}", you should specify a custom loader via "config.moduleLoaders"`) } diff --git a/packages/plugin-eval/tests/fixtures/addon1/foobar.coffee b/packages/plugin-eval/tests/fixtures/addon1/foobar.coffee new file mode 100644 index 0000000000..65e774b934 --- /dev/null +++ b/packages/plugin-eval/tests/fixtures/addon1/foobar.coffee @@ -0,0 +1,3 @@ +import bar from './bar.yml' + +export default (index = 1) -> bar[index] diff --git a/packages/plugin-eval/tests/fixtures/addon1/index.ts b/packages/plugin-eval/tests/fixtures/addon1/index.ts index d4e3100e6a..6d506b679e 100644 --- a/packages/plugin-eval/tests/fixtures/addon1/index.ts +++ b/packages/plugin-eval/tests/fixtures/addon1/index.ts @@ -1,8 +1,9 @@ import { registerCommand } from 'koishi/addons' import { foo } from './foo' +import foobar from './foobar' export * from './foo' registerCommand('test', () => { - return foo() + return foo() + foobar() }) diff --git a/packages/plugin-eval/tests/index.spec.ts b/packages/plugin-eval/tests/index.spec.ts index a9309e4539..14bcab2750 100644 --- a/packages/plugin-eval/tests/index.spec.ts +++ b/packages/plugin-eval/tests/index.spec.ts @@ -100,13 +100,20 @@ describe('Eval Loaders', () => { await ses.shouldReply('echo 1${"foo" as string}3', '1foo3') await app.stop() }) + + it('coffeescript', async () => { + const app = await createApp('coffeescript') + const ses = app.session('123') + await ses.shouldReply('echo 1${"foobar"}3', '1foobar3') + await app.stop() + }) }) describe('Eval Addons', () => { it('addon command', async () => { await ses.shouldReply('addon', /^addon\n扩展功能/) await ses.shouldReply('test -h', 'test\n测试功能') - await ses.shouldReply('test', 'bar') + await ses.shouldReply('test', 'barbaz') }) it('sandbox injection', async () => {