react-console-emulator
react-console-emulator copied to clipboard
typescript support?
Good job!
I haven’t used TypeScript awfully much, what’s the current bugbear against using this with it? I’d be glad to support it though!
Well, it simply gives this error after following the directions from README:
index.js:1 ERROR in /Users/me/project/pages/admin/queue.tsx
6:22 Could not find a declaration file for module 'react-console-emulator'. '/Users/me/project/node_modules/react-console-emulator/lib/components/Terminal.js' implicitly has an 'any' type.
Try `npm install @types/react-console-emulator` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-console-emulator';`
4 | import { useHarmonicIntervalFn } from 'react-use'
5 | import { Pane, PaneBody, PaneHead } from '@components/admin/PaneView'
> 6 | import Terminal from 'react-console-emulator'
| ^
7 | import * as Space from 'react-spaces'
8 |
9 | const Style = styled.div`
Ah, so I have to provide a type declaration for it, gotcha. I’ll implement that as soon as possible, but if you’re in a rush, you could always monkey-patch it for the time being. Thanks for the report!
Temporary solution for this is creating a declaration.d.ts file in your src folder and declaring a module and exporting the Terminal.
declare module 'react-console-emulator' {
export default Terminal;
}
After some consideration, I'm potentially going to convert this library to TypeScript entirely at some point in the future. However, for now, maintaining duplicate type declarations is not something I'm going to start doing, since I already have one set to maintain with prop-types and maintaining both is just not really all that feasible. You folks using TS will have to get by with declaring custom types for a while to come.
Labeling this issue as deferred for now to kick the can down the road for the eventual TS rewrite. I'll leave it open however.
Hi @linuswillner,
Thanks for the great library! I miss the type definitions and I'd be happy to help to convert the package to TypeScript.
The library seems to be small enough, so it won't take too long to do it and review it. Also, it would allow removing almost all checks from the validateCommands function. I saw the package has tests, so you'll be able to validate everything works as expected.
If you're worried about maintaining both TypeScript types and prop-types, babel-plugin-typescript-to-proptypes would probably help
Please let me know if you're interested in a pull request
For now, if you want to use react-console-emulator in your TypeScript project, you need to write a module declaration yourself. I've already done it, you can reuse my solution.
- Install csstype
- Create a
global.d.tsfile in your project root - Paste the next declaration there
declare module 'react-console-emulator' {
import * as React from 'react';
import * as CSS from 'csstype';
interface OptionProps {
autoFocus: boolean;
dangerMode: boolean;
disableOnProcess: boolean;
noDefaults: boolean;
noAutomaticStdout: boolean;
noHistory: boolean;
noAutoScroll: boolean;
}
interface LabelProps {
welcomeMessage: boolean | string | string[];
promptLabel: string;
errorText: string;
}
interface CommandProps {
commands?: {
description: string;
usage?: string;
fn: () => string;
};
commandCallback?: () => {};
}
export type TerminalProps = CommandProps &
LabelProps &
OptionProps &
StyleProps;
export default class Terminal extends React.Component<TerminalProps, {}> {}
}
Hi @kulyk, thanks for the brilliant suggestions! A few things here.
First of all, I really appreciate the offer to help out in the TypeScript conversion! I’ll be sure to get back to you when that’s relevant - however, I’m currently working on a major overhaul of the library on the v4 branch, and I think it’s best if I complete that overhaul before I start considering the TS conversion, hence (partly) my reasoning to defer the conversion until later.
Second, as for being able to get rid of validateCommands, I do want this library to continue functioning identically in vanilla JavaScript even after it’s converted to TypeScript, meaning that I have to consider keeping those checks if necessary. If it becomes apparent that they can be removed entirely, I will do that in that event. I’ll have to re-evaluate this better later, as explained above.
Lastly, big thanks for the excellent solution recommendation and sharing your typings! I’ll be sure to keep these in mind as well for the future.
Top job there, thanks a bunch.
- Oh, cool! Didn't know about that
- Yes, you're right, it would be a more safe solution for vanilla JS without type checks
Feel free to ping me in this thread later, I'll be happy to help
Any progress on this regards?
I am more than willing to also help out with this endeavor. I already looked at the source code and made webpack build system work with typescript, if you want the code, just ask me.
I think I do but, will I be able to run commands on the node.js backend from a websocket such as socket.io?
@staminna Yes, I'm doing so right now actually.
@staminna Here is the method with a nodejs backend
Server
io.on('connection', (socket: Socket) =>{
socket.on('clear', (params, callback) => {
// send data back to client by using emit
socket.emit('clear');
// broadcasting data to all other connected clients
socket.broadcast.emit('clear');
})
})
Client
class App extends Component<props, state> {
terminal: any = React.createRef();
componentDidMount() {
socket.on("clear", () => {
console.log("recieved clear");
this.terminal.current.clearInput();
this.terminal.current.terminalInput.current.value = "clear";
this.terminal.current.processCommand();
})
}
componentWillUnmount() {
socket.off('clear');
}
render() {
return ...
}
}
If you want to run some code on the node js backend, you can do the following instead. Server
socket.on('pull', (params, callback) => {
console.log("getting pull")
// broadcasting data to all other connected clients
socket.broadcast.emit('pull');
try {
if (fs.existsSync(gitDir)) {
fs.rmSync(gitDir, { recursive: true });
}
fs.mkdirSync(gitDir);
const options = {
baseDir: gitDir,
};
simpleGit(options).clean(CleanOptions.FORCE);
const remote = config.gitRepository;
simpleGit()
.clone(remote)
.then(() => {
socket.emit('stdout', "Successfully pulled " + config.gitBaseDir + " from github");
socket.broadcast.emit('stdout', "Successfully pulled " + config.gitBaseDir + " from github");
}).catch((err) => {
throw err;
});
} catch (error) {
socket.emit('stdout', "Error attempting to pull the repository");
socket.broadcast.emit('stdout', "Error attempting to pull the repository");
}
})
Client
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import constructEcho from 'react-console-emulator/dist/utils/constructEcho';
...
class App extends Component<props, state> {
terminal: any = React.createRef();
componentDidMount() {
socket.on("pull", (gitUrl) => {
console.log("recieved pull");
const commandName = "pull"
this.terminal.current.pushToHistory(commandName)
this.terminal.current.pushToStdout(constructEcho(this.terminal.current.props.promptLabel || '$', commandName, this.terminal.current.props), { isEcho: true })
})
socket.on("stdout", (out) => {
console.log("recieving stdout");
console.log("out: ", out);
this.terminal.current.pushToStdout(out)
})
}
componentWillUnmount() {
socket.off('pull');
socket.off('stdout');
}
commands = {
pull: {
description: 'Does a git pull to update the current repository on server',
fn: () => {
socket.emit("pull");
}
},
}
render() {
return ...
}
}
You can see my attempted implementation in my repository BDOS-Online (name soon to change to BREDOS-Online) under the socket-io branch if you want to look further.
Does react-console-emulator currently support typescript? Is there any latest progress?
@resetsix any javascript code supported in typescript
Check this comment https://github.com/linuswillner/react-console-emulator/issues/416#issuecomment-619490463 I just used it and it works