• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { isNumber } from './safe-types';
17import { Plugins, PluginContext, PluginHandler, PluginState, PluginExecutor } from '../../common/plugin-context';
18import * as arkts from '@koalaui/libarkts';
19
20export interface PluginDriver {
21    initPlugins(plugins: Plugins[]): void;
22    getSortedPlugins(state: arkts.Es2pandaContextState): PluginExecutor[] | undefined;
23    getPluginContext(): PluginContext;
24}
25
26function toCamelCase(str: string): string {
27    return str
28        .split('_')
29        .map((word, index) => {
30            if (index === 0) {
31                return word;
32            }
33            return word.charAt(0).toUpperCase() + word.slice(1);
34        })
35        .join('');
36}
37
38function stateName(value: arkts.Es2pandaContextState): PluginState {
39    return toCamelCase(
40        arkts.Es2pandaContextState[value].substring('ES2PANDA_STATE_'.length).toLowerCase()
41    ) as PluginState;
42}
43
44function selectPlugins(plugins: Plugins[], stage: PluginState): PluginExecutor[] {
45    const pre: PluginExecutor[] = [];
46    const normal: PluginExecutor[] = [];
47    const post: PluginExecutor[] = [];
48
49    plugins
50        .filter((it) => stage in it)
51        .forEach((it) => {
52            const pluginName: string = it.name;
53            const handler: PluginHandler = it[stage]!;
54            const order: string | undefined = typeof handler === 'object' ? handler.order : undefined;
55            const rawPluginHook: PluginExecutor = {
56                name: pluginName,
57                handler: typeof handler === 'object' ? handler.handler : handler,
58            };
59
60            if (order === 'pre') {
61                pre.push(rawPluginHook);
62            } else if (order === 'post') {
63                post.push(rawPluginHook);
64            } else {
65                normal.push(rawPluginHook);
66            }
67        });
68
69    return [...pre, ...normal, ...post];
70}
71
72class MockPluginDriver implements PluginDriver {
73    private sortedPlugins: Map<arkts.Es2pandaContextState, PluginExecutor[] | undefined>;
74    private context: PluginContext;
75
76    constructor() {
77        this.sortedPlugins = new Map<arkts.Es2pandaContextState, PluginExecutor[] | undefined>();
78        this.context = new PluginContext();
79    }
80
81    public initPlugins(plugins: Plugins[]): void {
82        const pluginsByState = new Map<arkts.Es2pandaContextState, PluginExecutor[] | undefined>();
83
84        Object.values(arkts.Es2pandaContextState)
85            .filter(isNumber)
86            .forEach((it) => {
87                const selected = selectPlugins(plugins, stateName(it));
88                if (selected.length > 0) {
89                    pluginsByState.set(it, selected);
90                } else {
91                    pluginsByState.set(it, undefined);
92                }
93            });
94
95        this.sortedPlugins = pluginsByState;
96    }
97
98    public getSortedPlugins(state: arkts.Es2pandaContextState): PluginExecutor[] | undefined {
99        return this.sortedPlugins.get(state);
100    }
101
102    public getPluginContext(): PluginContext {
103        return this.context;
104    }
105}
106
107export { stateName, MockPluginDriver };
108