Resolver

Resolver

Resolvers make requests, parse responses, and format data.

Constructor

new Resolver(service)

Source:
Parameters:
Name Type Description
service LinkService

The service this Resolver is registered to.

Methods

builder() → {DocumentBuilder}

Source:

Create a new DocumentBuilder instance. Purely a convenience method.

Returns:

New instance.

Type
DocumentBuilder

getExamples() → {Array.<ExampleURL>|Array.<String>|Array.<URL>}

Source:

Get an array of example URLs that this Resolver can handle. Used for populating a selection field in testing clients.

The default implementation checks if the Resolver class has a static array called examples and, if so, returns that.

It is not necessary to provide examples, but examples do make testing easier.

Example
class MyResolver extends Resolver { };
MyResolver.examples = [
    {title: 'Some Page', url: 'https://example.com/'}
];
Returns:

List of URLs.

Type
Array.<ExampleURL> | Array.<String> | Array.<URL>

handles(host) → {Boolean}

Source:

Determine whether or not this Resolver can handle a request for a given domain.

The default implementation checks if the Resolver class has a static array called hosts and, if so, checks to see if the host is in that list.

If you're not using the hosts array, you must override the method. Otherwise, it will throw an error.

Example
class MyResolver extends Resolver { };
MyResolver.hosts = ['example.org'];

const inst = new MyResolver(link_service);

inst.handles('google.com'); // === false
inst.handles('example.org'); // === true
inst.handles('test.example.org'); // === true
Parameters:
Name Type Description
host String

The domain to check.

Returns:

Whether or not this Resolver can handle requests for that domain.

Type
Boolean

processBody(body, mode, ctx, request) → {Object|UseMetadata|Redirect}

Source:

The final method called while a Resolver works. This method is used for handling the parsed response body. If this method returns a non-null value, that value will be the result emitted from the LinkService.

Depending on the parsing mode, body will be one of several different objects. If the mode is buffer, then body will be a Buffer instance as returned from node-fetch. If mode is json, then body will be the parsed JSON object.

If mode is html or xml, then body will be a cheerio instance.

Example
processBody(body, mode) {
    if ( ! body?.video || mode !== 'json' )
        return UseMetadata;

    return {
        v: 5,
        accent: '#f00',
        short: this.builder()
            .setTitle(body.video.title)
            .setSubtitle('Example Service')
            .setLogo(SERVICE_LOGO)
            .addImage(body.video.thumbnail)
            .addField(
                i18nToken('embed.example.length', 'Length'),
                formatToken('duration', body.video.length)
            )
    };
}
Parameters:
Name Type Description
body Buffer | Object | cheerio

The parsed response body. This can be one of several different objects, depending on the detected Content-Type of the response. If ctx.parse is set, the response body will be parsed in that manner rather than through content detection.

mode String

The mode used for parsing the response body. This will be one of: buffer, json, html, or xml

ctx RequestContext

A context object that will be maintained while processing this URL to keep track of extra data.

request FetchResponse

The result of our fetch request, in case it's still needed for some reason.

Returns:

If an object is returned, that data will be used as the final response. If UseMetadata or Redirect are returned, the Resolver will pass control back to its LinkService.

Type
Object | UseMetadata | Redirect

processHeaders(request, ctx) → {Boolean|UseMetadata|Redirect}

Source:

The second method called while a Resolver works. This method is used for determining what to do once we've received response headers.

The default implementation of this method just returns request.ok to request response body handling if the request is okay. (Meaning: the status code was in the range of 200-299.)

In some cases, we'll receive all the information we need in just the response headers. In those cases, we can return a falsey value from this method to avoid parsing the response body at all.

If we need to redirect, or we determine that the metadata resolver would have better results, we can also fall back to those behaviors.

Note: If ctx.follow_redirects has not been set to false, the Resolver instance will automatically handle Location and Refresh headers. The following example is only an example and does not need to be replicated in your own functions.

Example
processHeaders(request, ctx) {
    if ( ! request.ok )
        return false;

    if ( request.headers.has('Location') )
        return new Redirect(request.headers.get('Location'), ctx.url);

    return true;
}
Parameters:
Name Type Description
request FetchResponse

The result after waiting for our fetch request to resolve.

ctx RequestContext

A context object that will be maintained while processing this URL to keep track of extra data.

Returns:

If UseMetadata or Redirect are returned, the Resolver will pass control back to its LinkService. Otherwise, the truthiness of the return value will be used to determine whether or not we should spend the time to handle the response body.

Type
Boolean | UseMetadata | Redirect

proxyImage(url, sizeopt) → {String}

Source:

Create a URL for passing an image through a proxy, used to avoid leaking end-user IP addresses and to perform sanity checks on the contents of the image.

This just calls LinkService#proxyImage as a convenience method.

Parameters:
Name Type Attributes Default Description
url String | URL

The URL to proxy.

size Number <optional>
324

The size parameter to pass to the proxy server.

Returns:

The proxied image URL, or null if no proxy server is configured.

Type
String

transformURL(url, ctx) → {String|URL|UseMetadata|Redirect}

Source:

The first method called while a Resolver works. This method is used for further processing a URL and determining what resource we actually want to fetch from the remove host, if any.

Here, we can process a URL and, rather than requesting the normal webpage, redirect the request to the site's API. If we determine that we can't actually handle a specific URL, we can also fall back to the metadata provider here or outright redirect to another URL.

We can also set cache_key on the ctx object to improve the cache hit rate when multiple URLs can describe the same resource.

Example
transformURL(url, ctx) {
    if ( ! url.pathname.startsWith('/video/') )
        return UseMetadata;

    const video_id = url.pathname.slice(7);
    ctx.cache_key = `my-service--${video_id}`;
    return `https://api.service.example/v2/video?id=${video_id}`;
}
Parameters:
Name Type Description
url URL

The URL we're processing.

ctx RequestContext

A context object that will be maintained while processing this URL to keep track of extra data.

Returns:

If a String or URL are returned, they will be requested. If UseMetadata or Redirect are returned, the Resolver will pass control back to its LinkService.

Type
String | URL | UseMetadata | Redirect