@tgify/tgify 0.1.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.
Files changed (168) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +356 -0
  3. package/filters.d.ts +1 -0
  4. package/filters.js +1 -0
  5. package/format.d.ts +1 -0
  6. package/format.js +1 -0
  7. package/future.d.ts +1 -0
  8. package/future.js +1 -0
  9. package/lib/button.js +100 -0
  10. package/lib/cli.mjs +105 -0
  11. package/lib/composer.js +582 -0
  12. package/lib/context.js +1219 -0
  13. package/lib/core/helpers/args.js +57 -0
  14. package/lib/core/helpers/check.js +55 -0
  15. package/lib/core/helpers/compact.js +16 -0
  16. package/lib/core/helpers/deunionize.js +12 -0
  17. package/lib/core/helpers/formatting.js +91 -0
  18. package/lib/core/helpers/util.js +50 -0
  19. package/lib/core/network/client.js +330 -0
  20. package/lib/core/network/error.js +21 -0
  21. package/lib/core/network/multipart-stream.js +71 -0
  22. package/lib/core/network/polling.js +87 -0
  23. package/lib/core/network/webhook.js +54 -0
  24. package/lib/core/types/typegram.js +27 -0
  25. package/lib/filters.js +69 -0
  26. package/lib/format.js +38 -0
  27. package/lib/future.js +149 -0
  28. package/lib/index.js +58 -0
  29. package/lib/input.js +61 -0
  30. package/lib/markup.js +121 -0
  31. package/lib/middleware.js +2 -0
  32. package/lib/reactions.js +84 -0
  33. package/lib/router.js +46 -0
  34. package/lib/scenes/base.js +39 -0
  35. package/lib/scenes/context.js +104 -0
  36. package/lib/scenes/index.js +21 -0
  37. package/lib/scenes/stage.js +49 -0
  38. package/lib/scenes/wizard/context.js +31 -0
  39. package/lib/scenes/wizard/index.js +45 -0
  40. package/lib/scenes.js +17 -0
  41. package/lib/session.js +166 -0
  42. package/lib/telegraf.js +256 -0
  43. package/lib/telegram-types.js +6 -0
  44. package/lib/telegram.js +1240 -0
  45. package/lib/types.js +2 -0
  46. package/lib/utils.js +5 -0
  47. package/markup.d.ts +1 -0
  48. package/markup.js +1 -0
  49. package/package.json +140 -0
  50. package/scenes.d.ts +1 -0
  51. package/scenes.js +1 -0
  52. package/session.d.ts +1 -0
  53. package/session.js +1 -0
  54. package/src/button.ts +182 -0
  55. package/src/composer.ts +1008 -0
  56. package/src/context.ts +1661 -0
  57. package/src/core/helpers/args.ts +63 -0
  58. package/src/core/helpers/check.ts +71 -0
  59. package/src/core/helpers/compact.ts +18 -0
  60. package/src/core/helpers/deunionize.ts +26 -0
  61. package/src/core/helpers/formatting.ts +119 -0
  62. package/src/core/helpers/util.ts +96 -0
  63. package/src/core/network/client.ts +396 -0
  64. package/src/core/network/error.ts +29 -0
  65. package/src/core/network/multipart-stream.ts +45 -0
  66. package/src/core/network/polling.ts +94 -0
  67. package/src/core/network/webhook.ts +58 -0
  68. package/src/core/types/typegram.ts +54 -0
  69. package/src/filters.ts +109 -0
  70. package/src/format.ts +110 -0
  71. package/src/future.ts +213 -0
  72. package/src/index.ts +17 -0
  73. package/src/input.ts +59 -0
  74. package/src/markup.ts +142 -0
  75. package/src/middleware.ts +24 -0
  76. package/src/reactions.ts +118 -0
  77. package/src/router.ts +55 -0
  78. package/src/scenes/base.ts +52 -0
  79. package/src/scenes/context.ts +136 -0
  80. package/src/scenes/index.ts +21 -0
  81. package/src/scenes/stage.ts +71 -0
  82. package/src/scenes/wizard/context.ts +58 -0
  83. package/src/scenes/wizard/index.ts +63 -0
  84. package/src/scenes.ts +1 -0
  85. package/src/session.ts +204 -0
  86. package/src/telegraf.ts +354 -0
  87. package/src/telegram-types.ts +219 -0
  88. package/src/telegram.ts +1635 -0
  89. package/src/types.ts +2 -0
  90. package/src/utils.ts +1 -0
  91. package/types.d.ts +1 -0
  92. package/types.js +1 -0
  93. package/typings/button.d.ts +36 -0
  94. package/typings/button.d.ts.map +1 -0
  95. package/typings/composer.d.ts +227 -0
  96. package/typings/composer.d.ts.map +1 -0
  97. package/typings/context.d.ts +655 -0
  98. package/typings/context.d.ts.map +1 -0
  99. package/typings/core/helpers/args.d.ts +11 -0
  100. package/typings/core/helpers/args.d.ts.map +1 -0
  101. package/typings/core/helpers/check.d.ts +56 -0
  102. package/typings/core/helpers/check.d.ts.map +1 -0
  103. package/typings/core/helpers/compact.d.ts +4 -0
  104. package/typings/core/helpers/compact.d.ts.map +1 -0
  105. package/typings/core/helpers/deunionize.d.ts +18 -0
  106. package/typings/core/helpers/deunionize.d.ts.map +1 -0
  107. package/typings/core/helpers/formatting.d.ts +30 -0
  108. package/typings/core/helpers/formatting.d.ts.map +1 -0
  109. package/typings/core/helpers/util.d.ts +26 -0
  110. package/typings/core/helpers/util.d.ts.map +1 -0
  111. package/typings/core/network/client.d.ts +53 -0
  112. package/typings/core/network/client.d.ts.map +1 -0
  113. package/typings/core/network/error.d.ts +16 -0
  114. package/typings/core/network/error.d.ts.map +1 -0
  115. package/typings/core/network/multipart-stream.d.ts +16 -0
  116. package/typings/core/network/multipart-stream.d.ts.map +1 -0
  117. package/typings/core/network/polling.d.ts +16 -0
  118. package/typings/core/network/polling.d.ts.map +1 -0
  119. package/typings/core/network/webhook.d.ts +6 -0
  120. package/typings/core/network/webhook.d.ts.map +1 -0
  121. package/typings/core/types/typegram.d.ts +42 -0
  122. package/typings/core/types/typegram.d.ts.map +1 -0
  123. package/typings/filters.d.ts +18 -0
  124. package/typings/filters.d.ts.map +1 -0
  125. package/typings/format.d.ts +22 -0
  126. package/typings/format.d.ts.map +1 -0
  127. package/typings/future.d.ts +12 -0
  128. package/typings/future.d.ts.map +1 -0
  129. package/typings/index.d.ts +15 -0
  130. package/typings/index.d.ts.map +1 -0
  131. package/typings/input.d.ts +50 -0
  132. package/typings/input.d.ts.map +1 -0
  133. package/typings/markup.d.ts +27 -0
  134. package/typings/markup.d.ts.map +1 -0
  135. package/typings/middleware.d.ts +8 -0
  136. package/typings/middleware.d.ts.map +1 -0
  137. package/typings/reactions.d.ts +32 -0
  138. package/typings/reactions.d.ts.map +1 -0
  139. package/typings/router.d.ts +21 -0
  140. package/typings/router.d.ts.map +1 -0
  141. package/typings/scenes/base.d.ts +22 -0
  142. package/typings/scenes/base.d.ts.map +1 -0
  143. package/typings/scenes/context.d.ts +36 -0
  144. package/typings/scenes/context.d.ts.map +1 -0
  145. package/typings/scenes/index.d.ts +11 -0
  146. package/typings/scenes/index.d.ts.map +1 -0
  147. package/typings/scenes/stage.d.ts +24 -0
  148. package/typings/scenes/stage.d.ts.map +1 -0
  149. package/typings/scenes/wizard/context.d.ts +29 -0
  150. package/typings/scenes/wizard/context.d.ts.map +1 -0
  151. package/typings/scenes/wizard/index.d.ts +16 -0
  152. package/typings/scenes/wizard/index.d.ts.map +1 -0
  153. package/typings/scenes.d.ts +2 -0
  154. package/typings/scenes.d.ts.map +1 -0
  155. package/typings/session.d.ts +55 -0
  156. package/typings/session.d.ts.map +1 -0
  157. package/typings/telegraf.d.ts +115 -0
  158. package/typings/telegraf.d.ts.map +1 -0
  159. package/typings/telegram-types.d.ts +117 -0
  160. package/typings/telegram-types.d.ts.map +1 -0
  161. package/typings/telegram.d.ts +675 -0
  162. package/typings/telegram.d.ts.map +1 -0
  163. package/typings/types.d.ts +3 -0
  164. package/typings/types.d.ts.map +1 -0
  165. package/typings/utils.d.ts +2 -0
  166. package/typings/utils.d.ts.map +1 -0
  167. package/utils.d.ts +1 -0
  168. package/utils.js +1 -0
