From 388920ce333ead498933a0883484ff4eec8d5a8f Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Wed, 30 Oct 2024 18:02:15 -0500 Subject: [PATCH 1/3] start to make the distinction between protocol and message --- lib/src/actions/forward-action.ts | 1 + lib/src/protocols/http-protocol.ts | 106 ++++++++++++++- lib/src/protocols/index.ts | 1 - lib/src/protocols/websocket-protocol.ts | 125 ------------------ lib/src/router.ts | 25 +--- webui/src/app/app.module.ts | 4 +- .../components/config/config.component.html | 54 ++++---- .../app/components/config/config.component.ts | 27 +--- .../message-type.component.css} | 0 .../message-type.component.html} | 12 +- .../message-type.component.ts} | 42 +++--- webui/src/app/models/events.model.ts | 6 - webui/src/app/services/schema.service.ts | 40 +++--- 13 files changed, 188 insertions(+), 255 deletions(-) delete mode 100644 lib/src/protocols/websocket-protocol.ts rename webui/src/app/components/{protocol/protocol.component.css => message-type/message-type.component.css} (100%) rename webui/src/app/components/{protocol/protocol.component.html => message-type/message-type.component.html} (90%) rename webui/src/app/components/{protocol/protocol.component.ts => message-type/message-type.component.ts} (67%) diff --git a/lib/src/actions/forward-action.ts b/lib/src/actions/forward-action.ts index a87c25fd..8e651495 100644 --- a/lib/src/actions/forward-action.ts +++ b/lib/src/actions/forward-action.ts @@ -19,6 +19,7 @@ class ForwardAction extends Action { if (resolvedParams.protocol === 'udp') { protocols.udp.send(Buffer.from(msgToForward), resolvedParams.port, resolvedParams.host); } else if (resolvedParams.protocol === 'tcp') { + // TODO(jwetzell): osc messages are always slip encoded? protocols.tcp.send( Buffer.from(msgToForward), resolvedParams.port, diff --git a/lib/src/protocols/http-protocol.ts b/lib/src/protocols/http-protocol.ts index e72cc95d..650b8280 100644 --- a/lib/src/protocols/http-protocol.ts +++ b/lib/src/protocols/http-protocol.ts @@ -3,11 +3,14 @@ import { EventEmitter } from 'node:events'; import cors from 'cors'; import express, { Application } from 'express'; import http, { IncomingMessage, Server, ServerResponse } from 'http'; +import { WebSocket, WebSocketServer } from 'ws'; + import { get, has, set } from 'lodash-es'; import { AddressInfo } from 'net'; import superagent from 'superagent'; import Config from '../config.js'; -import { HTTPMessage } from '../messages/index.js'; +import { HTTPMessage, WebSocketMessage } from '../messages/index.js'; +import { WebUIPayload } from '../messages/websocket-message.js'; import Router from '../router.js'; import { disabled, logger } from '../utils/index.js'; @@ -15,6 +18,9 @@ class HTTPProtocol extends EventEmitter { router: Router; app: Application; httpServer: Server; + wsServer: WebSocketServer; + webUISockets: WebSocket[]; + openWebSockets: WebSocket[]; server: Server; constructor(router) { @@ -25,9 +31,7 @@ class HTTPProtocol extends EventEmitter { this.app = express(); this.httpServer = http.createServer(this.app); - this.httpServer.on('upgrade', (req, socket, head) => { - this.emit('httpUpgrade', req, socket, head); - }); + this.setupWebSocket(); // Express Server this.app.use(cors()); @@ -130,6 +134,72 @@ class HTTPProtocol extends EventEmitter { }); } + setupWebSocket() { + this.webUISockets = []; + this.openWebSockets = []; + this.wsServer = new WebSocketServer({ + noServer: true, + }); + + this.wsServer.on('connection', (ws, req) => { + if (ws.protocol === 'webui') { + const webUISocket = ws; + // NOTE(jwetzell): this setups the websocket protocol for the webui + // storing the socket for later reference and not setting the usual message listener + this.webUISockets.push(webUISocket); + webUISocket.onclose = () => { + const socketIndex = this.webUISockets.indexOf(webUISocket); + if (socketIndex > -1) { + this.webUISockets.splice(socketIndex, 1); + } + }; + webUISocket.on('message', (msgBuffer) => { + const wsMsg = new WebSocketMessage(msgBuffer, { + protocol: 'tcp', + address: req.socket?.remoteAddress, + port: req.socket?.remotePort, + }); + + if (wsMsg.payload !== undefined && typeof wsMsg.payload === 'object') { + const webUIPayload = wsMsg.payload as WebUIPayload; + if (webUIPayload.eventName === 'getProtocolStatus') { + this.emit('getProtocolStatus', webUISocket); + } else if (webUIPayload.eventName === 'runAction') { + if (webUIPayload.data) { + // TODO(jwetzell) error handling here? + this.emit('runAction', webUIPayload.data.action, webUIPayload.data.msg, webUIPayload.data.vars); + } + } + } + }); + } else { + const webSocketConnection = ws; + this.openWebSockets.push(webSocketConnection); + webSocketConnection.onclose = () => { + const socketIndex = this.openWebSockets.indexOf(ws); + if (socketIndex > -1) { + this.openWebSockets.splice(socketIndex, 1); + } + }; + webSocketConnection.on('message', (msgBuffer) => { + // NOTE(jwetzell): extract some key request properties + const wsMsg = new WebSocketMessage(msgBuffer, { + protocol: 'tcp', + address: req.socket?.remoteAddress, + port: req.socket?.remotePort, + }); + this.emit('messageIn', wsMsg); + }); + } + }); + + this.httpServer.on('upgrade', (req, socket, head) => { + this.wsServer.handleUpgrade(req, socket, head, (ws) => { + this.wsServer.emit('connection', ws, req); + }); + }); + } + servePath(filePath) { this.app.use('/', express.static(filePath)); // NOTE(jwetzell): move the static paths up in priority @@ -155,6 +225,13 @@ class HTTPProtocol extends EventEmitter { }); return; } + + if (this.webUISockets.length > 0) { + this.webUISockets.forEach((webUISocket) => { + webUISocket.close(); + }); + } + try { this.server = this.httpServer.listen(params.port, params.address ? params.address : '0.0.0.0', () => { logger.debug( @@ -171,6 +248,17 @@ class HTTPProtocol extends EventEmitter { } } + sendToWebUISockets(eventName: string, data) { + this.webUISockets.forEach((socket) => { + socket.send( + JSON.stringify({ + eventName, + data, + }) + ); + }); + } + send(url: string, method: string, body, contentType: string) { const request = superagent(method, url); if (contentType !== undefined) { @@ -189,6 +277,16 @@ class HTTPProtocol extends EventEmitter { } stop() { + // NOTE(jwetzell): close all web sockets + this.webUISockets.forEach((socket) => { + socket.close(); + }); + + this.openWebSockets.forEach((socket) => { + socket.close(); + }); + + // NOTE(jwetzell): close http server if (this.server) { if (this.server.listening) { this.server.close(); diff --git a/lib/src/protocols/index.ts b/lib/src/protocols/index.ts index 0e72afa8..3d960d7a 100644 --- a/lib/src/protocols/index.ts +++ b/lib/src/protocols/index.ts @@ -4,4 +4,3 @@ export { default as MIDIProtocol } from './midi-protocol.js'; export { default as MQTTProtocol } from './mqtt-protocol.js'; export { default as TCPProtocol } from './tcp-protocol.js'; export { default as UDPProtocol } from './udp-protocol.js'; -export { default as WebSocketProtocol } from './websocket-protocol.js'; diff --git a/lib/src/protocols/websocket-protocol.ts b/lib/src/protocols/websocket-protocol.ts deleted file mode 100644 index b940e10c..00000000 --- a/lib/src/protocols/websocket-protocol.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { EventEmitter } from 'node:events'; -import { WebSocketServer as Server, WebSocket } from 'ws'; -import { WebSocketMessage } from '../messages/index.js'; -import { WebUIPayload } from '../messages/websocket-message.js'; -import Router from '../router.js'; -import { disabled } from '../utils/index.js'; - -class WebSocketProtocol extends EventEmitter { - router: Router; - webUISockets: WebSocket[]; - openWebSockets: WebSocket[]; - server: Server; - - constructor(router) { - super(); - this.router = router; - - this.webUISockets = []; - this.openWebSockets = []; - - this.server = new Server({ - noServer: true, - }); - - this.server.on('connection', (ws, req) => { - const webUISocket = ws; - if (webUISocket.protocol === 'webui') { - // NOTE(jwetzell): this setups the websocket protocol for the webui - // storing the socket for later reference and not setting the usual message listener - this.webUISockets.push(webUISocket); - webUISocket.onclose = () => { - const socketIndex = this.webUISockets.indexOf(webUISocket); - if (socketIndex > -1) { - this.webUISockets.splice(socketIndex, 1); - } - }; - webUISocket.on('message', (msgBuffer) => { - const wsMsg = new WebSocketMessage(msgBuffer, { - protocol: 'tcp', - address: req.socket?.remoteAddress, - port: req.socket?.remotePort, - }); - - if (wsMsg.payload !== undefined && typeof wsMsg.payload === 'object') { - const webUIPayload = wsMsg.payload as WebUIPayload; - if (webUIPayload.eventName === 'getProtocolStatus') { - this.emit('getProtocolStatus', webUISocket); - } else if (webUIPayload.eventName === 'runAction') { - if (webUIPayload.data) { - // TODO(jwetzell) error handling here? - this.emit('runAction', webUIPayload.data.action, webUIPayload.data.msg, webUIPayload.data.vars); - } - } - } - }); - } else { - const webSocketConnection = ws; - this.openWebSockets.push(webSocketConnection); - webSocketConnection.onclose = () => { - const socketIndex = this.openWebSockets.indexOf(webUISocket); - if (socketIndex > -1) { - this.openWebSockets.splice(socketIndex, 1); - } - }; - webSocketConnection.on('message', (msgBuffer) => { - // NOTE(jwetzell): extract some key request properties - const wsMsg = new WebSocketMessage(msgBuffer, { - protocol: 'tcp', - address: req.socket?.remoteAddress, - port: req.socket?.remotePort, - }); - this.emit('messageIn', wsMsg); - }); - } - }); - } - - handleUpgrade(req, socket, head) { - this.server.handleUpgrade(req, socket, head, (ws) => { - this.server.emit('connection', ws, req); - }); - } - - sendToWebUISockets(eventName: string, data) { - this.webUISockets.forEach((socket) => { - socket.send( - JSON.stringify({ - eventName, - data, - }) - ); - }); - } - - reload() { - if (this.webUISockets.length > 0) { - this.webUISockets.forEach((webUISocket) => { - webUISocket.close(); - }); - } - this.emit('started'); - } - - stop() { - // NOTE(jwetzell): close all web sockets - this.webUISockets.forEach((socket) => { - socket.close(); - }); - - this.openWebSockets.forEach((socket) => { - socket.close(); - }); - - this.emit('stopped'); - } - - get status() { - return { - enabled: !disabled.protocols.has('ws'), - listening: !!this.server, - }; - } -} - -export default WebSocketProtocol; diff --git a/lib/src/router.ts b/lib/src/router.ts index 4fc390af..87e3f0a1 100644 --- a/lib/src/router.ts +++ b/lib/src/router.ts @@ -15,7 +15,6 @@ import { MQTTProtocol, TCPProtocol, UDPProtocol, - WebSocketProtocol, } from './protocols/index.js'; import Trigger from './triggers/trigger.js'; @@ -26,7 +25,6 @@ export type RouterProtocols = { midi: MIDIProtocol; mqtt: MQTTProtocol; cloud: CloudProtocol; - ws: WebSocketProtocol; }; class Router extends EventEmitter { @@ -48,7 +46,6 @@ class Router extends EventEmitter { midi: new MIDIProtocol(this), mqtt: new MQTTProtocol(this), cloud: new CloudProtocol(this), - ws: new WebSocketProtocol(this), }; // NOTE(jwetzell): listen for all messages on all protocols @@ -58,11 +55,6 @@ class Router extends EventEmitter { }); }); - // NOTE(jwetzell): websocket server needs the http server instance to load - this.protocols.http.on('httpUpgrade', (req, socket, head) => { - this.protocols.ws.handleUpgrade(req, socket, head); - }); - this.protocols.http.on('configUploaded', (updatedConfig) => { try { this.config = updatedConfig; @@ -74,11 +66,11 @@ class Router extends EventEmitter { } }); - this.protocols.ws.on('runAction', (action: Action, msg: Message, vars: RouterVars) => { + this.protocols.http.on('runAction', (action: Action, msg: Message, vars: RouterVars) => { this.runAction(action, msg, vars); }); - this.protocols.ws.on('getProtocolStatus', (webSocket) => { + this.protocols.http.on('getProtocolStatus', (webSocket) => { const protocolStatusEvent: any = { eventName: 'protocolStatus', data: {}, @@ -88,13 +80,6 @@ class Router extends EventEmitter { protocolStatusEvent.data[protocol] = this.protocols[protocol].status; }); - // NOTE(jwetzell): osc is a "shadow" protocol so need to insert the status manually - protocolStatusEvent.data.osc = { - enabled: protocolStatusEvent.data.tcp.enabled || protocolStatusEvent.data.udp.enabled, - udp: protocolStatusEvent.data.udp, - tcp: protocolStatusEvent.data.tcp, - }; - if (webSocket.readyState === WebSocket.OPEN) { webSocket.send(JSON.stringify(protocolStatusEvent)); } @@ -105,7 +90,7 @@ class Router extends EventEmitter { }); this.on('trigger', (triggerEvent) => { - this.protocols.ws.sendToWebUISockets('trigger', triggerEvent); + this.protocols.http.sendToWebUISockets('trigger', triggerEvent); }); this.on('action', (actionEvent) => { @@ -113,11 +98,11 @@ class Router extends EventEmitter { this.emit('varsUpdated', this.vars); } - this.protocols.ws.sendToWebUISockets('action', actionEvent); + this.protocols.http.sendToWebUISockets('action', actionEvent); }); this.on('transform', (transformEvent) => { - this.protocols.ws.sendToWebUISockets('transform', transformEvent); + this.protocols.http.sendToWebUISockets('transform', transformEvent); }); } diff --git a/webui/src/app/app.module.ts b/webui/src/app/app.module.ts index 8e82190f..8d9e2e42 100644 --- a/webui/src/app/app.module.ts +++ b/webui/src/app/app.module.ts @@ -25,10 +25,10 @@ import { ArrayFormComponent } from './components/array-form/array-form.component import { ClipboardDialogComponent } from './components/clipboard-dialog/clipboard-dialog.component'; import { ConfigComponent } from './components/config/config.component'; import { ImportConfigComponent } from './components/import-config/import-config.component'; +import { MessageTypeComponent } from './components/message-type/message-type.component'; import { MIDIInfoDialogComponent } from './components/midi-info-dialog/midi-info-dialog.component'; import { ParamsFormComponent } from './components/params-form/params-form.component'; import { PatchEditorComponent } from './components/patch-editor/patch-editor.component'; -import { ProtocolComponent } from './components/protocol/protocol.component'; import { TransformComponent } from './components/transform/transform.component'; import { TriggerComponent } from './components/trigger/trigger.component'; @NgModule({ @@ -38,7 +38,7 @@ import { TriggerComponent } from './components/trigger/trigger.component'; TransformComponent, ActionComponent, TriggerComponent, - ProtocolComponent, + MessageTypeComponent, ParamsFormComponent, ArrayFormComponent, ImportConfigComponent, diff --git a/webui/src/app/components/config/config.component.html b/webui/src/app/components/config/config.component.html index 5e0dd9f6..43fe9bac 100644 --- a/webui/src/app/components/config/config.component.html +++ b/webui/src/app/components/config/config.component.html @@ -1,38 +1,36 @@
- - - -
-
- - {{ protocol.name }} - -
+ + +
+
+ + {{ messageType.name }} +
- - -
-
- - {{ protocol.name }} - -
-
-
+
+ +
+
+ + {{ messageType.name }} + +
+
+
-
- +
+
diff --git a/webui/src/app/components/config/config.component.ts b/webui/src/app/components/config/config.component.ts index 0a8303c3..cbd1295a 100644 --- a/webui/src/app/components/config/config.component.ts +++ b/webui/src/app/components/config/config.component.ts @@ -1,5 +1,4 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { map } from 'rxjs'; import { ConfigFile } from 'src/app/models/config.models'; import { ObjectInfo } from 'src/app/models/form.model'; import { EventService } from 'src/app/services/event.service'; @@ -15,31 +14,15 @@ export class ConfigComponent { @Input() config!: ConfigFile; @Output() updated: EventEmitter = new EventEmitter(); pendingUpdate?: ConfigFile; - selectedProtocol: ObjectInfo = this.schemaService.protocolTypes[0]; + selectedMessageType: ObjectInfo = this.schemaService.messageTypes[0]; - enabledProtocols: string[]; + messageTypes: string[]; constructor( public schemaService: SchemaService, public eventService: EventService, public settingsService: SettingsService ) { - this.enabledProtocols = this.schemaService.protocolTypes.map((protocolInfo) => protocolInfo.type); - - this.eventService.protocolStatus$ - .pipe( - map((protocolStatus) => { - return Object.entries(protocolStatus.data) - .filter(([key, value]) => { - return value.enabled; - }) - .map(([key, value]) => { - return key; - }); - }) - ) - .subscribe((protocolTypes) => { - this.enabledProtocols = protocolTypes; - }); + this.messageTypes = this.schemaService.messageTypes.map((protocolInfo) => protocolInfo.type); } protocolUpdate(type: string) { @@ -51,7 +34,7 @@ export class ConfigComponent { this.updated.emit(true); } - selectProtocolType(protocol: ObjectInfo) { - this.selectedProtocol = protocol; + selectMessageType(messageType: ObjectInfo) { + this.selectedMessageType = messageType; } } diff --git a/webui/src/app/components/protocol/protocol.component.css b/webui/src/app/components/message-type/message-type.component.css similarity index 100% rename from webui/src/app/components/protocol/protocol.component.css rename to webui/src/app/components/message-type/message-type.component.css diff --git a/webui/src/app/components/protocol/protocol.component.html b/webui/src/app/components/message-type/message-type.component.html similarity index 90% rename from webui/src/app/components/protocol/protocol.component.html rename to webui/src/app/components/message-type/message-type.component.html index d7a8e99e..4bf54d80 100644 --- a/webui/src/app/components/protocol/protocol.component.html +++ b/webui/src/app/components/message-type/message-type.component.html @@ -1,4 +1,4 @@ - +
@@ -16,7 +16,7 @@
@@ -25,13 +25,13 @@
-
+ [cdkDropListData]="messageTypeConfig?.triggers"> +
diff --git a/webui/src/app/components/protocol/protocol.component.ts b/webui/src/app/components/message-type/message-type.component.ts similarity index 67% rename from webui/src/app/components/protocol/protocol.component.ts rename to webui/src/app/components/message-type/message-type.component.ts index 199ed525..b0a3b174 100644 --- a/webui/src/app/components/protocol/protocol.component.ts +++ b/webui/src/app/components/message-type/message-type.component.ts @@ -12,13 +12,13 @@ import { ListsService } from 'src/app/services/lists.service'; import { SchemaService } from 'src/app/services/schema.service'; @Component({ - selector: 'app-protocol', - templateUrl: './protocol.component.html', - styleUrls: ['./protocol.component.css'], + selector: 'app-message-type', + templateUrl: './message-type.component.html', + styleUrls: ['./message-type.component.css'], }) -export class ProtocolComponent { - @Input() protocolType?: string; - @Input() protocol?: ProtocolConfiguration; +export class MessageTypeComponent { + @Input() messageType?: string; + @Input() messageTypeConfig?: ProtocolConfiguration; @Output() updated: EventEmitter = new EventEmitter(); @ViewChild('settingsDialogRef') dialogRef?: TemplateRef; @@ -36,23 +36,23 @@ export class ProtocolComponent { ) {} ngOnChanges(changes: SimpleChanges) { - if (this.protocolType) { - this.triggerTypes = this.schemaService.getTriggerTypesForProtocol(this.protocolType); + if (this.messageType) { + this.triggerTypes = this.schemaService.getTriggerTypesForMessageType(this.messageType); - this.schema = this.schemaService.getSchemaForProtocol(this.protocolType); + this.schema = this.schemaService.getSchemaForMessageType(this.messageType); this.hasSettings = this.schema.properties.params !== undefined; } } protocolParamsUpdated(params: any) { - if (this.protocol) { - this.protocol.params = params; + if (this.messageTypeConfig) { + this.messageTypeConfig.params = params; } this.updated.emit(true); } deleteTrigger(index: number) { - this.protocol?.triggers?.splice(index, 1); + this.messageTypeConfig?.triggers?.splice(index, 1); this.updated.emit(true); this.snackBar.open('Trigger Removed', 'Dismiss', { duration: 3000, @@ -64,18 +64,18 @@ export class ProtocolComponent { } addTrigger(triggerType: string) { - if (this.protocol && this.protocol?.triggers === undefined) { - this.protocol.triggers = []; + if (this.messageTypeConfig && this.messageTypeConfig?.triggers === undefined) { + this.messageTypeConfig.triggers = []; } const triggerTemplate = this.schemaService.getSkeletonForTrigger(triggerType); - this.protocol?.triggers?.push(triggerTemplate); + this.messageTypeConfig?.triggers?.push(triggerTemplate); this.updated.emit(true); } dropTrigger(event: CdkDragDrop[] | undefined>) { if (event.previousContainer === event.container) { - if (this.protocol?.triggers !== undefined) { - moveItemInArray(this.protocol?.triggers, event.previousIndex, event.currentIndex); + if (this.messageTypeConfig?.triggers !== undefined) { + moveItemInArray(this.messageTypeConfig?.triggers, event.previousIndex, event.currentIndex); this.updated.emit(true); } } else if (event.previousContainer.data && event.container.data) { @@ -95,13 +95,13 @@ export class ProtocolComponent { return; } - if (this.protocol && this.protocol?.triggers === undefined) { - this.protocol.triggers = []; + if (this.messageTypeConfig && this.messageTypeConfig?.triggers === undefined) { + this.messageTypeConfig.triggers = []; } if (Array.isArray(copyObject.object)) { - this.protocol?.triggers?.push(...cloneDeep(copyObject.object)); + this.messageTypeConfig?.triggers?.push(...cloneDeep(copyObject.object)); } else { - this.protocol?.triggers?.push(cloneDeep(copyObject.object)); + this.messageTypeConfig?.triggers?.push(cloneDeep(copyObject.object)); } this.updated.emit(true); } diff --git a/webui/src/app/models/events.model.ts b/webui/src/app/models/events.model.ts index 4cb5f680..d4f78aa0 100644 --- a/webui/src/app/models/events.model.ts +++ b/webui/src/app/models/events.model.ts @@ -38,7 +38,6 @@ export type ProtocolStatusEventData = { mqtt?: MQTTStatus; tcp?: TCPStatus; udp?: UDPStatus; - ws?: WebSocketStatus; }; }; @@ -94,8 +93,3 @@ export type UDPStatus = { address: string; }; }; - -export type WebSocketStatus = { - enabled: boolean; - listening: boolean; -}; diff --git a/webui/src/app/services/schema.service.ts b/webui/src/app/services/schema.service.ts index e46d24ba..dcdb3476 100644 --- a/webui/src/app/services/schema.service.ts +++ b/webui/src/app/services/schema.service.ts @@ -21,7 +21,7 @@ export class SchemaService { actionTypes: ObjectInfo[] = []; transformTypes: ObjectInfo[] = []; triggerTypes: ObjectInfo[] = []; - protocolTypes: ObjectInfo[] = []; + messageTypes: ObjectInfo[] = []; errorPaths: string[] = []; @@ -123,26 +123,26 @@ export class SchemaService { this.actionTypes = []; this.transformTypes = []; this.triggerTypes = []; - this.protocolTypes = []; + this.messageTypes = []; this.ajv.addSchema(schema); this.populateActionTypes(); this.populateTransformTypes(); this.populateTriggerTypes(); - this.populateProtocolTypes(); + this.populateMessageTypes(); } - populateProtocolTypes() { + populateMessageTypes() { if (this.schema?.properties) { - const protocolKeys = Object.keys(this.schema.properties); - protocolKeys.forEach((protocolKey) => { - const protocolSchema = this.schema?.properties[protocolKey]; - if (protocolSchema) { - this.protocolTypes.push({ - name: protocolSchema.title, - type: protocolKey, - schema: this.schema?.properties[protocolKey], + const messageTypeKeys = Object.keys(this.schema.properties); + messageTypeKeys.forEach((messageTypeKey) => { + const messageTypeSchema = this.schema?.properties[messageTypeKey]; + if (messageTypeSchema) { + this.messageTypes.push({ + name: messageTypeSchema.title, + type: messageTypeKey, + schema: this.schema?.properties[messageTypeKey], }); } }); @@ -233,13 +233,13 @@ export class SchemaService { return undefined; } - getSchemaForProtocol(protocolType: string) { + getSchemaForMessageType(messageType: string) { if (this.schema) { const schemaProperties = this.schema.properties; if (schemaProperties) { - const protocolSchema = schemaProperties[protocolType]; + const messageTypeSchema = schemaProperties[messageType]; - return protocolSchema; + return messageTypeSchema; } } else { console.error('schema is null'); @@ -523,16 +523,16 @@ export class SchemaService { return undefined; } - getTriggerTypesForProtocol(protocolType: string): ObjectInfo[] { + getTriggerTypesForMessageType(messageType: string): ObjectInfo[] { const types: ObjectInfo[] = []; if (!this.schema) { return types; } - if (this.schema.properties[protocolType]) { - const protocolTypeSchema = this.schema.properties[protocolType]; - if (protocolTypeSchema?.properties?.triggers?.items?.oneOf) { - const validTriggerRefs = protocolTypeSchema.properties.triggers.items.oneOf; + if (this.schema.properties[messageType]) { + const messageTypeSchema = this.getSchemaForMessageType(messageType); + if (messageTypeSchema?.properties?.triggers?.items?.oneOf) { + const validTriggerRefs = messageTypeSchema.properties.triggers.items.oneOf; validTriggerRefs .map((triggerRef: any) => triggerRef['$ref']) .forEach((triggerRef: string) => { From 4314fc4f319d2aed5f96a1153346b26d6d946e72 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Wed, 30 Oct 2024 18:02:24 -0500 Subject: [PATCH 2/3] update docs --- README.md | 3 +-- docs/src/content/docs/reference/messages.md | 6 +++--- docs/src/content/docs/showbridge/overview.md | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0c0149bd..0e8b0652 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ Simple protocol router _/s_
### Supported Protocols -- HTTP -- WebSocket +- HTTP & WebSocket - OSC (via UDP and TCP) - UDP - TCP diff --git a/docs/src/content/docs/reference/messages.md b/docs/src/content/docs/reference/messages.md index 248614b5..9e86ffa4 100644 --- a/docs/src/content/docs/reference/messages.md +++ b/docs/src/content/docs/reference/messages.md @@ -10,6 +10,8 @@ For templating purposes (any param starting with an underscore `_`) the incoming - baseUrl: express.js req.baseUrl - path: express.js req.path - body: express.js req.body +## **websocket** + - payload: ws message content (if this is JSON it will be parsed into an object) ## **midi** - port: the name of the midi port that the message came in on - status: midi status i.e. note_on, note_off, program_change, control_change, etc. @@ -37,6 +39,4 @@ For templating purposes (any param starting with an underscore `_`) the incoming - string: string representation of the TCP packet ## **udp** - bytes: UInt8Array of the UDP packet - - string: string representation of the UDP packet -## **websocket** - - payload: ws message content (if this is JSON it will be parsed into an object) \ No newline at end of file + - string: string representation of the UDP packet \ No newline at end of file diff --git a/docs/src/content/docs/showbridge/overview.md b/docs/src/content/docs/showbridge/overview.md index 294f0202..302f5ae1 100644 --- a/docs/src/content/docs/showbridge/overview.md +++ b/docs/src/content/docs/showbridge/overview.md @@ -7,8 +7,7 @@ sidebar: showbridge is a kind of re-imagining of [OSCulator](https://osculator.net/) taken way too far. ### Supported Protocols -- HTTP -- WebSocket +- HTTP & WebSocket - incoming websocket connections only - OSC (via UDP and TCP) - UDP From 193ea0acecdde3f14fdf9da576016c9b0c26a96e Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Wed, 30 Oct 2024 18:06:53 -0500 Subject: [PATCH 3/3] sync docs package-lock --- docs/package-lock.json | 473 ++++------------------------------------- 1 file changed, 45 insertions(+), 428 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index f8c39333..d82f08f8 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -227,9 +227,8 @@ }, "node_modules/@babel/code-frame": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", - "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", @@ -241,18 +240,16 @@ }, "node_modules/@babel/compat-data": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz", - "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -288,9 +285,8 @@ }, "node_modules/@babel/generator": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz", - "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.26.0", "@babel/types": "^7.26.0", @@ -315,9 +311,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", @@ -331,18 +326,16 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-module-imports": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" @@ -353,9 +346,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9", @@ -378,36 +370,32 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.25.9", "@babel/types": "^7.26.0" @@ -418,9 +406,8 @@ }, "node_modules/@babel/parser": { "version": "7.26.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz", - "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.26.0" }, @@ -476,9 +463,8 @@ }, "node_modules/@babel/template": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.9", "@babel/parser": "^7.25.9", @@ -490,9 +476,8 @@ }, "node_modules/@babel/traverse": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.9", "@babel/generator": "^7.25.9", @@ -508,9 +493,8 @@ }, "node_modules/@babel/types": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" @@ -575,94 +559,13 @@ "dev": true, "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-x64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -671,278 +574,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@expressive-code/core": { "version": "0.35.6", "dev": true, @@ -1455,9 +1086,8 @@ }, "node_modules/acorn": { "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1581,9 +1211,8 @@ }, "node_modules/astro": { "version": "4.16.7", - "resolved": "https://registry.npmjs.org/astro/-/astro-4.16.7.tgz", - "integrity": "sha512-nON+8MUEkWTFwXbS4zsQIq4t0Fs42eulM4x236AL+qNnWfqNAOOqAnFxO1dxfJ1q+XopIBbbT9Mtev+0zH47PQ==", "dev": true, + "license": "MIT", "dependencies": { "@astrojs/compiler": "^2.10.3", "@astrojs/internal-helpers": "0.4.1", @@ -1791,8 +1420,6 @@ }, "node_modules/browserslist": { "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -1808,6 +1435,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -1834,8 +1462,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001673", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", - "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==", "dev": true, "funding": [ { @@ -1850,7 +1476,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/ccount": { "version": "2.0.1", @@ -2276,9 +1903,8 @@ }, "node_modules/electron-to-chromium": { "version": "1.5.47", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", - "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/emmet": { "version": "2.4.11", @@ -2318,10 +1944,9 @@ }, "node_modules/esbuild": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -3244,9 +2869,8 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -3405,18 +3029,16 @@ }, "node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/magic-string": { "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -4554,9 +4176,8 @@ }, "node_modules/node-releases": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/not": { "version": "0.1.0", @@ -4907,9 +4528,8 @@ }, "node_modules/prettier": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "bin": { @@ -5603,9 +5223,8 @@ }, "node_modules/tinyexec": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", - "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -5638,9 +5257,8 @@ }, "node_modules/tsconfck": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.4.tgz", - "integrity": "sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==", "dev": true, + "license": "MIT", "bin": { "tsconfck": "bin/tsconfck.js" }, @@ -5843,8 +5461,6 @@ }, "node_modules/update-browserslist-db": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -5860,6 +5476,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.0" @@ -5917,9 +5534,8 @@ }, "node_modules/vite": { "version": "5.4.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", - "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -5976,9 +5592,12 @@ }, "node_modules/vitefu": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.3.tgz", - "integrity": "sha512-iKKfOMBHob2WxEJbqbJjHAkmYgvFDPhuqrO82om83S8RLk+17FtyMBfcyeH8GqD0ihShtkMW/zzJgiA51hCNCQ==", "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*" + ], "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0-beta.0" }, @@ -6291,9 +5910,8 @@ }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "2.6.0", @@ -6331,9 +5949,8 @@ }, "node_modules/yaml-language-server/node_modules/prettier": { "version": "2.8.7", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", - "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true, + "license": "MIT", "optional": true, "bin": { "prettier": "bin-prettier.js"