commit
This commit is contained in:
parent
be4fd23bcf
commit
0bd53741af
728 changed files with 86573 additions and 0 deletions
52
node_modules/telegraf/src/scenes/base.ts
generated
vendored
Normal file
52
node_modules/telegraf/src/scenes/base.ts
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { Middleware, MiddlewareFn } from '../middleware'
|
||||
import Composer from '../composer'
|
||||
import Context from '../context'
|
||||
|
||||
const { compose } = Composer
|
||||
|
||||
export interface SceneOptions<C extends Context> {
|
||||
ttl?: number
|
||||
handlers: ReadonlyArray<MiddlewareFn<C>>
|
||||
enterHandlers: ReadonlyArray<MiddlewareFn<C>>
|
||||
leaveHandlers: ReadonlyArray<MiddlewareFn<C>>
|
||||
}
|
||||
|
||||
export class BaseScene<C extends Context = Context> extends Composer<C> {
|
||||
id: string
|
||||
ttl?: number
|
||||
enterHandler: MiddlewareFn<C>
|
||||
leaveHandler: MiddlewareFn<C>
|
||||
constructor(id: string, options?: SceneOptions<C>) {
|
||||
const opts: SceneOptions<C> = {
|
||||
handlers: [],
|
||||
enterHandlers: [],
|
||||
leaveHandlers: [],
|
||||
...options,
|
||||
}
|
||||
super(...opts.handlers)
|
||||
this.id = id
|
||||
this.ttl = opts.ttl
|
||||
this.enterHandler = compose(opts.enterHandlers)
|
||||
this.leaveHandler = compose(opts.leaveHandlers)
|
||||
}
|
||||
|
||||
enter(...fns: Array<Middleware<C>>) {
|
||||
this.enterHandler = compose([this.enterHandler, ...fns])
|
||||
return this
|
||||
}
|
||||
|
||||
leave(...fns: Array<Middleware<C>>) {
|
||||
this.leaveHandler = compose([this.leaveHandler, ...fns])
|
||||
return this
|
||||
}
|
||||
|
||||
enterMiddleware() {
|
||||
return this.enterHandler
|
||||
}
|
||||
|
||||
leaveMiddleware() {
|
||||
return this.leaveHandler
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseScene
|
136
node_modules/telegraf/src/scenes/context.ts
generated
vendored
Normal file
136
node_modules/telegraf/src/scenes/context.ts
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
import BaseScene from './base'
|
||||
import Composer from '../composer'
|
||||
import Context from '../context'
|
||||
import d from 'debug'
|
||||
import { SessionContext } from '../session'
|
||||
const debug = d('telegraf:scenes:context')
|
||||
|
||||
const noop = () => Promise.resolve()
|
||||
const now = () => Math.floor(Date.now() / 1000)
|
||||
|
||||
export interface SceneContext<D extends SceneSessionData = SceneSessionData>
|
||||
extends Context {
|
||||
session: SceneSession<D>
|
||||
scene: SceneContextScene<SceneContext<D>, D>
|
||||
}
|
||||
|
||||
export interface SceneSessionData {
|
||||
current?: string
|
||||
expires?: number
|
||||
state?: object
|
||||
}
|
||||
|
||||
export interface SceneSession<S extends SceneSessionData = SceneSessionData> {
|
||||
__scenes: S
|
||||
}
|
||||
|
||||
export interface SceneContextSceneOptions<D extends SceneSessionData> {
|
||||
ttl?: number
|
||||
default?: string
|
||||
defaultSession: D
|
||||
}
|
||||
|
||||
export default class SceneContextScene<
|
||||
C extends SessionContext<SceneSession<D>>,
|
||||
D extends SceneSessionData = SceneSessionData
|
||||
> {
|
||||
private readonly options: SceneContextSceneOptions<D>
|
||||
|
||||
constructor(
|
||||
private readonly ctx: C,
|
||||
private readonly scenes: Map<string, BaseScene<C>>,
|
||||
options: Partial<SceneContextSceneOptions<D>>
|
||||
) {
|
||||
// @ts-expect-error {} might not be assignable to D
|
||||
const fallbackSessionDefault: D = {}
|
||||
|
||||
this.options = { defaultSession: fallbackSessionDefault, ...options }
|
||||
}
|
||||
|
||||
get session(): D {
|
||||
const defaultSession = this.options.defaultSession
|
||||
|
||||
let session = this.ctx.session?.__scenes ?? defaultSession
|
||||
if (session.expires !== undefined && session.expires < now()) {
|
||||
session = defaultSession
|
||||
}
|
||||
if (this.ctx.session === undefined) {
|
||||
this.ctx.session = { __scenes: session }
|
||||
} else {
|
||||
this.ctx.session.__scenes = session
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
||||
get state() {
|
||||
return (this.session.state ??= {})
|
||||
}
|
||||
|
||||
set state(value) {
|
||||
this.session.state = { ...value }
|
||||
}
|
||||
|
||||
get current() {
|
||||
const sceneId = this.session.current ?? this.options.default
|
||||
return sceneId === undefined || !this.scenes.has(sceneId)
|
||||
? undefined
|
||||
: this.scenes.get(sceneId)
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (this.ctx.session !== undefined)
|
||||
this.ctx.session.__scenes = this.options.defaultSession
|
||||
}
|
||||
|
||||
async enter(sceneId: string, initialState: object = {}, silent = false) {
|
||||
if (!this.scenes.has(sceneId)) {
|
||||
throw new Error(`Can't find scene: ${sceneId}`)
|
||||
}
|
||||
if (!silent) {
|
||||
await this.leave()
|
||||
}
|
||||
debug('Entering scene', sceneId, initialState, silent)
|
||||
this.session.current = sceneId
|
||||
this.state = initialState
|
||||
const ttl = this.current?.ttl ?? this.options.ttl
|
||||
if (ttl !== undefined) {
|
||||
this.session.expires = now() + ttl
|
||||
}
|
||||
if (this.current === undefined || silent) {
|
||||
return
|
||||
}
|
||||
const handler =
|
||||
'enterMiddleware' in this.current &&
|
||||
typeof this.current.enterMiddleware === 'function'
|
||||
? this.current.enterMiddleware()
|
||||
: this.current.middleware()
|
||||
return await handler(this.ctx, noop)
|
||||
}
|
||||
|
||||
reenter() {
|
||||
return this.session.current === undefined
|
||||
? undefined
|
||||
: this.enter(this.session.current, this.state)
|
||||
}
|
||||
|
||||
private leaving = false
|
||||
async leave() {
|
||||
if (this.leaving) return
|
||||
debug('Leaving scene')
|
||||
try {
|
||||
this.leaving = true
|
||||
if (this.current === undefined) {
|
||||
return
|
||||
}
|
||||
const handler =
|
||||
'leaveMiddleware' in this.current &&
|
||||
typeof this.current.leaveMiddleware === 'function'
|
||||
? this.current.leaveMiddleware()
|
||||
: Composer.passThru()
|
||||
await handler(this.ctx, noop)
|
||||
return this.reset()
|
||||
} finally {
|
||||
this.leaving = false
|
||||
}
|
||||
}
|
||||
}
|
21
node_modules/telegraf/src/scenes/index.ts
generated
vendored
Normal file
21
node_modules/telegraf/src/scenes/index.ts
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @see https://github.com/telegraf/telegraf/issues/705#issuecomment-549056045
|
||||
* @see https://www.npmjs.com/package/telegraf-stateless-question
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export { Stage } from './stage'
|
||||
export {
|
||||
SceneContext,
|
||||
SceneSession,
|
||||
default as SceneContextScene,
|
||||
SceneSessionData,
|
||||
} from './context'
|
||||
export { BaseScene } from './base'
|
||||
export { WizardScene } from './wizard'
|
||||
export {
|
||||
WizardContext,
|
||||
WizardSession,
|
||||
default as WizardContextWizard,
|
||||
WizardSessionData,
|
||||
} from './wizard/context'
|
71
node_modules/telegraf/src/scenes/stage.ts
generated
vendored
Normal file
71
node_modules/telegraf/src/scenes/stage.ts
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { isSessionContext, SessionContext } from '../session'
|
||||
import SceneContextScene, {
|
||||
SceneContextSceneOptions,
|
||||
SceneSession,
|
||||
SceneSessionData,
|
||||
} from './context'
|
||||
import { BaseScene } from './base'
|
||||
import { Composer } from '../composer'
|
||||
import { Context } from '../context'
|
||||
|
||||
export class Stage<
|
||||
C extends SessionContext<SceneSession<D>> & {
|
||||
scene: SceneContextScene<C, D>
|
||||
},
|
||||
D extends SceneSessionData = SceneSessionData
|
||||
> extends Composer<C> {
|
||||
options: Partial<SceneContextSceneOptions<D>>
|
||||
scenes: Map<string, BaseScene<C>>
|
||||
|
||||
constructor(
|
||||
scenes: ReadonlyArray<BaseScene<C>> = [],
|
||||
options?: Partial<SceneContextSceneOptions<D>>
|
||||
) {
|
||||
super()
|
||||
this.options = { ...options }
|
||||
this.scenes = new Map<string, BaseScene<C>>()
|
||||
scenes.forEach((scene) => this.register(scene))
|
||||
}
|
||||
|
||||
register(...scenes: ReadonlyArray<BaseScene<C>>) {
|
||||
scenes.forEach((scene) => {
|
||||
if (scene?.id == null || typeof scene.middleware !== 'function') {
|
||||
throw new Error('telegraf: Unsupported scene')
|
||||
}
|
||||
this.scenes.set(scene.id, scene)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
middleware() {
|
||||
const handler = Composer.compose<C>([
|
||||
(ctx, next) => {
|
||||
const scenes: Map<string, BaseScene<C>> = this.scenes
|
||||
const scene = new SceneContextScene<C, D>(ctx, scenes, this.options)
|
||||
ctx.scene = scene
|
||||
return next()
|
||||
},
|
||||
super.middleware(),
|
||||
Composer.lazy<C>((ctx) => ctx.scene.current ?? Composer.passThru()),
|
||||
])
|
||||
return Composer.optional(isSessionContext, handler)
|
||||
}
|
||||
|
||||
static enter<C extends Context & { scene: SceneContextScene<C> }>(
|
||||
...args: Parameters<SceneContextScene<C>['enter']>
|
||||
) {
|
||||
return (ctx: C) => ctx.scene.enter(...args)
|
||||
}
|
||||
|
||||
static reenter<C extends Context & { scene: SceneContextScene<C> }>(
|
||||
...args: Parameters<SceneContextScene<C>['reenter']>
|
||||
) {
|
||||
return (ctx: C) => ctx.scene.reenter(...args)
|
||||
}
|
||||
|
||||
static leave<C extends Context & { scene: SceneContextScene<C> }>(
|
||||
...args: Parameters<SceneContextScene<C>['leave']>
|
||||
) {
|
||||
return (ctx: C) => ctx.scene.leave(...args)
|
||||
}
|
||||
}
|
58
node_modules/telegraf/src/scenes/wizard/context.ts
generated
vendored
Normal file
58
node_modules/telegraf/src/scenes/wizard/context.ts
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
import SceneContextScene, { SceneSession, SceneSessionData } from '../context'
|
||||
import Context from '../../context'
|
||||
import { Middleware } from '../../middleware'
|
||||
import { SessionContext } from '../../session'
|
||||
|
||||
export interface WizardContext<D extends WizardSessionData = WizardSessionData>
|
||||
extends Context {
|
||||
session: WizardSession<D>
|
||||
scene: SceneContextScene<WizardContext<D>, D>
|
||||
wizard: WizardContextWizard<WizardContext<D>>
|
||||
}
|
||||
|
||||
export interface WizardSessionData extends SceneSessionData {
|
||||
cursor: number
|
||||
}
|
||||
|
||||
export interface WizardSession<S extends WizardSessionData = WizardSessionData>
|
||||
extends SceneSession<S> {}
|
||||
|
||||
export default class WizardContextWizard<
|
||||
C extends SessionContext<WizardSession> & {
|
||||
scene: SceneContextScene<C, WizardSessionData>
|
||||
}
|
||||
> {
|
||||
readonly state: object
|
||||
constructor(
|
||||
private readonly ctx: C,
|
||||
private readonly steps: ReadonlyArray<Middleware<C>>
|
||||
) {
|
||||
this.state = ctx.scene.state
|
||||
this.cursor = ctx.scene.session.cursor ?? 0
|
||||
}
|
||||
|
||||
get step() {
|
||||
return this.steps[this.cursor]
|
||||
}
|
||||
|
||||
get cursor() {
|
||||
return this.ctx.scene.session.cursor
|
||||
}
|
||||
|
||||
set cursor(cursor: number) {
|
||||
this.ctx.scene.session.cursor = cursor
|
||||
}
|
||||
|
||||
selectStep(index: number) {
|
||||
this.cursor = index
|
||||
return this
|
||||
}
|
||||
|
||||
next() {
|
||||
return this.selectStep(this.cursor + 1)
|
||||
}
|
||||
|
||||
back() {
|
||||
return this.selectStep(this.cursor - 1)
|
||||
}
|
||||
}
|
63
node_modules/telegraf/src/scenes/wizard/index.ts
generated
vendored
Normal file
63
node_modules/telegraf/src/scenes/wizard/index.ts
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
import BaseScene, { SceneOptions } from '../base'
|
||||
import { Middleware, MiddlewareObj } from '../../middleware'
|
||||
import WizardContextWizard, { WizardSessionData } from './context'
|
||||
import Composer from '../../composer'
|
||||
import Context from '../../context'
|
||||
import SceneContextScene from '../context'
|
||||
|
||||
export class WizardScene<
|
||||
C extends Context & {
|
||||
scene: SceneContextScene<C, WizardSessionData>
|
||||
wizard: WizardContextWizard<C>
|
||||
}
|
||||
>
|
||||
extends BaseScene<C>
|
||||
implements MiddlewareObj<C>
|
||||
{
|
||||
steps: Array<Middleware<C>>
|
||||
|
||||
constructor(id: string, ...steps: Array<Middleware<C>>)
|
||||
constructor(
|
||||
id: string,
|
||||
options: SceneOptions<C>,
|
||||
...steps: Array<Middleware<C>>
|
||||
)
|
||||
constructor(
|
||||
id: string,
|
||||
options: SceneOptions<C> | Middleware<C>,
|
||||
...steps: Array<Middleware<C>>
|
||||
) {
|
||||
let opts: SceneOptions<C> | undefined
|
||||
let s: Array<Middleware<C>>
|
||||
if (typeof options === 'function' || 'middleware' in options) {
|
||||
opts = undefined
|
||||
s = [options, ...steps]
|
||||
} else {
|
||||
opts = options
|
||||
s = steps
|
||||
}
|
||||
super(id, opts)
|
||||
this.steps = s
|
||||
}
|
||||
|
||||
middleware() {
|
||||
return Composer.compose<C>([
|
||||
(ctx, next) => {
|
||||
ctx.wizard = new WizardContextWizard<C>(ctx, this.steps)
|
||||
return next()
|
||||
},
|
||||
super.middleware(),
|
||||
(ctx, next) => {
|
||||
if (ctx.wizard.step === undefined) {
|
||||
ctx.wizard.selectStep(0)
|
||||
return ctx.scene.leave()
|
||||
}
|
||||
return Composer.unwrap(ctx.wizard.step)(ctx, next)
|
||||
},
|
||||
])
|
||||
}
|
||||
|
||||
enterMiddleware() {
|
||||
return Composer.compose([this.enterHandler, this.middleware()])
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue