Skip to content

Commit

Permalink
feat(core): support experimental Schema.dynamic()
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 6, 2023
1 parent 767a1ce commit 5d5ba30
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 41 deletions.
46 changes: 5 additions & 41 deletions packages/core/src/filter.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,15 @@
import { defineProperty } from 'cosmokit'
import { Context, Schema, Session } from '@satorijs/core'
import { Context, Session } from '@satorijs/core'
import { Eval } from '@minatojs/core'
import { Channel, User } from './database'

declare global {
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>>>
}

namespace Path {
interface Options {
filters?: Filter[]
allowCreate?: boolean
}

type Filter = FileFilter | 'file' | 'directory'

interface FileFilter {
name: string
extensions: string[]
}
}

export namespace Computed {
export interface Options {
userFields?: User.Field[]
channelFields?: Channel.Field[]
}
}
export namespace Computed {
export interface Options {
userFields?: User.Field[]
channelFields?: Channel.Field[]
}
}

Schema.filter = function filter() {
return Schema.any().role('filter')
}

Schema.computed = function computed(inner, options = {}) {
return Schema.union([inner, Schema.any().hidden()]).role('computed', options)
}

Schema.path = function path(options = {}) {
return Schema.string().role('path', options)
}

export type Computed<T> = T | Eval.Expr<T> | ((session: Session) => T)
export type Filter = (session: Session) => boolean

Expand Down
51 changes: 51 additions & 0 deletions packages/core/src/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,47 @@
import { Dict, remove } from 'cosmokit'
import { Context, Schema } from '@satorijs/core'
import { Computed } from './filter'

declare global {
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.any().hidden()]).role('computed', options)
}

Schema.path = function path(options = {}) {
return Schema.string().role('path', options)
}

const kSchemaOrder = Symbol('schema-order')

Expand Down Expand Up @@ -37,6 +79,15 @@ export class SchemaService {
get(name: string) {
return this._data[name] ||= Schema.intersect([])
}

set(name: string, schema: Schema) {
this._data[name] = schema
this.ctx.emit('internal/schema', name)
this[Context.current]?.on('dispose', () => {
delete this._data[name]
this.ctx.emit('internal/schema', name)
})
}
}

Context.service('schema', SchemaService)

0 comments on commit 5d5ba30

Please sign in to comment.