From 050c0f1acac719da9a9423794f240418ef9ff187 Mon Sep 17 00:00:00 2001 From: rhpidfyre Date: Tue, 11 Mar 2025 03:23:13 -0400 Subject: [PATCH] (WIP) `name` and `timestamp` resepect permissions --- src/rt/rfwfs/main.ts | 117 +++++++++++++++++++++++-------------------- src/rt/rfwfs/wrap.ts | 10 ++-- 2 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/rt/rfwfs/main.ts b/src/rt/rfwfs/main.ts index 0e9c12d..b50759a 100644 --- a/src/rt/rfwfs/main.ts +++ b/src/rt/rfwfs/main.ts @@ -1,21 +1,23 @@ -import { EntryType, PushStatus, ReadStatus, Permissions } from "./enum" +import { EntryType, PushStatus, ReadStatus, Permissions, ConstEnum, PermissionsBinary } from "./enum" import { wrap_entry, wrap_none, WrapResultEntry, WrapResultNone } from "./wrap" import directory_search from "./index" +import hash_table from "./hash" type FileInner = string | number +type EntryFileInner = EntryValue -interface Entry { - name: string, - timestamp: number, - permissions: Permissions, - //please do not change the inner values directly on entries or else there will be catastrophic consequences - readonly type: EntryType, +//please do not change the inner values directly on entries or else there will be catastrophic consequences +interface EntryValue { + __inner: T, + write: (value: T) => boolean, + read: () => U, } -interface EntryFileInner { - __body: FileInner, - write: (item: FileInner) => boolean, - read: () => FileInner | undefined, +interface Entry { + permissions: Permissions, + timestamp: EntryValue, + name: EntryValue, + readonly type: EntryType, } interface EntryFile extends Entry { inner: EntryFileInner, @@ -24,43 +26,48 @@ interface EntryFile extends Entry { interface EntryCollection extends Entry { inner: EntryCollectionManipulate, } - interface EntryCollectionManipulate { - __body: T[], + __inner: T[], clone: (file_name: string) => WrapResultEntry find: (file_name: string) => WrapResultEntry push: (entry: Entry) => WrapResultNone, sort: () => void, pop: (file_name: string) => WrapResultEntry, } - interface Rfwfs { - directory: (default_name: string, permissions: Permissions, timestamp?: number, inner_default?: T[]) => EntryCollection, + directory: (default_name: string, default_permissions: Permissions, default_timestamp?: number, default_inner?: T[]) => EntryCollection, + file: (default_name: string, default_permissions: Permissions, default_timestamp?: number, default_inner?: FileInner) => Promise, + is_binary: (entry: T) => boolean, is_file: (entry: T) => boolean, is_dir: (entry: T) => boolean, - file: (default_name: string, permissions: Permissions, timestamp?: number, inner_default?: FileInner) => EntryFile, } -function read_write_access(permissions: Permissions): boolean { +function execute_access

(permissions: P): boolean { + return permissions === PermissionsBinary.rwx + || permissions === PermissionsBinary.rx + || permissions === PermissionsBinary.wx + || permissions === PermissionsBinary.x +} +function read_write_access

(permissions: P): boolean { return permissions === Permissions.rw } -function read_access(permissions: Permissions): boolean { +function read_access

(permissions: P): boolean { return read_write_access(permissions) || permissions === Permissions.r } -function write_access(permissions: Permissions): boolean { +function write_access

(permissions: P): boolean { return read_write_access(permissions) || permissions === Permissions.w } function directory_sort(self: EntryCollectionManipulate) { - self.__body.sort((a,z) => a.name.localeCompare(z.name)) + self.__inner.sort((a,z) => a.name.read().localeCompare(z.name.read())) } function directory_push(self: EntryCollection, entry: E): WrapResultNone { if (write_access(self.permissions)) { - const no_duplicates = directory_search(self.inner.__body, entry.name) + const no_duplicates = directory_search(self.inner.__inner, entry.name.read()) if (!no_duplicates) { - self.inner.__body.push(entry) - self.inner.__body.sort() + self.inner.__inner.push(entry) + self.inner.__inner.sort() return wrap_none(PushStatus.Ok) } return wrap_none(PushStatus.Duplicate) @@ -70,7 +77,7 @@ function directory_push(self: EntryCollection, entry: E): Wr function directory_find(self: EntryCollection, file_name: string): WrapResultEntry { if (read_access(self.permissions)) { - const file_search = directory_search(self.inner.__body, file_name) + const file_search = directory_search(self.inner.__inner, file_name) if (file_search) { return wrap_entry(ReadStatus.Ok, file_search.result) } @@ -81,9 +88,9 @@ function directory_find(self: EntryCollection, file_name: st function directory_pop(self: EntryCollection, file_name: string): WrapResultEntry { if (read_write_access(self.permissions)) { - const pop_find = directory_search(self.inner.__body, file_name) + const pop_find = directory_search(self.inner.__inner, file_name) if (pop_find) { - self.inner.__body.splice(pop_find.some, 1) + self.inner.__inner.splice(pop_find.some, 1) return wrap_entry(ReadStatus.Ok, pop_find.result) } return wrap_entry(ReadStatus.NotFound) @@ -93,7 +100,7 @@ function directory_pop(self: EntryCollection, file_name: str function directory_clone(self: EntryCollection, file_name: string): WrapResultEntry { if (read_write_access(self.permissions)) { - const clone_find = directory_search(self.inner.__body, file_name) + const clone_find = directory_search(self.inner.__inner, file_name) if (clone_find) { return wrap_entry(ReadStatus.Ok, { ...clone_find.result }) } @@ -102,32 +109,32 @@ function directory_clone(self: EntryCollection, file_name: s return wrap_entry(ReadStatus.Denied) } -function file_inner_read(self: EntryFileInner, permissions: Permissions): FileInner | undefined { - return read_access(permissions) ? self.__body : undefined +function inner_read(self: EntryValue, permissions: P): FileInner | undefined { + return read_access(permissions) ? self.__inner : undefined } -function file_inner_write(self: EntryFileInner, permissions: Permissions, item: FileInner): boolean { +function inner_write(self: EntryValue, permissions: P, item: I): boolean { if (write_access(permissions)) { - self.__body = item + self.__inner = item return true } return false } -function file_inner(permissions: Permissions, inner_default: FileInner): EntryFileInner { - const file_inner_trait = { __body: inner_default } as EntryFileInner - file_inner_trait.read = function() { return file_inner_read(this, permissions) } - file_inner_trait.write = function(item) { return file_inner_write(this, permissions, item) } - return file_inner_trait +function inner

>(permissions: P, inner_default: I): R { + const inner_trait = { __inner: inner_default } as R + inner_trait.write = function(item) { return inner_write(this, permissions, item) } + inner_trait.read = function() { return inner_read(this, permissions) } + return inner_trait } function dir_inner(self: EntryCollection, collection: T[]): EntryCollectionManipulate { - const collection_trait = { __body: collection } as EntryCollectionManipulate + const collection_trait = { __inner: collection } as EntryCollectionManipulate collection_trait.clone = function(file_name) { return directory_clone(self, file_name) } - collection_trait.pop = function(file_name) { return directory_pop(self, file_name) } collection_trait.find = function(file_name) { return directory_find(self, file_name) } collection_trait.push = function(entry) { return directory_push(self, entry) } collection_trait.sort = function() { return directory_sort(this) } + collection_trait.pop = function(file_name) { return directory_pop(self, file_name) } collection_trait.sort() //the default collection is automatically sorted on directory creation. return collection_trait } @@ -140,32 +147,34 @@ rfwfs.is_dir = function(entry) { rfwfs.is_file = function(entry) { return entry.type === EntryType.File } +rfwfs.is_binary = function(entry) { + return entry.type === EntryType.Binary +} -rfwfs.file = function(default_name, permissions, timestamp, inner_default) { +rfwfs.file = async function(default_name, default_permissions, default_timestamp, default_inner = "") { const file = { type: EntryType.File } as EntryFile - file.permissions = permissions - file.timestamp = timestamp ? timestamp : (Date.now()/1000)|0 - file.inner = file_inner(permissions, inner_default ? inner_default : "") - file.name = default_name - file.hash = "0" + file.permissions = default_permissions + file.timestamp = inner(default_permissions, default_timestamp ? default_timestamp : (Date.now()/1000)|0) + file.inner = inner(default_permissions, default_inner) + file.name = inner(default_permissions, default_name) + file.hash = await hash_table.sha256(default_inner) return file } -rfwfs.directory = function(default_name: string, permissions: Permissions, timestamp?: number, inner_default?: T[]): EntryCollection { +rfwfs.directory = function(default_name: string, default_permissions: Permissions, default_timestamp?: number, default_inner?: T[]): EntryCollection { const directory = { type: EntryType.Directory } as EntryCollection - directory.permissions = permissions - directory.timestamp = timestamp ? timestamp : (Date.now()/1000)|0 - directory.inner = dir_inner(directory, inner_default ? inner_default : []) - directory.name = default_name + directory.permissions = default_permissions + directory.timestamp = inner(default_permissions, default_timestamp ? default_timestamp : (Date.now()/1000)|0) + directory.inner = inner(default_permissions, default_inner) + directory.name = inner(default_permissions, default_name) return directory } export default rfwfs export { - type FileInner, - type Entry, - type EntryFile, - type EntryFileInner, - type EntryCollection, type EntryCollectionManipulate, + type EntryCollection, + type FileInner, + type EntryFile, + type Entry, } \ No newline at end of file diff --git a/src/rt/rfwfs/wrap.ts b/src/rt/rfwfs/wrap.ts index d341cb7..754f75f 100644 --- a/src/rt/rfwfs/wrap.ts +++ b/src/rt/rfwfs/wrap.ts @@ -1,14 +1,14 @@ -import { Result } from "./enum" +import { Result, type ConstEnum } from "./enum" import { type Entry } from "./main" -type ConstEnum = number - type WrapResultEntry = WrapResult type WrapBSearch = WrapResult type WrapResultNone = WrapResult interface WrapResult { + /** The resulting value if `U` is a success */ readonly result: T, + /** Represents some arbitrary extra value, usually a success status */ readonly some: U } @@ -20,7 +20,7 @@ function wrap_bsearch(index: number, result: T): WrapBSearch return wrap(result, index) } -function wrap_entry(status: U, result?: T): WrapResultEntry { +function wrap_entry(status: T, result?: U): WrapResultEntry { return wrap(result, status) } @@ -37,4 +37,4 @@ export { type WrapResultNone, type WrapBSearch, type WrapResult, -} \ No newline at end of file +}