alemonjs 2.1.49 → 2.1.50
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 +21 -0
- package/lib/app/event-format.d.ts +19 -0
- package/lib/app/event-format.js +128 -0
- package/lib/app/event-utils.js +1 -1
- package/lib/app/hook-use/client.js +21 -17
- package/lib/app/hook-use/event.d.ts +20 -0
- package/lib/app/hook-use/event.js +38 -0
- package/lib/app/hook-use/index.d.ts +2 -0
- package/lib/app/hook-use/index.js +2 -0
- package/lib/app/hook-use/subscribe.d.ts +73 -0
- package/lib/app/hook-use/subscribe.js +112 -0
- package/lib/app/index.d.ts +1 -1
- package/lib/app/index.js +3 -1
- package/lib/app/load_modules/load.js +1 -1
- package/lib/app/load_modules/loadChild.js +3 -3
- package/lib/app/message-api.d.ts +2 -2
- package/lib/app/message-api.js +6 -38
- package/lib/cbp/connects/platform.js +3 -3
- package/lib/cbp/server/main.js +6 -6
- package/lib/core/utils.js +5 -5
- package/lib/index.js +3 -1
- package/lib/process/module.js +3 -3
- package/lib/process/platform.js +3 -3
- package/lib/server/routers/router.js +59 -10
- package/lib/server/routers/utils.d.ts +2 -0
- package/lib/server/routers/utils.js +12 -1
- package/lib/types/event/base/platform.d.ts +1 -1
- package/lib/types/event/builder.d.ts +36 -0
- package/lib/types/event/builder.js +1 -0
- package/lib/types/event/channel/index.d.ts +4 -4
- package/lib/types/event/guild/index.d.ts +4 -4
- package/lib/types/event/interaction/index.d.ts +3 -3
- package/lib/types/event/member/index.d.ts +6 -6
- package/lib/types/event/message/message.d.ts +7 -7
- package/lib/types/event/message/private.message.d.ts +4 -4
- package/lib/types/event/notice/index.d.ts +3 -3
- package/lib/types/event/request/index.d.ts +4 -4
- package/lib/types/index.d.ts +1 -0
- package/lib/utils.js +1 -1
- package/package.json +3 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013-present, Yuxi (Evan) You
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIdED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Events, EventKeys, EventBuilder, ReservedEventKeys, User, Guild, Channel, Message, MessageText, MessageMedia, MessageOpen, Platform } from '../types';
|
|
2
|
+
export declare class FormatEvent<T extends EventKeys = EventKeys> {
|
|
3
|
+
#private;
|
|
4
|
+
private constructor();
|
|
5
|
+
static create<T extends EventKeys>(name: T): EventBuilder<T>;
|
|
6
|
+
addPlatform(params: Platform): this;
|
|
7
|
+
addGuild(params: Guild): this;
|
|
8
|
+
addChannel(params: Channel): this;
|
|
9
|
+
addUser(params: User): this;
|
|
10
|
+
addMessage(params: Message): this;
|
|
11
|
+
addText(params: MessageText): this;
|
|
12
|
+
addMedia(params: MessageMedia): this;
|
|
13
|
+
addOpen(params: MessageOpen): this;
|
|
14
|
+
add<E extends Record<string, unknown>>(fields: {
|
|
15
|
+
[K in keyof E]: K extends ReservedEventKeys ? never : E[K];
|
|
16
|
+
}): this;
|
|
17
|
+
get value(): Events[T];
|
|
18
|
+
}
|
|
19
|
+
export declare function wrapEvent<E extends Record<string, unknown>>(event: object): Readonly<E>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
class FormatEvent {
|
|
2
|
+
#data;
|
|
3
|
+
constructor(name) {
|
|
4
|
+
this.#data = { name, Timestamp: Date.now() };
|
|
5
|
+
}
|
|
6
|
+
static create(name) {
|
|
7
|
+
return new FormatEvent(name);
|
|
8
|
+
}
|
|
9
|
+
addPlatform(params) {
|
|
10
|
+
const { value, ...otherParams } = params;
|
|
11
|
+
Object.assign(this.#data, otherParams);
|
|
12
|
+
Object.defineProperty(this.#data, 'value', {
|
|
13
|
+
value,
|
|
14
|
+
enumerable: false
|
|
15
|
+
});
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
addGuild(params) {
|
|
19
|
+
Object.assign(this.#data, {
|
|
20
|
+
GuildId: params.GuildId,
|
|
21
|
+
SpaceId: params.SpaceId
|
|
22
|
+
});
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
addChannel(params) {
|
|
26
|
+
Object.assign(this.#data, {
|
|
27
|
+
ChannelId: params.ChannelId
|
|
28
|
+
});
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
addUser(params) {
|
|
32
|
+
Object.assign(this.#data, {
|
|
33
|
+
UserId: params.UserId,
|
|
34
|
+
UserKey: params.UserKey,
|
|
35
|
+
IsMaster: params.IsMaster,
|
|
36
|
+
IsBot: params.IsBot,
|
|
37
|
+
...(params.UserName !== undefined && { UserName: params.UserName }),
|
|
38
|
+
...(params.UserAvatar !== undefined && { UserAvatar: params.UserAvatar })
|
|
39
|
+
});
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
addMessage(params) {
|
|
43
|
+
const assign = { MessageId: params.MessageId };
|
|
44
|
+
if (params.ReplyId !== undefined) {
|
|
45
|
+
assign.ReplyId = params.ReplyId;
|
|
46
|
+
}
|
|
47
|
+
Object.assign(this.#data, assign);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
addText(params) {
|
|
51
|
+
Object.assign(this.#data, {
|
|
52
|
+
MessageText: params.MessageText
|
|
53
|
+
});
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
addMedia(params) {
|
|
57
|
+
Object.assign(this.#data, {
|
|
58
|
+
MessageMedia: params.MessageMedia
|
|
59
|
+
});
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
addOpen(params) {
|
|
63
|
+
Object.assign(this.#data, {
|
|
64
|
+
OpenId: params.OpenId
|
|
65
|
+
});
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
add(fields) {
|
|
69
|
+
for (const key of Object.keys(fields)) {
|
|
70
|
+
this.#data[`_${key}`] = fields[key];
|
|
71
|
+
}
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
get value() {
|
|
75
|
+
return this.#data;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function wrapEvent(event) {
|
|
79
|
+
return new Proxy(event, {
|
|
80
|
+
get(target, prop, receiver) {
|
|
81
|
+
if (typeof prop === 'string' && !prop.startsWith('_')) {
|
|
82
|
+
const privateKey = `_${prop}`;
|
|
83
|
+
if (privateKey in target) {
|
|
84
|
+
return Reflect.get(target, privateKey, receiver);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return Reflect.get(target, prop, receiver);
|
|
88
|
+
},
|
|
89
|
+
has(target, prop) {
|
|
90
|
+
if (typeof prop === 'string' && !prop.startsWith('_')) {
|
|
91
|
+
if (`_${prop}` in target) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return Reflect.has(target, prop);
|
|
96
|
+
},
|
|
97
|
+
set() {
|
|
98
|
+
return false;
|
|
99
|
+
},
|
|
100
|
+
deleteProperty() {
|
|
101
|
+
return false;
|
|
102
|
+
},
|
|
103
|
+
ownKeys(target) {
|
|
104
|
+
return Reflect.ownKeys(target).map(key => {
|
|
105
|
+
if (typeof key === 'string' && key.startsWith('_')) {
|
|
106
|
+
return key.slice(1);
|
|
107
|
+
}
|
|
108
|
+
return key;
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
112
|
+
if (typeof prop === 'string' && !prop.startsWith('_')) {
|
|
113
|
+
const privateKey = `_${prop}`;
|
|
114
|
+
const desc = Reflect.getOwnPropertyDescriptor(target, privateKey);
|
|
115
|
+
if (desc) {
|
|
116
|
+
return { ...desc, configurable: true, writable: false };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const desc = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
120
|
+
if (desc) {
|
|
121
|
+
return { ...desc, writable: false };
|
|
122
|
+
}
|
|
123
|
+
return desc;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { FormatEvent, wrapEvent };
|
package/lib/app/event-utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getConfig } from '../core/config.js';
|
|
2
|
-
import { ChildrenApp, State
|
|
2
|
+
import { StateSubscribe, ChildrenApp, State } from './store.js';
|
|
3
3
|
import { ResultCode } from '../core/variable.js';
|
|
4
4
|
|
|
5
5
|
const unChildren = (name = 'main') => {
|
|
@@ -10,6 +10,26 @@ import { sendAPI } from '../../cbp/processor/api.js';
|
|
|
10
10
|
import '../message-format-old.js';
|
|
11
11
|
import { getCurrentEvent } from '../hook-event-context.js';
|
|
12
12
|
|
|
13
|
+
const createDeepProxy = (event, path = []) => {
|
|
14
|
+
return new Proxy((() => { }), {
|
|
15
|
+
get(_target, prop) {
|
|
16
|
+
if (typeof prop === 'symbol') {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return createDeepProxy(event, [...path, String(prop)]);
|
|
20
|
+
},
|
|
21
|
+
apply(_target, _thisArg, args) {
|
|
22
|
+
return sendAPI({
|
|
23
|
+
action: 'client.api',
|
|
24
|
+
payload: {
|
|
25
|
+
event,
|
|
26
|
+
key: path.join('.'),
|
|
27
|
+
params: args
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
13
33
|
function useClient(eventOrClass, _ApiClass) {
|
|
14
34
|
let valueEvent;
|
|
15
35
|
if (eventOrClass !== undefined && typeof eventOrClass === 'function') {
|
|
@@ -26,23 +46,7 @@ function useClient(eventOrClass, _ApiClass) {
|
|
|
26
46
|
});
|
|
27
47
|
throw new Error('Invalid event: event must be an object');
|
|
28
48
|
}
|
|
29
|
-
const client =
|
|
30
|
-
get(_target, prop) {
|
|
31
|
-
if (typeof prop === 'symbol') {
|
|
32
|
-
return undefined;
|
|
33
|
-
}
|
|
34
|
-
return (...args) => {
|
|
35
|
-
return sendAPI({
|
|
36
|
-
action: 'client.api',
|
|
37
|
-
payload: {
|
|
38
|
-
event: valueEvent,
|
|
39
|
-
key: String(prop),
|
|
40
|
-
params: args
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
});
|
|
49
|
+
const client = createDeepProxy(valueEvent);
|
|
46
50
|
return [client];
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EventKeys, Events } from 'types';
|
|
2
|
+
type UseEventOptions<T extends EventKeys> = {
|
|
3
|
+
selects: T | T[];
|
|
4
|
+
regular?: RegExp;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
exact?: string;
|
|
7
|
+
};
|
|
8
|
+
type UseEventResult<T extends EventKeys> = {
|
|
9
|
+
current: Events[T];
|
|
10
|
+
value: Events[T]['value'];
|
|
11
|
+
match: {
|
|
12
|
+
selects: boolean;
|
|
13
|
+
regular: boolean;
|
|
14
|
+
prefix: boolean;
|
|
15
|
+
exact: boolean;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare function useEvent<T extends EventKeys>(options?: UseEventOptions<T>): readonly [UseEventResult<T>];
|
|
19
|
+
export declare function useEvent<T extends EventKeys>(event?: Events[T], options?: UseEventOptions<T>): readonly [UseEventResult<T>];
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getEventOrThrow } from './common.js';
|
|
2
|
+
|
|
3
|
+
const isOptions = (v) => {
|
|
4
|
+
return typeof v === 'object' && 'selects' in v;
|
|
5
|
+
};
|
|
6
|
+
function useEvent(eventOrOptions, options) {
|
|
7
|
+
let eventArg;
|
|
8
|
+
let opts;
|
|
9
|
+
if (eventOrOptions && isOptions(eventOrOptions)) {
|
|
10
|
+
opts = eventOrOptions;
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
eventArg = eventOrOptions;
|
|
14
|
+
opts = options;
|
|
15
|
+
}
|
|
16
|
+
const { selects, regular, prefix, exact } = opts ?? {};
|
|
17
|
+
const eventValue = getEventOrThrow(eventArg);
|
|
18
|
+
const { name, MessageText } = eventValue;
|
|
19
|
+
const selectsArr = Array.isArray(selects) ? selects : [selects];
|
|
20
|
+
const match = {
|
|
21
|
+
selects: selectsArr.includes(name),
|
|
22
|
+
exact: !!(exact && MessageText === exact),
|
|
23
|
+
prefix: !!(prefix && MessageText?.startsWith(prefix)),
|
|
24
|
+
regular: !!(regular && MessageText && regular.test(MessageText))
|
|
25
|
+
};
|
|
26
|
+
const r = {
|
|
27
|
+
current: { ...eventValue },
|
|
28
|
+
match
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(r, 'value', {
|
|
31
|
+
get() {
|
|
32
|
+
return eventValue.value;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return [r];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { useEvent };
|
|
@@ -13,3 +13,5 @@ export { useReaction } from './reaction.js';
|
|
|
13
13
|
export { useRequest } from './request.js';
|
|
14
14
|
export { useRole } from './role.js';
|
|
15
15
|
export { useUser } from './user.js';
|
|
16
|
+
export { useObserver, useSubscribe } from './subscribe.js';
|
|
17
|
+
export { useEvent } from './event.js';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { EventCycleEnum, Current, Events, EventKeys } from '../../types';
|
|
2
|
+
export declare function useSubscribe<T extends EventKeys>(selects: T | T[]): readonly [
|
|
3
|
+
{
|
|
4
|
+
create: (callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
5
|
+
id: string;
|
|
6
|
+
selects: T[];
|
|
7
|
+
choose: EventCycleEnum;
|
|
8
|
+
};
|
|
9
|
+
mount: (callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
10
|
+
id: string;
|
|
11
|
+
selects: T[];
|
|
12
|
+
choose: EventCycleEnum;
|
|
13
|
+
};
|
|
14
|
+
unmount: (callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
15
|
+
id: string;
|
|
16
|
+
selects: T[];
|
|
17
|
+
choose: EventCycleEnum;
|
|
18
|
+
};
|
|
19
|
+
cancel: (value: {
|
|
20
|
+
id: string;
|
|
21
|
+
selects: T[];
|
|
22
|
+
choose: EventCycleEnum;
|
|
23
|
+
}) => void;
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
export declare function useSubscribe<T extends EventKeys>(event: Events[T] | undefined, selects: T | T[]): readonly [
|
|
27
|
+
{
|
|
28
|
+
create: (callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
29
|
+
id: string;
|
|
30
|
+
selects: T[];
|
|
31
|
+
choose: EventCycleEnum;
|
|
32
|
+
};
|
|
33
|
+
mount: (callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
34
|
+
id: string;
|
|
35
|
+
selects: T[];
|
|
36
|
+
choose: EventCycleEnum;
|
|
37
|
+
};
|
|
38
|
+
unmount: (callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
39
|
+
id: string;
|
|
40
|
+
selects: T[];
|
|
41
|
+
choose: EventCycleEnum;
|
|
42
|
+
};
|
|
43
|
+
cancel: (value: {
|
|
44
|
+
id: string;
|
|
45
|
+
selects: T[];
|
|
46
|
+
choose: EventCycleEnum;
|
|
47
|
+
}) => void;
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
export declare function useObserver<T extends EventKeys>(selects: T | T[]): readonly [
|
|
51
|
+
(callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
52
|
+
id: string;
|
|
53
|
+
selects: T[];
|
|
54
|
+
choose: EventCycleEnum;
|
|
55
|
+
},
|
|
56
|
+
(value: {
|
|
57
|
+
id: string;
|
|
58
|
+
selects: T[];
|
|
59
|
+
choose: EventCycleEnum;
|
|
60
|
+
}) => void
|
|
61
|
+
];
|
|
62
|
+
export declare function useObserver<T extends EventKeys>(event: Events[T] | undefined, selects: T | T[]): readonly [
|
|
63
|
+
(callback: Current<T>, keys: (keyof Events[T])[]) => {
|
|
64
|
+
id: string;
|
|
65
|
+
selects: T[];
|
|
66
|
+
choose: EventCycleEnum;
|
|
67
|
+
},
|
|
68
|
+
(value: {
|
|
69
|
+
id: string;
|
|
70
|
+
selects: T[];
|
|
71
|
+
choose: EventCycleEnum;
|
|
72
|
+
}) => void
|
|
73
|
+
];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { ResultCode } from '../../core/variable.js';
|
|
2
|
+
import { SubscribeList } from '../store.js';
|
|
3
|
+
import { SubscribeStatus } from '../config.js';
|
|
4
|
+
import { getCurrentEvent } from '../hook-event-context.js';
|
|
5
|
+
|
|
6
|
+
function useSubscribe(eventOrSelects, maybeSelects) {
|
|
7
|
+
const selects = (maybeSelects === undefined ? eventOrSelects : maybeSelects);
|
|
8
|
+
const event = (maybeSelects === undefined ? undefined : eventOrSelects);
|
|
9
|
+
const valueEvent = event ?? getCurrentEvent();
|
|
10
|
+
if (typeof valueEvent !== 'object' || valueEvent === null) {
|
|
11
|
+
logger.error({
|
|
12
|
+
code: ResultCode.FailParams,
|
|
13
|
+
message: 'event is not object',
|
|
14
|
+
data: null
|
|
15
|
+
});
|
|
16
|
+
throw new Error('event is not object');
|
|
17
|
+
}
|
|
18
|
+
if (typeof selects !== 'string' && !Array.isArray(selects)) {
|
|
19
|
+
logger.error({
|
|
20
|
+
code: ResultCode.FailParams,
|
|
21
|
+
message: 'select is not string or array',
|
|
22
|
+
data: null
|
|
23
|
+
});
|
|
24
|
+
throw new Error('select is not string or array');
|
|
25
|
+
}
|
|
26
|
+
const register = (callback, keys, choose) => {
|
|
27
|
+
const curSelects = Array.isArray(selects) ? selects : [selects];
|
|
28
|
+
const ID = Date.now().toString(36) + Math.random().toString(36).substring(2, 15);
|
|
29
|
+
if (keys.length === 0) {
|
|
30
|
+
logger.warn({
|
|
31
|
+
code: ResultCode.FailParams,
|
|
32
|
+
message: 'subscribe keys is empty',
|
|
33
|
+
data: null
|
|
34
|
+
});
|
|
35
|
+
return { selects: curSelects, choose, id: ID };
|
|
36
|
+
}
|
|
37
|
+
for (const select of curSelects) {
|
|
38
|
+
const subList = new SubscribeList(choose, select);
|
|
39
|
+
const values = {};
|
|
40
|
+
for (const key of keys) {
|
|
41
|
+
if (typeof key === 'string' && (typeof valueEvent[key] === 'string' || typeof valueEvent[key] === 'number' || typeof valueEvent[key] === 'boolean')) {
|
|
42
|
+
values[key] = valueEvent[key];
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
logger.warn({
|
|
46
|
+
code: ResultCode.FailParams,
|
|
47
|
+
message: `Invalid key: ${key?.toString()} must be a string, number or boolean`,
|
|
48
|
+
data: null
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
subList.value.append({
|
|
53
|
+
choose,
|
|
54
|
+
selects: curSelects,
|
|
55
|
+
keys: values,
|
|
56
|
+
current: callback,
|
|
57
|
+
status: SubscribeStatus.active,
|
|
58
|
+
id: ID
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
selects: curSelects,
|
|
63
|
+
choose,
|
|
64
|
+
id: ID
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
const create = (callback, keys) => {
|
|
68
|
+
return register(callback, keys, 'create');
|
|
69
|
+
};
|
|
70
|
+
const mountBefore = (callback, keys) => {
|
|
71
|
+
return register(callback, keys, 'mount');
|
|
72
|
+
};
|
|
73
|
+
const unmount = (callback, keys) => {
|
|
74
|
+
return register(callback, keys, 'unmount');
|
|
75
|
+
};
|
|
76
|
+
const cancel = (value) => {
|
|
77
|
+
const selects = value.selects;
|
|
78
|
+
const ID = value.id;
|
|
79
|
+
for (const select of selects) {
|
|
80
|
+
const subList = new SubscribeList(value.choose, select);
|
|
81
|
+
subList.value.forEach(node => {
|
|
82
|
+
if (node.data.id === ID) {
|
|
83
|
+
node.data.status = SubscribeStatus.paused;
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const subscribe = {
|
|
90
|
+
create,
|
|
91
|
+
mount: mountBefore,
|
|
92
|
+
unmount,
|
|
93
|
+
cancel
|
|
94
|
+
};
|
|
95
|
+
return [subscribe];
|
|
96
|
+
}
|
|
97
|
+
function useObserver(eventOrSelects, maybeSelects) {
|
|
98
|
+
const selects = (maybeSelects === undefined ? eventOrSelects : maybeSelects);
|
|
99
|
+
const event = (maybeSelects === undefined ? undefined : eventOrSelects);
|
|
100
|
+
if (selects === undefined) {
|
|
101
|
+
logger.error({
|
|
102
|
+
code: ResultCode.FailParams,
|
|
103
|
+
message: 'select is not string or array',
|
|
104
|
+
data: null
|
|
105
|
+
});
|
|
106
|
+
throw new Error('select is not string or array');
|
|
107
|
+
}
|
|
108
|
+
const [subscribe] = useSubscribe(event, selects);
|
|
109
|
+
return [subscribe.mount, subscribe.cancel];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { useObserver, useSubscribe };
|
package/lib/app/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './define-platform.js';
|
|
|
5
5
|
export * from './define-response.js';
|
|
6
6
|
export * from './define-middleware.js';
|
|
7
7
|
export * from './define-router.js';
|
|
8
|
+
export * from './event-format.js';
|
|
8
9
|
export * from './event-group.js';
|
|
9
10
|
export * from './event-middleware';
|
|
10
11
|
export * from './event-processor';
|
|
@@ -16,6 +17,5 @@ export * from './event-processor-subscribe.js';
|
|
|
16
17
|
export * from './hook-use/index.js';
|
|
17
18
|
export * from './hook-event-context.js';
|
|
18
19
|
export * from './event-utils.js';
|
|
19
|
-
export * from './hook-use-subscribe.js';
|
|
20
20
|
export * from './message-api.js';
|
|
21
21
|
export * from './message-format.js';
|
package/lib/app/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { definePlatform } from './define-platform.js';
|
|
|
6
6
|
export { defineResponse } from './define-response.js';
|
|
7
7
|
export { defineMiddleware } from './define-middleware.js';
|
|
8
8
|
export { defineRouter, lazy } from './define-router.js';
|
|
9
|
+
export { FormatEvent, wrapEvent } from './event-format.js';
|
|
9
10
|
export { onGroup } from './event-group.js';
|
|
10
11
|
export { OnMiddleware, onMiddleware } from './event-middleware.js';
|
|
11
12
|
export { OnProcessor, onProcessor } from './event-processor.js';
|
|
@@ -29,9 +30,10 @@ export { useReaction } from './hook-use/reaction.js';
|
|
|
29
30
|
export { useRequest } from './hook-use/request.js';
|
|
30
31
|
export { useRole } from './hook-use/role.js';
|
|
31
32
|
export { useUser } from './hook-use/user.js';
|
|
33
|
+
export { useObserver, useSubscribe } from './hook-use/subscribe.js';
|
|
34
|
+
export { useEvent } from './hook-use/event.js';
|
|
32
35
|
export { getCurrentEvent, withEventContext } from './hook-event-context.js';
|
|
33
36
|
export { createEventValue, createSelects, onSelects, onState, unChildren, unState, useState } from './event-utils.js';
|
|
34
|
-
export { useObserver, useSubscribe } from './hook-use-subscribe.js';
|
|
35
37
|
export { MessageDirect, createDataFormat, format, getMessageIntent, sendToChannel, sendToUser } from './message-api.js';
|
|
36
38
|
export { Format, FormatButtonGroup, FormatMarkDown, createEvent } from './message-format.js';
|
|
37
39
|
export { Attachment, Audio, BT, Button, Image, ImageFile, ImageURL, Link, MD, Markdown, MarkdownOriginal, Mention, Text, Video } from './message-format-old.js';
|
|
@@ -8,7 +8,7 @@ const loadApps = () => {
|
|
|
8
8
|
const cfg = getConfig();
|
|
9
9
|
const apps = Array.isArray(cfg.value?.apps) ? cfg.value.apps : Object.keys(cfg.value?.apps ?? {}).filter(Boolean);
|
|
10
10
|
const uniqueApps = Array.from(new Set(apps));
|
|
11
|
-
|
|
11
|
+
uniqueApps.forEach(app => void loadChildrenFile(app));
|
|
12
12
|
};
|
|
13
13
|
const run = (input) => {
|
|
14
14
|
if (!input) {
|
|
@@ -3,11 +3,11 @@ import { existsSync } from 'fs';
|
|
|
3
3
|
import { showErrorModule, getRecursiveDirFiles, createEventName } from '../../core/utils.js';
|
|
4
4
|
import { ChildrenApp } from '../store.js';
|
|
5
5
|
import { ResultCode, fileSuffixMiddleware } from '../../core/variable.js';
|
|
6
|
-
import module from 'module';
|
|
6
|
+
import module$1 from 'module';
|
|
7
7
|
|
|
8
8
|
const initRequire = () => { };
|
|
9
9
|
initRequire.resolve = () => '';
|
|
10
|
-
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
10
|
+
const require$1 = module$1?.createRequire?.(import.meta.url) ?? initRequire;
|
|
11
11
|
const loadChildren = async (mainPath, appName) => {
|
|
12
12
|
if (!mainPath || typeof mainPath !== 'string') {
|
|
13
13
|
logger.error({
|
|
@@ -168,7 +168,7 @@ const loadChildrenFile = (appName) => {
|
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
170
|
try {
|
|
171
|
-
const mainPath = require.resolve(appName);
|
|
171
|
+
const mainPath = require$1.resolve(appName);
|
|
172
172
|
if (!existsSync(mainPath)) {
|
|
173
173
|
logger.error({
|
|
174
174
|
code: ResultCode.FailParams,
|
package/lib/app/message-api.d.ts
CHANGED
|
@@ -7,12 +7,12 @@ export declare class MessageDirect {
|
|
|
7
7
|
static create(): MessageDirect;
|
|
8
8
|
sendToChannel(params: {
|
|
9
9
|
SpaceId: string;
|
|
10
|
-
format: Format;
|
|
10
|
+
format: Format | DataEnums[];
|
|
11
11
|
replyId?: string;
|
|
12
12
|
}): Promise<Result[]>;
|
|
13
13
|
sendToUser(params: {
|
|
14
14
|
OpenID: string;
|
|
15
|
-
format: Format;
|
|
15
|
+
format: Format | DataEnums[];
|
|
16
16
|
}): Promise<Result[]>;
|
|
17
17
|
}
|
|
18
18
|
export declare const sendToChannel: (SpaceId: string, data: DataEnums[]) => Promise<Result[]>;
|
package/lib/app/message-api.js
CHANGED
|
@@ -36,7 +36,7 @@ class MessageDirect {
|
|
|
36
36
|
payload: {
|
|
37
37
|
ChannelId: params.SpaceId,
|
|
38
38
|
params: {
|
|
39
|
-
format: params.format.value,
|
|
39
|
+
format: Array.isArray(params.format) ? params.format : params.format.value,
|
|
40
40
|
replyId: params?.replyId
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -56,49 +56,17 @@ class MessageDirect {
|
|
|
56
56
|
payload: {
|
|
57
57
|
UserId: params.OpenID,
|
|
58
58
|
params: {
|
|
59
|
-
format: params.format.value
|
|
59
|
+
format: Array.isArray(params.format) ? params.format : params.format.value
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
const sendToChannel =
|
|
66
|
-
|
|
67
|
-
logger.error({
|
|
68
|
-
code: ResultCode.FailParams,
|
|
69
|
-
message: 'Invalid SpaceId: SpaceId must be a string',
|
|
70
|
-
data: null
|
|
71
|
-
});
|
|
72
|
-
throw new Error('Invalid SpaceId: SpaceId must be a string');
|
|
73
|
-
}
|
|
74
|
-
return await sendAction({
|
|
75
|
-
action: 'message.send.channel',
|
|
76
|
-
payload: {
|
|
77
|
-
ChannelId: SpaceId,
|
|
78
|
-
params: {
|
|
79
|
-
format: data
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
});
|
|
65
|
+
const sendToChannel = (SpaceId, data) => {
|
|
66
|
+
return MessageDirect.create().sendToChannel({ SpaceId, format: data, replyId: undefined });
|
|
83
67
|
};
|
|
84
|
-
const sendToUser =
|
|
85
|
-
|
|
86
|
-
logger.error({
|
|
87
|
-
code: ResultCode.FailParams,
|
|
88
|
-
message: 'Invalid OpenID: OpenID must be a string',
|
|
89
|
-
data: null
|
|
90
|
-
});
|
|
91
|
-
throw new Error('Invalid OpenID: OpenID must be a string');
|
|
92
|
-
}
|
|
93
|
-
return await sendAction({
|
|
94
|
-
action: 'message.send.user',
|
|
95
|
-
payload: {
|
|
96
|
-
UserId: OpenID,
|
|
97
|
-
params: {
|
|
98
|
-
format: data
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
});
|
|
68
|
+
const sendToUser = (OpenID, data) => {
|
|
69
|
+
return MessageDirect.create().sendToUser({ OpenID, format: data });
|
|
102
70
|
};
|
|
103
71
|
const getMessageIntent = async () => {
|
|
104
72
|
const results = await sendAction({
|
|
@@ -185,7 +185,7 @@ const cbpPlatform = (url, options = {
|
|
|
185
185
|
};
|
|
186
186
|
const currentURL = createCurrentURL() || `ws://localhost:${process.env.port || 17117}`;
|
|
187
187
|
const send = (data) => {
|
|
188
|
-
if (global.chatbotPlatform
|
|
188
|
+
if (global.chatbotPlatform?.readyState === WebSocket.OPEN) {
|
|
189
189
|
data.DeviceId = deviceId;
|
|
190
190
|
data.CreateAt = Date.now();
|
|
191
191
|
global.chatbotPlatform.send(flattedJSON.stringify(sanitizeForSerialization(data)));
|
|
@@ -194,7 +194,7 @@ const cbpPlatform = (url, options = {
|
|
|
194
194
|
const actionReplys = [];
|
|
195
195
|
const apiReplys = [];
|
|
196
196
|
const replyAction = (data, payload) => {
|
|
197
|
-
if (global.chatbotPlatform
|
|
197
|
+
if (global.chatbotPlatform?.readyState === WebSocket.OPEN) {
|
|
198
198
|
global.chatbotPlatform.send(flattedJSON.stringify({
|
|
199
199
|
action: data.action,
|
|
200
200
|
payload: payload,
|
|
@@ -204,7 +204,7 @@ const cbpPlatform = (url, options = {
|
|
|
204
204
|
}
|
|
205
205
|
};
|
|
206
206
|
const replyApi = (data, payload) => {
|
|
207
|
-
if (global.chatbotPlatform
|
|
207
|
+
if (global.chatbotPlatform?.readyState === WebSocket.OPEN) {
|
|
208
208
|
global.chatbotPlatform.send(flattedJSON.stringify({
|
|
209
209
|
action: data.action,
|
|
210
210
|
apiId: data.apiId,
|
package/lib/cbp/server/main.js
CHANGED
|
@@ -15,7 +15,7 @@ import { getClientChild } from '../../process/ipc-bridge.js';
|
|
|
15
15
|
const routeMessageToDevice = (DeviceId, message) => {
|
|
16
16
|
if (childrenClient.has(DeviceId)) {
|
|
17
17
|
const clientWs = childrenClient.get(DeviceId);
|
|
18
|
-
if (clientWs
|
|
18
|
+
if (clientWs?.readyState === WebSocket.OPEN) {
|
|
19
19
|
clientWs.send(message);
|
|
20
20
|
}
|
|
21
21
|
else {
|
|
@@ -24,7 +24,7 @@ const routeMessageToDevice = (DeviceId, message) => {
|
|
|
24
24
|
}
|
|
25
25
|
else if (fullClient.has(DeviceId)) {
|
|
26
26
|
const clientWs = fullClient.get(DeviceId);
|
|
27
|
-
if (clientWs
|
|
27
|
+
if (clientWs?.readyState === WebSocket.OPEN) {
|
|
28
28
|
clientWs.send(message);
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
@@ -90,7 +90,7 @@ const handleEvent = (message, ID) => {
|
|
|
90
90
|
});
|
|
91
91
|
if (bindId) {
|
|
92
92
|
const clientWs = childrenClient.get(bindId);
|
|
93
|
-
if (clientWs
|
|
93
|
+
if (clientWs?.readyState === WebSocket.OPEN) {
|
|
94
94
|
bindChannelToClient(ID, bindId);
|
|
95
95
|
clientWs.send(message);
|
|
96
96
|
}
|
|
@@ -118,7 +118,7 @@ const handleEvent = (message, ID) => {
|
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
120
|
const clientWs = childrenClient.get(bindId);
|
|
121
|
-
if (
|
|
121
|
+
if (clientWs?.readyState !== WebSocket.OPEN) {
|
|
122
122
|
childrenClient.delete(bindId);
|
|
123
123
|
reBind();
|
|
124
124
|
return;
|
|
@@ -129,7 +129,7 @@ const setChildrenClient = (originId, ws) => {
|
|
|
129
129
|
childrenClient.set(originId, ws);
|
|
130
130
|
ws.on('message', (message) => {
|
|
131
131
|
if (global.__sandbox) {
|
|
132
|
-
if (global.testoneClient
|
|
132
|
+
if (global.testoneClient?.readyState === WebSocket.OPEN) {
|
|
133
133
|
global.testoneClient.send(message.toString());
|
|
134
134
|
}
|
|
135
135
|
return;
|
|
@@ -166,7 +166,7 @@ const setFullClient = (originId, ws) => {
|
|
|
166
166
|
fullClient.set(originId, ws);
|
|
167
167
|
ws.on('message', (message) => {
|
|
168
168
|
if (global.__sandbox) {
|
|
169
|
-
if (global.testoneClient
|
|
169
|
+
if (global.testoneClient?.readyState === WebSocket.OPEN) {
|
|
170
170
|
global.testoneClient.send(message.toString());
|
|
171
171
|
}
|
|
172
172
|
return;
|
package/lib/core/utils.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createHash as createHash$1 } from 'node:crypto';
|
|
2
2
|
import fs__default, { existsSync, readdirSync } from 'fs';
|
|
3
3
|
import path__default, { join } from 'path';
|
|
4
|
-
import {
|
|
5
|
-
import module from 'module';
|
|
4
|
+
import { ResultCode, fileSuffixResponse } from './variable.js';
|
|
5
|
+
import module$1 from 'module';
|
|
6
6
|
import { getConfigValue } from './config.js';
|
|
7
7
|
|
|
8
8
|
const initRequire = () => { };
|
|
9
9
|
initRequire.resolve = () => '';
|
|
10
|
-
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
10
|
+
const require$1 = module$1?.createRequire?.(import.meta.url) ?? initRequire;
|
|
11
11
|
const createHash = (str, options = {}) => {
|
|
12
12
|
const { length = 11, algorithm = 'sha256' } = options;
|
|
13
13
|
const hash = createHash$1(algorithm).update(str).digest('hex');
|
|
@@ -117,7 +117,7 @@ const showErrorModule = (e) => {
|
|
|
117
117
|
});
|
|
118
118
|
};
|
|
119
119
|
const sanitizeForSerialization = (data) => {
|
|
120
|
-
const flatted = require('flatted');
|
|
120
|
+
const flatted = require$1('flatted');
|
|
121
121
|
return flatted.parse(flatted.stringify(data));
|
|
122
122
|
};
|
|
123
123
|
const createExports = (packageJson) => {
|
|
@@ -133,7 +133,7 @@ const createExports = (packageJson) => {
|
|
|
133
133
|
const getInputExportPath = (input) => {
|
|
134
134
|
const packageJsonPath = path__default.join(input ?? process.cwd(), 'package.json');
|
|
135
135
|
if (fs__default.existsSync(packageJsonPath)) {
|
|
136
|
-
const packageJson = require(packageJsonPath);
|
|
136
|
+
const packageJson = require$1(packageJsonPath);
|
|
137
137
|
const main = packageJson?.main || createExports(packageJson);
|
|
138
138
|
if (main) {
|
|
139
139
|
return main;
|
package/lib/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export { definePlatform } from './app/define-platform.js';
|
|
|
13
13
|
export { defineResponse } from './app/define-response.js';
|
|
14
14
|
export { defineMiddleware } from './app/define-middleware.js';
|
|
15
15
|
export { defineRouter, lazy } from './app/define-router.js';
|
|
16
|
+
export { FormatEvent, wrapEvent } from './app/event-format.js';
|
|
16
17
|
export { onGroup } from './app/event-group.js';
|
|
17
18
|
export { OnMiddleware, onMiddleware } from './app/event-middleware.js';
|
|
18
19
|
export { OnProcessor, onProcessor } from './app/event-processor.js';
|
|
@@ -36,9 +37,10 @@ export { useReaction } from './app/hook-use/reaction.js';
|
|
|
36
37
|
export { useRequest } from './app/hook-use/request.js';
|
|
37
38
|
export { useRole } from './app/hook-use/role.js';
|
|
38
39
|
export { useUser } from './app/hook-use/user.js';
|
|
40
|
+
export { useObserver, useSubscribe } from './app/hook-use/subscribe.js';
|
|
41
|
+
export { useEvent } from './app/hook-use/event.js';
|
|
39
42
|
export { getCurrentEvent, withEventContext } from './app/hook-event-context.js';
|
|
40
43
|
export { createEventValue, createSelects, onSelects, onState, unChildren, unState, useState } from './app/event-utils.js';
|
|
41
|
-
export { useObserver, useSubscribe } from './app/hook-use-subscribe.js';
|
|
42
44
|
export { MessageDirect, createDataFormat, format, getMessageIntent, sendToChannel, sendToUser } from './app/message-api.js';
|
|
43
45
|
export { Format, FormatButtonGroup, FormatMarkDown, createEvent } from './app/message-format.js';
|
|
44
46
|
export { start } from './main.js';
|
package/lib/process/module.js
CHANGED
|
@@ -2,12 +2,12 @@ import childProcess from 'child_process';
|
|
|
2
2
|
import { ResultCode } from '../core/variable.js';
|
|
3
3
|
import { getConfigValue } from '../core/config.js';
|
|
4
4
|
import '../core/utils.js';
|
|
5
|
-
import module from 'module';
|
|
5
|
+
import module$1 from 'module';
|
|
6
6
|
import { setClientChild, forwardFromClient } from './ipc-bridge.js';
|
|
7
7
|
|
|
8
8
|
const initRequire = () => { };
|
|
9
9
|
initRequire.resolve = () => '';
|
|
10
|
-
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
10
|
+
const require$1 = module$1?.createRequire?.(import.meta.url) ?? initRequire;
|
|
11
11
|
function startModuleAdapter() {
|
|
12
12
|
const values = getConfigValue();
|
|
13
13
|
const pro = values?.process ?? {};
|
|
@@ -17,7 +17,7 @@ function startModuleAdapter() {
|
|
|
17
17
|
FORK_TIMEOUT: pro?.fork_timeout ?? 6000
|
|
18
18
|
};
|
|
19
19
|
try {
|
|
20
|
-
modulePath = require.resolve('../client.js');
|
|
20
|
+
modulePath = require$1.resolve('../client.js');
|
|
21
21
|
}
|
|
22
22
|
catch (error) {
|
|
23
23
|
logger?.warn?.({
|
package/lib/process/platform.js
CHANGED
|
@@ -2,12 +2,12 @@ import childProcess from 'child_process';
|
|
|
2
2
|
import { ResultCode } from '../core/variable.js';
|
|
3
3
|
import { getConfigValue } from '../core/config.js';
|
|
4
4
|
import '../core/utils.js';
|
|
5
|
-
import module from 'module';
|
|
5
|
+
import module$1 from 'module';
|
|
6
6
|
import { setPlatformChild, forwardFromPlatform } from './ipc-bridge.js';
|
|
7
7
|
|
|
8
8
|
const initRequire = () => { };
|
|
9
9
|
initRequire.resolve = () => '';
|
|
10
|
-
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
10
|
+
const require$1 = module$1?.createRequire?.(import.meta.url) ?? initRequire;
|
|
11
11
|
function startPlatformAdapterWithFallback() {
|
|
12
12
|
const values = getConfigValue();
|
|
13
13
|
const pro = values?.process ?? {};
|
|
@@ -29,7 +29,7 @@ function startPlatformAdapterWithFallback() {
|
|
|
29
29
|
let isForkFailed = false;
|
|
30
30
|
let imported = false;
|
|
31
31
|
try {
|
|
32
|
-
modulePath = require.resolve(platformPath);
|
|
32
|
+
modulePath = require$1.resolve(platformPath);
|
|
33
33
|
}
|
|
34
34
|
catch {
|
|
35
35
|
logger?.warn?.({
|
|
@@ -3,16 +3,16 @@ import fs__default, { existsSync } from 'fs';
|
|
|
3
3
|
import path__default, { join, dirname } from 'path';
|
|
4
4
|
import mime from 'mime-types';
|
|
5
5
|
import hello from './hello.html.js';
|
|
6
|
-
import { getModuelFile, formatPath } from './utils.js';
|
|
6
|
+
import { safePath, getModuelFile, formatPath, isValidPackageName } from './utils.js';
|
|
7
7
|
import { collectMiddlewares, runMiddlewares } from './middleware.js';
|
|
8
8
|
import { ResultCode } from '../../core/variable.js';
|
|
9
9
|
import 'yaml';
|
|
10
10
|
import '../../core/utils.js';
|
|
11
|
-
import module from 'module';
|
|
11
|
+
import module$1 from 'module';
|
|
12
12
|
|
|
13
13
|
const initRequire = () => { };
|
|
14
14
|
initRequire.resolve = () => '';
|
|
15
|
-
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
15
|
+
const require$1 = module$1?.createRequire?.(import.meta.url) ?? initRequire;
|
|
16
16
|
const mainDirMap = new Map();
|
|
17
17
|
const router = new KoaRouter({
|
|
18
18
|
prefix: '/'
|
|
@@ -55,7 +55,17 @@ router.all('app/{*path}', async (ctx) => {
|
|
|
55
55
|
}
|
|
56
56
|
const mainDir = dirname(mainPath);
|
|
57
57
|
try {
|
|
58
|
-
const
|
|
58
|
+
const routeBase = join(mainDir, 'route');
|
|
59
|
+
const dir = safePath(routeBase, ctx.path?.replace(apiPath, '/api') || '');
|
|
60
|
+
if (!dir) {
|
|
61
|
+
ctx.status = 403;
|
|
62
|
+
ctx.body = {
|
|
63
|
+
code: 403,
|
|
64
|
+
message: '非法路径',
|
|
65
|
+
data: null
|
|
66
|
+
};
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
59
69
|
if (existsSync(dir) && fs__default.statSync(dir).isFile()) {
|
|
60
70
|
ctx.status = 404;
|
|
61
71
|
ctx.body = {
|
|
@@ -102,7 +112,7 @@ router.all('app/{*path}', async (ctx) => {
|
|
|
102
112
|
let root = '';
|
|
103
113
|
const resourcePath = formatPath(ctx.params?.path);
|
|
104
114
|
try {
|
|
105
|
-
const pkg = require(path__default.join(rootPath, 'package.json')) ?? {};
|
|
115
|
+
const pkg = require$1(path__default.join(rootPath, 'package.json')) ?? {};
|
|
106
116
|
root = pkg.alemonjs?.web?.root ?? '';
|
|
107
117
|
}
|
|
108
118
|
catch (err) {
|
|
@@ -114,7 +124,17 @@ router.all('app/{*path}', async (ctx) => {
|
|
|
114
124
|
};
|
|
115
125
|
return;
|
|
116
126
|
}
|
|
117
|
-
const
|
|
127
|
+
const webRoot = root ? path__default.join(rootPath, root) : rootPath;
|
|
128
|
+
const fullPath = safePath(webRoot, resourcePath);
|
|
129
|
+
if (!fullPath) {
|
|
130
|
+
ctx.status = 403;
|
|
131
|
+
ctx.body = {
|
|
132
|
+
code: 403,
|
|
133
|
+
message: '非法路径',
|
|
134
|
+
data: null
|
|
135
|
+
};
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
118
138
|
try {
|
|
119
139
|
const file = await fs__default.promises.readFile(fullPath);
|
|
120
140
|
const mimeType = mime.lookup(fullPath) || 'application/octet-stream';
|
|
@@ -146,11 +166,20 @@ router.all('app', ctx => {
|
|
|
146
166
|
});
|
|
147
167
|
router.all('apps/:app/{*path}', async (ctx) => {
|
|
148
168
|
const appName = ctx.params.app;
|
|
169
|
+
if (!isValidPackageName(appName)) {
|
|
170
|
+
ctx.status = 400;
|
|
171
|
+
ctx.body = {
|
|
172
|
+
code: 400,
|
|
173
|
+
message: '无效的应用名称',
|
|
174
|
+
data: null
|
|
175
|
+
};
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
149
178
|
const apiPath = `/apps/${appName}/api`;
|
|
150
179
|
if (ctx.path.startsWith(apiPath)) {
|
|
151
180
|
try {
|
|
152
181
|
if (!mainDirMap.has(appName)) {
|
|
153
|
-
const mainPath = require.resolve(appName);
|
|
182
|
+
const mainPath = require$1.resolve(appName);
|
|
154
183
|
if (!existsSync(mainPath)) {
|
|
155
184
|
ctx.status = 400;
|
|
156
185
|
ctx.body = {
|
|
@@ -163,7 +192,17 @@ router.all('apps/:app/{*path}', async (ctx) => {
|
|
|
163
192
|
const mainDir = dirname(mainPath);
|
|
164
193
|
mainDirMap.set(appName, mainDir);
|
|
165
194
|
}
|
|
166
|
-
const
|
|
195
|
+
const routeBase = join(mainDirMap.get(appName), 'route');
|
|
196
|
+
const dir = safePath(routeBase, ctx.path?.replace(apiPath, '/api') || '');
|
|
197
|
+
if (!dir) {
|
|
198
|
+
ctx.status = 403;
|
|
199
|
+
ctx.body = {
|
|
200
|
+
code: 403,
|
|
201
|
+
message: '非法路径',
|
|
202
|
+
data: null
|
|
203
|
+
};
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
167
206
|
if (existsSync(dir) && fs__default.statSync(dir).isFile()) {
|
|
168
207
|
ctx.status = 404;
|
|
169
208
|
ctx.body = {
|
|
@@ -215,7 +254,7 @@ router.all('apps/:app/{*path}', async (ctx) => {
|
|
|
215
254
|
const resourcePath = formatPath(ctx.params?.path);
|
|
216
255
|
let root = '';
|
|
217
256
|
try {
|
|
218
|
-
const pkg = require(`${appName}/package`) ?? {};
|
|
257
|
+
const pkg = require$1(`${appName}/package`) ?? {};
|
|
219
258
|
root = pkg?.alemonjs?.web?.root ?? '';
|
|
220
259
|
}
|
|
221
260
|
catch (err) {
|
|
@@ -227,7 +266,17 @@ router.all('apps/:app/{*path}', async (ctx) => {
|
|
|
227
266
|
};
|
|
228
267
|
return;
|
|
229
268
|
}
|
|
230
|
-
const
|
|
269
|
+
const webRoot = root ? path__default.join(rootPath, root) : rootPath;
|
|
270
|
+
const fullPath = safePath(webRoot, resourcePath);
|
|
271
|
+
if (!fullPath) {
|
|
272
|
+
ctx.status = 403;
|
|
273
|
+
ctx.body = {
|
|
274
|
+
code: 403,
|
|
275
|
+
message: '非法路径',
|
|
276
|
+
data: null
|
|
277
|
+
};
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
231
280
|
try {
|
|
232
281
|
const file = await fs__default.promises.readFile(fullPath);
|
|
233
282
|
const mimeType = mime.lookup(fullPath) || 'application/octet-stream';
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
export declare const safePath: (root: string, untrusted: string) => string | null;
|
|
2
|
+
export declare const isValidPackageName: (name: string) => boolean;
|
|
1
3
|
export declare const getModuelFile: (dir: string) => string;
|
|
2
4
|
export declare const formatPath: (path: string) => string;
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import fs__default, { existsSync } from 'fs';
|
|
2
|
+
import path__default from 'path';
|
|
2
3
|
|
|
4
|
+
const safePath = (root, untrusted) => {
|
|
5
|
+
const resolved = path__default.resolve(root, untrusted);
|
|
6
|
+
if (resolved !== root && !resolved.startsWith(root + path__default.sep)) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return resolved;
|
|
10
|
+
};
|
|
11
|
+
const isValidPackageName = (name) => {
|
|
12
|
+
return /^(?:@[a-z0-9\-~][a-z0-9\-._~]*\/)?[a-z0-9\-~][a-z0-9\-._~]*$/.test(name);
|
|
13
|
+
};
|
|
3
14
|
const getModuelFile = (dir) => {
|
|
4
15
|
const dirMap = {
|
|
5
16
|
'.js': `${dir}.js`,
|
|
@@ -36,4 +47,4 @@ const formatPath = (path) => {
|
|
|
36
47
|
return path;
|
|
37
48
|
};
|
|
38
49
|
|
|
39
|
-
export { formatPath, getModuelFile };
|
|
50
|
+
export { formatPath, getModuelFile, isValidPackageName, safePath };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Guild, Channel } from './base/guild';
|
|
2
|
+
import { Message, MessageText, MessageMedia, MessageOpen } from './base/message';
|
|
3
|
+
import { Platform } from './base/platform';
|
|
4
|
+
import { User } from './base/user';
|
|
5
|
+
import { AutoFields } from './base/auto';
|
|
6
|
+
import { EventKeys, Events } from './map';
|
|
7
|
+
export type ReservedEventKeys = keyof Guild | keyof Channel | keyof User | keyof Message | keyof MessageText | keyof MessageMedia | keyof MessageOpen | keyof Platform | keyof AutoFields | 'name' | 'Timestamp';
|
|
8
|
+
type GuildMethods<T extends EventKeys> = Events[T] extends Guild ? {
|
|
9
|
+
addGuild(params: Guild): EventBuilder<T>;
|
|
10
|
+
} : Record<string, never>;
|
|
11
|
+
type ChannelMethods<T extends EventKeys> = Events[T] extends Channel ? {
|
|
12
|
+
addChannel(params: Channel): EventBuilder<T>;
|
|
13
|
+
} : Record<string, never>;
|
|
14
|
+
type UserMethods<T extends EventKeys> = Events[T] extends User ? {
|
|
15
|
+
addUser(params: User): EventBuilder<T>;
|
|
16
|
+
} : Record<string, never>;
|
|
17
|
+
type MessageMethods<T extends EventKeys> = Events[T] extends Message ? {
|
|
18
|
+
addMessage(params: Message): EventBuilder<T>;
|
|
19
|
+
} : Record<string, never>;
|
|
20
|
+
type TextMethods<T extends EventKeys> = Events[T] extends MessageText ? {
|
|
21
|
+
addText(params: MessageText): EventBuilder<T>;
|
|
22
|
+
} : Record<string, never>;
|
|
23
|
+
type MediaMethods<T extends EventKeys> = Events[T] extends MessageMedia ? {
|
|
24
|
+
addMedia(params: MessageMedia): EventBuilder<T>;
|
|
25
|
+
} : Record<string, never>;
|
|
26
|
+
type OpenMethods<T extends EventKeys> = Events[T] extends MessageOpen ? {
|
|
27
|
+
addOpen(params: MessageOpen): EventBuilder<T>;
|
|
28
|
+
} : Record<string, never>;
|
|
29
|
+
export type EventBuilder<T extends EventKeys> = {
|
|
30
|
+
addPlatform(params: Platform): EventBuilder<T>;
|
|
31
|
+
add<E extends Record<string, unknown>>(fields: {
|
|
32
|
+
[K in keyof E]: K extends ReservedEventKeys ? never : E[K];
|
|
33
|
+
}): EventBuilder<T>;
|
|
34
|
+
readonly value: Events[T];
|
|
35
|
+
} & GuildMethods<T> & ChannelMethods<T> & UserMethods<T> & MessageMethods<T> & TextMethods<T> & MediaMethods<T> & OpenMethods<T>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Guild, Channel } from '../base/guild';
|
|
2
|
-
import {
|
|
2
|
+
import { Platform } from '../base/platform';
|
|
3
3
|
import { Message } from '../base/message';
|
|
4
4
|
import { Expansion } from '../base/expansion';
|
|
5
|
-
export type PublicEventChannelCreate =
|
|
5
|
+
export type PublicEventChannelCreate = Platform & Guild & Channel & Message & {
|
|
6
6
|
name: 'channel.create';
|
|
7
7
|
} & Expansion;
|
|
8
|
-
export type PublicEventChannelDelete =
|
|
8
|
+
export type PublicEventChannelDelete = Platform & Guild & Channel & Message & {
|
|
9
9
|
name: 'channel.delete';
|
|
10
10
|
} & Expansion;
|
|
11
|
-
export type PublicEventChannelUpdate =
|
|
11
|
+
export type PublicEventChannelUpdate = Platform & Guild & Channel & Message & {
|
|
12
12
|
name: 'channel.update';
|
|
13
13
|
} & Expansion;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Expansion } from '../base/expansion';
|
|
2
2
|
import { Channel, Guild } from '../base/guild';
|
|
3
3
|
import { Message } from '../base/message';
|
|
4
|
-
import {
|
|
4
|
+
import { Platform } from '../base/platform';
|
|
5
5
|
import { User } from '../base/user';
|
|
6
|
-
export type PublicEventGuildJoin =
|
|
6
|
+
export type PublicEventGuildJoin = Platform & Guild & Channel & Message & User & {
|
|
7
7
|
name: 'guild.join';
|
|
8
8
|
} & Expansion;
|
|
9
|
-
export type PublicEventGuildExit =
|
|
9
|
+
export type PublicEventGuildExit = Platform & Guild & Channel & Message & User & {
|
|
10
10
|
name: 'guild.exit';
|
|
11
11
|
} & Expansion;
|
|
12
|
-
export type PublicEventGuildUpdate =
|
|
12
|
+
export type PublicEventGuildUpdate = Platform & Guild & Channel & Message & {
|
|
13
13
|
name: 'guild.update';
|
|
14
14
|
} & Expansion;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Guild, Channel } from '../base/guild';
|
|
2
2
|
import { Message, MessageOpen, MessageText } from '../base/message';
|
|
3
3
|
import { User } from '../base/user';
|
|
4
|
-
import {
|
|
4
|
+
import { Platform } from '../base/platform';
|
|
5
5
|
import { Expansion } from '../base/expansion';
|
|
6
|
-
export type PrivateEventInteractionCreate = MessageText & MessageOpen &
|
|
6
|
+
export type PrivateEventInteractionCreate = MessageText & MessageOpen & Platform & Message & User & {
|
|
7
7
|
name: 'private.interaction.create';
|
|
8
8
|
} & Expansion;
|
|
9
|
-
export type PublicEventInteractionCreate = MessageText & MessageOpen &
|
|
9
|
+
export type PublicEventInteractionCreate = MessageText & MessageOpen & Platform & Guild & Channel & Message & User & {
|
|
10
10
|
name: 'interaction.create';
|
|
11
11
|
} & Expansion;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { Guild, Channel } from '../base/guild';
|
|
2
2
|
import { Message } from '../base/message';
|
|
3
3
|
import { User } from '../base/user';
|
|
4
|
-
import {
|
|
4
|
+
import { Platform } from '../base/platform';
|
|
5
5
|
import { Expansion } from '../base/expansion';
|
|
6
|
-
export type PublicEventMemberAdd =
|
|
6
|
+
export type PublicEventMemberAdd = Platform & Guild & Channel & Message & User & {
|
|
7
7
|
name: 'member.add';
|
|
8
8
|
} & Expansion;
|
|
9
|
-
export type PublicEventMemberRemove =
|
|
9
|
+
export type PublicEventMemberRemove = Platform & Guild & Channel & Message & User & {
|
|
10
10
|
name: 'member.remove';
|
|
11
11
|
} & Expansion;
|
|
12
|
-
export type PublicEventMemberBan =
|
|
12
|
+
export type PublicEventMemberBan = Platform & Guild & Channel & Message & User & {
|
|
13
13
|
name: 'member.ban';
|
|
14
14
|
} & Expansion;
|
|
15
|
-
export type PublicEventMemberUnban =
|
|
15
|
+
export type PublicEventMemberUnban = Platform & Guild & Channel & Message & User & {
|
|
16
16
|
name: 'member.unban';
|
|
17
17
|
} & Expansion;
|
|
18
|
-
export type PublicEventMemberUpdate =
|
|
18
|
+
export type PublicEventMemberUpdate = Platform & Guild & Channel & Message & User & {
|
|
19
19
|
name: 'member.update';
|
|
20
20
|
} & Expansion;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { Guild, Channel } from '../base/guild';
|
|
2
2
|
import { Message, MessageMedia, MessageOpen, MessageText } from '../base/message';
|
|
3
3
|
import { User } from '../base/user';
|
|
4
|
-
import {
|
|
4
|
+
import { Platform } from '../base/platform';
|
|
5
5
|
import { Expansion } from '../base/expansion';
|
|
6
|
-
export type PublicEventMessageCreate = MessageText & MessageMedia & MessageOpen &
|
|
6
|
+
export type PublicEventMessageCreate = MessageText & MessageMedia & MessageOpen & Platform & Guild & Channel & Message & User & {
|
|
7
7
|
name: 'message.create';
|
|
8
8
|
} & Expansion;
|
|
9
|
-
export type PublicEventMessageUpdate =
|
|
9
|
+
export type PublicEventMessageUpdate = Platform & Guild & Channel & Message & User & {
|
|
10
10
|
name: 'message.update';
|
|
11
11
|
} & Expansion;
|
|
12
|
-
export type PublicEventMessageDelete =
|
|
12
|
+
export type PublicEventMessageDelete = Platform & Guild & Channel & Message & {
|
|
13
13
|
name: 'message.delete';
|
|
14
14
|
} & Expansion;
|
|
15
|
-
export type PublicEventMessageReactionAdd =
|
|
15
|
+
export type PublicEventMessageReactionAdd = Platform & Guild & Channel & Message & {
|
|
16
16
|
name: 'message.reaction.add';
|
|
17
17
|
} & Expansion;
|
|
18
|
-
export type PublicEventMessageReactionRemove =
|
|
18
|
+
export type PublicEventMessageReactionRemove = Platform & Guild & Channel & Message & {
|
|
19
19
|
name: 'message.reaction.remove';
|
|
20
20
|
} & Expansion;
|
|
21
|
-
export type PublicEventMessagePin =
|
|
21
|
+
export type PublicEventMessagePin = Platform & Guild & Channel & Message & {
|
|
22
22
|
name: 'message.pin';
|
|
23
23
|
} & Expansion;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Expansion } from '../base/expansion';
|
|
2
2
|
import { Message, MessageMedia, MessageOpen, MessageText } from '../base/message';
|
|
3
|
-
import {
|
|
3
|
+
import { Platform } from '../base/platform';
|
|
4
4
|
import { User } from '../base/user';
|
|
5
|
-
export type PrivateEventMessageCreate = MessageText & MessageMedia & MessageOpen &
|
|
5
|
+
export type PrivateEventMessageCreate = MessageText & MessageMedia & MessageOpen & Platform & Message & User & {
|
|
6
6
|
name: 'private.message.create';
|
|
7
7
|
} & Expansion;
|
|
8
|
-
export type PrivateEventMessageUpdate =
|
|
8
|
+
export type PrivateEventMessageUpdate = Platform & Message & User & {
|
|
9
9
|
name: 'private.message.update';
|
|
10
10
|
} & Expansion;
|
|
11
|
-
export type PrivateEventMessageDelete =
|
|
11
|
+
export type PrivateEventMessageDelete = Platform & Message & {
|
|
12
12
|
name: 'private.message.delete';
|
|
13
13
|
} & Expansion;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Guild, Channel } from '../base/guild';
|
|
2
2
|
import { Message } from '../base/message';
|
|
3
3
|
import { User } from '../base/user';
|
|
4
|
-
import {
|
|
4
|
+
import { Platform } from '../base/platform';
|
|
5
5
|
import { Expansion } from '../base/expansion';
|
|
6
|
-
export type PublicEventNoticeCreate =
|
|
6
|
+
export type PublicEventNoticeCreate = Platform & Guild & Channel & Message & User & {
|
|
7
7
|
name: 'notice.create';
|
|
8
8
|
} & Expansion;
|
|
9
|
-
export type PrivateEventNoticeCreate =
|
|
9
|
+
export type PrivateEventNoticeCreate = Platform & Message & User & {
|
|
10
10
|
name: 'private.notice.create';
|
|
11
11
|
} & Expansion;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Expansion } from '../base/expansion';
|
|
2
2
|
import { Message } from '../base/message';
|
|
3
|
-
import {
|
|
3
|
+
import { Platform } from '../base/platform';
|
|
4
4
|
import { User } from '../base/user';
|
|
5
|
-
export type PrivateEventRequestFriendAdd =
|
|
5
|
+
export type PrivateEventRequestFriendAdd = Platform & Message & User & {
|
|
6
6
|
name: 'private.friend.add';
|
|
7
7
|
} & Expansion;
|
|
8
|
-
export type PrivateEventRequestGuildAdd =
|
|
8
|
+
export type PrivateEventRequestGuildAdd = Platform & Message & User & {
|
|
9
9
|
name: 'private.guild.add';
|
|
10
10
|
} & Expansion;
|
|
11
|
-
export type PrivateEventRequestFriendRemove =
|
|
11
|
+
export type PrivateEventRequestFriendRemove = Platform & Message & User & {
|
|
12
12
|
name: 'private.friend.remove';
|
|
13
13
|
} & Expansion;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './event/request/index';
|
|
|
16
16
|
export * from './event/actions';
|
|
17
17
|
export * from './event/index';
|
|
18
18
|
export * from './event/map';
|
|
19
|
+
export * from './event/builder';
|
|
19
20
|
export * from './logger/index';
|
|
20
21
|
export * from './client/index';
|
|
21
22
|
export * from './message/index';
|
package/lib/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alemonjs",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.50",
|
|
4
4
|
"description": "bot script",
|
|
5
5
|
"author": "lemonade",
|
|
6
6
|
"license": "MIT",
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"type": "git",
|
|
70
70
|
"url": "https://github.com/lemonade-lab/alemonjs.git"
|
|
71
71
|
},
|
|
72
|
-
"gitHead": "
|
|
73
|
-
}
|
|
72
|
+
"gitHead": "41d135f9d54dda92785d1bec929db4afcf4a3f25"
|
|
73
|
+
}
|