diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2020-03-19 21:32:49 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-19 11:32:49 +0100 |
commit | 5b10ab0984fd762c14caf524d59ec8b6940d2bfb (patch) | |
tree | 1201c46987eacaf93b99231eb28ed1d1dd7998ea /std/permissions/mod.ts | |
parent | b0b27c43100bf4a7303174b9765c853d2f76f207 (diff) |
feat: Add helper functions for permissions to std (#4258)
Diffstat (limited to 'std/permissions/mod.ts')
-rw-r--r-- | std/permissions/mod.ts | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/std/permissions/mod.ts b/std/permissions/mod.ts new file mode 100644 index 000000000..e11493426 --- /dev/null +++ b/std/permissions/mod.ts @@ -0,0 +1,120 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +const { PermissionDenied } = Deno.errors; + +function getPermissionString(descriptors: Deno.PermissionDescriptor[]): string { + return descriptors.length + ? ` ${descriptors + .map(pd => { + switch (pd.name) { + case "read": + case "write": + return pd.path + ? `--allow-${pd.name}=${pd.path}` + : `--allow-${pd.name}`; + case "net": + return pd.url + ? `--allow-${pd.name}=${pd.url}` + : `--allow-${pd.name}`; + default: + return `--allow-${pd.name}`; + } + }) + .join("\n ")}` + : ""; +} + +/** Attempts to grant a set of permissions, resolving with the descriptors of + * the permissions that are granted. + * + * const perms = await grant({ name: "net" }, { name: "read" }); + * if (perms && perms.length === 2) { + * // do something cool that connects to the net and reads files + * } else { + * // notify user of missing permissions + * } + * + * If one of the permissions requires a prompt, the function will attempt to + * prompt for it. The function resolves with all of the granted permissions. */ +export async function grant( + ...descriptors: Deno.PermissionDescriptor[] +): Promise<void | Deno.PermissionDescriptor[]>; +/** Attempts to grant a set of permissions, resolving with the descriptors of + * the permissions that are granted. + * + * const perms = await grant([{ name: "net" }, { name: "read" }]); + * if (perms && perms.length === 2) { + * // do something cool that connects to the net and reads files + * } else { + * // notify user of missing permissions + * } + * + * If one of the permissions requires a prompt, the function will attempt to + * prompt for it. The function resolves with all of the granted permissions. */ +export async function grant( + descriptors: Deno.PermissionDescriptor[] +): Promise<void | Deno.PermissionDescriptor[]>; +export async function grant( + descriptor: Deno.PermissionDescriptor[] | Deno.PermissionDescriptor, + ...descriptors: Deno.PermissionDescriptor[] +): Promise<void | Deno.PermissionDescriptor[]> { + const result: Deno.PermissionDescriptor[] = []; + descriptors = Array.isArray(descriptor) + ? descriptor + : [descriptor, ...descriptors]; + for (const descriptor of descriptors) { + let state = (await Deno.permissions.query(descriptor)).state; + if (state === "prompt") { + state = (await Deno.permissions.request(descriptor)).state; + } + if (state === "granted") { + result.push(descriptor); + } + } + return result.length ? result : undefined; +} + +/** Attempts to grant a set of permissions or rejects. + * + * await grantOrThrow({ name: "env" }, { name: "net" }); + * + * If the permission can be prompted for, the function will attempt to prompt. + * If any of the permissions are denied, the function will reject for the first + * permission that is denied. If all permissions are granted, the function + * will resolve. */ +export async function grantOrThrow( + ...descriptors: Deno.PermissionDescriptor[] +): Promise<void>; +/** Attempts to grant a set of permissions or rejects. + * + * await grantOrThrow([{ name: "env" }, { name: "net" }]); + * + * If the permission can be prompted for, the function will attempt to prompt. + * If any of the permissions are denied, the function will reject mentioning the + * the denied permissions. If all permissions are granted, the function will + * resolve. */ +export async function grantOrThrow( + descriptors: Deno.PermissionDescriptor[] +): Promise<void>; +export async function grantOrThrow( + descriptor: Deno.PermissionDescriptor[] | Deno.PermissionDescriptor, + ...descriptors: Deno.PermissionDescriptor[] +): Promise<void> { + const denied: Deno.PermissionDescriptor[] = []; + descriptors = Array.isArray(descriptor) + ? descriptor + : [descriptor, ...descriptors]; + for (const descriptor of descriptors) { + const { state } = await Deno.permissions.request(descriptor); + if (state !== "granted") { + denied.push(descriptor); + } + } + if (denied.length) { + throw new PermissionDenied( + `The following permissions have not been granted:\n${getPermissionString( + denied + )}` + ); + } +} |