New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@koishijs/core

Package Overview
Dependencies
Maintainers
1
Versions
167
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@koishijs/core - npm Package Compare versions

Comparing version 4.17.8 to 4.17.9

src/schema.ts

95

lib/index.d.ts

@@ -7,3 +7,3 @@ import * as utils from '@koishijs/utils';

import { Driver, FlatKeys, FlatPick, Update, Eval } from 'minato';
import { Fragment, EventOptions, h, Schema, Universal, Bot, HTTP } from '@satorijs/core';
import { Fragment, EventOptions, Hook, h, Schema, Universal, Bot, HTTP } from '@satorijs/core';
import { LocaleTree } from '@koishijs/i18n-utils';

@@ -80,3 +80,5 @@ import { Disposable, GetEvents, Parameters, ReturnType, ThisType } from 'cordis';

}
export class KoishiDatabase {
declare interface KoishiDatabase extends minato.Database<Tables, Types, Context> {
}
declare class KoishiDatabase {
ctx: Context;

@@ -143,3 +145,3 @@ constructor(ctx: Context);

private ctx;
_hooks: [Context, Middleware, EventOptions][];
_hooks: Hook[];
_sessions: Dict<Session>;

@@ -150,4 +152,3 @@ _userCache: SharedCache<User.Observed<keyof User>>;

constructor(ctx: Context);
protected get caller(): Context;
middleware(middleware: Middleware, options?: boolean | EventOptions): any;
middleware(middleware: Middleware, options?: boolean | EventOptions): () => any;
match(pattern: string | RegExp, response: Matcher.Response, options: Matcher.Options): () => void;

@@ -254,3 +255,2 @@ private _executeMatcher;

constructor(ctx: Context);
private get caller();
define<P extends string>(pattern: P, options: Permissions.Options<P>): () => boolean;

@@ -322,2 +322,3 @@ provide<P extends string>(pattern: P, check: Permissions.Check<P>): () => boolean;

natural: number;
bigint: bigint;
date: Date;

@@ -550,5 +551,10 @@ img: JSX.IntrinsicElements['img'];

}
declare interface Task {
delay: number;
content: Fragment;
resolve(ids: string[]): void;
reject(reason: any): void;
}
export type FieldCollector<T extends keyof Tables, K = keyof Tables[T], A extends any[] = any[], O extends {} = {}> = Iterable<K> | ((argv: Argv<never, never, A, O>, fields: Set<keyof Tables[T]>) => void);
export class Session<U extends User.Field = never, G extends Channel.Field = never, C extends Context = Context> extends satori.Session<C> {
static shadow: symbol;
export interface Session<U extends User.Field = never, G extends Channel.Field = never, C extends Context = Context> extends satori.Session<C> {
argv?: Argv<U, G>;

@@ -561,6 +567,32 @@ user?: User.Observed<U>;

response?: () => Promise<Fragment>;
private _stripped;
private _queuedTasks;
private _queuedTimeout;
resolve<T, R extends any[]>(source: T | Eval.Expr | ((session: this, ...args: R) => T), ...args: R): T extends Eval.Expr ? Eval<T> : T extends (...args: any[]) => any ? ReturnType<T> : T;
stripped: Stripped;
username: string;
send(fragment: Fragment, options?: Universal.SendOptions): Promise<string[]>;
cancelQueued(delay?: number): void;
sendQueued(content: Fragment, delay?: number): Promise<string[]>;
getChannel<K extends Channel.Field = never>(id?: string, fields?: K[]): Promise<Channel>;
observeChannel<T extends Channel.Field = never>(fields: Iterable<T>): Promise<Channel.Observed<T | G>>;
getUser<K extends User.Field = never>(userId?: string, fields?: K[]): Promise<User>;
observeUser<T extends User.Field = never>(fields: Iterable<T>): Promise<User.Observed<T | U>>;
withScope(scope: string, callback: () => Awaitable<string>): Promise<string>;
resolveScope(path: string): string;
text(path: string | string[], params?: object): string;
i18n(path: string | string[], params?: object): satori.Element[];
collect<T extends 'user' | 'channel'>(key: T, argv: Argv, fields?: Set<keyof Tables[T]>): Set<keyof Tables[T]>;
execute(content: string, next?: true | Next): Promise<string>;
execute(argv: Argv, next?: true | Next): Promise<string>;
middleware(middleware: Middleware<this>): () => boolean;
prompt(timeout?: number): Promise<string>;
prompt<T>(callback: (session: this) => Awaitable<T>, options?: PromptOptions): Promise<T>;
suggest(options: SuggestOptions): Promise<string>;
}
declare interface KoishiSession<U extends User.Field, G extends Channel.Field, C extends Context> extends Session<U, G, C> {
_stripped: Stripped;
_queuedTasks: Task[];
_queuedTimeout: NodeJS.Timeout;
}
declare class KoishiSession<U, G, C> {
constructor(ctx: C);
resolve<T, R extends any[]>(source: T | Eval.Expr | ((session: this, ...args: R) => T), ...args: R): T extends Eval.Expr ? Eval<T> : T extends (...args: any[]) => any ? ReturnType<T> : T;
_stripNickname(content: string): string;

@@ -572,9 +604,9 @@ /** @deprecated */

send(fragment: Fragment, options?: Universal.SendOptions): Promise<string[]>;
cancelQueued(delay?: any): void;
cancelQueued(delay?: number): void;
_next(): void;
sendQueued(content: Fragment, delay?: number): Promise<string[]>;
getChannel<K extends Channel.Field = never>(id?: string, fields?: K[]): Promise<any>;
getChannel<K extends Channel.Field = never>(id?: string, fields?: K[]): any;
_observeChannelLike<K extends Channel.Field = never>(channelId: string, fields?: Iterable<K>): Promise<Channel.Observed<keyof Channel>>;
observeChannel<T extends Channel.Field = never>(fields: Iterable<T>): Promise<Channel.Observed<T | G>>;
getUser<K extends User.Field = never>(userId?: string, fields?: K[]): Promise<any>;
getUser<K extends User.Field = never>(userId?: string, fields?: K[]): any;
observeUser<T extends User.Field = never>(fields: Iterable<T>): Promise<User.Observed<T | U>>;

@@ -588,3 +620,3 @@ withScope(scope: string, callback: () => Awaitable<string>): Promise<string>;

execute(argv: Argv, next?: true | Next): Promise<string>;
middleware(middleware: Middleware<this>): () => boolean;
middleware(middleware: Middleware<this>): any;
prompt(timeout?: number): Promise<string>;

@@ -618,5 +650,4 @@ prompt<T>(callback: (session: this) => Awaitable<T>, options?: PromptOptions): Promise<T>;

export class FilterService {
private app;
constructor(app: Context);
protected get caller(): Context;
private ctx;
constructor(ctx: Context);
any(): Context;

@@ -632,3 +663,3 @@ never(): Context;

platform(...values: string[]): Context;
private(...values: string[]): Context;
private(): Context;
}

@@ -659,2 +690,18 @@ declare global {

}
declare module '@satorijs/core' {
interface Context {
schema: SchemaService;
}
interface Events {
'internal/schema'(name: string): void;
}
}
export class SchemaService {
ctx: Context;
_data: Dict<Schema>;
constructor(ctx: Context);
extend(name: string, schema: Schema, order?: number): void;
get(name: string): Schema;
set(name: string, schema: Schema): void;
}
export type EffectScope = cordis.EffectScope<Context>;

@@ -686,9 +733,10 @@ export type ForkScope = cordis.ForkScope<Context>;

[Context.session]: Session<never, never, this>;
koishi: Koishi;
}
export class Context extends satori.Context {
static readonly Session: typeof Session;
static shadow: symbol;
constructor(config?: Context.Config);
/** @deprecated use `ctx.root` instead */
get app(): this;
/** @deprecated use `root.config` instead */
/** @deprecated use `koishi.config` instead */
get options(): any;

@@ -747,9 +795,8 @@ /** @deprecated */

}
export interface KoishiBot extends Bot<Context> {
declare interface KoishiBot extends Bot<Context> {
}
export class KoishiBot {
declare class KoishiBot {
constructor(ctx: Context);
getGuildMemberMap(guildId: string): Promise<Dict<string>>;
broadcast(channels: (string | [string, string] | Session)[], content: Fragment, delay?: any): Promise<string[]>;
session(event?: Partial<Event>): any;
}

@@ -756,0 +803,0 @@ export * from '@koishijs/utils';

{
"name": "@koishijs/core",
"description": "Core Features for Koishi",
"version": "4.17.8",
"version": "4.17.9",
"main": "lib/index.cjs",

@@ -36,8 +36,8 @@ "module": "lib/index.mjs",

"@koishijs/utils": "^7.2.1",
"@satorijs/core": "^4.1.1",
"cordis": "^3.16.1",
"@satorijs/core": "^4.1.2",
"cordis": "^3.17.1",
"cosmokit": "^1.6.2",
"fastest-levenshtein": "^1.0.16",
"minato": "^3.4.0"
"minato": "^3.4.1"
}
}

@@ -19,9 +19,10 @@ import { sleep } from '@koishijs/utils'

export interface KoishiBot extends Bot<Context> {}
interface KoishiBot extends Bot<Context> {}
export class KoishiBot {
class KoishiBot {
constructor(ctx: Context) {
ctx.accessor('bot.getGuildMemberMap', { get: () => this.getGuildMemberMap })
ctx.accessor('bot.broadcast', { get: () => this.broadcast })
ctx.accessor('bot.session', { get: () => this.session })
ctx.mixin(this, {
getGuildMemberMap: 'bot.getGuildMemberMap',
broadcast: 'bot.broadcast',
})
}

@@ -54,6 +55,4 @@

}
}
session(event: Partial<Event> = {}) {
return new Session(this, event)
}
}
export default KoishiBot

@@ -193,2 +193,10 @@ import { Awaitable, defineProperty, Time } from 'cosmokit'

this.domain('bigint', (source, session) => {
try {
return BigInt(source)
} catch {
throw new Error('internal.invalid-integer')
}
}, { numeric: true })
this.domain('date', (source, session) => {

@@ -323,3 +331,2 @@ const timestamp = Time.parseDate(source)

const segments = path.split(/(?=[./])/g)
const caller: Context = this[Context.current]

@@ -351,4 +358,4 @@ /** parent command in the chain */

const isLast = index === segments.length - 1
command = new Command(name, isLast ? decl : '', caller, isLast ? config : {})
command._disposables.push(caller.i18n.define('', {
command = new Command(name, isLast ? decl : '', this.ctx, isLast ? config : {})
command._disposables.push(this.ctx.i18n.define('', {
[`commands.${command.name}.$`]: '',

@@ -367,5 +374,5 @@ [`commands.${command.name}.description`]: isLast ? desc : '',

// Make sure `command.config` is set before emitting any events
created.forEach(command => caller.emit('command-added', command))
parent[Context.current] = caller
if (root) caller.collect(`command <${root.name}>`, () => root.dispose())
created.forEach(command => this.ctx.emit('command-added', command))
parent[Context.current] = this.ctx
if (root) this.ctx.collect(`command <${root.name}>`, () => root.dispose())
return parent

@@ -377,6 +384,5 @@ }

domain<K extends keyof Argv.Domain>(name: K, transform?: Argv.Transform<Argv.Domain[K]>, options?: Argv.DomainConfig<Argv.Domain[K]>) {
const caller = this[Context.current] as Context
const service = 'domain:' + name
if (!transform) return caller.get(service)
return caller.set(service, { transform, ...options })
if (!transform) return this.ctx.get(service)
return this.ctx.set(service, { transform, ...options })
}

@@ -383,0 +389,0 @@

@@ -185,2 +185,3 @@ import { camelCase, Dict, paramCase } from 'cosmokit'

natural: number
bigint: bigint
date: Date

@@ -187,0 +188,0 @@ img: JSX.IntrinsicElements['img']

@@ -6,10 +6,12 @@ import { defineProperty, Promisify, Time } from 'cosmokit'

import * as cordis from 'cordis'
import * as minato from 'minato'
import { Computed, FilterService } from './filter'
import { Commander } from './command'
import { I18n } from './i18n'
import { Session } from './session'
import SessionMixin, { Session } from './session'
import { Processor } from './middleware'
import { Permissions } from './permission'
import { KoishiDatabase } from './database'
import { KoishiBot } from './bot'
import DatabaseMixin from './database'
import BotMixin from './bot'
import { SchemaService } from './schema'

@@ -46,6 +48,7 @@ export type EffectScope = cordis.EffectScope<Context>

[Context.session]: Session<never, never, this>
koishi: Koishi
}
export class Context extends satori.Context {
static readonly Session = Session
static shadow = Symbol.for('session.shadow')

@@ -61,2 +64,3 @@ constructor(config: Context.Config = {}) {

this.provide('$filter', new FilterService(this), true)
this.provide('schema', new SchemaService(this), true)
this.provide('$processor', new Processor(this), true)

@@ -68,4 +72,4 @@ this.provide('i18n', new I18n(this, this.config.i18n), true)

this.provide('$commander', new Commander(this, this.config), true)
this.provide('koishi.database', new KoishiDatabase(this), true)
this.provide('koishi.bot', new KoishiBot(this), true)
this.plugin(minato.Database)
this.plugin(Koishi, this.config)
}

@@ -78,3 +82,3 @@

/** @deprecated use `root.config` instead */
/** @deprecated use `koishi.config` instead */
get options() {

@@ -89,6 +93,6 @@ return this.root.config

async waterfall(...args: [any, ...any[]]) {
const thisArg = typeof args[0] === 'object' ? args.shift() : null
const thisArg = typeof args[0] === 'object' || typeof args[0] === 'function' ? args.shift() : null
const name = args.shift()
for (const callback of this.lifecycle.getHooks(name, thisArg)) {
const result = await callback.apply(thisArg, args)
for (const hook of this.lifecycle.filterHooks(this.lifecycle._hooks[name] || [], thisArg)) {
const result = await hook.callback.apply(thisArg, args)
args[0] = result

@@ -103,6 +107,6 @@ }

chain(...args: [any, ...any[]]) {
const thisArg = typeof args[0] === 'object' ? args.shift() : null
const thisArg = typeof args[0] === 'object' || typeof args[0] === 'function' ? args.shift() : null
const name = args.shift()
for (const callback of this.lifecycle.getHooks(name, thisArg)) {
const result = callback.apply(thisArg, args)
for (const hook of this.lifecycle.filterHooks(this.lifecycle._hooks[name] || [], thisArg)) {
const result = hook.callback.apply(thisArg, args)
args[0] = result

@@ -121,3 +125,13 @@ }

Session.prototype[Context.filter] = function (this: Session, ctx: Context) {
export default class Koishi extends cordis.Service<Context.Config, Context> {
bot = new BotMixin(this.ctx)
database = new DatabaseMixin(this.ctx)
session = new SessionMixin(this.ctx)
constructor(ctx: Context, public config: Context.Config) {
super(ctx, 'koishi', true)
}
}
satori.Session.prototype[Context.filter] = function (this: Session, ctx: Context) {
return ctx.filter(this)

@@ -124,0 +138,0 @@ }

@@ -90,8 +90,7 @@ import * as utils from '@koishijs/utils'

// Do not set "database" inject for this service.
export class KoishiDatabase {
interface KoishiDatabase extends minato.Database<Tables, Types, Context> {}
class KoishiDatabase {
constructor(public ctx: Context) {
ctx.plugin(minato.Database)
ctx.mixin('koishi.database', {
ctx.mixin(this, {
getUser: 'database.getUser',

@@ -156,5 +155,5 @@ setUser: 'database.setUser',

async getUser<K extends FlatKeys<User>>(platform: string, pid: string, modifier?: Driver.Cursor<K>): Promise<FlatPick<User, K>> {
const [binding] = await this.ctx.database.get('binding', { platform, pid }, ['aid'])
const [binding] = await this.get('binding', { platform, pid }, ['aid'])
if (!binding) return
const [user] = await this.ctx.database.get('user', { id: binding.aid }, modifier)
const [user] = await this.get('user', { id: binding.aid }, modifier)
return user

@@ -164,10 +163,10 @@ }

async setUser(platform: string, pid: string, data: Update<User>) {
const [binding] = await this.ctx.database.get('binding', { platform, pid }, ['aid'])
const [binding] = await this.get('binding', { platform, pid }, ['aid'])
if (!binding) throw new Error('user not found')
return this.ctx.database.set('user', binding.aid, data)
return this.set('user', binding.aid, data)
}
async createUser(platform: string, pid: string, data: Partial<User>) {
const user = await this.ctx.database.create('user', data)
await this.ctx.database.create('binding', { aid: user.id, bid: user.id, pid, platform })
const user = await this.create('user', data)
await this.create('binding', { aid: user.id, bid: user.id, pid, platform })
return user

@@ -178,4 +177,4 @@ }

getChannel<K extends FlatKeys<Channel>>(platform: string, ids: string[], modifier?: Driver.Cursor<K>): Promise<FlatPick<Channel, K>[]>
async getChannel(platform: string, id: MaybeArray<string>, modifier?: Driver.Cursor<Channel.Field>) {
const data = await this.ctx.database.get('channel', { platform, id }, modifier)
async getChannel(platform: string, id: MaybeArray<string>, modifier?: any) {
const data = await this.get('channel', { platform, id }, modifier)
if (Array.isArray(id)) return data

@@ -197,3 +196,3 @@ if (data[0]) Object.assign(data[0], { platform, id })

async getAssignedChannels(fields?: Channel.Field[], selfIdMap: Dict<string[]> = this.getSelfIds()) {
return this.ctx.database.get('channel', {
return this.get('channel', {
$or: Object.entries(selfIdMap).map(([platform, assignee]) => ({ platform, assignee })),

@@ -204,7 +203,7 @@ }, fields)

setChannel(platform: string, id: string, data: Update<Channel>) {
return this.ctx.database.set('channel', { platform, id }, data)
return this.set('channel', { platform, id }, data)
}
createChannel(platform: string, id: string, data: Partial<Channel>) {
return this.ctx.database.create('channel', { platform, id, ...data })
return this.create('channel', { platform, id, ...data })
}

@@ -236,3 +235,3 @@

if (channels?.length) {
this[Context.current].logger('app').warn('broadcast', 'channel not found: ', channels.join(', '))
this.ctx.logger('app').warn('broadcast', 'channel not found: ', channels.join(', '))
}

@@ -256,1 +255,3 @@

}
export default KoishiDatabase
import { defineProperty } from 'cosmokit'
import { Eval } from 'minato'
import { Schema } from '@satorijs/core'
import { Channel, User } from './database'

@@ -43,7 +42,7 @@ import { Context } from './context'

export class FilterService {
constructor(private app: Context) {
defineProperty(this, Context.current, app)
constructor(private ctx: Context) {
defineProperty(this, Context.current, ctx)
app.filter = () => true
app.on('internal/runtime', (runtime) => {
ctx.filter = () => true
ctx.on('internal/runtime', (runtime) => {
if (!runtime.uid) return

@@ -56,116 +55,48 @@ runtime.ctx.filter = (session) => {

protected get caller() {
return this[Context.current] as Context
}
any() {
return this.caller.extend({ filter: () => true })
return this.ctx.extend({ filter: () => true })
}
never() {
return this.caller.extend({ filter: () => false })
return this.ctx.extend({ filter: () => false })
}
union(arg: Filter | Context) {
const caller = this.caller
const filter = typeof arg === 'function' ? arg : arg.filter
return caller.extend({ filter: s => caller.filter(s) || filter(s) })
return this.ctx.extend({ filter: s => this.ctx.filter(s) || filter(s) })
}
intersect(arg: Filter | Context) {
const caller = this.caller
const filter = typeof arg === 'function' ? arg : arg.filter
return caller.extend({ filter: s => caller.filter(s) && filter(s) })
return this.ctx.extend({ filter: s => this.ctx.filter(s) && filter(s) })
}
exclude(arg: Filter | Context) {
const caller = this.caller
const filter = typeof arg === 'function' ? arg : arg.filter
return caller.extend({ filter: s => caller.filter(s) && !filter(s) })
return this.ctx.extend({ filter: s => this.ctx.filter(s) && !filter(s) })
}
user(...values: string[]) {
return property(this.caller, 'userId', ...values)
return property(this.ctx, 'userId', ...values)
}
self(...values: string[]) {
return property(this.caller, 'selfId', ...values)
return property(this.ctx, 'selfId', ...values)
}
guild(...values: string[]) {
return property(this.caller, 'guildId', ...values)
return property(this.ctx, 'guildId', ...values)
}
channel(...values: string[]) {
return property(this.caller, 'channelId', ...values)
return property(this.ctx, 'channelId', ...values)
}
platform(...values: string[]) {
return property(this.caller, 'platform', ...values)
return property(this.ctx, 'platform', ...values)
}
private(...values: string[]) {
return property(this.caller.exclude(property(this.caller, 'guildId')), 'userId', ...values)
private() {
return this.ctx.intersect((session) => session.isDirect)
}
}
declare global {
interface Schemastery<S, T> {
computed(options?: Computed.Options): Schema<Computed<S>, Computed<T>>
}
namespace Schemastery {
interface Static {
path(options?: Path.Options): Schema<string>
filter(): Schema<Computed<boolean>>
computed<X>(inner: X, options?: Computed.Options): Schema<Computed<TypeS<X>>, Computed<TypeT<X>>>
dynamic(name: string): Schema
}
namespace Path {
interface Options {
filters?: Filter[]
allowCreate?: boolean
}
type Filter = FileFilter | 'file' | 'directory'
interface FileFilter {
name: string
extensions: string[]
}
}
}
}
Schema.dynamic = function dynamic(name) {
return Schema.any().role('dynamic', { name }) as never
}
Schema.filter = function filter() {
return Schema.any().role('filter')
}
Schema.computed = function computed(inner, options = {}) {
return Schema.union([
Schema.from(inner),
Schema.object({
$switch: Schema.object({
branches: Schema.array(Schema.object({
case: Schema.any(),
then: Schema.from(inner),
})),
default: Schema.from(inner),
}),
}).hidden(),
Schema.any().hidden(),
]).role('computed', options)
}
Schema.path = function path(options = {}) {
return Schema.string().role('path', options)
}
Schema.prototype.computed = function computed(this: Schema, options = {}) {
return Schema.computed(this, options).default(this.meta.default)
}

@@ -128,3 +128,2 @@ import { distance } from 'fastest-levenshtein'

define(locale: string, ...args: [I18n.Store] | [string, I18n.Node]) {
const caller = this[Context.current] || this.ctx
const dict = this._data[locale] ||= {}

@@ -135,3 +134,3 @@ const paths = [...typeof args[0] === 'string'

this.ctx.emit('internal/i18n')
return caller.collect('i18n', () => {
return this.ctx.collect('i18n', () => {
for (const path of paths) {

@@ -138,0 +137,0 @@ delete dict[path]

@@ -11,2 +11,3 @@ // @ts-ignore

export * from './middleware'
export * from './schema'
export * from './session'

@@ -13,0 +14,0 @@ export * from './permission'

import { coerce, makeArray, Random } from '@koishijs/utils'
import { Awaitable, defineProperty, Dict, Time } from 'cosmokit'
import { EventOptions, Fragment, h } from '@satorijs/core'
import { EventOptions, Fragment, h, Hook } from '@satorijs/core'
import { Session } from './session'
import { Context } from './context'
import { Channel, User } from './database'
import { Session } from './session'

@@ -65,3 +65,3 @@ declare module './context' {

export class Processor {
_hooks: [Context, Middleware, EventOptions][] = []
_hooks: Hook[] = []
_sessions: Dict<Session> = Object.create(null)

@@ -136,6 +136,2 @@ _userCache = new SharedCache<User.Observed<keyof User>>()

protected get caller() {
return this[Context.current] as Context
}
middleware(middleware: Middleware, options?: boolean | EventOptions) {

@@ -145,9 +141,9 @@ if (typeof options !== 'object') {

}
return this.caller.lifecycle.register('middleware', this._hooks, middleware, options)
return this.ctx.lifecycle.register('middleware', this._hooks, middleware, options)
}
match(pattern: string | RegExp, response: Matcher.Response, options: Matcher.Options) {
const matcher: Matcher = { ...options, context: this.caller, pattern, response }
const matcher: Matcher = { ...options, context: this.ctx, pattern, response }
this._matchers.add(matcher)
return this.caller.collect('shortcut', () => {
return this.ctx.collect('shortcut', () => {
return this._matchers.delete(matcher)

@@ -248,5 +244,5 @@ })

this._sessions[session.id] = session
const queue: Next.Queue = this._hooks
.filter(([context]) => context.filter(session))
.map(([, middleware]) => middleware.bind(null, session))
const queue: Next.Queue = this.ctx.lifecycle
.filterHooks(this._hooks, session)
.map(({ callback }) => callback.bind(null, session))

@@ -253,0 +249,0 @@ // execute middlewares

import { Logger } from '@satorijs/core'
import { Awaitable, defineProperty, remove } from 'cosmokit'
import { Session } from './session'
import { Context } from './context'
import { createMatch, MatchResult } from './i18n'
import { Session } from './session'

@@ -66,6 +66,2 @@ const logger = new Logger('app')

private get caller(): Context {
return this[Context.current]
}
define<P extends string>(pattern: P, options: Permissions.Options<P>) {

@@ -77,3 +73,3 @@ const entry: Permissions.Entry = {

if (!pattern.includes('(')) entry.list ||= () => [pattern]
return this.caller.effect(() => {
return this.ctx.effect(() => {
this.store.push(entry)

@@ -139,3 +135,3 @@ return () => remove(this.store, entry)

async test(names: Iterable<string>, session: Partial<Session> = {}, cache: Map<string, Promise<boolean>> = new Map()) {
session = session[Session.shadow] || session
session = session[Context.shadow] || session
if (typeof names === 'string') names = [names]

@@ -142,0 +138,0 @@ for (const name of this.subgraph('depends', names)) {

@@ -59,5 +59,3 @@ import { observe } from '@koishijs/utils'

export class Session<U extends User.Field = never, G extends Channel.Field = never, C extends Context = Context> extends satori.Session<C> {
static shadow = Symbol.for('session.shadow')
export interface Session<U extends User.Field = never, G extends Channel.Field = never, C extends Context = Context> extends satori.Session<C> {
argv?: Argv<U, G>

@@ -67,10 +65,64 @@ user?: User.Observed<U>

guild?: Channel.Observed<G>
permissions: string[] = []
permissions: string[]
scope?: string
response?: () => Promise<Fragment>
resolve<T, R extends any[]>(source: T | Eval.Expr | ((session: this, ...args: R) => T), ...args: R):
| T extends Eval.Expr ? Eval<T>
: T extends (...args: any[]) => any ? ReturnType<T>
: T
stripped: Stripped
username: string
send(fragment: Fragment, options?: Universal.SendOptions): Promise<string[]>
cancelQueued(delay?: number): void
sendQueued(content: Fragment, delay?: number): Promise<string[]>
getChannel<K extends Channel.Field = never>(id?: string, fields?: K[]): Promise<Channel>
observeChannel<T extends Channel.Field = never>(fields: Iterable<T>): Promise<Channel.Observed<T | G>>
getUser<K extends User.Field = never>(userId?: string, fields?: K[]): Promise<User>
observeUser<T extends User.Field = never>(fields: Iterable<T>): Promise<User.Observed<T | U>>
withScope(scope: string, callback: () => Awaitable<string>): Promise<string>
resolveScope(path: string): string
text(path: string | string[], params?: object): string
i18n(path: string | string[], params?: object): satori.Element[]
collect<T extends 'user' | 'channel'>(key: T, argv: Argv, fields?: Set<keyof Tables[T]>): Set<keyof Tables[T]>
execute(content: string, next?: true | Next): Promise<string>
execute(argv: Argv, next?: true | Next): Promise<string>
middleware(middleware: Middleware<this>): () => boolean
prompt(timeout?: number): Promise<string>
prompt<T>(callback: (session: this) => Awaitable<T>, options?: PromptOptions): Promise<T>
suggest(options: SuggestOptions): Promise<string>
}
private _stripped: Stripped
private _queuedTasks: Task[] = []
private _queuedTimeout: NodeJS.Timeout
interface KoishiSession<U extends User.Field, G extends Channel.Field, C extends Context> extends Session<U, G, C> {
// DO NOT set class properties here,
// because they will override the actual properties in the instance.
_stripped: Stripped
_queuedTasks: Task[]
_queuedTimeout: NodeJS.Timeout
}
class KoishiSession<U, G, C> {
constructor(ctx: C) {
ctx.mixin(this, {
resolve: 'session.resolve',
stripped: 'session.stripped',
username: 'session.username',
send: 'session.send',
cancelQueued: 'session.cancelQueued',
sendQueued: 'session.sendQueued',
getChannel: 'session.getChannel',
observeChannel: 'session.observeChannel',
getUser: 'session.getUser',
observeUser: 'session.observeUser',
withScope: 'session.withScope',
resolveScope: 'session.resolveScope',
text: 'session.text',
i18n: 'session.i18n',
collect: 'session.collect',
execute: 'session.execute',
middleware: 'session.middleware',
prompt: 'session.prompt',
suggest: 'session.suggest',
})
}
resolve<T, R extends any[]>(source: T | Eval.Expr | ((session: this, ...args: R) => T), ...args: R):

@@ -91,3 +143,3 @@ | T extends Eval.Expr ? Eval<T>

if (content.startsWith('@')) content = content.slice(1)
for (const nickname of this.resolve(this.app.config.nickname) ?? []) {
for (const nickname of this.resolve(this.app.koishi.config.nickname) ?? []) {
if (!content.startsWith(nickname)) continue

@@ -157,3 +209,3 @@ const rest = content.slice(nickname.length)

cancelQueued(delay = this.app.config.delay.cancel) {
cancelQueued(delay = this.app.koishi.config.delay.cancel) {
clearTimeout(this._queuedTimeout)

@@ -165,3 +217,3 @@ this._queuedTasks = []

_next() {
const task = this._queuedTasks.shift()
const task = this._queuedTasks?.shift()
if (!task) {

@@ -179,7 +231,7 @@ this._queuedTimeout = null

if (isNullable(delay)) {
const { message, character } = this.app.config.delay
const { message, character } = this.app.koishi.config.delay
delay = Math.max(message, character * text.length)
}
return new Promise<string[]>((resolve, reject) => {
this._queuedTasks.push({ content, delay, resolve, reject })
(this._queuedTasks ??= []).push({ content, delay, resolve, reject })
if (!this._queuedTimeout) this._next()

@@ -194,3 +246,3 @@ })

if (channel) return channel
const assignee = this.resolve(app.config.autoAssign) ? this.selfId : ''
const assignee = this.resolve(app.koishi.config.autoAssign) ? this.selfId : ''
if (assignee) {

@@ -249,3 +301,3 @@ return app.database.createChannel(platform, id, { assignee, guildId, createdAt: new Date() })

if (user) return user
const authority = this.resolve(app.config.autoAuthorize)
const authority = this.resolve(app.koishi.config.autoAuthorize)
const data = { locales: this.locales, authority, createdAt: new Date() }

@@ -275,3 +327,3 @@ if (authority) {

const fallback = this.app.model.tables.user.create()
fallback.authority = this.resolve(this.app.config.autoAuthorize)
fallback.authority = this.resolve(this.app.koishi.config.autoAuthorize)
const user = observe(fallback, () => Promise.resolve())

@@ -330,3 +382,3 @@ return this.user = user

]
if (this.app.config.i18n.output === 'prefer-user') {
if (this.app.koishi.config.i18n.output === 'prefer-user') {
locales.unshift(...(this.user as User.Observed)?.locales || [])

@@ -449,3 +501,3 @@ } else {

resolve(undefined)
}, options.timeout ?? this.app.config.delay.prompt)
}, options.timeout ?? this.app.koishi.config.delay.prompt)
})

@@ -490,1 +542,3 @@ }

}
export default KoishiSession

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc