signify-ts
Version:
Signing at the edge for KERI, ACDC, and KERIA
99 lines (80 loc) • 2.82 kB
text/typescript
import { Bexter, Reb64 } from './bexter';
import { MatterArgs, MtrDex } from './matter';
import { EmptyMaterialError } from './kering';
/*
Pather is a subclass of Bexter that provides SAD Path language specific functionality
for variable length strings that only contain Base64 URL safe characters. Pather allows
the specification of SAD Paths as a list of field components which will be converted to the
Base64 URL safe character representation.
Additionally, Pather provides .rawify for extracting and serializing the content targeted by
.path for a SAD, represented as an instance of Serder. Pather enforces Base64 URL character
safety by leveraging the fact that SADs must have static field ordering. Any field label can
be replaced by its field ordinal to allow for path specification and traversal for any field
labels that contain non-Base64 URL safe characters.
Examples: strings:
path = []
text = "-"
qb64 = '6AABAAA-'
path = ["A"]
text = "-A"
qb64 = '5AABAA-A'
path = ["A", "B"]
text = "-A-B"
qb64 = '4AAB-A-B'
path = ["A", 1, "B", 3]
text = "-A-1-B-3"
qb64 = '4AAC-A-1-B-3'
*/
export class Pather extends Bexter {
constructor(
{ raw, code = MtrDex.StrB64_L0, qb64b, qb64, qb2 }: MatterArgs,
bext?: string,
path?: string[]
) {
if (
raw === undefined &&
bext === undefined &&
qb64b === undefined &&
qb64 === undefined &&
qb2 === undefined
) {
if (path === undefined)
throw new EmptyMaterialError('Missing bext string.');
bext = Pather._bextify(path);
}
super({ raw, code, qb64b, qb64, qb2 }, bext);
}
// TODO: implement SAD access methods like resolve, root, strip, startswith and tail
get path(): string[] {
if (!this.bext.startsWith('-')) {
throw new Error('invalid SAD ptr');
}
let path = this.bext;
while (path.charAt(0) === '-') {
path = path.substring(1);
}
const apath = path.split('-');
if (apath[0] !== '') {
return apath;
} else {
return [];
}
}
static _bextify(path: any[]): string {
const vath = [];
for (const p of path) {
let sp = '';
if (typeof p === 'number') {
sp = p.toString();
} else {
sp = p;
}
const match = Reb64.exec(sp);
if (!match) {
throw new Error(`"Non Base64 path component = ${p}.`);
}
vath.push(sp);
}
return '-' + vath.join('-');
}
}