@nodecg/types
Version:
Dynamic broadcast graphics rendered in a browser
460 lines (417 loc) • 10.7 kB
text/typescript
/* eslint-disable @typescript-eslint/no-namespace */
import type { DatabaseAdapter } from "@nodecg/database-adapter-types";
import type express from "express";
import type * as ExpressCore from "express-serve-static-core";
import type { NodeCGConfig } from "./nodecg-config-schema";
import type {
ClientToServerEvents,
ServerToClientEvents,
} from "./socket-protocol";
type Person =
| {
name: string;
email?: string;
url?: string;
}
| string;
export namespace NodeCG {
/**
* A collection of types that represent the raw data from the `nodecg` stanza in a bundle's `package.json`.
*/
export namespace Manifest {
/**
* An unparsed `assetCategory` from a bundle's `package.json`.
*/
export interface UnparsedAssetCategory {
name: string;
title: string;
allowedTypes?: string[];
}
/**
* An unparsed `panel` from a bundle's `package.json`.
*/
export interface UnparsedPanel {
name: string;
title: string;
file: string;
headerColor?: string;
fullbleed?: boolean;
workspace?: string;
dialog?: boolean;
dialogButtons?: { name: string; type: "dismiss" | "confirm" }[];
width?: number;
}
/**
* An unparsed `graphic` from a bundle's `package.json`.
*/
export interface UnparsedGraphic {
file: string;
width: number;
height: number;
singleInstance?: boolean;
}
/**
* An unparsed `mount` configuration from a bundle's `package.json`.
*/
export interface UnparsedMount {
directory: string;
endpoint: string;
}
/**
* An unparsed `soundCue` from a bundle's `package.json`.
*/
export interface UnparsedSoundCue {
name: string;
assignable?: boolean;
defaultVolume?: number;
defaultFile?: string;
}
/**
* An unparsed record of `bundleDependencies` from a bundle's `package.json`.
*/
export type UnparsedBundleDependencies = Record<string, string>;
/**
* The actual structure of a bundle's `nodecg` stanza from it's `package.json`.
*/
export interface UnparsedManifest {
compatibleRange?: string;
transformBareModuleSpecifiers?: boolean;
dashboardPanels?: UnparsedPanel[];
graphics?: UnparsedGraphic[];
assetCategories?: UnparsedAssetCategory[];
mount?: UnparsedMount[];
soundCues?: UnparsedSoundCue[];
bundleDependencies?: UnparsedBundleDependencies;
}
}
/**
* The rough structure of a bundle's `package.json`.
* Only includes types that NodeCG cares about.
*/
export interface PackageJSON {
name: string;
version: string;
license?: string;
description?: string;
homepage?: string;
author?: Person;
contributors?: Person[];
nodecg?: Manifest.UnparsedManifest;
}
/**
* A _parsed_ bundle manifest as used internally by NodeCG.
*/
export type Manifest = Omit<PackageJSON, "nodecg"> &
Manifest.UnparsedManifest & { transformBareModuleSpecifiers: boolean };
/**
* A collection of types that comprise a `bundle`.
*/
export namespace Bundle {
export type GitData =
| undefined
| {
branch: string;
hash: string;
shortHash: string;
}
| {
branch: string;
hash: string;
shortHash: string;
date: string;
message: string;
};
export type Graphic = {
url: string;
} & Required<Manifest.UnparsedGraphic>;
export type Panel = Manifest.UnparsedPanel & {
path: string;
headerColor: string;
bundleName: string;
html: string;
} & (
| {
dialog: false;
workspace: string;
}
| {
dialog: true;
}
) &
(
| {
fullbleed: false;
width: number;
}
| {
fullbleed: true;
}
);
export type Mount = Manifest.UnparsedMount;
export type SoundCue = Manifest.UnparsedSoundCue;
export type AssetCategory = Manifest.UnparsedAssetCategory;
export type BundleDependencies = Manifest.UnparsedBundleDependencies;
export type UnknownConfig = Record<string, unknown>;
}
export interface NodecgBundleConfig {
databaseAdapter?: DatabaseAdapter;
}
/**
* The actual type of a `bundle`.
*/
export interface Bundle {
name: string;
version: string;
license?: string;
description?: string;
homepage?: string;
author?: Person;
contributors?: Person[];
dir: string;
git: Bundle.GitData;
transformBareModuleSpecifiers: boolean;
hasAssignableSoundCues: boolean;
hasExtension: boolean;
config: Bundle.UnknownConfig;
dashboard: {
dir: string;
panels: Bundle.Panel[];
};
graphics: Bundle.Graphic[];
assetCategories: Bundle.AssetCategory[];
mount: Bundle.Mount[];
soundCues: Bundle.SoundCue[];
compatibleRange?: string;
bundleDependencies?: Bundle.BundleDependencies;
nodecgBundleConfig: NodecgBundleConfig;
}
/**
* NodeCG's socket protocol.
* It is unikely that you will need to use this directly.
* Does not include builtin Socket.IO events such as `connect`, `disconnect`, etc.
*/
export interface SocketProtocol {
serverToClient: ServerToClientEvents;
clientToServer: ClientToServerEvents;
}
/**
* The full, parsed NodeCG config (i.e `cfg/nodecg.{json,yaml,js}`).
* Contains sensitive secrets!
* Available to server-side code (extensions) only.
*/
export type Config = NodeCGConfig;
/**
* The filtered, minimal, parsed NodeCG config (i.e `cfg/nodecg.{json,yaml,js}`).
* Does not contain any sensitive secrets.
* Available to client-side code (dashboard, graphics) only.
*/
export interface FilteredConfig {
host: string;
port: number;
baseURL: string;
logging: {
console: {
enabled: boolean;
level: string;
timestamps: boolean;
replicants: boolean;
};
file: {
enabled: boolean;
level: string;
timestamps: boolean;
replicants: boolean;
};
};
sentry: {
enabled: boolean;
dsn?: string;
};
login: {
enabled: boolean;
steam?: {
enabled: boolean;
};
twitch?: {
enabled: boolean;
clientID?: string;
scope?: string;
};
local?: {
enabled: boolean;
};
discord?: {
enabled: boolean;
clientID?: string;
scope?: string;
};
};
ssl?: {
enabled: boolean;
};
}
/**
* A sound cue `file`, as used in sound cue Replicants.
*/
export interface CueFile {
sum: string;
base: string;
ext: string;
name: string;
url: string;
default: boolean;
}
/**
* A sound cue definition, as used in sound cue Replicants.
*/
export interface SoundCue {
name: string;
volume: number;
file?: CueFile;
assignable: boolean;
channels?: number;
bundleName?: TemplateStringsArray;
defaultVolume?: number | undefined;
defaultFile?: CueFile;
}
/**
* An asset file, as used in assets Replicants.
*/
export interface AssetFile {
sum: string;
base: string;
ext: string;
name: string;
namespace: string;
category: string;
url: string;
}
/**
* A namespace containing various types used in the Replicant system.
* It should be unlikely that you need to use these directly.
*/
export namespace Replicant {
export type Options<D> = OptionsNoDefault | OptionsWithDefault<D>;
export interface OptionsNoDefault {
persistent?: boolean;
persistenceInterval?: number;
schemaPath?: string;
}
export interface OptionsWithDefault<D> {
persistent?: boolean;
persistenceInterval?: number;
schemaPath?: string;
defaultValue: D;
}
export type Operation<T> = {
path: string;
} & ( // Objects and arrays
| { method: "overwrite"; args: { newValue: T | undefined } }
| { method: "delete"; args: { prop: string | number | symbol } }
| { method: "add"; args: { prop: string; newValue: any } }
| { method: "update"; args: { prop: string; newValue: any } }
// Array mutator methods
// This whole thing is gross and needs to be removed in v3
// It is rife with unsupported cases, very easy to make bugs here
| {
method: "copyWithin";
args: { mutatorArgs: Parameters<any[]["copyWithin"]> };
}
| { method: "fill"; args: { mutatorArgs: Parameters<any[]["fill"]> } }
| { method: "pop" }
| { method: "push"; args: { mutatorArgs: Parameters<any[]["push"]> } }
| { method: "reverse" }
| { method: "shift" }
| { method: "sort"; args: { mutatorArgs: Parameters<any[]["sort"]> } }
| { method: "splice"; args: { mutatorArgs: Parameters<any[]["splice"]> } }
| {
method: "unshift";
args: { mutatorArgs: Parameters<any[]["unshift"]> };
}
);
}
/**
* Express middleware that can be mounted to NodeCG's webserver via `nodecg.mount`.
*/
export type Middleware =
ExpressCore.ApplicationRequestHandler<express.Application>;
/**
* A description of an instance of a currently-open graphic.
* It is unlikely that you will need to use this type directly.
*/
export interface GraphicsInstance {
ipv4: string;
timestamp: number;
bundleName: string;
bundleVersion?: string;
bundleGit: Bundle.GitData;
pathName: string;
singleInstance: boolean;
socketId: string;
open: boolean;
potentiallyOutOfDate: boolean;
}
/**
* A description of a dashboard workspace.
* It is unlikely that you will need to use this type directly.
*/
export interface Workspace {
name: string;
label: string;
route: string;
fullbleed?: boolean;
}
/**
* A handled `listenFor` acknowledgement.
* Attempting to call/invoke a handled acknowledgement will throw an error.
*/
export interface HandledAcknowledgement {
handled: true;
}
/**
* An unhandled `listenFor` acknowledgement.
* It can safely be called/invoked.
*/
export interface UnhandledAcknowledgement {
handled: false;
(err?: any, response?: unknown): void;
}
/**
* A `listenFor` acknowledgement, sent from client to server.
*/
export type Acknowledgement =
| HandledAcknowledgement
| UnhandledAcknowledgement;
/**
* A `listenFor` handler function/callback.
*/
export type ListenHandler = (data: any, ack?: Acknowledgement) => void;
/**
* A description of NodeCG's logger interface.
*/
export interface Logger {
name: string;
trace: (...args: any[]) => void;
debug: (...args: any[]) => void;
info: (...args: any[]) => void;
warn: (...args: any[]) => void;
error: (...args: any[]) => void;
replicants: (...args: any[]) => void;
}
/**
* The logging levels available to NodeCG.
*/
export enum LogLevel {
Trace = "verbose",
Debug = "debug",
Info = "info",
Warn = "warn",
Error = "error",
Silent = "silent",
}
/**
* A description of which platform/environment an instance of the NodeCG API is being used in.
* It should not be necessary to ever use this type directly in your bundle's code.
*/
export type Platform = "server" | "client";
}