permissify
v1.1.3
Published
[](https://www.npmjs.com/package/permissify) [](LICENSE) [](https://www.npmjs.com
Readme
📦 Permissify
Permissify is a wrapper for the navigator browser api. It greatly improves the developer experience by providing more detailed feedback.
Enjoy my work? :)
Buy me a coffee! ☕
✨ Features
🚀 Works on all browsers
🔥 Framework for convenient camera usage
✅ Classes as Enums: strongly typed and usable with instanceof
🔧 Strongly typed and amazing IntelliSense via discriminated unions(tagged unions)
Table of Contents
- Introduction
- Installation
- Usage
- API Reference
- Type Reference
- ResolutionTable
- GlobalCameraConstraints
- FailedCameraRequest
- SuccessfulCameraRequestResult
- SuccessfulCameraRequest
- CameraRequestDeniedWrapper
- CameraAcceptedDeniedWrapper
- RequestRetryableBasic
- RequestRetryableAfterReload
- RequestRetryableUnknown
- RequestRetryableWithDetail
- CameraInitErrorClass
- BrowserDeniedReasonClass
- BrowserPermissionStateClass
- Examples
- Contributing
- Changelog
- Support
- License
📦 Installation
Install via npm:
npm install permissifyOr using yarn:
yarn add permissify🚀 Usage
Basic example:
import { CameraPermissionHandler } from "permissify";
const handler = new CameraPermissionHandler();
onMounted(async () => {
const initResult = await handler.initHandler();
if(initResult.permissionGranted === true) {
//request successful and results(strongly typed):
const workingStream = initResult.request.result.stream;
//set html stream source;
console.log(initResult.request.result.devices);
return;
}
//handle any kind of errors
})More advanced example:
import { CameraPermissionHandler } from "permissify";
import { CameraInitErrorClass } from "permissify";
const handler = new CameraPermissionHandler();
onMounted(async () => {
const initResult = await handler.initHandler();
//Handle initial errors e.g Navigator api not supported
if (initResult instanceof CameraInitErrorClass) {
console.log("Error starting cam: ", initResult); //Handle your initial error
return;
}
//IMPORTANT: strictly check for false (instead of !initResult.permissionGranted)
// to retain strong ts types and intelliSense
if(initResult.permissionGranted === false) {
console.log("Camera Access denied by: ", initResult.deniedBy); //Browser or User
console.log("Is retryable: ", initResult.retryable); //handle retry
return
}
//request successful and results(strongly typed):
const workingStream = initResult.request.result.stream;
//set html stream source;
console.log(initResult.request.result.devices);
})
onUnmounted(() => {
//stop camera
})on(eventName: , listener: () => void): void
Requests permission for video device access and returns the result, including the permission state before and after the request.
This is considered to be the more "unguided approach" to request a videoDevice. Consider using startCamera() instead
Events:
| Name | callback-type | Description |
|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| video-devicelist-update | Map<string, MediaDeviceInfo> | Gets fired when the list of available video-devices changes. This can either happen when the list is first initalized or when the browser detects a new device/ a device is removed. |
| log | string | Gets fired for internal logs. |
| permission-status-change | { detail: string, state: BrowserPermissionStateClass } | Gets fired when the browser permission state changes. This could be the case when the user manually disables camera access in the browser. |
Parameters:
| Parameter | Type | Description |
|-------------|-------------------------------------------------|------------------------|
| eventName | [event-name] as string | The event to listen to |
| listener | (data: [callback-type] of [event-name]) => void | The event to listen to |
Example:
import { CameraPermissionHandler } from "permissify";
import { BrowserPermissionStateClass } from "permissify";
const handler = new CameraPermissionHandler();
handler.on('permission-status-change', (data: { detail: string, state: BrowserPermissionStateClass }) => {
console.log(data.state, data.detail)
//handle data
})Returns:
- void
requestVideoDevice(userMediaConstraints?: MediaStreamConstraints): Promise<SuccessfulCameraRequest | FailedCameraRequest>
Requests permission for video device access and returns the result, including the permission state before and after the request.
This is considered to be the more "unguided approach" to request a videoDevice. Consider using startCamera() instead
Parameters:
| Parameter | Type | Description |
|-----------------------|------------------------|----------------------------------------------------|
| userMediaConstraints | MediaStreamConstraints | The constraints for accessing the media stream (optional) |
Returns:
- Promise<SuccessfulCameraRequest | FailedCameraRequest> - A promise that resolves with either a successful or failed camera request, along with permission state and duration.
getVideoDevices(): Promise<{ successful: true, result: MediaDeviceInfo[], duration: number } | { successful: false, result: string, duration: number }>
Gets a list of video devices and returns either a success with the device list or a failure with the error message.
Parameters:
None
Returns:
- Promise<{ successful: true, result: MediaDeviceInfo[], duration: number } | { successful: false, result: string, duration: number }> - A promise that resolves with either a successful response containing video devices or a failed response with an error message.
getMediaDeviceByStream(stream: MediaStream)
Extracts the video device ID from the given media stream.
Parameters:
| Parameter | Type | Description |
|-----------|------------|----------------------------------------|
| stream | MediaStream | The media stream to extract device info from |
Returns:
- { videoDevice: MediaTrackSettings | null } - The video device settings extracted from the media stream.
startCamera(id?: string, constraints?: MediaStreamConstraints): Promise<CameraRequestAcceptedWrapper | CameraRequestDeniedWrapper | CameraInitErrorClass>
Starts the camera with the given device ID and constraints, and returns the result based on permission state.
Parameters:
| Parameter | Type | Description |
|-------------|------------------------|--------------------------------------------------|
| id | string (optional) | The ID of the video device to use (optional) |
| constraints | MediaStreamConstraints | The media stream constraints (optional) |
Returns:
- Promise<CameraRequestAcceptedWrapper | CameraRequestDeniedWrapper | CameraInitErrorClass> - A promise that resolves with either a successful camera start response, a denied camera request, or an error.
getBrowserPermissionState(): Promise<{ state: BrowserPermissionStateClass, detail: string }>
Checks the current permission state for camera access and returns the state along with a detailed message.
Parameters:
None
Returns:
- Promise<{ state: BrowserPermissionStateClass, detail: string }> - A promise that resolves with the camera permission state and a description of the state.
stopCameraByStream(stream: MediaStream, track?: MediaStreamTrack)
Stops the given media stream or a specific track within the stream.
Parameters:
| Parameter | Type | Description |
|-----------|-----------------|---------------------------------------------------|
| stream | MediaStream | The media stream to stop |
| track | MediaStreamTrack (optional) | A specific track to remove from the stream (optional) |
Returns:
- CameraInitErrorClass | void - Returns a CameraInitErrorClass if the camera ID doesn't exist, or stops the camera/ a specific track if provided.
stopCameraStreamById(cameraId: string, track?: MediaStreamTrack)
Stops the camera stream associated with the given camera ID, or stops a specific track in the stream.
Parameters:
| Parameter | Type | Description |
|------------|---------------------|---------------------------------------------------|
| cameraId | string | The ID of the camera stream to stop |
| track | MediaStreamTrack (optional) | A specific track to remove from the stream (optional) |
Returns:
- CameraInitErrorClass | void - Returns a CameraInitErrorClass if the camera ID doesn't exist, or stops the tracks in the stream.
getPreferredCamera(videoDevices: MediaDeviceInfo[])
Determines the preferred camera (environmental or front) from a list of available video devices.
Parameters:
| Parameter | Type | Description |
|-------------------|-------------------|-------------------------------------------------------|
| videoDevices | MediaDeviceInfo | An array of available video devices |
Returns:
- { facing: string, id: string } - Returns the preferred camera's facing direction ('environment', 'front', or 'unknown') and the device ID of the camera.
initHandler(constraints: MediaStreamConstraints = { video: GlobalIdealCameraConstraints }): Promise<CameraRequestAcceptedWrapper | CameraRequestDeniedWrapper | CameraInitErrorClass>
Initializes the camera and handles permission states, device detection, and updates for the camera access.
Parameters:
| Parameter | Type | Description |
|---------------|----------------------|---------------------------------------------------|
| constraints | MediaStreamConstraints (optional) | The constraints for the media stream (default is GlobalIdealCameraConstraints) |
Returns:
- Promise<CameraRequestAcceptedWrapper | CameraRequestDeniedWrapper | CameraInitErrorClass> - A promise that resolves with the appropriate response, either an accepted wrapper, denied wrapper, or error.
📖 API Reference: Types
Resolution Table: resolution16By9Table
Defines a mapping of common resolutions with a 16:9 aspect ratio, including 4k and 720p resolutions.
{
'4k': { height: 4096, width: 2160 },
'720p': { height: 1280, width: 720 }
}Global Camera Constraints: GlobalIdealCameraConstraints
Defines ideal camera settings using 720p resolution with a front-facing camera and a 60fps frame rate.
{
height: { ideal: 1280 },
width: { ideal: 720 },
facingMode: { ideal: 'environment' },
frameRate: { ideal: 60 }
}FailedCameraRequest
Represents a failed camera request with details about permission state, error information, and request duration.
SuccessfulCameraRequestResult
Represents a successful camera request, containing the stream and device information.
SuccessfulCameraRequest
Represents a successful camera request, including permission states and the resulting stream and device information.
RequestRetryableBasic
Represents a request that can be retried, indicating if the retry is possible.
RequestRetryableAfterReload
Describes a retryable request that can only be retried after a reload, specifying the trigger for reload.
RequestRetryableUnknown
Describes a retryable request with an unknown status.
CameraRequestDeniedWrapper
Represents a denied camera request with details about the denial reason, retry status, and permission state.
CameraRequestAcceptedWrapper
Represents an accepted camera request with permission status and result details.
CameraInitErrorClass
Represents various camera initialization error states such as PermissionDismissed, PermissionDenied, NoDevices, etc.
class CameraInitErrorClass {
static readonly PermissionDismissed = new CameraInitErrorClass("PermissionDismissed");
static readonly PermissionDenied = new CameraInitErrorClass("PermissionDenied");
static readonly InUse = new CameraInitErrorClass("InUse");
static readonly Overconstrained = new CameraInitErrorClass("Overconstrained");
static readonly UnknownError = new CameraInitErrorClass("UnknownError");
static readonly BrowserApiInaccessible = new CameraInitErrorClass("BrowserApiInaccessible");
static readonly NoDevices = new CameraInitErrorClass("NoDevices");
}BrowserDeniedReasonClass
Represents the reason for denial of camera access, either by the browser or the user.
class BrowserDeniedReasonClass {
static readonly Browser = new BrowserDeniedReasonClass("Browser");
static readonly User = new BrowserDeniedReasonClass("User");
}BrowserPermissionStateClass
Represents the permission state of the browser, with values like Granted, Denied, Prompt, etc.
export class PermissionsRetryableClass {
static readonly Yes = new PermissionsRetryableClass("Yes");
static readonly No = new PermissionsRetryableClass("No");
static readonly AfterReload = new PermissionsRetryableClass("AfterReload");
static readonly Unknown = new PermissionsRetryableClass("Unknown");
}🎯 Examples
Check out the /examples folder for more detailed usage.
🛠️ Development
Clone the repository:
git clone https://github.com/Laurenz-M/permissify.git
cd permissify
npm install📝 Changelog
- Version 1.1.0: Change function names and add documentation
🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature-branch) - Commit your changes (
git commit -m 'Add new feature') - Push to the branch (
git push origin feature-branch) - Open a Pull Request
📜 License
This project is licensed under the MIT License - see the LICENSE file for details.
