@whitewall/blip-sdk 0.0.136 → 0.0.137

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.
Files changed (50) hide show
  1. package/package.json +2 -2
  2. package/src/client.ts +117 -0
  3. package/src/index.ts +6 -0
  4. package/src/namespaces/account.ts +729 -0
  5. package/src/namespaces/activecampaign.ts +285 -0
  6. package/src/namespaces/analytics.ts +230 -0
  7. package/src/namespaces/billing.ts +17 -0
  8. package/src/namespaces/builder.ts +52 -0
  9. package/src/namespaces/configurations.ts +19 -0
  10. package/src/namespaces/context.ts +67 -0
  11. package/src/namespaces/desk.ts +679 -0
  12. package/src/namespaces/media.ts +39 -0
  13. package/src/namespaces/namespace.ts +125 -0
  14. package/src/namespaces/plugins.ts +223 -0
  15. package/src/namespaces/portal.ts +402 -0
  16. package/src/namespaces/scheduler.ts +88 -0
  17. package/src/namespaces/whatsapp.ts +383 -0
  18. package/src/sender/bliperror.ts +42 -0
  19. package/src/sender/enveloperesolver.ts +148 -0
  20. package/src/sender/gateway/customgatewaysender.ts +43 -0
  21. package/src/sender/http/httpsender.ts +94 -0
  22. package/src/sender/index.ts +7 -0
  23. package/src/sender/plugin/communication.ts +72 -0
  24. package/src/sender/plugin/pluginsender.ts +75 -0
  25. package/src/sender/security.ts +33 -0
  26. package/src/sender/sender.ts +145 -0
  27. package/src/sender/sessionnegotiator.ts +175 -0
  28. package/src/sender/tcp/tcpsender.ts +252 -0
  29. package/src/sender/throttler.ts +36 -0
  30. package/src/sender/websocket/websocketsender.ts +175 -0
  31. package/src/types/account.ts +84 -0
  32. package/src/types/analytics.ts +18 -0
  33. package/src/types/billing.ts +15 -0
  34. package/src/types/command.ts +47 -0
  35. package/src/types/commons.ts +16 -0
  36. package/src/types/desk.ts +51 -0
  37. package/src/types/envelope.ts +9 -0
  38. package/src/types/flow.ts +327 -0
  39. package/src/types/index.ts +13 -0
  40. package/src/types/message.ts +116 -0
  41. package/src/types/node.ts +86 -0
  42. package/src/types/notification.ts +18 -0
  43. package/src/types/plugins.ts +51 -0
  44. package/src/types/portal.ts +39 -0
  45. package/src/types/reason.ts +22 -0
  46. package/src/types/session.ts +22 -0
  47. package/src/types/whatsapp.ts +84 -0
  48. package/src/utils/odata.ts +114 -0
  49. package/src/utils/random.ts +3 -0
  50. package/src/utils/uri.ts +46 -0
