Skip to content

Commit

Permalink
Add handlers for App methods on Deno and refactor their usages on Node (
Browse files Browse the repository at this point in the history
  • Loading branch information
d-gubert authored Dec 27, 2023
1 parent 4a6c7e5 commit 0ed2fd6
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 21 deletions.
3 changes: 1 addition & 2 deletions deno-runtime/handlers/app/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default async function handleConstructApp(params: unknown): Promise<boole
const [appPackage] = params as [IParseAppPackageResult];

if (!appPackage?.info?.id || !appPackage?.info?.classFile || !appPackage?.files) {
throw new Error('Invalid params', { cause: 'invalid_param_type'});
throw new Error('Invalid params', { cause: 'invalid_param_type' });
}

AppObjectRegistry.set('id', appPackage.info.id);
Expand Down Expand Up @@ -93,4 +93,3 @@ export default async function handleConstructApp(params: unknown): Promise<boole

return true;
}

14 changes: 14 additions & 0 deletions deno-runtime/handlers/app/handleGetStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppObjectRegistry } from '../../AppObjectRegistry.ts';

export default function handleGetStatus(): Promise<boolean> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.getStatus !== 'function') {
throw new Error('App must contain a getStatus function', {
cause: 'invalid_app',
});
}

return app.getStatus();
}
18 changes: 18 additions & 0 deletions deno-runtime/handlers/app/handleOnDisable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppObjectRegistry } from '../../AppObjectRegistry.ts';
import { AppAccessorsInstance } from '../../lib/accessors/mod.ts';

export default async function handleOnDisable(): Promise<boolean> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.onDisable !== 'function') {
throw new Error('App must contain an onDisable function', {
cause: 'invalid_app',
});
}

await app.onDisable(AppAccessorsInstance.getConfigurationModify());

return true;
}

16 changes: 16 additions & 0 deletions deno-runtime/handlers/app/handleOnEnable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';

import { AppObjectRegistry } from '../../AppObjectRegistry.ts';
import { AppAccessorsInstance } from '../../lib/accessors/mod.ts';

export default function handleOnEnable(): Promise<boolean> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.onEnable !== 'function') {
throw new Error('App must contain an onEnable function', {
cause: 'invalid_app',
});
}

return app.onEnable(AppAccessorsInstance.getEnvironmentRead(), AppAccessorsInstance.getConfigurationModify());
}
29 changes: 29 additions & 0 deletions deno-runtime/handlers/app/handleOnInstall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppObjectRegistry } from '../../AppObjectRegistry.ts';
import { AppAccessorsInstance } from '../../lib/accessors/mod.ts';

export default async function handleOnInstall(params: unknown): Promise<boolean> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.onInstall !== 'function') {
throw new Error('App must contain an onInstall function', {
cause: 'invalid_app',
});
}

if (!Array.isArray(params)) {
throw new Error('Invalid params', { cause: 'invalid_param_type' });
}

const [context] = params as [Record<string, unknown>];

await app.onInstall(
context,
AppAccessorsInstance.getReader(),
AppAccessorsInstance.getHttp(),
AppAccessorsInstance.getPersistence(),
AppAccessorsInstance.getModifier(),
);

return true;
}
21 changes: 21 additions & 0 deletions deno-runtime/handlers/app/handleOnPreSettingUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppObjectRegistry } from '../../AppObjectRegistry.ts';
import { AppAccessorsInstance } from '../../lib/accessors/mod.ts';

export default function handleOnPreSettingUpdate(params: unknown): Promise<object> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.onPreSettingUpdate !== 'function') {
throw new Error('App must contain an onPreSettingUpdate function', {
cause: 'invalid_app',
});
}

if (!Array.isArray(params)) {
throw new Error('Invalid params', { cause: 'invalid_param_type' });
}

const [setting] = params as [Record<string, unknown>];

return app.onPreSettingUpdate(setting, AppAccessorsInstance.getConfigurationModify(), AppAccessorsInstance.getReader(), AppAccessorsInstance.getHttp());
}
23 changes: 23 additions & 0 deletions deno-runtime/handlers/app/handleOnSettingUpdated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppObjectRegistry } from '../../AppObjectRegistry.ts';
import { AppAccessorsInstance } from '../../lib/accessors/mod.ts';

export default async function handleOnSettingUpdated(params: unknown): Promise<boolean> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.onSettingUpdated !== 'function') {
throw new Error('App must contain an onSettingUpdated function', {
cause: 'invalid_app',
});
}

if (!Array.isArray(params)) {
throw new Error('Invalid params', { cause: 'invalid_param_type' });
}

const [setting] = params as [Record<string, unknown>];

await app.onSettingUpdated(setting, AppAccessorsInstance.getConfigurationModify(), AppAccessorsInstance.getReader(), AppAccessorsInstance.getHttp());

return true;
}
29 changes: 29 additions & 0 deletions deno-runtime/handlers/app/handleOnUninstall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppObjectRegistry } from '../../AppObjectRegistry.ts';
import { AppAccessorsInstance } from '../../lib/accessors/mod.ts';

