@quenty/chatproviderservice 9.52.2 → 9.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [9.54.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/chatproviderservice@9.53.0...@quenty/chatproviderservice@9.54.0) (2026-07-14)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **lint:** resolve selene and moonwave issues from strict conversions ([d427005](https://github.com/Quenty/NevermoreEngine/commit/d42700569ecb085fee4166c5bfdad382dd8442c2))
11
+
12
+ ### Features
13
+
14
+ - **chatproviderservice:** convert package to --!strict ([3edae04](https://github.com/Quenty/NevermoreEngine/commit/3edae04e44a9bcda2cf43367719d67fb08769fa4))
15
+
16
+ # [9.53.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/chatproviderservice@9.52.2...@quenty/chatproviderservice@9.53.0) (2026-06-24)
17
+
18
+ ### Features
19
+
20
+ - **chatproviderservice:** convert package to --!strict typing ([#718](https://github.com/Quenty/NevermoreEngine/issues/718)) ([3bfbf13](https://github.com/Quenty/NevermoreEngine/commit/3bfbf13db961a91beec8a476126a5f1dbc32b40f))
21
+
6
22
  ## [9.52.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/chatproviderservice@9.52.1...@quenty/chatproviderservice@9.52.2) (2026-06-03)
7
23
 
8
24
  **Note:** Version bump only for package @quenty/chatproviderservice
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/chatproviderservice",
3
- "version": "9.52.2",
3
+ "version": "9.54.0",
4
4
  "description": "Provide wrapper around chat system to allow tags to be set",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -30,26 +30,26 @@
30
30
  "dependencies": {
31
31
  "@quenty/attributeutils": "14.30.1",
32
32
  "@quenty/baseobject": "10.13.0",
33
- "@quenty/binder": "14.36.1",
33
+ "@quenty/binder": "14.37.0",
34
34
  "@quenty/brio": "14.30.1",
35
- "@quenty/clienttranslator": "14.37.1",
36
- "@quenty/cmdrservice": "13.45.2",
37
- "@quenty/color3utils": "11.36.1",
38
- "@quenty/datastore": "13.39.1",
35
+ "@quenty/clienttranslator": "14.38.0",
36
+ "@quenty/cmdrservice": "13.46.0",
37
+ "@quenty/color3utils": "11.37.0",
38
+ "@quenty/datastore": "13.40.0",
39
39
  "@quenty/instanceutils": "13.30.1",
40
40
  "@quenty/loader": "10.11.0",
41
- "@quenty/localizedtextutils": "12.30.1",
41
+ "@quenty/localizedtextutils": "12.31.0",
42
42
  "@quenty/maid": "3.9.0",
43
43
  "@quenty/nevermore-test-runner": "1.4.0",
44
- "@quenty/permissionprovider": "14.38.2",
45
- "@quenty/playerbinder": "14.36.1",
44
+ "@quenty/permissionprovider": "14.39.0",
45
+ "@quenty/playerbinder": "14.37.0",
46
46
  "@quenty/playerutils": "8.32.1",
47
47
  "@quenty/preferredparentutils": "4.4.2",
48
48
  "@quenty/promise": "10.18.1",
49
49
  "@quenty/remoting": "12.32.1",
50
50
  "@quenty/richtext": "1.4.2",
51
51
  "@quenty/rx": "13.28.3",
52
- "@quenty/rxbinderutils": "14.36.1",
52
+ "@quenty/rxbinderutils": "14.37.0",
53
53
  "@quenty/servicebag": "11.18.1",
54
54
  "@quenty/signal": "7.13.1",
55
55
  "@quenty/string": "3.3.7",
@@ -60,5 +60,5 @@
60
60
  "publishConfig": {
61
61
  "access": "public"
62
62
  },
63
- "gitHead": "1acafc712ce34f5dbaa70bb23b16da95e9cd3f82"
63
+ "gitHead": "13f0162f4971a77378e55e9b7236aea94f0dd3a8"
64
64
  }
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class HasChatTagsClient
4
4
  ]=]
@@ -18,8 +18,19 @@ local HasChatTagsClient = setmetatable({}, HasChatTagsBase)
18
18
  HasChatTagsClient.ClassName = "HasChatTagsClient"
19
19
  HasChatTagsClient.__index = HasChatTagsClient
20
20
 
21
- function HasChatTagsClient.new(player: Player, serviceBag: ServiceBag.ServiceBag)
22
- local self = setmetatable(HasChatTagsBase.new(player), HasChatTagsClient)
21
+ export type HasChatTagsClient =
22
+ typeof(setmetatable(
23
+ {} :: {
24
+ _serviceBag: ServiceBag.ServiceBag,
25
+ _chatTagBinder: Binder.Binder<ChatTagClient.ChatTagClient>,
26
+ _translator: typeof(ChatProviderTranslator),
27
+ },
28
+ {} :: typeof({ __index = HasChatTagsClient })
29
+ ))
30
+ & HasChatTagsBase.HasChatTagsBase
31
+
32
+ function HasChatTagsClient.new(player: Player, serviceBag: ServiceBag.ServiceBag): HasChatTagsClient
33
+ local self: HasChatTagsClient = setmetatable(HasChatTagsBase.new(player) :: any, HasChatTagsClient)
23
34
 
24
35
  self._serviceBag = assert(serviceBag, "No serviceBag")
25
36
  self._chatTagBinder = self._serviceBag:GetService(ChatTagClient)
@@ -28,11 +39,11 @@ function HasChatTagsClient.new(player: Player, serviceBag: ServiceBag.ServiceBag
28
39
  return self
29
40
  end
30
41
 
31
- function HasChatTagsClient:GetChatTagBinder()
42
+ function HasChatTagsClient.GetChatTagBinder(self: HasChatTagsClient): Binder.Binder<ChatTagClient.ChatTagClient>
32
43
  return self._chatTagBinder
33
44
  end
34
45
 
35
- function HasChatTagsClient:GetAsRichText(): string?
46
+ function HasChatTagsClient.GetAsRichText(self: HasChatTagsClient): string?
36
47
  local lastChatTags = self._lastChatTags.Value
37
48
  if not (lastChatTags and #lastChatTags > 0) then
38
49
  return nil
@@ -42,7 +53,7 @@ function HasChatTagsClient:GetAsRichText(): string?
42
53
  for index, tagData in lastChatTags do
43
54
  output = output .. string.format("<font color='%s'>", Color3Utils.toWebHexString(tagData.TagColor))
44
55
 
45
- local translatedText
56
+ local translatedText: string
46
57
  if tagData.TagLocalizedText then
47
58
  translatedText = LocalizedTextUtils.localizedTextToString(self._translator, tagData.TagLocalizedText)
48
59
  else
@@ -63,4 +74,4 @@ function HasChatTagsClient:GetAsRichText(): string?
63
74
  return output
64
75
  end
65
76
 
66
- return Binder.new("HasChatTags", HasChatTagsClient)
77
+ return Binder.new("HasChatTags", HasChatTagsClient :: any) :: Binder.Binder<HasChatTagsClient>
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class ChatProviderServiceClient
4
4
  ]=]
@@ -9,6 +9,8 @@ local HttpService = game:GetService("HttpService")
9
9
  local Players = game:GetService("Players")
10
10
  local TextChatService = game:GetService("TextChatService")
11
11
 
12
+ local Binder = require("Binder")
13
+ local HasChatTagsClient = require("HasChatTagsClient")
12
14
  local Maid = require("Maid")
13
15
  local ServiceBag = require("ServiceBag")
14
16
  local Signal = require("Signal")
@@ -18,13 +20,23 @@ local TextChannelUtils = require("TextChannelUtils")
18
20
  local ChatProviderServiceClient = {}
19
21
  ChatProviderServiceClient.ServiceName = "ChatProviderServiceClient"
20
22
 
21
- function ChatProviderServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
22
- assert(not self._serviceBag, "Already initialized")
23
+ export type ChatProviderServiceClient = typeof(setmetatable(
24
+ {} :: {
25
+ _serviceBag: ServiceBag.ServiceBag,
26
+ _maid: Maid.Maid,
27
+ MessageIncoming: Signal.Signal<TextChatMessage>,
28
+ _hasChatTagsBinder: Binder.Binder<HasChatTagsClient.HasChatTagsClient>,
29
+ },
30
+ {} :: typeof({ __index = ChatProviderServiceClient })
31
+ ))
32
+
33
+ function ChatProviderServiceClient.Init(self: ChatProviderServiceClient, serviceBag: ServiceBag.ServiceBag): ()
34
+ assert(not (self :: any)._serviceBag, "Already initialized")
23
35
  self._serviceBag = assert(serviceBag, "No serviceBag")
24
36
  self._maid = Maid.new()
25
37
 
26
38
  -- State
27
- self.MessageIncoming = self._maid:Add(Signal.new())
39
+ self.MessageIncoming = self._maid:Add((Signal.new() :: any) :: Signal.Signal<TextChatMessage>)
28
40
 
29
41
  -- External
30
42
  self._serviceBag:GetService(require("CmdrServiceClient"))
@@ -33,11 +45,11 @@ function ChatProviderServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
33
45
  self._serviceBag:GetService(require("ChatTagClient"))
34
46
  self._serviceBag:GetService(require("ChatProviderTranslator"))
35
47
  self._serviceBag:GetService(require("ChatProviderCommandServiceClient"))
36
- self._hasChatTagsBinder = self._serviceBag:GetService(require("HasChatTagsClient"))
48
+ self._hasChatTagsBinder = self._serviceBag:GetService(HasChatTagsClient)
37
49
  end
38
50
 
39
- function ChatProviderServiceClient:Start()
40
- TextChatService.OnIncomingMessage = function(textChatMessage)
51
+ function ChatProviderServiceClient.Start(self: ChatProviderServiceClient): ()
52
+ TextChatService.OnIncomingMessage = function(textChatMessage): TextChatMessageProperties?
41
53
  self.MessageIncoming:Fire(textChatMessage)
42
54
 
43
55
  local metadata = textChatMessage.Metadata
@@ -63,10 +75,10 @@ function ChatProviderServiceClient:Start()
63
75
 
64
76
  local textSource = textChatMessage.TextSource
65
77
  if not textSource then
66
- return
78
+ return nil
67
79
  end
68
80
 
69
- local tags = self:_renderTags(textSource)
81
+ local tags = ChatProviderServiceClient._renderTags(self, textSource)
70
82
  if tags then
71
83
  local properties = Instance.new("TextChatMessageProperties")
72
84
  local name = String.removePostfix(textChatMessage.PrefixText, ":")
@@ -76,7 +88,7 @@ function ChatProviderServiceClient:Start()
76
88
  return properties
77
89
  end
78
90
 
79
- return
91
+ return nil
80
92
  end
81
93
  end
82
94
 
@@ -85,11 +97,12 @@ end
85
97
  @param encodedMessageData string
86
98
  @param channel TextChannel?
87
99
  ]=]
88
- function ChatProviderServiceClient:SendSystemMessage(
100
+ function ChatProviderServiceClient.SendSystemMessage(
101
+ _self: ChatProviderServiceClient,
89
102
  message: string,
90
103
  encodedMessageData: string?,
91
104
  channel: TextChannel?
92
- )
105
+ ): ()
93
106
  assert(typeof(message) == "string", "[ChatProviderServiceClient.SendSystemMessage] - Bad message")
94
107
 
95
108
  if not channel then
@@ -104,7 +117,7 @@ function ChatProviderServiceClient:SendSystemMessage(
104
117
  channel:DisplaySystemMessage(message, encodedMessageData)
105
118
  end
106
119
 
107
- function ChatProviderServiceClient:_renderTags(textSource)
120
+ function ChatProviderServiceClient._renderTags(self: ChatProviderServiceClient, textSource: TextSource): string?
108
121
  local player = Players:GetPlayerByUserId(textSource.UserId)
109
122
  if not player then
110
123
  return nil
@@ -119,7 +132,7 @@ function ChatProviderServiceClient:_renderTags(textSource)
119
132
  return hasChatTags:GetAsRichText()
120
133
  end
121
134
 
122
- function ChatProviderServiceClient:Destroy()
135
+ function ChatProviderServiceClient.Destroy(self: ChatProviderServiceClient): ()
123
136
  self._maid:DoCleaning()
124
137
  end
125
138
 
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class ChatProviderCommandServiceClient
4
4
  ]=]
@@ -7,6 +7,8 @@ local require = require(script.Parent.loader).load(script)
7
7
 
8
8
  local Players = game:GetService("Players")
9
9
 
10
+ local Binder = require("Binder")
11
+ local ChatTagClient = require("ChatTagClient")
10
12
  local ChatTagCmdrUtils = require("ChatTagCmdrUtils")
11
13
  local Maid = require("Maid")
12
14
  local ServiceBag = require("ServiceBag")
@@ -16,17 +18,31 @@ local String = require("String")
16
18
  local ChatProviderCommandServiceClient = {}
17
19
  ChatProviderCommandServiceClient.ServiceName = "ChatProviderCommandServiceClient"
18
20
 
19
- function ChatProviderCommandServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
20
- assert(not self._serviceBag, "Already initialized")
21
+ export type ChatProviderCommandServiceClient = typeof(setmetatable(
22
+ {} :: {
23
+ _serviceBag: ServiceBag.ServiceBag,
24
+ _maid: Maid.Maid,
25
+ _cmdrService: any, -- CmdrServiceClient (nonstrict, no exported type)
26
+ _chatProviderServiceClient: any, -- require cycle with ChatProviderServiceClient
27
+ _chatTagBinder: Binder.Binder<ChatTagClient.ChatTagClient>,
28
+ },
29
+ {} :: typeof({ __index = ChatProviderCommandServiceClient })
30
+ ))
31
+
32
+ function ChatProviderCommandServiceClient.Init(
33
+ self: ChatProviderCommandServiceClient,
34
+ serviceBag: ServiceBag.ServiceBag
35
+ )
36
+ assert(not (self :: any)._serviceBag, "Already initialized")
21
37
  self._serviceBag = assert(serviceBag, "No serviceBag")
22
38
  self._maid = Maid.new()
23
39
 
24
40
  self._cmdrService = self._serviceBag:GetService(require("CmdrServiceClient"))
25
41
  self._chatProviderServiceClient = self._serviceBag:GetService((require :: any)("ChatProviderServiceClient"))
26
- self._chatTagBinder = self._serviceBag:GetService(require("ChatTagClient"))
42
+ self._chatTagBinder = self._serviceBag:GetService(ChatTagClient)
27
43
  end
28
44
 
29
- function ChatProviderCommandServiceClient:Start()
45
+ function ChatProviderCommandServiceClient.Start(self: ChatProviderCommandServiceClient)
30
46
  self._cmdrService:PromiseCmdr():Then(function(cmdr)
31
47
  ChatTagCmdrUtils.registerChatTagKeys(cmdr, self)
32
48
 
@@ -34,7 +50,7 @@ function ChatProviderCommandServiceClient:Start()
34
50
  end)
35
51
  end
36
52
 
37
- function ChatProviderCommandServiceClient:_registerChatCommand(cmdr)
53
+ function ChatProviderCommandServiceClient._registerChatCommand(self: ChatProviderCommandServiceClient, cmdr: any)
38
54
  self._maid:GiveTask(self._chatProviderServiceClient.MessageIncoming:Connect(function(textChatMessage)
39
55
  if not (textChatMessage.TextSource and textChatMessage.TextSource.UserId == Players.LocalPlayer.UserId) then
40
56
  return
@@ -46,8 +62,8 @@ function ChatProviderCommandServiceClient:_registerChatCommand(cmdr)
46
62
  end))
47
63
  end
48
64
 
49
- function ChatProviderCommandServiceClient:GetChatTagKeyList()
50
- local tagSet = {}
65
+ function ChatProviderCommandServiceClient.GetChatTagKeyList(self: ChatProviderCommandServiceClient)
66
+ local tagSet: { [any]: boolean } = {}
51
67
  for chatTag, _ in pairs(self._chatTagBinder:GetAllSet()) do
52
68
  local tagKey = chatTag.ChatTagKey.Value
53
69
  tagSet[tagKey] = true
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class ChatTag
4
4
  ]=]
