mirror of
https://github.com/Eugeny/tabby-web.git
synced 2025-06-13 07:59:54 +00:00
wip
This commit is contained in:
parent
dc69574c07
commit
e1425c6c80
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
index.d.ts
|
|
||||||
*.ignore.js
|
*.ignore.js
|
||||||
*.ignore.js.map
|
*.ignore.js.map
|
||||||
dist
|
dist
|
||||||
@ -9,3 +8,5 @@ app-dist
|
|||||||
db.sqlite3
|
db.sqlite3
|
||||||
__pycache__
|
__pycache__
|
||||||
.vscode
|
.vscode
|
||||||
|
build
|
||||||
|
*.d.ts
|
||||||
|
@ -1 +0,0 @@
|
|||||||
<!DOCTYPE html><html><head><base href="dist/"><meta name="viewport" content="initial-scale=1, minimal-ui, shrink-to-fit=no"><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400" rel="stylesheet"><script src="index.js" defer></script><title>Terminus</title></head><body><div class="terminal"><iframe src="terminal.html"></iframe></div></body></html>
|
|
35
package.json
35
package.json
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-web",
|
"name": "terminus-web-container",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -8,24 +8,40 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@angular/animations": "^11.0.0",
|
||||||
|
"@angular/common": "^11.0.0",
|
||||||
|
"@angular/compiler": "^11.0.0",
|
||||||
|
"@angular/compiler-cli": "^11.0.0",
|
||||||
|
"@angular/core": "^11.0.0",
|
||||||
|
"@angular/forms": "^11.0.0",
|
||||||
|
"@angular/platform-browser": "^11.0.0",
|
||||||
|
"@angular/platform-browser-dynamic": "^11.0.0",
|
||||||
"@fortawesome/fontawesome-free": "^5.7.2",
|
"@fortawesome/fontawesome-free": "^5.7.2",
|
||||||
|
"@ng-bootstrap/ng-bootstrap": "11.0.0-beta.1",
|
||||||
|
"@ngtools/webpack": "^12.0.4",
|
||||||
|
"@terminus-term/to-string-loader": "^1.1.7-beta.1",
|
||||||
"@types/node": "^11.9.5",
|
"@types/node": "^11.9.5",
|
||||||
|
"apply-loader": "^2.0.0",
|
||||||
"assert": "1.5.0",
|
"assert": "1.5.0",
|
||||||
"awesome-typescript-loader": "^5.2.1",
|
"awesome-typescript-loader": "^5.2.1",
|
||||||
"bootstrap": "^4.3.1",
|
"bootstrap": "^5.0.1",
|
||||||
"browserify-zlib": "^0.2.0",
|
"browserify-zlib": "^0.2.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"constants-browserify": "^1.0.0",
|
"constants-browserify": "^1.0.0",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.14.0",
|
||||||
"crypto-browserify": "^3.12.0",
|
"crypto-browserify": "^3.12.0",
|
||||||
"css-loader": "^2.1.0",
|
"css-loader": "^2.1.0",
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
"file-loader": "^1.1.11",
|
"file-loader": "^1.1.11",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
"ngx-toastr": "^14.0.0",
|
||||||
"node-sass": "^6.0.0",
|
"node-sass": "^6.0.0",
|
||||||
"pug": "^2.0.3",
|
"pug": "^3.0.2",
|
||||||
"pug-cli": "^1.0.0-alpha6",
|
"pug-cli": "^1.0.0-alpha6",
|
||||||
"pug-html-loader": "^1.1.5",
|
"pug-html-loader": "^1.1.5",
|
||||||
"raw-loader": "^1.0.0",
|
"pug-loader": "^2.4.0",
|
||||||
|
"raw-loader": "^4.0.2",
|
||||||
|
"rxjs": "^7.1.0",
|
||||||
"sass-loader": "^11.1.1",
|
"sass-loader": "^11.1.1",
|
||||||
"script-loader": "^0.7.2",
|
"script-loader": "^0.7.2",
|
||||||
"setimmediate": "^1.0.5",
|
"setimmediate": "^1.0.5",
|
||||||
@ -35,10 +51,11 @@
|
|||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"string_decoder": "^1.3.0",
|
"string_decoder": "^1.3.0",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^0.23.1",
|
||||||
"typescript": "3.3.3333",
|
"typescript": "~4.1",
|
||||||
"val-loader": "^1.1.1",
|
"val-loader": "^4.0.0",
|
||||||
"webpack": "^5.37.0",
|
"webpack": "^5.38.1",
|
||||||
"webpack-cli": "^4.7.0"
|
"webpack-cli": "^4.7.2",
|
||||||
|
"zone.js": "^0.11.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"**/util": "^0.12.0"
|
"**/util": "^0.12.0"
|
||||||
|
4
polyfills.d.ts
vendored
4
polyfills.d.ts
vendored
@ -1,4 +0,0 @@
|
|||||||
export declare function utf8Write(string: any, offset: any, length: any): any;
|
|
||||||
export declare function base64Slice(start: any, end: any): any;
|
|
||||||
export declare function latin1Slice(start: any, end: any): string;
|
|
||||||
export declare function utf8Slice(this: any, start: any, end: any): any;
|
|
21
src/app.module.ts
Normal file
21
src/app.module.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'
|
||||||
|
import { AppComponent } from './components/app.component'
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
HttpClientXsrfModule,
|
||||||
|
NgbDropdownModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
1
src/assets/logo.svg
Normal file
1
src/assets/logo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 0 1024 1024" xml:space="preserve" style="enable-background:new 0 0 1024 1024"><style type="text/css">.st0{fill:url(#SVGID_1_)}.st1{opacity:.16;fill:url(#SVGID_2_)}.st2{fill:url(#SVGID_3_)}.st3{opacity:.16;fill:url(#SVGID_4_)}.st4{fill:url(#SVGID_5_)}.st5{opacity:.15;fill:url(#SVGID_6_)}.st6{fill:url(#SVGID_7_)}</style><g><linearGradient id="SVGID_1_" x1="260.967" x2="919.184" y1="871.181" y2="491.16" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#669abd"/><stop offset="1" style="stop-color:#77dbdb"/></linearGradient><polygon points="297.54 934.52 882.6 596.72 882.61 427.82 297.54 765.65" class="st0"/><linearGradient id="SVGID_2_" x1="553.505" x2="626.647" y1="617.828" y2="744.513" gradientUnits="userSpaceOnUse"><stop offset=".559" style="stop-color:#000;stop-opacity:0"/><stop offset="1" style="stop-color:#000"/></linearGradient><polygon points="297.54 934.52 882.6 596.72 882.61 427.82 297.54 765.65" class="st1"/></g><g><linearGradient id="SVGID_3_" x1="114.663" x2="334.091" y1="744.528" y2="871.214" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#6a8fad"/><stop offset="1" style="stop-color:#669abd"/></linearGradient><polygon points="151.23 681.18 151.22 850.09 297.54 934.52 297.54 765.65" class="st2"/><linearGradient id="SVGID_4_" x1="260.948" x2="187.806" y1="744.528" y2="871.213" gradientUnits="userSpaceOnUse"><stop offset=".559" style="stop-color:#000;stop-opacity:0"/><stop offset="1" style="stop-color:#000"/></linearGradient><polygon points="151.23 681.18 151.22 850.09 297.54 934.52 297.54 765.65" class="st3"/></g><g><linearGradient id="SVGID_5_" x1="114.663" x2="553.503" y1="237.793" y2="491.157" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#6a8fad"/><stop offset="1" style="stop-color:#669abd"/></linearGradient><polygon points="151.23 174.45 151.21 343.36 443.79 512.27 590.08 427.81" class="st4"/><linearGradient id="SVGID_6_" x1="370.656" x2="297.509" y1="301.128" y2="427.822" gradientUnits="userSpaceOnUse"><stop offset=".559" style="stop-color:#000;stop-opacity:0"/><stop offset="1" style="stop-color:#000"/></linearGradient><polygon points="151.23 174.45 151.21 343.36 443.79 512.27 590.08 427.81" class="st5"/></g><linearGradient id="SVGID_7_" x1="78.091" x2="736.337" y1="554.498" y2="174.459" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#ccecff"/><stop offset="1" style="stop-color:#9feced"/></linearGradient><polygon points="297.51 765.64 151.23 681.18 590.08 427.81 151.23 174.45 297.5 90 882.61 427.82" class="st6"/></svg>
|
After Width: | Height: | Size: 2.6 KiB |
15
src/components/app.component.pug
Normal file
15
src/components/app.component.pug
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.sidebar
|
||||||
|
img.logo(src='{{_logo}}')
|
||||||
|
|
||||||
|
div(ngbDropdown)
|
||||||
|
button.btn.btn-secondary(ngbDropdownToggle) Cfg
|
||||||
|
//) !{require('../icons/download-solid.svg')}
|
||||||
|
div(ngbDropdownMenu)
|
||||||
|
a(
|
||||||
|
*ngFor='let config of configs',
|
||||||
|
ngbDropdownItem,
|
||||||
|
(click)='selectConfig(config)'
|
||||||
|
) Config modified at {{config.modified_at}}
|
||||||
|
|
||||||
|
.terminal([hidden]='!showApp')
|
||||||
|
iframe(#iframe)
|
34
src/components/app.component.scss
Normal file
34
src/components/app.component.scss
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
:host {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 64px;
|
||||||
|
flex: none;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal {
|
||||||
|
flex: 1 1 0;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
}
|
50
src/components/app.component.ts
Normal file
50
src/components/app.component.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { Component, ElementRef, ViewChild } from '@angular/core'
|
||||||
|
import { HttpClient } from '@angular/common/http'
|
||||||
|
import { AppConnectorService } from '../services/appConnector.service'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app',
|
||||||
|
templateUrl: './app.component.pug',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
_logo = require('../assets/logo.svg')
|
||||||
|
showApp = false
|
||||||
|
configs: any[] = []
|
||||||
|
@ViewChild('iframe') iframe: ElementRef
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private appConnector: AppConnectorService,
|
||||||
|
private http: HttpClient,
|
||||||
|
) {
|
||||||
|
window.addEventListener('message', event => {
|
||||||
|
if (event.data === 'request-connector') {
|
||||||
|
this.iframe.nativeElement.contentWindow['__connector__'] = this.appConnector
|
||||||
|
this.iframe.nativeElement.contentWindow.postMessage('connector-ready', '*')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async ngAfterViewInit () {
|
||||||
|
this.configs = await this.http.get('/api/1/configs').toPromise()
|
||||||
|
this.selectConfig(this.configs[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
unloadApp () {
|
||||||
|
this.showApp = false
|
||||||
|
this.iframe.nativeElement.src = 'about:blank'
|
||||||
|
}
|
||||||
|
|
||||||
|
loadApp () {
|
||||||
|
this.iframe.nativeElement.src = '/terminal'
|
||||||
|
this.showApp = true
|
||||||
|
}
|
||||||
|
|
||||||
|
selectConfig (config: any) {
|
||||||
|
this.appConnector.config = config
|
||||||
|
this.unloadApp()
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loadApp()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,9 @@
|
|||||||
doctype html
|
doctype html
|
||||||
html
|
html
|
||||||
head
|
head
|
||||||
base(href='dist/')
|
|
||||||
meta(name='viewport', content='initial-scale=1, minimal-ui, shrink-to-fit=no')
|
meta(name='viewport', content='initial-scale=1, minimal-ui, shrink-to-fit=no')
|
||||||
link(href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400", rel="stylesheet")
|
link(href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400", rel="stylesheet")
|
||||||
script(src='index.js', defer)
|
script(src='/build/index.js', defer)
|
||||||
title Terminus
|
title Terminus
|
||||||
body
|
body
|
||||||
.terminal
|
app
|
||||||
iframe(src='terminal.html')
|
|
15
src/index.ts
Normal file
15
src/index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import 'zone.js'
|
||||||
|
import 'core-js/proposals/reflect-metadata'
|
||||||
|
import 'core-js/features/array/flat'
|
||||||
|
import 'rxjs'
|
||||||
|
|
||||||
|
import { enableProdMode } from '@angular/core'
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
|
||||||
|
|
||||||
|
import './styles.scss'
|
||||||
|
import { AppModule } from './app.module'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enableProdMode()
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
24
src/services/appConnector.service.ts
Normal file
24
src/services/appConnector.service.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Subject } from 'rxjs'
|
||||||
|
import { debounceTime } from 'rxjs/operators'
|
||||||
|
import { HttpClient } from '@angular/common/http'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AppConnectorService {
|
||||||
|
config: any
|
||||||
|
private configUpdate = new Subject<string>()
|
||||||
|
|
||||||
|
constructor (private http: HttpClient) {
|
||||||
|
this.configUpdate.pipe(debounceTime(1000)).subscribe(content => {
|
||||||
|
this.http.patch(`/api/1/configs/${this.config.id}`, { content }).toPromise()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadConfig (): Promise<string> {
|
||||||
|
return this.config.content
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveConfig (content: string): Promise<void> {
|
||||||
|
this.configUpdate.next(content)
|
||||||
|
}
|
||||||
|
}
|
9
src/styles.scss
Normal file
9
src/styles.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
$font-family-sans-serif: "Source Sans Pro";
|
||||||
|
$border-radius-lg: 0;
|
||||||
|
$btn-border-width: 3px;
|
||||||
|
|
||||||
|
body {
|
||||||
|
overscroll-behavior: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "node_modules/bootstrap/scss/bootstrap";
|
0
src/terminal-styles.scss
Normal file
0
src/terminal-styles.scss
Normal file
@ -2,7 +2,7 @@ doctype html
|
|||||||
html.terminus
|
html.terminus
|
||||||
head
|
head
|
||||||
meta(charset='UTF-8')
|
meta(charset='UTF-8')
|
||||||
script(src='/dist/terminal.js')
|
script(src='/build/terminal.js')
|
||||||
style#custom-css
|
style#custom-css
|
||||||
style.
|
style.
|
||||||
body { transition: 0.5s background; }
|
body { transition: 0.5s background; }
|
@ -15,6 +15,17 @@ Object.assign(window, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
import * as angularCoreModule from '@angular/core'
|
||||||
|
import * as angularCompilerModule from '@angular/compiler'
|
||||||
|
import * as angularCommonModule from '@angular/common'
|
||||||
|
import * as angularFormsModule from '@angular/forms'
|
||||||
|
import * as angularPlatformBrowserModule from '@angular/platform-browser'
|
||||||
|
import * as angularPlatformBrowserAnimationsModule from '@angular/platform-browser/animations'
|
||||||
|
import * as angularPlatformBrowserDynamicModule from '@angular/platform-browser-dynamic'
|
||||||
|
import * as angularAnimationsModule from '@angular/animations'
|
||||||
|
import * as ngBootstrapModule from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import * as ngxToastrModule from 'ngx-toastr'
|
||||||
|
|
||||||
|
|
||||||
import 'core-js/proposals/reflect-metadata'
|
import 'core-js/proposals/reflect-metadata'
|
||||||
import '@fortawesome/fontawesome-free/css/solid.css'
|
import '@fortawesome/fontawesome-free/css/solid.css'
|
||||||
@ -22,7 +33,6 @@ import '@fortawesome/fontawesome-free/css/brands.css'
|
|||||||
import '@fortawesome/fontawesome-free/css/fontawesome.css'
|
import '@fortawesome/fontawesome-free/css/fontawesome.css'
|
||||||
import 'source-code-pro/source-code-pro.css'
|
import 'source-code-pro/source-code-pro.css'
|
||||||
import 'source-sans-pro/source-sans-pro.css'
|
import 'source-sans-pro/source-sans-pro.css'
|
||||||
import * as yaml from 'js-yaml'
|
|
||||||
import { Duplex } from 'stream-browserify'
|
import { Duplex } from 'stream-browserify'
|
||||||
import { Buffer } from 'buffer'
|
import { Buffer } from 'buffer'
|
||||||
|
|
||||||
@ -88,21 +98,6 @@ async function start () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let windowReadyCallback
|
|
||||||
const configContent = `
|
|
||||||
enableAnalytics: false
|
|
||||||
enableWelcomeTab: false
|
|
||||||
terminal:
|
|
||||||
font: "Source Code Pro"
|
|
||||||
autoOpen: true
|
|
||||||
rightClick: menu
|
|
||||||
copyOnSelect: false
|
|
||||||
appearance:
|
|
||||||
vibrancy: false
|
|
||||||
pluginBlacklist: []
|
|
||||||
`
|
|
||||||
const config = yaml.load(configContent)
|
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
fs: {
|
fs: {
|
||||||
realpathSync: path => {
|
realpathSync: path => {
|
||||||
@ -110,9 +105,6 @@ async function start () {
|
|||||||
return path
|
return path
|
||||||
},
|
},
|
||||||
existsSync: path => {
|
existsSync: path => {
|
||||||
if (path === 'app-path/config.yaml') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
console.warn('mock existsSync', path)
|
console.warn('mock existsSync', path)
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
@ -126,9 +118,6 @@ async function start () {
|
|||||||
},
|
},
|
||||||
writeFileSync: () => null,
|
writeFileSync: () => null,
|
||||||
readFileSync: (path) => {
|
readFileSync: (path) => {
|
||||||
if (path === 'app-path/config.yaml') {
|
|
||||||
return configContent
|
|
||||||
}
|
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
readFile: (path, enc, cb) => {
|
readFile: (path, enc, cb) => {
|
||||||
@ -186,19 +175,13 @@ async function start () {
|
|||||||
},
|
},
|
||||||
electron: {
|
electron: {
|
||||||
ipcRenderer: {
|
ipcRenderer: {
|
||||||
on: () => null,
|
on: (e, c) => {
|
||||||
|
console.log('[ipc listen]', e)
|
||||||
|
},
|
||||||
once: (e, c) => {
|
once: (e, c) => {
|
||||||
if (e === 'start') {
|
console.log('[ipc listen once]', e)
|
||||||
windowReadyCallback = c
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
send: msg => {
|
send: msg => {
|
||||||
if (msg === 'ready') {
|
|
||||||
windowReadyCallback(null, {
|
|
||||||
config,
|
|
||||||
executable: '---',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
console.log('[ipc]', msg)
|
console.log('[ipc]', msg)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -277,7 +260,7 @@ async function start () {
|
|||||||
exists: path => mocks.fs.existsSync(path),
|
exists: path => mocks.fs.existsSync(path),
|
||||||
existsSync: path => mocks.fs.existsSync(path),
|
existsSync: path => mocks.fs.existsSync(path),
|
||||||
},
|
},
|
||||||
constants: {},
|
constants: require('constants-browserify'),
|
||||||
'hterm-umdjs': {
|
'hterm-umdjs': {
|
||||||
hterm: {
|
hterm: {
|
||||||
PreferenceManager: class { set () {} },
|
PreferenceManager: class { set () {} },
|
||||||
@ -307,16 +290,16 @@ async function start () {
|
|||||||
;(mocks.assert as any).notStrictEqual = () => true
|
;(mocks.assert as any).notStrictEqual = () => true
|
||||||
|
|
||||||
let builtins = {
|
let builtins = {
|
||||||
'@angular/core': require('@angular/core'),
|
'@angular/core': angularCoreModule,
|
||||||
'@angular/compiler': require('@angular/compiler'),
|
'@angular/compiler': angularCompilerModule,
|
||||||
'@angular/common': require('@angular/common'),
|
'@angular/common': angularCommonModule,
|
||||||
'@angular/forms': require('@angular/forms'),
|
'@angular/forms': angularFormsModule,
|
||||||
'@angular/platform-browser': require('@angular/platform-browser'),
|
'@angular/platform-browser': angularPlatformBrowserModule,
|
||||||
'@angular/platform-browser/animations': require('@angular/platform-browser/animations'),
|
'@angular/platform-browser/animations': angularPlatformBrowserAnimationsModule,
|
||||||
'@angular/platform-browser-dynamic': require('@angular/platform-browser-dynamic'),
|
'@angular/platform-browser-dynamic': angularPlatformBrowserDynamicModule,
|
||||||
'@angular/animations': require('@angular/animations'),
|
'@angular/animations': angularAnimationsModule,
|
||||||
'@ng-bootstrap/ng-bootstrap': require('@ng-bootstrap/ng-bootstrap'),
|
'@ng-bootstrap/ng-bootstrap': ngBootstrapModule,
|
||||||
'ngx-toastr': require('ngx-toastr'),
|
'ngx-toastr': ngxToastrModule,
|
||||||
'deepmerge': require('deepmerge'),
|
'deepmerge': require('deepmerge'),
|
||||||
'rxjs': require('rxjs'),
|
'rxjs': require('rxjs'),
|
||||||
'rxjs/operators': require('rxjs/operators'),
|
'rxjs/operators': require('rxjs/operators'),
|
||||||
@ -339,18 +322,17 @@ async function start () {
|
|||||||
|
|
||||||
window['require'].main = {
|
window['require'].main = {
|
||||||
paths: []
|
paths: []
|
||||||
}
|
} as any
|
||||||
|
|
||||||
window['module'] = {
|
window['module'] = {
|
||||||
paths: []
|
paths: []
|
||||||
}
|
} as any
|
||||||
|
|
||||||
window['require'].resolve = path => null
|
window['require'].resolve = (path => null) as any
|
||||||
window['Buffer'] = mocks.buffer.Buffer
|
window['Buffer'] = mocks.buffer.Buffer
|
||||||
window['__dirname'] = '__dirname'
|
window['__dirname'] = '__dirname'
|
||||||
window['setImmediate'] = setTimeout
|
window['setImmediate'] = setTimeout as any
|
||||||
mocks.module['prototype'] = { require: window['require'] }
|
mocks.module['prototype'] = { require: window['require'] }
|
||||||
window['terminusConfig'] = configContent
|
|
||||||
|
|
||||||
Buffer.prototype['latin1Slice'] = latin1Slice
|
Buffer.prototype['latin1Slice'] = latin1Slice
|
||||||
Buffer.prototype['utf8Slice'] = utf8Slice
|
Buffer.prototype['utf8Slice'] = utf8Slice
|
||||||
@ -364,7 +346,7 @@ async function start () {
|
|||||||
async function loadPlugin (name, file = 'index.js') {
|
async function loadPlugin (name, file = 'index.js') {
|
||||||
const url = `../app-dist/${name}/dist/${file}`
|
const url = `../app-dist/${name}/dist/${file}`
|
||||||
const e = document.createElement('script')
|
const e = document.createElement('script')
|
||||||
window['module'] = { exports: {} }
|
window['module'] = { exports: {} } as any
|
||||||
window['exports'] = window['module'].exports
|
window['exports'] = window['module'].exports
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
e.onload = resolve
|
e.onload = resolve
|
||||||
@ -392,6 +374,17 @@ async function start () {
|
|||||||
await loadPlugin('app', 'preload.js')
|
await loadPlugin('app', 'preload.js')
|
||||||
await loadPlugin('app', 'bundle-web.js')
|
await loadPlugin('app', 'bundle-web.js')
|
||||||
document.querySelector('app-root')['style'].display = 'flex'
|
document.querySelector('app-root')['style'].display = 'flex'
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
window.addEventListener('message', event => {
|
||||||
|
if (event.data === 'connector-ready') {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
window.parent.postMessage('request-connector', '*')
|
||||||
|
})
|
||||||
|
|
||||||
|
const config = window['__connector__'].loadConfig()
|
||||||
window['bootstrapTerminus'](pluginModules, { config })
|
window['bootstrapTerminus'](pluginModules, { config })
|
||||||
}
|
}
|
||||||
|
|
27
styles.scss
27
styles.scss
@ -1,27 +0,0 @@
|
|||||||
$font-family-sans-serif: "Source Sans Pro";
|
|
||||||
$border-radius-lg: 0;
|
|
||||||
$btn-border-width: 3px;
|
|
||||||
|
|
||||||
// @import "node_modules/bootstrap/scss/bootstrap";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.terminal {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
left: 100px;
|
|
||||||
width: calc(100vw - 200px);
|
|
||||||
height: calc(100vh - 200px);
|
|
||||||
border-radius: 9px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 0 100px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border: none;
|
|
||||||
}
|
|
20
terminal.d.ts
vendored
20
terminal.d.ts
vendored
@ -1,20 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import 'core-js/proposals/reflect-metadata';
|
|
||||||
import '@fortawesome/fontawesome-free/css/solid.css';
|
|
||||||
import '@fortawesome/fontawesome-free/css/brands.css';
|
|
||||||
import '@fortawesome/fontawesome-free/css/fontawesome.css';
|
|
||||||
import 'source-code-pro/source-code-pro.css';
|
|
||||||
import 'source-sans-pro/source-sans-pro.css';
|
|
||||||
import { Duplex } from 'stream-browserify';
|
|
||||||
import './terminal-styles.scss';
|
|
||||||
export declare class Socket extends Duplex {
|
|
||||||
webSocket: WebSocket;
|
|
||||||
initialBuffer: Buffer;
|
|
||||||
constructor();
|
|
||||||
connect(): void;
|
|
||||||
setNoDelay(): void;
|
|
||||||
setTimeout(): void;
|
|
||||||
_read(size: number): void;
|
|
||||||
_write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void;
|
|
||||||
_destroy(error: Error | null, callback: (error: Error | null) => void): void;
|
|
||||||
}
|
|
19
terminus/app/api.py
Normal file
19
terminus/app/api.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# from rest_framework import fields
|
||||||
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
from rest_framework.serializers import ModelSerializer
|
||||||
|
|
||||||
|
from .models import Config
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Config
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigViewSet(ModelViewSet):
|
||||||
|
queryset = Config.objects.all()
|
||||||
|
serializer_class = ConfigSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Config.objects.filter(user=self.request.user)
|
@ -2,6 +2,7 @@ from django.db import models
|
|||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.contrib.auth.signals import user_logged_in
|
from django.contrib.auth.signals import user_logged_in
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from django.db.models.signals import post_save
|
||||||
|
|
||||||
|
|
||||||
class Config(models.Model):
|
class Config(models.Model):
|
||||||
@ -19,4 +20,7 @@ class User(AbstractUser):
|
|||||||
modified_at = models.DateTimeField(auto_now=True)
|
modified_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
|
||||||
# @receiver
|
# @receiver(user_logged_in)
|
||||||
|
# def post_login(sender, user, request, **kwargs):
|
||||||
|
# if not user.active_config:
|
||||||
|
# user.active_config = Config.objects.filter()
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
|
from . import api
|
||||||
from . import consumers
|
from . import consumers
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
router = routers.DefaultRouter(trailing_slash=False)
|
router = routers.DefaultRouter(trailing_slash=False)
|
||||||
# router.register('api/2/auth/saml', SAMLProviderViewSet)
|
router.register('api/1/configs', api.ConfigViewSet)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.IndexView.as_view()),
|
path('', views.IndexView.as_view()),
|
||||||
|
path('terminal', views.TerminalView.as_view()),
|
||||||
path('app-dist/<path:path>', views.AppDistView.as_view()),
|
path('app-dist/<path:path>', views.AppDistView.as_view()),
|
||||||
path('dist/<path:path>', views.DistView.as_view()),
|
path('build/<path:path>', views.BuildView.as_view()),
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -7,7 +7,14 @@ from django.views import static
|
|||||||
|
|
||||||
class IndexView(APIView):
|
class IndexView(APIView):
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
return static.serve(request, 'terminal.html', document_root=str(settings.BASE_DIR / 'dist'))
|
return static.serve(request, 'index.html', document_root=str(settings.BASE_DIR / 'build'))
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalView(APIView):
|
||||||
|
def get(self, request, format=None):
|
||||||
|
response = static.serve(request, 'terminal.html', document_root=str(settings.BASE_DIR / 'build'))
|
||||||
|
response['X-Frame-Options'] = 'SAMEORIGIN'
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
class AppDistView(APIView):
|
class AppDistView(APIView):
|
||||||
@ -15,6 +22,6 @@ class AppDistView(APIView):
|
|||||||
return static.serve(request, path, document_root=str(settings.BASE_DIR / 'app-dist'))
|
return static.serve(request, path, document_root=str(settings.BASE_DIR / 'app-dist'))
|
||||||
|
|
||||||
|
|
||||||
class DistView(APIView):
|
class BuildView(APIView):
|
||||||
def get(self, request, path=None, format=None):
|
def get(self, request, path=None, format=None):
|
||||||
return static.serve(request, path, document_root=str(settings.BASE_DIR / 'dist'))
|
return static.serve(request, path, document_root=str(settings.BASE_DIR / 'build'))
|
||||||
|
@ -128,3 +128,8 @@ STATIC_URL = '/static/'
|
|||||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
CSRF_USE_SESSIONS = False
|
||||||
|
CSRF_COOKIE_HTTPONLY = False
|
||||||
|
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
|
||||||
|
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN'
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"baseUrl": "src/",
|
||||||
"module": "esNext",
|
"module": "esNext",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
@ -21,7 +22,10 @@
|
|||||||
"es5",
|
"es5",
|
||||||
"es6",
|
"es6",
|
||||||
"es7"
|
"es7"
|
||||||
]
|
],
|
||||||
|
"paths": {
|
||||||
|
"*": ["src/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["app-dist"]
|
"exclude": ["app-dist"]
|
||||||
}
|
}
|
31
tsconfig.main.json
Normal file
31
tsconfig.main.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "src/",
|
||||||
|
"module": "esNext",
|
||||||
|
"target": "es6",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"removeComments": false,
|
||||||
|
"emitDeclarationOnly": false,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"declaration": true,
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es5",
|
||||||
|
"es6",
|
||||||
|
"es7"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"*": ["src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["app-dist"]
|
||||||
|
}
|
@ -1,120 +1,4 @@
|
|||||||
const path = require('path')
|
module.exports = [
|
||||||
const webpack = require('webpack')
|
require('./webpack.main.config'),
|
||||||
|
require('./webpack.terminal.config'),
|
||||||
module.exports = {
|
|
||||||
target: 'web',
|
|
||||||
entry: {
|
|
||||||
'index.ignore': 'file-loader?name=../index.html!pug-html-loader!' + path.resolve(__dirname, './index.pug'),
|
|
||||||
'terminal.ignore': 'file-loader?name=terminal.html!pug-html-loader!' + path.resolve(__dirname, './terminal.pug'),
|
|
||||||
index: path.resolve(__dirname, 'index.ts'),
|
|
||||||
terminal: path.resolve(__dirname, 'terminal.ts'),
|
|
||||||
},
|
|
||||||
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
|
||||||
context: __dirname,
|
|
||||||
devtool: 'cheap-module-source-map',
|
|
||||||
output: {
|
|
||||||
path: path.join(__dirname, 'dist'),
|
|
||||||
pathinfo: true,
|
|
||||||
filename: '[name].js',
|
|
||||||
chunkFilename: '[name].bundle.js',
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
modules: [
|
|
||||||
...[
|
|
||||||
'../terminus/terminus-core/node_modules/',
|
|
||||||
'../terminus/terminus-settings/node_modules/',
|
|
||||||
'../terminus/terminus-terminal/node_modules/',
|
|
||||||
'../terminus/node_modules',
|
|
||||||
'../terminus/app/node_modules',
|
|
||||||
'../terminus/app/assets/',
|
|
||||||
].map(x => path.join(__dirname, x)),
|
|
||||||
'node_modules/',
|
|
||||||
],
|
|
||||||
extensions: ['.ts', '.js'],
|
|
||||||
fallback: {
|
|
||||||
stream: require.resolve('stream-browserify'),
|
|
||||||
assert: require.resolve('assert/'),
|
|
||||||
constants: require.resolve('constants-browserify'),
|
|
||||||
util: require.resolve('util/'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
externals: {
|
|
||||||
'dns': 'commonjs dns',
|
|
||||||
'tls': 'commonjs tls',
|
|
||||||
'tty': 'commonjs tty',
|
|
||||||
'crypto': 'commonjs crypto',
|
|
||||||
'querystring': 'commonjs querystring',
|
|
||||||
'https': 'commonjs https',
|
|
||||||
'http': 'commonjs http',
|
|
||||||
'url': 'commonjs url',
|
|
||||||
'zlib': 'commonjs zlib',
|
|
||||||
'../build/Release/cpufeatures.node': 'commonjs ../build/Release/cpufeatures.node',
|
|
||||||
'./crypto/build/Release/sshcrypto.node': 'commonjs ./crypto/build/Release/sshcrypto.node',
|
|
||||||
'terminus-core': 'commonjs terminus-core',
|
|
||||||
'terminus-terminal': 'commonjs terminus-terminal',
|
|
||||||
'terminus-settings': 'commonjs terminus-settings',
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.ts$/,
|
|
||||||
use: {
|
|
||||||
loader: 'awesome-typescript-loader',
|
|
||||||
options: {
|
|
||||||
configFileName: path.resolve(__dirname, 'tsconfig.json'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ test: /terminus\/app\/dist/, use: ['script-loader'] },
|
|
||||||
// { test: /dist\/index/, use: ['raw-loader'] },
|
|
||||||
{
|
|
||||||
test: /\.(ttf|eot|otf|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
|
||||||
use: {
|
|
||||||
loader: 'file-loader',
|
|
||||||
options: {
|
|
||||||
name: 'fonts/[name].[ext]',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
|
|
||||||
{ test: /\.css$/, use: ['css-loader', 'sass-loader'] },
|
|
||||||
{
|
|
||||||
test: /\.(jpeg|png|svg)?$/,
|
|
||||||
use: {
|
|
||||||
loader: 'file-loader',
|
|
||||||
options: {
|
|
||||||
name: '[name].[ext]'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const externals = [
|
|
||||||
'@electron/remote',
|
|
||||||
'any-promise',
|
|
||||||
'child_process',
|
|
||||||
'electron-promise-ipc',
|
|
||||||
'electron',
|
|
||||||
'fontmanager-redux',
|
|
||||||
'fs',
|
|
||||||
'keytar',
|
|
||||||
'hterm-umdjs',
|
|
||||||
'macos-native-processlist',
|
|
||||||
'native-process-working-directory',
|
|
||||||
'net',
|
|
||||||
'os',
|
|
||||||
'path',
|
|
||||||
'readline',
|
|
||||||
'serialport',
|
|
||||||
'socksv5',
|
|
||||||
'windows-native-registry',
|
|
||||||
'windows-process-tree',
|
|
||||||
'windows-process-tree/build/Release/windows_process_tree.node',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
for (const k of externals) {
|
|
||||||
module.exports.externals[k] = `commonjs ${k}`
|
|
||||||
}
|
|
||||||
|
67
webpack.main.config.js
Normal file
67
webpack.main.config.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
const path = require('path')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const { AngularWebpackPlugin } = require('@ngtools/webpack')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
target: 'web',
|
||||||
|
entry: {
|
||||||
|
'index.ignore': 'file-loader?name=index.html!pug-html-loader!' + path.resolve(__dirname, './src/index.pug'),
|
||||||
|
index: path.resolve(__dirname, 'src/index.ts'),
|
||||||
|
},
|
||||||
|
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
||||||
|
context: __dirname,
|
||||||
|
devtool: 'cheap-module-source-map',
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, 'build'),
|
||||||
|
pathinfo: true,
|
||||||
|
filename: '[name].js',
|
||||||
|
chunkFilename: '[name].bundle.js',
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
modules: [
|
||||||
|
'src/',
|
||||||
|
'node_modules/',
|
||||||
|
],
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.[jt]sx?$/,
|
||||||
|
loader: '@ngtools/webpack',
|
||||||
|
},
|
||||||
|
{ test: /terminus\/app\/dist/, use: ['script-loader'] },
|
||||||
|
{
|
||||||
|
test: /\.pug$/,
|
||||||
|
use: ['apply-loader', 'pug-loader'],
|
||||||
|
include: /component\.pug/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: ['@terminus-term/to-string-loader', 'css-loader', 'sass-loader'],
|
||||||
|
include: /component\.scss/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||||
|
exclude: /component\.scss/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(ttf|eot|otf|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||||
|
type: 'asset/resource',
|
||||||
|
},
|
||||||
|
{ test: /\.css$/, use: ['css-loader', 'sass-loader'] },
|
||||||
|
{
|
||||||
|
test: /\.(jpeg|png|svg)?$/,
|
||||||
|
type: 'asset/resource',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
new AngularWebpackPlugin({
|
||||||
|
tsconfig: 'tsconfig.main.json',
|
||||||
|
directTemplateLoading: false,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}
|
122
webpack.terminal.config.js
Normal file
122
webpack.terminal.config.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
const path = require('path')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'web-container-terminal',
|
||||||
|
target: 'web',
|
||||||
|
entry: {
|
||||||
|
'terminal.ignore': 'file-loader?name=terminal.html!pug-html-loader!' + path.resolve(__dirname, './src/terminal.pug'),
|
||||||
|
terminal: path.resolve(__dirname, 'src/terminal.ts'),
|
||||||
|
},
|
||||||
|
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
||||||
|
context: __dirname,
|
||||||
|
devtool: 'cheap-module-source-map',
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, 'build'),
|
||||||
|
pathinfo: true,
|
||||||
|
filename: '[name].js',
|
||||||
|
chunkFilename: '[name].bundle.js',
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
modules: [
|
||||||
|
...[
|
||||||
|
'../terminus/terminus-core/node_modules/',
|
||||||
|
'../terminus/terminus-settings/node_modules/',
|
||||||
|
'../terminus/terminus-terminal/node_modules/',
|
||||||
|
'../terminus/node_modules',
|
||||||
|
'../terminus/app/node_modules',
|
||||||
|
'../terminus/app/assets/',
|
||||||
|
'src',
|
||||||
|
].map(x => path.join(__dirname, x)),
|
||||||
|
'node_modules/',
|
||||||
|
],
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
fallback: {
|
||||||
|
stream: require.resolve('stream-browserify'),
|
||||||
|
assert: require.resolve('assert/'),
|
||||||
|
constants: require.resolve('constants-browserify'),
|
||||||
|
util: require.resolve('util/'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
'dns': 'commonjs dns',
|
||||||
|
'tls': 'commonjs tls',
|
||||||
|
'tty': 'commonjs tty',
|
||||||
|
'crypto': 'commonjs crypto',
|
||||||
|
'querystring': 'commonjs querystring',
|
||||||
|
'https': 'commonjs https',
|
||||||
|
'http': 'commonjs http',
|
||||||
|
'url': 'commonjs url',
|
||||||
|
'zlib': 'commonjs zlib',
|
||||||
|
'../build/Release/cpufeatures.node': 'commonjs ../build/Release/cpufeatures.node',
|
||||||
|
'./crypto/build/Release/sshcrypto.node': 'commonjs ./crypto/build/Release/sshcrypto.node',
|
||||||
|
'terminus-core': 'commonjs terminus-core',
|
||||||
|
'terminus-terminal': 'commonjs terminus-terminal',
|
||||||
|
'terminus-settings': 'commonjs terminus-settings',
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.ts$/,
|
||||||
|
use: {
|
||||||
|
loader: 'awesome-typescript-loader',
|
||||||
|
options: {
|
||||||
|
configFileName: path.resolve(__dirname, 'tsconfig.container.json'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// { test: /terminus\/app\/dist/, use: ['script-loader'] },
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(ttf|eot|otf|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: 'fonts/[name].[ext]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ test: /\.css$/, use: ['css-loader', 'sass-loader'] },
|
||||||
|
{
|
||||||
|
test: /\.(jpeg|png|svg)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const externals = [
|
||||||
|
'@electron/remote',
|
||||||
|
'any-promise',
|
||||||
|
'child_process',
|
||||||
|
'electron-promise-ipc',
|
||||||
|
'electron',
|
||||||
|
'fontmanager-redux',
|
||||||
|
'fs',
|
||||||
|
'keytar',
|
||||||
|
'hterm-umdjs',
|
||||||
|
'macos-native-processlist',
|
||||||
|
'native-process-working-directory',
|
||||||
|
'net',
|
||||||
|
'os',
|
||||||
|
'path',
|
||||||
|
'readline',
|
||||||
|
'serialport',
|
||||||
|
'socksv5',
|
||||||
|
'windows-native-registry',
|
||||||
|
'windows-process-tree',
|
||||||
|
'windows-process-tree/build/Release/windows_process_tree.node',
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const k of externals) {
|
||||||
|
module.exports.externals[k] = `commonjs ${k}`
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user