Skip to content

Commit

Permalink
refactor: updated render to use common API
Browse files Browse the repository at this point in the history
  • Loading branch information
manchuck committed Jan 29, 2025
1 parent bd525d2 commit a14ca30
Showing 1 changed file with 56 additions and 152 deletions.
208 changes: 56 additions & 152 deletions lib/render.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
/* eslint-env es2018 */
const errors = require('./errors');
const fetch = require('node-fetch');
const { version } = require('../package.json');
const _ = require('lodash');
const generateJwt = require('./generateJwt.js');
const { api } = require('./api');

/**
* An object representing an Experience Composer renderer.
Expand Down Expand Up @@ -51,113 +47,14 @@ const generateJwt = require('./generateJwt.js');
* @class Render
*/

const generateHeaders = (config, additionalHeaders = {}) => ({
'User-Agent': 'OpenTok-Node-SDK/' + version,
'X-OPENTOK-AUTH': generateJwt(config),
Accept: 'application/json',
...additionalHeaders
});

const api = (
{
method,
config,
path,
params = {},
body = null,
headers = {}
},
callback
) => {
const rurl = new URL(config.apiEndpoint);
rurl.pathname = Array.isArray(path)
? _.compact(path).join('/')
: path;

rurl.searchParams = params;

// Increase the likely hood of cache hits
rurl.searchParams.sort();

const requestHeaders = generateHeaders(config, headers)
if (body && ['POST', 'PATCH', 'PUT'].includes(method)) {
requestHeaders['Content-Type'] = 'application/json';
}

Promise.resolve(fetch(
rurl,
{
method: method,
body: body ? JSON.stringify(body) : null,
headers: requestHeaders,
}
))
.then(async (response) => {
const otResponse = {
statusCode: response.status,
}
callback(null, otResponse, await response.json())
})
.catch(async (error) => {
callback(error);
});
};

const guardParams = (method, options, callback) => {
const cb = typeof options === 'function' ? options : callback;
const opts = typeof options !== 'function' ? options : { count: 50 };

if (typeof cb !== 'function') {
throw new errors.ArgumentError('No callback given to ' + method);
}

return [cb, opts];
};

const handleResponse = (callback, err, response) => {
const handleResponse = (callback) => (err, body, response) => {
if (err) {
callback(err);
return;
}

try {
const { statusCode } = response;

// TODO use the http-errors package
switch (statusCode) {
case 200:
callback(null, JSON.parse(response.body), response);
break;
case 202:
callback(null, response.body, response);
break;
case 401:
case 403:
callback(new errors.AuthError(), null, response);
break;
case 404:
callback(new errors.NotFoundError(), null, response);
break;
case 500:
callback(new errors.RequestError(), null, response);
break;
default:
callback(
new errors.RequestError('Unexpected response code: ' + statusCode),
null,
response
);
}
}
catch (exception) {
// Most Likely from JSON.parse
if (exception instanceof SyntaxError) {
callback(new errors.RequestError('Cannot decode JSON response'));
return;
}

callback(new Error('Uknown Error'));
}
callback(null, body, response);
};

/**
Expand All @@ -171,31 +68,31 @@ const handleResponse = (callback, err, response) => {
* @memberof Render
*/
exports.listRenders = (config, options, callback) => {
const [cb, opts] = guardParams('listRenders', options, callback);
const { offset, count } = opts;
if (typeof callback !== 'function') {
throw new errors.ArgumentError('No callback given to listRenders');
}

const { offset, count } = options;

if (count > 1000 || count < 1) {
throw new errors.ArgumentError('Count is out of range');
}

const params = new URLSearchParams();
const renderUrl = new URL(`${config.apiEndpoint}/v2/project/${config.apiKey}/render`);

if (offset) {
params.append('offset', offset);
renderUrl.searchParams.set('offset', offset);
}

if (count) {
params.append('count', count);
renderUrl.searchParams.set('count', count);
}

api(
{
path: 'v2/project/' + config.apiKey + '/render',
config: config,
params: params
},
_.partial(handleResponse, cb)
);
api({
config: config,
url: renderUrl.toString(),
callback: handleResponse(callback),
});
};

/**
Expand All @@ -209,15 +106,18 @@ exports.listRenders = (config, options, callback) => {
* @memberof Render
*/
exports.getRender = (config, renderId, callback) => {
const [cb] = guardParams('getRender', {}, callback);
if (typeof callback !== 'function') {
throw new errors.ArgumentError('No callback given to getRender');
}

api(
{
path: 'v2/project/' + config.apiKey + '/render/' + renderId,
config: config
},
_.partial(handleResponse, cb)
);
const renderUrl = new URL(`${config.apiEndpoint}/v2/project/${config.apiKey}/render/${renderId}`);

api({
method: 'GET',
config: config,
url: renderUrl.toString(),
callback: handleResponse(callback)
});
};

/**
Expand All @@ -232,24 +132,26 @@ exports.getRender = (config, renderId, callback) => {
* @memberof Render
*/
exports.startRender = (config, options, callback) => {
const [cb, opts] = guardParams('startRender', options, callback);
if (typeof callback !== 'function') {
throw new errors.ArgumentError('No callback given to startRender');
}

api(
{
method: 'POST',
path: 'v2/project/' + config.apiKey + '/render',
config: config,
body: {
sessionId: _.get(opts, 'sessionId'),
token: _.get(opts, 'token'),
url: _.get(opts, 'url'),
maxDuration: _.get(opts, 'maxDuration', 1800),
resolution: _.get(opts, 'resolution', '1280x720'),
statusCallbackUrl: _.get(opts, 'statusCallbackUrl')
}
const renderUrl = new URL(`${config.apiEndpoint}/v2/project/${config.apiKey}/render`);

api({
url: renderUrl.toString(),
config: config,
method: 'POST',
body: {
sessionId: _.get(opts, 'sessionId'),
token: _.get(opts, 'token'),
url: _.get(opts, 'url'),
maxDuration: _.get(opts, 'maxDuration', 1800),
resolution: _.get(opts, 'resolution', '1280x720'),
statusCallbackUrl: _.get(opts, 'statusCallbackUrl')
},
_.partial(handleResponse, cb)
);
callback: handleResponse(callback),
});
};

/**
Expand All @@ -263,14 +165,16 @@ exports.startRender = (config, options, callback) => {
* @memberof Render
*/
exports.stopRender = (config, renderId, callback) => {
const [cb] = guardParams('getRender', {}, callback);
if (typeof callback !== 'function') {
throw new errors.ArgumentError('No callback given to stopRender');
}

api(
{
method: 'DELETE',
path: 'v2/project/' + config.apiKey + '/render/' + renderId,
config: config
},
_.partial(handleResponse, cb)
);
const renderUrl = new URL(`${config.apiEndpoint}/v2/project/${config.apiKey}/render/${renderId}`);

api({
method: 'DELETE',
config: config,
url: renderUrl.toString(),
callback: handleResponse(callback),
});
};

0 comments on commit a14ca30

Please sign in to comment.