@@ -13,8 +13,18 @@ local ChatTag = setmetatable({}, ChatTagBase)
13
13
  ChatTag.ClassName = "ChatTag"
14
14
  ChatTag.__index = ChatTag
15
15
 
16
- function ChatTag.new(folder: Folder, serviceBag: ServiceBag.ServiceBag)
17
- local self = setmetatable(ChatTagBase.new(folder), ChatTag)
16
+ export type ChatTag =
17
+ typeof(setmetatable(
18
+ {} :: {
19
+ _serviceBag: ServiceBag.ServiceBag,
20
+ _playerDataStoreService: any, -- PlayerDataStoreService (GetService returns the module type, not the instance type)
21
+ },
22
+ {} :: typeof({ __index = ChatTag })
23
+ ))
24
+ & ChatTagBase.ChatTagBase
25
+
26
+ function ChatTag.new(folder: Folder, serviceBag: ServiceBag.ServiceBag): ChatTag
27
+ local self: ChatTag = setmetatable(ChatTagBase.new(folder) :: any, ChatTag)
18
28
 
19
29
  self._serviceBag = assert(serviceBag, "No serviceBag")
20
30
  self._playerDataStoreService = self._serviceBag:GetService(require("PlayerDataStoreService"))
@@ -24,18 +34,18 @@ function ChatTag.new(folder: Folder, serviceBag: ServiceBag.ServiceBag)
24
34
  return self
