import { literalUnion, parse, valita_exports } from "../../../shared/src/valita.js";
import { logOptions } from "../../../otel/src/log-options.js";
import { appOptions, shardOptions, zeroOptions } from "../config/zero-config.js";
import { colorConsole } from "../../../shared/src/logging.js";
import { permissionsConfigSchema } from "../../../zero-schema/src/compiled-permissions.js";
import { isSchemaConfig } from "../../../zero-schema/src/schema-config.js";
import { existsSync } from "node:fs";
import { basename, dirname, join, relative, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
import { tsImport } from "tsx/esm/api";
//#region ../zero-cache/src/scripts/permissions.ts
var deployPermissionsOptions = {
	schema: { path: {
		type: valita_exports.string().default("schema.ts"),
		desc: ["Relative path to the file containing the schema definition."],
		alias: "p"
	} },
	upstream: {
		db: {
			type: valita_exports.string().optional(),
			desc: [`The upstream Postgres database to deploy permissions to.`, `This is ignored if an {bold output-file} is specified.`]
		},
		type: zeroOptions.upstream.type
	},
	app: { id: appOptions.id },
	shard: shardOptions,
	log: logOptions,
	output: {
		file: {
			type: valita_exports.string().optional(),
			desc: [`Outputs the permissions to a file with the requested {bold output-format}.`]
		},
		format: {
			type: literalUnion("sql", "json", "pretty").default("sql"),
			desc: [
				`The desired format of the output file.`,
				``,
				`A {bold sql} file can be executed via "psql -f <file.sql>", or "\\\\i <file.sql>"`,
				`from within the psql console, or copied and pasted into a migration script.`,
				``,
				`The {bold json} and {bold pretty} formats are available for non-pg backends`,
				`and general debugging.`
			]
		}
	},
	force: {
		type: valita_exports.boolean().default(false),
		desc: [`Deploy to upstream without validation. Use at your own risk.`],
		alias: "f"
	}
};
async function loadSchemaAndPermissions(schemaPath, allowMissing) {
	const typeModuleErrorMessage = () => `\n\nYou may need to add \` "type": "module" \` to the package.json file for ${schemaPath}.\n`;
	colorConsole.info(`Loading schema from ${schemaPath}`);
	const dir = dirname(fileURLToPath(import.meta.url));
	const absoluteSchemaPath = resolve(schemaPath);
	const relativeDir = relative(dir, dirname(absoluteSchemaPath));
	let relativePath = relativeDir.length && relativeDir !== "." ? join(relativeDir, basename(absoluteSchemaPath)) : `.${sep}${basename(absoluteSchemaPath)}`;
	relativePath = relativePath.replace(/\\/g, "/");
	if (!existsSync(absoluteSchemaPath)) {
		if (allowMissing) return;
		colorConsole.error(`Schema file ${schemaPath} does not exist.`);
		process.exit(1);
	}
	let module;
	try {
		module = await tsImport(relativePath, import.meta.url);
	} catch (e) {
		colorConsole.error(`Failed to load zero schema from ${absoluteSchemaPath}` + typeModuleErrorMessage());
		throw e;
	}
	if (!isSchemaConfig(module)) {
		colorConsole.error(`Schema file ${schemaPath} must export [schema].` + typeModuleErrorMessage());
		process.exit(1);
	}
	try {
		const schemaConfig = module;
		const perms = await schemaConfig.permissions;
		const { schema } = schemaConfig;
		if (perms) colorConsole.warn?.("Permissions are deprecated and will be removed in an upcoming release. See: https://zero.rocicorp.dev/docs/auth.");
		return {
			schema,
			permissions: parse(perms ?? {}, permissionsConfigSchema)
		};
	} catch (e) {
		colorConsole.error(`Failed to parse Permissions object`);
		throw e;
	}
}
//#endregion
export { deployPermissionsOptions, loadSchemaAndPermissions };

//# sourceMappingURL=permissions.js.map