Skip to content

EyeSeeTea/d2-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

d2-api

Typescript library for the DHIS2 API.

Generate schemas

This task generate the schemas for active API versions from play.dhis2.org instances.

$ yarn generate-schemas

Development

$ yarn install
$ yarn build
$ cd build
$ yarn link

On your app:

$ yarn link d2-api

Publish

$ yarn build
$ yarn publish [--tag beta] [--patch | --minor | --major]

Usage

Create an API instance

import { D2Api } from "d2-api/2.36";

const api = new D2Api({
    baseUrl: "https://play.im.dhis2.org/dev",
    auth: { username: "admin", password: "district" },
});

Metadata models

GET single (by ID)

const dataSet = await api.models.dataSets
    .getById("BfMAe6Itzgt", {
        fields: {
            id: true,
            name: true,
            categoryOptions: {
                id: true,
                name: true,
            },
        },
    })
    .getData();

console.log(dataSet.id, dataSet.name, dataSet.categoryOptions);

GET (list)

const response = await api.models.dataSets
    .get({
        fields: {
            id: true,
            name: true,
        },
        filter: {
            name: { ilike: "health", "!in": ["Child Health"] },
            code: { $like: "DS_" },
        },
        order: "name:asc",
        paging: false,
    })
    .getData();

POST (create)

const response = await api.models.dataSets
    .post({
        name: "My DataSet",
        periodType: "Monthly",
    })
    .getData();

PUT (update)

const response = await api.models.dataSets
    .put({
        id: "Ew82BhPZkpa",
        name: "My DataSet",
        periodType: "Daily",
    })
    .getData();

DELETE (delete)

const response = await api.models.dataSets
    .delete({
        id: "Ew82BhPZkpa",
    })
    .getData();

Metadata

GET

const response = await api.metadata
    .get({
        dataSets: {
            fields: {
                id: true,
                name: true,
                organisationUnits: {
                    id: true,
                    name: true,
                },
            },
            filter: {
                name: { ilike: "health", "!in": ["Child Health"] },
                code: { $like: "DS_" },
            },
        },
        categories: {
            fields: {
                $owner: true,
            },
        },
    })
    .getData();

console.log(response);

POST

const response = await api.metadata
    .post({
        dataSets: [
            {
                name: "My DataSet",
                periodType: "Monthly",
            },
        ],
    })
    .getData();

console.log(response);

Analytics

Get

const analyticsData = await api.analytics
    .get({
        dimension: ["dx:fbfJHSPpUQD;cYeuwXTCPkU"],
        filter: ["pe:2014Q1;2014Q2", "ou:O6uvpzGd5pu;lc3eMKXaEfw"],
    })
    .getData();

Get enrollments query

const analyticsData = await api.analytics
    .getEnrollmentsQuery("IpHINAT79UW", {
        dimension: ["GxdhnY5wmHq", "ou:ImspTQPwCqd"],
        enrollmentDate: "LAST_12_MONTHS,THIS_MONTH",
    })
    .getData();

Run analytics

const analyticsRunResponse = await api.analytics.run().getData();

Data values

const response = await api.dataValues
    .postSet({
        dataSet: "Gs69Uw2Mom1",
        orgUnit: "qYIeuQe9OwF",
        period: "202001",
        attributeOptionCombo: "yi2bV1K4vl6",
        dataValues:
            _[
                ({
                    dataElement: "a4bd432446",
                    categoryOptionCombo: "d1bd43245af",
                    value: "1.5",
                },
                {
                    dataElement: "1agd43f4q2",
                    categoryOptionCombo: "aFwdq324132",
                    value: "Some comment",
                })
            ],
    })
    .getData();

Data store

Get

const dataStore = api.dataStore("namespace1");
const value = await dataStore.get("key1").getData();

Save

const dataStore = api.dataStore("namespace1");
await dataStore.save("key1", { x: 1, y: 2 });

Tracker

Get all tracked entities for an specific program:

const data = await api.tracker.trackedEntities
    .get({
        fields: {
            orgUnit: true,
        },
        ouMode: "ALL",
        program: "program_id",
    })
    .getData();

Order tracked entities by field/attribute id

const data = await api.tracker.trackedEntities
    .get({
        fields: {
            orgUnit: true,
        },
        ouMode: "ALL",
        program: "program_id",
        order: [
            { type: "field", field: "createdAt", direction: "asc" },
            { type: "trackedEntityAttributeId", id: "wMhqqPLb7pP", direction: "desc" },
        ],
    })
    .getData();

Adding the totalPages param will include a pager object:

const data = await api.tracker.trackedEntities
    .get({
        fields: {
            orgUnit: true,
        },
        ouMode: "ALL",
        program: "program_id",
        totalPages: true,
    })
    .getData();
/* Response:
    {
        page: 1;
        pageSize: 50;
        pageCount: 10;
        total: 500;
    }
    */

Emails

Send a test email:

await api.email.sendTestMessage().getData();

Send a system notification:

await api.email
    .sendSystemNotification({
        subject: "My subject",
        text: "My message",
    })
    .getData();

Send a message (requires role ALL or F_SEND_EMAIL):

await api.email
    .sendMessage({
        recipients: ["[email protected]"],
        subject: "My subject",
        text: "My message",
    })
    .getData();

Using type helpers

d2-api exposes some type helpers that you may need in your app. Some examples:

  • SelectedPick: Get model from a selector:
type PartialUser = SelectedPick<
    D2UserSchema,
    {
        id: true;
        favorite: true;
    }
>;
// type PartialUser = {id: string, favorite: boolean}
  • MetadataPick: Get indexes models from a metadata selector.
type Metadata = MetadataPick<{
    users: { fields: { id: true; favorite: true } };
    categories: { fields: { id: true; code: true } };
}>;
// type Metadata = {users: {id: string, favorite: boolean}, categories: {id: string, code: string}}

Cancelling requests

The examples use the method getData() to resolve the result. That's what we call when we simply want to get the result, but, on the general case, we probably need a cancel object (for example when using cancellable promises/futures, React.useEffect, and so on). An example:

const { cancel, response } = api.models.dataSets.getById("BfMAe6Itzgt", {
    fields: { id: true, name: true },
});

const res = await response(); // it's a function so the promise resolution can be controlled
console.log("Cancel function", cancel);
console.log(res.data);

Testing

import { D2Api } from "d2-api/2.36";
import { getMockApiFromClass } from "d2-api";

const currentUserMock = {
    id: "xE7jOejl9FI",
    displayName: "John Traore",
};

const { api, mock } = getMockApiFromClass(D2Api);

describe("Project", () => {
    beforeEach(() => {
        mock.reset();
    });

    describe("getList", () => {
        it("returns list of dataSets filtered", async () => {
            mock.onGet("/me").reply(200, currentUserMock);
            const currentUser = await api.currrentUser.get().getData();
            expect(currentUser.id).toEqual("xE7jOejl9FI");
        });
    });
});

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 10

Languages