project rename

This commit is contained in:
Eugene Pankov
2021-06-29 23:57:04 +02:00
parent c61be3d52b
commit 43cd3318da
609 changed files with 510 additions and 530 deletions

12
tabby-core/src/api/cli.ts Normal file
View File

@@ -0,0 +1,12 @@
export interface CLIEvent {
argv: any
cwd: string
secondInstance: boolean
}
export abstract class CLIHandler {
priority: number
firstMatchOnly: boolean
abstract handle (event: CLIEvent): Promise<boolean>
}

View File

@@ -0,0 +1,37 @@
/**
* Extend to add your own config options
*/
export abstract class ConfigProvider {
/**
* Default values, e.g.
*
* ```ts
* defaults = {
* myPlugin: {
* foo: 1
* }
* }
* ```
*/
defaults: any = {}
/**
* [[Platform]] specific defaults, e.g.
*
* ```ts
* platformDefaults = {
* [Platform.Windows]: {
* myPlugin: {
* bar: true
* }
* },
* [Platform.macOS]: {
* myPlugin: {
* bar: false
* }
* },
* }
* ```
*/
platformDefaults: Record<string, any> = {}
}

View File

@@ -0,0 +1,13 @@
import { Injectable } from '@angular/core'
@Injectable({ providedIn: 'root' })
export abstract class FileProvider {
name: string
async isAvailable (): Promise<boolean> {
return true
}
abstract selectAndStoreFile (description: string): Promise<string>
abstract retrieveFile (key: string): Promise<Buffer>
}

View File

@@ -0,0 +1,53 @@
import { Observable, Subject } from 'rxjs'
import { Injector } from '@angular/core'
import { Logger, LogService } from '../services/log.service'
export enum Platform {
Linux = 'Linux',
macOS = 'macOS',
Windows = 'Windows',
Web = 'Web',
}
/**
* Provides interaction with the main process
*/
export abstract class HostAppService {
abstract get platform (): Platform
abstract get configPlatform (): Platform
protected settingsUIRequest = new Subject<void>()
protected configChangeBroadcast = new Subject<void>()
protected logger: Logger
/**
* Fired when Preferences is selected in the macOS menu
*/
get settingsUIRequest$ (): Observable<void> { return this.settingsUIRequest }
/**
* Fired when another window modified the config file
*/
get configChangeBroadcast$ (): Observable<void> { return this.configChangeBroadcast }
constructor (
injector: Injector,
) {
this.logger = injector.get(LogService).create('hostApp')
}
abstract newWindow (): void
/**
* Notifies other windows of config file changes
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
broadcastConfigChange (_configStore: Record<string, any>): void { }
// eslint-disable-next-line @typescript-eslint/no-empty-function
emitReady (): void { }
abstract relaunch (): void
abstract quit (): void
}

View File

@@ -0,0 +1,36 @@
import { Observable, Subject } from 'rxjs'
export abstract class HostWindowService {
/**
* Fired once the window is visible
*/
get windowShown$ (): Observable<void> { return this.windowShown }
/**
* Fired when the window close button is pressed
*/
get windowCloseRequest$ (): Observable<void> { return this.windowCloseRequest }
get windowMoved$ (): Observable<void> { return this.windowMoved }
get windowFocused$ (): Observable<void> { return this.windowFocused }
protected windowShown = new Subject<void>()
protected windowCloseRequest = new Subject<void>()
protected windowMoved = new Subject<void>()
protected windowFocused = new Subject<void>()
abstract readonly isFullscreen: boolean
abstract reload (): void
abstract setTitle (title?: string): void
abstract toggleFullscreen (): void
abstract minimize (): void
abstract isMaximized (): boolean
abstract toggleMaximize (): void
abstract close (): void
// eslint-disable-next-line @typescript-eslint/no-empty-function
openDevTools (): void { }
// eslint-disable-next-line @typescript-eslint/no-empty-function
bringToFront (): void { }
}

View File

@@ -0,0 +1,12 @@
export interface HotkeyDescription {
id: string
name: string
}
/**
* Extend to provide your own hotkeys. A corresponding [[ConfigProvider]]
* must also provide the `hotkeys.foo` config options with the default values
*/
export abstract class HotkeyProvider {
abstract provide (): Promise<HotkeyDescription[]>
}

View File

