import type { Serialized } from '@rocket.chat/core-typings'; import { Emitter } from '@rocket.chat/emitter'; import type { Method, PathFor, OperationParams, OperationResult, UrlParams, PathPattern } from '@rocket.chat/rest-typings'; import type { ServerMethodName, ServerMethodParameters, ServerMethodReturn, StreamerCallbackArgs, UploadResult, StreamNames, StreamKeys, } from '@rocket.chat/ui-contexts'; import { ServerContext } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import { compile } from 'path-to-regexp'; import type { FC } from 'react'; import React from 'react'; import { Info as info } from '../../app/utils/client'; import { sdk } from '../../app/utils/client/lib/SDKClient'; const absoluteUrl = (path: string): string => Meteor.absoluteUrl(path); const callMethod = ( methodName: MethodName, ...args: ServerMethodParameters ): Promise> => Meteor.callAsync(methodName, ...args); const callEndpoint = ({ method, pathPattern, keys, params, }: { method: TMethod; pathPattern: TPathPattern; keys: UrlParams; params: OperationParams; }): Promise>> => { const compiledPath = compile(pathPattern, { encode: encodeURIComponent })(keys) as any; switch (method) { case 'GET': return sdk.rest.get(compiledPath, params as any) as any; case 'POST': return sdk.rest.post(compiledPath, params as any) as any; case 'PUT': return sdk.rest.put(compiledPath, params as never) as never; case 'DELETE': return sdk.rest.delete(compiledPath, params as any) as any; default: throw new Error('Invalid HTTP method'); } }; const uploadToEndpoint = (endpoint: PathFor<'POST'>, formData: any): Promise => sdk.rest.post(endpoint as any, formData); const getStream = >( streamName: N, _options?: { retransmit?: boolean | undefined; retransmitToSelf?: boolean | undefined; }, ): ((eventName: K, callback: (...args: StreamerCallbackArgs) => void) => () => void) => { return (eventName, callback): (() => void) => { return sdk.stream(streamName, [eventName], callback as (...args: any[]) => void).stop; }; }; const ee = new Emitter>(); const events = new Map void>(); const getSingleStream = >( streamName: N, _options?: { retransmit?: boolean | undefined; retransmitToSelf?: boolean | undefined; }, ): ((eventName: K, callback: (...args: StreamerCallbackArgs) => void) => () => void) => { const stream = getStream(streamName); return (eventName, callback): (() => void) => { ee.on(`${streamName}/${eventName}`, callback); const handler = (...args: any[]): void => { ee.emit(`${streamName}/${eventName}`, ...args); }; const stop = (): void => { // If someone is still listening, don't unsubscribe ee.off(`${streamName}/${eventName}`, callback); if (ee.has(`${streamName}/${eventName}`)) { return; } const unsubscribe = events.get(`${streamName}/${eventName}`); if (unsubscribe) { unsubscribe(); events.delete(`${streamName}/${eventName}`); } }; if (!events.has(`${streamName}/${eventName}`)) { events.set(`${streamName}/${eventName}`, stream(eventName, handler)); } return stop; }; }; const contextValue = { info, absoluteUrl, callMethod, callEndpoint, uploadToEndpoint, getStream, getSingleStream, }; const ServerProvider: FC = ({ children }) => ; export default ServerProvider;