feat: Port attribute interface from pure-ts:attribute.ts

This commit is contained in:
2026-07-04 14:02:39 +05:30
parent b17a749741
commit e712c0dd93
3 changed files with 111 additions and 3 deletions

View File

@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

View File

@@ -1 +1,100 @@
export {};
export enum AttributeVisibility {
PUBLIC = "PUBLIC",
PRIVATE = "PRIVATE",
}
export class Attribute {
readonly name: string;
private value: string;
private visibility: AttributeVisibility;
private allowedEntities: Set<string>;
constructor(name: string, value: string, visibility: AttributeVisibility) {
this.name = name;
this.value = value;
this.visibility = visibility;
this.allowedEntities = new Set();
}
setValue(newValue: string) {
this.value = newValue;
}
getValue(): string {
return this.value;
}
hasAccess(objectId: string): boolean {
return (
this.visibility === AttributeVisibility.PUBLIC ||
this.allowedEntities.has(objectId)
);
}
getVisibility(): AttributeVisibility {
return this.visibility;
}
setPublic() {
this.visibility = AttributeVisibility.PUBLIC;
}
setPrivate() {
this.allowedEntities.clear();
this.visibility = AttributeVisibility.PRIVATE;
}
grandAccess(objectId: string) {
if (this.visibility === AttributeVisibility.PRIVATE) {
this.allowedEntities.add(objectId);
}
}
revokeAccess(objectId: string) {
if (
this.visibility === AttributeVisibility.PRIVATE &&
this.allowedEntities.has(objectId)
) {
this.allowedEntities.delete(objectId);
}
}
}
export interface IAttribute {
id: string;
attributes: Map<string, Attribute>;
addAttribute(
name: string,
value: string,
visibility: AttributeVisibility,
): void;
getVisibileAttributesFor(viewerId: string): Attribute[];
}
export abstract class AttributableObject implements IAttribute {
readonly id: string = crypto.randomUUID();
readonly attributes: Map<string, Attribute> = new Map<string, Attribute>();
addAttribute(
name: string,
value: string,
visibility: AttributeVisibility,
): void {
if (this.attributes.has(name))
throw Error(`Attribute ${name} already exists`);
this.attributes.set(name, new Attribute(name, value, visibility));
}
removeAttribute(name: string): void {
if (!this.attributes.has(name))
throw Error(`Attribute ${name} does not exist`);
this.attributes.delete(name);
}
getVisibileAttributesFor(viewerId: string): Attribute[] {
return Array.from(this.attributes.values()).filter((attr) =>
attr.hasAccess(viewerId),
);
}
}

View File

@@ -1,5 +1,5 @@
import eslintConfigPrettier from "eslint-config-prettier";
import js from "eslint/js";
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
@@ -8,7 +8,7 @@ export default [
ignores: ["**/dist/**", "**/node_modules/**"],
},
js.configs.recommend,
js.configs.recommended,
...tseslint.configs.recommended,