chapterjs 0.1.4 → 0.2.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.
- package/dist/cli/build.js +9 -10
- package/dist/cli/dev.js +17 -16
- package/dist/cli/project.d.ts +38 -25
- package/dist/cli/project.js +199 -134
- package/dist/commands/command.d.ts +25 -11
- package/dist/commands/command.js +5 -5
- package/dist/commands/{convention.d.ts → declaration.d.ts} +24 -11
- package/dist/commands/{convention.js → declaration.js} +61 -33
- package/dist/commands/tree.d.ts +8 -4
- package/dist/commands/tree.js +16 -6
- package/dist/components/button.d.ts +13 -13
- package/dist/components/button.js +9 -11
- package/dist/components/component.d.ts +1 -1
- package/dist/components/component.js +1 -1
- package/dist/components/custom-id.d.ts +4 -4
- package/dist/components/custom-id.js +12 -12
- package/dist/components/declaration.d.ts +42 -0
- package/dist/components/{convention.js → declaration.js} +76 -73
- package/dist/components/declared.d.ts +29 -0
- package/dist/components/declared.js +49 -0
- package/dist/components/embed.d.ts +13 -12
- package/dist/components/embed.js +6 -6
- package/dist/components/instance.d.ts +3 -3
- package/dist/components/instance.js +2 -2
- package/dist/components/modal.d.ts +11 -10
- package/dist/components/modal.js +7 -8
- package/dist/components/router.d.ts +3 -2
- package/dist/components/router.js +14 -19
- package/dist/components/select.d.ts +14 -12
- package/dist/components/select.js +4 -4
- package/dist/events/declaration.d.ts +16 -0
- package/dist/events/declaration.js +80 -0
- package/dist/events/event.d.ts +42 -5
- package/dist/events/event.js +25 -11
- package/dist/events/registry.d.ts +1 -10
- package/dist/events/router.d.ts +3 -2
- package/dist/index.d.ts +11 -9
- package/dist/index.js +2 -0
- package/dist/loader/generated.d.ts +5 -32
- package/dist/loader/generated.js +21 -55
- package/dist/loader/loader.d.ts +57 -44
- package/dist/loader/loader.js +73 -89
- package/dist/main.d.ts +0 -1
- package/dist/main.js +2 -3
- package/dist/messages/commands.d.ts +3 -3
- package/dist/messages/commands.js +29 -10
- package/dist/messages/declaration.d.ts +89 -0
- package/dist/messages/declaration.js +455 -0
- package/dist/messages/messages.d.ts +65 -43
- package/dist/messages/messages.js +11 -10
- package/dist/messages/phrases.js +1 -1
- package/dist/messages/translate.d.ts +4 -4
- package/dist/messages/translate.js +4 -4
- package/dist/presence/declaration.d.ts +19 -0
- package/dist/presence/{convention.js → declaration.js} +13 -28
- package/dist/presence/presence.d.ts +7 -7
- package/dist/presence/presence.js +5 -5
- package/dist/structures/context.d.ts +1 -1
- package/dist/structures/interaction.d.ts +2 -2
- package/dist/structures/interaction.js +3 -3
- package/dist/structures/payload.d.ts +4 -4
- package/dist/structures/payload.js +4 -4
- package/dist/tasks/declaration.d.ts +16 -0
- package/dist/tasks/{convention.js → declaration.js} +14 -36
- package/dist/tasks/scheduler.d.ts +3 -1
- package/dist/tasks/scheduler.js +4 -4
- package/dist/tasks/task.d.ts +8 -9
- package/dist/tasks/task.js +6 -7
- package/package.json +1 -1
- package/dist/components/convention.d.ts +0 -35
- package/dist/components/file.d.ts +0 -30
- package/dist/components/file.js +0 -52
- package/dist/events/convention.d.ts +0 -25
- package/dist/events/convention.js +0 -97
- package/dist/events/types.d.ts +0 -7
- package/dist/events/types.js +0 -48
- package/dist/messages/convention.d.ts +0 -89
- package/dist/messages/convention.js +0 -347
- package/dist/presence/convention.d.ts +0 -26
- package/dist/tasks/convention.d.ts +0 -26
|
@@ -82,23 +82,24 @@ export interface EntitySelectConfig<Type extends EntitySelectType, Data extends
|
|
|
82
82
|
/** What a select file gives to `select()`: a menu of texts, or of things of the server. */
|
|
83
83
|
export type SelectConfig<Options extends SelectOptions = SelectOptions, Type extends EntitySelectType = EntitySelectType, Data extends DataShape = {}, Where extends ComponentWhere = 'guild'> = StringSelectConfig<Options, Data, Where> | EntitySelectConfig<Type, Data, Where>;
|
|
84
84
|
/**
|
|
85
|
-
* What `select()` returns:
|
|
86
|
-
* where you send a message, and call it with the data
|
|
87
|
-
* without data is used as is, or called with what to
|
|
85
|
+
* What `select()` returns: a declaration the framework finds in the exports
|
|
86
|
+
* of a file. Import it where you send a message, and call it with the data
|
|
87
|
+
* it carries; a menu without data is used as is, or called with what to
|
|
88
|
+
* show.
|
|
88
89
|
*/
|
|
89
|
-
export type
|
|
90
|
+
export type SelectDeclaration<Data extends DataShape = {}> = {
|
|
90
91
|
/** What the file gave to `select()`, not checked yet. */
|
|
91
92
|
readonly config: unknown;
|
|
92
93
|
} & ({} extends Data ? ((options?: SelectInstanceOptions) => SelectComponent) & SelectComponent : {} extends DataInputOf<Data> ? ((data?: DataInputOf<Data>, options?: SelectInstanceOptions) => SelectComponent) & SelectComponent : (data: DataInputOf<Data>, options?: SelectInstanceOptions) => SelectComponent);
|
|
93
94
|
/**
|
|
94
|
-
* Declares a select menu. Export the result
|
|
95
|
-
*
|
|
96
|
-
*
|
|
95
|
+
* Declares a select menu. Export the result from any file of `src/`: the
|
|
96
|
+
* name of the export is what tells the menu apart, so you never write an
|
|
97
|
+
* id.
|
|
97
98
|
*
|
|
98
99
|
* ```ts
|
|
99
100
|
* import { select } from 'chapterjs';
|
|
100
101
|
*
|
|
101
|
-
* export
|
|
102
|
+
* export const color = select({
|
|
102
103
|
* placeholder: 'Pick a color',
|
|
103
104
|
* options: { Red: 'red', Blue: 'blue' },
|
|
104
105
|
* async run({ interaction, value }) {
|
|
@@ -107,12 +108,13 @@ export type SelectFile<Data extends DataShape = {}> = {
|
|
|
107
108
|
* });
|
|
108
109
|
* ```
|
|
109
110
|
*/
|
|
110
|
-
export declare function select<const Options extends SelectOptions, const Data extends DataShape = {}, const Where extends ComponentWhere = 'guild'>(config: StringSelectConfig<Options, Data, Where>):
|
|
111
|
-
export declare function select<const Type extends EntitySelectType, const Data extends DataShape = {}, const Where extends ComponentWhere = 'guild'>(config: EntitySelectConfig<Type, Data, Where>):
|
|
112
|
-
/** A select
|
|
111
|
+
export declare function select<const Options extends SelectOptions, const Data extends DataShape = {}, const Where extends ComponentWhere = 'guild'>(config: StringSelectConfig<Options, Data, Where>): SelectDeclaration<Data>;
|
|
112
|
+
export declare function select<const Type extends EntitySelectType, const Data extends DataShape = {}, const Where extends ComponentWhere = 'guild'>(config: EntitySelectConfig<Type, Data, Where>): SelectDeclaration<Data>;
|
|
113
|
+
/** A select menu, checked. */
|
|
113
114
|
export interface LoadedSelect {
|
|
114
115
|
readonly kind: 'select';
|
|
115
|
-
|
|
116
|
+
/** The name of the export that declares it: its id for Discord. */
|
|
117
|
+
readonly name: string;
|
|
116
118
|
readonly type: SelectType;
|
|
117
119
|
/** The options of a menu of texts, their texts maybe computed when sent. */
|
|
118
120
|
readonly options: readonly LoadedOption[];
|
|
@@ -7,7 +7,7 @@ import { ChannelType } from '../discord/types/channel.js';
|
|
|
7
7
|
import { ComponentType, } from '../discord/types/component.js';
|
|
8
8
|
import { isDynamic, resolveText, } from './component.js';
|
|
9
9
|
import { checkData, encodeCustomId, } from './custom-id.js';
|
|
10
|
-
import {
|
|
10
|
+
import { createComponent } from './declared.js';
|
|
11
11
|
import { hasDynamicOption, resolveOptions, } from './options.js';
|
|
12
12
|
export const SELECT_TYPES = {
|
|
13
13
|
string: ComponentType.StringSelect,
|
|
@@ -17,7 +17,7 @@ export const SELECT_TYPES = {
|
|
|
17
17
|
channel: ComponentType.ChannelSelect,
|
|
18
18
|
};
|
|
19
19
|
export function select(config) {
|
|
20
|
-
return
|
|
20
|
+
return createComponent('select', config, {
|
|
21
21
|
asPiece: true,
|
|
22
22
|
pieceKind: 'select',
|
|
23
23
|
});
|
|
@@ -122,7 +122,7 @@ function readInstanceOptions(loaded, name, given) {
|
|
|
122
122
|
/** The menu as Discord takes it, for the data and the options given. */
|
|
123
123
|
export function renderSelect(loaded, args) {
|
|
124
124
|
const hasData = Object.keys(loaded.data).length > 0;
|
|
125
|
-
const name = loaded
|
|
125
|
+
const { name } = loaded;
|
|
126
126
|
if (args.length > (hasData ? 2 : 1)) {
|
|
127
127
|
fail(`${name} takes ${hasData ? 'its data, then options' : 'options'} at most.`);
|
|
128
128
|
}
|
|
@@ -133,7 +133,7 @@ export function renderSelect(loaded, args) {
|
|
|
133
133
|
const make = (context) => {
|
|
134
134
|
const placeholder = resolveText(`The placeholder of ${name}`, merged.placeholder, context, { max: Limits.SelectPlaceholder });
|
|
135
135
|
const base = {
|
|
136
|
-
custom_id: encodeCustomId(loaded.
|
|
136
|
+
custom_id: encodeCustomId(loaded.name, loaded.data, values),
|
|
137
137
|
...(placeholder !== undefined ? { placeholder } : {}),
|
|
138
138
|
...(loaded.min !== 1 ? { min_values: loaded.min } : {}),
|
|
139
139
|
...(loaded.max !== 1 ? { max_values: loaded.max } : {}),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Declaration } from '../loader/loader.js';
|
|
2
|
+
import { type EventContexts, type EventName } from './registry.js';
|
|
3
|
+
/** One reaction to an event, as a file declares it. */
|
|
4
|
+
export interface EventHandler<Name extends EventName = EventName> {
|
|
5
|
+
/** The event. */
|
|
6
|
+
readonly name: Name;
|
|
7
|
+
readonly handler: (context: EventContexts[Name]) => unknown;
|
|
8
|
+
/** The options the file gave to `event()`, checked. */
|
|
9
|
+
readonly options: Readonly<Record<string, unknown>>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* An event, declared anywhere in `src/` with `event()`: its `name` is the
|
|
13
|
+
* event, the rest its options and what to do. A file may declare several,
|
|
14
|
+
* of the same event or not.
|
|
15
|
+
*/
|
|
16
|
+
export declare const eventDeclaration: Declaration<EventHandler>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// What a file declares with `event()`, checked when it loads: the event
|
|
2
|
+
// exists, the options are the ones of that event, `run` is a function. A
|
|
3
|
+
// mistake is explained before the bot even connects.
|
|
4
|
+
import { isEventDeclaration } from './event.js';
|
|
5
|
+
import { EVENT_NAMES, EVENTS, isEventName, } from './registry.js';
|
|
6
|
+
const fail = message => {
|
|
7
|
+
throw new TypeError(message);
|
|
8
|
+
};
|
|
9
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
10
|
+
/** Checks the options written next to `name` against what the event accepts. */
|
|
11
|
+
function readOptions(name, options) {
|
|
12
|
+
const allowed = EVENTS[name].options ?? {};
|
|
13
|
+
const names = Object.keys(allowed);
|
|
14
|
+
const list = names.length === 0
|
|
15
|
+
? `${name} has no options: an event has a name, a run function, and nothing else.`
|
|
16
|
+
: `Options of ${name} are: ${names.join(', ')}.`;
|
|
17
|
+
for (const [key, value] of Object.entries(options)) {
|
|
18
|
+
if (!Object.hasOwn(allowed, key)) {
|
|
19
|
+
fail(`"${key}" is not an option of ${name}. ${list}`);
|
|
20
|
+
}
|
|
21
|
+
const kind = allowed[key];
|
|
22
|
+
const got = JSON.stringify(value) ?? typeof value;
|
|
23
|
+
if (kind === 'boolean') {
|
|
24
|
+
if (typeof value !== 'boolean') {
|
|
25
|
+
fail(`The option ${key} of ${name} is true or false, got ${got}.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else if (!kind.includes(value)) {
|
|
29
|
+
fail(`The option ${key} of ${name} is ${kind
|
|
30
|
+
.map(word => `'${word}'`)
|
|
31
|
+
.join(', ')
|
|
32
|
+
.replace(/, ([^,]*)$/, ' or $1')}, got ${got}.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return Object.freeze({ ...options });
|
|
36
|
+
}
|
|
37
|
+
/** " Did you mean "x"?" when a name is close to a real one. */
|
|
38
|
+
function suggest(name) {
|
|
39
|
+
const wanted = name.toLowerCase().replace(/[^a-z]/g, '');
|
|
40
|
+
if (wanted === '')
|
|
41
|
+
return '';
|
|
42
|
+
const close = EVENT_NAMES.find(event => {
|
|
43
|
+
const real = event.toLowerCase();
|
|
44
|
+
return real === wanted || real.includes(wanted) || wanted.includes(real);
|
|
45
|
+
});
|
|
46
|
+
return close ? ` Did you mean "${close}"?` : '';
|
|
47
|
+
}
|
|
48
|
+
const EXAMPLE = `event({ name: 'messageCreate', run({ message }) { ... } })`;
|
|
49
|
+
/**
|
|
50
|
+
* An event, declared anywhere in `src/` with `event()`: its `name` is the
|
|
51
|
+
* event, the rest its options and what to do. A file may declare several,
|
|
52
|
+
* of the same event or not.
|
|
53
|
+
*/
|
|
54
|
+
export const eventDeclaration = {
|
|
55
|
+
one: 'event',
|
|
56
|
+
many: 'events',
|
|
57
|
+
is: isEventDeclaration,
|
|
58
|
+
list: true,
|
|
59
|
+
read(value) {
|
|
60
|
+
const { config } = value;
|
|
61
|
+
if (!isRecord(config)) {
|
|
62
|
+
return fail(`event() needs an object: ${EXAMPLE}`);
|
|
63
|
+
}
|
|
64
|
+
const { name, run, ...options } = config;
|
|
65
|
+
if (name === undefined) {
|
|
66
|
+
fail(`This event has no "name": the event to react to, like ${EXAMPLE}. Events are: ${EVENT_NAMES.join(', ')}.`);
|
|
67
|
+
}
|
|
68
|
+
if (!isEventName(name)) {
|
|
69
|
+
fail(`${JSON.stringify(name) ?? typeof name} is not an event.${typeof name === 'string' ? suggest(name) : ''} Events are: ${EVENT_NAMES.join(', ')}.`);
|
|
70
|
+
}
|
|
71
|
+
if (typeof run !== 'function') {
|
|
72
|
+
fail(`This ${name} event has no "run": the function to run when it happens, like ${EXAMPLE}`);
|
|
73
|
+
}
|
|
74
|
+
return Object.freeze({
|
|
75
|
+
name,
|
|
76
|
+
handler: run,
|
|
77
|
+
options: readOptions(name, options),
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
};
|
package/dist/events/event.d.ts
CHANGED
|
@@ -1,8 +1,45 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ContextOf, EventName, OptionsOf } from './registry.js';
|
|
2
|
+
/** The options written next to `name` and `run`, as written. */
|
|
3
|
+
type OptionsWritten<Options> = {
|
|
4
|
+
[Key in keyof Options as Key extends 'name' | 'run' ? never : Key]: Options[Key];
|
|
5
|
+
};
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
7
|
+
* What a file gives to `event()`: the event, its options when it has
|
|
8
|
+
* some, and what to do. What `run` receives follows the options: what an
|
|
9
|
+
* option lets through is only there to handle when the option is on.
|
|
5
10
|
*/
|
|
6
|
-
export
|
|
11
|
+
export type EventConfig<Name extends EventName = EventName, Options extends object = {}> = {
|
|
12
|
+
/** The event to react to: `'messageCreate'`, `'memberJoin'`... */
|
|
13
|
+
name: Name;
|
|
14
|
+
/** What to do when the event happens. */
|
|
15
|
+
run: (context: ContextOf<Name, OptionsWritten<Options>>) => unknown;
|
|
16
|
+
} & Partial<OptionsOf<Name>> & {
|
|
17
|
+
[Key in keyof Options]: Key extends 'name' | 'run' ? unknown : Key extends keyof OptionsOf<Name> ? Options[Key] : never;
|
|
18
|
+
};
|
|
19
|
+
/** What `event()` returns: a declaration the framework finds in the exports of a file. */
|
|
20
|
+
export interface EventDeclaration<Name extends EventName = EventName> {
|
|
21
|
+
/** What the file gave to `event()`, not checked yet. */
|
|
22
|
+
readonly config: EventConfig<Name, never>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Declares what to do when an event happens. Export the result from any
|
|
26
|
+
* file of `src/`; `name` says which event, and types what `run` receives:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { event } from 'chapterjs';
|
|
30
|
+
*
|
|
31
|
+
* export const welcome = event({
|
|
32
|
+
* name: 'memberJoin',
|
|
33
|
+
* async run({ member, guild }) {
|
|
34
|
+
* await member.send(`Welcome to ${guild.name}!`);
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* Some events have options, written next to `name` (`bots: true`, `where:
|
|
40
|
+
* 'dm'`): what `run` receives follows them.
|
|
41
|
+
*/
|
|
42
|
+
export declare function event<Name extends EventName, const Options extends Partial<OptionsOf<Name>> & object = {}>(config: EventConfig<Name, Options>): EventDeclaration<Name>;
|
|
7
43
|
/** Whether a value was made by `event()`. */
|
|
8
|
-
export declare function
|
|
44
|
+
export declare function isEventDeclaration(value: unknown): value is EventDeclaration;
|
|
45
|
+
export {};
|
package/dist/events/event.js
CHANGED
|
@@ -1,19 +1,33 @@
|
|
|
1
|
-
// `event()`, as user files import it from 'chapterjs'
|
|
2
|
-
//
|
|
3
|
-
// the
|
|
1
|
+
// `event()`, as user files import it from 'chapterjs': what to do when
|
|
2
|
+
// something happens on Discord. The `name` of the event types the rest: what
|
|
3
|
+
// `run` receives, and the options the event has.
|
|
4
4
|
const BRAND = Symbol.for('chapterjs.event');
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Declares what to do when an event happens. Export the result from any
|
|
7
|
+
* file of `src/`; `name` says which event, and types what `run` receives:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { event } from 'chapterjs';
|
|
11
|
+
*
|
|
12
|
+
* export const welcome = event({
|
|
13
|
+
* name: 'memberJoin',
|
|
14
|
+
* async run({ member, guild }) {
|
|
15
|
+
* await member.send(`Welcome to ${guild.name}!`);
|
|
16
|
+
* },
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Some events have options, written next to `name` (`bots: true`, `where:
|
|
21
|
+
* 'dm'`): what `run` receives follows them.
|
|
8
22
|
*/
|
|
9
|
-
export function event(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
export function event(config) {
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
[BRAND]: true,
|
|
26
|
+
config,
|
|
27
|
+
});
|
|
14
28
|
}
|
|
15
29
|
/** Whether a value was made by `event()`. */
|
|
16
|
-
export function
|
|
30
|
+
export function isEventDeclaration(value) {
|
|
17
31
|
return (typeof value === 'object' &&
|
|
18
32
|
value !== null &&
|
|
19
33
|
value[BRAND] === true);
|
|
@@ -436,15 +436,6 @@ export interface EventContexts {
|
|
|
436
436
|
}
|
|
437
437
|
/** The name of an event: the name of a folder of `src/events/`. */
|
|
438
438
|
export type EventName = keyof EventContexts;
|
|
439
|
-
/**
|
|
440
|
-
* What `event()` returns: the default export of an event file.
|
|
441
|
-
*/
|
|
442
|
-
export interface EventFile {
|
|
443
|
-
/** The function to run when the event happens. */
|
|
444
|
-
readonly handler: (context: never) => unknown;
|
|
445
|
-
/** What the file passed as second argument, not checked yet. */
|
|
446
|
-
readonly options: unknown;
|
|
447
|
-
}
|
|
448
439
|
/**
|
|
449
440
|
* Where something happens: in servers (`'guild'`), in private messages with
|
|
450
441
|
* the bot (`'dm'`), or in both.
|
|
@@ -624,7 +615,7 @@ interface NarrowedContexts<Options> {
|
|
|
624
615
|
*/
|
|
625
616
|
export type ContextOf<Name extends EventName, Options = object> = (Name extends keyof NarrowedContexts<Options> ? NarrowedContexts<Options>[Name] : EventContexts[Name]) & TranslationContext;
|
|
626
617
|
/** The options of an event; nothing for an event without options. */
|
|
627
|
-
export type OptionsOf<Name extends EventName> = Name extends keyof EventOptions ? EventOptions[Name] :
|
|
618
|
+
export type OptionsOf<Name extends EventName> = Name extends keyof EventOptions ? EventOptions[Name] : {};
|
|
628
619
|
/** One gateway event an event comes from. */
|
|
629
620
|
interface Source<Name extends EventName, E extends GatewayDispatchEventName> {
|
|
630
621
|
on: E;
|
package/dist/events/router.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type CacheLimits } from '../cache/cache.js';
|
|
2
2
|
import type { GatewayDispatchEventName, GatewayDispatchEvents } from '../discord/types/gateway-events.js';
|
|
3
3
|
import type { Context } from '../structures/context.js';
|
|
4
|
-
import type { EventHandler } from './
|
|
4
|
+
import type { EventHandler } from './declaration.js';
|
|
5
5
|
import { type EventContexts, type EventName } from './registry.js';
|
|
6
|
-
/** A handler, with the file it comes from (to report its errors). */
|
|
6
|
+
/** A handler, with the file and the export it comes from (to report its errors). */
|
|
7
7
|
export interface LoadedEvent {
|
|
8
8
|
file: string;
|
|
9
|
+
export: string;
|
|
9
10
|
event: EventHandler;
|
|
10
11
|
}
|
|
11
12
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
export { command } from './commands/command.js';
|
|
2
|
-
export type { AutocompleteContext, ChannelOption, CommandAutocomplete, CommandConfig, CommandContext, CommandInDm, CommandInGuild, CommandInPrivate, CommandWhere,
|
|
2
|
+
export type { AutocompleteContext, ChannelOption, CommandAutocomplete, CommandConfig, CommandContext, CommandInDm, CommandInGuild, CommandInPrivate, CommandWhere, CommandDeclaration, CommandLocales, CommandName, CommandOption, CommandOptions, CommandTranslation, Cooldown, Duration, NumberOption, OptionsSoFar, OptionTranslation, OptionValuesOf, SimpleOption, StringOption, Suggestion, } from './commands/command.js';
|
|
3
3
|
export type { CommandInteraction, ComponentInteraction, DmCommandInteraction, GuildCommandInteraction, PrivateCommandInteraction, Interaction, InteractionReply, InteractionReplyOptions, ModalInteraction, } from './structures/interaction.js';
|
|
4
4
|
export type { DynamicText, TextContext } from './components/component.js';
|
|
5
5
|
export { button } from './components/button.js';
|
|
6
|
-
export type { ButtonConfig, ButtonContext,
|
|
6
|
+
export type { ButtonConfig, ButtonContext, ButtonDeclaration, ButtonLook, ButtonStyleName, } from './components/button.js';
|
|
7
7
|
export { select } from './components/select.js';
|
|
8
|
-
export type { EntitySelectConfig, EntitySelectType, SelectConfig, SelectContext,
|
|
8
|
+
export type { EntitySelectConfig, EntitySelectType, SelectConfig, SelectContext, SelectDeclaration, SelectInstanceOptions, SelectLook, SelectType, StringSelectConfig, } from './components/select.js';
|
|
9
9
|
export { modal } from './components/modal.js';
|
|
10
|
-
export type { CheckboxField, CheckboxesField, EntityField, FieldValue, FieldValuesOf, FilesField, ModalConfig, ModalContext, ModalField, ModalFields,
|
|
10
|
+
export type { CheckboxField, CheckboxesField, EntityField, FieldValue, FieldValuesOf, FilesField, ModalConfig, ModalContext, ModalField, ModalFields, ModalDeclaration, ModalInstanceOptions, ModalPrefill, NoteField, RadioField, SelectField, TextField, } from './components/modal.js';
|
|
11
11
|
export { embed } from './components/embed.js';
|
|
12
|
-
export type {
|
|
12
|
+
export type { EmbedDeclaration } from './components/embed.js';
|
|
13
13
|
export type { ComponentWhere, ComponentWho, InDm, InGuild, InPrivate, InteractiveConfig, InteractiveContext, PlaceInDm, PlaceInGuild, PlaceInPrivate, PlaceOf, } from './components/component.js';
|
|
14
14
|
export type { DataField, DataInputOf, DataKind, DataShape, DataValuesOf, } from './components/custom-id.js';
|
|
15
15
|
export type { OptionValue, RichOption, SelectOptions, } from './components/options.js';
|
|
16
16
|
export { container, file, gallery, linkButton, premiumButton, row, section, separator, text, thumbnail, } from './components/layout.js';
|
|
17
17
|
export type { ContainerOptions, LinkButtonOptions, MediaOptions, SeparatorOptions, } from './components/layout.js';
|
|
18
18
|
export type { ActionRowComponent, ButtonComponent, ContainerChild, ContainerComponent, FileComponent, GalleryComponent, MessageComponent, ModalComponent, Piece, SectionComponent, SelectComponent, SeparatorComponent, TextComponent, ThumbnailComponent, } from './components/instance.js';
|
|
19
|
-
export
|
|
19
|
+
export { event } from './events/event.js';
|
|
20
|
+
export type { EventConfig, EventDeclaration } from './events/event.js';
|
|
21
|
+
export type { ContextOf, EventWhere, WhereEventOptions, EventContexts, EventName, EventOptions, MessageEventOptions, ReactionEventOptions, } from './events/registry.js';
|
|
20
22
|
export type { CategoryChannel, Channel, DMChannel, FetchMessagesOptions, ForumChannel, ForumPostOptions, ForumTag, GuildChannel, GuildChannelEditOptions, InviteCreateOptions, PermissionOverwrite, TextBasedChannel, GuildTextBasedChannel, TextChannel, ThreadChannel, ThreadCreateOptions, ThreadEditOptions, ThreadMember, VoiceChannel, } from './structures/channel.js';
|
|
21
23
|
export type { GuildEmoji } from './structures/emoji.js';
|
|
22
24
|
export type { AuditLog, AuditLogEntry, AutoModerationRule, Ban, ChannelCreateOptions, Guild, GuildEditOptions, RoleCreateOptions, ScheduledEvent, Sticker, VoiceState, } from './structures/guild.js';
|
|
@@ -24,11 +26,11 @@ export type { Invite } from './structures/invite.js';
|
|
|
24
26
|
export type { BanOptions, GuildMember, MemberEditOptions, } from './structures/member.js';
|
|
25
27
|
export type { Attachment, EmojiInput, DmMessage, GuildMessage, MemberMessage, Message, PrivateMessage, MessageFlagName, Reaction, ReactionEmoji, } from './structures/message.js';
|
|
26
28
|
export { language } from './messages/messages.js';
|
|
27
|
-
export type { CommandsTranslations, FrameworkTexts, LanguageConfig,
|
|
29
|
+
export type { CommandsTranslations, FrameworkTexts, LanguageConfig, LanguageDeclaration, MergedMessages, MessagesOf, MessageText, MessageTexts, PluralText, ProjectCommands, ProjectLanguageDefaults, ParamsArgs, ParamsOf, Placeholders, ProjectLocale, ProjectLocales, LocaleGiven, ProjectMessages, TranslationContext, Translator, } from './messages/messages.js';
|
|
28
30
|
export { presence } from './presence/presence.js';
|
|
29
|
-
export type { Activity, ActivityKind, PlainActivity, PresenceConfig,
|
|
31
|
+
export type { Activity, ActivityKind, PlainActivity, PresenceConfig, PresenceDeclaration, PresenceStatusName, StreamingActivity, } from './presence/presence.js';
|
|
30
32
|
export { task } from './tasks/task.js';
|
|
31
|
-
export type { CronTaskConfig, EveryTaskConfig, TaskConfig, TaskContext,
|
|
33
|
+
export type { CronTaskConfig, EveryTaskConfig, TaskConfig, TaskContext, TaskDeclaration, } from './tasks/task.js';
|
|
32
34
|
export type { AssetFile, AssetOptions } from './assets/asset.js';
|
|
33
35
|
export type { AllowedMentions, Embed, FileInput, MessageEditOptions, MessageInput, MessageOptions, PollInput, } from './structures/payload.js';
|
|
34
36
|
export type { Role, RoleEditOptions } from './structures/role.js';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,8 @@ export { select } from './components/select.js';
|
|
|
16
16
|
export { modal } from './components/modal.js';
|
|
17
17
|
export { embed } from './components/embed.js';
|
|
18
18
|
export { container, file, gallery, linkButton, premiumButton, row, section, separator, text, thumbnail, } from './components/layout.js';
|
|
19
|
+
// What the functions of src/events/ receive, by event.
|
|
20
|
+
export { event } from './events/event.js';
|
|
19
21
|
// Tasks: what the files of src/tasks/ are written with.
|
|
20
22
|
export { language } from './messages/messages.js';
|
|
21
23
|
export { presence } from './presence/presence.js';
|
|
@@ -1,37 +1,10 @@
|
|
|
1
|
-
/** A folder of user files in which 'chapterjs' has its own types. */
|
|
2
|
-
export interface TypedFolder {
|
|
3
|
-
/** A unique name, used for file names: `events.memberJoin`. */
|
|
4
|
-
id: string;
|
|
5
|
-
/**
|
|
6
|
-
* The folder, from the project folder, with `/`. It may contain `**` to
|
|
7
|
-
* be found at any depth (inside `(group)` folders). It may also be one
|
|
8
|
-
* file (`src/messages/fr.ts`): a file whose 'chapterjs' is its own.
|
|
9
|
-
*/
|
|
10
|
-
folder: string;
|
|
11
|
-
/**
|
|
12
|
-
* What the project of this folder includes on top of its declarations:
|
|
13
|
-
* `shared` (what every file of the project gets, the default) and/or
|
|
14
|
-
* `main` (what the files outside typed folders get). A folder whose
|
|
15
|
-
* files `shared` refers to (a language file, which types `t` for every
|
|
16
|
-
* other file) takes `main` alone: through `shared`, the other files of
|
|
17
|
-
* its family would be checked with its declarations.
|
|
18
|
-
*/
|
|
19
|
-
includes?: readonly ('shared' | 'main')[];
|
|
20
|
-
/**
|
|
21
|
-
* The declarations 'chapterjs' has in this folder, on top of what the
|
|
22
|
-
* package exports. Written like a `.d.ts` that imports the package from
|
|
23
|
-
* `'#chapterjs'`.
|
|
24
|
-
*/
|
|
25
|
-
declarations: string;
|
|
26
|
-
}
|
|
27
1
|
/**
|
|
28
2
|
* Writes the `.chapterjs/` folder of a project. A file whose content did
|
|
29
3
|
* not change is left alone, so editors don't reload for nothing; what an
|
|
30
|
-
* older version wrote and this one does not is removed. `
|
|
31
|
-
* 'chapterjs'
|
|
32
|
-
*
|
|
33
|
-
* `'#chapterjs'
|
|
34
|
-
* same for the files outside typed folders only.
|
|
4
|
+
* older version wrote and this one does not is removed. `declarations` is
|
|
5
|
+
* what 'chapterjs' has in this project on top of the package: `declare
|
|
6
|
+
* module 'chapterjs'` augmentations, importing the package from
|
|
7
|
+
* `'#chapterjs'`.
|
|
35
8
|
* @returns how many files were written
|
|
36
9
|
*/
|
|
37
|
-
export declare function writeGenerated(projectDir: string,
|
|
10
|
+
export declare function writeGenerated(projectDir: string, declarations: string): Promise<number>;
|
package/dist/loader/generated.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
// The `.chapterjs/` folder of a project: what the framework writes so that
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// to the folder. The tsconfig of the user project only references this
|
|
10
|
-
// folder; editors and `tsc -b` find the project of each file by themselves.
|
|
2
|
+
// the files of the project are typed from the project itself, with nothing
|
|
3
|
+
// to write. Everything 'chapterjs' gives is typed by the package; what only
|
|
4
|
+
// the project knows (the files of `public/`, its languages, its commands)
|
|
5
|
+
// is written here as an augmentation of 'chapterjs', in one TypeScript
|
|
6
|
+
// project that covers every file of `src/`. The tsconfig of the user
|
|
7
|
+
// project only references this folder; editors and `tsc -b` find it by
|
|
8
|
+
// themselves.
|
|
11
9
|
import { existsSync } from 'node:fs';
|
|
12
10
|
import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
13
11
|
import { dirname, join, relative, sep } from 'node:path';
|
|
@@ -25,66 +23,34 @@ function packageSpecifier(projectDir) {
|
|
|
25
23
|
return `${path.split(sep).join('/')}/dist/index.js`;
|
|
26
24
|
}
|
|
27
25
|
/** Every file of `.chapterjs/`, by its path inside it. */
|
|
28
|
-
function generatedFiles(projectDir,
|
|
26
|
+
function generatedFiles(projectDir, declarations) {
|
|
29
27
|
const files = new Map();
|
|
30
28
|
const specifier = packageSpecifier(projectDir);
|
|
31
|
-
const types = (declarations) => `${HEADER}export * from '${specifier}';\n${declarations.replaceAll("'#chapterjs'", `'${specifier}'`)}`;
|
|
32
29
|
// The folder ignores itself: nothing to add to the project's .gitignore.
|
|
33
30
|
files.set('.gitignore', '*\n');
|
|
34
|
-
// What
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
// copy of the package for editors to offer.
|
|
38
|
-
const everywhere = shared === '' ? [] : ['../types/shared.d.ts'];
|
|
39
|
-
if (shared !== '') {
|
|
40
|
-
files.set('types/shared.d.ts', `${HEADER}${shared.replaceAll("'#chapterjs'", `'${specifier}'`)}`);
|
|
41
|
-
}
|
|
42
|
-
// What only the files outside typed folders get, and the typed folders
|
|
43
|
-
// that ask for it (`includes`): the commands a language file may
|
|
44
|
-
// translate.
|
|
45
|
-
const mainOnly = main === '' ? [] : ['../types/main.d.ts'];
|
|
46
|
-
if (main !== '') {
|
|
47
|
-
files.set('types/main.d.ts', `${HEADER}${main.replaceAll("'#chapterjs'", `'${specifier}'`)}`);
|
|
48
|
-
}
|
|
49
|
-
// Files that are in no typed folder: 'chapterjs' is the package itself.
|
|
50
|
-
files.set('projects/main.json', json({
|
|
51
|
-
extends: '../../tsconfig.json',
|
|
52
|
-
include: ['../../src', ...everywhere, ...mainOnly],
|
|
53
|
-
exclude: folders.map(({ folder }) => `../../${folder}`),
|
|
54
|
-
}));
|
|
55
|
-
for (const { id, folder, declarations, includes } of folders) {
|
|
56
|
-
const more = (includes ?? ['shared']).flatMap(what => what === 'shared' ? everywhere : mainOnly);
|
|
57
|
-
files.set(`projects/${id}.json`, json({
|
|
58
|
-
extends: '../../tsconfig.json',
|
|
59
|
-
compilerOptions: { paths: { chapterjs: [`../types/${id}.d.ts`] } },
|
|
60
|
-
// The declaration file is listed too: a folder that does not exist
|
|
61
|
-
// yet is then a valid, empty project, typed as soon as it exists.
|
|
62
|
-
include: [`../../${folder}`, `../types/${id}.d.ts`, ...more],
|
|
63
|
-
}));
|
|
64
|
-
files.set(`types/${id}.d.ts`, types(declarations));
|
|
65
|
-
}
|
|
31
|
+
// What the project adds to 'chapterjs': written as an augmentation, so
|
|
32
|
+
// the editor offers one 'chapterjs' and not a second copy of it.
|
|
33
|
+
files.set('types/project.d.ts', `${HEADER}${declarations.replaceAll("'#chapterjs'", `'${specifier}'`)}`);
|
|
66
34
|
files.set('tsconfig.json', json({
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
],
|
|
35
|
+
extends: '../tsconfig.json',
|
|
36
|
+
// The declaration file is listed too: a project without a src folder
|
|
37
|
+
// yet is then a valid, empty project.
|
|
38
|
+
include: ['../src', './types/project.d.ts'],
|
|
72
39
|
}));
|
|
73
40
|
return files;
|
|
74
41
|
}
|
|
75
42
|
/**
|
|
76
43
|
* Writes the `.chapterjs/` folder of a project. A file whose content did
|
|
77
44
|
* not change is left alone, so editors don't reload for nothing; what an
|
|
78
|
-
* older version wrote and this one does not is removed. `
|
|
79
|
-
* 'chapterjs'
|
|
80
|
-
*
|
|
81
|
-
* `'#chapterjs'
|
|
82
|
-
* same for the files outside typed folders only.
|
|
45
|
+
* older version wrote and this one does not is removed. `declarations` is
|
|
46
|
+
* what 'chapterjs' has in this project on top of the package: `declare
|
|
47
|
+
* module 'chapterjs'` augmentations, importing the package from
|
|
48
|
+
* `'#chapterjs'`.
|
|
83
49
|
* @returns how many files were written
|
|
84
50
|
*/
|
|
85
|
-
export async function writeGenerated(projectDir,
|
|
51
|
+
export async function writeGenerated(projectDir, declarations) {
|
|
86
52
|
const root = join(projectDir, '.chapterjs');
|
|
87
|
-
const files = generatedFiles(projectDir,
|
|
53
|
+
const files = generatedFiles(projectDir, declarations);
|
|
88
54
|
const existing = await readdir(root, {
|
|
89
55
|
recursive: true,
|
|
90
56
|
withFileTypes: true,
|