Skip to content

Commit

Permalink
Merge pull request #86 from hereje/feat/migrate-to-esm
Browse files Browse the repository at this point in the history
  • Loading branch information
stefandesu committed Sep 9, 2024
2 parents 8c11f12 + 2ffb1ae commit f6e36f6
Show file tree
Hide file tree
Showing 33 changed files with 409 additions and 362 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js → .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ module.exports = {
extends: ["gbv"],
parserOptions: {
sourceType: "module",
ecmaVersion: 2020,
ecmaVersion: "latest",
},
}
49 changes: 31 additions & 18 deletions bin/wdjskos
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
#!/usr/bin/env node

const program = require("commander")
const { readFileSync } = require("fs")
const { version } = require("../package.json")
const { red } = require("chalk")
const wdk = require("../lib/wdk")
const { WikidataService } = require("../lib/wikidata-wrapper")
const ndjson = require("../lib/ndjson")
const suggest = require("../lib/suggest")
const { loadMappingSchemes, updateMappingSchemes } = require("../lib/mapping-schemes")
const getConcepts = require("../lib/queries/get-concepts")
import { Command } from "commander"
import { readFileSync } from "fs"
import { readFile } from "node:fs/promises"
const pkg = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf-8"))
import chalk from "chalk"
import wdk from "../lib/wdk.js"
import { WikidataService } from "../lib/wikidata-wrapper.js"
import * as ndjson from "../lib/ndjson.js"
import suggest from "../lib/suggest.js"
import { loadMappingSchemes, updateMappingSchemes } from "../lib/mapping-schemes.js"
import getConcepts from "../lib/queries/get-concepts.js"

const program = new Command()

program
.version(version)
.version(pkg.version)
.description("Access Wikidata in JSKOS format")
.option("-l, --lang <lang>", "language(s), comma-separated")
.option("-s, --scheme <id>", "limit mappings to selected scheme")
Expand All @@ -23,8 +26,10 @@ program
// TODO: option to not include subjectOf

const error = (message, showHelp) => {
console.error(red(message))
if (showHelp) { program.help() }
console.error(chalk.red(message))
if (showHelp) {
program.help()
}
process.exit(1)
}

Expand All @@ -40,7 +45,7 @@ function conceptCommand (ids) {

getMappingSchemes()
.then(schemes => new WikidataService(schemes))
.then(service => getConcepts({ uri: ids.join("|"), language }))
.then(() => getConcepts({ uri: ids.join("|"), language }))
.then(ndjson.write)
}

