char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
9cca521
main
1import { 2ArrayIsArray , 3ArrayPrototypePush , 4ObjectSetPrototypeOf , 5ReflectOwnKeys , 6TypeError , 7} from "ext:core/primordials" ; 8import { op_pledge } from "ext:core/ops" ; 9import { usv } from "ext:web/idl.js" ; 10 11const categories = [ 12"net" , 13"read" , 14"write" , 15"jsExec" , 16"env" , 17"sys" , 18"run" , 19"ffi" , 20] as const ; 21export type PledgeRow = [ 22category :typeof categories [ number ], 23allow :string [] | null , 24deny :string [], 25]; 26function object ( value :unknown ) :value isRecord < PropertyKey , unknown > { 27return value !== null && 28( typeof value === "object" || typeof value === "function" ); 29} 30function keys ( value :object , allowed :readonly string []) :void { 31const names = ReflectOwnKeys ( value ); 32for ( let index = 0 ; index < names . length ; index ++ ) { 33let known = false ; 34for ( let key = 0 ; key < allowed . length ; key ++ ) { 35if ( names [ index ] === allowed [ key ]) known = true ; 36} 37if ( ! known ) throw new TypeError ( "Unknown pledge member" ); 38} 39} 40function list ( value :unknown ) :string [] | null { 41if ( value === undefined ) return null ; 42if ( ! ArrayIsArray ( value )) throw new TypeError ( "Pledge grants must be arrays" ); 43const result :string [] = []; 44ObjectSetPrototypeOf ( result , null ); 45const length = value . length ; 46for ( let index = 0 ; index < length ; index ++ ) { 47const item = value [ index ]; 48ArrayPrototypePush ( result , usv ( item )); 49} 50return result ; 51} 52export function preparePledge ( restrictions :unknown ) :PledgeRow [] { 53if ( ! object ( restrictions ) || ArrayIsArray ( restrictions )) { 54throw new TypeError ( "Pledge requires a restrictions object" ); 55} 56keys ( restrictions , categories ); 57const request :PledgeRow [] = []; 58ObjectSetPrototypeOf ( request , null ); 59for ( let index = 0 ; index < categories . length ; index ++ ) { 60const category = categories [ index ]; 61const value = restrictions [ category ]; 62if ( value === undefined ) continue ; 63let allow :string [] | null , deny :string []; 64if ( value === false ) { 65allow = []; 66deny = []; 67} else { 68if ( ! object ( value ) || ArrayIsArray ( value )) { 69throw new TypeError ( 70"Pledge restrictions must be false or { allow, deny }" , 71); 72} 73keys ( value , [ "allow" , "deny" ]); 74allow = list ( value . allow ); 75deny = list ( value . deny ) ?? []; 76} 77ArrayPrototypePush ( request , [ category , allow , deny ]); 78} 79return request ; 80} 81export function pledge ( restrictions :unknown ) :void { 82const error = op_pledge ( preparePledge ( restrictions )); 83if ( error !== null ) throw new TypeError ( error ); 84}