67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
import z from "zod";
|
|
import { readdir } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import type { ComposeSpecification } from "../schema/docker.d";
|
|
import { file, YAML } from "bun";
|
|
|
|
const ComposeFileNames = new Set([
|
|
"compose.yml",
|
|
"compose.yaml",
|
|
"docker-compose.yml",
|
|
"docker-compose.yaml",
|
|
]);
|
|
|
|
let composeSchema: Promise<z.ZodType<ComposeSpecification>> | undefined;
|
|
|
|
function getComposeSchema(): Promise<z.ZodType<ComposeSpecification>> {
|
|
if (!composeSchema) {
|
|
composeSchema = import("../schema/docker.ts")
|
|
.then(
|
|
({ default: schema }) =>
|
|
z
|
|
.fromJSONSchema(
|
|
schema as unknown as Parameters<typeof z.fromJSONSchema>[0],
|
|
)
|
|
.superRefine((value, context) => {
|
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
return;
|
|
for (const key of Object.keys(value)) {
|
|
if (
|
|
Object.hasOwn(schema.properties, key) ||
|
|
key.startsWith("x-")
|
|
)
|
|
continue;
|
|
context.addIssue({
|
|
code: "custom",
|
|
path: [key],
|
|
message: `Unrecognized Compose property: ${key}`,
|
|
});
|
|
}
|
|
}) as z.ZodType<ComposeSpecification>,
|
|
)
|
|
.catch((error) => {
|
|
composeSchema = undefined;
|
|
throw error;
|
|
});
|
|
}
|
|
return composeSchema;
|
|
}
|
|
|
|
export function readCompose(path: string): Promise<ComposeSpecification> {
|
|
return file(path)
|
|
.text()
|
|
.then(YAML.parse)
|
|
.then(async (value) => (await getComposeSchema()).parse(value));
|
|
}
|
|
|
|
export async function resolveComposeFile(
|
|
path: string,
|
|
): Promise<string | undefined> {
|
|
const entries = await readdir(path, { withFileTypes: true });
|
|
|
|
return entries
|
|
.filter((entry) => entry.isFile() && ComposeFileNames.has(entry.name))
|
|
.map((entry) => join(path, entry.name))
|
|
.sort()[0];
|
|
}
|