@salesforce/core
Version:
Core libraries to interact with SFDX projects, orgs, and APIs.
128 lines • 5.47 kB
JavaScript
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MyDomainResolver = void 0;
const node_dns_1 = require("node:dns");
const node_url_1 = require("node:url");
const node_util_1 = require("node:util");
const ts_types_1 = require("@salesforce/ts-types");
const kit_1 = require("@salesforce/kit");
const logger_1 = require("../logger/logger");
const sfdcUrl_1 = require("../util/sfdcUrl");
const pollingClient_1 = require("./pollingClient");
// Timeout for DNS lookup polling defaults to 3 seconds and should always be at least 3 seconds
const DNS_TIMEOUT = Math.max(3, new kit_1.Env().getNumber('SFDX_DNS_TIMEOUT', 3));
// Retry frequency for DNS lookup polling defaults to 1 second and should be at least 1 second
const DNS_RETRY_FREQ = Math.max(1, new kit_1.Env().getNumber('SFDX_DNS_RETRY_FREQUENCY', 1));
/**
* A class used to resolve MyDomains. After a ScratchOrg is created its host name my not be propagated to the
* Salesforce DNS service. This service is not exclusive to Salesforce My Domain URL and could be used for any hostname.
*
* ```
* (async () => {
* const options: MyDomainResolver.Options = {
* url: new URL('http://mydomain.salesforce.com'),
* timeout: Duration.minutes(5),
* frequency: Duration.seconds(10)
* };
* const resolver: MyDomainResolver = await MyDomainResolver.create(options);
* const ipAddress: AnyJson = await resolver.resolve();
* console.log(`Successfully resolved host: ${options.url} to address: ${ipAddress}`);
* })();
* ```
*/
class MyDomainResolver extends kit_1.AsyncOptionalCreatable {
static DEFAULT_DOMAIN = new node_url_1.URL('https://login.salesforce.com');
logger;
options;
/**
* Constructor
* **Do not directly construct instances of this class -- use {@link MyDomainResolver.create} instead.**
*
* @param options The options for the class instance
*/
constructor(options) {
super(options);
this.options = options ?? { url: MyDomainResolver.DEFAULT_DOMAIN };
}
getTimeout() {
return this.options.timeout ?? kit_1.Duration.seconds(DNS_TIMEOUT);
}
getFrequency() {
return this.options.frequency ?? kit_1.Duration.seconds(DNS_RETRY_FREQ);
}
/**
* Method that performs the dns lookup of the host. If the lookup fails the internal polling client will try again
* given the optional interval. Returns the resolved ip address.
*
* If SFDX_DISABLE_DNS_CHECK environment variable is set to true, it will immediately return the host without
* executing the dns loookup.
*/
async resolve() {
const env = new kit_1.Env();
if (env.getBoolean('SF_DISABLE_DNS_CHECK', env.getBoolean('SFDX_DISABLE_DNS_CHECK', false))) {
this.logger.debug('SF_DISABLE_DNS_CHECK set to true. Skipping DNS check...');
return this.options.url.host;
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
const pollingOptions = {
async poll() {
const { hostname } = self.options.url;
let dnsResult;
try {
self.logger.debug(`Attempting to resolve url: ${hostname}`);
if (new sfdcUrl_1.SfdcUrl(self.options.url).isLocalUrl()) {
return {
completed: true,
payload: '127.0.0.1',
};
}
dnsResult = await (0, node_util_1.promisify)(node_dns_1.lookup)(hostname);
self.logger.debug(`Successfully resolved host: ${hostname} result: ${JSON.stringify(dnsResult)}`);
return {
completed: true,
payload: dnsResult.address,
};
}
catch (e) {
self.logger.debug(`An error occurred trying to resolve: ${hostname}`);
self.logger.debug(`Error: ${e.message}`);
self.logger.debug('Re-trying dns lookup again....');
return {
completed: false,
};
}
},
timeout: this.getTimeout(),
frequency: this.getFrequency(),
timeoutErrorName: 'MyDomainResolverTimeoutError',
};
const client = await pollingClient_1.PollingClient.create(pollingOptions);
return (0, ts_types_1.ensureString)(await client.subscribe());
}
async getCnames() {
try {
await this.resolve();
return await (0, node_util_1.promisify)(node_dns_1.resolveCname)(this.options.url.host);
}
catch (e) {
this.logger.debug(`An error occurred trying to resolve: ${this.options.url.host}`);
this.logger.debug(`Error: ${e.message}`);
return [];
}
}
/**
* Used to initialize asynchronous components.
*/
async init() {
this.logger = await logger_1.Logger.child('MyDomainResolver');
}
}
exports.MyDomainResolver = MyDomainResolver;
//# sourceMappingURL=myDomainResolver.js.map
;