Appearance
TypeScript Support
Use TypeScript definitions for better IDE support when developing plugins.
Setup
Copy the type definitions to your plugin folder:
my-plugin/
├── plugin.js
├── gemshell.d.ts # Type definitions
└── ...Type Definitions
Create gemshell.d.ts:
typescript
/**
* Settings injected at runtime
*/
declare const GEMSHELL_SETTINGS: Record<string, any>;
/**
* Plugin setting definition
*/
interface PluginSetting {
id: string;
type: 'checkbox' | 'text' | 'textarea' | 'number' | 'slider' | 'range' | 'select' | 'color';
label: string;
default?: any;
description?: string;
placeholder?: string;
min?: number;
max?: number;
step?: number;
rows?: number;
options?: string[];
}
/**
* Build context passed to hooks
*/
interface BuildContext {
gamePath: string;
outputPath: string;
config: {
title: string;
appName: string;
version: string;
width: number;
height: number;
};
platform: 'darwin' | 'win32' | 'linux';
arch: 'arm64' | 'x64' | 'ia32';
error?: string;
percent?: number;
message?: string;
}
/**
* Plugin manifest
*/
interface Plugin {
name: string;
version: string;
author?: string;
description?: string;
gemshell?: string;
inject?: string[];
settings?: PluginSetting[];
onPreBuild?(context: BuildContext, settings: Record<string, any>): Promise<void>;
onModifyAssets?(context: BuildContext, settings: Record<string, any>): Promise<void>;
onBeforePackage?(context: BuildContext, settings: Record<string, any>): Promise<void>;
onPostBuild?(context: BuildContext, settings: Record<string, any>): Promise<void>;
onBuildError?(context: BuildContext, settings: Record<string, any>): Promise<void>;
onBuildProgress?(context: BuildContext, settings: Record<string, any>): void;
}
/**
* GemShell Plugin API (available in hooks)
*/
declare const gemshell: {
log(message: string, ...args: any[]): void;
warn(message: string, ...args: any[]): void;
error(message: string, ...args: any[]): void;
storage: {
get<T>(key: string, defaultValue?: T): T;
set(key: string, value: any): void;
delete(key: string): void;
clear(): void;
has(key: string): boolean;
keys(): string[];
};
fs: {
read(path: string): string;
readJson<T>(path: string): T;
readBinary(path: string): Buffer;
write(path: string, content: string): void;
writeJson(path: string, data: any): void;
writeBinary(path: string, buffer: Buffer): void;
exists(path: string): boolean;
stat(path: string): { size: number; mtime: number; isDirectory: boolean };
mkdir(path: string): void;
copy(src: string, dest: string): void;
remove(path: string): void;
list(path: string): string[];
};
http: {
get(url: string, options?: RequestOptions): Promise<HttpResponse>;
post(url: string, body?: any, options?: RequestOptions): Promise<HttpResponse>;
put(url: string, body?: any, options?: RequestOptions): Promise<HttpResponse>;
delete(url: string, options?: RequestOptions): Promise<HttpResponse>;
request(options: FullRequestOptions): Promise<HttpResponse>;
};
glob(pattern: string): string[];
transform: {
replaceInFile(path: string, search: string, replace: string): void;
appendToFile(path: string, content: string): void;
prependToFile(path: string, content: string): void;
injectIntoHtml(content: string, position: 'head' | 'body-start' | 'body-end'): void;
};
build: {
getInfo(): BuildInfo;
getGameConfig(): GameConfig;
incrementBuildNumber(): number;
getPaths(): BuildPaths;
};
native: {
isAvailable(): boolean;
getVersion(): string;
encrypt(key: string, text: string): string | null;
decrypt(key: string, ciphertext: string): string | null;
encryptBytes(key: string, buffer: Buffer): Buffer | null;
decryptBytes(key: string, buffer: Buffer): Buffer | null;
};
};
interface RequestOptions {
headers?: Record<string, string>;
timeout?: number;
auth?: { username: string; password: string };
}
interface FullRequestOptions extends RequestOptions {
method: string;
url: string;
body?: any;
}
interface HttpResponse {
status: number;
statusText: string;
headers: Record<string, string>;
data: any;
}
interface BuildInfo {
platform: string;
arch: string;
gemshellVersion: string;
buildNumber: number;
timestamp: string;
isProduction: boolean;
isDevelopment: boolean;
}
interface GameConfig {
title: string;
appName: string;
version: string;
width: number;
height: number;
}
interface BuildPaths {
source: string;
output: string;
temp: string;
assets: string;
}Usage in plugin.js
With the type definitions, your IDE will provide:
- Autocomplete for
gemshell.*APIs - Type checking for settings
- Documentation on hover
javascript
// @ts-check
/// <reference path="./gemshell.d.ts" />
/** @type {Plugin} */
module.exports = {
name: 'My Plugin',
version: '1.0.0',
settings: [
{ id: 'enabled', type: 'checkbox', label: 'Enable', default: true }
],
async onPreBuild(context, settings) {
// IDE now knows context.config.title is a string
gemshell.log(`Building ${context.config.title}`);
// IDE autocompletes gemshell.storage.get()
const count = gemshell.storage.get('buildCount', 0);
}
};Usage in script.js
javascript
// @ts-check
/// <reference path="./gemshell.d.ts" />
// IDE knows GEMSHELL_SETTINGS exists
const { enabled, position } = GEMSHELL_SETTINGS;JSDoc Alternative
If you prefer not to use a separate .d.ts file:
javascript
/**
* @typedef {Object} Settings
* @property {boolean} enabled
* @property {string} position
*/
/** @type {Settings} */
const settings = GEMSHELL_SETTINGS;