@@ -0,0 +1,63 @@
1
+ interface Entity {
2
+ /** Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag), “cashtag” ($USD), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers) */
3
+ type: string
4
+ /** Offset in UTF-16 code units to the start of the entity */
5
+ offset: number
6
+ /** Length of the entity in UTF-16 code units */
7
+ length: number
8
+ }
9
+
10
+ const SINGLE_QUOTE = "'"
11
+ const DOUBLE_QUOTE = '"'
12
+
13
+ export function argsParser(
14
+ str: string,
15
+ entities: Entity[] = [],
16
+ entityOffset = 0
17
+ ) {
18
+ const mentions: { [offset: string]: number } = {}
19
+ for (const entity of entities) // extract all text_mentions into an { offset: length } map
20
+ if (entity.type === 'text_mention' || entity.type === 'text_link')
21
+ mentions[entity.offset - entityOffset] = entity.length
22
+
23
+ const args: string[] = []
24
+ let done = 0
25
+ let inside: `'` | `"` | undefined = undefined
26
+ let buf = ''
27
+
28
+ function flush(to: number) {
29
+ if (done !== to) args.push(buf + str.slice(done, to)), (inside = undefined)
30
+ buf = ''
31
+ done = to + 1
32
+ }
33
+
34
+ for (let i = 0; i < str.length; i++) {
35
+ const char = str[i]
36
+ // quick lookup length of mention starting at i
37
+ const mention = mentions[i]
38
+ if (mention) {
39
+ // if we're inside a quote, eagerly flush existing state
40
+ flush(i)
41
+ // this also consumes current index, so decrement
42
+ done--
43
+ // fast forward to end of mention
44
+ i += mention
45
+ flush(i)
46
+ } else if (char === SINGLE_QUOTE || char === DOUBLE_QUOTE)
47
+ if (inside)
48
+ if (inside === char) flush(i)
49
+ else continue
50
+ else flush(i), (inside = char)
51
+ else if (char === ' ')
52
+ if (inside) continue
53
+ else flush(i)
54
+ else if (char === '\n') flush(i)
55
+ else if (char === '\\')
56
+ (buf += str.slice(done, i)), (done = ++i) // skip parsing the next char
57
+ else continue
58
+ }
59
+
60
+ if (done < str.length) flush(str.length)
61
+
62
+ return args
63
+ }
@@ -0,0 +1,71 @@
1
+ interface Mapping {
2
+ string: string
3
+ number: number
4
+ bigint: bigint
5
+ boolean: boolean
6
+ symbol: symbol
7
+ undefined: undefined
8
+ object: Record<string, unknown>
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ function: (...props: any[]) => any
11
+ }
12
+
13
+ /**
14
+ * Checks if a given object has a property with a given name.
15
+ *
16
+ * Example invocation:
17
+ * ```js
18
+ * let obj = { 'foo': 'bar', 'baz': () => {} }
19
+ * hasProp(obj, 'foo') // true
20
+ * hasProp(obj, 'baz') // true
21
+ * hasProp(obj, 'abc') // false
22
+ * ```
23
+ *
24
+ * @param obj An object to test
25
+ * @param prop The name of the property
26
+ */
27
+ export function hasProp<O extends object, K extends PropertyKey>(
28
+ obj: O | undefined,
29
+ prop: K
30
+ ): obj is O & Record<K, unknown> {
31
+ return obj !== undefined && prop in obj
32
+ }
33
+ /**
34
+ * Checks if a given object has a property with a given name.
35
+ * Furthermore performs a `typeof` check on the property if it exists.
36
+ *
37
+ * Example invocation:
38
+ * ```js
39
+ * let obj = { 'foo': 'bar', 'baz': () => {} }
40
+ * hasPropType(obj, 'foo', 'string') // true
41
+ * hasPropType(obj, 'baz', 'function') // true
42
+ * hasPropType(obj, 'abc', 'number') // false
43
+ * ```
44
+ *
45
+ * @param obj An object to test
46
+ * @param prop The name of the property
47
+ * @param type The type the property is expected to have
48
+ */
49
+ export function hasPropType<
50
+ O extends object,
51
+ K extends PropertyKey,
52
+ T extends keyof Mapping,
53
+ V extends Mapping[T],
54
+ >(obj: O | undefined, prop: K, type: T): obj is O & Record<K, V> {
55
+ return hasProp(obj, prop) && type === typeof obj[prop]
56
+ }
57
+
58
+ /**
59
+ * Checks if the supplied array has two dimensions or not.
60
+ *
61
+ * Example invocations:
62
+ * is2D([]) // false
63
+ * is2D([[]]) // true
64
+ * is2D([[], []]) // true
65
+ * is2D([42]) // false
66
+ *
67
+ * @param arr an array with one or two dimensions
68
+ */
69
+ export function is2D<E>(arr: E[] | E[][]): arr is E[][] {
70
+ return Array.isArray(arr[0])
71
+ }
@@ -0,0 +1,18 @@
1
+ export function compactOptions<T extends { [key: string]: unknown }>(
2
+ options?: T
3
+ ): T | undefined {
4
+ if (!options) {
5
+ return options
6
+ }
7
+
8
+ const compacted: Partial<T> = {}
9
+ for (const key in options)
10
+ if (
11
+ // todo(mkr): replace with Object.hasOwn in v5 (Node 16+)
12
+ Object.prototype.hasOwnProperty.call(options, key) &&
13
+ options[key] !== undefined
14
+ )
15
+ compacted[key] = options[key]
16
+
17
+ return compacted as T | undefined
18
+ }
@@ -0,0 +1,26 @@
1
+ export type PropOr<
2
+ T extends object | undefined,
3
+ P extends string | symbol | number,
4
+ D = undefined,
5
+ > = T extends Partial<Record<P, unknown>> ? T[P] : D
6
+
7
+ export type UnionKeys<T> = T extends unknown ? keyof T : never
8
+
9
+ type AddOptionalKeys<K extends PropertyKey> = { readonly [P in K]?: never }
10
+
11
+ /**
12
+ * @see https://millsp.github.io/ts-toolbelt/modules/union_strict.html
13
+ */
14
+ export type Deunionize<B extends object | undefined, T = B> = T extends object
15
+ ? T & AddOptionalKeys<Exclude<UnionKeys<B>, keyof T>>
16
+ : T
17
+
18
+ /**
19
+ * Expose properties from all union variants.
20
+ * @deprectated
21
+ * @see https://github.com/telegraf/telegraf/issues/1388#issuecomment-791573609
22
+ * @see https://millsp.github.io/ts-toolbelt/modules/union_strict.html
23
+ */
24
+ export function deunionize<T extends object | undefined>(t: T) {
25
+ return t as Deunionize<T>
26
+ }
@@ -0,0 +1,119 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
2
+ import { MessageEntity, User } from '@telegraf/types'
3
+ import { Any, zip } from './util'
4
+
5
+ export type Nestable<Kind extends string> =
6
+ | string
7
+ | number
8
+ | boolean
9
+ | FmtString<Kind>
10
+ export type MaybeNestableList<Kind extends string> =
11
+ | Nestable<Kind>
12
+ | readonly Nestable<Kind>[]
13
+
14
+ export interface FmtString<Brand extends string> {
15
+ text: string
16
+ entities?: MessageEntity[]
17
+ parse_mode?: undefined
18
+ __to_nest: Brand
19
+ }
20
+
21
+ export class FmtString<Brand extends string = string>
22
+ implements FmtString<Brand>
23
+ {
24
+ constructor(
25
+ public text: string,
26
+ entities?: MessageEntity[]
27
+ ) {
28
+ if (entities) {
29
+ this.entities = entities
30
+ // force parse_mode to undefined if entities are present
31
+ this.parse_mode = undefined
32
+ }
33
+ }
34
+ static normalise(content: Nestable<string>) {
35
+ if (content instanceof FmtString) return content
36
+ return new FmtString(String(content))
37
+ }
38
+ }
39
+
40
+ const isArray: <T>(xs: T | readonly T[]) => xs is readonly T[] = Array.isArray
41
+
42
+ /** Given a base FmtString and something to append to it, mutates the base */
43
+ const _add = (base: FmtString, next: FmtString | Any) => {
44
+ const len = base.text.length
45
+ if (next instanceof FmtString) {
46
+ base.text = `${base.text}${next.text}`
47
+ // next.entities could be undefined and condition will fail
48
+ for (let i = 0; i < (next.entities?.length || 0); i++) {
49
+ // because of the above condition, next.entities[i] cannot be undefined
50
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
51
+ const entity = next.entities![i]!
52
+ // base.entities is ensured by caller
53
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
54
+ base.entities!.push({ ...entity, offset: entity.offset + len })
55
+ }
56
+ } else base.text = `${base.text}${next}`
57
+ }
58
+
59
+ /**
60
+ * Given an `Iterable<FmtString | string | Any>` and a separator, flattens the list into a single FmtString.
61
+ * Analogous to Array#join -> string, but for FmtString
62
+ */
63
+ export const join = (
64
+ fragments: Iterable<FmtString | string | Any>,
65
+ separator?: string | FmtString
66
+ ) => {
67
+ const result = new FmtString('')
68
+ // ensure entities array so loop doesn't need to check
69
+ result.entities = []
70
+
71
+ const iter = fragments[Symbol.iterator]()
72
+
73
+ let curr = iter.next()
74
+ while (!curr.done) {
75
+ _add(result, curr.value)
76
+ curr = iter.next()
77
+ if (separator && !curr.done) _add(result, separator)
78
+ }
79
+
80
+ // set parse_mode: undefined if entities are present
81
+ if (result.entities.length) result.parse_mode = undefined
82
+ // remove entities array if not relevant
83
+ else delete result.entities
84
+
85
+ return result
86
+ }
87
+
88
+ /** Internal constructor for all fmt helpers */
89
+ export function createFmt(kind?: MessageEntity['type'], opts?: object) {
90
+ return function fmt(
91
+ parts: MaybeNestableList<string>,
92
+ ...items: Nestable<string>[]
93
+ ) {
94
+ parts = isArray(parts) ? parts : [parts]
95
+ const result = join(zip(parts, items))
96
+ if (kind) {
97
+ result.entities ??= []
98
+ result.entities.unshift({
99
+ type: kind,
100
+ offset: 0,
101
+ length: result.text.length,
102
+ ...opts,
103
+ } as MessageEntity)
104
+ result.parse_mode = undefined
105
+ }
106
+ return result
107
+ }
108
+ }
109
+
110
+ export const linkOrMention = (
111
+ content: Nestable<string>,
112
+ data:
113
+ | { type: 'text_link'; url: string }
114
+ | { type: 'text_mention'; user: User }
115
+ ) => {
116
+ const { text, entities = [] } = FmtString.normalise(content)
117
+ entities.unshift(Object.assign(data, { offset: 0, length: text.length }))
118
+ return new FmtString(text, entities)
119
+ }
@@ -0,0 +1,96 @@
1
+ import { FmtString } from './formatting'
2
+ import { Deunionize, UnionKeys } from './deunionize'
3
+
4
+ export const env = process.env
5
+
6
+ // eslint-disable-next-line @typescript-eslint/ban-types
7
+ export type Any = {} | undefined | null
8
+
9
+ export type Expand<T> = T extends object
10
+ ? T extends infer O
11
+ ? { [K in keyof O]: O[K] }
12
+ : never
13
+ : T
14
+
15
+ export type MaybeArray<T> = T | T[]
16
+ export type MaybePromise<T> = T | Promise<T>
17
+ export type NonemptyReadonlyArray<T> = readonly [T, ...T[]]
18
+
19
+ // prettier-ignore
20
+ export type ExclusiveKeys<A extends object, B extends object> = keyof Omit<A, keyof B>
21
+
22
+ export function fmtCaption<
23
+ Extra extends { caption?: string | FmtString } | undefined,
24
+ >(
25
+ extra?: Extra
26
+ ): Extra extends undefined
27
+ ? undefined
28
+ : Omit<Extra, 'caption'> & { caption?: string }
29
+
30
+ export function fmtCaption(extra?: { caption?: string | FmtString }) {
31
+ if (!extra) return
32
+ const caption = extra.caption
33
+ if (!caption || typeof caption === 'string') return extra
34
+ const { text, entities } = caption
35
+ return {
36
+ ...extra,
37
+ caption: text,
38
+ ...(entities && {
39
+ caption_entities: entities,
40
+ parse_mode: undefined,
41
+ }),
42
+ }
43
+ }
44
+
45
+ export type DistinctKeys<T extends object> = Exclude<UnionKeys<T>, keyof T>
46
+
47
+ // prettier-ignore
48
+ /* eslint-disable-next-line @typescript-eslint/ban-types */
49
+ export type KeyedDistinct<T extends object, K extends DistinctKeys<T>> = Record<K, {}> & Deunionize<Record<K, {}>, T>
50
+
51
+ // prettier-ignore
52
+ /* eslint-disable-next-line @typescript-eslint/ban-types */
53
+ export type Keyed<T extends object, K extends UnionKeys<T>> = Record<K, {}> & Deunionize<Record<K, {}>, T>
54
+
55
+ /** Construct a generic type guard */
56
+ export type Guard<X = unknown, Y extends X = X> = (x: X) => x is Y
57
+
58
+ /** Extract the guarded type from a type guard, defaults to never. */
59
+ export type Guarded<F> =
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ F extends (x: any) => x is infer T ? T : never
62
+
63
+ export function* zip<X, Y>(xs: Iterable<X>, ys: Iterable<Y>): Iterable<X | Y> {
64
+ const x = xs[Symbol.iterator]()
65
+ const y = ys[Symbol.iterator]()
66
+ let x1 = x.next()
67
+ let y1 = y.next()
68
+
69
+ while (!x1.done) {
70
+ yield x1.value
71
+ if (!y1.done) yield y1.value
72
+ x1 = x.next()
73
+ y1 = y.next()
74
+ }
75
+
76
+ while (!y1.done) {
77
+ yield y1.value
78
+ y1 = y.next()
79
+ }
80
+ }
81
+
82
+ export function indexed<T extends object, U>(
83
+ target: T,
84
+ indexer: (index: number) => U
85
+ ) {
86
+ return new Proxy(target, {
87
+ get: function (target, prop, receiver) {
88
+ if (
89
+ (typeof prop === 'string' || typeof prop === 'number') &&
90
+ !isNaN(+prop)
91
+ )
92
+ return indexer.call(target, +prop)
93
+ return Reflect.get(target, prop, receiver)
94
+ },
95
+ })
96
+ }