crest/v2/index.js

import appendPathComponent from "../../utils/uri/appendPathComponent";
import createBody from "./createBody";
import createRequest from "../createRequest";
import appendQueryString from "../../utils/uri/appendQueryString";

/**
 * Representation of a CREST v2 resource.
 * @example
 * import { CRESTv2 } from "@forgerock/crest-js";
 *
 * const resource = new CRESTv2("http://www.example.com");
 */
class v2 {
    /**
     * Creates a new instance.
     * @param {string} resourceURL URL of the resource.
     * @param {object} [options={}] Options.
     * @param {middleware[]} [options.middleware=[]] Middleware.
     * @param {string} [options.resourceVersion=1.0] Resource version.
     */
    constructor (resourceURL, { middleware = [], resourceVersion = "1.0" } = {}) {
        this.resourceURL = resourceURL;
        this.resourceVersion = resourceVersion;
        this.request = createRequest(this.protocolVersion, resourceVersion, middleware);
    }
    /**
     * CREST protocol version.
     * @readonly
     */
    get protocolVersion () {
        return "2.0";
    }
    /**
     * Invokes an action on a resource provider.
     * @param {string} action Action name.
     * @param {object} [options={}] Options.
     * @param {object} [options.body] Action body.
     * @param {object} [options.queryString] Additional query string.
     * @returns {Promise<Response>} A Promise that resolves to a Response object.
     * @see https://backstage.forgerock.com/docs/am/6.5/dev-guide/#about-crest-action
     */
    action (action, { body, queryString } = {}) {
        const input = appendQueryString(this.resourceURL, {
            ...queryString,
            _action: action
        });
        const headers = body ? { "Content-Type": "application/json" } : {};

        return this.request(input, {
            body: body ? createBody(body) : undefined,
            headers,
            method: "POST"
        });
    }
    /**
     * Creates a resource.
     * @param {object} body Resource representation.
     * @param {object} [options={}] Options.
     * @param {string} [options.id] Client provided ID for the resource.
     * @param {object} [options.queryString] Additional query string.
     * @returns {Promise<Response>} A Promise that resolves to a Response object.
     * @see https://backstage.forgerock.com/docs/am/6.5/dev-guide/#about-crest-create
     */
    create (body, { id, queryString } = {}) {
        const input = this.constructCreateInput(id, queryString);
        const headers = { "Content-Type": "application/json" };
        if (id) { headers["If-None-Match"] = "*"; }

        return this.request(input, {
            body: createBody(body),
            headers,
            method: id ? "PUT" : "POST"
        });
    }
    /**
     * Constructs the input when creating a resource.
     * @param {string} [id] Client provided ID for the resource.
     * @param {object} [queryString] Additional query string.
     * @returns {string} The input.
     * @see #create
     * @private
     */
    constructCreateInput (id, queryString) {
        return id
            ? appendQueryString(appendPathComponent(this.resourceURL, id), queryString)
            : appendQueryString(this.resourceURL, { ...queryString, _action: "create" });
    }
    /**
     * Deletes a single resource by ID.
     * @param {string} id Resource ID.
     * @param {object} [options={}] Options.
     * @param {string} [options.revision] Revision ID.
     * @param {object} [options.queryString] Additional query string.
     * @returns {Promise<Response>} A Promise that resolves to a Response object.
     * @see https://backstage.forgerock.com/docs/am/6.5/dev-guide/#about-crest-delete
     */
    delete (id, { queryString, revision } = {}) {
        const input = appendQueryString(appendPathComponent(this.resourceURL, id), queryString);
        const headers = {};
        if (revision) { headers["If-Match"] = revision; }

        return this.request(input, {
            headers,
            method: "DELETE"
        });
    }
    /**
     * Retrieves a single resource by ID.
     * @param {string} id Resource ID.
     * @param {object} [options={}] Options.
     * @param {object} [options.queryString] Additional query string.
     * @returns {Promise<Response>} A Promise that resolves to a Response object.
     * @see https://backstage.forgerock.com/docs/am/6.5/dev-guide/#about-crest-read
     */
    get (id, { queryString } = {}) {
        const input = appendQueryString(appendPathComponent(this.resourceURL, id), queryString);
        return this.request(input, {
            method: "GET"
        });
    }
    /**
     * Queries a resource collection.
     * @param {object} [options={}] Options.
     * @param {object} [options.queryString] Additional query string.
     * @returns {Promise<Response>} A Promise that resolves to a Response object.
     * @see https://backstage.forgerock.com/docs/am/6.5/dev-guide/#about-crest-query
     */
    queryFilter ({ queryString } = {}) {
        const input = appendQueryString(this.resourceURL, {
            ...queryString,
            _queryFilter: true
        });
        return this.request(input, {
            method: "GET"
        });
    }
    /**
     * Updates a single resource by ID.
     * @param {string} id Resource ID.
     * @param {object} body Resource representation.
     * @param {object} [options={}] Options.
     * @param {string} [options.revision] Revision ID.
     * @param {object} [options.queryString] Additional query string.
     * @returns {Promise<Response>} A Promise that resolves to a Response object.
     * @see https://backstage.forgerock.com/docs/am/6.5/dev-guide/#about-crest-update
     */
    update (id, body, { queryString, revision } = {}) {
        const input = appendQueryString(appendPathComponent(this.resourceURL, id), queryString);
        const headers = { "Content-Type": "application/json" };
        if (revision) { headers["If-Match"] = revision; }

        return this.request(input, {
            body: createBody(body),
            headers,
            method: "PUT"
        });
    }
}

export default v2;