25
35
  end
26
36
 
27
- function ChatTag:_getPlayer(): Player
28
- return self._obj:FindFirstAncestorWhichIsA("Player")
37
+ function ChatTag._getPlayer(self: ChatTag): Player?
38
+ return self._obj:FindFirstAncestorWhichIsA("Player") :: Player?
29
39
  end
30
40
 
31
- function ChatTag:_loadData()
41
+ function ChatTag._loadData(self: ChatTag)
32
42
  local player = self:_getPlayer()
33
43
  if not player then
34
44
  return
35
45
  end
36
46
 
37
47
  local tagKey = self.ChatTagKey.Value
38
- if not tagKey then
48
+ if tagKey == "" then
39
49
  return
40
50
  end
41
51
 
@@ -53,4 +63,4 @@ function ChatTag:_loadData()
53
63
  end)
54
64
  end
55
65
 
56
- return Binder.new("ChatTag", ChatTag)
66
+ return Binder.new("ChatTag", ChatTag :: any) :: Binder.Binder<ChatTag>
@@ -1,11 +1,13 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class HasChatTags
4
4
  ]=]
5
5
 
6
6
  local require = require(script.Parent.loader).load(script)
7
7
 
8
+ local Binder = require("Binder")
8
9
  local BinderUtils = require("BinderUtils")
