Rework actions to be loaded dynamically

This commit is contained in:
Tom Wiesing 2023-11-08 10:29:09 +01:00
parent e49f89d4ee
commit 08ab7b4383
No known key found for this signature in database
22 changed files with 934 additions and 81 deletions

View file

@ -2,91 +2,43 @@ package socket
import (
"context"
"encoding/json"
"fmt"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/provision"
"github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
func (sockets *Sockets) Actions() ActionMap {
return map[string]Action{
// generic actions
"backup": sockets.Generic(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, sockets *Sockets, in io.Reader, out io.Writer, params ...string) error {
return sockets.dependencies.Exporter.MakeExport(
ctx,
out,
exporter.ExportTask{
Dest: "",
Instance: nil,
actions := make(ActionMap, len(sockets.dependencies.Actions)+len(sockets.dependencies.IActions))
StagingOnly: false,
},
)
}),
"provision": sockets.Generic(scopes.ScopeUserAdmin, "", 1, func(ctx context.Context, sockets *Sockets, in io.Reader, out io.Writer, params ...string) error {
// read the flags of the instance to be provisioned
var flags provision.Flags
if err := json.Unmarshal([]byte(params[0]), &flags); err != nil {
return err
// setup basic actions
for _, a := range sockets.dependencies.Actions {
a := a
meta := a.Action()
actions[meta.Name] = Action{
NumParams: meta.NumParams,
Scope: meta.Scope,
ScopeParam: meta.ScopeParam,
Handle: a.Act,
}
}
instance, err := sockets.dependencies.Provision.Provision(
out,
ctx,
flags,
)
// setup instance actions
for _, a := range sockets.dependencies.IActions {
a := a
meta := a.Action()
actions[meta.Name] = Action{
NumParams: meta.NumParams + 1,
Scope: meta.Scope,
ScopeParam: meta.ScopeParam,
Handle: func(ctx context.Context, in io.Reader, out io.Writer, params ...string) error {
instance, err := sockets.dependencies.Instances.WissKI(ctx, params[0])
if err != nil {
return err
}
fmt.Fprintf(out, "URL: %s\n", instance.URL().String())
fmt.Fprintf(out, "Username: %s\n", instance.DrupalUsername)
fmt.Fprintf(out, "Password: %s\n", instance.DrupalPassword)
return nil
}),
// instance-specific actions!
"snapshot": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, socket *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return socket.dependencies.Exporter.MakeExport(
ctx,
out,
exporter.ExportTask{
Dest: "",
Instance: instance,
StagingOnly: false,
return a.Act(ctx, instance, in, out, params[1:]...)
},
)
}),
"rebuild": sockets.Instance(scopes.ScopeUserAdmin, "", 1, func(ctx context.Context, _ *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
// read the flags of the instance to be provisioned
var system models.System
if err := json.Unmarshal([]byte(params[0]), &system); err != nil {
return err
}
return instance.SystemManager().Apply(ctx, out, system, true)
}),
"update": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, _ *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Composer().Update(ctx, out)
}),
"cron": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, _ *Sockets, instance *wisski.WissKI, in io.Reader, str io.Writer, params ...string) error {
return instance.Drush().Cron(ctx, str)
}),
"start": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, _ *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Barrel().Stack().Up(ctx, out)
}),
"stop": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, _ *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Barrel().Stack().Down(ctx, out)
}),
"purge": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, sockets *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return sockets.dependencies.Purger.Purge(ctx, out, instance.Slug)
}),
}
return actions
}

View file

@ -0,0 +1,38 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
// Routeable is a component that is servable
type WebsocketAction interface {
component.Component
Action() Action
Act(ctx context.Context, in io.Reader, out io.Writer, params ...string) error
}
type WebsocketInstanceAction interface {
component.Component
Action() InstanceAction
Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error
}
// Action represents information about an action
type Action struct {
Name string
Scope scopes.Scope
ScopeParam string
NumParams int
}
type InstanceAction struct {
Action
}

View file

@ -0,0 +1,42 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter"
)
type Backup struct {
component.Base
dependencies struct {
Exporter *exporter.Exporter
}
}
var (
_ WebsocketAction = (*Backup)(nil)
)
func (*Backup) Action() Action {
return Action{
Name: "backup",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
}
}
func (b *Backup) Act(ctx context.Context, in io.Reader, out io.Writer, params ...string) error {
return b.dependencies.Exporter.MakeExport(
ctx,
out,
exporter.ExportTask{
Dest: "",
Instance: nil,
StagingOnly: false,
},
)
}

View file

@ -0,0 +1,32 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Cron struct {
component.Base
}
var (
_ WebsocketInstanceAction = (*Cron)(nil)
)
func (*Cron) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "cron",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
},
}
}
func (c *Cron) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Drush().Cron(ctx, out)
}

View file

@ -0,0 +1,54 @@
package actions
import (
"context"
"encoding/json"
"fmt"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/provision"
)
type Provision struct {
component.Base
dependencies struct {
Provision *provision.Provision
}
}
var (
_ WebsocketAction = (*Provision)(nil)
)
func (*Provision) Action() Action {
return Action{
Name: "provision",
Scope: scopes.ScopeUserAdmin,
NumParams: 1,
}
}
func (p *Provision) Act(ctx context.Context, in io.Reader, out io.Writer, params ...string) error {
// read the flags of the instance to be provisioned
var flags provision.Flags
if err := json.Unmarshal([]byte(params[0]), &flags); err != nil {
return err
}
instance, err := p.dependencies.Provision.Provision(
out,
ctx,
flags,
)
if err != nil {
return err
}
fmt.Fprintf(out, "URL: %s\n", instance.URL().String())
fmt.Fprintf(out, "Username: %s\n", instance.DrupalUsername)
fmt.Fprintf(out, "Password: %s\n", instance.DrupalPassword)
return nil
}

View file

@ -0,0 +1,36 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances/purger"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Purge struct {
component.Base
dependencies struct {
Purger *purger.Purger
}
}
var (
_ WebsocketInstanceAction = (*Stop)(nil)
)
func (*Purge) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "purge",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
},
}
}
func (p *Purge) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return p.dependencies.Purger.Purge(ctx, out, instance.Slug)
}

View file

@ -0,0 +1,39 @@
package actions
import (
"context"
"encoding/json"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Rebuild struct {
component.Base
}
var (
_ WebsocketInstanceAction = (*Rebuild)(nil)
)
func (*Rebuild) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "rebuild",
Scope: scopes.ScopeUserAdmin,
NumParams: 1,
},
}
}
func (r *Rebuild) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
// read the flags of the instance to be provisioned
var system models.System
if err := json.Unmarshal([]byte(params[0]), &system); err != nil {
return err
}
return instance.SystemManager().Apply(ctx, out, system, true)
}

View file

@ -0,0 +1,45 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Snapshot struct {
component.Base
dependencies struct {
Exporter *exporter.Exporter
}
}
var (
_ WebsocketInstanceAction = (*Snapshot)(nil)
)
func (*Snapshot) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "snapshot",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
},
}
}
func (s *Snapshot) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return s.dependencies.Exporter.MakeExport(
ctx,
out,
exporter.ExportTask{
Dest: "",
Instance: instance,
StagingOnly: false,
},
)
}

View file

@ -0,0 +1,32 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Start struct {
component.Base
}
var (
_ WebsocketInstanceAction = (*Start)(nil)
)
func (*Start) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "start",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
},
}
}
func (*Start) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Barrel().Stack().Up(ctx, out)
}

View file

@ -0,0 +1,32 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Stop struct {
component.Base
}
var (
_ WebsocketInstanceAction = (*Stop)(nil)
)
func (*Stop) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "stop",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
},
}
}
func (*Stop) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Barrel().Stack().Down(ctx, out)
}

View file

@ -0,0 +1,32 @@
package actions
import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/scopes"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
)
type Update struct {
component.Base
}
var (
_ WebsocketInstanceAction = (*Update)(nil)
)
func (*Update) Action() InstanceAction {
return InstanceAction{
Action: Action{
Name: "update",
Scope: scopes.ScopeUserAdmin,
NumParams: 0,
},
}
}
func (u *Update) Act(ctx context.Context, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
return instance.Composer().Update(ctx, out)
}

View file