Expand All @@ -59,8 +64,12 @@ function schemesCommand () {
function mappingsCommand (from, to) {
let direction = program.both || to === undefined ? "both" : "forward"

if (from === "-") from = undefined
if (to === "-") to = undefined
if (from === "-") {
from = undefined
}
if (to === "-") {
to = undefined
}

let languages = program.lang
let toScheme = (from || direction !== "forward") ? program.scheme : null
Expand Down Expand Up @@ -154,9 +163,13 @@ program
program.parse(process.argv)

// Show help by default
if (!program.args.length) program.help()
if (!program.args.length) {
program.help()
}

// Prevent logging an EPIPE error when piping the output
process.stdout.on("error", err => {
if (err.code !== "EPIPE") throw err
if (err.code !== "EPIPE") {
throw err
}
})
32 changes: 22 additions & 10 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
const _ = require("lodash")
require("dotenv").config()
import _ from "lodash"
import dotenv from "dotenv"
import process from "node:process"
import { readFile } from "node:fs/promises"

const fileUrl = new URL("./config.default.json", import.meta.url)
// Load default config
const configDefault = require("./config.default.json")
const configDefault = JSON.parse(await readFile(fileUrl, "utf8"))

dotenv.config()

// Load configuration from environment variables
const configEnvVariables = {
Expand Down Expand Up @@ -30,16 +35,19 @@ const env = configEnvVariables.env
// Load environment config
let configEnv
try {
configEnv = require(`./config.${env}.json`)
} catch(error) {
const fileUrl = new URL(`./config.${env}.json`, import.meta.url)
configEnv = JSON.parse(await readFile(fileUrl, "utf-8"))
} catch (error) {
configEnv = {}
}

// Load user config
let configUser
try {
configUser = require("./config.json")
} catch(error) {
const fileUrl = new URL("./config.json", import.meta.url)
configUser = JSON.parse(await readFile(fileUrl, "utf-8"))

} catch (error) {
configUser = {}
}

Expand All @@ -60,8 +68,12 @@ if (!config.wikibase.api) {

// Set capabilities for clients
// JSKOS API version and server version from package.json
config.version = require("./package.json").apiVersion
config.serverVersion = require("./package.json").version
const fileUrlPkg = new URL("./package.json", import.meta.url)
const pkg = JSON.parse(await readFile(fileUrlPkg, "utf-8"))

config.version = pkg.apiVersion
config.serverVersion = pkg.version

// Concepts (read only)
config.concepts = {
read: {
Expand Down Expand Up @@ -111,4 +123,4 @@ const log = (...args) => {
}
config.log = log

module.exports = config
export default config
6 changes: 3 additions & 3 deletions lib/debug.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require("../config")
const debug = require("debug")
import "../config.js"
import debug from "debug"

module.exports = {
export default {
sparql: message => debug("sparql")(message),
http: message => debug("http")(message),
query: message => debug("query")(message),
Expand Down
40 changes: 25 additions & 15 deletions lib/mappers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* Functions to map Wikidata entities to JSKOS items.
*/

const wdk = require("./wdk")
const { entityTypes } = require("./types")
const wikidata = require("./wikidata")
import wdk from "./wdk.js"
import { entityTypes } from "./types.js"
import wikidata from "./wikidata.js"

function mapIdentifier (id) {
return {
Expand Down Expand Up @@ -147,7 +147,10 @@ function mapSimpleSitelinks (sitelinks) {
subjectOf: Object.keys(sitelinks).map(site => {
try {
return {
url: wdk.getSitelinkUrl(site, sitelinks[site]),
url: wdk.getSitelinkUrl({
site,
title: sitelinks[site],
}),
}
} catch (e) {
// just ignore unkown sites
Expand Down Expand Up @@ -181,24 +184,31 @@ function mapSimpleEntity (entity) {
)
}

module.exports = {
mapSimpleIdentifier: mapIdentifier,
const mapLabels = labels => {
return labels ? mapSimpleLabels(wdk.simplify.labels(labels)) : {}
}
const mapAliases = aliases => mapSimpleAliases(wdk.simplify.aliases(aliases))
const mapDescriptions = descriptions => mapSimpleDescriptions(wdk.simplify.descriptions(descriptions))
const mapClaims = claims => mapSimpleClaims(wdk.simplify.claims(claims))
const mapSitelinks = sitelinks => mapSimpleSitelinks(wdk.simplify.sitelinks(sitelinks))
const mapEntity = entity => mapSimpleEntity(wdk.simplify.entity(entity))

export {
mapIdentifier as mapSimpleIdentifier,
mapSimpleLabels,
mapSimpleAliases,
mapSimpleDescriptions,
mapSimpleClaims,
mapSimpleSitelinks,
mapSimpleInfo: mapInfo,
mapInfo as mapSimpleInfo,
mapSimpleEntity,
mapIdentifier,
mapLabels: labels => {
return labels ? mapSimpleLabels(wdk.simplify.labels(labels)) : {}
},
mapAliases: aliases => mapSimpleAliases(wdk.simplify.aliases(aliases)),
mapDescriptions: descriptions => mapSimpleDescriptions(wdk.simplify.descriptions(descriptions)),
mapClaims: claims => mapSimpleClaims(wdk.simplify.claims(claims)),
mapSitelinks: sitelinks => mapSimpleSitelinks(wdk.simplify.sitelinks(sitelinks)),
mapEntity: entity => mapSimpleEntity(wdk.simplify.entity(entity)),
mapLabels,
mapAliases,
mapDescriptions,
mapClaims,
mapSitelinks,
mapEntity,
mapInfo,
mapMappingClaims,
}
42 changes: 21 additions & 21 deletions lib/mapping-schemes.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
const fs = require("fs")
const path = require("path")
const mkdirp = require("mkdirp")
const ndjson = require("./ndjson")
import fs from "node:fs"
import path, { dirname } from "node:path"
import { fileURLToPath } from "node:url"
import { mkdirp } from "mkdirp"
import * as ndjson from "./ndjson.js"

const getMappingSchemes = require("./queries/get-mapping-schemes")

const cache = path.resolve(__dirname, "../cache")
const assets = path.resolve(__dirname, "../assets")
import getMappingSchemes from "./queries/get-mapping-schemes.js"

module.exports = {
const __dirname = dirname(fileURLToPath(import.meta.url))

updateMappingSchemes() {
mkdirp.sync(cache)
return getMappingSchemes()
.then( schemes => {
ndjson.write(schemes, `${cache}/mapping-schemes.ndjson`)
return schemes
})
},
const cache = path.resolve(__dirname, "../cache")
const assets = path.resolve(__dirname, "../assets")

loadMappingSchemes() {
const cachedSchemes = `${cache}/mapping-schemes.ndjson`
const assetsSchemes = `${assets}/mapping-schemes.ndjson`
return ndjson.read( fs.existsSync(cachedSchemes) ? cachedSchemes : assetsSchemes )
},
export function updateMappingSchemes() {
mkdirp.sync(cache)
return getMappingSchemes()
.then(schemes => {
ndjson.write(schemes, `${cache}/mapping-schemes.ndjson`)
return schemes
})
}

export function loadMappingSchemes() {
const cachedSchemes = `${cache}/mapping-schemes.ndjson`
const assetsSchemes = `${assets}/mapping-schemes.ndjson`
return ndjson.read(fs.existsSync(cachedSchemes) ? cachedSchemes : assetsSchemes)
}
24 changes: 14 additions & 10 deletions lib/ndjson.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
const fs = require("fs")
import fs from "fs"

module.exports = {
read: (file) => {
return fs.readFileSync(file).toString().split(/\n/).filter(s => s).map(JSON.parse)
},
write: (data, file) => {
const stream = file ? fs.createWriteStream(file) : process.stdout
const objects = Array.isArray(data) ? data : [data]
objects.forEach(obj => stream.write(JSON.stringify(obj) + "\n"))
},
const read = (file) => {
return fs.readFileSync(file).toString().split(/\n/).filter(s => s).map(JSON.parse)
}

const write = (data, file) => {
const stream = file ? fs.createWriteStream(file) : process.stdout
const objects = Array.isArray(data) ? data : [data]
objects.forEach(obj => stream.write(JSON.stringify(obj) + "\n"))
}

export {
read,
write,
}
8 changes: 3 additions & 5 deletions lib/queries/get-backlinks.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { sparqlRequest } = require("../request")
const languageFilter = require("./language-filter")
import { sparqlRequest } from "../request.js"
import languageFilter from "./language-filter.js"

function getBacklinks (uris, languages, properties) {
export default function getBacklinks (uris, languages, properties) {
const values = uris.map(uri => `<${uri}>`).join(" ")
const props = properties.map(p => `wdt:${p}`).join(" | ")

Expand Down Expand Up @@ -43,5 +43,3 @@ function getBacklinks (uris, languages, properties) {
.map(row => [row.from.value, entities[row.item.value]])
})
}

module.exports = getBacklinks
24 changes: 13 additions & 11 deletions lib/queries/get-concepts.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
const wdk = require("../wdk")
const { selectedLanguages } = require("../utils")
const { detectWikidataConcepts } = require("../utils")
const { httpRequest } = require("../request")
const getBacklinks = require("./get-backlinks")
const { mapEntity } = require("../mappers")
import wdk from "../wdk.js"
import { selectedLanguages } from "../utils.js"
import { detectWikidataConcepts } from "../utils.js"
import { httpRequest } from "../request.js"
import getBacklinks from "./get-backlinks.js"
import { mapEntity } from "../mappers.js"

async function getConcepts (query) {
export default async function getConcepts (query) {
const concepts = detectWikidataConcepts(query.uri)
if (!concepts.length) {
return []
}

const languages = selectedLanguages(query)
const props = ["info", "sitelinks", "labels", "aliases", "descriptions", "claims"]
const url = wdk.getEntities(concepts.map(concept => concept.notation[0]), languages, props)
const url = wdk.getEntities({
ids: concepts.map(concept => concept.notation[0]),
languages,
props,
})

return httpRequest(url)
.then(res => res.entities || {})
Expand All @@ -25,7 +29,7 @@ async function getConcepts (query) {
}
const index = {}
entities.forEach(e => {
index[e.uri] = e
index[e.uri] = e
})
const rels = ["P361", "P31", "P279", "P131"]
return getBacklinks(Object.keys(index), languages, rels)
Expand All @@ -42,5 +46,3 @@ async function getConcepts (query) {
})
})
}

module.exports = getConcepts
6 changes: 3 additions & 3 deletions lib/queries/get-mapping-list.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { sparqlRequest } = require("../request")
const { mappingTypes } = require("../types")
import { sparqlRequest } from "../request.js"
import { mappingTypes } from "../types.js"

/**
* Get total number of Wikidata statements a property is used in.
Expand Down Expand Up @@ -79,4 +79,4 @@ LIMIT ${limit} OFFSET ${offset}`
return mappings
}

module.exports = getMappingList
export default getMappingList
Loading

0 comments on commit f6e36f6

Please sign in to comment.