First version
This commit is contained in:
parent
fc2efe3988
commit
fcc76b05ca
18 changed files with 264 additions and 32013 deletions
4
go.mod
4
go.mod
|
@ -3,6 +3,7 @@ module github.com/mattermost/mattermost-plugin-starter-template
|
|||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/Masterminds/squirrel v1.5.4
|
||||
github.com/mattermost/mattermost/server/public v0.0.14
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
|
@ -22,6 +23,8 @@ require (
|
|||
github.com/hashicorp/go-hclog v1.6.2 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 // indirect
|
||||
|
@ -35,6 +38,7 @@ require (
|
|||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/tinylib/msgp v1.1.9 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
|
|
12
go.sum
12
go.sum
|
@ -8,6 +8,8 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1
|
|||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
|
@ -86,6 +88,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
|
@ -160,11 +166,16 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1l
|
|||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
|
||||
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
|
@ -225,6 +236,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "com.mattermost.plugin-starter-template",
|
||||
"name": "Plugin Starter Template",
|
||||
"description": "This plugin serves as a starting point for writing a Mattermost plugin.",
|
||||
"id": "fawkes",
|
||||
"name": "Fawkes",
|
||||
"description": "This plugin shows instance information useful for debugging.",
|
||||
"homepage_url": "https://github.com/mattermost/mattermost-plugin-starter-template",
|
||||
"support_url": "https://github.com/mattermost/mattermost-plugin-starter-template/issues",
|
||||
"icon_path": "assets/starter-template-icon.svg",
|
||||
|
@ -15,9 +15,6 @@
|
|||
"windows-amd64": "server/dist/plugin-windows-amd64.exe"
|
||||
}
|
||||
},
|
||||
"webapp": {
|
||||
"bundle_path": "webapp/dist/main.js"
|
||||
},
|
||||
"settings_schema": {
|
||||
"header": "",
|
||||
"footer": "",
|
||||
|
|
248
server/plugin.go
248
server/plugin.go
|
@ -1,11 +1,15 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
|
||||
)
|
||||
|
||||
// Plugin implements the interface expected by the Mattermost server to communicate between the server and plugin processes.
|
||||
|
@ -18,11 +22,249 @@ type Plugin struct {
|
|||
// configuration is the active plugin configuration. Consult getConfiguration and
|
||||
// setConfiguration for usage.
|
||||
configuration *configuration
|
||||
|
||||
apiClient *pluginapi.Client
|
||||
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// ServeHTTP demonstrates a plugin that handles HTTP requests by greeting the world.
|
||||
func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Hello, world!")
|
||||
// func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||
// fmt.Fprint(w, "Hello, world!")
|
||||
// }
|
||||
|
||||
func (p *Plugin) Q() sq.StatementBuilderType {
|
||||
return sq.StatementBuilder.PlaceholderFormat(sq.Dollar).RunWith(p.db)
|
||||
}
|
||||
|
||||
func (p *Plugin) OnActivate() error {
|
||||
p.apiClient = pluginapi.NewClient(p.API, p.Driver)
|
||||
|
||||
db, dbErr := p.apiClient.Store.GetMasterDB()
|
||||
if dbErr != nil {
|
||||
return dbErr
|
||||
}
|
||||
p.db = db
|
||||
|
||||
if err := p.API.UnregisterCommand("", "fawkes"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
autocompleteData := model.NewAutocompleteData("fawkes", "[command]", "Gets information about the msteams current state")
|
||||
|
||||
whitelistedCmd := model.NewAutocompleteData("count-whitelisted", "", "Counts the amount of whitelisted users in msteamssync_whitelisted_users")
|
||||
// adds the from arg?
|
||||
autocompleteData.AddCommand(whitelistedCmd)
|
||||
|
||||
lastConnectAtCmd := model.NewAutocompleteData("count-lastconnectat", "", "Counts the amount of users with a lastconnectat value != 0 in msteamssync_whitelisted_users")
|
||||
autocompleteData.AddCommand(lastConnectAtCmd)
|
||||
|
||||
lastDisconnectAtCmd := model.NewAutocompleteData("count-lastdisconnectat", "", "Counts the amount of users with a lastdisconnectat value != 0 in msteamssync_whitelisted_users")
|
||||
autocompleteData.AddCommand(lastDisconnectAtCmd)
|
||||
|
||||
userInfoCmd := model.NewAutocompleteData("user-info", "[username|email]", "Returns information about the user state regarding msteams")
|
||||
autocompleteData.AddCommand(userInfoCmd)
|
||||
|
||||
channelInfoCmd := model.NewAutocompleteData("channel-info", "[channelID]", "Returns information about the channel state regarding msteams")
|
||||
autocompleteData.AddCommand(channelInfoCmd)
|
||||
|
||||
listInvitesCmd := model.NewAutocompleteData("list-invites", "", "List the current invites")
|
||||
autocompleteData.AddCommand(listInvitesCmd)
|
||||
|
||||
removeInviteCmd := model.NewAutocompleteData("remove-invite", "[mmUserID]", "Deletes the invite for the user ID")
|
||||
autocompleteData.AddCommand(removeInviteCmd)
|
||||
|
||||
cmd := &model.Command{
|
||||
Trigger: "fawkes",
|
||||
AutoComplete: true,
|
||||
AutoCompleteDesc: "Get insights of the user state",
|
||||
AutocompleteData: autocompleteData,
|
||||
}
|
||||
|
||||
if err := p.API.RegisterCommand(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
p.API.LogDebug("plugin started")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Plugin) ExecuteCommand(_ *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
||||
split := strings.Fields(args.Command)
|
||||
command := split[0]
|
||||
var parameters []string
|
||||
action := ""
|
||||
if len(split) > 1 {
|
||||
action = split[1]
|
||||
}
|
||||
if len(split) > 2 {
|
||||
parameters = split[2:]
|
||||
}
|
||||
|
||||
if command != "/fawkes" {
|
||||
return &model.CommandResponse{}, nil
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case "count-whitelisted":
|
||||
rows, err := p.Q().Select("count(*)").From("msteamssync_whitelisted_users").Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result int
|
||||
rows.Next()
|
||||
if err := rows.Scan(&result); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("There are %d users in the msteamssync_whitelisted_users table", result), args)
|
||||
case "count-lastconnectat":
|
||||
rows, err := p.Q().Select("count(*)").From("msteamssync_users").Where(sq.NotEq{"lastconnectat": 0}).Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result int
|
||||
rows.Next()
|
||||
if err := rows.Scan(&result); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("There are %d users in the msteamssync_users table with `lastconnectat != 0`", result), args)
|
||||
case "count-lastdisconnectat":
|
||||
rows, err := p.Q().Select("count(*)").From("msteamssync_users").Where(sq.NotEq{"lastdisconnectat": 0}).Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result int
|
||||
rows.Next()
|
||||
if err := rows.Scan(&result); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("There are %d users in the msteamssync_users table with `lastdisconnectat != 0`", result), args)
|
||||
case "user-info":
|
||||
if len(parameters) != 1 {
|
||||
return p.sendEphemeralAndExit("user-info must receive one \"username\" or \"email\" parameter", args)
|
||||
}
|
||||
|
||||
email := parameters[0]
|
||||
|
||||
var user *model.User
|
||||
var appErr *model.AppError
|
||||
user, appErr = p.API.GetUserByEmail(email)
|
||||
if appErr != nil {
|
||||
user, appErr = p.API.GetUserByUsername(email)
|
||||
if appErr != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR getting the user by email and username: %s", appErr.Error()), args)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := p.Q().
|
||||
Select("msteamsuserid, token, lastconnectat, lastdisconnectat").
|
||||
From("msteamssync_users").
|
||||
Where(sq.Eq{"mmuserid": user.Id}).
|
||||
Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR querying for msteamssync user: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var mmTeamsUserID string
|
||||
var token string
|
||||
var lastConnectAt int
|
||||
var lastDisconnectAt int
|
||||
if !rows.Next() {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("User %q not found in the msteamssync_users table", email), args)
|
||||
}
|
||||
if err := rows.Scan(&mmTeamsUserID, &token, &lastConnectAt, &lastDisconnectAt); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR scanning rows: %s", err), args)
|
||||
}
|
||||
|
||||
var remoteID string
|
||||
if user.RemoteId != nil {
|
||||
remoteID = *user.RemoteId
|
||||
}
|
||||
|
||||
hasToken := false
|
||||
if token != "" {
|
||||
hasToken = true
|
||||
}
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("User %q has\n - `mmTeamsUserID`: %s\n - `hasToken`: %v\n - `lastConnectAt`: %d\n - `lastDisconnectAt`: %d\n - `remoteID`: %s", email, mmTeamsUserID, hasToken, lastConnectAt, lastDisconnectAt, remoteID), args)
|
||||
case "channel-info":
|
||||
if len(parameters) != 1 {
|
||||
return p.sendEphemeralAndExit("channel-info must receive the channel ID", args)
|
||||
}
|
||||
|
||||
channelID := parameters[0]
|
||||
|
||||
channel, appErr := p.API.GetChannel(channelID)
|
||||
if appErr != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR getting the channel: %s", appErr.Error()), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf(" - `Id`: %s\n - `name`: %s\n - `IsShared`: %v", channel.Id, channel.Name, channel.IsShared()), args)
|
||||
case "list-invites":
|
||||
rows, err := p.Q().
|
||||
Select("mmuserid, invitependingsince, invitelastsentat").
|
||||
From("msteamssync_invited_users").
|
||||
Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR querying for invited users: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
invites := []map[string]any{}
|
||||
for rows.Next() {
|
||||
var mmUserID string
|
||||
var invitePendingSince int
|
||||
var inviteLastSentAt int
|
||||
if err := rows.Scan(&mmUserID, &invitePendingSince, &inviteLastSentAt); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR scanning row: %s", err), args)
|
||||
}
|
||||
|
||||
invites = append(invites, map[string]any{
|
||||
"mmUserID": mmUserID,
|
||||
"invitePendingSince": invitePendingSince,
|
||||
"inviteLastSentAt": inviteLastSentAt,
|
||||
})
|
||||
}
|
||||
|
||||
message := "Invite list:\n"
|
||||
for _, invite := range invites {
|
||||
message += fmt.Sprintf(
|
||||
" - `mmUserID`: %s :: `invitePendingSince`: %d :: `inviteLastSentAt`: %d\n",
|
||||
invite["mmUserID"],
|
||||
invite["invitePendingSince"],
|
||||
invite["inviteLastSentAt"],
|
||||
)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(message, args)
|
||||
case "delete-invite":
|
||||
return p.sendEphemeralAndExit("Not implemented yet", args)
|
||||
default:
|
||||
p.sendEphemeral(fmt.Sprintf("Invalid command %q", action), args)
|
||||
return &model.CommandResponse{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Plugin) sendEphemeral(message string, args *model.CommandArgs) {
|
||||
_ = p.API.SendEphemeralPost(args.UserId, &model.Post{
|
||||
Message: message,
|
||||
UserId: args.UserId,
|
||||
ChannelId: args.ChannelId,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Plugin) sendEphemeralAndExit(message string, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
||||
p.sendEphemeral(message, args)
|
||||
return &model.CommandResponse{}, nil
|
||||
}
|
||||
|
||||
// See https://developers.mattermost.com/extend/plugins/server/reference/
|
||||
|
|
|
@ -1,681 +0,0 @@
|
|||
{
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"typescript": {
|
||||
"project": "./tsconfig.json"
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
"version": "16.14.0"
|
||||
}
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"plugin:jest/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"jest",
|
||||
"react",
|
||||
"import",
|
||||
"babel",
|
||||
"cypress",
|
||||
"no-only-tests",
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true,
|
||||
"impliedStrict": true,
|
||||
"modules": true,
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jquery": true,
|
||||
"es6": true,
|
||||
"jest": true
|
||||
},
|
||||
"rules": {
|
||||
"array-bracket-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"array-callback-return": 2,
|
||||
"arrow-body-style": 0,
|
||||
"arrow-parens": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"arrow-spacing": [
|
||||
2,
|
||||
{
|
||||
"before": true,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"block-scoped-var": 2,
|
||||
"brace-style": [
|
||||
2,
|
||||
"1tbs",
|
||||
{
|
||||
"allowSingleLine": false
|
||||
}
|
||||
],
|
||||
"capitalized-comments": 0,
|
||||
"class-methods-use-this": 0,
|
||||
"comma-dangle": [
|
||||
2,
|
||||
"always-multiline"
|
||||
],
|
||||
"comma-spacing": [
|
||||
2,
|
||||
{
|
||||
"before": false,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"comma-style": [
|
||||
2,
|
||||
"last"
|
||||
],
|
||||
"complexity": [
|
||||
0,
|
||||
10
|
||||
],
|
||||
"computed-property-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"consistent-return": 2,
|
||||
"consistent-this": [
|
||||
2,
|
||||
"self"
|
||||
],
|
||||
"constructor-super": 2,
|
||||
"curly": [
|
||||
2,
|
||||
"all"
|
||||
],
|
||||
"dot-location": [
|
||||
2,
|
||||
"object"
|
||||
],
|
||||
"dot-notation": 2,
|
||||
"eqeqeq": [
|
||||
2,
|
||||
"smart"
|
||||
],
|
||||
"func-call-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"func-name-matching": 0,
|
||||
"func-names": 2,
|
||||
"func-style": [
|
||||
2,
|
||||
"declaration",
|
||||
{
|
||||
"allowArrowFunctions": true
|
||||
}
|
||||
],
|
||||
"generator-star-spacing": [
|
||||
2,
|
||||
{
|
||||
"before": false,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"global-require": 2,
|
||||
"guard-for-in": 2,
|
||||
"id-blacklist": 0,
|
||||
"import/no-unresolved": 2,
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"newlines-between": "always-and-inside-groups",
|
||||
"groups": [
|
||||
"builtin",
|
||||
"external",
|
||||
[
|
||||
"internal",
|
||||
"parent"
|
||||
],
|
||||
"sibling",
|
||||
"index"
|
||||
]
|
||||
}
|
||||
],
|
||||
"indent": [
|
||||
2,
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 0
|
||||
}
|
||||
],
|
||||
"jsx-quotes": [
|
||||
2,
|
||||
"prefer-single"
|
||||
],
|
||||
"key-spacing": [
|
||||
2,
|
||||
{
|
||||
"beforeColon": false,
|
||||
"afterColon": true,
|
||||
"mode": "strict"
|
||||
}
|
||||
],
|
||||
"keyword-spacing": [
|
||||
2,
|
||||
{
|
||||
"before": true,
|
||||
"after": true,
|
||||
"overrides": {}
|
||||
}
|
||||
],
|
||||
"line-comment-position": 0,
|
||||
"linebreak-style": 2,
|
||||
"lines-around-comment": [
|
||||
2,
|
||||
{
|
||||
"beforeBlockComment": true,
|
||||
"beforeLineComment": true,
|
||||
"allowBlockStart": true,
|
||||
"allowBlockEnd": true
|
||||
}
|
||||
],
|
||||
"max-lines": [
|
||||
1,
|
||||
{
|
||||
"max": 450,
|
||||
"skipBlankLines": true,
|
||||
"skipComments": false
|
||||
}
|
||||
],
|
||||
"max-nested-callbacks": [
|
||||
2,
|
||||
{
|
||||
"max": 2
|
||||
}
|
||||
],
|
||||
"max-statements-per-line": [
|
||||
2,
|
||||
{
|
||||
"max": 1
|
||||
}
|
||||
],
|
||||
"multiline-ternary": [
|
||||
1,
|
||||
"never"
|
||||
],
|
||||
"new-cap": 2,
|
||||
"new-parens": 2,
|
||||
"newline-before-return": 0,
|
||||
"newline-per-chained-call": 0,
|
||||
"no-alert": 2,
|
||||
"no-array-constructor": 2,
|
||||
"no-await-in-loop": 2,
|
||||
"no-caller": 2,
|
||||
"no-case-declarations": 2,
|
||||
"no-class-assign": 2,
|
||||
"no-compare-neg-zero": 2,
|
||||
"no-cond-assign": [
|
||||
2,
|
||||
"except-parens"
|
||||
],
|
||||
"no-confusing-arrow": 2,
|
||||
"no-console": 2,
|
||||
"no-const-assign": 2,
|
||||
"no-constant-condition": 2,
|
||||
"no-debugger": 2,
|
||||
"no-div-regex": 2,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-class-members": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-duplicate-imports": [
|
||||
2,
|
||||
{
|
||||
"includeExports": true
|
||||
}
|
||||
],
|
||||
"no-else-return": 2,
|
||||
"no-empty": 2,
|
||||
"no-empty-function": 2,
|
||||
"no-empty-pattern": 2,
|
||||
"no-eval": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-extra-label": 2,
|
||||
"no-extra-parens": 0,
|
||||
"no-extra-semi": 2,
|
||||
"no-fallthrough": 2,
|
||||
"no-floating-decimal": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-global-assign": 2,
|
||||
"no-implicit-coercion": 2,
|
||||
"no-implicit-globals": 0,
|
||||
"no-implied-eval": 2,
|
||||
"no-inner-declarations": 0,
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 2,
|
||||
"no-lonely-if": 2,
|
||||
"no-loop-func": 2,
|
||||
"no-magic-numbers": [
|
||||
0,
|
||||
{
|
||||
"ignore": [
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
"enforceConst": true,
|
||||
"detectObjects": true
|
||||
}
|
||||
],
|
||||
"no-mixed-operators": [
|
||||
2,
|
||||
{
|
||||
"allowSamePrecedence": false
|
||||
}
|
||||
],
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"no-multi-assign": 2,
|
||||
"no-multi-spaces": [
|
||||
2,
|
||||
{
|
||||
"exceptions": {
|
||||
"Property": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"no-multi-str": 0,
|
||||
"no-multiple-empty-lines": [
|
||||
2,
|
||||
{
|
||||
"max": 1
|
||||
}
|
||||
],
|
||||
"no-native-reassign": 2,
|
||||
"no-negated-condition": 2,
|
||||
"no-nested-ternary": 2,
|
||||
"no-new": 2,
|
||||
"no-new-func": 2,
|
||||
"no-new-object": 2,
|
||||
"no-new-symbol": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-octal-escape": 2,
|
||||
"no-param-reassign": 2,
|
||||
"no-process-env": 2,
|
||||
"no-process-exit": 2,
|
||||
"no-proto": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-return-assign": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"no-return-await": 2,
|
||||
"no-script-url": 2,
|
||||
"no-self-assign": [
|
||||
2,
|
||||
{
|
||||
"props": true
|
||||
}
|
||||
],
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": [
|
||||
2,
|
||||
{
|
||||
"hoist": "functions"
|
||||
}
|
||||
],
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-spaced-func": 2,
|
||||
"no-tabs": 0,
|
||||
"no-template-curly-in-string": 2,
|
||||
"no-ternary": 0,
|
||||
"no-this-before-super": 2,
|
||||
"no-throw-literal": 2,
|
||||
"no-trailing-spaces": [
|
||||
2,
|
||||
{
|
||||
"skipBlankLines": false
|
||||
}
|
||||
],
|
||||
"no-undef-init": 2,
|
||||
"no-undefined": 2,
|
||||
"no-underscore-dangle": 2,
|
||||
"no-unexpected-multiline": 2,
|
||||
"no-unmodified-loop-condition": 2,
|
||||
"no-unneeded-ternary": [
|
||||
2,
|
||||
{
|
||||
"defaultAssignment": false
|
||||
}
|
||||
],
|
||||
"no-unreachable": 2,
|
||||
"no-unsafe-finally": 2,
|
||||
"no-unsafe-negation": 2,
|
||||
"no-unused-expressions": 2,
|
||||
"no-unused-vars": [
|
||||
2,
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "after-used"
|
||||
}
|
||||
],
|
||||
"no-use-before-define": [
|
||||
2,
|
||||
{
|
||||
"classes": false,
|
||||
"functions": false,
|
||||
"variables": false
|
||||
}
|
||||
],
|
||||
"no-useless-computed-key": 2,
|
||||
"no-useless-concat": 2,
|
||||
"no-useless-constructor": 2,
|
||||
"no-useless-escape": 2,
|
||||
"no-useless-rename": 2,
|
||||
"no-useless-return": 2,
|
||||
"no-var": 0,
|
||||
"no-void": 2,
|
||||
"no-warning-comments": 1,
|
||||
"no-whitespace-before-property": 2,
|
||||
"no-with": 2,
|
||||
"object-curly-newline": 0,
|
||||
"object-curly-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"object-property-newline": [
|
||||
2,
|
||||
{
|
||||
"allowMultiplePropertiesPerLine": true
|
||||
}
|
||||
],
|
||||
"object-shorthand": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"one-var": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"one-var-declaration-per-line": 0,
|
||||
"operator-assignment": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"operator-linebreak": [
|
||||
2,
|
||||
"after"
|
||||
],
|
||||
"padded-blocks": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"prefer-arrow-callback": 2,
|
||||
"prefer-const": 2,
|
||||
"prefer-destructuring": 0,
|
||||
"prefer-numeric-literals": 2,
|
||||
"prefer-promise-reject-errors": 2,
|
||||
"prefer-rest-params": 2,
|
||||
"prefer-spread": 2,
|
||||
"prefer-template": 0,
|
||||
"quote-props": [
|
||||
2,
|
||||
"as-needed"
|
||||
],
|
||||
"quotes": [
|
||||
2,
|
||||
"single",
|
||||
"avoid-escape"
|
||||
],
|
||||
"radix": 2,
|
||||
"react/display-name": [
|
||||
0,
|
||||
{
|
||||
"ignoreTranspilerName": false
|
||||
}
|
||||
],
|
||||
"react/forbid-component-props": 0,
|
||||
"react/forbid-elements": [
|
||||
2,
|
||||
{
|
||||
"forbid": [
|
||||
"embed"
|
||||
]
|
||||
}
|
||||
],
|
||||
"react/jsx-boolean-value": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"react/jsx-closing-bracket-location": [
|
||||
2,
|
||||
{
|
||||
"location": "tag-aligned"
|
||||
}
|
||||
],
|
||||
"react/jsx-curly-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"react/jsx-equals-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"react/jsx-filename-extension": 2,
|
||||
"react/jsx-first-prop-new-line": [
|
||||
2,
|
||||
"multiline"
|
||||
],
|
||||
"react/jsx-handler-names": 0,
|
||||
"react/jsx-indent": [
|
||||
2,
|
||||
4
|
||||
],
|
||||
"react/jsx-indent-props": [
|
||||
2,
|
||||
4
|
||||
],
|
||||
"react/jsx-key": 2,
|
||||
"react/jsx-max-props-per-line": [
|
||||
2,
|
||||
{
|
||||
"maximum": 1
|
||||
}
|
||||
],
|
||||
"react/jsx-no-bind": 0,
|
||||
"react/jsx-no-comment-textnodes": 2,
|
||||
"react/jsx-no-duplicate-props": [
|
||||
2,
|
||||
{
|
||||
"ignoreCase": false
|
||||
}
|
||||
],
|
||||
"react/jsx-no-literals": 2,
|
||||
"react/jsx-no-target-blank": 2,
|
||||
"react/jsx-no-undef": 2,
|
||||
"react/jsx-pascal-case": 2,
|
||||
"react/jsx-tag-spacing": [
|
||||
2,
|
||||
{
|
||||
"closingSlash": "never",
|
||||
"beforeSelfClosing": "never",
|
||||
"afterOpening": "never"
|
||||
}
|
||||
],
|
||||
"react/jsx-uses-react": 2,
|
||||
"react/jsx-uses-vars": 2,
|
||||
"react/jsx-wrap-multilines": 2,
|
||||
"react/no-array-index-key": 1,
|
||||
"react/no-children-prop": 2,
|
||||
"react/no-danger": 0,
|
||||
"react/no-danger-with-children": 2,
|
||||
"react/no-deprecated": 1,
|
||||
"react/no-did-mount-set-state": 2,
|
||||
"react/no-did-update-set-state": 2,
|
||||
"react/no-direct-mutation-state": 2,
|
||||
"react/no-find-dom-node": 1,
|
||||
"react/no-is-mounted": 2,
|
||||
"react/no-multi-comp": [
|
||||
2,
|
||||
{
|
||||
"ignoreStateless": true
|
||||
}
|
||||
],
|
||||
"react/no-render-return-value": 2,
|
||||
"react/no-set-state": 0,
|
||||
"react/no-string-refs": 0,
|
||||
"react/no-unescaped-entities": 2,
|
||||
"react/no-unknown-property": 2,
|
||||
"react/no-unused-prop-types": [
|
||||
1,
|
||||
{
|
||||
"skipShapeProps": true
|
||||
}
|
||||
],
|
||||
"react/prefer-es6-class": 2,
|
||||
"react/prefer-stateless-function": 2,
|
||||
"react/prop-types": [
|
||||
2,
|
||||
{
|
||||
"ignore": [
|
||||
"location",
|
||||
"history",
|
||||
"component"
|
||||
]
|
||||
}
|
||||
],
|
||||
"react/require-default-props": 0,
|
||||
"react/require-optimization": 1,
|
||||
"react/require-render-return": 2,
|
||||
"react/self-closing-comp": 2,
|
||||
"react/sort-comp": 0,
|
||||
"react/style-prop-object": 2,
|
||||
"require-yield": 2,
|
||||
"rest-spread-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"semi-spacing": [
|
||||
2,
|
||||
{
|
||||
"before": false,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"sort-imports": 0,
|
||||
"sort-keys": 0,
|
||||
"space-before-blocks": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"space-before-function-paren": [
|
||||
2,
|
||||
{
|
||||
"anonymous": "never",
|
||||
"named": "never",
|
||||
"asyncArrow": "always"
|
||||
}
|
||||
],
|
||||
"space-in-parens": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"space-infix-ops": 2,
|
||||
"space-unary-ops": [
|
||||
2,
|
||||
{
|
||||
"words": true,
|
||||
"nonwords": false
|
||||
}
|
||||
],
|
||||
"symbol-description": 2,
|
||||
"template-curly-spacing": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"valid-typeof": [
|
||||
2,
|
||||
{
|
||||
"requireStringLiterals": false
|
||||
}
|
||||
],
|
||||
"vars-on-top": 0,
|
||||
"wrap-iife": [
|
||||
2,
|
||||
"outside"
|
||||
],
|
||||
"wrap-regex": 2,
|
||||
"yoda": [
|
||||
2,
|
||||
"never",
|
||||
{
|
||||
"exceptRange": false,
|
||||
"onlyEquality": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/*.tsx",
|
||||
"**/*.ts"
|
||||
],
|
||||
"extends": "plugin:@typescript-eslint/recommended",
|
||||
"rules": {
|
||||
"@typescript-eslint/ban-ts-ignore": 0,
|
||||
"@typescript-eslint/ban-types": 1,
|
||||
"@typescript-eslint/ban-ts-comment": 0,
|
||||
"@typescript-eslint/no-var-requires": 0,
|
||||
"@typescript-eslint/prefer-interface": 0,
|
||||
"@typescript-eslint/explicit-function-return-type": 0,
|
||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||
"@typescript-eslint/indent": [
|
||||
2,
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 0
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-use-before-define": [
|
||||
2,
|
||||
{
|
||||
"classes": false,
|
||||
"functions": false,
|
||||
"variables": false
|
||||
}
|
||||
],
|
||||
"react/jsx-filename-extension": [
|
||||
1,
|
||||
{
|
||||
"extensions": [
|
||||
".jsx",
|
||||
".tsx"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
3
webapp/.gitignore
vendored
3
webapp/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
.eslintcache
|
||||
junit.xml
|
||||
node_modules
|
|
@ -1 +0,0 @@
|
|||
save-exact=true
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
const config = {
|
||||
presets: [
|
||||
['@babel/preset-env', {
|
||||
targets: {
|
||||
chrome: 66,
|
||||
firefox: 60,
|
||||
edge: 42,
|
||||
safari: 12,
|
||||
},
|
||||
modules: false,
|
||||
corejs: 3,
|
||||
debug: false,
|
||||
useBuiltIns: 'usage',
|
||||
shippedProposals: true,
|
||||
}],
|
||||
['@babel/preset-react', {
|
||||
useBuiltIns: true,
|
||||
}],
|
||||
['@babel/typescript', {
|
||||
allExtensions: true,
|
||||
isTSX: true,
|
||||
}],
|
||||
['@emotion/babel-preset-css-prop'],
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/proposal-object-rest-spread',
|
||||
'@babel/plugin-proposal-optional-chaining',
|
||||
'babel-plugin-typescript-to-proptypes',
|
||||
],
|
||||
};
|
||||
|
||||
// Jest needs module transformation
|
||||
config.env = {
|
||||
test: {
|
||||
presets: config.presets,
|
||||
plugins: config.plugins,
|
||||
},
|
||||
};
|
||||
config.env.test.presets[0][1].modules = 'auto';
|
||||
|
||||
module.exports = config;
|
|
@ -1 +0,0 @@
|
|||
{}
|
30965
webapp/package-lock.json
generated
30965
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,126 +0,0 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack --mode=production",
|
||||
"build:watch": "webpack --mode=production --watch",
|
||||
"debug": "webpack --mode=none",
|
||||
"debug:watch": "webpack --mode=development --watch",
|
||||
"lint": "eslint --ignore-pattern node_modules --ignore-pattern dist --ext .js --ext .jsx --ext tsx --ext ts . --quiet --cache",
|
||||
"fix": "eslint --ignore-pattern node_modules --ignore-pattern dist --ext .js --ext .jsx --ext tsx --ext ts . --quiet --fix --cache",
|
||||
"test": "jest --forceExit --detectOpenHandles --verbose",
|
||||
"test:watch": "jest --watch",
|
||||
"test-ci": "jest --forceExit --detectOpenHandles --maxWorkers=2",
|
||||
"check-types": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.16.8",
|
||||
"@babel/core": "7.16.12",
|
||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.16.7",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@babel/preset-react": "7.16.7",
|
||||
"@babel/preset-typescript": "7.16.7",
|
||||
"@babel/runtime": "7.16.7",
|
||||
"@emotion/babel-preset-css-prop": "11.2.0",
|
||||
"@emotion/core": "10.3.1",
|
||||
"@mattermost/types": "6.7.0-0",
|
||||
"@testing-library/jest-dom": "5.16.1",
|
||||
"@types/babel__core": "7.1.18",
|
||||
"@types/babel__template": "7.4.1",
|
||||
"@types/enzyme": "3.10.11",
|
||||
"@types/jest": "27.4.0",
|
||||
"@types/node": "17.0.12",
|
||||
"@types/react": "16.14.26",
|
||||
"@types/react-dom": "17.0.11",
|
||||
"@types/react-redux": "7.1.22",
|
||||
"@types/react-router-dom": "5.1.5",
|
||||
"@types/react-transition-group": "4.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.10.1",
|
||||
"@typescript-eslint/parser": "5.10.1",
|
||||
"@typescript-eslint/typescript-estree": "5.52.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-loader": "8.2.2",
|
||||
"babel-plugin-formatjs": "10.3.7",
|
||||
"babel-plugin-typescript-to-proptypes": "2.0.0",
|
||||
"css-loader": "6.5.1",
|
||||
"enzyme": "3.11.0",
|
||||
"enzyme-adapter-react-16": "1.15.6",
|
||||
"enzyme-to-json": "3.6.2",
|
||||
"eslint": "8.8.0",
|
||||
"eslint-import-resolver-alias": "1.1.2",
|
||||
"eslint-import-resolver-typescript": "2.7.1",
|
||||
"eslint-import-resolver-webpack": "0.13.2",
|
||||
"eslint-plugin-babel": "5.3.1",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-jest": "26.5.3",
|
||||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost",
|
||||
"eslint-plugin-no-only-tests": "2.6.0",
|
||||
"eslint-plugin-react": "7.28.0",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"file-loader": "6.2.0",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"isomorphic-fetch": "3.0.0",
|
||||
"jest": "27.4.7",
|
||||
"jest-canvas-mock": "2.3.1",
|
||||
"jest-junit": "13.0.0",
|
||||
"sass": "1.52.3",
|
||||
"sass-loader": "13.0.0",
|
||||
"style-loader": "3.3.1",
|
||||
"webpack": "5.75.0",
|
||||
"webpack-cli": "5.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "3.22.8",
|
||||
"mattermost-redux": "5.33.1",
|
||||
"react": "^16.14.0",
|
||||
"react-redux": "8.0.2",
|
||||
"redux": "4.2.0",
|
||||
"typescript": "4.6.4"
|
||||
},
|
||||
"jest": {
|
||||
"snapshotSerializers": [
|
||||
"<rootDir>/node_modules/enzyme-to-json/serializer"
|
||||
],
|
||||
"testPathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"/non_npm_dependencies/"
|
||||
],
|
||||
"clearMocks": true,
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.{js,jsx}"
|
||||
],
|
||||
"coverageReporters": [
|
||||
"lcov",
|
||||
"text-summary"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "identity-obj-proxy",
|
||||
"^.+\\.(css|less|scss)$": "identity-obj-proxy",
|
||||
"^.*i18n.*\\.(json)$": "<rootDir>/tests/i18n_mock.json",
|
||||
"^bundle-loader\\?lazy\\!(.*)$": "$1"
|
||||
},
|
||||
"moduleDirectories": [
|
||||
"",
|
||||
"node_modules",
|
||||
"non_npm_dependencies"
|
||||
],
|
||||
"reporters": [
|
||||
"default",
|
||||
"jest-junit"
|
||||
],
|
||||
"transformIgnorePatterns": [
|
||||
"node_modules/(?!react-native|react-router|mattermost-webapp)"
|
||||
],
|
||||
"setupFiles": [
|
||||
"jest-canvas-mock"
|
||||
],
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/tests/setup.tsx"
|
||||
],
|
||||
"testURL": "http://localhost:8065"
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import {Store, Action} from 'redux';
|
||||
|
||||
import {GlobalState} from '@mattermost/types/lib/store';
|
||||
|
||||
import manifest from '@/manifest';
|
||||
|
||||
import {PluginRegistry} from '@/types/mattermost-webapp';
|
||||
|
||||
export default class Plugin {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
||||
public async initialize(registry: PluginRegistry, store: Store<GlobalState, Action<Record<string, unknown>>>) {
|
||||
// @see https://developers.mattermost.com/extend/plugins/webapp/reference/
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
registerPlugin(pluginId: string, plugin: Plugin): void
|
||||
}
|
||||
}
|
||||
|
||||
window.registerPlugin(manifest.id, new Plugin());
|
|
@ -1,7 +0,0 @@
|
|||
import manifest from './manifest';
|
||||
|
||||
test('Plugin manifest, id and version are defined', () => {
|
||||
expect(manifest).toBeDefined();
|
||||
expect(manifest.id).toBeDefined();
|
||||
expect(manifest.version).toBeDefined();
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
export interface PluginRegistry {
|
||||
registerPostTypeComponent(typeName: string, component: React.ElementType)
|
||||
|
||||
// Add more if needed from https://developers.mattermost.com/extend/plugins/webapp/reference
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{}
|
|
@ -1,6 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// import '@mattermost/webapp/tests/setup';
|
||||
|
||||
export {};
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
},
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"experimentalDecorators": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"tests"
|
||||
],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"node_modules",
|
||||
"!node_modules/@types"
|
||||
]
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
const exec = require('child_process').exec;
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const PLUGIN_ID = require('../plugin.json').id;
|
||||
|
||||
const NPM_TARGET = process.env.npm_lifecycle_event; //eslint-disable-line no-process-env
|
||||
const isDev = NPM_TARGET === 'debug' || NPM_TARGET === 'debug:watch';
|
||||
|
||||
const plugins = [];
|
||||
if (NPM_TARGET === 'build:watch' || NPM_TARGET === 'debug:watch') {
|
||||
plugins.push({
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.watchRun.tap('WatchStartPlugin', () => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Change detected. Rebuilding webapp.');
|
||||
});
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', () => {
|
||||
exec('cd .. && make deploy-from-watch', (err, stdout, stderr) => {
|
||||
if (stdout) {
|
||||
process.stdout.write(stdout);
|
||||
}
|
||||
if (stderr) {
|
||||
process.stderr.write(stderr);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const config = {
|
||||
entry: [
|
||||
'./src/index.tsx',
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
},
|
||||
modules: [
|
||||
'src',
|
||||
'node_modules',
|
||||
path.resolve(__dirname),
|
||||
],
|
||||
extensions: ['*', '.js', '.jsx', '.ts', '.tsx'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
|
||||
// Babel configuration is in babel.config.js because jest requires it to be there.
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(scss|css)$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sassOptions: {
|
||||
includePaths: ['node_modules/compass-mixins/lib', 'sass'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
externals: {
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM',
|
||||
redux: 'Redux',
|
||||
'react-redux': 'ReactRedux',
|
||||
'prop-types': 'PropTypes',
|
||||
'react-bootstrap': 'ReactBootstrap',
|
||||
'react-router-dom': 'ReactRouterDom',
|
||||
},
|
||||
output: {
|
||||
devtoolNamespace: PLUGIN_ID,
|
||||
path: path.join(__dirname, '/dist'),
|
||||
publicPath: '/',
|
||||
filename: 'main.js',
|
||||
},
|
||||
mode: (isDev) ? 'eval-source-map' : 'production',
|
||||
plugins,
|
||||
};
|
||||
|
||||
if (isDev) {
|
||||
Object.assign(config, {devtool: 'eval-source-map'});
|
||||
}
|
||||
|
||||
module.exports = config;
|
Loading…
Reference in a new issue