@ -12,6 +12,7 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances/purger"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/provision"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/admin/socket/actions"
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
"github.com/rs/zerolog"
"github.com/tkw1536/pkglib/httpx"
@ -24,6 +25,9 @@ type Sockets struct {
actions lazy.Lazy[ActionMap]
dependencies struct {
Actions []actions.WebsocketAction
IActions []actions.WebsocketInstanceAction
Provision *provision.Provision
Instances *instances.Instances
Exporter *exporter.Exporter

View file

@ -0,0 +1 @@
package component

View file

@ -27,6 +27,7 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/admin"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/admin/socket"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/admin/socket/actions"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/cron"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/home"
@ -209,7 +210,6 @@ func (dis *Distillery) allComponents(context *lifetime.RegisterContext[component
resolver.RefreshInterval = time.Minute
})
lifetime.Place[*admin.Admin](context) // TODO: Remove analytics
lifetime.Place[*socket.Sockets](context)
lifetime.Place[*legal.Legal](context)
lifetime.Place[*news.News](context)
@ -217,6 +217,18 @@ func (dis *Distillery) allComponents(context *lifetime.RegisterContext[component
lifetime.Place[*logo.Logo](context)
lifetime.Place[*templating.Templating](context)
// Websockets
lifetime.Place[*socket.Sockets](context)
lifetime.Place[*actions.Backup](context)
lifetime.Place[*actions.Provision](context)
lifetime.Place[*actions.Snapshot](context)
lifetime.Place[*actions.Rebuild](context)
lifetime.Place[*actions.Update](context)
lifetime.Place[*actions.Cron](context)
lifetime.Place[*actions.Start](context)
lifetime.Place[*actions.Stop](context)
lifetime.Place[*actions.Purge](context)
// Cron
lifetime.Place[*cron.Cron](context)

5
utils/README.md Normal file
View file

@ -0,0 +1,5 @@
This folder contains utility code used for testing and maintaing the distillery.
None of this is used by the distillery itself.
Currently these are:
- `wsclient`: A client for the websocket API, written in typescript.

View file

@ -0,0 +1,83 @@
import type { WebSocketCall } from ".";
/** Backup backups everything */
export function Backup(): WebSocketCall {
return {
'call': 'backup',
'params': [],
}
}
type ProvisionParams = {
Slug: string;
Flavor?: "Drupal 10" | "Drupal 9",
System: SystemParams
}
type SystemParams = {
PHP: "Default (8.1)" | "8.0" | "8.1" | "8.2",
OpCacheDevelopment: boolean,
ContentSecurityPolicy: string,
}
/** Provision provisions a new instance */
export function Provision(params: ProvisionParams): WebSocketCall {
return {
'call': 'provision',
'params': [
JSON.stringify(params)
],
}
}
/** Snapshot makes a snapshot of an instance */
export function Snapshot(Slug: string): WebSocketCall {
return {
'call': 'snapshot',
'params': [Slug],
}
}
/** Rebuild rebuilds an instance */
export function Rebuild(Slug: string, params: SystemParams): WebSocketCall {
return {
'call': 'rebuild',
'params': [
Slug,
JSON.stringify(params)
],
}
}
/** Update updates a specific instance */
export function Update(Slug: string): WebSocketCall {
return {
'call': 'update',
'params': [Slug],
}
}
/** Start starts a specific instance */
export function Start(Slug: string): WebSocketCall {
return {
'call': 'start',
'params': [Slug],
}
}
/** Stop stops a specific instance */
export function Stop(Slug: string): WebSocketCall {
return {
'call': 'stop',
'params': [Slug],
}
}
/** Purge purges a specific instance */
export function Purge(Slug: string): WebSocketCall {
return {
'call': 'purge',
'params': [Slug],
}
}

View file

@ -0,0 +1,71 @@
/** @file implements the websocket protocol used by the distillery */
import WebSocket from "ws";
/** A call to the websocket endpoint */
export interface WebSocketCall {
call: string;
params: string[];
}
/** the result of a websocket call */
export interface WebSocketResult {
success: boolean,
message: string,
}
/** optional hooks to call when something happens */
export interface Hooks {
beforeCall: (call: WebSocketCall) => void; // called right before sending the request
afterCall: (call: WebSocketCall, result: WebSocketResult) => void; // called when the socket is closed
onError: (call: WebSocketCall, error: any) => void; // called when an error occurs before rejecting the promise
onLogLine: (call: WebSocketCall, line: string) => void; // called when a log line is received
}
/** specifies a remote endpoint */
export interface Remote {
url: string; // the remote websocket url to talk to
token?: string; // optional token
}
/** run a websocket remote call */
export default async function Call(remote: Remote, call: WebSocketCall, hooks?: Partial<Hooks>): Promise<WebSocketResult> {
return new Promise((resolve, reject) => {
let options = { headers: {} };
if (remote.token) {
options.headers = { 'Authorization': 'Bearer ' + remote.token };
}
const ws = new WebSocket(remote.url, options);
let result = {'success': false, 'message': 'Unknown error'};
ws.on('error', (err) => {
if (hooks && hooks.onError) {
hooks.onError(call, err);
}
reject(err)
});
ws.on('open', () => {
if (hooks && hooks.beforeCall) {
hooks.beforeCall(call);
}
ws.send(Buffer.from(JSON.stringify(call), 'utf8'));
});
ws.on('message', async (msg, isBinary) => {
if (!isBinary) {
if (hooks && hooks.onLogLine) {
hooks.onLogLine(call, msg.toString());
}
return;
}
result = JSON.parse(msg.toString());
});
ws.on('close', () => {
if (hooks && hooks.afterCall) {
hooks.afterCall(call, result);
}
resolve(result);
});
});
}

View file

@ -0,0 +1,43 @@
import Call, { Hooks } from './client'
import { Provision } from './client/calls';
const eConsole = new console.Console(process.stderr, process.stderr);
// read API KEY
const API_KEY = process.env.API_KEY;
if (!API_KEY) {
eConsole.error('API_KEY not speciied')
}
// READ ARGUMENTS
if (process.argv.length < 4) {
eConsole.error('Usage: API_KEY=$API_KEY <script> $REMOTE $SLUG');
process.exit(1);
}
const REMOTE = process.argv[2];
const SLUG = process.argv[3];
// do the call!
const result = Call(
{
url: REMOTE,
token: API_KEY,
},
Provision({
Slug: SLUG,
Flavor: "Drupal 10",
System: {
PHP: "Default (8.1)",
OpCacheDevelopment: false,
ContentSecurityPolicy: "",
}
}),
{
beforeCall: eConsole.log.bind(eConsole, 'beforeCall'),
afterCall: eConsole.log.bind(eConsole, 'afterCall'),
onError: eConsole.error.bind(eConsole, 'onError'),
onLogLine: (_, line) => process.stdout.write(line)
},
);
result.then((x) => eConsole.log(x)).catch((x) => eConsole.error(x));

View file

@ -0,0 +1,39 @@
import Call, { Hooks } from './client'
import { Provision, Rebuild } from './client/calls';
const eConsole = new console.Console(process.stderr, process.stderr);
// read API KEY
const API_KEY = process.env.API_KEY;
if (!API_KEY) {
eConsole.error('API_KEY not speciied')
}
// READ ARGUMENTS
if (process.argv.length < 4) {
eConsole.error('Usage: API_KEY=$API_KEY <script> $REMOTE $SLUG');
process.exit(1);
}
const REMOTE = process.argv[2];
const SLUG = process.argv[3];
// do the call!
const result = Call(
{
url: REMOTE,
token: API_KEY,
},
Rebuild(SLUG, {
PHP: "Default (8.1)",
OpCacheDevelopment: false,
ContentSecurityPolicy: "",
}),
{
beforeCall: eConsole.log.bind(eConsole, 'beforeCall'),
afterCall: eConsole.log.bind(eConsole, 'afterCall'),
onError: eConsole.error.bind(eConsole, 'onError'),
onLogLine: (_, line) => process.stdout.write(line)
},
);
result.then((x) => eConsole.log(x)).catch((x) => eConsole.error(x));

View file

@ -0,0 +1,16 @@
{
"name": "wsclient",
"version": "1.0.0",
"main": "index.ts",
"author": "Tom Wiesing",
"license": "AGPL",
"private": true,
"devDependencies": {
"@types/ws": "^8.5.9",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
},
"dependencies": {
"ws": "^8.14.2"
}
}

View file

@ -0,0 +1,109 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": ["node"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

136
utils/wsclient/yarn.lock Normal file
View file

@ -0,0 +1,136 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@jridgewell/resolve-uri@^3.0.3":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721"
integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@tsconfig/node10@^1.0.7":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
"@tsconfig/node12@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
"@tsconfig/node14@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
"@tsconfig/node16@^1.0.2":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
"@types/node@*":
version "20.9.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298"
integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==
dependencies:
undici-types "~5.26.4"
"@types/ws@^8.5.9":
version "8.5.9"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.9.tgz#384c489f99c83225a53f01ebc3eddf3b8e202a8c"
integrity sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==
dependencies:
"@types/node" "*"
acorn-walk@^8.1.1:
version "8.3.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f"
integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==
acorn@^8.4.1:
version "8.11.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
ts-node@^10.9.1:
version "10.9.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
dependencies:
"@cspotcode/source-map-support" "^0.8.0"
"@tsconfig/node10" "^1.0.7"
"@tsconfig/node12" "^1.0.7"
"@tsconfig/node14" "^1.0.0"
"@tsconfig/node16" "^1.0.2"
acorn "^8.4.1"
acorn-walk "^8.1.1"
arg "^4.1.0"
create-require "^1.1.0"
diff "^4.0.1"
make-error "^1.1.1"
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
typescript@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
ws@^8.14.2:
version "8.14.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==