10
+ local ChatTag = require("ChatTag")
9
11
  local ChatTagConstants = require("ChatTagConstants")
10
12
  local ChatTagDataUtils = require("ChatTagDataUtils")
11
13
  local HasChatTagsBase = require("HasChatTagsBase")
@@ -22,8 +24,10 @@ HasChatTags.__index = HasChatTags
22
24
  export type HasChatTags =
23
25
  typeof(setmetatable(
24
26
  {} :: {
27
+ _serviceBag: ServiceBag.ServiceBag,
28
+ _chatProviderService: any, -- require cycle with ChatProviderService
25
29
  _chatTagsContainer: Folder,
26
- _chatTagBinder: any,
30
+ _chatTagBinder: Binder.Binder<ChatTag.ChatTag>,
27
31
  },
28
32
  {} :: typeof({ __index = HasChatTags })
29
33
  ))
@@ -34,7 +38,7 @@ function HasChatTags.new(player: Player, serviceBag: ServiceBag.ServiceBag): Has
34
38
 
35
39
  self._serviceBag = assert(serviceBag, "No serviceBag")
36
40
  self._chatProviderService = self._serviceBag:GetService((require :: any)("ChatProviderService"))
37
- self._chatTagBinder = self._serviceBag:GetService(require("ChatTag"))
41
+ self._chatTagBinder = self._serviceBag:GetService(ChatTag)
38
42
 
39
43
  self._chatTagsContainer = Instance.new("Folder")
40
44
  self._chatTagsContainer.Name = HasChatTagsConstants.TAG_CONTAINER_NAME
@@ -50,7 +54,7 @@ function HasChatTags.new(player: Player, serviceBag: ServiceBag.ServiceBag): Has
50
54
  return self
51
55
  end
52
56
 
53
- function HasChatTags:GetChatTagBinder()
57
+ function HasChatTags.GetChatTagBinder(self: HasChatTags): Binder.Binder<ChatTag.ChatTag>
54
58
  return self._chatTagBinder
55
59
  end
56
60
 
