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.

One response to “A Groovy approach to npm-gate”

  1. Great writeup, Ken! 😄

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.