UNPKG

@c8y/client

Version:

Client application programming interface to access the Cumulocity IoT-Platform REST services.

503 lines • 17.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApplicationService = void 0; const core_1 = require("../core"); const inventory_1 = require("../inventory"); const tenant_1 = require("../tenant"); const user_1 = require("../user"); const ApplicationBinaryService_1 = require("./ApplicationBinaryService"); const ApplicationType_1 = require("./ApplicationType"); const gettext_1 = require("../gettext"); class ApplicationService extends core_1.Service { constructor() { super(...arguments); this.baseUrl = 'application'; this.listUrl = 'applications'; this.propertyName = 'applications'; this.channel = '/applications/*'; } /** * Creates a new application. * * @param {IIdentified} entity Application object. * * @returns Response wrapped in [[IResult]] * * **Example** * ```typescript * * const newApp = { * name: 'New application', * type: 'EXTERNAL', * key: 'new-app' * }; * * (async () => { * const {data, res} = await applicationService.create(newApp); * })(); * ``` */ async create(entity) { return super.create(entity); } /** * Clones a given application. The application name, key, and context-path will be * prefixed with `clone` and if necessary a number. * @param entity The application to clone. * @param version If a blueprint, you can define which version to clone. If not provided, it will always clone the latest version. * @returns The application entity. */ async clone(entity, version) { const url = `${this.getDetailUrl(entity)}/clone`; const method = 'POST'; const body = ''; const headers = { 'content-type': 'application/json', accept: 'application/json' }; let params = undefined; if (version) { params = { version }; } const res = await this.fetch(url, { method, body, headers, params }); const data = await res.json(); return { res, data }; } /** * Gets the list of existing applications filtered by parameters. * * @returns Response wrapped in [[IResultList]] * * @param {object} filter Object containing filters for querying applications. * * **Example** * ```typescript * * const filter: object = { * pageSize: 100, * withTotalPages: true * }; * * (async () => { * const {data, res, paging} = await applicationService.list(filter); * })(); * ``` */ async list(filter = {}) { return super.list(filter); } /** * Gets the list of all application versions. * * @param {string|number|IIdentified} entityOrId Entity or Id of the entity. * * @param {object} params Additional request parameters. * * @returns Returns list of all application versions. * * **Example** * ```typescript * * const applicationId: number = 1; * * (async () => { * const {res, data} = await applicationService.listVersions(applicationId); * })(); * ``` */ async listVersions(entityOrId, params = {}) { const id = this.getEntityId(entityOrId); const url = `${this.listUrl}/${id}/versions`; const headers = { 'content-type': 'application/json' }; try { const res = await this.fetch(url, { headers, params }); const data = (await res.json())?.applicationVersions; return { res, data }; } catch (ex) { if (ex.res.status === 404) { const { data: appDetail, res } = await this.detail(entityOrId); return { res, data: appDetail.applicationVersions }; } throw ex; } } /** * Gets the details of selected application. * * @param {string|number|IIdentified} entityOrId Entity or Id of the entity. * * @returns Response wrapped in [[IResult]] * * **Example** * ```typescript * * const applicationId: number = 1; * * (async () => { * const {data, res} = await applicationService.detail(applicationId); * })(); * ``` */ async detail(entityOrId) { return super.detail(entityOrId); } /** * Updates existing application. * Make sure that you specifiy the application id within the update object. * * @param {IIdentified} entity Application object. * * @returns Response wrapped in [[IResult]] * * **Example** * ```typescript * * const updateApp = { * id: 38 * name: 'Updated application' * }; * * (async () => { * const {data, res} = await applicationService.update(updateApp); * })(); * ``` */ async update(entity) { return super.update(entity); } /** * Removes an application with given id. * * @returns Response wrapped in [[IResult]] * * @param {string | number | IIdentified} entityOrId entity or id of the application. * * **Example** * ```typescript * * const removeApp: object = { * id: 38 * }; * * (async () => { * const {data, res} = await applicationService.delete(removeApp); * // data will be null * })(); * ``` */ async delete(entityOrId) { return super.delete(entityOrId); } async listByName(name, params = {}) { const headers = { 'content-type': 'application/json' }; const url = `applicationsByName/${encodeURIComponent(name)}`; const res = await this.fetch(url, { headers, params }); const json = await res.json(); const data = json[this.propertyName]; return { res, data }; } async listByTenant(tenantOrName, params = {}) { const headers = { 'content-type': 'application/json' }; const tenantService = new tenant_1.TenantService(this.client); const tenantName = this.getIdString(tenantOrName || (await tenantService.current()).data.name); const url = `applicationsByTenant/${encodeURIComponent(tenantName)}`; const res = await this.fetch(url, { headers, params }); const json = await res.json(); const data = json[this.propertyName]; return { res, data }; } async listByOwner(tenantOrName, params = {}) { const headers = { 'content-type': 'application/json' }; const tenantService = new tenant_1.TenantService(this.client); const tenantName = this.getIdString(tenantOrName || (await tenantService.current()).data.name); const url = `applicationsByOwner/${encodeURIComponent(tenantName)}`; const res = await this.fetch(url, { headers, params }); const json = await res.json(); const data = json[this.propertyName]; return { res, data }; } async listByUser(userOrId, params = {}) { const headers = { 'content-type': 'application/json' }; const userService = new user_1.UserService(this.client); const userId = this.getIdString(userOrId || (await userService.current()).data); const url = `applicationsByUser/${encodeURIComponent(userId)}`; const res = await this.fetch(url, { headers, params }); const json = await res.json(); const data = json[this.propertyName]; return { res, data }; } async reactivateArchive(appId) { const url = `${this.listUrl}/${appId}/refresh`; const method = 'POST'; const body = ''; const headers = { 'content-type': 'application/json', accept: 'application/json' }; const res = await this.fetch(url, { method, body, headers }); return { res, data: null }; } binary(application) { return new ApplicationBinaryService_1.ApplicationBinaryService(this.client, application); } getHref(application) { if (application.type === ApplicationType_1.ApplicationType.EXTERNAL) { return application.externalUrl; } return `/apps/${application.public ? 'public/' : ''}${application.contextPath}`; } /** * Checks if current user can access specified application. * * @returns Response wrapped in [[IResult]] * * @param {string | IApplication} application Application name or contextPath as a * string or Application object. * * **Example** * ```typescript * * const checkApp: object = { * name: 'myApplication' * }; * * (async () => { * const {data, res} = await applicationService.isAvailable(checkApp); * })(); * ``` */ async isAvailable(application) { const { res, data } = await this.listByUser(undefined, { dropOverwrittenApps: true, noPaging: true }); const available = (data || []).some((availableApp) => typeof application === 'string' ? availableApp.name === application || availableApp.contextPath === application : this.isMatch(availableApp, application)); return { data: available, res }; } /** * Gets instance details of the specified application (microservice). * * @param {string|number|IApplication} entityOrId Entity or Id of the application. * * @returns Response wrapped in [[IResultList]] * * **Example** * ```typescript * * const applicationId: number = 1; * * (async () => { * const {data, res} = await applicationService.getStatusDetails(applicationId); * })(); * ``` */ async getStatusDetails(entityOrId) { const appId = this.getEntityId(entityOrId); const inventory = new inventory_1.InventoryService(this.client, this.realtime); return inventory.list({ type: `c8y_Application_${appId}` }); } /** * Extracts instance names of the provided IApplicationManagedObject. * * @param {IApplicationManagedObject} appStatusDetails Application details managedObject. * * @returns instance names * * **Example** * ```typescript * * const applicationId: number = 1; * * (async () => { * const {data, res} = await applicationService.getStatusDetails(applicationId); * const instances = data.map((appMO) => applicationService.getInstanceNames(appMO)); * })(); * ``` */ getInstanceNames(appStatusDetails) { let instanceNames = new Array(); if (appStatusDetails && appStatusDetails.c8y_Status && appStatusDetails.c8y_Status.instances) { instanceNames = Object.keys(appStatusDetails.c8y_Status.instances); } return instanceNames; } /** * Get log for a specific application instance. * * @param {string|number|IApplication} entityOrId Entity or Id of the application. * * @param {string} instanceName instance name of the application. * * @param {IApplicationInstanceLogRequestParams} params Object containing parameters for querying the log file. * * @returns Response wrapped in [[IResult]] * * **Example** * ```typescript * * const applicationId: number = 1; * const applicationInstanceName: string = 'apama-ctrl-1c-4g-scope-t123456789-deployment-abcdefghij-abcde'; * * (async () => { * const {data, res} = await applicationService.getInstanceLog(applicationId, applicationInstanceName); * })(); * ``` */ async getInstanceLog(entityOrId, instanceName, params) { const url = `${this.getDetailUrl(entityOrId)}/logs/${instanceName}`; const headers = { accept: this.mimeType('applicationLogs') }; const res = await this.fetch(url, { headers, params }); const data = await res.json(); return { res, data }; } /** * Dynamic options are stored on the API in a specific `config: {}` object. They can * be used to configure the app dynamically. * * Note: To avoids conflicts with the default Config, it is recommended * to use a certain namespace. * @param entityOrId Entity or Id of the application. * @param config Configuration to be updated. * @returns Returns updated configuration. */ async updateApplicationConfig(entityOrId, config) { const id = this.getEntityId(entityOrId); const { data: app } = await this.detail(id); const currentConfig = app?.config || {}; const newConfig = { ...currentConfig, ...config }; const updatedConfigApp = await this.update({ id, config: newConfig }); return (await updatedConfigApp)?.data; } /** * Gets manifest (cumulocity.json file) of a given application. * * @param {IApplication} app Application entity. * * @param {string} app version * * @returns Application manifest object. */ async getAppManifest(app, version) { const date = new Date(); let result; if (!version) { result = await this.client.fetch(`/apps/${app.contextPath}/cumulocity.json?nocache=${date.getTime()}`); } else { result = await this.client.fetch(`/apps/${app.contextPath}@${version}/cumulocity.json?nocache=${date.getTime()}`); } if (result.status >= 400) { throw new Error((0, gettext_1.gettext)('No Cumulocity IoT manifest found.')); } const c8yJson = await result.json(); return c8yJson; } /** * Updates manifest (cumulocity.json file) of a given application. * * @param {string|number|IApplication} entityOrId Entity or Id of the application. * * @param {any} manifestJSON Application manifest object to be stored. * * @returns Application manifest object. */ async storeAppManifest(entityOrId, manifestJSON) { return await this.binary(entityOrId).updateFiles([ { path: 'cumulocity.json', contents: JSON.stringify(manifestJSON) } ]); } /** * Sets tags for specific application package version. * * @param {IApplication} app Application entity. * * @param {string} version Application package version which tags will be set. * * @param {string[]} tags Tags array to set on package version * * @returns Application version object. */ async setPackageVersionTag(app, version, tags) { const url = `${this.getDetailUrl(app)}/versions/${version}`; const method = 'PUT'; const body = JSON.stringify({ tags }); const headers = { accept: 'application/vnd.com.nsn.cumulocity.applicationVersion+json;charset=UTF-8;ver=0.9', 'content-type': 'application/json' }; const res = await this.fetch(url, { method, body, headers }); const data = await res.json(); return { res, data }; } /** * Retrieves the manifest of the application behind the given context path. * @param contextPath */ async getManifestOfContextPath(contextPath) { const url = `${this.getDetailUrl(contextPath)}/manifest`; const res = await this.fetch(url); const { application } = await res.json(); return { res, data: application }; } /** * Removes package version. * * @param {IApplication} app Application entity. * * @param {IApplicationVersionDeleteParams} params Version or tag indication package to remove. * * @returns Request response. * * **Example** * ```typescript * * const { res } = await applicationService.deleteVersionPackage(app, {version: '1.0.0'}); * * const { res } = await applicationService.deleteVersionPackage(app, {tag: 'next'}); * * ``` */ async deleteVersionPackage(app, params) { const url = `${this.getDetailUrl(app)}/versions/`; const method = 'DELETE'; const res = await this.fetch(url, this.changeFetchOptions({ method, params }, url)); return { res, data: null }; } /** * Updates the availability of the given application to the provided value. * * @param {string|number|IApplication} entityOrId Entity or Id of the application. * * @param {any} availability The new application availability. * * @returns Updated application. */ async updateApplicationAvailability(entityOrId, availability) { const id = this.getEntityId(entityOrId); return await this.update({ id, availability }); } isMatch(object, source) { return Object.keys(source).every(key => { if (Array.isArray(object[key]) && Array.isArray(source[key])) { return source[key].every(el => object[key].includes(el)); } else if (typeof object[key] === 'object' && object[key] !== null && typeof source[key] === 'object' && source[key] !== null) { return this.isMatch(object[key], source[key]); } else { return object[key] === source[key]; } }); } } exports.ApplicationService = ApplicationService; //# sourceMappingURL=ApplicationService.js.map