@@ -0,0 +1,33 @@
export { BaseComponent, SubscriptionContainer } from '../components/base.component'
export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component'
export { TabHeaderComponent } from '../components/tabHeader.component'
export { SplitTabComponent, SplitContainer } from '../components/splitTab.component'
export { TabRecoveryProvider, RecoveredTab, RecoveryToken } from './tabRecovery'
export { ToolbarButtonProvider, ToolbarButton } from './toolbarButtonProvider'
export { ConfigProvider } from './configProvider'
export { HotkeyProvider, HotkeyDescription } from './hotkeyProvider'
export { Theme } from './theme'
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
export { SelectorOption } from './selector'
export { CLIHandler, CLIEvent } from './cli'
export { PlatformService, ClipboardContent, MessageBoxResult, MessageBoxOptions, FileDownload, FileUpload, FileTransfer, HTMLFileUpload, FileUploadOptions } from './platform'
export { MenuItemOptions } from './menu'
export { BootstrapData, PluginInfo, BOOTSTRAP_DATA } from './mainProcess'
export { HostWindowService } from './hostWindow'
export { HostAppService, Platform } from './hostApp'
export { FileProvider } from './fileProvider'
export { AppService } from '../services/app.service'
export { ConfigService } from '../services/config.service'
export { DockingService, Screen } from '../services/docking.service'
export { Logger, ConsoleLogger, LogService } from '../services/log.service'
export { HomeBaseService } from '../services/homeBase.service'
export { HotkeysService } from '../services/hotkeys.service'
export { NotificationsService } from '../services/notifications.service'
export { ThemesService } from '../services/themes.service'
export { SelectorService } from '../services/selector.service'
export { TabsService } from '../services/tabs.service'
export { UpdaterService } from '../services/updater.service'
export { VaultService, Vault, VaultSecret, VAULT_SECRET_TYPE_FILE } from '../services/vault.service'
export { FileProvidersService } from '../services/fileProviders.service'
export * from '../utils'

View File

@@ -0,0 +1,22 @@
export const BOOTSTRAP_DATA = 'BOOTSTRAP_DATA'
export interface PluginInfo {
name: string
description: string
packageName: string
isBuiltin: boolean
version: string
author: string
homepage?: string
path?: string
info?: any
}
export interface BootstrapData {
config: Record<string, any>
executable: string
isFirstWindow: boolean
windowID: number
installedPlugins: PluginInfo[]
userPluginsPath: string
}

View File

@@ -0,0 +1,9 @@
export interface MenuItemOptions {
type?: ('normal' | 'separator' | 'submenu' | 'checkbox' | 'radio')
label?: string
sublabel?: string
enabled?: boolean
checked?: boolean
submenu?: MenuItemOptions[]
click?: () => void
}

View File

@@ -0,0 +1,210 @@
import { MenuItemOptions } from './menu'
import { Subject, Observable } from 'rxjs'
/* eslint-disable @typescript-eslint/no-unused-vars */
export interface ClipboardContent {
text: string
html?: string
}
export interface MessageBoxOptions {
type: 'warning'|'error'
message: string
detail?: string
buttons: string[]
defaultId?: number
}
export interface MessageBoxResult {
response: number
}
export abstract class FileTransfer {
abstract getName (): string
abstract getSize (): number
abstract close (): void
getSpeed (): number {
return this.lastChunkSpeed
}
getCompletedBytes (): number {
return this.completedBytes
}
isComplete (): boolean {
return this.completedBytes >= this.getSize()
}
isCancelled (): boolean {
return this.cancelled
}
cancel (): void {
this.cancelled = true
this.close()
}
protected increaseProgress (bytes: number): void {
this.completedBytes += bytes
this.lastChunkSpeed = bytes * 1000 / (Date.now() - this.lastChunkStartTime)
this.lastChunkStartTime = Date.now()
}
private completedBytes = 0
private lastChunkStartTime = Date.now()
private lastChunkSpeed = 0
private cancelled = false
}
export abstract class FileDownload extends FileTransfer {
abstract write (buffer: Buffer): Promise<void>
}
export abstract class FileUpload extends FileTransfer {
abstract read (): Promise<Buffer>
async readAll (): Promise<Buffer> {
const buffers: Buffer[] = []
while (true) {
const buf = await this.read()
if (!buf.length) {
break
}
buffers.push(Buffer.from(buf))
}
return Buffer.concat(buffers)
}
}
export interface FileUploadOptions {
multiple: boolean
}
export abstract class PlatformService {
supportsWindowControls = false
get fileTransferStarted$ (): Observable<FileTransfer> { return this.fileTransferStarted }
get displayMetricsChanged$ (): Observable<void> { return this.displayMetricsChanged }
protected fileTransferStarted = new Subject<FileTransfer>()
protected displayMetricsChanged = new Subject<void>()
abstract readClipboard (): string
abstract setClipboard (content: ClipboardContent): void
abstract loadConfig (): Promise<string>
abstract saveConfig (content: string): Promise<void>
abstract startDownload (name: string, size: number): Promise<FileDownload|null>
abstract startUpload (options?: FileUploadOptions): Promise<FileUpload[]>
startUploadFromDragEvent (event: DragEvent, multiple = false): FileUpload[] {
const result: FileUpload[] = []
if (!event.dataTransfer) {
return []
}
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < event.dataTransfer.files.length; i++) {
const file = event.dataTransfer.files[i]
const transfer = new HTMLFileUpload(file)
this.fileTransferStarted.next(transfer)
result.push(transfer)
if (!multiple) {
break
}
}
return result
}
getConfigPath (): string|null {
return null
}
showItemInFolder (path: string): void {
throw new Error('Not implemented')
}
async isProcessRunning (name: string): Promise<boolean> {
return false
}
async installPlugin (name: string, version: string): Promise<void> {
throw new Error('Not implemented')
}
async uninstallPlugin (name: string): Promise<void> {
throw new Error('Not implemented')
}
getWinSCPPath (): string|null {
throw new Error('Not implemented')
}
exec (app: string, argv: string[]): void {
throw new Error('Not implemented')
}
isShellIntegrationSupported (): boolean {
return false
}
async isShellIntegrationInstalled (): Promise<boolean> {
return false
}
async installShellIntegration (): Promise<void> {
throw new Error('Not implemented')
}
async uninstallShellIntegration (): Promise<void> {
throw new Error('Not implemented')
}
openPath (path: string): void {
throw new Error('Not implemented')
}
abstract getOSRelease (): string
abstract getAppVersion (): string
abstract openExternal (url: string): void
abstract listFonts (): Promise<string[]>
abstract setErrorHandler (handler: (_: any) => void): void
abstract popupContextMenu (menu: MenuItemOptions[], event?: MouseEvent): void
abstract showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult>
abstract quit (): void
}
export class HTMLFileUpload extends FileUpload {
private stream: ReadableStream
private reader: ReadableStreamDefaultReader
constructor (private file: File) {
super()
this.stream = this.file.stream()
this.reader = this.stream.getReader()
}
getName (): string {
return this.file.name
}
getSize (): number {
return this.file.size
}
async read (): Promise<Buffer> {
const result: any = await this.reader.read()
if (result.done || !result.value) {
return Buffer.from('')
}
const chunk = Buffer.from(result.value)
this.increaseProgress(chunk.length)
return chunk
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
bringToFront (): void { }
// eslint-disable-next-line @typescript-eslint/no-empty-function
close (): void { }
}

View File

@@ -0,0 +1,8 @@
export interface SelectorOption<T> {
name: string
description?: string
result?: T
icon?: string
freeInputPattern?: string
callback?: (string?) => void
}

View File

@@ -0,0 +1,12 @@
import { BaseTabComponent } from '../components/baseTab.component'
import { TabHeaderComponent } from '../components/tabHeader.component'
import { MenuItemOptions } from './menu'
/**
* Extend to add items to the tab header's context menu
*/
export abstract class TabContextMenuItemProvider {
weight = 0
abstract getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]>
}

