Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typescript support? #416

Open
18601673727 opened this issue Nov 29, 2019 · 16 comments
Open

typescript support? #416

18601673727 opened this issue Nov 29, 2019 · 16 comments
Assignees
Labels
deferred Kicking the can down the road to a future update

Comments

@18601673727
Copy link

Good job!

@linuswillner
Copy link
Owner

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!

@18601673727
Copy link
Author

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`

@linuswillner
Copy link
Owner

linuswillner commented Nov 30, 2019

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!

@linuswillner linuswillner added the enhancement New feature or request label Nov 30, 2019
@linuswillner linuswillner self-assigned this Nov 30, 2019
@Fronix
Copy link

Fronix commented Mar 6, 2020

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;
}

@linuswillner
Copy link
Owner

linuswillner commented Apr 22, 2020

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.

@linuswillner linuswillner added deferred Kicking the can down the road to a future update and removed enhancement New feature or request labels Apr 22, 2020
@kulyk
Copy link

kulyk commented Apr 26, 2020

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

@kulyk
Copy link

kulyk commented Apr 26, 2020

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.

  1. Install csstype
  2. Create a global.d.ts file in your project root
  3. 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, {}> {}
}

@linuswillner
Copy link
Owner

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.

@kulyk
Copy link

kulyk commented Apr 26, 2020

  1. Oh, cool! Didn't know about that
  2. 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

@staminna
Copy link

Any progress on this regards?

@BjornTheProgrammer
Copy link

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.

@staminna
Copy link

I think I do but, will I be able to run commands on the node.js backend from a websocket such as socket.io?

@BjornTheProgrammer
Copy link

BjornTheProgrammer commented Aug 23, 2022

@staminna Yes, I'm doing so right now actually.

@BjornTheProgrammer
Copy link

BjornTheProgrammer commented Aug 23, 2022

@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.

@resetsix
Copy link

Does react-console-emulator currently support typescript? Is there any latest progress?

@im7mortal
Copy link

im7mortal commented May 24, 2024

@resetsix any javascript code supported in typescript

Check this comment
#416 (comment)
I just used it and it works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deferred Kicking the can down the road to a future update
Projects
None yet
Development

No branches or pull requests

8 participants