Check out a free preview of the full Polyglot Programming: TypeScript, Go, & Rust course
The "Using the Projector CLI in TypeScript" Lesson is part of the full, Polyglot Programming: TypeScript, Go, & Rust course featured in this preview video. Here's what you'd learn in this lesson:
ThePrimeagen walks through setting up and using the TypeScript Projector CLI built throughout this course. Retrieving the options and projector, saving the config, and implementing the previously created operations are covered in this segment.
Transcript from the "Using the Projector CLI in TypeScript" Lesson
[00:00:00]
>> So let's keep on going with the delicious presentation right now, which is we're gonna tie everything all together. We've created the get, the set, the remove, and the get all in all three languages. We have our main file. Now, all we need to do is just one at a time, do that simple tying of everything together.
[00:00:17]
So let's do that. It should be pretty easy, we'll start off with TypeScript. And we're gonna go to our index.html. So right now, all we do in this file is just get the options. So let's fix that, right? Let's go const-opts =, get those delicious options, right? Config, of course, is getConfig, I believe is what it's called.
[00:00:41]
getConfig, yeah, it is, it's definitely called that. Awesome, and we're also gonna need the projector. And we're also from the config gonna want Operation, I'm just kinda filling in things ahead of time, projector, awesome. So we kinda have all the things we need right now, we got the config, but the config, of course, takes in the options, we now have that.
[00:01:03]
Everything's only been unit tested, so we actually haven't ran this program yet. So will we successfully do this? This is real first try territory here. All right, so of course, what is our config? Capital C Config. So let's create a projector const proj = Projector.fromConfig. So now we're actually using the thing we didn't test, which is reading it from a file.
[00:01:29]
And so let's pass in our config, beautiful. And now, we have a type projector, awesome. So now we can do the operation on it, I'm not gonna get too clever for this operation, we only have three operations available. So we can either use a switch or if statements, I don't think we need to get much beyond that.
[00:01:45]
So let's of course just go like this, if(config). Hopefully, by the way, have you guys spotted where Rust is gonna blow up yet? Is your Rust power starting to get better? The Rust power, the power of Rust. It's kind of like the power of friendship, just less awesome.
[00:02:08]
All right, here we go, Operation, let's go Print. There we go, all right?. So let's see, if we have a print operation there's two modes we have to do, are there arguments or they're not arguments, correct? If there's arguments, we do get value, if there isn't arguments, we do get value all.
[00:02:27]
So let's go like this, config.args = 0. That's a seven, that's definitely not the number we want. So if it equals 0, we can do something simple and go console.log(JSON.stringify proj.getValueAll. My goodness, got all the correct amount of parentheses. Else, I really hate if-elses by the way, else we have to log out if there is a value found.
[00:03:00]
So of course, value =proj.getValue, pass in the key, which is gonna of course be config.args[0]. if(value), cuz remember, value could be a string or undefined. I don't know I didn't say or undefined there, fantastic. So it could be undefined, let's make sure that it's not undefined, and go console.log(value).
[00:03:25]
Perfect, so we've done the official first operation, print. Let's do the next operation, (config.operation === Operation.Add). Move out into the middle, so what do we have to do here? We have to call that simple method, projector.setValue. And then afterwards, we need to save up the file, we haven't yet written the save function.
[00:03:47]
That should be pretty easy to do in all three languages. So let's first start off with setting the value. So we're gonna go, proj.setValue, and then we're gonna go config.args[0], config.args[1], right? Beautiful, we've now set the value, so now I ideally like to just call like this, projector save.
[00:04:09]
So we'll write that here in a moment. For now, let's move on to remove, yank all that. Actually I'm gonna undo that, cuz I should have yarped it. We all know you should have yarped it, it was a beautiful time to do it. The only thing we need to do different now is to go removeValue, remove, and of course, remove that.
[00:04:29]
There we go, we have it done, we now have all three operations done. So what's the last thing we need to do? Write the save function. I feel like the save function is gonna to be pretty darn easy. So let's jump down here and create Save. All right, so let's discuss this.
[00:04:45]
We need to be able to take your config and save it. But there's multiple problems that can happen. Now, if you remember in the beginning when we were doing this yesterday, we did use or at least I used the SDG pathing. Which means that I need to do a folder projector and then a JSON projector, which means that the folder that it is in may not exist.
[00:05:05]
So we need to create. And I could give you just a random path, which means it's gonna need to create a lot of paths potentially. So we can't just simply try to read the file, we're going to have to create all the way there, plus create the file.
[00:05:17]
So couple things there, should be pretty straightforward. So first, we're gonna go like this. We're gonna get the path, or we shouldn't call it a path, because there's a library called path. We'll call it configPath = path, which is the one we want to use, right, dot dirname.
[00:05:37]
So this is the directory name of our file. And we're gonna go like this, we're gonna go dirname(this.config.config, right? I love when it's config.config, nothing is better than that. So there we go. We have everything but the actual projector.JSON here. And we're gonna go like this, if fs existsSync(configPath).
[00:06:02]
Or if it doesn't exist synchronously, then we need to create it. Luckily, fs comes with mkdirSync, and then it has an extra option, you can actually see it right there. Recursive equals true, so it will actually do a mkdir-p. That's what that option is, so fantastic. We can just use this, we can go configPath and recurse: true.
[00:06:28]
There we go, we've created it all the way to that point. And so now, we should probably also do the other way, which is if, we don't have to check to see if the file exists. We can overwrite the file, cuz our new contents is a modified form of our previous contents, correct?
[00:06:44]
So now, all we have to do is go fs.writeFileSync and just do this.config.config, and of course JSON.stringify (this.data), right? And so if we wanted, we could also pretty write it. But in my opinion, you don't really need the pretty right it, cuz you have something like JQ on the command line.
[00:07:09]
So you can just simply grab out your file, pass this to JQ, right? That's good enough, you don't need to actually have it pretty printed. And it's also weird if you're editing things by hand. Got to ask yourself, why am I doing such things? There we go. So now I'm gonna go back here, everything is working, it is looking good.
[00:07:25]
We have finished up our application, let's give it a shot, let's do a little projecting? All right, are you guys a little nervous? I'm a little [INAUDIBLE]. Let's find out what happens here. So let's run index.ts and let's start off by just simply doing an empty projector. It should return us some squirrely braces, and what happens here, we actually completely destroyed.
[00:07:51]
But my guess is it's because we did something silly. We forgot to do, my guess is it's yarn add, I don't even really read the error, types/command-line args. Okay, we have some sort of TypeScript error here. This module is declared using export equal and can only, let's see, it can only be used as the default import when using es Interop flag, fantastic.
[00:08:19]
Okay, so we have this problem, we're doing a default import, we don't have es Interop flag. We've been doing star for the previous one, we should probably just keep on doing star, though it probably at this point would be a better idea not to do that. But, well, sometimes you live with the decisions you've made.
[00:08:37]
There you go, we see the empty thing. [SOUND] Did everyone take a deep breath? We've successfully done it, my goodness, I'm so excited. What about foo? It printed nothing, perfect, right? Because there is no foo right now. Let's add foo bar. It printed nothing, fantastic. That's kind of what we were hoping to see, but I did notice something that's gonna make it hard to check.
[00:09:01]
Where's that file? Well, it's technically in /.config/projector/project.json. And there it is, right? This is my previous file. So we had some issues probably going on with this. So hold on, let me erase that. Let's not use that thing. Let's pass in a config and just go present working directory, conf.json.
[00:09:29]
All right, cat conf.json, there we go, beautiful. Look at that, look at how wonderful that looks. That's exactly what I was hoping to see, which means that I should be able to do a foo now. We see bar, fantastic. We should be able to do an empty one and see it again.
[00:09:49]
Oopsies, My goodness, it just feels so good, right? One last test, we're gonna do the ultimate test here. We're gonna take our present working directory and we're gonna go present working directory tab, expand that, present working directory. And I'm gonna go one back on my directory, and I'm going to add the same thing, add foo baz, right?
[00:10:20]
So now, what do we get here? We see foo bar [SOUND]. Remove foo, see it again. My goodness, it worked, we've done it, we've built the program, first try, all the way through. Look how great unit tests are, everyone should be happy. Yeah, thank you, thank you. [APPLAUSE] My goodness, I can't believe I'm clapping.
[00:10:42]
>> [APPLAUSE]
>> Yeah, okay. [SOUND] All right, we did it.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops