@tgify/tgify 0.1.0 → 0.1.4
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/LICENSE +23 -23
- package/README.md +356 -356
- package/lib/cli.mjs +9 -9
- package/package.json +1 -1
- package/src/button.ts +182 -182
- package/src/composer.ts +1008 -1008
- package/src/context.ts +1661 -1661
- package/src/core/helpers/args.ts +63 -63
- package/src/core/helpers/check.ts +71 -71
- package/src/core/helpers/compact.ts +18 -18
- package/src/core/helpers/deunionize.ts +26 -26
- package/src/core/helpers/formatting.ts +119 -119
- package/src/core/helpers/util.ts +96 -96
- package/src/core/network/client.ts +396 -396
- package/src/core/network/error.ts +29 -29
- package/src/core/network/multipart-stream.ts +45 -45
- package/src/core/network/polling.ts +94 -94
- package/src/core/network/webhook.ts +58 -58
- package/src/core/types/typegram.ts +54 -54
- package/src/filters.ts +109 -109
- package/src/format.ts +110 -110
- package/src/future.ts +213 -213
- package/src/index.ts +17 -17
- package/src/input.ts +59 -59
- package/src/markup.ts +142 -142
- package/src/middleware.ts +24 -24
- package/src/reactions.ts +118 -118
- package/src/router.ts +55 -55
- package/src/scenes/base.ts +52 -52
- package/src/scenes/context.ts +136 -136
- package/src/scenes/index.ts +21 -21
- package/src/scenes/stage.ts +71 -71
- package/src/scenes/wizard/context.ts +58 -58
- package/src/scenes/wizard/index.ts +63 -63
- package/src/scenes.ts +1 -1
- package/src/session.ts +204 -204
- package/src/telegraf.ts +354 -354
- package/src/telegram-types.ts +219 -219
- package/src/telegram.ts +1635 -1635
- package/src/types.ts +2 -2
- package/src/utils.ts +1 -1
- package/typings/telegraf.d.ts.map +1 -1
package/src/scenes/base.ts
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import { Middleware, MiddlewareFn } from '../middleware'
|
|
2
|
-
import Composer from '../composer'
|
|
3
|
-
import Context from '../context'
|
|
4
|
-
|
|
5
|
-
const { compose } = Composer
|
|
6
|
-
|
|
7
|
-
export interface SceneOptions<C extends Context> {
|
|
8
|
-
ttl?: number
|
|
9
|
-
handlers: ReadonlyArray<MiddlewareFn<C>>
|
|
10
|
-
enterHandlers: ReadonlyArray<MiddlewareFn<C>>
|
|
11
|
-
leaveHandlers: ReadonlyArray<MiddlewareFn<C>>
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class BaseScene<C extends Context = Context> extends Composer<C> {
|
|
15
|
-
id: string
|
|
16
|
-
ttl?: number
|
|
17
|
-
enterHandler: MiddlewareFn<C>
|
|
18
|
-
leaveHandler: MiddlewareFn<C>
|
|
19
|
-
constructor(id: string, options?: SceneOptions<C>) {
|
|
20
|
-
const opts: SceneOptions<C> = {
|
|
21
|
-
handlers: [],
|
|
22
|
-
enterHandlers: [],
|
|
23
|
-
leaveHandlers: [],
|
|
24
|
-
...options,
|
|
25
|
-
}
|
|
26
|
-
super(...opts.handlers)
|
|
27
|
-
this.id = id
|
|
28
|
-
this.ttl = opts.ttl
|
|
29
|
-
this.enterHandler = compose(opts.enterHandlers)
|
|
30
|
-
this.leaveHandler = compose(opts.leaveHandlers)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
enter(...fns: Array<Middleware<C>>) {
|
|
34
|
-
this.enterHandler = compose([this.enterHandler, ...fns])
|
|
35
|
-
return this
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
leave(...fns: Array<Middleware<C>>) {
|
|
39
|
-
this.leaveHandler = compose([this.leaveHandler, ...fns])
|
|
40
|
-
return this
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
enterMiddleware() {
|
|
44
|
-
return this.enterHandler
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
leaveMiddleware() {
|
|
48
|
-
return this.leaveHandler
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export default BaseScene
|
|
1
|
+
import { Middleware, MiddlewareFn } from '../middleware'
|
|
2
|
+
import Composer from '../composer'
|
|
3
|
+
import Context from '../context'
|
|
4
|
+
|
|
5
|
+
const { compose } = Composer
|
|
6
|
+
|
|
7
|
+
export interface SceneOptions<C extends Context> {
|
|
8
|
+
ttl?: number
|
|
9
|
+
handlers: ReadonlyArray<MiddlewareFn<C>>
|
|
10
|
+
enterHandlers: ReadonlyArray<MiddlewareFn<C>>
|
|
11
|
+
leaveHandlers: ReadonlyArray<MiddlewareFn<C>>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class BaseScene<C extends Context = Context> extends Composer<C> {
|
|
15
|
+
id: string
|
|
16
|
+
ttl?: number
|
|
17
|
+
enterHandler: MiddlewareFn<C>
|
|
18
|
+
leaveHandler: MiddlewareFn<C>
|
|
19
|
+
constructor(id: string, options?: SceneOptions<C>) {
|
|
20
|
+
const opts: SceneOptions<C> = {
|
|
21
|
+
handlers: [],
|
|
22
|
+
enterHandlers: [],
|
|
23
|
+
leaveHandlers: [],
|
|
24
|
+
...options,
|
|
25
|
+
}
|
|
26
|
+
super(...opts.handlers)
|
|
27
|
+
this.id = id
|
|
28
|
+
this.ttl = opts.ttl
|
|
29
|
+
this.enterHandler = compose(opts.enterHandlers)
|
|
30
|
+
this.leaveHandler = compose(opts.leaveHandlers)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
enter(...fns: Array<Middleware<C>>) {
|
|
34
|
+
this.enterHandler = compose([this.enterHandler, ...fns])
|
|
35
|
+
return this
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
leave(...fns: Array<Middleware<C>>) {
|
|
39
|
+
this.leaveHandler = compose([this.leaveHandler, ...fns])
|
|
40
|
+
return this
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
enterMiddleware() {
|
|
44
|
+
return this.enterHandler
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
leaveMiddleware() {
|
|
48
|
+
return this.leaveHandler
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default BaseScene
|
package/src/scenes/context.ts
CHANGED
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
import BaseScene from './base'
|
|
2
|
-
import Composer from '../composer'
|
|
3
|
-
import Context from '../context'
|
|
4
|
-
import d from 'debug'
|
|
5
|
-
import { SessionContext } from '../session'
|
|
6
|
-
const debug = d('telegraf:scenes:context')
|
|
7
|
-
|
|
8
|
-
const noop = () => Promise.resolve()
|
|
9
|
-
const now = () => Math.floor(Date.now() / 1000)
|
|
10
|
-
|
|
11
|
-
export interface SceneContext<D extends SceneSessionData = SceneSessionData>
|
|
12
|
-
extends Context {
|
|
13
|
-
session: SceneSession<D>
|
|
14
|
-
scene: SceneContextScene<SceneContext<D>, D>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface SceneSessionData {
|
|
18
|
-
current?: string
|
|
19
|
-
expires?: number
|
|
20
|
-
state?: object
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface SceneSession<S extends SceneSessionData = SceneSessionData> {
|
|
24
|
-
__scenes?: S
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface SceneContextSceneOptions<D extends SceneSessionData> {
|
|
28
|
-
ttl?: number
|
|
29
|
-
default?: string
|
|
30
|
-
defaultSession: D
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default class SceneContextScene<
|
|
34
|
-
C extends SessionContext<SceneSession<D>>,
|
|
35
|
-
D extends SceneSessionData = SceneSessionData,
|
|
36
|
-
> {
|
|
37
|
-
private readonly options: SceneContextSceneOptions<D>
|
|
38
|
-
|
|
39
|
-
constructor(
|
|
40
|
-
private readonly ctx: C,
|
|
41
|
-
private readonly scenes: Map<string, BaseScene<C>>,
|
|
42
|
-
options: Partial<SceneContextSceneOptions<D>>
|
|
43
|
-
) {
|
|
44
|
-
// @ts-expect-error {} might not be assignable to D
|
|
45
|
-
const fallbackSessionDefault: D = {}
|
|
46
|
-
|
|
47
|
-
this.options = { defaultSession: fallbackSessionDefault, ...options }
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get session(): D {
|
|
51
|
-
const defaultSession = Object.assign({}, this.options.defaultSession)
|
|
52
|
-
|
|
53
|
-
let session = this.ctx.session?.__scenes ?? defaultSession
|
|
54
|
-
if (session.expires !== undefined && session.expires < now()) {
|
|
55
|
-
session = defaultSession
|
|
56
|
-
}
|
|
57
|
-
if (this.ctx.session === undefined) {
|
|
58
|
-
this.ctx.session = { __scenes: session }
|
|
59
|
-
} else {
|
|
60
|
-
this.ctx.session.__scenes = session
|
|
61
|
-
}
|
|
62
|
-
return session
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
get state() {
|
|
66
|
-
return (this.session.state ??= {})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
set state(value) {
|
|
70
|
-
this.session.state = { ...value }
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
get current() {
|
|
74
|
-
const sceneId = this.session.current ?? this.options.default
|
|
75
|
-
return sceneId === undefined || !this.scenes.has(sceneId)
|
|
76
|
-
? undefined
|
|
77
|
-
: this.scenes.get(sceneId)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
reset() {
|
|
81
|
-
if (this.ctx.session !== undefined)
|
|
82
|
-
this.ctx.session.__scenes = Object.assign({}, this.options.defaultSession)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async enter(sceneId: string, initialState: object = {}, silent = false) {
|
|
86
|
-
if (!this.scenes.has(sceneId)) {
|
|
87
|
-
throw new Error(`Can't find scene: ${sceneId}`)
|
|
88
|
-
}
|
|
89
|
-
if (!silent) {
|
|
90
|
-
await this.leave()
|
|
91
|
-
}
|
|
92
|
-
debug('Entering scene', sceneId, initialState, silent)
|
|
93
|
-
this.session.current = sceneId
|
|
94
|
-
this.state = initialState
|
|
95
|
-
const ttl = this.current?.ttl ?? this.options.ttl
|
|
96
|
-
if (ttl !== undefined) {
|
|
97
|
-
this.session.expires = now() + ttl
|
|
98
|
-
}
|
|
99
|
-
if (this.current === undefined || silent) {
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
const handler =
|
|
103
|
-
'enterMiddleware' in this.current &&
|
|
104
|
-
typeof this.current.enterMiddleware === 'function'
|
|
105
|
-
? this.current.enterMiddleware()
|
|
106
|
-
: this.current.middleware()
|
|
107
|
-
return await handler(this.ctx, noop)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
reenter() {
|
|
111
|
-
return this.session.current === undefined
|
|
112
|
-
? undefined
|
|
113
|
-
: this.enter(this.session.current, this.state)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private leaving = false
|
|
117
|
-
async leave() {
|
|
118
|
-
if (this.leaving) return
|
|
119
|
-
debug('Leaving scene')
|
|
120
|
-
try {
|
|
121
|
-
this.leaving = true
|
|
122
|
-
if (this.current === undefined) {
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
const handler =
|
|
126
|
-
'leaveMiddleware' in this.current &&
|
|
127
|
-
typeof this.current.leaveMiddleware === 'function'
|
|
128
|
-
? this.current.leaveMiddleware()
|
|
129
|
-
: Composer.passThru()
|
|
130
|
-
await handler(this.ctx, noop)
|
|
131
|
-
return this.reset()
|
|
132
|
-
} finally {
|
|
133
|
-
this.leaving = false
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
1
|
+
import BaseScene from './base'
|
|
2
|
+
import Composer from '../composer'
|
|
3
|
+
import Context from '../context'
|
|
4
|
+
import d from 'debug'
|
|
5
|
+
import { SessionContext } from '../session'
|
|
6
|
+
const debug = d('telegraf:scenes:context')
|
|
7
|
+
|
|
8
|
+
const noop = () => Promise.resolve()
|
|
9
|
+
const now = () => Math.floor(Date.now() / 1000)
|
|
10
|
+
|
|
11
|
+
export interface SceneContext<D extends SceneSessionData = SceneSessionData>
|
|
12
|
+
extends Context {
|
|
13
|
+
session: SceneSession<D>
|
|
14
|
+
scene: SceneContextScene<SceneContext<D>, D>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SceneSessionData {
|
|
18
|
+
current?: string
|
|
19
|
+
expires?: number
|
|
20
|
+
state?: object
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SceneSession<S extends SceneSessionData = SceneSessionData> {
|
|
24
|
+
__scenes?: S
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SceneContextSceneOptions<D extends SceneSessionData> {
|
|
28
|
+
ttl?: number
|
|
29
|
+
default?: string
|
|
30
|
+
defaultSession: D
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default class SceneContextScene<
|
|
34
|
+
C extends SessionContext<SceneSession<D>>,
|
|
35
|
+
D extends SceneSessionData = SceneSessionData,
|
|
36
|
+
> {
|
|
37
|
+
private readonly options: SceneContextSceneOptions<D>
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
private readonly ctx: C,
|
|
41
|
+
private readonly scenes: Map<string, BaseScene<C>>,
|
|
42
|
+
options: Partial<SceneContextSceneOptions<D>>
|
|
43
|
+
) {
|
|
44
|
+
// @ts-expect-error {} might not be assignable to D
|
|
45
|
+
const fallbackSessionDefault: D = {}
|
|
46
|
+
|
|
47
|
+
this.options = { defaultSession: fallbackSessionDefault, ...options }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get session(): D {
|
|
51
|
+
const defaultSession = Object.assign({}, this.options.defaultSession)
|
|
52
|
+
|
|
53
|
+
let session = this.ctx.session?.__scenes ?? defaultSession
|
|
54
|
+
if (session.expires !== undefined && session.expires < now()) {
|
|
55
|
+
session = defaultSession
|
|
56
|
+
}
|
|
57
|
+
if (this.ctx.session === undefined) {
|
|
58
|
+
this.ctx.session = { __scenes: session }
|
|
59
|
+
} else {
|
|
60
|
+
this.ctx.session.__scenes = session
|
|
61
|
+
}
|
|
62
|
+
return session
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get state() {
|
|
66
|
+
return (this.session.state ??= {})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
set state(value) {
|
|
70
|
+
this.session.state = { ...value }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get current() {
|
|
74
|
+
const sceneId = this.session.current ?? this.options.default
|
|
75
|
+
return sceneId === undefined || !this.scenes.has(sceneId)
|
|
76
|
+
? undefined
|
|
77
|
+
: this.scenes.get(sceneId)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
reset() {
|
|
81
|
+
if (this.ctx.session !== undefined)
|
|
82
|
+
this.ctx.session.__scenes = Object.assign({}, this.options.defaultSession)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async enter(sceneId: string, initialState: object = {}, silent = false) {
|
|
86
|
+
if (!this.scenes.has(sceneId)) {
|
|
87
|
+
throw new Error(`Can't find scene: ${sceneId}`)
|
|
88
|
+
}
|
|
89
|
+
if (!silent) {
|
|
90
|
+
await this.leave()
|
|
91
|
+
}
|
|
92
|
+
debug('Entering scene', sceneId, initialState, silent)
|
|
93
|
+
this.session.current = sceneId
|
|
94
|
+
this.state = initialState
|
|
95
|
+
const ttl = this.current?.ttl ?? this.options.ttl
|
|
96
|
+
if (ttl !== undefined) {
|
|
97
|
+
this.session.expires = now() + ttl
|
|
98
|
+
}
|
|
99
|
+
if (this.current === undefined || silent) {
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
const handler =
|
|
103
|
+
'enterMiddleware' in this.current &&
|
|
104
|
+
typeof this.current.enterMiddleware === 'function'
|
|
105
|
+
? this.current.enterMiddleware()
|
|
106
|
+
: this.current.middleware()
|
|
107
|
+
return await handler(this.ctx, noop)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
reenter() {
|
|
111
|
+
return this.session.current === undefined
|
|
112
|
+
? undefined
|
|
113
|
+
: this.enter(this.session.current, this.state)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private leaving = false
|
|
117
|
+
async leave() {
|
|
118
|
+
if (this.leaving) return
|
|
119
|
+
debug('Leaving scene')
|
|
120
|
+
try {
|
|
121
|
+
this.leaving = true
|
|
122
|
+
if (this.current === undefined) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
const handler =
|
|
126
|
+
'leaveMiddleware' in this.current &&
|
|
127
|
+
typeof this.current.leaveMiddleware === 'function'
|
|
128
|
+
? this.current.leaveMiddleware()
|
|
129
|
+
: Composer.passThru()
|
|
130
|
+
await handler(this.ctx, noop)
|
|
131
|
+
return this.reset()
|
|
132
|
+
} finally {
|
|
133
|
+
this.leaving = false
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
package/src/scenes/index.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @see https://github.com/telegraf/telegraf/issues/705#issuecomment-549056045
|
|
3
|
-
* @see https://www.npmjs.com/package/telegraf-stateless-question
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export { Stage } from './stage'
|
|
8
|
-
export {
|
|
9
|
-
SceneContext,
|
|
10
|
-
SceneSession,
|
|
11
|
-
default as SceneContextScene,
|
|
12
|
-
SceneSessionData,
|
|
13
|
-
} from './context'
|
|
14
|
-
export { BaseScene } from './base'
|
|
15
|
-
export { WizardScene } from './wizard'
|
|
16
|
-
export {
|
|
17
|
-
WizardContext,
|
|
18
|
-
WizardSession,
|
|
19
|
-
default as WizardContextWizard,
|
|
20
|
-
WizardSessionData,
|
|
21
|
-
} from './wizard/context'
|
|
1
|
+
/**
|
|
2
|
+
* @see https://github.com/telegraf/telegraf/issues/705#issuecomment-549056045
|
|
3
|
+
* @see https://www.npmjs.com/package/telegraf-stateless-question
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { Stage } from './stage'
|
|
8
|
+
export {
|
|
9
|
+
SceneContext,
|
|
10
|
+
SceneSession,
|
|
11
|
+
default as SceneContextScene,
|
|
12
|
+
SceneSessionData,
|
|
13
|
+
} from './context'
|
|
14
|
+
export { BaseScene } from './base'
|
|
15
|
+
export { WizardScene } from './wizard'
|
|
16
|
+
export {
|
|
17
|
+
WizardContext,
|
|
18
|
+
WizardSession,
|
|
19
|
+
default as WizardContextWizard,
|
|
20
|
+
WizardSessionData,
|
|
21
|
+
} from './wizard/context'
|
package/src/scenes/stage.ts
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import { isSessionContext, SessionContext } from '../session'
|
|
2
|
-
import SceneContextScene, {
|
|
3
|
-
SceneContextSceneOptions,
|
|
4
|
-
SceneSession,
|
|
5
|
-
SceneSessionData,
|
|
6
|
-
} from './context'
|
|
7
|
-
import { BaseScene } from './base'
|
|
8
|
-
import { Composer } from '../composer'
|
|
9
|
-
import { Context } from '../context'
|
|
10
|
-
|
|
11
|
-
export class Stage<
|
|
12
|
-
C extends SessionContext<SceneSession<D>> & {
|
|
13
|
-
scene: SceneContextScene<C, D>
|
|
14
|
-
},
|
|
15
|
-
D extends SceneSessionData = SceneSessionData,
|
|
16
|
-
> extends Composer<C> {
|
|
17
|
-
options: Partial<SceneContextSceneOptions<D>>
|
|
18
|
-
scenes: Map<string, BaseScene<C>>
|
|
19
|
-
|
|
20
|
-
constructor(
|
|
21
|
-
scenes: ReadonlyArray<BaseScene<C>> = [],
|
|
22
|
-
options?: Partial<SceneContextSceneOptions<D>>
|
|
23
|
-
) {
|
|
24
|
-
super()
|
|
25
|
-
this.options = { ...options }
|
|
26
|
-
this.scenes = new Map<string, BaseScene<C>>()
|
|
27
|
-
scenes.forEach((scene) => this.register(scene))
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
register(...scenes: ReadonlyArray<BaseScene<C>>) {
|
|
31
|
-
scenes.forEach((scene) => {
|
|
32
|
-
if (scene?.id == null || typeof scene.middleware !== 'function') {
|
|
33
|
-
throw new Error('telegraf: Unsupported scene')
|
|
34
|
-
}
|
|
35
|
-
this.scenes.set(scene.id, scene)
|
|
36
|
-
})
|
|
37
|
-
return this
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
middleware() {
|
|
41
|
-
const handler = Composer.compose<C>([
|
|
42
|
-
(ctx, next) => {
|
|
43
|
-
const scenes: Map<string, BaseScene<C>> = this.scenes
|
|
44
|
-
const scene = new SceneContextScene<C, D>(ctx, scenes, this.options)
|
|
45
|
-
ctx.scene = scene
|
|
46
|
-
return next()
|
|
47
|
-
},
|
|
48
|
-
super.middleware(),
|
|
49
|
-
Composer.lazy<C>((ctx) => ctx.scene.current ?? Composer.passThru()),
|
|
50
|
-
])
|
|
51
|
-
return Composer.optional(isSessionContext, handler)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
static enter<C extends Context & { scene: SceneContextScene<C> }>(
|
|
55
|
-
...args: Parameters<SceneContextScene<C>['enter']>
|
|
56
|
-
) {
|
|
57
|
-
return (ctx: C) => ctx.scene.enter(...args)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
static reenter<C extends Context & { scene: SceneContextScene<C> }>(
|
|
61
|
-
...args: Parameters<SceneContextScene<C>['reenter']>
|
|
62
|
-
) {
|
|
63
|
-
return (ctx: C) => ctx.scene.reenter(...args)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
static leave<C extends Context & { scene: SceneContextScene<C> }>(
|
|
67
|
-
...args: Parameters<SceneContextScene<C>['leave']>
|
|
68
|
-
) {
|
|
69
|
-
return (ctx: C) => ctx.scene.leave(...args)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
1
|
+
import { isSessionContext, SessionContext } from '../session'
|
|
2
|
+
import SceneContextScene, {
|
|
3
|
+
SceneContextSceneOptions,
|
|
4
|
+
SceneSession,
|
|
5
|
+
SceneSessionData,
|
|
6
|
+
} from './context'
|
|
7
|
+
import { BaseScene } from './base'
|
|
8
|
+
import { Composer } from '../composer'
|
|
9
|
+
import { Context } from '../context'
|
|
10
|
+
|
|
11
|
+
export class Stage<
|
|
12
|
+
C extends SessionContext<SceneSession<D>> & {
|
|
13
|
+
scene: SceneContextScene<C, D>
|
|
14
|
+
},
|
|
15
|
+
D extends SceneSessionData = SceneSessionData,
|
|
16
|
+
> extends Composer<C> {
|
|
17
|
+
options: Partial<SceneContextSceneOptions<D>>
|
|
18
|
+
scenes: Map<string, BaseScene<C>>
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
scenes: ReadonlyArray<BaseScene<C>> = [],
|
|
22
|
+
options?: Partial<SceneContextSceneOptions<D>>
|
|
23
|
+
) {
|
|
24
|
+
super()
|
|
25
|
+
this.options = { ...options }
|
|
26
|
+
this.scenes = new Map<string, BaseScene<C>>()
|
|
27
|
+
scenes.forEach((scene) => this.register(scene))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
register(...scenes: ReadonlyArray<BaseScene<C>>) {
|
|
31
|
+
scenes.forEach((scene) => {
|
|
32
|
+
if (scene?.id == null || typeof scene.middleware !== 'function') {
|
|
33
|
+
throw new Error('telegraf: Unsupported scene')
|
|
34
|
+
}
|
|
35
|
+
this.scenes.set(scene.id, scene)
|
|
36
|
+
})
|
|
37
|
+
return this
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
middleware() {
|
|
41
|
+
const handler = Composer.compose<C>([
|
|
42
|
+
(ctx, next) => {
|
|
43
|
+
const scenes: Map<string, BaseScene<C>> = this.scenes
|
|
44
|
+
const scene = new SceneContextScene<C, D>(ctx, scenes, this.options)
|
|
45
|
+
ctx.scene = scene
|
|
46
|
+
return next()
|
|
47
|
+
},
|
|
48
|
+
super.middleware(),
|
|
49
|
+
Composer.lazy<C>((ctx) => ctx.scene.current ?? Composer.passThru()),
|
|
50
|
+
])
|
|
51
|
+
return Composer.optional(isSessionContext, handler)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static enter<C extends Context & { scene: SceneContextScene<C> }>(
|
|
55
|
+
...args: Parameters<SceneContextScene<C>['enter']>
|
|
56
|
+
) {
|
|
57
|
+
return (ctx: C) => ctx.scene.enter(...args)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static reenter<C extends Context & { scene: SceneContextScene<C> }>(
|
|
61
|
+
...args: Parameters<SceneContextScene<C>['reenter']>
|
|
62
|
+
) {
|
|
63
|
+
return (ctx: C) => ctx.scene.reenter(...args)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static leave<C extends Context & { scene: SceneContextScene<C> }>(
|
|
67
|
+
...args: Parameters<SceneContextScene<C>['leave']>
|
|
68
|
+
) {
|
|
69
|
+
return (ctx: C) => ctx.scene.leave(...args)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import SceneContextScene, { SceneSession, SceneSessionData } from '../context'
|
|
2
|
-
import Context from '../../context'
|
|
3
|
-
import { Middleware } from '../../middleware'
|
|
4
|
-
import { SessionContext } from '../../session'
|
|
5
|
-
|
|
6
|
-
export interface WizardContext<D extends WizardSessionData = WizardSessionData>
|
|
7
|
-
extends Context {
|
|
8
|
-
session: WizardSession<D>
|
|
9
|
-
scene: SceneContextScene<WizardContext<D>, D>
|
|
10
|
-
wizard: WizardContextWizard<WizardContext<D>>
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface WizardSessionData extends SceneSessionData {
|
|
14
|
-
cursor: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface WizardSession<S extends WizardSessionData = WizardSessionData>
|
|
18
|
-
extends SceneSession<S> {}
|
|
19
|
-
|
|
20
|
-
export default class WizardContextWizard<
|
|
21
|
-
C extends SessionContext<WizardSession> & {
|
|
22
|
-
scene: SceneContextScene<C, WizardSessionData>
|
|
23
|
-
},
|
|
24
|
-
> {
|
|
25
|
-
readonly state: object
|
|
26
|
-
constructor(
|
|
27
|
-
private readonly ctx: C,
|
|
28
|
-
private readonly steps: ReadonlyArray<Middleware<C>>
|
|
29
|
-
) {
|
|
30
|
-
this.state = ctx.scene.state
|
|
31
|
-
this.cursor = ctx.scene.session.cursor ?? 0
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get step() {
|
|
35
|
-
return this.steps[this.cursor]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
get cursor() {
|
|
39
|
-
return this.ctx.scene.session.cursor
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
set cursor(cursor: number) {
|
|
43
|
-
this.ctx.scene.session.cursor = cursor
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
selectStep(index: number) {
|
|
47
|
-
this.cursor = index
|
|
48
|
-
return this
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
next() {
|
|
52
|
-
return this.selectStep(this.cursor + 1)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
back() {
|
|
56
|
-
return this.selectStep(this.cursor - 1)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
import SceneContextScene, { SceneSession, SceneSessionData } from '../context'
|
|
2
|
+
import Context from '../../context'
|
|
3
|
+
import { Middleware } from '../../middleware'
|
|
4
|
+
import { SessionContext } from '../../session'
|
|
5
|
+
|
|
6
|
+
export interface WizardContext<D extends WizardSessionData = WizardSessionData>
|
|
7
|
+
extends Context {
|
|
8
|
+
session: WizardSession<D>
|
|
9
|
+
scene: SceneContextScene<WizardContext<D>, D>
|
|
10
|
+
wizard: WizardContextWizard<WizardContext<D>>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface WizardSessionData extends SceneSessionData {
|
|
14
|
+
cursor: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface WizardSession<S extends WizardSessionData = WizardSessionData>
|
|
18
|
+
extends SceneSession<S> {}
|
|
19
|
+
|
|
20
|
+
export default class WizardContextWizard<
|
|
21
|
+
C extends SessionContext<WizardSession> & {
|
|
22
|
+
scene: SceneContextScene<C, WizardSessionData>
|
|
23
|
+
},
|
|
24
|
+
> {
|
|
25
|
+
readonly state: object
|
|
26
|
+
constructor(
|
|
27
|
+
private readonly ctx: C,
|
|
28
|
+
private readonly steps: ReadonlyArray<Middleware<C>>
|
|
29
|
+
) {
|
|
30
|
+
this.state = ctx.scene.state
|
|
31
|
+
this.cursor = ctx.scene.session.cursor ?? 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get step() {
|
|
35
|
+
return this.steps[this.cursor]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get cursor() {
|
|
39
|
+
return this.ctx.scene.session.cursor
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
set cursor(cursor: number) {
|
|
43
|
+
this.ctx.scene.session.cursor = cursor
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
selectStep(index: number) {
|
|
47
|
+
this.cursor = index
|
|
48
|
+
return this
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
next() {
|
|
52
|
+
return this.selectStep(this.cursor + 1)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
back() {
|
|
56
|
+
return this.selectStep(this.cursor - 1)
|
|
57
|
+
}
|
|
58
|
+
}
|