npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@trimjs/web-app

v0.4.2

Published

web app sdk for nas

Readme

@trimjs/web-app

SDK for building apps that run inside the Trim host environment.

@trimjs/web-app provides a single JavaScript API for common host capabilities, including page title updates, file operations, file authorization, app settings, and App Auth route flows. It works in supported web iframe hosts and mobile WebView hosts.

Installation

npm install @trimjs/web-app
yarn add @trimjs/web-app
pnpm add @trimjs/web-app

Quick Start

import { TrimApp } from '@trimjs/web-app';

const app = new TrimApp();

await app.setTitle('My App');

const config = await app.getPlatformConfig();
console.log(config.theme, config.language);

All host APIs wait for SDK initialization internally. You usually do not need to call ready() before using them.

Basic Usage

import { TrimApp } from '@trimjs/web-app';

const app = new TrimApp({ debug: true });

await app.setTitle('Document Viewer');

await app.openFile('/vol1/1000/demo.pdf');

await app.openFileManager('/vol1/1000');

await app.setExitPageTips({
  title: 'Leave this page?',
  content: 'Unsaved changes may be lost.',
});

const files = await app.pickFile({
  multiple: true,
  accept: ['.pdf', '.doc', '.docx'],
  title: 'Select files',
});

const userFileAuth = await app.authorizeUserFile('/vol1/1000/photos');
console.log(userFileAuth?.data);

Public APIs

Constructor

new TrimApp(options?: TrimAppOptions)

Creates a Trim app SDK instance.

const app = new TrimApp({ debug: true });

ready

ready(): Promise<void>

Waits until the SDK initialization is complete. Most apps do not need to call this explicitly because SDK methods wait for initialization automatically.

setTitle

setTitle(title: string): Promise<void | null>

Sets the current app page title in the host.

await app.setTitle('My App');

setExitPageTips

setExitPageTips(params?: { title?: string; content?: string }): Promise<void | null>

Sets or clears the confirmation message shown when the user leaves the app page.

await app.setExitPageTips({
  title: 'Leave this page?',
  content: 'Unsaved changes may be lost.',
});

await app.setExitPageTips();

getPlatformConfig

getPlatformConfig(): Promise<PlatformConfig>

Returns host platform settings such as theme, language, app version, system version, date format, and time format.

const config = await app.getPlatformConfig();

if (config.theme === 'dark') {
  document.documentElement.classList.add('dark');
}

openFile

openFile(path: string): Promise<void | null>

Opens a file with the host system.

await app.openFile('/vol1/1000/demo.pdf');

openFileManager

openFileManager(path: string): Promise<void | null>

Opens the host file manager and navigates to the given path.

await app.openFileManager('/vol1/1000');

openAppSetting

openAppSetting(): Promise<void | null>

Opens the current app settings page in the host system.

await app.openAppSetting();

openURL

openURL(url: string, target?: string, features?: string): Promise<void | null>

Opens a URL using the host-supported behavior. In a web host, this follows browser window.open behavior. In a mobile WebView host, it opens the URL in the system browser.

await app.openURL('https://example.com', '_blank');

close

close(): Promise<void | null>

Closes the current app page.

await app.close();

showFileDetails

showFileDetails(paths: string[], options?: FileDetailsOptions): Promise<void | null>

Shows the host file details panel for one or more paths.

await app.showFileDetails(['/vol1/1000/photos'], { admin: true });

authorizeUserFile

authorizeUserFile(path: string): Promise<AppBridgeResponse<boolean> | undefined>

Requests authorization for a user file or folder path.

const result = await app.authorizeUserFile('/vol1/1000/photos');

if (result?.data) {
  console.log('Authorized');
}

authorizeSharedFile

authorizeSharedFile(path: string): Promise<AppBridgeResponse<boolean> | undefined>

Requests authorization for a shared file or folder path.

const result = await app.authorizeSharedFile('/share/demo');

pickFile

pickFile(params: FilePickerParams): Promise<string[] | undefined>

Opens the host file picker.

const files = await app.pickFile({
  multiple: true,
  accept: ['.pdf', '.jpg', '.jpeg', '.png', '.gif', '.webp'],
  sidebarGroup: ['myFiles', 'external'],
  title: 'Select files',
});

pickUserFile

