diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2023-02-07 20:22:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-07 20:22:46 +0100 |
commit | b4aa1530970f7b9cc4e6f2f27e077852c4e178d3 (patch) | |
tree | 3d008912affe8550692183bd2697a386db5e3c79 /runtime/js/10_permissions.js | |
parent | 65500f36e870b4ada3996b06aa287e30177d21a3 (diff) |
refactor: Use ES modules for internal runtime code (#17648)
This PR refactors all internal js files (except core) to be written as
ES modules.
`__bootstrap`has been mostly replaced with static imports in form in
`internal:[path to file from repo root]`.
To specify if files are ESM, an `esm` method has been added to
`Extension`, similar to the `js` method.
A new ModuleLoader called `InternalModuleLoader` has been added to
enable the loading of internal specifiers, which is used in all
situations except when a snapshot is only loaded, and not a new one is
created from it.
---------
Co-authored-by: Bartek IwaĆczuk <biwanczuk@gmail.com>
Diffstat (limited to 'runtime/js/10_permissions.js')
-rw-r--r-- | runtime/js/10_permissions.js | 479 |
1 files changed, 237 insertions, 242 deletions
diff --git a/runtime/js/10_permissions.js b/runtime/js/10_permissions.js index 7c4af8ed0..6019302e4 100644 --- a/runtime/js/10_permissions.js +++ b/runtime/js/10_permissions.js @@ -1,287 +1,282 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const { ops } = Deno.core; - const { Event } = window.__bootstrap.event; - const { EventTarget } = window.__bootstrap.eventTarget; - const { pathFromURL } = window.__bootstrap.util; - const { illegalConstructorKey } = window.__bootstrap.webUtil; - const { - ArrayIsArray, - ArrayPrototypeIncludes, - ArrayPrototypeMap, - ArrayPrototypeSlice, - Map, - MapPrototypeGet, - MapPrototypeHas, - MapPrototypeSet, - FunctionPrototypeCall, - PromiseResolve, - PromiseReject, - ReflectHas, - SafeArrayIterator, - SymbolFor, - TypeError, - } = window.__bootstrap.primordials; - /** - * @typedef StatusCacheValue - * @property {PermissionState} state - * @property {PermissionStatus} status - */ - - /** @type {ReadonlyArray<"read" | "write" | "net" | "env" | "sys" | "run" | "ffi" | "hrtime">} */ - const permissionNames = [ - "read", - "write", - "net", - "env", - "sys", - "run", - "ffi", - "hrtime", - ]; - - /** - * @param {Deno.PermissionDescriptor} desc - * @returns {Deno.PermissionState} - */ - function opQuery(desc) { - return ops.op_query_permission(desc); +const core = globalThis.Deno.core; +const ops = core.ops; +import { Event, EventTarget } from "internal:ext/web/02_event.js"; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayIsArray, + ArrayPrototypeIncludes, + ArrayPrototypeMap, + ArrayPrototypeSlice, + Map, + MapPrototypeGet, + MapPrototypeHas, + MapPrototypeSet, + FunctionPrototypeCall, + PromiseResolve, + PromiseReject, + ReflectHas, + SafeArrayIterator, + Symbol, + SymbolFor, + TypeError, +} = primordials; + +const illegalConstructorKey = Symbol("illegalConstructorKey"); + +/** + * @typedef StatusCacheValue + * @property {PermissionState} state + * @property {PermissionStatus} status + */ + +/** @type {ReadonlyArray<"read" | "write" | "net" | "env" | "sys" | "run" | "ffi" | "hrtime">} */ +const permissionNames = [ + "read", + "write", + "net", + "env", + "sys", + "run", + "ffi", + "hrtime", +]; + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {Deno.PermissionState} + */ +function opQuery(desc) { + return ops.op_query_permission(desc); +} + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {Deno.PermissionState} + */ +function opRevoke(desc) { + return ops.op_revoke_permission(desc); +} + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {Deno.PermissionState} + */ +function opRequest(desc) { + return ops.op_request_permission(desc); +} + +class PermissionStatus extends EventTarget { + /** @type {{ state: Deno.PermissionState }} */ + #state; + + /** @type {((this: PermissionStatus, event: Event) => any) | null} */ + onchange = null; + + /** @returns {Deno.PermissionState} */ + get state() { + return this.#state.state; } /** - * @param {Deno.PermissionDescriptor} desc - * @returns {Deno.PermissionState} + * @param {{ state: Deno.PermissionState }} state + * @param {unknown} key */ - function opRevoke(desc) { - return ops.op_revoke_permission(desc); + constructor(state = null, key = null) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); + } + super(); + this.#state = state; } /** - * @param {Deno.PermissionDescriptor} desc - * @returns {Deno.PermissionState} + * @param {Event} event + * @returns {boolean} */ - function opRequest(desc) { - return ops.op_request_permission(desc); - } - - class PermissionStatus extends EventTarget { - /** @type {{ state: Deno.PermissionState }} */ - #state; - - /** @type {((this: PermissionStatus, event: Event) => any) | null} */ - onchange = null; - - /** @returns {Deno.PermissionState} */ - get state() { - return this.#state.state; - } - - /** - * @param {{ state: Deno.PermissionState }} state - * @param {unknown} key - */ - constructor(state = null, key = null) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); - } - super(); - this.#state = state; - } - - /** - * @param {Event} event - * @returns {boolean} - */ - dispatchEvent(event) { - let dispatched = super.dispatchEvent(event); - if (dispatched && this.onchange) { - FunctionPrototypeCall(this.onchange, this, event); - dispatched = !event.defaultPrevented; - } - return dispatched; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ state: this.state, onchange: this.onchange }) - }`; + dispatchEvent(event) { + let dispatched = super.dispatchEvent(event); + if (dispatched && this.onchange) { + FunctionPrototypeCall(this.onchange, this, event); + dispatched = !event.defaultPrevented; } + return dispatched; } - /** @type {Map<string, StatusCacheValue>} */ - const statusCache = new Map(); - - /** - * @param {Deno.PermissionDescriptor} desc - * @param {Deno.PermissionState} state - * @returns {PermissionStatus} - */ - function cache(desc, state) { - let { name: key } = desc; - if ( - (desc.name === "read" || desc.name === "write" || desc.name === "ffi") && - ReflectHas(desc, "path") - ) { - key += `-${desc.path}&`; - } else if (desc.name === "net" && desc.host) { - key += `-${desc.host}&`; - } else if (desc.name === "run" && desc.command) { - key += `-${desc.command}&`; - } else if (desc.name === "env" && desc.variable) { - key += `-${desc.variable}&`; - } else if (desc.name === "sys" && desc.kind) { - key += `-${desc.kind}&`; - } else { - key += "$"; - } - if (MapPrototypeHas(statusCache, key)) { - const status = MapPrototypeGet(statusCache, key); - if (status.state !== state) { - status.state = state; - status.status.dispatchEvent(new Event("change", { cancelable: false })); - } - return status.status; + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ state: this.state, onchange: this.onchange }) + }`; + } +} + +/** @type {Map<string, StatusCacheValue>} */ +const statusCache = new Map(); + +/** + * @param {Deno.PermissionDescriptor} desc + * @param {Deno.PermissionState} state + * @returns {PermissionStatus} + */ +function cache(desc, state) { + let { name: key } = desc; + if ( + (desc.name === "read" || desc.name === "write" || desc.name === "ffi") && + ReflectHas(desc, "path") + ) { + key += `-${desc.path}&`; + } else if (desc.name === "net" && desc.host) { + key += `-${desc.host}&`; + } else if (desc.name === "run" && desc.command) { + key += `-${desc.command}&`; + } else if (desc.name === "env" && desc.variable) { + key += `-${desc.variable}&`; + } else if (desc.name === "sys" && desc.kind) { + key += `-${desc.kind}&`; + } else { + key += "$"; + } + if (MapPrototypeHas(statusCache, key)) { + const status = MapPrototypeGet(statusCache, key); + if (status.state !== state) { + status.state = state; + status.status.dispatchEvent(new Event("change", { cancelable: false })); } - /** @type {{ state: Deno.PermissionState; status?: PermissionStatus }} */ - const status = { state }; - status.status = new PermissionStatus(status, illegalConstructorKey); - MapPrototypeSet(statusCache, key, status); return status.status; } - - /** - * @param {unknown} desc - * @returns {desc is Deno.PermissionDescriptor} - */ - function isValidDescriptor(desc) { - return typeof desc === "object" && desc !== null && - ArrayPrototypeIncludes(permissionNames, desc.name); + /** @type {{ state: Deno.PermissionState; status?: PermissionStatus }} */ + const status = { state }; + status.status = new PermissionStatus(status, illegalConstructorKey); + MapPrototypeSet(statusCache, key, status); + return status.status; +} + +/** + * @param {unknown} desc + * @returns {desc is Deno.PermissionDescriptor} + */ +function isValidDescriptor(desc) { + return typeof desc === "object" && desc !== null && + ArrayPrototypeIncludes(permissionNames, desc.name); +} + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {desc is Deno.PermissionDescriptor} + */ +function formDescriptor(desc) { + if ( + desc.name === "read" || desc.name === "write" || desc.name === "ffi" + ) { + desc.path = pathFromURL(desc.path); + } else if (desc.name === "run") { + desc.command = pathFromURL(desc.command); } +} - /** - * @param {Deno.PermissionDescriptor} desc - * @returns {desc is Deno.PermissionDescriptor} - */ - function formDescriptor(desc) { - if ( - desc.name === "read" || desc.name === "write" || desc.name === "ffi" - ) { - desc.path = pathFromURL(desc.path); - } else if (desc.name === "run") { - desc.command = pathFromURL(desc.command); +class Permissions { + constructor(key = null) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); } } - class Permissions { - constructor(key = null) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); - } + query(desc) { + try { + return PromiseResolve(this.querySync(desc)); + } catch (error) { + return PromiseReject(error); } + } - query(desc) { - try { - return PromiseResolve(this.querySync(desc)); - } catch (error) { - return PromiseReject(error); - } + querySync(desc) { + if (!isValidDescriptor(desc)) { + throw new TypeError( + `The provided value "${desc?.name}" is not a valid permission name.`, + ); } - querySync(desc) { - if (!isValidDescriptor(desc)) { - throw new TypeError( - `The provided value "${desc?.name}" is not a valid permission name.`, - ); - } + formDescriptor(desc); - formDescriptor(desc); + const state = opQuery(desc); + return cache(desc, state); + } - const state = opQuery(desc); - return cache(desc, state); + revoke(desc) { + try { + return PromiseResolve(this.revokeSync(desc)); + } catch (error) { + return PromiseReject(error); } + } - revoke(desc) { - try { - return PromiseResolve(this.revokeSync(desc)); - } catch (error) { - return PromiseReject(error); - } + revokeSync(desc) { + if (!isValidDescriptor(desc)) { + throw new TypeError( + `The provided value "${desc?.name}" is not a valid permission name.`, + ); } - revokeSync(desc) { - if (!isValidDescriptor(desc)) { - throw new TypeError( - `The provided value "${desc?.name}" is not a valid permission name.`, - ); - } + formDescriptor(desc); - formDescriptor(desc); + const state = opRevoke(desc); + return cache(desc, state); + } - const state = opRevoke(desc); - return cache(desc, state); + request(desc) { + try { + return PromiseResolve(this.requestSync(desc)); + } catch (error) { + return PromiseReject(error); } + } - request(desc) { - try { - return PromiseResolve(this.requestSync(desc)); - } catch (error) { - return PromiseReject(error); - } + requestSync(desc) { + if (!isValidDescriptor(desc)) { + throw new TypeError( + `The provided value "${desc?.name}" is not a valid permission name.`, + ); } - requestSync(desc) { - if (!isValidDescriptor(desc)) { - throw new TypeError( - `The provided value "${desc?.name}" is not a valid permission name.`, - ); - } - - formDescriptor(desc); + formDescriptor(desc); - const state = opRequest(desc); - return cache(desc, state); - } + const state = opRequest(desc); + return cache(desc, state); } +} + +const permissions = new Permissions(illegalConstructorKey); - const permissions = new Permissions(illegalConstructorKey); - - /** Converts all file URLs in FS allowlists to paths. */ - function serializePermissions(permissions) { - if (typeof permissions == "object" && permissions != null) { - const serializedPermissions = {}; - for ( - const key of new SafeArrayIterator(["read", "write", "run", "ffi"]) - ) { - if (ArrayIsArray(permissions[key])) { - serializedPermissions[key] = ArrayPrototypeMap( - permissions[key], - (path) => pathFromURL(path), - ); - } else { - serializedPermissions[key] = permissions[key]; - } +/** Converts all file URLs in FS allowlists to paths. */ +function serializePermissions(permissions) { + if (typeof permissions == "object" && permissions != null) { + const serializedPermissions = {}; + for ( + const key of new SafeArrayIterator(["read", "write", "run", "ffi"]) + ) { + if (ArrayIsArray(permissions[key])) { + serializedPermissions[key] = ArrayPrototypeMap( + permissions[key], + (path) => pathFromURL(path), + ); + } else { + serializedPermissions[key] = permissions[key]; } - for ( - const key of new SafeArrayIterator(["env", "hrtime", "net", "sys"]) - ) { - if (ArrayIsArray(permissions[key])) { - serializedPermissions[key] = ArrayPrototypeSlice(permissions[key]); - } else { - serializedPermissions[key] = permissions[key]; - } + } + for ( + const key of new SafeArrayIterator(["env", "hrtime", "net", "sys"]) + ) { + if (ArrayIsArray(permissions[key])) { + serializedPermissions[key] = ArrayPrototypeSlice(permissions[key]); + } else { + serializedPermissions[key] = permissions[key]; } - return serializedPermissions; } - return permissions; + return serializedPermissions; } + return permissions; +} - window.__bootstrap.permissions = { - serializePermissions, - permissions, - Permissions, - PermissionStatus, - }; -})(this); +export { Permissions, permissions, PermissionStatus, serializePermissions }; |