Categories
Groovy

A Groovy approach to npm-gate

Recently the JavaScript community experienced a serious disruption when a developer removed one of his deployed libraries from the central npm server, an event now being referred to as npm-gate. I don’t want to get into the various ethical, moral, or legal issues about that here. Rather, I want to show how trivially the missing functionality can be supplied using Groovy.

The chaos came from a function known as left-pad. All the function does is take a string, a number, and a delimiter, and returns a padded string of the requested length using the supplied delimiter. Here are the examples shown on the home page:

[sourcecode language=”javascript”]
leftpad = require(‘left-pad’)

leftpad(‘foo’, 5)
// => " foo"

leftpad(‘foobar’, 6)
// => "foobar"

leftpad(1, 2, 0)
// => "01"
[/sourcecode]

As you can see, there’s not much to it. The implementation is pretty simple as well:

[sourcecode language=”javascript”]
module.exports = leftpad;

function leftpad (str, len, ch) {
str = String(str);

var i = -1;

if (!ch && ch !== 0) ch = ‘ ‘;

len = len – str.length;

while (++i < len) {
str = ch + str;
}

return str;
}
[/sourcecode]

The Groovy implementation is almost trivially easy, because the Groovy JDK already has a method in the String class called padLeft.

[sourcecode language=”groovy”]
assert ‘foo’.padLeft(5) == ‘ foo’
assert ‘foobar’.padLeft(6) == ‘foobar’
assert ‘1’.padLeft(2, ‘0’) == ’01’
[/sourcecode]

It’s easy enough to make a method out of this:

[sourcecode language=”groovy”]
String leftPad(s, len, ch=’ ‘) {
s.toString().padLeft(len, ch.toString())
}

assert ‘ foo’ == leftPad(‘foo’, 5)
assert ‘foobar’ == leftPad(‘foobar’, 6)
assert ’01’ == leftPad(1, 2, 0)
assert ‘ null’ == leftPad(null, 5)
[/sourcecode]

So far, so good, plus it’s also a nice example of specifying a default parameter in a method.

Of course, providing a function like that to JavaScript developers doesn’t really help, because they can’t invoke it (easily) from JS. Might as well make it a RESTful web service, then. I made a Ratpack app and added a ratpack.groovy script:

[sourcecode language=”groovy”]
import static ratpack.groovy.Groovy.ratpack

ratpack {
handlers {
get() {
String s = request.queryParams.string ?: ‘hello’
String len = request.queryParams.num ?: ‘5’
String delim = request.queryParams.delim ?: ‘ ‘
response.send s.padLeft(len.toInteger(), delim)
}
}
}
[/sourcecode]

All the query parameters are strings by default, but I wanted to make sure they all had values. Thus the series of Elvis operators to provide defaults. Next I went through the simple series of hoops necessary to deploy the app to Heroku, so I can access it using HTTP:

[sourcecode language=”bash”]
> http leftpad.herokuapp.com

hello

> http leftpad.herokuapp.com string==foo num==5

foo

> http leftpad.herokuapp.com string==foobar num==6
foobar

> http leftpad.herokuapp.com string==1 num==2 delim==0

01

[/sourcecode]

To make the HTTP requests, I’m using httpie, which is my standard curl replacement. Feel
You can use curl, or just type a URL like

http://leftpad.herokuapp.com/?string=foo&num=8&delim=x

into a browser to see the results.

Normally at this point I would make some kind of joke lamenting how so many JavaScript developers needed an online, downloaded dependency just to pad a string, but I won’t. After all, coding in JavaScript is its own punishment. I’ll just note that, yet again, Groovy made something trivial that apparently other languages have to work to do.