dwnpm
Version:
Decentralized Registry Package Manager (DRPM) helps developers publish, install, find and manage Decentralized Packages (DPKs) published to Decentralized Web Nodes (DWNs). DRPM does this by looking up a Decentralized Identifier (DID) to find its DID docum
102 lines (89 loc) • 3.51 kB
text/typescript
import { DEFAULT_DWN_URL, DRPM_PROTOCOL_B64URL } from '../../config.js';
import { Logger } from '../logger.js';
import { BaseDrl, DrlAddQueryFilterParams, DrlFiltersParams, DrlReadParams } from '../types.js';
import { DrlUtils } from './drl-utils.js';
import dwn from './protocol.js';
export class DrlBuilder {
baseDrl: string;
path: string = '';
query: string[] = [];
constructor({ endpoint, did }: BaseDrl) {
if (!did) throw new Error('DID required to build DRL');
if (!endpoint) Logger.warn('No DWN Endpoint Found! Using the default endpoint is not recommended.');
this.baseDrl = `${endpoint ?? DEFAULT_DWN_URL}/${did}`;
}
// Start building with base DRL
static create({ did, endpoint }: BaseDrl): DrlBuilder {
return new DrlBuilder({ did, endpoint });
}
// Add a generic path (e.g., query, read)
addPath({pathSegment}: {pathSegment: string}): DrlBuilder {
this.path = `${this.path}/${pathSegment}`;
return this;
}
addProtocolEncoded(): DrlBuilder {
this.path = `${this.path}/read/protocols/${DRPM_PROTOCOL_B64URL}`;
return this;
}
// Add encoded protocol to the path
addProtocol({protocol}: {protocol?: string}): DrlBuilder {
const encodedProtocol = DrlUtils.base64urlEncode(protocol ?? dwn.protocol);
this.path = `${this.path}/read/protocols/${encodedProtocol}`;
return this;
}
// Add encoded protocol to the path
addProtocolPath({protocolPath}: {protocolPath: string}): DrlBuilder {
this.path = `${this.path}/${protocolPath}`;
return this;
}
// Add filter query parameters dynamically
addFilter({key, value, subKey}: DrlAddQueryFilterParams): DrlBuilder {
const filter = subKey
? `filter.${key}.${subKey}=${value}`
: `filter.${key}=${value}`;
this.query.push(filter);
return this;
}
// Add multiple filters dynamically, supporting arrays for filters like tags
addFilters({ filters }: DrlFiltersParams): DrlBuilder {
Object.keys(filters).forEach(key => {
const filter = filters[key];
// Case 1: Simple key-value pair, e.g., { 'protocolPath': 'package' }
if (typeof filter === 'string') {
this.addFilter({ key, value: filter });
}
// Case 2: List of objects with value and subKey,
// e.g. { tags: [{ value: 'tool5', subKey: 'name' }, { value: '6.1.0', subKey: 'version' }] }
else if (Array.isArray(filter)) {
filter.forEach(({value, subKey}) => {
this.addFilter({ key, value, subKey });
});
}
// Case 3: Single object with value and subKey, e.g., { tags: { value: 'tool5', subKey: 'name' } }
else if (DrlUtils.isJsonObject(filter)) {
const {value, subKey} = filter ?? {};
this.addFilter({ key, value, subKey });
}
});
return this;
}
// Build and return the final DRL
build(): string {
const queryString = this.query.length ? `?${this.query.join('&')}` : '';
console.log('this', this);
return `${this.baseDrl}${this.path}${queryString}`;
}
// Handle building a query-based DRL
buildDrlQuery({ filters }: DrlFiltersParams): string {
this.addPath({ pathSegment: 'query' });
this.addFilters({ filters });
return this.build();
}
// Handle building a protocol read DRL with optional protocolPath and filters
buildDrlRead({ protocolPath, filters }: DrlReadParams): string {
this.addProtocol({});
this.addProtocolPath({ protocolPath });
this.addFilters({ filters });
return this.build();
}
}