pickUserFile(params?: FilePickerParams): Promise<AppBridgeResponse<string[]> | undefined>

Opens the user file picker and authorizes the selected paths for the current app.

const result = await app.pickUserFile({
  accept: ['.jpg', '.jpeg', '.png'],
  sidebarGroup: ['myFiles', 'external'],
  title: 'Select and authorize files',
});

console.log(result?.data);

Common FilePickerParams fields:

| Field | Type | Description | | --------------- | ---------- | --------------------------------------------------- | | multiple | boolean | Allows selecting multiple files. | | directory | boolean | Allows selecting folders instead of files. | | accept | string[] | Accepted file extensions, each prefixed with .. | | sidebarGroup | string[] | Sidebar groups to show, in display order. | | title | string | Picker title. | | okText | string | Confirm button text. | | creatable | boolean | Allows creating folders when supported by the host. | | disabledPaths | string[] | Paths that cannot be selected. |

pickSharedFile

pickSharedFile(
  params?: Omit<FilePickerParams, 'directory'>,
): Promise<AppBridgeResponse<string[]> | undefined>

Opens the shared file picker and authorizes the selected shared paths for the current app. The host controls the directory behavior, so callers should not pass it.

const result = await app.pickSharedFile({
  title: 'Select shared folder',
  sidebarGroup: ['myFiles', 'otherShare'],
});

console.log(result?.data);

Host Events

$on

$on(event: string, callback: (...args: unknown[]) => void): Promise<void>

Subscribes to host events when the current runtime provides an event bus. The most common use cases are reacting to theme and language changes.

await app.$on('os/theme', (theme) => {
  console.log('Theme changed:', theme);
});

await app.$on('os/language', (language) => {
  console.log('Language changed:', language);
});

App Auth Route Flow

App Auth routes are useful when an app needs to start a file authorization or file picker flow through a route-based page and receive the result through a callback URL.

openAppAuth

openAppAuth(
  method: AppAuthMethod,
  params: AppAuthParams,
  options?: { target?: string; features?: string },
): Promise<string>

Starts an App Auth route flow. The returned string is the URL that was opened.

await app.openAppAuth('pickFile', {
  appName: 'trim.demo',
  directory: true,
  redirectUri: '/callback',
  state: 'pick-file-demo',
});

Supported method names and their internal routes:

| method | route | | --------------------- | --------------------------------- | | pickFile | /app-auth/pick-file | | pickUserFile | /app-auth/pick-user-file | | pickSharedFile | /app-auth/pick-shared-file | | authorizeUserFile | /app-auth/authorize-user-file | | authorizeSharedFile | /app-auth/authorize-shared-file |

parseAppAuthCallback

parseAppAuthCallback(input?: string | URL | URLSearchParams): AppAuthResult

Parses the callback query parameters returned by an App Auth route flow.

const result = app.parseAppAuthCallback();

console.log(result.status);
console.log(result.method);
console.log(result.state);
console.log(result.path);

For successful picker routes, result.path contains the selected paths.

buildAppAuthUrl

buildAppAuthUrl(method: AppAuthMethod, params: AppAuthParams): Promise<string>

Builds an App Auth route URL without opening it. Most apps should use openAppAuth() directly. Use this helper only when you need to control navigation yourself.

All methods accept these common params:

| Field | Type | Required | Description | | ------------- | -------- | -------- | --------------------------------------------------------------- | | appName | string | Yes | App identifier used by the authorization flow. | | redirectUri | string | No | Callback URL or path that receives the authorization result. | | state | string | No | Caller-defined opaque value returned unchanged in the callback. |

state does not affect authorization. Use it to correlate a callback with the flow that created it. For security-sensitive flows, generate an unpredictable value, store it before navigation, and verify that the callback returns the same value.

pickFile

buildAppAuthUrl(method: 'pickFile', params: AppAuthPickFileParams): Promise<string>

| Field | Type | Required | Description | | -------------- | ---------- | -------- | ------------------------------------------------- | | directory | boolean | No | Select folders instead of files. | | accept | string[] | No | Accepted file extensions, each prefixed with .. | | sidebarGroup | string[] | No | Sidebar groups to show, in display order. |

