mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-20 07:47:19 +08:00
112 lines
4.1 KiB
TypeScript
112 lines
4.1 KiB
TypeScript
import {
|
|
type CollectedApisMap,
|
|
type CollectedEventsMap,
|
|
type Entry,
|
|
} from './types';
|
|
|
|
export const determineEntry = (path: string): Entry => {
|
|
if (path.includes('src/entries/helper')) return 'helper';
|
|
return 'main';
|
|
};
|
|
|
|
/**
|
|
* Generates the API type definitions file content
|
|
*/
|
|
export function generateApiTypesFile(collectedApis: CollectedApisMap): string {
|
|
let content = `// AUTO-GENERATED FILE. DO NOT EDIT MANUALLY.\n// Generated by: packages/frontend/apps/electron/scripts/generate-types.ts\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n`;
|
|
|
|
content += `// Utility type: remove trailing IpcMainInvokeEvent param and ensure Promise return\n`;
|
|
content += `type EnsurePromise<T> = T extends Promise<any> ? T : Promise<T>;\n`;
|
|
content += `export type ApiMethod<T> = T extends (...args: infer P) => infer R ? (...args: P) => EnsurePromise<R> : never;\n\n`;
|
|
|
|
content += `export interface ElectronApis {\n`;
|
|
|
|
for (const [scope, methods] of collectedApis) {
|
|
content += ` ${scope}: {\n`;
|
|
for (const method of methods) {
|
|
if (method.description && method.description.trim().length > 0) {
|
|
const lines = method.description.split('\n').map(l => ` * ${l}`);
|
|
content += ' /**\n';
|
|
content += lines.join('\n') + '\n';
|
|
content += ' */\n';
|
|
}
|
|
content += ` ${method.apiMethodName}: ApiMethod<import('${method.modulePath}').${method.className}['${method.methodName}']>;\n`;
|
|
}
|
|
content += ` };\n`;
|
|
}
|
|
|
|
content += `}\n`;
|
|
return content;
|
|
}
|
|
|
|
/**
|
|
* Generates the event type definitions file content
|
|
*/
|
|
export function generateEventTypesFile(
|
|
collectedEvents: CollectedEventsMap
|
|
): string {
|
|
let out = `// AUTO-GENERATED FILE. DO NOT EDIT MANUALLY.\n// Generated by: packages/frontend/apps/electron/scripts/generate-types.ts\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Observable } from 'rxjs';\n\n`;
|
|
|
|
out += `type ToSubscribe<T extends Observable<unknown>> = T extends Observable<infer P> ? (callback: (payload: P) => void) => () => void : never;\n\n`;
|
|
|
|
out += `export interface ElectronEvents {\n`;
|
|
for (const [scope, events] of collectedEvents) {
|
|
out += ` ${scope}: {\n`;
|
|
for (const evt of events) {
|
|
const capName =
|
|
evt.eventName.charAt(0).toUpperCase() + evt.eventName.slice(1);
|
|
if (evt.description && evt.description.trim().length > 0) {
|
|
const lines = evt.description.split('\n').map(l => ` * ${l}`);
|
|
out += ' /**\n';
|
|
out += lines.join('\n') + '\n';
|
|
out += ' */\n';
|
|
}
|
|
out += ` on${capName}: ToSubscribe<import('${evt.modulePath}').${evt.className}['${evt.propertyName}']>;\n`;
|
|
}
|
|
out += ` };\n`;
|
|
}
|
|
out += `}\n`;
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Generates a combined metadata file for both IPC handlers and events
|
|
*/
|
|
export function generateCombinedMetaFile(
|
|
apiHandlers: CollectedApisMap,
|
|
events: CollectedEventsMap
|
|
): string {
|
|
let content = `// AUTO-GENERATED FILE. DO NOT EDIT MANUALLY.\n// Generated by: packages/frontend/apps/electron/scripts/generate-types.ts\n/* eslint-disable @typescript-eslint/no-explicit-any */\n`;
|
|
|
|
// Build nested structure: entry -> scope -> names[]
|
|
const handlersMeta: Record<string, Record<string, string[]>> = {};
|
|
apiHandlers.forEach((methods, scope) => {
|
|
methods.forEach(m => {
|
|
const ent = m.entry;
|
|
if (!handlersMeta[ent]) handlersMeta[ent] = {};
|
|
if (!handlersMeta[ent][scope]) handlersMeta[ent][scope] = [];
|
|
handlersMeta[ent][scope].push(m.apiMethodName);
|
|
});
|
|
});
|
|
|
|
const eventsMeta: Record<string, Record<string, string[]>> = {};
|
|
events.forEach((evtList, scope) => {
|
|
evtList.forEach(e => {
|
|
const ent = e.entry;
|
|
if (!eventsMeta[ent]) eventsMeta[ent] = {};
|
|
if (!eventsMeta[ent][scope]) eventsMeta[ent][scope] = [];
|
|
eventsMeta[ent][scope].push(e.eventName);
|
|
});
|
|
});
|
|
|
|
// Serialize handlersMeta & eventsMeta
|
|
content += `export const handlersMeta = ${JSON.stringify(
|
|
handlersMeta,
|
|
null,
|
|
2
|
|
)} as const;\n\n`;
|
|
content += `export const eventsMeta = ${JSON.stringify(eventsMeta, null, 2)} as const;\n`;
|
|
|
|
return content;
|
|
}
|