UNPKG

cv-dialog-sdk

Version:

Catavolt Dialog Javascript API

604 lines (543 loc) 33.6 kB
import {JsonClientResponse} from "../client/JsonClientResponse"; import {storage as clientStorage} from "../storage"; import {Base64} from "../util/Base64"; import {Log} from "../util/Log"; import {StringDictionary} from "../util/StringDictionary"; import {FetchClient} from "../ws/FetchClient"; import {ContentRedirectionVisitor} from "./ContentRedirectionVisitor"; import {DialogRedirectionVisitor} from "./DialogRedirectionVisitor"; import {DialogRequest} from "./DialogRequest"; import {DialogVisitor} from "./DialogVisitor"; import {LargePropertyVisitor} from "./LargePropertyVisitor"; import {ReadLargePropertyParametersVisitor} from "./ReadLargePropertyParametersVisitor"; import {RecordSetVisitor} from "./RecordSetVisitor"; import {RecordVisitor} from "./RecordVisitor"; import {WriteLargePropertyParametersVisitor} from "./WriteLargePropertyParametersVisitor"; // @FIX_THIS // remove this: const storage = clientStorage; // uncomment this // const storage = clientStorage.getSecureInstance(); // Set the secret key like this: // storage.secretKey = 'secret_key'; /** * */ export class DialogProxyTools { // Model Types private static ACTION_PARAMETERS_MODEL_TYPE = 'hxgn.api.dialog.ActionParameters'; private static ANNOTATION_MODEL_TYPE = 'hxgn.api.dialog.Annotation'; private static DIALOG_MESSAGE_MODEL_TYPE = 'hxgn.api.dialog.DialogMessage'; private static EDITOR_DIALOG_MODEL_TYPE = 'hxgn.api.dialog.EditorDialog'; private static LOGIN_MODEL_TYPE = 'hxgn.api.dialog.Login'; private static PROPERTY_MODEL_TYPE = 'hxgn.api.dialog.Property'; private static PROPERTY_DEF_MODEL_TYPE = 'hxgn.api.dialog.PropertyDef'; private static QUERY_DIALOG_MODEL_TYPE = 'hxgn.api.dialog.QueryDialog'; private static RECORD_MODEL_TYPE = 'hxgn.api.dialog.Record'; private static RECORD_SET_MODEL_TYPE = 'hxgn.api.dialog.RecordSet'; private static REFERRING_DIALOG_MODEL_TYPE = 'hxgn.api.dialog.ReferringDialog'; private static REFERRING_WORKBENCH_MODEL_TYPE = 'hxgn.api.dialog.ReferringWorkbench'; private static SESSION_MODEL_TYPE = 'hxgn.api.dialog.Session'; // Storage Keys private static CONTENT_STORAGE_KEY = '${userId}.${tenantId}.${contentId}.${sequence}.content'; private static DIALOG_STORAGE_KEY = '${userId}.${tenantId}.${dialogId}.dialog'; private static PROPERTY_COMMIT_STORAGE_KEY = '${userId}.${tenantId}.${dialogId}.${propertyName}.propertycommit'; private static RECORD_COMMIT_STORAGE_KEY = '${userId}.${tenantId}.${dialogId}.recordcommit'; private static RECORD_SET_STORAGE_KEY = '${userId}.${tenantId}.${dialogId}.recordset'; private static RECORD_STORAGE_KEY = '${userId}.${tenantId}.${dialogId}.record'; private static REDIRECTION_STORAGE_KEY = '${userId}.${tenantId}.${stateId}.${actionId}.redirection'; private static STORAGE_KEY_PREFIX = '${userId}.${tenantId}.'; private static COMMON_FETCH_CLIENT = new FetchClient(); public static async captureDialog(userId: string, baseUrl: string, tenantId: string, sessionId: string, dialogId: string, referringDialogId): Promise<object> { const thisMethod = 'DialogProxyTools::captureDialog'; // GET DIALOG // const resourcePath = `tenants/${tenantId}/sessions/${sessionId}/dialogs/${dialogId}`; // Log.info(`${thisMethod} -- capturing online dialog: ${resourcePath}`); const dialogJcr = await DialogProxyTools.commonFetchClient().getJson(baseUrl, resourcePath); if (dialogJcr.statusCode !== 200) { throw new Error(`Unexpected result when getting dialog ${dialogId}: ${dialogJcr.statusCode}`); } // Log.info(`${thisMethod} -- dialog: ${JSON.stringify(dialogJcr.value)}`); // WRITE DIALOG // const dialogVisitor = new DialogVisitor(dialogJcr.value); const beforeDialog = dialogVisitor.copyAsJsonObject(); dialogVisitor.deriveDialogIdsFromDialogNameAndRecordId(); // Not all referring objects are dialogs, so we must check that a dialog id is present if (referringDialogId) { dialogVisitor.visitAndSetReferringDialogId(referringDialogId); } // Log.info(`${thisMethod} -- writing online dialog to offline dialog id: ${dialogVisitor.visitId()}`); // Log.info(`${thisMethod} -- writing online dialog to offline storage: ${dialogVisitor.copyAsJsonString()}`); await this.writeDialog(userId, tenantId, dialogVisitor); return {beforeDialog, afterDialog: dialogVisitor.enclosedJsonObject()}; } public static async captureMenuActionRedirectionAndDialog(userId: string, baseUrl: string, tenantId: string, sessionId: string, dialogId: string, offlineDialogId: string, actionId: string, targetId: string): Promise<any> { const thisMethod = 'DialogProxyTools::captureMenuActionRedirectionAndDialog'; const resourcePath = `tenants/${tenantId}/sessions/${sessionId}/dialogs/${dialogId}/actions/${actionId}`; // Log.info(`${thisMethod} -- capturing menu redirection and dialog: ${resourcePath}`); // GET REDIRECTION // const actionParameters = { targets: [targetId], type: "hxgn.api.dialog.ActionParameters" }; // Log.info(`${thisMethod} -- capturing online dialog redirection: ${resourcePath}`); const dialogRedirectionJcr = await DialogProxyTools.commonFetchClient().postJson(baseUrl, resourcePath, actionParameters); if (dialogRedirectionJcr.statusCode !== 303) { throw new Error(`Unexpected result when posting menu dialog ${dialogId} action ${actionId}: ${dialogRedirectionJcr.statusCode}`); } // Log.info(`${thisMethod} -- menu action redirection: ${JSON.stringify(dialogRedirectionJcr.value)}`); // WRITE REDIRECTION // const dialogRedirectionVisitor = new DialogRedirectionVisitor(dialogRedirectionJcr.value); const beforeDialogRedirection = dialogRedirectionVisitor.copyAsJsonObject(); dialogRedirectionVisitor.deriveDialogIdsFromDialogNameAndRecordId(); dialogRedirectionVisitor.visitAndSetReferringDialogId(offlineDialogId); let actionIdAtTargetId = actionId; if (targetId) { const targetIdEncoded = Base64.encodeUrlSafeString(targetId); actionIdAtTargetId = actionIdAtTargetId + '@' + targetIdEncoded; } // Log.info(`${thisMethod} -- writing online dialog redirection with dialog id: ${dialogRedirectionVisitor.visitDialogId()}`); // Log.info(`${thisMethod} -- writing online dialog redirection with referring dialog id: ${dialogRedirectionVisitor.visitReferringDialogId()}`); // Log.info(`${thisMethod} -- writing online dialog redirection with record id: ${dialogRedirectionVisitor.visitRecordId()}`); // Log.info(`${thisMethod} -- writing online dialog redirection to offline redirection id: ${dialogRedirectionVisitor.visitId()}`); // Log.info(`${thisMethod} -- writing online dialog redirection to offline storage: ${dialogRedirectionVisitor.copyAsJsonString()}`); const referringDialogId = dialogRedirectionVisitor.visitReferringDialogId(); await this.writeDialogRedirection(userId, tenantId, referringDialogId, actionIdAtTargetId, dialogRedirectionVisitor); // CAPTURE DIALOG // const beforeDialogId = beforeDialogRedirection['dialogId']; const beforeAndAfterDialog = await this.captureDialog(userId, baseUrl, tenantId, sessionId, beforeDialogId, referringDialogId); return {beforeDialogRedirection, afterDialogRedirection: dialogRedirectionVisitor.enclosedJsonObject(), beforeDialog: beforeAndAfterDialog['beforeDialog'], afterDialog: beforeAndAfterDialog['afterDialog']}; } public static async captureRecord(userId: string, baseUrl: string, tenantId: string, sessionId: string, beforeAndAfterValues: any, listDialogName: string): Promise<RecordVisitor> { const thisMethod = 'DialogProxyTools::captureRecord'; // ONLINE const onlineRootDialogVisitor = new DialogVisitor(beforeAndAfterValues.beforeDialog); const onlineEditorDialogVisitor = onlineRootDialogVisitor.visitChildAtName(listDialogName); const onlineEditorDialogId = onlineEditorDialogVisitor.visitId(); const onlineEditorRecordPath = `tenants/${tenantId}/sessions/${sessionId}/dialogs/${onlineEditorDialogId}/record`; // Log.info(`${thisMethod} -- capturing online record: ${onlineEditorRecordPath}`); const onlineEditorRecordJcr = await DialogProxyTools.commonFetchClient().getJson(baseUrl, onlineEditorRecordPath); if (onlineEditorRecordJcr.statusCode !== 200) { throw new Error(`Unexpected result when getting record: ${onlineEditorRecordJcr.statusCode}`); } const onlineEditorRecordVisitor = new RecordVisitor(onlineEditorRecordJcr.value); // OFFLINE const offlineRootDialogVisitor = new DialogVisitor(beforeAndAfterValues.afterDialog); const offlineEditorDialogVisitor = offlineRootDialogVisitor.visitChildAtName(listDialogName); const offlineEditorDialogId = offlineEditorDialogVisitor.visitId(); // WRITE TO STORAGE // Log.info(`${thisMethod} -- writing online record to offline editor dialog id: ${offlineEditorDialogId}`); // Log.info(`${thisMethod} -- writing online record to offline storage: ${onlineEditorRecordVisitor.copyAsJsonString()}`); await DialogProxyTools.writeRecord(userId, tenantId, offlineEditorDialogId, onlineEditorRecordVisitor); return onlineEditorRecordVisitor; } public static async captureRecordSet(userId: string, baseUrl: string, tenantId: string, sessionId: string, beforeAndAfterValues: any, listDialogName: string): Promise<RecordSetVisitor> { const thisMethod = 'DialogProxyTools::captureRecordSet'; // ONLINE const onlineRootDialogVisitor = new DialogVisitor(beforeAndAfterValues.beforeDialog); const onlineQueryDialogVisitor = onlineRootDialogVisitor.visitChildAtName(listDialogName); const onlineQueryDialogId = onlineQueryDialogVisitor.visitId(); const onlineQueryRecordsPath = `tenants/${tenantId}/sessions/${sessionId}/dialogs/${onlineQueryDialogId}/records`; const onlineQueryParameters = { fetchDirection: "FORWARD", fetchMaxRecords: 999, type: "hxgn.api.dialog.QueryParameters" }; // Log.info(`${thisMethod} -- capturing online record set: ${onlineQueryRecordsPath}`); const onlineQueryRecordsJcr = await DialogProxyTools.commonFetchClient().postJson(baseUrl, onlineQueryRecordsPath, onlineQueryParameters); if (onlineQueryRecordsJcr.statusCode !== 200) { throw new Error(`Unexpected result when getting records: ${onlineQueryRecordsJcr.statusCode}`); } const onlineQueryRecordSetVisitor = new RecordSetVisitor(onlineQueryRecordsJcr.value); // OFFLINE const offlineRootDialogVisitor = new DialogVisitor(beforeAndAfterValues.afterDialog); const offlineQueryDialogVisitor = offlineRootDialogVisitor.visitChildAtName(listDialogName); const offlineQueryDialogId = offlineQueryDialogVisitor.visitId(); // WRITE TO STORAGE // Log.info(`${thisMethod} -- writing online record set to offline query dialog id: ${offlineQueryDialogId}`); // Log.info(`${thisMethod} -- writing online record set to offline storage: ${onlineQueryRecordSetVisitor.copyAsJsonString()}`); await DialogProxyTools.writeRecordSet(userId, tenantId, offlineQueryDialogId, onlineQueryRecordSetVisitor); return onlineQueryRecordSetVisitor; } public static async captureWorkbenchActionRedirectionAndDialog(userId: string, baseUrl: string, tenantId: string, sessionId: string, workbenchId: string, actionId: string): Promise<any> { const thisMethod = 'DialogProxyTools::captureWorkbenchActionRedirectionAndDialog'; const resourcePath = `tenants/${tenantId}/sessions/${sessionId}/workbenches/${workbenchId}/actions/${actionId}`; // Log.info(`${thisMethod} -- capturing workbench redirection and dialog: ${resourcePath}`); // GET REDIRECTION // // Log.info(`${thisMethod} -- capturing online dialog redirection: ${resourcePath}`); const dialogRedirectionJcr = await DialogProxyTools.commonFetchClient().postJson(baseUrl, resourcePath, {}); if (dialogRedirectionJcr.statusCode !== 303) { throw new Error(`Unexpected result when posting workbench ${workbenchId} action ${actionId}: ${dialogRedirectionJcr.statusCode}`); } // Log.info(`${thisMethod} -- workbench action redirection: ${JSON.stringify(dialogRedirectionJcr.value)}`); // WRITE REDIRECTION // const dialogRedirectionVisitor = new DialogRedirectionVisitor(dialogRedirectionJcr.value); const beforeDialogRedirection = dialogRedirectionVisitor.copyAsJsonObject(); dialogRedirectionVisitor.deriveDialogIdsFromDialogNameAndRecordId(); // Log.info(`${thisMethod} -- writing online dialog redirection to offline redirection id: ${dialogRedirectionVisitor.visitId()}`); // Log.info(`${thisMethod} -- writing online dialog redirection to offline storage: ${dialogRedirectionVisitor.copyAsJsonString()}`); await this.writeDialogRedirection(userId, tenantId, workbenchId, actionId, dialogRedirectionVisitor); // CAPTURE DIALOG // const beforeDialogId = beforeDialogRedirection['dialogId']; const beforeAndAfterDialog = await this.captureDialog(userId, baseUrl, tenantId, sessionId, beforeDialogId, null); return {beforeDialogRedirection, afterDialogRedirection: dialogRedirectionVisitor.enclosedJsonObject(), beforeDialog: beforeAndAfterDialog['beforeDialog'], afterDialog: beforeAndAfterDialog['afterDialog']}; } public static async clearAllStorageAt(userId: string, tenantId: string): Promise<void> { const thisMethod = 'DialogProxyTools::clearAllStorageAt'; let prefix = this.STORAGE_KEY_PREFIX.replace('${userId}', userId); prefix = prefix.replace('${tenantId}', tenantId); // Log.info(`${thisMethod} -- ************** BEGIN CLEAR ALL STORAGE AT **************`); const allKeys = await storage.getAllKeys(); for (const k of allKeys) { if (k.startsWith(prefix)) { await storage.removeItem(k); // Log.info(`${thisMethod} -- Removed from storage: ${k}`); } } // Log.info(`${thisMethod} -- ************** END CLEAR ALL STORAGE AT **************`); } public static commonFetchClient(): FetchClient { return this.COMMON_FETCH_CLIENT; } public static constructDialogMessageModel(message: string) { return {type: this.DIALOG_MESSAGE_MODEL_TYPE, message}; } public static constructLoginModel(userId: string, password: string): object { return { "userId": userId, "password": password, "clientType": "MOBILE", "deviceProperties": {}, "type": this.LOGIN_MODEL_TYPE }; } public static constructRedirectionStorageKey(userId: string, tenantId: string, stateId: string, actionId: string): string { let key = this.REDIRECTION_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${stateId}', stateId); key = key.replace('${actionId}', actionId); return key; } public static constructRequestNotValidDuringOfflineMode(action: string, resourcePath: string): JsonClientResponse { return new JsonClientResponse(this.constructDialogMessageModel(`${action} at ${resourcePath} is not valid during offline mode: `), 400); } /** * Construct an empty null redirection with the following defaults: * referringObject will be a type of "hxgn.api.dialog.ReferringDialog" * dialogAlias=null * dialogName=null * dialogMode='READ' * actionId=null * dialogId=null * refreshNeeded=true * id=randomly generated value */ public static constructNullRedirection(tenantId: string, sessionId: string): StringDictionary { const nullRedirectionId = DialogProxyTools.constructNullRedirectionId(); return { "tenantId": tenantId, "referringObject": { "dialogMode": "READ", "dialogAlias": null, "dialogName": null, "actionId": null, "type": "hxgn.api.dialog.ReferringDialog", "dialogId": null }, "refreshNeeded": true, "sessionId": sessionId, "id": nullRedirectionId, "type": "hxgn.api.dialog.NullRedirection" }; } public static constructNullRedirectionId(): string { return `null_redirection__offline_${Date.now()}`; } // ----- MODEL QUERY METHODS ----- // public static isActionParametersModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.ACTION_PARAMETERS_MODEL_TYPE; } public static isAnnotationModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.ANNOTATION_MODEL_TYPE; } public static isDialogModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.EDITOR_DIALOG_MODEL_TYPE || jsonObject['type'] === this.QUERY_DIALOG_MODEL_TYPE; } public static isLoginModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.LOGIN_MODEL_TYPE; } public static isPropertyModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.PROPERTY_MODEL_TYPE; } public static isPropertyDefModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.PROPERTY_DEF_MODEL_TYPE; } public static isRecordModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.RECORD_MODEL_TYPE; } public static isRecordSetModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.RECORD_SET_MODEL_TYPE; } public static isReferringDialogModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.REFERRING_DIALOG_MODEL_TYPE; } public static isReferringWorkbenchModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.REFERRING_WORKBENCH_MODEL_TYPE; } public static isSessionModel(jsonObject: object): boolean { if (!jsonObject || !jsonObject['type']) { return false; } return jsonObject['type'] === this.SESSION_MODEL_TYPE; } // ----- PATH QUERY METHODS ----- // public static readDialogAsOfflineResponse(userId: string, request: DialogRequest): Promise<JsonClientResponse> { return this.readDialogAsVisitor(userId, request).then(dialogVisitor => { return dialogVisitor ? new JsonClientResponse(dialogVisitor.enclosedJsonObject(), 200) : this.constructRequestNotValidDuringOfflineMode('readDialogAsOfflineResponse', request.resourcePath()); }); } public static readDialogAsVisitor(userId: string, request: DialogRequest): Promise<DialogVisitor> { const thisMethod = 'DialogProxyTools::readDialogAsVisitor'; const pathFields = request.deconstructGetDialogPath(); const tenantId = pathFields.tenantId; const sessionId = pathFields.sessionId; const dialogId = pathFields.dialogId; let key = this.DIALOG_STORAGE_KEY.replace('${tenantId}', tenantId); key = key.replace('${userId}', userId); key = key.replace('${dialogId}', dialogId); // Log.info(`${thisMethod} -- reading for dialog at key: ${key}`); return storage.getJson(key).then(jsonObject => jsonObject ? new DialogVisitor(jsonObject) : null); } public static readDialogRedirectionAsVisitor(userId: string, tenantId: string, stateId: string, actionId: string): Promise<DialogRedirectionVisitor> { const thisMethod = 'DialogProxyTools::readDialogRedirectionAsVisitor'; const key = this.constructRedirectionStorageKey(userId, tenantId, stateId, actionId); // Log.info(`${thisMethod} -- reading for redirection at key: ${key}`); return storage.getJson(key).then(jsonObject => jsonObject ? new DialogRedirectionVisitor(jsonObject) : null); } public static readMenuActionRedirectionAsOfflineResponse(userId: string, request: DialogRequest): Promise<JsonClientResponse> { return this.readMenuActionRedirectionAsVisitor(userId, request).then(dialogRedirectionVisitor => { return dialogRedirectionVisitor ? new JsonClientResponse(dialogRedirectionVisitor.enclosedJsonObject(), 303) : this.constructRequestNotValidDuringOfflineMode('readMenuActionRedirectionAsOfflineResponse', request.resourcePath()); }); } public static readMenuActionRedirectionAsVisitor(userId: string, request: DialogRequest): Promise<DialogRedirectionVisitor> { const pathFields = request.deconstructPostMenuActionPath(); let actionIdAtTargetId = request.actionId(); const targetId = request.targetId(); if (targetId) { const targetIdEncoded = Base64.encodeUrlSafeString(targetId); actionIdAtTargetId = `${request.actionId()}@${targetIdEncoded}`; } return this.readDialogRedirectionAsVisitor(userId, pathFields.tenantId, pathFields.dialogId, actionIdAtTargetId); } public static readPropertyCommit(userId: string, tenantId: string, dialogId: string, propertyName: string): Promise<any> { let key = this.PROPERTY_COMMIT_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); key = key.replace('${propertyName}', propertyName); return storage.getJson(key); } public static readRecordAsOfflineResponse(userId: string, request: DialogRequest): Promise<JsonClientResponse> { return this.readRecordAsVisitorFromRequest(userId, request).then(recordVisitor => { return recordVisitor ? new JsonClientResponse(recordVisitor.enclosedJsonObject(), 200) : this.constructRequestNotValidDuringOfflineMode('readRecordAsOfflineResponse', request.resourcePath()); }); } public static readRecordAsVisitor(userId: string, tenantId: string, dialogId: string): Promise<RecordVisitor> { let key = this.RECORD_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); return storage.getJson(key).then(jsonObject => jsonObject ? new RecordVisitor(jsonObject) : null); } public static readRecordAsVisitorFromRequest(userId: string, request: DialogRequest): Promise<RecordVisitor> { const pathFields = request.deconstructGetRecordPath(); const tenantId = pathFields.tenantId; const dialogId = pathFields.dialogId; return this.readRecordAsVisitor(userId, tenantId, dialogId); } public static readRecordCommitAsVisitor(userId: string, tenantId: string, dialogId: string): Promise<RecordVisitor> { let key = this.RECORD_COMMIT_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); return storage.getJson(key).then(jsonObject => jsonObject ? new RecordVisitor(jsonObject) : null); } public static readRecordSetAsOfflineResponse(userId: string, request: DialogRequest): Promise<JsonClientResponse> { return this.readRecordSetAsVisitor(userId, request).then(recordSetVisitor => { return recordSetVisitor ? new JsonClientResponse(recordSetVisitor.enclosedJsonObject(), 200) : this.constructRequestNotValidDuringOfflineMode('readRecordSetAsOfflineResponse', request.resourcePath()); }); } public static async readRecordSetAsVisitor(userId: string, request: DialogRequest): Promise<RecordSetVisitor> { const pathFields = request.deconstructPostRecordsPath(); const tenantId = pathFields.tenantId; const sessionId = pathFields.sessionId; const dialogId = pathFields.dialogId; let key = this.RECORD_SET_STORAGE_KEY.replace('${tenantId}', tenantId); key = key.replace('${userId}', userId); key = key.replace('${dialogId}', dialogId); const jsonObject = await storage.getJson(key); if (!jsonObject) { return null; } const recordSetVisitor = new RecordSetVisitor(jsonObject); if (request.body().fromRecordId) { recordSetVisitor.fromRecordId(request.body().fromRecordId); } return recordSetVisitor; } public static readSessionContentAsOfflineResponse(userId: string, request: DialogRequest): Promise<JsonClientResponse> { const pathFields = request.deconstructPostSessionContentPath(); const tenantId = pathFields.tenantId; const contentId = pathFields.contentId; const parametersVisitor = new ReadLargePropertyParametersVisitor(request.body()); const sequence = parametersVisitor.visitSequence(); return this.readSessionContentAsVisitor(userId, tenantId, contentId, sequence).then(largePropertyVisitor => { return largePropertyVisitor ? new JsonClientResponse(largePropertyVisitor.enclosedJsonObject(), 200) : this.constructRequestNotValidDuringOfflineMode('readSessionContentAsOfflineResponse', request.resourcePath()); }); } public static readSessionContentAsVisitor(userId: string, tenantId: string, contentId: string, sequence: number): Promise<LargePropertyVisitor> { let key = this.CONTENT_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${contentId}', contentId); key = key.replace('${sequence}', sequence.toString()); return storage.getJson(key).then(jsonObject => jsonObject ? new LargePropertyVisitor(jsonObject) : null); } public static readWorkbenchActionRedirectionAsOfflineResponse(userId: string, request: DialogRequest): Promise<JsonClientResponse> { const pathFields = request.deconstructPostWorkbenchActionPath(); return this.readDialogRedirectionAsVisitor(userId, pathFields.tenantId, pathFields.workbenchId, pathFields.actionId).then(dialogRedirectionVisitor => { return dialogRedirectionVisitor ? new JsonClientResponse(dialogRedirectionVisitor.enclosedJsonObject(), 303) : this.constructRequestNotValidDuringOfflineMode('readWorkbenchActionRedirectionAsOfflineResponse', request.resourcePath()); }); } public static async showStoredDialogNavigation(): Promise<void> { const thisMethod = 'DialogProxyTools::showAllRedirectionStorageKeys'; // Log.info(`${thisMethod} -- ************** BEGIN SHOW ALL REDIRECTION STORAGE KEYS **************`); const allKeys = await storage.getAllKeys(); for (const k of allKeys) { if (k.endsWith('.redirection')) { const redirection = await storage.getJson(k); // Log.info(`${thisMethod} -- ${k} => \n${redirection.dialogName}(id=${redirection.id})\n`); } } // Log.info(`${thisMethod} -- ************** END SHOW ALL REDIRECTION STORAGE KEYS **************`); } public static async showAllStorageKeys(): Promise<void> { const thisMethod = 'DialogProxyTools::showAllStorageKeys'; // Log.info(`${thisMethod} -- ************** BEGIN SHOW ALL STORAGE KEYS **************`); const allKeys = await storage.getAllKeys(); for (const k of allKeys) { const v = await clientStorage.getItem(k); // Log.info(`${thisMethod} -- ${k}`); } // Log.info(`${thisMethod} -- ************** END SHOW ALL STORAGE KEYS **************`); } public static async showAllStorageKeysAndValues(): Promise<void> { const thisMethod = 'DialogProxyTools::showAllStorageKeysAndValues'; // Log.info(`${thisMethod} -- ************** BEGIN SHOW ALL STORAGE KEYS AND VALUES **************`); const allKeys = await storage.getAllKeys(); for (const k of allKeys) { const v = await clientStorage.getItem(k); // Log.info(`${thisMethod} -- ${k}: ${v}`); } // Log.info(`${thisMethod} -- ************** END SHOW ALL STORAGE KEYS AND VALUES **************`); } public static writeContentChunk(userId: string, tenantId: string, contentId: string, sequence: number, largePropertyVisitor: LargePropertyVisitor): Promise<void> { let key = this.CONTENT_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${contentId}', contentId); key = key.replace('${sequence}', sequence.toString()); return storage.setJson(key, largePropertyVisitor.enclosedJsonObject()); } public static writeContentRedirection(userId: string, tenantId: string, stateId: string, actionId: string, contentRedirectionVistor: ContentRedirectionVisitor): Promise<void> { const key = this.constructRedirectionStorageKey(userId, tenantId, stateId, actionId); return storage.setJson(key, contentRedirectionVistor.enclosedJsonObject()); } public static writeDialog(userId: string, tenantId: string, dialogVisitor: DialogVisitor): Promise<void> { let key = this.DIALOG_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogVisitor.visitId()); return storage.setJson(key, dialogVisitor.enclosedJsonObject()); } public static writeDialogRedirection(userId: string, tenantId: string, stateId: string, actionId: string, dialogRedirectionVistor: DialogRedirectionVisitor): Promise<void> { const key = this.constructRedirectionStorageKey(userId, tenantId, stateId, actionId); return storage.setJson(key, dialogRedirectionVistor.enclosedJsonObject()); } public static async writePropertyCommit(userId: string, tenantId: string, dialogId: string, propertyName: string, writeLargePropertyParametersVisitor: WriteLargePropertyParametersVisitor): Promise<void> { let key = this.PROPERTY_COMMIT_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); key = key.replace('${propertyName}', propertyName); let writeHistory = []; if (writeLargePropertyParametersVisitor.visitAppend()) { const jsonObject = await storage.getJson(key); if (jsonObject) { writeHistory = jsonObject; } } writeHistory.push(writeLargePropertyParametersVisitor.enclosedJsonObject()); return storage.setJson(key, writeHistory); } public static writeRecord(userId: string, tenantId: string, dialogId: string, recordVisitor: RecordVisitor): Promise<void> { let key = this.RECORD_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); return storage.setJson(key, recordVisitor.enclosedJsonObject()); } public static writeRecordCommit(userId: string, tenantId: string, dialogId: string, recordVisitor: RecordVisitor): Promise<void> { let key = this.RECORD_COMMIT_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); return storage.setJson(key, recordVisitor.enclosedJsonObject()); } public static writeRecordSet(userId: string, tenantId: string, dialogId: string, recordSetVisitor: RecordSetVisitor): Promise<void> { let key = this.RECORD_SET_STORAGE_KEY.replace('${userId}', userId); key = key.replace('${tenantId}', tenantId); key = key.replace('${dialogId}', dialogId); return storage.setJson(key, recordSetVisitor.enclosedJsonObject()); } }