@@ -58,8 +62,9 @@ end
58
62
  Adds chat tags to the player
59
63
 
60
64
  @param chatTagData ChatTagData
65
+ @return Instance
61
66
  ]=]
62
- function HasChatTags:AddChatTag(chatTagData: ChatTagDataUtils.ChatTagData)
67
+ function HasChatTags.AddChatTag(self: HasChatTags, chatTagData: ChatTagDataUtils.ChatTagData): Instance
63
68
  assert(ChatTagDataUtils.isChatTagData(chatTagData), "Bad chatTagData")
64
69
 
65
70
  local tag = self._chatTagBinder:Create("Folder")
@@ -81,12 +86,13 @@ function HasChatTags:AddChatTag(chatTagData: ChatTagDataUtils.ChatTagData)
81
86
  return tag
82
87
  end
83
88
 
84
- function HasChatTags:GetChatTagByKey(chatTagKey: string): ChatTagDataUtils.ChatTagData?
89
+ function HasChatTags.GetChatTagByKey(self: HasChatTags, chatTagKey: string): ChatTag.ChatTag?
85
90
  assert(type(chatTagKey) == "string", "Bad chatTagKey")
86
91
 
87
92
  for _, item in BinderUtils.getChildren(self._chatTagBinder, self._chatTagsContainer) do
88
93
  if item.ChatTagKey.Value == chatTagKey then
89
- return item
94
+ -- cast dodges an old-solver recursive-type blowup on ChatTagData; value is already ChatTag.ChatTag
95
+ return item :: any
90
96
  end
91
97
  end
92
98
 
@@ -96,7 +102,7 @@ end
96
102
  --[=[
97
103
  Removes all chat tags from the player
98
104
  ]=]
99
- function HasChatTags:ClearTags()
105
+ function HasChatTags.ClearTags(self: HasChatTags)
100
106
  for _, item in self._chatTagsContainer:GetChildren() do
101
107
  if self._chatTagBinder:Get(item) then
102
108
  item:Destroy()
@@ -104,4 +110,4 @@ function HasChatTags:ClearTags()
104
110
  end
105
111
  end
106
112
 
107
- return PlayerBinder.new("HasChatTags", HasChatTags)
113
+ return PlayerBinder.new("HasChatTags", HasChatTags :: any) :: Binder.Binder<HasChatTags>
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  Wrapper around Roblox chat service on the server
4
4
  @class ChatProviderService
@@ -9,8 +9,10 @@ local require = require(script.Parent.loader).load(script)
9
9
  local ServerScriptService = game:GetService("ServerScriptService")
10
10
  local TextChatService = game:GetService("TextChatService")
11
11
 
12
+ local Binder = require("Binder")
12
13
  local Brio = require("Brio")
13
14
  local ChatTagDataUtils = require("ChatTagDataUtils")
15
+ local HasChatTags = require("HasChatTags")
14
16
  local LocalizedTextUtils = require("LocalizedTextUtils")
15
17
  local Maid = require("Maid")
16
18
  local Observable = require("Observable")
@@ -25,7 +27,19 @@ local Signal = require("Signal")
25
27
  local ChatProviderService = {}
26
28
  ChatProviderService.ServiceName = "ChatProviderService"
27
29
 
28
- function ChatProviderService:Init(serviceBag: ServiceBag.ServiceBag)
30
+ export type ChatProviderService = typeof(setmetatable(
31
+ {} :: {
32
+ _serviceBag: ServiceBag.ServiceBag,
33
+ _maid: Maid.Maid,
34
+ MessageIncoming: Signal.Signal<any>,
35
+ _hasChatTagsBinder: Binder.Binder<HasChatTags.HasChatTags>,
36
+ _chatService: any, -- legacy ChatServiceRunner.ChatService (untyped)
37
+ _chatServicePromise: any, -- Promise.Promise<any>
38
+ },
39
+ {} :: typeof({ __index = ChatProviderService })
40
+ ))
41
+
42
+ function ChatProviderService.Init(self: ChatProviderService, serviceBag: ServiceBag.ServiceBag)
29
43
  self._serviceBag = assert(serviceBag, "No serviceBag")
30
44
  self._maid = Maid.new()
31
45
 
@@ -43,25 +57,25 @@ function ChatProviderService:Init(serviceBag: ServiceBag.ServiceBag)
43
57
 
44
58
  -- Binders
45
59
  self._serviceBag:GetService(require("ChatTag"))
46
- self._hasChatTagsBinder = self._serviceBag:GetService(require("HasChatTags"))
60
+ self._hasChatTagsBinder = self._serviceBag:GetService(HasChatTags)
47
61
 
48
62
  -- note: normally we don't expose default API surfaces like this with defaults, however, because this only affects developers and this
49
63
  -- tends to significantly improve feedback we're leaving this default configuration in place.
50
64
  self:SetDeveloperTag(ChatTagDataUtils.createChatTagData({
51
65
  TagText = "(dev)",
52
- LocalizedText = LocalizedTextUtils.create("chatTags.dev"),
66
+ TagLocalizedText = LocalizedTextUtils.create("chatTags.dev"),
53
67
  TagPriority = 15,
54
68
  TagColor = Color3.fromRGB(245, 163, 27),
55
69
  }))
