UNPKG

@c8y/client

Version:

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

574 lines • 20.9 kB
import { __awaiter } from "tslib"; import { Service } from '../core/index.js'; import { InventoryService } from '../inventory/index.js'; import { TenantService } from '../tenant/index.js'; import { UserService } from '../user/index.js'; import { ApplicationBinaryService } from './ApplicationBinaryService.js'; import { ApplicationType } from './ApplicationType.js'; import { gettext } from '../gettext.js'; export class ApplicationService extends 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); * })(); * ``` */ create(entity) { const _super = Object.create(null, { create: { get: () => super.create } }); return __awaiter(this, void 0, void 0, function* () { return _super.create.call(this, 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. */ clone(entity, version) { return __awaiter(this, void 0, void 0, function* () { 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 = yield this.fetch(url, { method, body, headers, params }); const data = yield 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); * })(); * ``` */ list() { const _super = Object.create(null, { list: { get: () => super.list } }); return __awaiter(this, arguments, void 0, function* (filter = {}) { return _super.list.call(this, 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); * })(); * ``` */ listVersions(entityOrId_1) { return __awaiter(this, arguments, void 0, function* (entityOrId, params = {}) { var _a; const id = this.getEntityId(entityOrId); const url = `${this.listUrl}/${id}/versions`; const headers = { 'content-type': 'application/json' }; try { const res = yield this.fetch(url, { headers, params }); const data = (_a = (yield res.json())) === null || _a === void 0 ? void 0 : _a.applicationVersions; return { res, data }; } catch (ex) { if (ex.res.status === 404) { const { data: appDetail, res } = yield 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); * })(); * ``` */ detail(entityOrId) { const _super = Object.create(null, { detail: { get: () => super.detail } }); return __awaiter(this, void 0, void 0, function* () { return _super.detail.call(this, entityOrId); }); } /** * Allows to retrieve bootstrap user credentials for a specific application (microservice). * @param {string|number|IIdentified} entityOrId Entity or Id of the entity. * @returns Response wrapped in [[IResult]] */ getBootstrapUser(entityOrId) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.getDetailUrl(entityOrId)}/bootstrapUser`; const res = yield this.fetch(url); const data = yield res.json(); return { res, data }; }); } /** * 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); * })(); * ``` */ update(entity) { const _super = Object.create(null, { update: { get: () => super.update } }); return __awaiter(this, void 0, void 0, function* () { return _super.update.call(this, 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 * })(); * ``` */ delete(entityOrId) { const _super = Object.create(null, { delete: { get: () => super.delete } }); return __awaiter(this, void 0, void 0, function* () { return _super.delete.call(this, entityOrId); }); } listByName(name_1) { return __awaiter(this, arguments, void 0, function* (name, params = {}) { const headers = { 'content-type': 'application/json' }; const url = `applicationsByName/${encodeURIComponent(name)}`; const res = yield this.fetch(url, { headers, params }); const json = yield res.json(); const data = json[this.propertyName]; return { res, data }; }); } listByTenant(tenantOrName_1) { return __awaiter(this, arguments, void 0, function* (tenantOrName, params = {}) { const headers = { 'content-type': 'application/json' }; const tenantService = new TenantService(this.client); const tenantName = this.getIdString(tenantOrName || (yield tenantService.current()).data.name); const url = `applicationsByTenant/${encodeURIComponent(tenantName)}`; const res = yield this.fetch(url, { headers, params }); const json = yield res.json(); const data = json[this.propertyName]; return { res, data }; }); } listByOwner(tenantOrName_1) { return __awaiter(this, arguments, void 0, function* (tenantOrName, params = {}) { const headers = { 'content-type': 'application/json' }; const tenantService = new TenantService(this.client); const tenantName = this.getIdString(tenantOrName || (yield tenantService.current()).data.name); const url = `applicationsByOwner/${encodeURIComponent(tenantName)}`; const res = yield this.fetch(url, { headers, params }); const json = yield res.json(); const data = json[this.propertyName]; return { res, data }; }); } listByUser(userOrId_1) { return __awaiter(this, arguments, void 0, function* (userOrId, params = {}) { const headers = { 'content-type': 'application/json' }; const userService = new UserService(this.client); const userId = this.getIdString(userOrId || (yield userService.current()).data); const url = `applicationsByUser/${encodeURIComponent(userId)}`; const res = yield this.fetch(url, { headers, params }); const json = yield res.json(); const data = json[this.propertyName]; return { res, data }; }); } reactivateArchive(appId) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.listUrl}/${appId}/refresh`; const method = 'POST'; const body = ''; const headers = { 'content-type': 'application/json', accept: 'application/json' }; const res = yield this.fetch(url, { method, body, headers }); return { res, data: null }; }); } binary(application) { return new ApplicationBinaryService(this.client, application); } getHref(application) { if (application.type === 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); * })(); * ``` */ isAvailable(application) { return __awaiter(this, void 0, void 0, function* () { const { res, data } = yield 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); * })(); * ``` */ getStatusDetails(entityOrId) { return __awaiter(this, void 0, void 0, function* () { const appId = this.getEntityId(entityOrId); const inventory = new 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); * })(); * ``` */ getInstanceLog(entityOrId, instanceName, params) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.getDetailUrl(entityOrId)}/logs/${instanceName}`; const headers = { accept: this.mimeType('applicationLogs') }; const res = yield this.fetch(url, { headers, params }); const data = yield 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. */ updateApplicationConfig(entityOrId, config) { return __awaiter(this, void 0, void 0, function* () { var _a; const id = this.getEntityId(entityOrId); const { data: app } = yield this.detail(id); const currentConfig = (app === null || app === void 0 ? void 0 : app.config) || {}; const newConfig = Object.assign(Object.assign({}, currentConfig), config); const updatedConfigApp = yield this.update({ id, config: newConfig }); return (_a = (yield updatedConfigApp)) === null || _a === void 0 ? void 0 : _a.data; }); } /** * Gets manifest (cumulocity.json file) of a given application. * * @param {IApplication} app Application entity. * * @param {string} app version * * @returns Application manifest object. */ getAppManifest(app, version) { return __awaiter(this, void 0, void 0, function* () { const date = new Date(); let result; if (!version) { result = yield this.client.fetch(`/apps/${app.contextPath}/cumulocity.json?nocache=${date.getTime()}`); } else { result = yield this.client.fetch(`/apps/${app.contextPath}@${version}/cumulocity.json?nocache=${date.getTime()}`); } if (result.status >= 400) { throw new Error(gettext('No Cumulocity IoT manifest found.')); } const c8yJson = yield 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. */ storeAppManifest(entityOrId, manifestJSON) { return __awaiter(this, void 0, void 0, function* () { return yield 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. */ setPackageVersionTag(app, version, tags) { return __awaiter(this, void 0, void 0, function* () { 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 = yield this.fetch(url, { method, body, headers }); const data = yield res.json(); return { res, data }; }); } /** * Retrieves the manifest of the application behind the given context path. * @param contextPath */ getManifestOfContextPath(contextPath) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.getDetailUrl(contextPath)}/manifest`; const res = yield this.fetch(url); const { application } = yield 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'}); * * ``` */ deleteVersionPackage(app, params) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.getDetailUrl(app)}/versions/`; const method = 'DELETE'; const res = yield 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. */ updateApplicationAvailability(entityOrId, availability) { return __awaiter(this, void 0, void 0, function* () { const id = this.getEntityId(entityOrId); return yield 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]; } }); } } //# sourceMappingURL=ApplicationService.js.map