export async function generator()

in packages/better-auth/src/plugins/open-api/generator.ts [274:468]


export async function generator(ctx: AuthContext, options: BetterAuthOptions) {
	const baseEndpoints = getEndpoints(ctx, {
		...options,
		plugins: [],
	});

	const tables = getAuthTables(options);
	const models = Object.entries(tables).reduce((acc, [key, value]) => {
		const modelName = key.charAt(0).toUpperCase() + key.slice(1);
		// @ts-ignore
		acc[modelName] = {
			type: "object",
			properties: Object.entries(value.fields).reduce(
				(acc, [key, value]) => {
					acc[key] = {
						type: value.type,
					};
					return acc;
				},
				{ id: { type: "string" } } as Record<string, any>,
			),
		};
		return acc;
	}, {});

	const components = {
		schemas: {
			...models,
		},
	};

	Object.entries(baseEndpoints.api).forEach(([_, value]) => {
		if (ctx.options.disabledPaths?.includes(value.path)) return;
		const options = value.options as EndpointOptions;
		if (options.metadata?.SERVER_ONLY) return;
		const path = toOpenApiPath(value.path);
		if (options.method === "GET") {
			paths[path] = {
				get: {
					tags: ["Default", ...(options.metadata?.openapi?.tags || [])],
					description: options.metadata?.openapi?.description,
					operationId: options.metadata?.openapi?.operationId,
					security: [
						{
							bearerAuth: [],
						},
					],
					parameters: getParameters(options),
					responses: getResponse(options.metadata?.openapi?.responses),
				},
			};
		}

		if (options.method === "POST") {
			const body = getRequestBody(options);
			paths[path] = {
				post: {
					tags: ["Default", ...(options.metadata?.openapi?.tags || [])],
					description: options.metadata?.openapi?.description,
					operationId: options.metadata?.openapi?.operationId,
					security: [
						{
							bearerAuth: [],
						},
					],
					parameters: getParameters(options),
					...(body
						? { requestBody: body }
						: {
								requestBody: {
									//set body none
									content: {
										"application/json": {
											schema: {
												type: "object",
												properties: {},
											},
										},
									},
								},
							}),
					responses: getResponse(options.metadata?.openapi?.responses),
				},
			};
		}
	});

	for (const plugin of options.plugins || []) {
		if (plugin.id === "open-api") {
			continue;
		}
		const pluginEndpoints = getEndpoints(ctx, {
			...options,
			plugins: [plugin],
		});
		const api = Object.keys(pluginEndpoints.api)
			.map((key) => {
				if (
					baseEndpoints.api[key as keyof typeof baseEndpoints.api] === undefined
				) {
					return pluginEndpoints.api[key as keyof typeof pluginEndpoints.api];
				}
				return null;
			})
			.filter((x) => x !== null) as Endpoint[];
		Object.entries(api).forEach(([key, value]) => {
			if (ctx.options.disabledPaths?.includes(value.path)) return;
			const options = value.options as EndpointOptions;
			if (options.metadata?.SERVER_ONLY) return;
			const path = toOpenApiPath(value.path);
			if (options.method === "GET") {
				paths[path] = {
					get: {
						tags: options.metadata?.openapi?.tags || [
							plugin.id.charAt(0).toUpperCase() + plugin.id.slice(1),
						],
						description: options.metadata?.openapi?.description,
						operationId: options.metadata?.openapi?.operationId,
						security: [
							{
								bearerAuth: [],
							},
						],
						parameters: getParameters(options),
						responses: getResponse(options.metadata?.openapi?.responses),
					},
				};
			}
			if (options.method === "POST") {
				paths[path] = {
					post: {
						tags: options.metadata?.openapi?.tags || [
							plugin.id.charAt(0).toUpperCase() + plugin.id.slice(1),
						],
						description: options.metadata?.openapi?.description,
						operationId: options.metadata?.openapi?.operationId,
						security: [
							{
								bearerAuth: [],
							},
						],
						parameters: getParameters(options),
						requestBody: getRequestBody(options),
						responses: getResponse(options.metadata?.openapi?.responses),
					},
				};
			}
		});
	}

	const res = {
		openapi: "3.1.1",
		info: {
			title: "Better Auth",
			description: "API Reference for your Better Auth Instance",
			version: "1.1.0",
		},
		components: {
			...components,
			securitySchemes: {
				apiKeyCookie: {
					type: "apiKey",
					in: "cookie",
					name: "apiKeyCookie",
					description: "API Key authentication via cookie",
				},
				bearerAuth: {
					type: "http",
					scheme: "bearer",
					description: "Bearer token authentication",
				},
			},
		},
		security: [
			{
				apiKeyCookie: [],
				bearerAuth: [],
			},
		],
		servers: [
			{
				url: ctx.baseURL,
			},
		],
		tags: [
			{
				name: "Default",
				description:
					"Default endpoints that are included with Better Auth by default. These endpoints are not part of any plugin.",
			},
		],
		paths,
	};
	return res;
}