TypeScript¶
The npm package ships JavaScript ES modules and matching .d.ts declarations.
Use the JavaScript / TypeScript tabs throughout this guide for API calls;
TypeScript infers their types from the same imports. No separate @types
package is needed for DataHubClient.
Setup¶
Install the package in your application:
npm install @nfdi4plants/datahub-client
npm install --save-dev typescript
Node.js¶
Use a Node.js runtime with native fetch. Install Node's types and enable ES
modules in your application's package.json:
npm install --save-dev @types/node
npm pkg set type=module
For a standalone application with sources in src/, use this tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"verbatimModuleSyntax": true,
"noEmitOnError": true,
"types": ["node"],
"rootDir": "src",
"outDir": "dist"
},
"include": ["src/**/*.ts"]
}
Save your program as src/index.ts, then compile and run it:
npx tsc
node dist/index.js
Keep the .js suffix on the package's deep imports, even inside .ts files.
TypeScript resolves the corresponding declarations; the emitted JavaScript
loads the .js module.
Browser applications¶
Keep your framework's TypeScript configuration. For a standalone browser app
using a bundler such as Vite, a minimal tsconfig.json is:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["ES2022", "DOM"],
"types": [],
"strict": true,
"verbatimModuleSyntax": true,
"noEmit": true
},
"include": ["src/**/*.ts"]
}
Run npx tsc to check types and your bundler to build the application. These
settings follow TypeScript's distinction between
Node.js and bundler module resolution.
DataHubClient uses the browser's fetch; cross-origin requests still require
the DataHub to allow your application's origin through CORS.
Inferred types¶
Create a client using the same imports as JavaScript:
import { DataHubClient } from "@nfdi4plants/datahub-client";
import { Authentication } from "@nfdi4plants/datahub-client/Http/Authentication.js";
const client = new DataHubClient(
"https://hub.example", Authentication.Anonymous());
Replace https://hub.example with your DataHub URL. Anonymous authentication
reads public resources; see authentication
for private resources.
const project = await client.Projects.GetAsync(42); // Project
const name = project.Name; // string
const description = project.Description ?? "No description";
console.log(name, description);
GetAsync returns Promise<Project>, so await gives you a Project with typed
properties and editor completion. Description is optional (string | undefined).
You only need to import the Project type when you name it in your own code.
This is ordinary TypeScript inference.
Collection results are native arrays:
const projects = await client.Projects.ListAsync(); // Project[] (one page)
const names = projects.map(project => project.Name); // string[]
console.log(projects.length, names);
Use array methods, indexing, and .length directly. Projects.ListAsync returns
one page; use Projects.ListAllAsync when you need every page.
Explicit types for your own functions¶
Use import type to annotate parameters or return values with the library's
model types:
import type { Project } from "@nfdi4plants/datahub-client/Models/Project.js";
function projectLabel(project: Project): string {
return `${project.PathWithNamespace}: ${project.Name}`;
}
Call it with an inferred result:
console.log(projectLabel(project));
Model types live under Models/, such as Models/Project.js and Models/Issue.js.
The package root exports DataHubClient. A
type-only import
is removed from emitted JavaScript. Use a regular import when you need the class
at runtime, for example to call new Project(...) or use instanceof.
Browser downloads¶
The shared RO-Crate guide covers fetching metadata and saving it
in Node.js or the browser. For a browser helper written in TypeScript, annotate
its parameters and return type. Save this as browser.ts:
import type { DataHubClient } from "@nfdi4plants/datahub-client";
/** Download an ARC's JSON-LD metadata using the browser's save-file flow. */
export async function downloadROCrate(client: DataHubClient, projectId: number): Promise<void> {
const metadata = await client.Packages.DownloadROCrateAsync(projectId);
const blob = new Blob([metadata], { type: "application/ld+json;charset=utf-8" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "arc-ro-crate-metadata.json";
link.hidden = true;
document.body.append(link);
try {
link.click();
} finally {
link.remove();
// Give the browser time to start the download before releasing its URL.
setTimeout(() => URL.revokeObjectURL(url), 1000);
}
}
Then use it from your application's TypeScript entry point:
import { DataHubClient } from "@nfdi4plants/datahub-client";
import { Authentication } from "@nfdi4plants/datahub-client/Http/Authentication.js";
import { downloadROCrate } from "./browser.js";
const client = new DataHubClient("https://git.nfdi4plants.org", Authentication.Anonymous());
const button = document.createElement("button");
button.textContent = "Download RO-Crate";
button.addEventListener("click", () => {
downloadROCrate(client, 42).catch(console.error);
});
document.body.append(button);
Replace the example DataHub URL and project ID with your own. The ./browser.js
import resolves to browser.ts during type checking and to the emitted module
at runtime. Keep filesystem imports such as node:fs/promises in Node.js code;
browser saving uses Blob and an object URL.