56
70
  self:SetAdminTag(ChatTagDataUtils.createChatTagData({
57
71
  TagText = "(mod)",
58
- LocalizedText = LocalizedTextUtils.create("chatTags.mod"),
72
+ TagLocalizedText = LocalizedTextUtils.create("chatTags.mod"),
59
73
  TagPriority = 10,
60
74
  TagColor = Color3.fromRGB(78, 205, 196),
61
75
  }))
62
76
  end
63
77
 
64
- function ChatProviderService:AddChatCommand(textChatCommand: TextChatCommand)
78
+ function ChatProviderService.AddChatCommand(_self: ChatProviderService, textChatCommand: TextChatCommand)
65
79
  assert(typeof(textChatCommand) == "Instance", "Bad textChatCommand")
66
80
 
67
81
  textChatCommand.Parent = PreferredParentUtils.getPreferredParent(TextChatService, "ChatProviderCommands")
@@ -73,11 +87,11 @@ end
73
87
  @param chatTagData ChatTagData?
74
88
  @return Maid
75
89
  ]=]
76
- function ChatProviderService:SetDeveloperTag(chatTagData: ChatTagDataUtils.ChatTagData)
90
+ function ChatProviderService.SetDeveloperTag(self: ChatProviderService, chatTagData: ChatTagDataUtils.ChatTagData?)
77
91
  assert(ChatTagDataUtils.isChatTagData(chatTagData) or chatTagData == nil, "Bad chatTagData")
78
92
 
79
93
  if chatTagData then
80
- local permissionService = self._serviceBag:GetService(require("PermissionService"))
94
+ local permissionService: any = self._serviceBag:GetService(require("PermissionService"))
81
95
  local observeBrio = permissionService:ObservePermissionedPlayersBrio(PermissionLevel.CREATOR)
82
96
 
83
97
  self._maid._developer = self:_addObservablePlayerTag(observeBrio, chatTagData)
@@ -92,24 +106,24 @@ end
92
106
  @param chatTagData ChatTagData?
93
107
  @return Maid
94
108
  ]=]
95
- function ChatProviderService:SetAdminTag(chatTagData: ChatTagDataUtils.ChatTagData?)
109
+ function ChatProviderService.SetAdminTag(self: ChatProviderService, chatTagData: ChatTagDataUtils.ChatTagData?)
96
110
  assert(ChatTagDataUtils.isChatTagData(chatTagData) or chatTagData == nil, "Bad chatTagData")
97
111
 
98
112
  if chatTagData then
99
- local permissionService = self._serviceBag:GetService(require("PermissionService"))
113
+ local permissionService: any = self._serviceBag:GetService(require("PermissionService"))
100
114
  local observeBrio = permissionService:ObservePermissionedPlayersBrio(PermissionLevel.ADMIN):Pipe({
101
115
  RxBrioUtils.flatMapBrio(function(player: Player)
102
116
  return Rx.fromPromise(permissionService:PromiseIsPermissionLevel(player, PermissionLevel.CREATOR))
103
117
  :Pipe({
104
- Rx.switchMap(function(isAlsoCreator)
118
+ Rx.switchMap(function(isAlsoCreator): any
105
119
  if not isAlsoCreator then
106
120
  return Rx.of(player)
107
121
  else
108
122
  return Rx.EMPTY
109
123
  end
110
- end),
124
+ end) :: any,
111
125
  })
112
- end),
126
+ end) :: any,
113
127
  })
114
128
 
115
129
  self._maid._admin = self:_addObservablePlayerTag(observeBrio, chatTagData)
@@ -118,10 +132,11 @@ function ChatProviderService:SetAdminTag(chatTagData: ChatTagDataUtils.ChatTagDa
118
132
  end
119
133
  end
120
134
 
121
- function ChatProviderService:_addObservablePlayerTag(
135
+ function ChatProviderService._addObservablePlayerTag(
136
+ self: ChatProviderService,
122
137
  observePlayersBrio: Observable.Observable<Brio.Brio<Player>>,
123
138
  chatTagData: ChatTagDataUtils.ChatTagData
124
- )
139
+ ): Maid.Maid
125
140
  assert(ChatTagDataUtils.isChatTagData(chatTagData), "Bad chatTagData")
126
141
 
127
142
  local topMaid = Maid.new()
@@ -153,14 +168,15 @@ end
153
168
  @param chatTagData ChatTagData
154
169
  @return Promise<Instance>
155
170
  ]=]
156
- function ChatProviderService:PromiseAddChatTag(
171
+ function ChatProviderService.PromiseAddChatTag(
172
+ self: ChatProviderService,
157
173
  player: Player,
158
174
  chatTagData: ChatTagDataUtils.ChatTagData
159
175
  ): Promise.Promise<Instance>
160
176
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
161
177
  assert(ChatTagDataUtils.isChatTagData(chatTagData), "Bad chatTagData")
162
178
 
163
- local hasChatTagBinder = self._serviceBag:GetService(require("HasChatTags"))
179
+ local hasChatTagBinder = self._serviceBag:GetService(HasChatTags)
164
180
 
165
181
  return hasChatTagBinder:Promise(player):Then(function(hasChatTag)
166
182
  return hasChatTag:AddChatTag(chatTagData)
@@ -172,10 +188,10 @@ end
172
188
 
173
189
  @param player Player
174
190
  ]=]
175
- function ChatProviderService:ClearChatTags(player: Player)
191
+ function ChatProviderService.ClearChatTags(self: ChatProviderService, player: Player)
176
192
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
177
193
 
