All files / permissions.ts

100.00% Branches 3/3
100.00% Lines 64/64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
x1
 
x5
 
x5
x5
x5
x352
x352
 
x5
x5
x5
x17
x18
x18
x17
x85
x17
 
x5
x5
x10
x10
x10
x10
 
x5
x5
x5
 
x5
x5
x5
x21
x21
x21
x21
x21
 
x5
x5
x8
x8
 
x5
x7
x7
 
x5
 
x20
x20
x33
x33
 
x20
x22
x22
 
x20
 
x20
x20
x21
x21
x22
x22
x22
x22
x22
x22
x21
x21
 
x20
x5
x5











































































// Imports
import type { Nullable } from "@libs/typing"
import { type _Permissions, type _PermissionsStatus, dispatch, illegal, internal } from "./_.ts"

/** https://developer.mozilla.org/en-US/docs/Web/API/Permissions */
export class Permissions implements _Permissions {
  constructor(_?: { [internal]?: boolean }) {
    illegal(arguments)
  }

  // https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query
  // Note: arbitrary set to "denied" by default
  query({ name }: PermissionDescriptor): Promise<PermissionsStatus> {
    if (!name) {
      return Promise.reject(new TypeError(`'${name}' (value of 'name' member of PermissionDescriptor) is not a valid value for enumeration PermissionName.`))
    }
    const state = this.#state[name] ?? "denied"
    return Promise.resolve(new PermissionsStatus({ [internal]: true, name, state }))
  }

  /** Internal acessor. */
  get [internal](): { state: Record<string, PermissionState> } {
    return {
      state: this.#state,
    }
  }

  /** Custom permissions state that can be set through {@link internal}. */
  readonly #state = {} as Record<string, PermissionState>
}

/** https://developer.mozilla.org/en-US/docs/Web/API/PermissionStatus */
export class PermissionsStatus extends EventTarget implements _PermissionsStatus {
  constructor({ name, state } = {} as { [internal]?: boolean; name?: PermissionsStatus["name"]; state?: PermissionState }) {
    illegal(arguments)
    super()
    this.#name = name!
    this.#state = state!
  }

  // https://developer.mozilla.org/en-US/docs/Web/API/PermissionStatus/name
  get name(): string {
    return this.#name
  }

  set name(_: string) {
    return
  }

  readonly #name

  // https://developer.mozilla.org/en-US/docs/Web/API/PermissionStatus/state
  get state(): PermissionState {
    return this.#state
  }

  set state(_: PermissionState) {
    return
  }

  #state

  /** Internal acessor. */
  get [internal](): { state: (state: PermissionsStatus["state"]) => void } {
    return {
      state: (state: PermissionsStatus["state"]) => {
        const changed = this.#state !== state
        this.#state = state
        if (changed) {
          dispatch(this, new Event("change"))
        }
      },
    }
  }

  // deno-lint-ignore no-explicit-any
  onchange = null as Nullable<(this: _PermissionsStatus, event: Event) => any>
}