n8n-nodes-selfhosthub
Version:
Collection of n8n nodes for self-hosted AI services, including Leonardo.ai integration for AI image and content generation capabilities.
592 lines (591 loc) • 16 kB
TypeScript
/**
* Complete JSON2Video API Schema Definition
* Based on official v2 API documentation - serves as the single source of truth for all API validation
*/
/**
* Root JSON2Video API request interface
*/
export interface JSON2VideoRequest {
id?: string;
resolution?: string;
width?: number;
height?: number;
quality?: 'low' | 'medium' | 'high' | 'very_high';
cache?: boolean;
'client-data'?: Record<string, any>;
comment?: string;
variables?: Record<string, any>;
elements?: MovieElement[];
exports?: ExportConfig[];
scenes: Scene[];
}
/**
* Export configuration for video delivery methods (v2 API format)
*/
export interface ExportConfig {
destinations: ExportDestination[];
}
/**
* Export destination union type
*/
export type ExportDestination = WebhookDestination | FtpDestination | EmailDestination;
/**
* Webhook export destination
*/
export interface WebhookDestination {
type: 'webhook';
endpoint: string;
}
/**
* FTP/SFTP export destination
*/
export interface FtpDestination {
type: 'ftp';
host: string;
port?: number;
username: string;
password: string;
'remote-path'?: string;
file?: string;
secure?: boolean;
}
/**
* Email export destination
*/
export interface EmailDestination {
type: 'email';
to: string | string[];
from?: string;
subject?: string;
message?: string;
}
/**
* Scene object containing elements and settings
*/
export interface Scene {
id?: string;
duration?: number;
'background-color'?: string;
comment?: string;
condition?: string;
cache?: boolean;
variables?: Record<string, any>;
elements: SceneElement[];
}
/**
* Base element interface with common properties
*/
export interface BaseElement {
type: string;
id?: string;
comment?: string;
condition?: string;
variables?: Record<string, any>;
cache?: boolean;
start?: number;
duration?: number;
'extra-time'?: number;
'z-index'?: number;
'fade-in'?: number;
'fade-out'?: number;
}
/**
* Visual element interface with positioning and effects
*/
export interface VisualElement extends BaseElement {
position?: string;
x?: number;
y?: number;
width?: number;
height?: number;
resize?: 'cover' | 'fill' | 'fit' | 'contain';
crop?: CropObject;
rotate?: RotateObject;
pan?: string;
'pan-distance'?: number;
'pan-crop'?: boolean;
zoom?: number;
'flip-horizontal'?: boolean;
'flip-vertical'?: boolean;
mask?: string;
'chroma-key'?: ChromaKeyObject;
correction?: CorrectionObject;
}
/**
* Audio element interface with playback controls
*/
export interface AudioElement extends BaseElement {
src?: string;
seek?: number;
volume?: number;
muted?: boolean;
loop?: number;
}
/**
* Movie-level text element (global across entire video)
*/
export interface MovieTextElement extends BaseElement {
type: 'text';
text: string;
style?: '001' | '002' | '003' | '004' | '005' | '006' | '007' | '008' | '009' | '010';
position?: string;
x?: number;
y?: number;
width?: number;
height?: number;
resize?: string;
settings?: TextSettings;
}
/**
* Subtitle element (only allowed at movie level)
*/
export interface SubtitleElement extends BaseElement {
type: 'subtitles';
captions?: string;
src?: string;
text?: string;
language?: string;
model?: 'default' | 'whisper';
settings?: SubtitleSettings;
}
/**
* Movie-level audio element
*/
export interface MovieAudioElement extends AudioElement {
type: 'audio';
}
/**
* Voice/TTS element for speech synthesis
*/
export interface VoiceElement extends BaseElement {
type: 'voice';
text: string;
voice?: string;
model?: 'azure' | 'elevenlabs' | 'elevenlabs-flash-v2-5';
connection?: string;
volume?: number;
muted?: boolean;
}
/**
* Union type for all movie-level elements
*/
export type MovieElement = MovieTextElement | SubtitleElement | MovieAudioElement | VoiceElement;
/**
* Video element for scene-level video content
*/
export interface VideoElement extends VisualElement {
type: 'video';
src?: string;
seek?: number;
volume?: number;
muted?: boolean;
loop?: number;
}
/**
* Image element with support for AI generation
*/
export interface ImageElement extends VisualElement {
type: 'image';
src?: string;
prompt?: string;
model?: 'flux-pro' | 'flux-schnell' | 'freepik-classic';
'aspect-ratio'?: 'horizontal' | 'vertical' | 'squared';
connection?: string;
'model-settings'?: Record<string, any>;
}
/**
* Scene-level text element
*/
export interface SceneTextElement extends BaseElement {
type: 'text';
text: string;
style?: '001' | '002' | '003' | '004' | '005' | '006' | '007' | '008' | '009' | '010';
position?: string;
x?: number;
y?: number;
width?: number;
height?: number;
resize?: string;
settings?: TextSettings;
}
/**
* Scene-level audio element
*/
export interface SceneAudioElement extends AudioElement {
type: 'audio';
}
/**
* Scene-level voice element
*/
export interface SceneVoiceElement extends BaseElement {
type: 'voice';
text: string;
voice?: string;
model?: 'azure' | 'elevenlabs' | 'elevenlabs-flash-v2-5';
connection?: string;
volume?: number;
muted?: boolean;
}
/**
* Component element for reusable video components
*/
export interface ComponentElement extends VisualElement {
type: 'component';
component: string;
settings?: Record<string, any>;
}
/**
* Audiogram element for audio waveform visualization
*/
export interface AudiogramElement extends VisualElement {
type: 'audiogram';
color?: string;
opacity?: number;
amplitude?: number;
}
/**
* HTML element for custom HTML rendering
*/
export interface HtmlElement extends VisualElement {
type: 'html';
html?: string;
src?: string;
tailwindcss?: boolean;
wait?: number;
}
/**
* Union type for all scene-level elements
*/
export type SceneElement = VideoElement | ImageElement | SceneTextElement | SceneAudioElement | SceneVoiceElement | ComponentElement | AudiogramElement | HtmlElement;
/**
* Crop object for element cropping
*/
export interface CropObject {
width: number;
height: number;
x?: number;
y?: number;
}
/**
* Rotation object for element rotation effects
*/
export interface RotateObject {
angle: number;
speed?: number;
}
/**
* Chroma key object for green screen effects
*/
export interface ChromaKeyObject {
color: string;
tolerance?: number;
}
/**
* Color correction object for visual adjustments
*/
export interface CorrectionObject {
brightness?: number;
contrast?: number;
gamma?: number;
saturation?: number;
}
/**
* Text styling settings using kebab-case properties
*/
export interface TextSettings {
'font-family'?: string;
'font-size'?: number | string;
'font-weight'?: number | string;
'font-color'?: string;
'background-color'?: string;
'text-align'?: 'left' | 'center' | 'right' | 'justify';
'vertical-position'?: 'top' | 'center' | 'bottom';
'horizontal-position'?: 'left' | 'center' | 'right';
'line-height'?: number;
'letter-spacing'?: number;
'text-shadow'?: string;
'text-decoration'?: string;
'text-transform'?: string;
}
/**
* Subtitle styling settings using kebab-case properties
*/
export interface SubtitleSettings {
style?: string;
'all-caps'?: boolean;
'font-family'?: string;
'font-size'?: number | string;
'font-url'?: string;
position?: string;
'word-color'?: string;
'line-color'?: string;
'box-color'?: string;
'outline-color'?: string;
'outline-width'?: number;
'shadow-color'?: string;
'shadow-offset'?: number;
'max-words-per-line'?: number;
x?: number;
y?: number;
keywords?: string[];
replace?: Record<string, string>;
model?: string;
language?: string;
}
/**
* API rules and validation constants
*/
export declare const API_RULES: {
readonly MOVIE_ELEMENT_TYPES: readonly ["text", "subtitles", "audio", "voice"];
readonly SCENE_ELEMENT_TYPES: readonly ["video", "audio", "image", "text", "voice", "component", "audiogram", "html"];
readonly REQUIRED_FIELDS: {
readonly movie: readonly ["scenes"];
readonly scene: readonly [];
readonly video: readonly ["type"];
readonly audio: readonly [];
readonly image: readonly [];
readonly text: readonly ["text", "type"];
readonly voice: readonly ["text", "type"];
readonly subtitles: readonly ["type"];
readonly component: readonly ["component", "type"];
readonly audiogram: readonly [];
readonly html: readonly [];
};
readonly EXPORT_RULES: {
readonly REQUIRED_FIELDS: {
readonly webhook: readonly ["endpoint"];
readonly ftp: readonly ["host", "username", "password"];
readonly email: readonly ["to"];
};
readonly VALID_DESTINATION_TYPES: readonly ["webhook", "ftp", "email"];
readonly SUPPORTS_MULTIPLE_DESTINATIONS: true;
readonly SINGLE_EXPORT_CONFIG: true;
};
readonly SUBTITLE_RULES: {
readonly ONLY_AT_MOVIE_LEVEL: true;
readonly NOT_ALLOWED_IN_SCENES: true;
};
readonly VALIDATION_RANGES: {
readonly width: {
readonly min: 50;
readonly max: 3840;
};
readonly height: {
readonly min: 50;
readonly max: 3840;
};
readonly volume: {
readonly min: 0;
readonly max: 10;
};
readonly opacity: {
readonly min: 0;
readonly max: 1;
};
readonly 'z-index': {
readonly min: -99;
readonly max: 99;
};
readonly zoom: {
readonly min: -10;
readonly max: 10;
};
readonly 'pan-distance': {
readonly min: 0.01;
readonly max: 0.5;
};
readonly tolerance: {
readonly min: 1;
readonly max: 100;
};
readonly brightness: {
readonly min: -1;
readonly max: 1;
};
readonly contrast: {
readonly min: -1000;
readonly max: 1000;
};
readonly gamma: {
readonly min: 0.1;
readonly max: 10;
};
readonly saturation: {
readonly min: 0;
readonly max: 3;
};
readonly wait: {
readonly min: 0;
readonly max: 5;
};
readonly ftpPort: {
readonly min: 1;
readonly max: 65535;
};
};
readonly VALID_POSITIONS: readonly ["top-left", "top-center", "top-right", "center-left", "center-center", "center-right", "bottom-left", "bottom-center", "bottom-right", "custom"];
readonly VALID_QUALITIES: readonly ["low", "medium", "high", "very_high"];
readonly VALID_RESOLUTIONS: readonly ["sd", "hd", "full-hd", "squared", "instagram-story", "instagram-feed", "twitter-landscape", "twitter-portrait", "custom"];
readonly VALID_RESIZE_MODES: readonly ["cover", "fill", "fit", "contain"];
readonly VALID_TEXT_STYLES: readonly ["001", "002", "003", "004", "005", "006", "007", "008", "009", "010"];
readonly VALID_AI_MODELS: readonly ["flux-pro", "flux-schnell", "freepik-classic"];
readonly VALID_ASPECT_RATIOS: readonly ["horizontal", "vertical", "squared"];
readonly VALID_TTS_MODELS: readonly ["azure", "elevenlabs", "elevenlabs-flash-v2-5"];
readonly VALID_PAN_DIRECTIONS: readonly ["left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right"];
readonly SPECIAL_DURATION_VALUES: readonly [-1, -2];
};
/**
* Text element parameters for processing - simplified for JSON settings approach
*/
export interface TextElementParams {
text: string;
textStyle?: string;
textSettings?: string | object;
position?: string;
x?: number;
y?: number;
width?: number;
height?: number;
start?: number;
duration?: number;
[key: string]: any;
}
/**
* Subtitle element parameters for processing
*/
export interface SubtitleElementParams {
captions?: string;
src?: string;
text?: string;
style?: string;
model?: string;
language?: string;
allCaps?: boolean;
position?: string;
fontSize?: number | string;
fontFamily?: string;
fontUrl?: string;
wordColor?: string;
lineColor?: string;
boxColor?: string;
outlineColor?: string;
outlineWidth?: number;
shadowColor?: string;
shadowOffset?: number;
maxWordsPerLine?: number;
x?: number;
y?: number;
keywords?: string[];
replace?: Record<string, string>;
}
/**
* Basic element parameters for processing
*/
export interface BasicElementParams {
type: string;
src?: string;
text?: string;
start?: number;
duration?: number;
volume?: number;
muted?: boolean;
loop?: boolean | number;
crop?: boolean | CropObject;
position?: string;
x?: number;
y?: number;
width?: number;
height?: number;
[key: string]: any;
}
/**
* HTML element parameters for processing
*/
export interface HtmlElementParams {
html?: string;
src?: string;
tailwindcss?: boolean;
wait?: number;
position?: string;
x?: number;
y?: number;
width?: number;
height?: number;
start?: number;
duration?: number;
resize?: string;
crop?: boolean | CropObject;
rotate?: RotateObject;
pan?: string;
panDistance?: number;
panCrop?: boolean;
zoom?: number;
flipHorizontal?: boolean;
flipVertical?: boolean;
mask?: string;
chromaKey?: ChromaKeyObject;
correction?: CorrectionObject;
[key: string]: any;
}
/**
* Type guard for movie-level elements
*/
export declare function isMovieElement(element: any): element is MovieElement;
/**
* Type guard for scene-level elements
*/
export declare function isSceneElement(element: any): element is SceneElement;
/**
* Type guard for subtitle elements
*/
export declare function isSubtitleElement(element: any): element is SubtitleElement;
/**
* Type guard for text elements
*/
export declare function isTextElement(element: any): element is MovieTextElement | SceneTextElement;
/**
* Type guard for HTML elements
*/
export declare function isHtmlElement(element: any): element is HtmlElement;
/**
* Type guard for export destinations
*/
export declare function isWebhookDestination(destination: any): destination is WebhookDestination;
export declare function isFtpDestination(destination: any): destination is FtpDestination;
export declare function isEmailDestination(destination: any): destination is EmailDestination;
/**
* Check if element has all required fields for its type
*/
export declare function hasRequiredFields(element: any): boolean;
/**
* Check if export destination has all required fields for its type
*/
export declare function hasRequiredExportFields(destination: any): boolean;
/**
* Validate duration value according to API rules
*/
export declare function isValidDuration(duration: any): boolean;
/**
* Validate position value according to API rules
*/
export declare function isValidPosition(position: string): boolean;
/**
* Validate wait time for HTML elements
*/
export declare function isValidWait(wait: any): boolean;
/**
* Validate FTP port number
*/
export declare function isValidFtpPort(port: any): boolean;
/**
* Union type for all element types
*/
export type AllElements = MovieElement | SceneElement;
/**
* Alias for the main request interface
*/
export type { JSON2VideoRequest as MovieRequest };
/**
* Alias for the scene interface
*/
export type { Scene as SceneRequest };