Update ShellDirective to use ts-node interpreter by default
This commit is contained in:
parent
710b6cb535
commit
b8cf8499d2
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@extollo/lib",
|
"name": "@extollo/lib",
|
||||||
"version": "0.13.3",
|
"version": "0.13.4",
|
||||||
"description": "The framework library that lifts up your code.",
|
"description": "The framework library that lifts up your code.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
import {Directive} from '../Directive'
|
import {Directive, OptionDefinition} from '../Directive'
|
||||||
import * as colors from 'colors/safe'
|
import * as colors from 'colors/safe'
|
||||||
import * as repl from 'repl'
|
import * as repl from 'repl'
|
||||||
import {DependencyKey} from '../../di'
|
import * as tsNode from 'ts-node'
|
||||||
|
import {globalRegistry} from '../../util'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch an interactive REPL shell from within the application.
|
* Launch an interactive REPL shell from within the application.
|
||||||
* This is very useful for debugging and testing things during development.
|
* This is very useful for debugging and testing things during development.
|
||||||
|
*
|
||||||
|
* By default, the shell launches a TypeScript interpreter, but you can use
|
||||||
|
* the `--js` flag to get a JavaScript interpreter.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```sh
|
||||||
|
* pnpm cli -- shell
|
||||||
|
* pnpm cli -- shell --js
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
export class ShellDirective extends Directive {
|
export class ShellDirective extends Directive {
|
||||||
protected options: any = {
|
protected options: any = {
|
||||||
welcome: `powered by Extollo, © ${(new Date()).getFullYear()} Garrett Mills\nAccess your application using the "app" global.`,
|
welcome: `powered by Extollo, © ${(new Date()).getFullYear()} Garrett Mills\nAccess your application using the "app" global and @extollo/lib using the "lib" global.`,
|
||||||
prompt: `${colors.blue('(')}extollo${colors.blue(') ➤ ')}`,
|
prompt: `${colors.blue('(')}extollo${colors.blue(') ➤ ')}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,17 +41,57 @@ export class ShellDirective extends Directive {
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOptions(): OptionDefinition[] {
|
||||||
|
return [
|
||||||
|
'--js | launch in JavaScript mode instead of TypeScript',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
async handle(): Promise<void> {
|
async handle(): Promise<void> {
|
||||||
const state: any = {
|
const state: any = {
|
||||||
|
globalRegistry,
|
||||||
app: this.app(),
|
app: this.app(),
|
||||||
lib: await import('../../index'),
|
lib: await import('../../index'),
|
||||||
make: (target: DependencyKey, ...parameters: any[]) => this.make(target, ...parameters),
|
exports: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>(res => {
|
await new Promise<void>(res => {
|
||||||
|
// Currently, there's no way to programmatically access the async context
|
||||||
|
// of the REPL from this directive w/o requiring the user to perform manual
|
||||||
|
// actions. So, instead, override the context on the GlobalRegistry to make
|
||||||
|
// the current one the global default.
|
||||||
|
globalRegistry.forceContextOverride()
|
||||||
|
|
||||||
|
// Create the ts-node compiler service.
|
||||||
|
const replService = tsNode.createRepl()
|
||||||
|
const service = tsNode.create({...replService.evalAwarePartialHost})
|
||||||
|
replService.setService(service)
|
||||||
|
|
||||||
|
// We global these values into the REPL's state directly (using the `state` object
|
||||||
|
// above), but since we're using a separate ts-node interpreter, we need to make it
|
||||||
|
// aware of the globals using declaration syntax.
|
||||||
|
replService.evalCode(`
|
||||||
|
declare const lib: typeof import('@extollo/lib');
|
||||||
|
declare const app: typeof lib['Application'];
|
||||||
|
declare const globalRegistry: typeof lib['globalRegistry'];
|
||||||
|
`)
|
||||||
|
|
||||||
|
// Print the welome message and start the interpreter
|
||||||
this.nativeOutput(this.options.welcome)
|
this.nativeOutput(this.options.welcome)
|
||||||
this.repl = repl.start(this.options.prompt)
|
this.repl = repl.start({
|
||||||
|
// Causes the REPL to use the ts-node interpreter service:
|
||||||
|
eval: !this.option('js', false) ? (...args) => replService.nodeEval(...args) : undefined,
|
||||||
|
prompt: this.options.prompt,
|
||||||
|
useGlobal: true,
|
||||||
|
useColors: true,
|
||||||
|
terminal: true,
|
||||||
|
preview: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add our globals into the REPL's context
|
||||||
Object.assign(this.repl.context, state)
|
Object.assign(this.repl.context, state)
|
||||||
|
|
||||||
|
// Wait for the REPL to exit
|
||||||
this.repl.on('exit', () => res())
|
this.repl.on('exit', () => res())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user