@@ -0,0 +1,9 @@
1
+ import type { NodeLike } from './node.ts'
2
+
3
+ export type Envelope = {
4
+ id: string
5
+ from?: NodeLike
6
+ to?: NodeLike
7
+ metadata?: Record<string, string | null>
8
+ pp?: NodeLike
9
+ }
@@ -0,0 +1,327 @@
1
+ import type { MessageTypesContent } from './message.ts'
2
+
3
+ type SendMessageActionSettings = {
4
+ $invalid?: boolean
5
+ id: string
6
+ type: keyof MessageTypesContent
7
+ content: MessageTypesContent[keyof MessageTypesContent]
8
+ }
9
+
10
+ type ProcessHttpActionSettings = {
11
+ $invalid?: boolean
12
+ method: 'POST' | 'GET' | 'PUT' | 'DELETE'
13
+ // The URL to be called, you can use variables in the URL, for example: https://api.example.com/{{contact.email}}
14
+ uri: string
15
+ // The headers to be sent in the request. You can use variables in the headers, for example: Authorization: Bearer {{config.token}}
16
+ headers: Record<string, string>
17
+ // The body of the request. You can use variables in the body, for example: { "email": "{{contact.email}}" }
18
+ body: string
19
+ responseBodyVariable: string
20
+ responseStatusVariable: string
21
+ }
22
+
23
+ type TrackEventActionSettings = {
24
+ $invalid?: boolean
25
+ category: string
26
+ action: string
27
+ extras: Record<string, string>
28
+ }
29
+
30
+ type MergeContactActionSettings = {
31
+ $invalid?: boolean
32
+ name: string
33
+ email: string
34
+ city: string
35
+ extras: Record<string, string>
36
+ }
37
+
38
+ type ExecuteScriptActionSettings = {
39
+ $invalid?: boolean
40
+ function: 'run'
41
+ // It should be a valid ES5 code
42
+ source: string
43
+ // The input variables that will be passed to the function, you must not use the {{ variableName }} syntax or @ syntax here, just the variable name
44
+ // Can be a context variable or any other special variable
45
+ inputVariables: Array<string>
46
+ // The context variable name to store the returned result of the function
47
+ outputVariable: string
48
+ }
49
+
50
+ type SendRawMessageActionSettings = {
51
+ $invalid?: boolean
52
+ type: 'application/json'
53
+ // Useful to send raw content to the user, like raw whatsapp messages
54
+ // Example: {"recipient_type": "individual","type": "interactive","interactive": {"type": "button","body": {"text": "..."},"action": {"buttons": [...]}}}
55
+ rawContent: string
56
+ }
57
+
58
+ type SetVariableActionSettings = {
59
+ $invalid?: boolean
60
+ variable: string
61
+ value: string
62
+ // Expiration time of the variable in seconds, if unsure, don't set it
63
+ expiration?: number
64
+ }
65
+
66
+ type TypeOfStateId = 'state' | 'variable'
67
+
68
+ export type Condition = {
69
+ source: 'input' | 'context'
70
+ // The variable name of the conversation context to be evaluated, if the 'source' value is 'context'
71
+ variable?: string
72
+ // The type of the comparison. Optional. The default value is 'equals'
73
+ comparison:
74
+ | 'equals'
75
+ | 'notEquals'
76
+ | 'contains'
77
+ | 'startsWith'
78
+ | 'endsWith'
79
+ | 'greaterThan'
80
+ | 'lessThan'
81
+ | 'greaterThanOrEquals'
82
+ | 'lessThanOrEquals'
83
+ | 'matches'
84
+ | 'approximateTo'
85
+ | 'exists'
86
+ | 'notExists'
87
+ // The operator for comparison with the provided values. The default value is 'or'
88
+ operator?: 'or' | 'and'
89
+ values: Array<string>
90
+ }
91
+
92
+ export type Action = {
93
+ $id: string
94
+ // The type of content should only exists if the action is of type SendMessage or SendRawMessage
95
+ // It should match the content type of the action settings
96
+ $typeOfContent?: // if don`t exists is set with empty string in GET
97
+ | ''
98
+ // type = text/plain
99
+ | 'text'
100
+ // type = application/vnd.lime.select+json
101
+ // content.scope = immediate
102
+ | 'select-immediate'
103
+ // content.scope = persistent
104
+ | 'select'
105
+ // type = application/vnd.lime.media-link+json
106
+ // content.type = image/png, image/jpeg, image/gif
107
+ | 'media'
108
+ // content.type = audio/mpeg, audio/wav, audio/ogg
109
+ | 'media-audio'
110
+ // content.type = video/mp4
111
+ | 'media-video'
112
+ // content.type = application/pdf
113
+ | 'media-document'
114
+ // type = application/vnd.lime.chatstate+json
115
+ | 'chat-state'
116
+ // type = application/vnd.lime.web-link+json
117
+ | 'web-link'
118
+ // type = application/json
119
+ // Should be used only for SendRawMessage action
120
+ | 'raw-content'
121
+ // The type of the action to be executed
122
+ type: // Send a message to the user
123
+ | 'SendMessage'
124
+ // Send a raw message to the user, useful to send whatsapp content
125
+ | 'SendRawMessage'
126
+ // Track an event in the conversation
127
+ | 'TrackEvent'
128
+ // Process an HTTP request
129
+ | 'ProcessHttp'
130
+ // Update the contact information of the user
131
+ | 'MergeContact'
132
+ // Execute a ES5 script
133
+ | 'ExecuteScript'
134
+ // Set a variable in the context
135
+ | 'SetVariable'
136
+ | 'ForwardToDesk'
137
+ | 'LeavingFromDesk'
138
+ $title?: string
139
+ $invalid?: boolean
140
+ // The matching settings of the action type
141
+ settings:
142
+ | SendMessageActionSettings
143
+ | SendRawMessageActionSettings
144
+ | TrackEventActionSettings
145
+ | ProcessHttpActionSettings
146
+ | MergeContactActionSettings
147
+ | ExecuteScriptActionSettings
148
+ | SetVariableActionSettings
149
+ | Record<string, never>
150
+ // Must always be set if the action is of type SendMessage or SendRawMessage
151
+ // If other action type, it must be null
152
+ $cardContent?: {
153
+ document: {
154
+ id: string
155
+ // Should always be the same of settings.type
156
+ type: keyof MessageTypesContent | 'application/json'
157
+ // The content of the message, it should be the same of settings.content
158
+ content: MessageTypesContent[keyof MessageTypesContent] | string
159
+ textContent?: string
160
+ }
161
+ editable: boolean
162
+ deletable: boolean
163
+ position: 'left'
164
+ }
165
+ conditions?: Array<Condition>
166
+ }
167
+
168
+ type InputState = {
169
+ // Always same values, except for the document.id
170
+ $cardContent: {
171
+ document: {
172
+ id: string
173
+ type: 'text/plain'
174
+ content?: 'Entrada do usuário'
175
+ // Should always be the same of the variable name
176
+ textContent?: string
177
+ }
178
+ editable: boolean
179
+ editing: boolean
180
+ deletable: boolean
181
+ position: 'right'
182
+ }
183
+ $invalid: boolean
184
+ bypass: boolean
185
+ validation?: {
186
+ // Gets or sets the validation rule to be used
187
+ rule: 'text' | 'number' | 'date' | 'regex' | 'type'
188
+ // The regular expression to be used in case of the 'rule' value is regex'
189
+ regex?: string
190
+ // The type to be used in case of the 'rule' value is 'type'
191
+ type?: string
192
+ // The error message text to be returned to the user in case of the input value is not valid accordingly to the defined rule
193
+ error: string
194
+ }
195
+ // Input expiration time in minutes. If not set, the input will never expire. If unsure, don't set it
196
+ expiration?: string
197
+ variable?: string
198
+ conditions?: Array<Condition>
199
+ }
200
+
201
+ export type State = {
202
+ $contentActions: Array<{
203
+ // The actions that would be executed after entering actions
204
+ // All the actions here should be of type SendMessage
205
+ // This is the only place that can have the SendMessage action
206
+ action?: Action
207
+ // If the state should have a user input, it should be defined here
208
+ input?: InputState
209
+ }>
210
+ $conditionOutputs: Array<{
211
+ stateId: string
212
+ typeOfStateId?: TypeOfStateId
213
+ $id?: string
214
+ conditions: Array<Condition>
215
+ $invalid?: boolean
216
+ $isDeskOutput?: boolean
217
+ $isDeskDefaultOutput?: boolean
218
+ }>
219
+ // The actions that would be executed after entering the state
220
+ $enteringCustomActions: Array<Action>
221
+ // The actions that would be executed after leaving the state, before the output conditions
222
+ $leavingCustomActions: Array<Action>
223
+ $inputSuggestions: []
224
+ $defaultOutput: {
225
+ // Id of the state to redirect
226
+ stateId: string
227
+ $invalid: boolean
228
+ typeOfStateId?: TypeOfStateId
229
+ }
230
+ isAiGenerated?: boolean
231
+ deskStateVersion?: string
232
+ $afterStateChangedActions?: Array<Action>
233
+ $tags: Array<{
234
+ id: string
235
+ label: string
236
+ // Hexadecimal color code of the tag, with # prefix
237
+ background: string
238
+ canChangeBackground: boolean
239
+ }>
240
+ id?: string
241
+ // Only the special state with id "onbarding" has root as boolean
242
+ root?: boolean
243
+ $title?: string
244
+ $position?: {
245
+ top: string
246
+ left: string
247
+ }
248
+ $invalidContentActions: boolean
249
+ $invalidOutputs: boolean
250
+ $invalidCustomActions: boolean
251
+ $invalid?: boolean
252
+ }
253
+
254
+ export type BuilderConfiguration = {
255
+ 'builder:minimumIntentScore'?: string
256
+ 'builder:stateTrack'?: string
257
+ 'builder:#localTimeZone'?: string
258
+ } & Record<string, string | number>
259
+
260
+ export type BuilderFlow = Record<'onboarding' | 'fallback' | string, State>
261
+
262
+ // The history index is a number from 1 to 10, representing the last 10 publications
263
+ export type HistoryIndex = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
264
+
265
+ export type Publication = {
266
+ authorIdentity: string
267
+ author: string
268
+ }
269
+
270
+ export type BuilderLatestPublications = {
271
+ // The last publication its a rotate of 10
272
+ lastInsertedIndex: HistoryIndex
273
+ isMoreOptionsActive: string
274
+ publications: Array<Publication & { publishedAt: string; index: HistoryIndex }>
275
+ }
276
+
277
+ export type BuilderLatestPublication = {
278
+ flow: BuilderFlow
279
+ globalActions?: State
280
+ configuration?: BuilderConfiguration
281
+ }
282
+
283
+ type RecursivelyRemoveDollar<T> = T extends object
284
+ ? T extends Array<infer U>
285
+ ? Array<RecursivelyRemoveDollar<U>>
286
+ : { [K in keyof T as K extends `$${string}` ? never : K]: RecursivelyRemoveDollar<T[K]> }
287
+ : T
288
+
289
+ export type StateApplication = {
290
+ id: string
291
+ root?: boolean
292
+ name: string
293
+ inputActions: RecursivelyRemoveDollar<Array<Action>>
294
+ input: RecursivelyRemoveDollar<InputState>
295
+ outputActions: RecursivelyRemoveDollar<Array<Action>>
296
+ afterStateChangedActions: RecursivelyRemoveDollar<Array<Action>>
297
+ outputs: Array<{
298
+ stateId: string
299
+ conditions?: RecursivelyRemoveDollar<Array<Condition>>
300
+ }>
301
+ }
302
+
303
+ export type ApplicationAction = RecursivelyRemoveDollar<Action>
304
+
305
+ export type ApplicationFlow = {
306
+ identifier: string
307
+ messageReceivers: Array<{
308
+ state: string
309
+ type: string
310
+ }>
311
+ notificationReceivers: Array<{
312
+ type: string
313
+ }>
314
+ serviceProviderType: string
315
+ settings: {
316
+ flow: {
317
+ id: string
318
+ version: number
319
+ states: Array<StateApplication>
320
+ configuration: BuilderConfiguration
321
+ inputActions: Array<ApplicationAction>
322
+ outputActions: Array<ApplicationAction>
323
+ type: 'flow'
324
+ }
325
+ }
326
+ settingsType: 'Settings'
327
+ }
@@ -0,0 +1,13 @@
1
+ export * from './node.ts'
2
+ export * from './envelope.ts'
3
+ export * from './message.ts'
4
+ export * from './command.ts'
5
+ export * from './notification.ts'
6
+ export * from './desk.ts'
7
+ export * from './account.ts'
8
+ export * from './whatsapp.ts'
9
+ export * from './portal.ts'
10
+ export * from './plugins.ts'
11
+ export * from './analytics.ts'
12
+ export * from './flow.ts'
13
+ export * from './commons.ts'
@@ -0,0 +1,116 @@
1
+ import type { JsonObject } from './commons.ts'
2
+ import type { TicketStatus } from './desk.ts'
3
+ import type { Envelope } from './envelope.ts'
4
+ import type { Identity } from './node.ts'
5
+
6
+ export type PlainText = string
7
+
8
+ export type Ticket<Type extends MessageTypes | undefined = undefined> = {
9
+ id: string
10
+ sequentialId: string
11
+ ownerIdentity: Identity
12
+ customerIdentity: Identity
13
+ customerDomain: string
14
+ provider: string
15
+ status: TicketStatus
16
+ statusDate?: string
17
+ storageDate: string
18
+ openDate?: string
19
+ closeDate?: string
20
+ firstResponseDate?: string
21
+ averageAgentResponseTime?: number
22
+ agentIdentity?: Identity
23
+ team?: string
24
+ rating: number
25
+ unreadMessages: number
26
+ customerInput: Type extends MessageTypes ? Document<Type> : undefined
27
+ closed: boolean
28
+ closedBy?: Identity
29
+ tags: Array<string>
30
+ }
31
+
32
+ export type Redirect<Type extends MessageTypes> = {
33
+ address: Identity
34
+ context: Document<Type>
35
+ }
36
+
37
+ export type MediaLink = {
38
+ // Mime type of the content
39
+ type: string
40
+ uri: string
41
+ title?: string
42
+ text?: string
43
+ }
44
+
45
+ export type Reply<Type extends MessageTypes> = {
46
+ replied: Document<Type>
47
+ }
48
+
49
+ export type Select = {
50
+ text: string
51
+ scope?: 'immediate' | 'persistent'
52
+ options: Array<{
53
+ text: string
54
+ }>
55
+ }
56
+
57
+ export type ChatState = {
58
+ state: 'starting' | 'composing' | 'paused' | 'deleted' | 'gone'
59
+ }
60
+
61
+ export type WebLink = {
62
+ title?: string
63
+ text: string
64
+ target?: 'blank' | 'self' | 'selfCompact' | 'selfTall'
65
+ uri: string
66
+ }
67
+
68
+ export interface MessageTypesContent {
69
+ 'text/plain': PlainText
70
+ 'application/vnd.iris.ticket+json': Ticket<MessageTypes>
71
+ 'application/vnd.lime.redirect+json': Redirect<MessageTypes>
72
+ 'application/vnd.lime.media-link+json': MediaLink
73
+ 'application/json': JsonObject
74
+ 'application/vnd.lime.reply+json': Reply<MessageTypes>
75
+ 'application/vnd.lime.select+json': Select
76
+ 'application/vnd.lime.chatstate+json': ChatState
77
+ 'application/vnd.lime.web-link+json': WebLink
78
+ }
79
+
80
+ export type MessageTypes = keyof MessageTypesContent
81
+
82
+ export type Document<Type extends MessageTypes> = {
83
+ type: Type
84
+ value: MessageTypesContent[Type]
85
+ }
86
+
87
+ export type MessageContent<Type extends MessageTypes> = {
88
+ type: Type
89
+ content: MessageTypesContent[Type]
90
+ }
91
+
92
+ export type Message<Type extends MessageTypes> = Envelope & MessageContent<Type>
93
+
94
+ export type UnknownDocument = Document<MessageTypes>
95
+ export type UnknownMessage = Message<MessageTypes>
96
+ export type UnknownMessageContent = MessageContent<MessageTypes>
97
+
98
+ export const isMessage = (envelope: Envelope): envelope is UnknownMessage =>
99
+ 'type' in envelope && 'content' in envelope && typeof envelope.type === 'string'
100
+
101
+ export const isMessageOfType = <Type extends MessageTypes>(
102
+ message: UnknownMessage,
103
+ type: Type,
104
+ ): message is Message<Type> => message.type === type
105
+
106
+ export const isDocumentOfType = <Type extends MessageTypes>(
107
+ document: UnknownDocument,
108
+ type: Type,
109
+ ): document is Document<Type> => document.type === type
110
+
111
+ export const messageToDocument = <Type extends MessageTypes>(
112
+ message: Pick<Message<Type>, 'type' | 'content'>,
113
+ ): Document<Type> => ({
114
+ type: message.type,
115
+ value: message.content,
116
+ })
@@ -0,0 +1,86 @@
1
+ export type Domain = `${string}.${string}`
2
+ export type BlipDomain = 'msging.net' | 'blip.ai' | '0mn.io'
3
+ export type Identity = `${string}@${Domain}`
4
+ export type NodeShape = Identity | `${Identity}/${string}`
5
+ export type NodeLike = Node | NodeShape
6
+ export type PossiblyNode = Node | string
7
+
8
+ export class Node extends String {
9
+ constructor(
10
+ public readonly name: string,
11
+ public readonly domain: Domain,
12
+ public readonly instance?: string,
13
+ ) {
14
+ super(`${encodeURIComponent(name)}@${domain}${instance ? `/${instance}` : ''}`)
15
+ }
16
+
17
+ public toIdentity(): Identity {
18
+ return `${encodeURIComponent(this.name)}@${this.domain}`
19
+ }
20
+
21
+ public withInstance(instance: string) {
22
+ return new Node(this.name, this.domain, instance)
23
+ }
24
+
25
+ public getSource() {
26
+ switch (this.domain) {
27
+ case '0mn.io':
28
+ return 'Blip Chat'
29
+ case 'messenger.gw.msging.net':
30
+ return 'Messenger'
31
+ case 'instagram.gw.msging.net':
32
+ return 'Instagram'
33
+ case 'wa.gw.msging.net':
34
+ return 'WhatsApp'
35
+ case 'businessmessages.gw.msging.net':
36
+ return 'Google Business Messages'
37
+ case 'telegram.gw.msging.net':
38
+ return 'Telegram'
39
+ case 'workplace.gw.msging.net':
40
+ return 'Workplace'
41
+ case 'mailgun.gw.msging.net':
42
+ return 'Email'
43
+ case 'msging.net':
44
+ return 'Bot'
45
+ case 'blip.ai':
46
+ return 'Blip'
47
+ case 'tunnel.msging.net':
48
+ return 'Tunnel'
49
+ case 'custom.gw.msging.net': {
50
+ if (this.name.endsWith('.mail')) {
51
+ return 'Email'
52
+ } else if (this.name.endsWith('.slack')) {
53
+ return 'Slack'
54
+ } else {
55
+ return 'Custom'
56
+ }
57
+ }
58
+ default:
59
+ return 'Unknown'
60
+ }
61
+ }
62
+
63
+ public static from(node: NodeLike): Node
64
+ public static from(nameOrPossibleNode: PossiblyNode, domain: Domain): Node
65
+ public static from(nameOrPossibleNode: PossiblyNode, domain?: Domain): Node {
66
+ if (nameOrPossibleNode instanceof Node) {
67
+ return nameOrPossibleNode
68
+ }
69
+
70
+ if (Node.isValid(nameOrPossibleNode)) {
71
+ const [name, otherPart] = nameOrPossibleNode.split('@')
72
+ const [domain, instance] = otherPart.split('/')
73
+ return new Node(decodeURIComponent(name), domain as Domain, instance)
74
+ }
75
+
76
+ if (domain) {
77
+ return new Node(decodeURIComponent(nameOrPossibleNode), domain)
78
+ }
79
+
80
+ throw new Error(`Invalid node shape: ${nameOrPossibleNode}`)
81
+ }
82
+
83
+ public static isValid(node: string | null | undefined): node is NodeShape {
84
+ return node ? /^.+@.+\..+/.test(node) : false
85
+ }
86
+ }
@@ -0,0 +1,18 @@
1
+ import type { Envelope } from './envelope.ts'
2
+ import type { Reason } from './reason.ts'
3
+
4
+ export type FailedNotification = {
5
+ event: 'failed'
6
+ reason: Reason
7
+ }
8
+
9
+ export type CommonNotification = {
10
+ // The official documentation is not up to date, so we need to check the source code
11
+ // https://github.com/takenet/lime-csharp/blob/master/src/Lime.Protocol/Notification.cs#L47
12
+ event: 'accepted' | 'consumed' | 'dispatched' | 'received' | 'deleted'
13
+ }
14
+
15
+ export type Notification = Envelope & (FailedNotification | CommonNotification)
16
+
17
+ export const isNotification = (envelope: Envelope): envelope is Notification =>
18
+ 'event' in envelope && typeof envelope.event === 'string'
@@ -0,0 +1,51 @@
1
+ export type Plugin = {
2
+ id: string
3
+ name: string
4
+ overview: string
5
+ price: number
6
+ isPaid: boolean
7
+ icon: string
8
+ storageDate: string
9
+ author: {
10
+ id: number
11
+ name: string
12
+ email: string
13
+ logo: string
14
+ isActive: boolean
15
+ }
16
+ installedBotsNumber?: number
17
+ installedBotsNumberAllContracts?: number
18
+ subscription?: {
19
+ status: string
20
+ }
21
+ tags: Array<string>
22
+ chargeType: string
23
+ imageUrl: string
24
+ }
25
+
26
+ export type DetailedPlugin = Plugin & {
27
+ description?: string
28
+ documentation?: string
29
+ }
30
+
31
+ export type PluginBilling = {
32
+ billingId: string
33
+ currency: string
34
+ description: string
35
+ featuresIncluded: string
36
+ isRecommended: boolean
37
+ language: string
38
+ name: string
39
+ price: number
40
+ }
41
+
42
+ export type PluginSubscription = DetailedPlugin & {
43
+ /** All possible billings for the plugin */
44
+ billings: Array<PluginBilling>
45
+ subscription: NonNullable<Plugin['subscription']> & {
46
+ /** The active billing plans, usually the length is 0 or 1 */
47
+ billings: Array<PluginBilling>
48
+ chargeType: string
49
+ price: number
50
+ }
51
+ }
@@ -0,0 +1,39 @@
1
+ import type { Identity } from './node.ts'
2
+
3
+ export type Application = {
4
+ shortName: string
5
+ name: string
6
+ imageUri: string
7
+ template: 'builder' | 'master'
8
+ tenantId: string
9
+ created: string
10
+ updated: string
11
+ hasPermission: boolean
12
+ emailOwner: string
13
+ }
14
+
15
+ export type TenantSubscription = {
16
+ ownerIdentity: Identity
17
+ id: string
18
+ subscriber: Identity
19
+ planId: string
20
+ startDate: string
21
+ lastChangeDate: string
22
+ isPending: boolean
23
+ isActive: boolean
24
+ extras: {
25
+ WalletId: string
26
+ }
27
+ }
28
+
29
+ export type TenantUserInfo = {
30
+ tenantId: string
31
+ userIdentity: Identity
32
+ fullName: string
33
+ creationDate: string
34
+ updateDate: string
35
+ userStatus: string
36
+ roleId: 'member' | 'admin' | 'guest'
37
+ }
38
+
39
+ export type ApplicationUserInfo = { userIdentity: Identity; creationDate: string }
@@ -0,0 +1,22 @@
1
+ export enum ReasonCodes {
2
+ PipelineTimeout = 2,
3
+ MaxThroughputExceeded = 38,
4
+ GeneralError = 101,
5
+ FailedToSendEnvelopeViaHTTP = 2105,
6
+ }
7
+
8
+ export interface Reason {
9
+ code: ReasonCodes | number
10
+ description: string
11
+ }
12
+
13
+ export const isReason = (value: unknown): value is Reason => {
14
+ return (
15
+ typeof value === 'object' &&
16
+ value !== null &&
17
+ 'code' in value &&
18
+ typeof value.code === 'number' &&
19
+ 'description' in value &&
20
+ typeof value.description === 'string'
21
+ )
22
+ }