mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-09 04:19:26 +00:00
docs: fix method match actual behavior (#5238)
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { Endpoint } from "./endpoint";
|
||||
// import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
||||
import { DynamicCodeBlock } from "./ui/dynamic-code-block";
|
||||
import {
|
||||
Table,
|
||||
@@ -46,6 +45,8 @@ const placeholderProperty: Property = {
|
||||
isClientOnly: false,
|
||||
};
|
||||
|
||||
const indentationSpace = ` `;
|
||||
|
||||
export const APIMethod = ({
|
||||
path,
|
||||
isServerOnly,
|
||||
@@ -129,7 +130,14 @@ export const APIMethod = ({
|
||||
let { props, functionName, code_prefix, code_suffix } = parseCode(children);
|
||||
|
||||
const authClientMethodPath = pathToDotNotation(path);
|
||||
const clientBody = createClientBody({ props });
|
||||
|
||||
const clientBody = createClientBody({
|
||||
props,
|
||||
method: method ?? "GET",
|
||||
forceAsBody,
|
||||
forceAsQuery,
|
||||
});
|
||||
|
||||
const serverBody = createServerBody({
|
||||
props,
|
||||
method: method ?? "GET",
|
||||
@@ -589,29 +597,75 @@ function parseCode(children: JSX.Element) {
|
||||
};
|
||||
}
|
||||
|
||||
const indentationSpace = ` `;
|
||||
/**
|
||||
* Builds a property line with proper formatting and comments
|
||||
*/
|
||||
function buildPropertyLine(
|
||||
prop: Property,
|
||||
indentLevel: number,
|
||||
additionalComments: string[] = [],
|
||||
): string {
|
||||
const comments: string[] = [...additionalComments];
|
||||
if (!prop.isOptional) comments.push("required");
|
||||
if (prop.comments) comments.push(prop.comments);
|
||||
const addComment = comments.length > 0;
|
||||
|
||||
function createClientBody({ props }: { props: Property[] }) {
|
||||
let body = ``;
|
||||
const indent = indentationSpace.repeat(indentLevel);
|
||||
const propValue = prop.exampleValue ? `: ${prop.exampleValue}` : "";
|
||||
const commentText = addComment ? ` // ${comments.join(", ")}` : "";
|
||||
|
||||
if (prop.type === "Object") {
|
||||
// For object types, put comment after the opening brace
|
||||
return `${indent}${prop.propName}${propValue}: {${commentText}\n`;
|
||||
} else {
|
||||
// For non-object types, put comment after the comma
|
||||
return `${indent}${prop.propName}${propValue},${commentText}\n`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the client request should use query parameters
|
||||
*
|
||||
* - GET requests use query params by default, unless `forceAsBody` is true
|
||||
* - Any request can be forced to use query params with `forceAsQuery`
|
||||
*/
|
||||
function shouldClientUseQueryParams(
|
||||
method: string | undefined,
|
||||
forceAsBody: boolean | undefined,
|
||||
forceAsQuery: boolean | undefined,
|
||||
): boolean {
|
||||
if (forceAsQuery) return true;
|
||||
if (forceAsBody) return false;
|
||||
return method === "GET";
|
||||
}
|
||||
|
||||
function createClientBody({
|
||||
props,
|
||||
method,
|
||||
forceAsBody,
|
||||
forceAsQuery,
|
||||
}: {
|
||||
props: Property[];
|
||||
method?: string;
|
||||
forceAsBody?: boolean;
|
||||
forceAsQuery?: boolean;
|
||||
}) {
|
||||
const isQueryParam = shouldClientUseQueryParams(
|
||||
method,
|
||||
forceAsBody,
|
||||
forceAsQuery,
|
||||
);
|
||||
const baseIndentLevel = isQueryParam ? 2 : 1;
|
||||
|
||||
let params = ``;
|
||||
|
||||
let i = -1;
|
||||
for (const prop of props) {
|
||||
i++;
|
||||
if (prop.isServerOnly) continue;
|
||||
if (body === "") body += "{\n";
|
||||
if (params === "") params += "{\n";
|
||||
|
||||
let addComment = false;
|
||||
let comment: string[] = [];
|
||||
if (!prop.isOptional || prop.comments) addComment = true;
|
||||
|
||||
if (!prop.isOptional) comment.push("required");
|
||||
if (prop.comments) comment.push(prop.comments);
|
||||
|
||||
body += `${indentationSpace.repeat(prop.path.length + 1)}${prop.propName}${
|
||||
prop.exampleValue ? `: ${prop.exampleValue}` : ""
|
||||
}${prop.type === "Object" ? ": {" : ","}${
|
||||
addComment ? ` // ${comment.join(", ")}` : ""
|
||||
}\n`;
|
||||
params += buildPropertyLine(prop, prop.path.length + baseIndentLevel);
|
||||
|
||||
if ((props[i + 1]?.path?.length || 0) < prop.path.length) {
|
||||
const diff = prop.path.length - (props[i + 1]?.path?.length || 0);
|
||||
@@ -620,13 +674,37 @@ function createClientBody({ props }: { props: Property[] }) {
|
||||
.fill(0)
|
||||
.map((_, i) => i)
|
||||
.reverse()) {
|
||||
body += `${indentationSpace.repeat(index + 1)}},\n`;
|
||||
params += `${indentationSpace.repeat(index + baseIndentLevel)}},\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (body !== "") body += "}";
|
||||
|
||||
return body;
|
||||
if (params !== "") {
|
||||
if (isQueryParam) {
|
||||
// Wrap in query object for GET requests and when forceAsQuery is true
|
||||
params = `{\n query: ${params} },\n}`;
|
||||
} else {
|
||||
params += "}";
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the server request should use query parameters
|
||||
*
|
||||
* - GET requests use query params by default, unless `forceAsBody` is true
|
||||
* - Other methods (POST, PUT, DELETE) use body by default, unless `forceAsQuery` is true
|
||||
*/
|
||||
function shouldServerUseQueryParams(
|
||||
method: string,
|
||||
forceAsBody: boolean | undefined,
|
||||
forceAsQuery: boolean | undefined,
|
||||
): boolean {
|
||||
if (forceAsQuery) return true;
|
||||
if (forceAsBody) return false;
|
||||
return method === "GET";
|
||||
}
|
||||
|
||||
function createServerBody({
|
||||
@@ -642,24 +720,24 @@ function createServerBody({
|
||||
forceAsQuery: boolean | undefined;
|
||||
forceAsBody: boolean | undefined;
|
||||
}) {
|
||||
let serverBody = "";
|
||||
|
||||
let body2 = ``;
|
||||
const isQueryParam = shouldServerUseQueryParams(
|
||||
method,
|
||||
forceAsBody,
|
||||
forceAsQuery,
|
||||
);
|
||||
const clientOnlyProps = props.filter((x) => !x.isClientOnly);
|
||||
|
||||
// Build properties content
|
||||
let propertiesContent = ``;
|
||||
let i = -1;
|
||||
|
||||
for (const prop of props) {
|
||||
i++;
|
||||
if (prop.isClientOnly) continue;
|
||||
if (body2 === "") body2 += "{\n";
|
||||
if (propertiesContent === "") propertiesContent += "{\n";
|
||||
|
||||
let addComment = false;
|
||||
let comment: string[] = [];
|
||||
|
||||
if (!prop.isOptional || prop.comments) {
|
||||
addComment = true;
|
||||
}
|
||||
|
||||
if (
|
||||
// Check if this is a server-only nested property
|
||||
const isNestedServerOnlyProp =
|
||||
prop.isServerOnly &&
|
||||
!(
|
||||
prop.path.length &&
|
||||
@@ -669,19 +747,17 @@ function createServerBody({
|
||||
prop.path.slice(0, prop.path.length - 2).join(".") &&
|
||||
x.propName === prop.path[prop.path.length - 1],
|
||||
)
|
||||
)
|
||||
) {
|
||||
comment.push("server-only");
|
||||
addComment = true;
|
||||
}
|
||||
if (!prop.isOptional) comment.push("required");
|
||||
if (prop.comments) comment.push(prop.comments);
|
||||
);
|
||||
|
||||
const additionalComments: string[] = [];
|
||||
if (isNestedServerOnlyProp) additionalComments.push("server-only");
|
||||
|
||||
propertiesContent += buildPropertyLine(
|
||||
prop,
|
||||
prop.path.length + 2,
|
||||
additionalComments,
|
||||
);
|
||||
|
||||
body2 += `${indentationSpace.repeat(prop.path.length + 2)}${prop.propName}${
|
||||
prop.exampleValue ? `: ${prop.exampleValue}` : ""
|
||||
}${prop.type === "Object" ? ": {" : ","}${
|
||||
addComment ? ` // ${comment.join(", ")}` : ""
|
||||
}\n`;
|
||||
if ((props[i + 1]?.path?.length || 0) < prop.path.length) {
|
||||
const diff = prop.path.length - (props[i + 1]?.path?.length || 0);
|
||||
|
||||
@@ -689,29 +765,31 @@ function createServerBody({
|
||||
.fill(0)
|
||||
.map((_, i) => i)
|
||||
.reverse()) {
|
||||
body2 += `${indentationSpace.repeat(index + 2)}},\n`;
|
||||
propertiesContent += `${indentationSpace.repeat(index + 2)}},\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (body2 !== "") body2 += " },";
|
||||
|
||||
if (propertiesContent !== "") propertiesContent += " },";
|
||||
|
||||
// Build fetch options
|
||||
let fetchOptions = "";
|
||||
if (requireSession) {
|
||||
fetchOptions +=
|
||||
"\n // This endpoint requires session cookies.\n headers: await headers(),";
|
||||
}
|
||||
|
||||
if (props.filter((x) => !x.isClientOnly).length > 0) {
|
||||
serverBody += "{\n";
|
||||
if ((method === "POST" || forceAsBody) && !forceAsQuery) {
|
||||
serverBody += ` body: ${body2}${fetchOptions}\n}`;
|
||||
} else {
|
||||
serverBody += ` query: ${body2}${fetchOptions}\n}`;
|
||||
}
|
||||
// Assemble final result
|
||||
let result = "";
|
||||
if (clientOnlyProps.length > 0) {
|
||||
result += "{\n";
|
||||
const paramType = isQueryParam ? "query" : "body";
|
||||
result += ` ${paramType}: ${propertiesContent}${fetchOptions}\n}`;
|
||||
} else if (fetchOptions.length) {
|
||||
serverBody += `{${fetchOptions}\n}`;
|
||||
result += `{${fetchOptions}\n}`;
|
||||
}
|
||||
return serverBody;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function Note({ children }: { children: ReactNode }) {
|
||||
|
||||
Reference in New Issue
Block a user