Recently Deno 1.01 was released. I have been experimenting with Javascript and Node.js for quite a while. However, my experiments with Typescript were very limited. Deno provides a secure runtime for both Javascript and Typescript. This article is related to my experiments with Deno and Typescript for accessing Wikidata. If you have been following some of my past works like WDProp2 or WikiProvenance3, you may have observed that both of these works were developed in vanilla Javascript without any Node.js4 module. However, given the static typing of Typescript, I want to explore it with Deno for accessing Wikidata. And the preliminary development experience went well.
Deno
Installing Deno5 was easy and it could be installed locally in the user environment.
$ curl -fsSL https://deno.land/x/install/install.sh | sh
######################################################################## 100,0%##O#- # ######################################################################## 100,0%
Archive: /home/john/.deno/bin/deno.zip
inflating: deno
Deno was installed successfully to /home/john/.deno/bin/deno
After manually adding the deno
directory to my $HOME/.bashrc
, I could start working with it.
export DENO_INSTALL="/home/john/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"
To ensure that my changes are taken into consideration, I ran
$ source $HOME/.bashrc
At the time of writing, I have the following version of Deno installed.
$ deno --version
deno 1.1.0
v8 8.4.300
typescript 3.9.2
My first Hello World
program was written in the file hello.ts
console.log("Hello World!")
Executing it required the run
option and I could see that the file was compiled and the output can be seen on the terminal.
$ deno run hello.ts
Compile file:///home/john/deno/hello.ts
Hello World!
Thus I am all set for running my Typescript programs with deno
.
Wikidata
My next goal was to make use of simple SPARQL queries and get data from the Wikidata SPARQL endpoint6. For example, the following SPARQL queries would give me 10 human from Wikidata.
SELECT ?item {
?item wdt:P31 wd:Q5
}
LIMIT 10
Deno and Wikidata
Making use of Wikidata SPARQL endpoint, I first wrote the following code fetch.ts
.
const result = await fetch("https://query.wikidata.org/sparql?query=SELECT%20%3Fitem%20%7B%0A%20%20%3Fitem%20wdt%3AP31%20wd%3AQ5%0A%7D%0ALIMIT%2010&format=json");
const data = await result.json();
console.log(data.results)
Continuing with the same style of execution as shown above, a simple deno run
however gave the following errors:
$ deno run fetch.ts
Compile file:///home/john/deno/fetch.ts
error: Uncaught PermissionDenied: network access to "https://query.wikidata.org/sparql?query=SELECT%20%3Fitem%20%7B%0A%20%20%3Fitem%20wdt%3AP31%20wd%3AQ5%0A%7D%0ALIMIT%2010&format=jsn", run again with the --allow-net flag
at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
at Object.sendAsync ($deno$/ops/dispatch_json.ts:98:10)
at async fetch ($deno$/web/fetch.ts:265:27)
at async file:///home/john/contributions/deno/fetch.ts:1:16
This is the interesting part of deno
. Unlike node, deno requires permissions from the user to connect with the internet. Hence the option --allow-net
need to be used with deno run
for running the above
file.
$ deno run --allow-net fetch.ts
{
bindings: [
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q23" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q42" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q76" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q80" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q91" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q157" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q181" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q185" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q186" } },
{ item: { type: "uri", value: "http://www.wikidata.org/entity/Q192" } }
]
}
The next goal is to make use of functions and split the logic of calling Wikidata and printing results separately. First, a function in the file wdqs.ts
is created to query Wikidata and handle proper response or an error. Note
that the function has been declared as asynchronous and it is also declared to be exported, i.e., it can be used in other Typescript files.
export async function query_wikidata(query: string){
let queryresults:object = [];
await fetch(query)
.then(response => {
if (!response.ok) {
throw new Error("Problem in obtaining a response");
}
return response.json();
})
.then(results => {
queryresults = results.results.bindings;
})
.catch(error => {
console.error('Error in calling Wikidata API', error);
});
return (queryresults);
}
Now, this function is imported in another file query.ts
. The first line imports the function query_wikidata()
. In this file, the URL of SPARQL endpoint is passed as an input. And once the result is obtained, the Wikidata
identifiers of different humans are obtained.
import {query_wikidata} from "./wdqs.ts"
let promise = query_wikidata("https://query.wikidata.org/sparql?query=SELECT%20%3Fitem%20%7B%0A%20%20%3Fitem%20wdt%3AP31%20wd%3AQ5%0A%7D%0ALIMIT%2010&format=json")
promise.then(
(result: any) => {
for (let row of result) {
console.log(row.item.value)
}
});
Finally, the new file query.ts
is run using deno
.
$ deno run --allow-net query.ts
Compile file:///home/john/deno/query.ts
http://www.wikidata.org/entity/Q23
http://www.wikidata.org/entity/Q42
http://www.wikidata.org/entity/Q76
http://www.wikidata.org/entity/Q80
http://www.wikidata.org/entity/Q91
http://www.wikidata.org/entity/Q157
http://www.wikidata.org/entity/Q181
http://www.wikidata.org/entity/Q185
http://www.wikidata.org/entity/Q186
http://www.wikidata.org/entity/Q192
I like how deno
asks permissions from the user before running the scripts. There are flags like --allow-read
or --allow-net
that ensures deno
does not access the local filesystem and the
local environment respectively without these flags. The current way of importing functions using URLs (not discussed here) is very interesting. I would like to further explore Typescript and Deno for future Wikidata related projects.