178
- local hasChatTagBinder = self._serviceBag:GetService(require("HasChatTags"))
194
+ local hasChatTagBinder = self._serviceBag:GetService(HasChatTags)
179
195
  local hasChatTags = hasChatTagBinder:Get(player)
180
196
 
181
197
  if hasChatTags then
@@ -190,7 +206,8 @@ end
190
206
  @param chatTagDataList { ChatTagData }
191
207
  @return Promise
192
208
  ]=]
193
- function ChatProviderService:PromiseSetSpeakerTags(
209
+ function ChatProviderService.PromiseSetSpeakerTags(
210
+ self: ChatProviderService,
194
211
  speakerName: string,
195
212
  chatTagDataList: { ChatTagDataUtils.ChatTagData }
196
213
  ): Promise.Promise<()>
@@ -208,7 +225,7 @@ function ChatProviderService:PromiseSetSpeakerTags(
208
225
  end)
209
226
  end
210
227
 
211
- function ChatProviderService:_getChatServiceAsync()
228
+ function ChatProviderService._getChatServiceAsync(self: ChatProviderService): any
212
229
  if self._chatService then
213
230
  return self._chatService
214
231
  end
@@ -219,13 +236,13 @@ function ChatProviderService:_getChatServiceAsync()
219
236
  return nil
220
237
  end
221
238
 
222
- local chatService = require(chatServiceRunner:WaitForChild("ChatService"))
239
+ local chatService = (require :: any)(chatServiceRunner:WaitForChild("ChatService"))
223
240
  self._chatService = chatService or error("No chatService retrieved")
224
241
 
225
242
  return self._chatService
226
243
  end
227
244
 
228
- function ChatProviderService:_promiseChatService(): Promise.Promise<any>
245
+ function ChatProviderService._promiseChatService(self: ChatProviderService): Promise.Promise<any>
229
246
  if self._chatService then
230
247
  return Promise.resolved(self._chatService)
231
248
  end
@@ -241,7 +258,7 @@ function ChatProviderService:_promiseChatService(): Promise.Promise<any>
241
258
  return Promise.resolved(self._chatServicePromise)
242
259
  end
243
260
 
244
- function ChatProviderService:_promiseSpeaker(speakerName: string)
261
+ function ChatProviderService._promiseSpeaker(self: ChatProviderService, speakerName: string): Promise.Promise<any>
245
262
  assert(type(speakerName) == "string", "Bad speakerName")
246
263
 
247
264
  return self:_promiseChatService():Then(function(chatService)
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class ChatProviderCommandService
4
4
  ]=]
@@ -7,8 +7,11 @@ local require = require(script.Parent.loader).load(script)
7
7
 
8
8
  local Players = game:GetService("Players")
9
9
 
10
+ local Binder = require("Binder")
11
+ local ChatTag = require("ChatTag")
10
12
  local ChatTagCmdrUtils = require("ChatTagCmdrUtils")
11
13
  local ChatTagDataUtils = require("ChatTagDataUtils")
14
+ local HasChatTags = require("HasChatTags")
12
15
  local Maid = require("Maid")
13
16
  local PlayerUtils = require("PlayerUtils")
14
17
  local ServiceBag = require("ServiceBag")
@@ -17,8 +20,22 @@ local Set = require("Set")
17
20
  local ChatProviderCommandService = {}
18
21
  ChatProviderCommandService.ServiceName = "ChatProviderCommandService"
19
22
 
20
- function ChatProviderCommandService:Init(serviceBag: ServiceBag.ServiceBag)
21
- assert(not self._serviceBag, "Already initialized")
23
+ export type ChatProviderCommandService = typeof(setmetatable(
24
+ {} :: {
25
+ _serviceBag: ServiceBag.ServiceBag,
26
+ _maid: Maid.Maid,
27
+ _cmdrService: any, -- CmdrService (GetService returns the module type, not the instance type)
28
+ _permissionService: any, -- PermissionService (GetService returns the module type, not the instance type)
29
+ _chatProviderService: any, -- require cycle with ChatProviderService
30
+ _chatTagBinder: Binder.Binder<ChatTag.ChatTag>,
31
+ _hasChatTagsBinder: Binder.Binder<HasChatTags.HasChatTags>,
32
+ _remoting: any, -- never assigned in this service (pre-existing)
33
+ },
34
+ {} :: typeof({ __index = ChatProviderCommandService })
35
+ ))
36
+
37
+ function ChatProviderCommandService.Init(self: ChatProviderCommandService, serviceBag: ServiceBag.ServiceBag)
38
+ assert(not (self :: any)._serviceBag, "Already initialized")
22
39
  self._serviceBag = assert(serviceBag, "No serviceBag")
23
40
  self._maid = Maid.new()
24
41
 
@@ -28,16 +45,16 @@ function ChatProviderCommandService:Init(serviceBag: ServiceBag.ServiceBag)
28
45
 
29
46
  -- Internal
30
47
  self._chatProviderService = self._serviceBag:GetService((require :: any)("ChatProviderService"))
31
- self._chatTagBinder = self._serviceBag:GetService(require("ChatTag"))
32
- self._hasChatTagsBinder = self._serviceBag:GetService(require("HasChatTags"))
48
+ self._chatTagBinder = self._serviceBag:GetService(ChatTag)
49
+ self._hasChatTagsBinder = self._serviceBag:GetService(HasChatTags)
33
50
  end
