@httpc/kit
Version:
httpc toolbox for building function-based API with minimal code and end-to-end type safety
117 lines (116 loc) • 3.58 kB
JavaScript
export class PermissionsModel {
constructor(params) {
this._tokens = [];
this._tokens = params?.tokens?.slice() || [];
}
get tokens() {
return this._tokens;
}
find(token, level = "any") {
if (typeof token === "string") {
token = [token];
}
token = token.map(x => x.toLowerCase());
let defs = this._tokens;
for (let a = 0; a < token.length; a++) {
const part = token[a];
const isLast = a === token.length - 1;
// if wildcard search, use the the first definition
// * support only last position wildcard search -> token:*, token:child:*
// * no support for "nested-wildcard search" -> *:child, token:*:child
const def = part === "*"
? defs[0]
: defs.find(def => def.token.toLowerCase() === part || def.alias?.some(x => x.toLowerCase() === part));
if (!def) {
return;
}
const hasChildren = def.child && def.child.length > 0;
if (isLast) {
return ((hasChildren && level === "partial") ||
(!hasChildren && level === "exact") ||
level === "any") ? def : undefined;
}
// if not last, continue with the children
if (!hasChildren) {
return;
}
defs = def.child;
}
}
}
class FluentToken {
constructor(_token, parent) {
this._token = _token;
this._fullToken = [...parent || [], _token];
}
alias(alias) {
(this._alias ?? (this._alias = new Set())).add(alias);
return this;
}
tag(tag) {
this._tags ?? (this._tags = new Set());
if (Array.isArray(tag)) {
tag.forEach(x => this._tags.add(x));
}
else {
this._tags.add(tag);
}
return this;
}
includes(token) {
if (Array.isArray(token)) {
(this._includes ?? (this._includes = [])).push(...token);
}
else {
(this._includes ?? (this._includes = [])).push(token);
}
return this;
}
token(token, builder) {
if (builder) {
(this._child ?? (this._child = [])).push(builder(new FluentToken(token, this._fullToken)).build());
}
else {
(this._child ?? (this._child = [])).push({
token,
fullToken: [...this._fullToken, token],
});
}
return this;
}
build() {
return {
token: this._token,
fullToken: this._fullToken,
alias: this._alias ? [...this._alias] : undefined,
includes: this._includes,
tags: this._tags ? [...this._tags] : undefined,
child: this._child,
};
}
}
class FluentPermission {
constructor() {
this._tokens = [];
}
token(token, builder) {
if (builder) {
this._tokens.push(builder(new FluentToken(token)).build());
}
else {
this._tokens.push({
token,
fullToken: [token],
});
}
return this;
}
build() {
return new PermissionsModel({
tokens: this._tokens
});
}
}
export function permissions(api) {
return api(new FluentPermission()).build();
}