export default async function handleOnUninstall(params: unknown): Promise<boolean> {
const app = AppObjectRegistry.get<App>('app');

if (typeof app?.onUninstall !== 'function') {
throw new Error('App must contain an onUninstall function', {
cause: 'invalid_app',
});
}

if (!Array.isArray(params)) {
throw new Error('Invalid params', { cause: 'invalid_param_type' });
}

const [context] = params as [Record<string, unknown>];

await app.onUninstall(
context,
AppAccessorsInstance.getReader(),
AppAccessorsInstance.getHttp(),
AppAccessorsInstance.getPersistence(),
AppAccessorsInstance.getModifier(),
);

return true;
}
24 changes: 24 additions & 0 deletions deno-runtime/handlers/app/handleSetStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { App } from '@rocket.chat/apps-engine/definition/App.ts';
import { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus.ts';

import { AppObjectRegistry } from '../../AppObjectRegistry.ts';

export default async function handleSetStatus(params: unknown): Promise<null> {
if (!Array.isArray(params) || !Object.values(AppStatus).includes(params[0])) {
throw new Error('Invalid params', { cause: 'invalid_param_type' });
}

const [status] = params as [AppStatus];

const app = AppObjectRegistry.get<App>('app');

if (!app || typeof app['setStatus'] !== 'function') {
throw new Error('App must contain a setStatus function', {
cause: 'invalid_app',
});
}

await app['setStatus'](status);

return null;
}
27 changes: 26 additions & 1 deletion deno-runtime/handlers/app/handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { Defined, JsonRpcError } from 'jsonrpc-lite';

import handleConstructApp from './construct.ts';
import handleInitialize from './initialize.ts';
import handleInitialize from "./handleInitialize.ts";
import handleGetStatus from "./handleGetStatus.ts";
import handleSetStatus from "./handleSetStatus.ts";
import handleOnEnable from "./handleOnEnable.ts";
import handleOnInstall from "./handleOnInstall.ts";
import handleOnDisable from "./handleOnDisable.ts";
import handleOnUninstall from "./handleOnUninstall.ts";
import handleOnPreSettingUpdate from "./handleOnPreSettingUpdate.ts";
import handleOnSettingUpdated from "./handleOnSettingUpdated.ts";

export default async function handleApp(method: string, params: unknown): Promise<Defined | JsonRpcError> {
const [, appMethod] = method.split(':');
Expand All @@ -11,6 +20,22 @@ export default async function handleApp(method: string, params: unknown): Promis
return await handleConstructApp(params);
case 'initialize':
return await handleInitialize();
case 'getStatus':
return await handleGetStatus();
case 'setStatus':
return await handleSetStatus(params);
case 'onEnable':
return await handleOnEnable();
case 'onDisable':
return await handleOnDisable();
case 'onInstall':
return await handleOnInstall(params);
case 'onUninstall':
return await handleOnUninstall(params);
case 'onPreSettingUpdate':
return await handleOnPreSettingUpdate(params);
case 'onSettingUpdated':
return await handleOnSettingUpdated(params);
default:
throw new JsonRpcError('Method not found', -32601);
}
Expand Down
1 change: 1 addition & 0 deletions deno-runtime/handlers/app/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export default async function handleInitialize(): Promise<boolean> {

return true;
}

22 changes: 4 additions & 18 deletions src/server/AppManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,7 @@ export class AppManager {
}

if (AppStatusUtils.isEnabled(app.getStatus())) {
await app
.call(AppMethod.ONDISABLE, this.accessorManager.getConfigurationModify(app.getID()))
.catch((e) => console.warn('Error while disabling:', e));
await app.call(AppMethod.ONDISABLE).catch((e) => console.warn('Error while disabling:', e));
}

await this.purgeAppConfig(app, { keepScheduledJobs: true });
Expand Down Expand Up @@ -887,14 +885,10 @@ export class AppManager {

private async installApp(storageItem: IAppStorageItem, app: ProxiedApp, user: IUser): Promise<boolean> {
let result: boolean;
const read = this.getAccessorManager().getReader(storageItem.id);
const http = this.getAccessorManager().getHttp(storageItem.id);
const persistence = this.getAccessorManager().getPersistence(storageItem.id);
const modifier = this.getAccessorManager().getModifier(storageItem.id);
const context = { user };

try {
await app.call(AppMethod.ONINSTALL, context, read, http, persistence, modifier);
await app.call(AppMethod.ONINSTALL, context);

result = true;
} catch (e) {
Expand Down Expand Up @@ -1000,11 +994,7 @@ export class AppManager {
await app.validateLicense();
await app.validateInstallation();

enable = (await app.call(
AppMethod.ONENABLE,
this.getAccessorManager().getEnvironmentRead(storageItem.id),
this.getAccessorManager().getConfigurationModify(storageItem.id),
)) as boolean;
enable = (await app.call(AppMethod.ONENABLE)) as boolean;

if (enable) {
status = isManual ? AppStatus.MANUALLY_ENABLED : AppStatus.AUTO_ENABLED;
Expand Down Expand Up @@ -1089,14 +1079,10 @@ export class AppManager {

private async uninstallApp(app: ProxiedApp, user: IUser): Promise<boolean> {
let result: boolean;
const read = this.getAccessorManager().getReader(app.getID());
const http = this.getAccessorManager().getHttp(app.getID());
const persistence = this.getAccessorManager().getPersistence(app.getID());
const modifier = this.getAccessorManager().getModifier(app.getID());
const context = { user };

try {
await app.call(AppMethod.ONUNINSTALL, context, read, http, persistence, modifier);
await app.call(AppMethod.ONUNINSTALL, context);

result = true;
} catch (e) {
Expand Down

0 comments on commit 0ed2fd6

Please sign in to comment.