const url = await app.buildAppAuthUrl('pickFile', {
  appName: 'trim.demo',
  directory: false,
  accept: ['.jpg', '.jpeg', '.png'],
  sidebarGroup: ['myFiles', 'external'],
  redirectUri: '/callback',
  state: 'pick-file-demo',
});

pickUserFile

buildAppAuthUrl(method: 'pickUserFile', params: AppAuthPickFileParams): Promise<string>

pickUserFile supports the same picker params as pickFile, then authorizes the selected user paths for appName before redirecting.

| Field | Type | Required | Description | | -------------- | ---------- | -------- | ------------------------------------------------- | | directory | boolean | No | Select folders instead of files. | | accept | string[] | No | Accepted file extensions, each prefixed with .. | | sidebarGroup | string[] | No | Sidebar groups to show, in display order. |

const url = await app.buildAppAuthUrl('pickUserFile', {
  appName: 'trim.demo',
  directory: false,
  accept: ['.jpg', '.jpeg', '.png'],
  sidebarGroup: ['myFiles', 'external'],
  redirectUri: '/callback',
  state: 'pick-user-file-demo',
});

pickSharedFile

buildAppAuthUrl(method: 'pickSharedFile', params: AppAuthPickSharedFileParams): Promise<string>

pickSharedFile selects a shared folder. Its directory behavior is controlled by the host and cannot be configured by the caller.

| Field | Type | Required | Description | | -------------- | ---------- | -------- | ----------------------------------------- | | sidebarGroup | string[] | No | Sidebar groups to show, in display order. |

const url = await app.buildAppAuthUrl('pickSharedFile', {
  appName: 'trim.demo',
  sidebarGroup: ['myFiles', 'otherShare'],
  redirectUri: '/callback',
  state: 'pick-shared-file-demo',
});

authorizeUserFile

buildAppAuthUrl(method: 'authorizeUserFile', params: AppAuthAuthorizeParams): Promise<string>

| Field | Type | Required | Description | | ------ | -------- | -------- | -------------------------------------- | | path | string | Yes | User file or folder path to authorize. |

const url = await app.buildAppAuthUrl('authorizeUserFile', {
  appName: 'trim.demo',
  path: '/vol1/1000/photos',
  redirectUri: '/callback',
  state: 'authorize-user-file-demo',
});

authorizeSharedFile

buildAppAuthUrl(method: 'authorizeSharedFile', params: AppAuthAuthorizeParams): Promise<string>

| Field | Type | Required | Description | | ------ | -------- | -------- | ---------------------------------------- | | path | string | Yes | Shared file or folder path to authorize. |

const url = await app.buildAppAuthUrl('authorizeSharedFile', {
  appName: 'trim.demo',
  path: '/share/demo',
  redirectUri: '/callback',
  state: 'authorize-shared-file-demo',
});

Instance Properties

isWeb

isWeb: boolean;

Indicates whether the current runtime is a web host.

isStandaloneWeb

isStandaloneWeb: boolean;

Indicates whether the current runtime is a standalone browser page without an iframe host.

Types

import type {
  AppAuthAuthorizeParams,
  AppAuthBaseParams,
  AppAuthCallbackError,
  AppAuthCallbackStatus,
  AppAuthMethod,
  AppAuthMethodParamsMap,
  AppAuthParams,
  AppAuthPickFileParams,
  AppAuthPickSharedFileParams,
  AppAuthResult,
  AppBridgeResponse,
  AuthorizeFileResult,
  FileDetailsOptions,
  FilePickerParams,
  PlatformConfig,
  TrimAppOptions,
} from '@trimjs/web-app';

TrimAppOptions

interface TrimAppOptions {
  debug?: boolean;
}

PlatformConfig

interface PlatformConfig {
  theme: 'dark' | 'light';
  language: string;
  appVersion?: string;
  systemVersion: string;
  format: {
    date?: string;
    time?: string;
  };
}

AppBridgeResponse

type AppBridgeResponse<T> = {
  code: number;
  msg: string;
  data: T;
};

Platform Notes

The SDK normalizes supported host APIs across web iframe hosts and mobile WebView hosts. Some APIs may require a recent host version. When an API is unavailable, the SDK throws an error or returns undefined depending on the method behavior.

For route-based App Auth flows, use openAppAuth() to start the flow and parseAppAuthCallback() on the callback page to read the result.

License

MIT