Skip to content

Commit

Permalink
feat: update studio command to use hosted instance
Browse files Browse the repository at this point in the history
  • Loading branch information
Souvikns committed Jan 18, 2024
1 parent 3883073 commit 020db35
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 23 deletions.
7 changes: 4 additions & 3 deletions src/commands/new/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Flags} from '@oclif/core';
import { promises as fPromises, readFileSync } from 'fs';
import Command from '../../base';
import * as inquirer from 'inquirer';
import { start as startStudio, DEFAULT_PORT } from '../../models/Studio';
import { start as startStudio, DEFAULT_PORT, startOnline } from '../../models/Studio';

Check failure on line 5 in src/commands/new/file.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

'startStudio' is defined but never used
import { resolve } from 'path';

const { writeFile, readFile } = fPromises;
Expand Down Expand Up @@ -60,7 +60,8 @@ export default class NewFile extends Command {

if (flags.studio) {
if (isTTY) {
startStudio(fileName, flags.port || DEFAULT_PORT);
startOnline(fileName, flags.port || DEFAULT_PORT);
//startStudio(fileName, flags.port || DEFAULT_PORT);
} else {
this.warn('Warning: --studio flag was passed but the terminal is not interactive. Ignoring...');
}
Expand Down Expand Up @@ -132,7 +133,7 @@ export default class NewFile extends Command {
selectedTemplate = selectedTemplate || DEFAULT_ASYNCAPI_TEMPLATE;

await this.createAsyncapiFile(fileName, selectedTemplate);
if (openStudio) { startStudio(fileName, flags.port || DEFAULT_PORT);}
if (openStudio) { startOnline(fileName, flags.port || DEFAULT_PORT);}
}

async createAsyncapiFile(fileName:string, selectedTemplate:string) {
Expand Down
5 changes: 3 additions & 2 deletions src/commands/start/studio.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Flags} from '@oclif/core';
import Command from '../../base';
import { start as startStudio } from '../../models/Studio';
import { start as startStudio, startOnline } from '../../models/Studio';

Check failure on line 3 in src/commands/start/studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

'startStudio' is defined but never used
import { load } from '../../models/SpecificationFile';

export default class StartStudio extends Command {
Expand All @@ -19,6 +19,7 @@ export default class StartStudio extends Command {
const filePath = flags.file || (await load()).getFilePath();
const port = flags.port;

Check failure on line 20 in src/commands/start/studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

'port' is assigned a value but never used

startStudio(filePath as string, port);
//startStudio(filePath as string, port);
startOnline(filePath as string)

Check failure on line 23 in src/commands/start/studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Missing semicolon
}
}
112 changes: 94 additions & 18 deletions src/models/Studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { WebSocketServer } from 'ws';
import chokidar from 'chokidar';
import open from 'open';
import path from 'path';
import fs from 'fs'

Check failure on line 9 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Missing semicolon

const { readFile, writeFile } = fPromises;
const { readFile, writeFile } = fPromises;

const sockets: any[] = [];
const messageQueue: string[] = [];
Expand All @@ -18,29 +19,104 @@ function isValidFilePath(filePath: string): boolean {
return existsSync(filePath);
}

export function startOnline(filePath: string, port: number = DEFAULT_PORT): void {

Check warning on line 22 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed
if (!isValidFilePath(filePath)) {
throw new SpecificationFileNotFound(filePath)

Check failure on line 24 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Missing semicolon
}

const server = createServer((request, response) => {

Check failure on line 27 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Block must not be padded by blank lines

if (request.url === '/fileread') {
var extname = path.extname(filePath);

Check failure on line 30 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Unexpected var, use let or const instead
var contentType = 'text/html';

Check failure on line 31 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Unexpected var, use let or const instead
switch (extname) {
case '.json':

Check failure on line 33 in src/models/Studio.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Expected indentation of 6 spaces but found 8
contentType = 'application/json';
break;
}
const headers = {
'Access-Control-Allow-Origin': '*', /* @dev First, read about security */
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
};

fs.readFile(filePath, (error, content) => {
response.writeHead(200, { 'content-Type': contentType, ...headers })
response.end(content, 'utf-8')
})
}
})

server.on('upgrade', (request, socket, head) => {
if (request.url === '/filesave') {
wsServer.handleUpgrade(request, socket, head, (sock: any) => {
wsServer.emit('connection', sock, request)
})
} else {
socket.destroy()
}
})

const wsServer = new WebSocketServer({ noServer: true })

wsServer.on('connection', (socket: any) => {
sockets.push(socket)
getFileContent(filePath).then((code: string) => {
messageQueue.push(JSON.stringify({
type: 'file:loaded',
code
}));
sendQueuedMessages();
})

socket.on('message', (event: string) => {
try {
const json: any = JSON.parse(event);
if (json.type === 'file:update') {
saveFileContent(filePath, json.code);
} else {
console.warn('Live Server: An unkown event has been received. See details:');
console.log(json)
}
} catch (error) {
console.error(`Live Server: An invalid event has been received. See details:\n${event}`)
}
})
wsServer.on('close', (socekt: any) => {
sockets.splice(sockets.findIndex(s => s === socket))
})
})

server.listen(port, () => {
const url = `https://studio.asyncapi.com/?url=http://localhost:${port}/fileread&url_save=http://localhost:${port}/filesave`
console.log(`Studio is running at ${url}`)
open(url)
})

}

export function start(filePath: string, port: number = DEFAULT_PORT): void {
if (!isValidFilePath(filePath)) {
throw new SpecificationFileNotFound(filePath);
}
chokidar.watch(filePath).on('all', (event, path) => {
switch (event) {
case 'add':
case 'change':
getFileContent(path).then((code:string) => {
case 'add':
case 'change':
getFileContent(path).then((code: string) => {
messageQueue.push(JSON.stringify({
type: 'file:changed',
code,
}));
sendQueuedMessages();
});
break;
case 'unlink':
messageQueue.push(JSON.stringify({
type: 'file:changed',
code,
type: 'file:deleted',
filePath,
}));
sendQueuedMessages();
});
break;
case 'unlink':
messageQueue.push(JSON.stringify({
type: 'file:deleted',
filePath,
}));
sendQueuedMessages();
break;
break;
}
});

Expand Down Expand Up @@ -79,7 +155,7 @@ export function start(filePath: string, port: number = DEFAULT_PORT): void {

socket.on('message', (event: string) => {
try {
const json:any = JSON.parse(event);
const json: any = JSON.parse(event);
if (json.type === 'file:update') {
saveFileContent(filePath, json.code);
} else {
Expand All @@ -88,10 +164,10 @@ export function start(filePath: string, port: number = DEFAULT_PORT): void {
}
} catch (e) {
console.error(`Live Server: An invalid event has been received. See details:\n${event}`);
}
}
});
});

wsServer.on('close', (socket: any) => {
sockets.splice(sockets.findIndex(s => s === socket));
});
Expand Down

0 comments on commit 020db35

Please sign in to comment.