import * as v from "../../shared/src/valita.js";
import { compoundKeySchema } from "../../zero-protocol/src/ast.js";
import { valueTypeSchema } from "../../zero-protocol/src/client-schema.js";
import { primaryKeySchema } from "../../zero-protocol/src/primary-key.js";
import { permissionsConfigSchema, } from "./compiled-permissions.js";
const relationshipPart = v.readonlyObject({
    sourceField: compoundKeySchema,
    destField: compoundKeySchema,
    destSchema: v.string(),
    cardinality: v.literalUnion('one', 'many'),
});
export const relationshipSchema = v.union(v.readonly(v.tuple([relationshipPart])), v.readonly(v.tuple([relationshipPart, relationshipPart])));
export const schemaValueSchema = v.readonlyObject({
    type: valueTypeSchema,
    serverName: v.string().optional(),
    optional: v.boolean().optional(),
});
export const tableSchemaSchema = v.readonlyObject({
    name: v.string(),
    serverName: v.string().optional(),
    columns: v.record(schemaValueSchema),
    primaryKey: primaryKeySchema,
});
export const schemaSchema = v.readonlyObject({
    tables: v.record(tableSchemaSchema),
    relationships: v.record(v.record(relationshipSchema)),
    enableLegacyQueries: v.boolean().optional(),
    enableLegacyMutators: v.boolean().optional(),
});
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
export function isSchemaConfig(value) {
    // oxlint-disable-next-line eqeqeq
    return value != null && 'schema' in value && 'permissions' in value;
}
export async function stringifySchema(module) {
    if (!isSchemaConfig(module)) {
        throw new Error('Schema file must have a export `schema` and `permissions`.');
    }
    const schemaConfig = module;
    const permissions = v.parse(await schemaConfig.permissions, permissionsConfigSchema);
    return JSON.stringify({
        permissions,
        schema: schemaConfig.schema,
    }, undefined, 2);
}
export function parseSchema(input, source) {
    try {
        const config = JSON.parse(input);
        const permissions = v.parse(config.permissions, permissionsConfigSchema);
        return {
            permissions,
            schema: config.schema,
        };
    }
    catch (e) {
        throw new Error(`Failed to parse schema config from ${source}: ${e}`);
    }
}
//# sourceMappingURL=schema-config.js.map