-
Notifications
You must be signed in to change notification settings - Fork 379
Expand file tree
/
Copy pathgenerate-provider-registry.ts
More file actions
79 lines (70 loc) · 2.67 KB
/
Copy pathgenerate-provider-registry.ts
File metadata and controls
79 lines (70 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import type { ProviderSource } from "./provider-source.ts";
import { readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { loadProviderSources } from "./provider-source.ts";
const providersDir = join(process.cwd(), "src/providers");
/**
* Generate provider registries from definitions already loaded by the caller.
*/
export async function generateProviderRegistries(providerSources: ProviderSource[]): Promise<void> {
await Promise.all([
writeRegistry("registry.generated.ts", providerSources),
writeRegistry(
"registry.cloudflare.generated.ts",
providerSources.filter((source) => !source.nodeOnly),
),
]);
}
if (import.meta.main) {
await generateProviderRegistries(await loadProviderSources());
}
function propertyName(service: string): string {
return /^[A-Za-z_$][\w$]*$/.test(service) ? service : JSON.stringify(service);
}
async function writeRegistry(filename: string, sources: ProviderSource[]): Promise<void> {
const services = sources.map((source) => source.service);
const executableActionIds = new Map<string, string[]>(
sources.map((source) => [
source.service,
source.definition.actions.map((action) => action.id).sort((a, b) => a.localeCompare(b)),
]),
);
const lines = [
'import type { ExecutorModule } from "./provider-loader.ts";',
"",
"/** Generated lazy imports for provider executors. Do not hand-edit. */",
"export const executorModules: Record<string, () => Promise<ExecutorModule>> = {",
...services.map(
(service) => ` ${propertyName(service)}: (): Promise<ExecutorModule> => import("./${service}/executors.ts"),`,
),
"};",
"",
"/** Generated local executable action ids by provider. Do not hand-edit. */",
"export const executableActionIds: Record<string, string[]> = {",
...services.flatMap((service) => [
` ${propertyName(service)}: [`,
...(executableActionIds.get(service) ?? []).map((actionId) => ` ${JSON.stringify(actionId)},`),
" ],",
]),
"};",
];
const path = join(providersDir, filename);
const content = `${lines.join("\n")}\n`;
const existingContent = await readTextFile(path);
if (existingContent !== content) {
await writeFile(path, content);
console.log(`Generated ${filename} for ${services.length} providers.`);
} else {
console.log(`${filename} is up to date for ${services.length} providers.`);
}
}
async function readTextFile(path: string): Promise<string | undefined> {
try {
return await readFile(path, "utf8");
} catch (error) {
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
return undefined;
}
throw error;
}
}