34
51
 
35
- function ChatProviderCommandService:Start()
52
+ function ChatProviderCommandService.Start(self: ChatProviderCommandService)
36
53
  self:_registerCommands()
37
54
  self:_createActivateChatCommand()
38
55
  end
39
56
 
40
- function ChatProviderCommandService:_createActivateChatCommand()
57
+ function ChatProviderCommandService._createActivateChatCommand(self: ChatProviderCommandService)
41
58
  local command = Instance.new("TextChatCommand")
42
59
  command.Name = "OpenCmdrCommand"
43
60
  command.PrimaryAlias = "/cmdr"
@@ -59,8 +76,8 @@ function ChatProviderCommandService:_createActivateChatCommand()
59
76
  self._chatProviderService:AddChatCommand(command)
60
77
  end
61
78
 
62
- function ChatProviderCommandService:GetChatTagKeyList()
63
- local tagSet = {}
79
+ function ChatProviderCommandService.GetChatTagKeyList(self: ChatProviderCommandService)
80
+ local tagSet: { [any]: boolean } = {}
64
81
  for chatTag, _ in pairs(self._chatTagBinder:GetAllSet()) do
65
82
  local tagKey = chatTag.ChatTagKey.Value
66
83
  tagSet[tagKey] = true
@@ -69,7 +86,7 @@ function ChatProviderCommandService:GetChatTagKeyList()
69
86
  return Set.toList(tagSet)
70
87
  end
71
88
 
72
- function ChatProviderCommandService:_registerCommands()
89
+ function ChatProviderCommandService._registerCommands(self: ChatProviderCommandService)
73
90
  self._cmdrService:PromiseCmdr():Then(function(cmdr)
74
91
  ChatTagCmdrUtils.registerChatTagKeys(cmdr, self)
75
92
  end)
@@ -95,17 +112,17 @@ function ChatProviderCommandService:_registerCommands()
95
112
  Type = "color3",
96
113
  Description = "Color for the tag to have",
97
114
  Optional = true,
98
- Default = Color3.fromRGB(255, 170, 0),
115
+ Default = Color3.fromRGB(255, 170, 0) :: any,
99
116
  },
100
117
  {
101
118
  Name = "TagPriority",
102
119
  Type = "number",
103
120
  Description = "Priority for the tag to have",
104
121
  Optional = true,
105
- Default = 0,
122
+ Default = 0 :: any,
106
123
  },
107
124
  },
108
- }, function(_context, player, tagText, tagColor, priority)
125
+ }, function(_context, player: Player, tagText, tagColor, priority)
109
126
  self._chatProviderService:PromiseAddChatTag(
110
127
  player,
111
128
  ChatTagDataUtils.createChatTagData({
@@ -130,7 +147,7 @@ function ChatProviderCommandService:_registerCommands()
130
147
  Description = "Player to add a tag for",
131
148
  },
132
149
  },
133
- }, function(_context, player)
150
+ }, function(_context, player: Player)
134
151
  self._chatProviderService:ClearChatTags(player)
135
152
 
136
153
  return string.format("Cleared chat tags on a player %q", PlayerUtils.formatName(player))
@@ -159,7 +176,7 @@ function ChatProviderCommandService:_registerCommands()
159
176
  Default = true,
160
177
  },
161
178
  },
162
- }, function(_context, player, chatTagKey, chatTagDisabled)
179
+ }, function(_context, player: Player, chatTagKey, chatTagDisabled)
163
180
  local hasChatTags = self._hasChatTagsBinder:Get(player)
164
181
 
165
182
  if not hasChatTags then
@@ -182,7 +199,7 @@ function ChatProviderCommandService:_registerCommands()
182
199
  end)
183
200
  end
184
201
 
185
- function ChatProviderCommandService:Destroy()
202
+ function ChatProviderCommandService.Destroy(self: ChatProviderCommandService)
186
203
  self._maid:DoCleaning()
187
204
  end
188
205
 
@@ -28,7 +28,7 @@ export type ChatTagBase =
28
28
 
29
29
  -- Public
30
30
  UserDisabled: AttributeValue.AttributeValue<boolean>,
31
- ChatTagKey: AttributeValue.AttributeValue<boolean>,
31
+ ChatTagKey: AttributeValue.AttributeValue<string>,
32
32
  },
33
33
  {} :: typeof({ __index = ChatTagBase })
34
34
  ))
@@ -43,7 +43,7 @@ function ChatTagBase.new(obj: Folder): ChatTagBase
43
43
  self._chatTagPriority = AttributeValue.new(self._obj, ChatTagConstants.TAG_PRIORITY_ATTRIBUTE, 0)
44
44
 
45
45
  self.UserDisabled = AttributeValue.new(self._obj, ChatTagConstants.USER_DISABLED_ATTRIBUTE, false)
46
- self.ChatTagKey = AttributeValue.new(self._obj, ChatTagConstants.TAG_KEY_ATTRIBUTE, false)
46
+ self.ChatTagKey = AttributeValue.new(self._obj, ChatTagConstants.TAG_KEY_ATTRIBUTE, "")
47
47
 
48
48
  return self
49
49
  end
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class ChatTagDataUtils
4
4
  ]=]