View File

@@ -0,0 +1,61 @@
import deepClone from 'clone-deep'
import { TabComponentType } from '../services/tabs.service'
export interface RecoveredTab {
/**
* Component type to be instantiated
*/
type: TabComponentType
/**
* Component instance inputs
*/
options?: any
}
export interface RecoveryToken {
[_: string]: any
type: string
tabColor?: string|null
}
/**
* Extend to enable recovery for your custom tab.
* This works in conjunction with [[getRecoveryToken()]]
*
* Tabby will try to find any [[TabRecoveryProvider]] that is able to process
* the recovery token previously returned by [[getRecoveryToken]].
*
* Recommended token format:
*
* ```json
* {
* type: 'my-tab-type',
* foo: 'bar',
* }
* ```
*/
export abstract class TabRecoveryProvider {
/**
* @param recoveryToken a recovery token found in the saved tabs list
* @returns [[boolean]] whether this [[TabRecoveryProvider]] can recover a tab from this token
*/
abstract applicableTo (recoveryToken: RecoveryToken): Promise<boolean>
/**
* @param recoveryToken a recovery token found in the saved tabs list
* @returns [[RecoveredTab]] descriptor containing tab type and component inputs
* or `null` if this token is from a different tab type or is not supported
*/
abstract recover (recoveryToken: RecoveryToken): Promise<RecoveredTab>
/**
* @param recoveryToken a recovery token found in the saved tabs list
* @returns [[RecoveryToken]] a new recovery token to create the duplicate tab from
*
* The default implementation just returns a deep copy of the original token
*/
duplicate (recoveryToken: RecoveryToken): RecoveryToken {
return deepClone(recoveryToken)
}
}

View File

@@ -0,0 +1,16 @@
/**
* Extend to add a custom CSS theme
*/
export abstract class Theme {
name: string
/**
* Complete CSS stylesheet
*/
css: string
terminalBackground: string
macOSWindowButtonsInsetX?: number
macOSWindowButtonsInsetY?: number
}

View File

@@ -0,0 +1,37 @@
/**
* See [[ToolbarButtonProvider]]
*/
export interface ToolbarButton {
/**
* Raw SVG icon code
*/
icon?: string
title: string
/**
* Optional Touch Bar icon ID
*/
touchBarNSImage?: string
/**
* Optional Touch Bar button label
*/
touchBarTitle?: string
weight?: number
click?: () => void
submenu?: () => Promise<ToolbarButton[]>
/** @hidden */
submenuItems?: ToolbarButton[]
}
/**
* Extend to add buttons to the toolbar
*/
export abstract class ToolbarButtonProvider {
abstract provide (): ToolbarButton[]
}