unleash-server
Version:
Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.
82 lines • 3.4 kB
JavaScript
import { FeatureLinkAddedEvent, FeatureLinkRemovedEvent, FeatureLinkUpdatedEvent, } from '../../types/index.js';
import { BadDataError, NotFoundError, OperationDeniedError, } from '../../error/index.js';
import normalizeUrl from 'normalize-url';
import { parse } from 'tldts';
import { FEAUTRE_LINK_COUNT } from '../metrics/impact/define-impact-metrics.js';
export default class FeatureLinkService {
constructor(stores, { getLogger, flagResolver, }, eventService) {
this.logger = getLogger('feature-links/feature-link-service.ts');
this.featureLinkStore = stores.featureLinkStore;
this.eventService = eventService;
this.flagResolver = flagResolver;
}
async getAll() {
return this.featureLinkStore.getAll();
}
normalize(url) {
try {
return normalizeUrl(url, { defaultProtocol: 'https' });
}
catch (_e) {
throw new BadDataError(`Invalid URL: ${url}`);
}
}
async createLink(projectId, newLink, auditUser) {
const countLinks = await this.featureLinkStore.count({
featureName: newLink.featureName,
});
if (countLinks >= 10) {
throw new OperationDeniedError('Too many links (10) exist for this feature');
}
const normalizedUrl = this.normalize(newLink.url);
const { domainWithoutSuffix } = parse(normalizedUrl);
const link = await this.featureLinkStore.insert({
...newLink,
url: normalizedUrl,
domain: domainWithoutSuffix,
});
this.flagResolver.impactMetrics?.incrementCounter(FEAUTRE_LINK_COUNT);
await this.eventService.storeEvent(new FeatureLinkAddedEvent({
featureName: newLink.featureName,
project: projectId,
data: { url: normalizedUrl, title: newLink.title },
auditUser,
}));
return link;
}
async updateLink({ projectId, linkId }, updatedLink, auditUser) {
const normalizedUrl = this.normalize(updatedLink.url);
const { domainWithoutSuffix } = parse(normalizedUrl);
const preData = await this.featureLinkStore.get(linkId);
if (!preData) {
throw new NotFoundError(`Could not find link with id ${linkId}`);
}
const link = await this.featureLinkStore.update(linkId, {
...updatedLink,
url: normalizedUrl,
domain: domainWithoutSuffix,
});
await this.eventService.storeEvent(new FeatureLinkUpdatedEvent({
featureName: updatedLink.featureName,
project: projectId,
data: { url: normalizedUrl, title: link.title },
preData: { url: preData.url, title: preData.title },
auditUser,
}));
return link;
}
async deleteLink({ projectId, linkId }, auditUser) {
const link = await this.featureLinkStore.get(linkId);
if (!link) {
throw new NotFoundError(`Could not find link with id ${linkId}`);
}
await this.featureLinkStore.delete(linkId);
await this.eventService.storeEvent(new FeatureLinkRemovedEvent({
featureName: link.featureName,
project: projectId,
preData: { url: link.url, title: link.title },
auditUser,
}));
}
}
//# sourceMappingURL=feature-link-service.js.map