Rework actions to be loaded dynamically
This commit is contained in:
parent
e49f89d4ee
commit
08ab7b4383
22 changed files with 934 additions and 81 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
42
internal/dis/component/server/admin/socket/actions/backup.go
Normal file
42
internal/dis/component/server/admin/socket/actions/backup.go
Normal 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,
|
||||
},
|
||||
)
|
||||
}
|
||||
32
internal/dis/component/server/admin/socket/actions/cron.go
Normal file
32
internal/dis/component/server/admin/socket/actions/cron.go
Normal 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)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
36
internal/dis/component/server/admin/socket/actions/purge.go
Normal file
36
internal/dis/component/server/admin/socket/actions/purge.go
Normal 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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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,
|
||||
},
|
||||
)
|
||||
}
|
||||
32
internal/dis/component/server/admin/socket/actions/start.go
Normal file
32
internal/dis/component/server/admin/socket/actions/start.go
Normal 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)
|
||||
}
|
||||
32
internal/dis/component/server/admin/socket/actions/stop.go
Normal file
32
internal/dis/component/server/admin/socket/actions/stop.go
Normal 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)
|
||||
}
|
||||
32
internal/dis/component/server/admin/socket/actions/update.go
Normal file
32
internal/dis/component/server/admin/socket/actions/update.go
Normal 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)
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
1
internal/dis/component/ws.go
Normal file
1
internal/dis/component/ws.go
Normal file
|
|
@ -0,0 +1 @@
|
|||
package component
|
||||
|
|
@ -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
5
utils/README.md
Normal 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.
|
||||
83
utils/wsclient/client/calls.ts
Normal file
83
utils/wsclient/client/calls.ts
Normal 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],
|
||||
}
|
||||
}
|
||||
71
utils/wsclient/client/index.ts
Normal file
71
utils/wsclient/client/index.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
43
utils/wsclient/example_provision.ts
Normal file
43
utils/wsclient/example_provision.ts
Normal 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));
|
||||
39
utils/wsclient/example_rebuild.ts
Normal file
39
utils/wsclient/example_rebuild.ts
Normal 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));
|
||||
16
utils/wsclient/package.json
Normal file
16
utils/wsclient/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
109
utils/wsclient/tsconfig.json
Normal file
109
utils/wsclient/tsconfig.json
Normal 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
136
utils/wsclient/yarn.lock
Normal 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==
|
||||
Loading…
Add table
Add a link
Reference in a new issue