Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/content/modeling/agents/agents-as-principals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Check whether the agent can read a specific issue. The agent's project membershi
object={'issue:issue-123'}
allowed={true}
skipSetup={true}
pseudoCodeMode={true}
/>

The agent cannot delete the issue because `can_delete` requires `reporter` or project-level `can_delete` (which requires `owner` or `admin`):
Expand All @@ -110,6 +111,7 @@ The agent cannot delete the issue because `can_delete` requires `reporter` or pr
object={'issue:issue-123'}
allowed={false}
skipSetup={true}
pseudoCodeMode={true}
/>

## Direct assignment for fine-grained control
Expand Down
13 changes: 5 additions & 8 deletions src/components/Docs/SnippetViewer/BatchCheckRequestViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface BatchCheckRequestViewerOpts {
authorizationModelId?: string;
checks: Check[];
skipSetup?: boolean;
pseudoCodeMode?: boolean;
allowedLanguages?: SupportedLanguage[];
}

Expand All @@ -32,8 +33,7 @@ function batchCheckRequestViewer(lang: SupportedLanguage, opts: BatchCheckReques
throw new Error('Batch check is not supported in the CLI');

case SupportedLanguage.JS_SDK:
return `// Requires >=v0.8.0 for the server side BatchCheck, earlier versions support a client-side BatchCheck with a slightly different interface
const body = {
return `const body = {
checks: [
${checks
.map(
Expand Down Expand Up @@ -108,8 +108,7 @@ const { result } = await fgaClient.batchCheck(body, options);
*/`;

case SupportedLanguage.GO_SDK:
return `// Requires >=v0.7.0 for the server side BatchCheck, earlier versions support a client-side BatchCheck with a slightly different interface
body := ClientBatchCheckRequest{
return `body := ClientBatchCheckRequest{
Checks: []ClientBatchCheckItem{${checks
.map(
(check) => `
Expand Down Expand Up @@ -249,9 +248,7 @@ response.Result = [${checks
`;

case SupportedLanguage.PYTHON_SDK:
return `# Requires >=v0.9.0 for the server side BatchCheck, earlier versions support a client-side BatchCheck with a slightly different interface

checks = [${checks
return `checks = [${checks
.map(
(check) => `
ClientBatchCheckItem(
Expand Down Expand Up @@ -298,7 +295,7 @@ response = await fga_client.batch_check(ClientBatchCheckRequest(checks=checks),
.join(', ')}]`;

case SupportedLanguage.JAVA_SDK:
return ` // Requires >=v0.8.0 for the server side BatchCheck, earlier versions support a client-side BatchCheck with a slightly different interface
return `
var request = new ClientBatchCheckRequest().checks(
List.of(
${checks
Expand Down
16 changes: 5 additions & 11 deletions src/components/Docs/SnippetViewer/CheckRequestViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface CheckRequestViewerOpts {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
context?: Record<string, any>;
skipSetup?: boolean;
pseudoCodeMode?: boolean;
allowedLanguages?: SupportedLanguage[];

// Optional custom headers
Expand Down Expand Up @@ -256,12 +257,12 @@ response = await fga_client.check(body, options)
return `check(
user = "${user}", // check if the user \`${user}\`
relation = "${relation}", // has an \`${relation}\` relation
object = "${object}", // with the object \`${object}\`
${
object = "${object}", // with the object \`${object}\`${
contextualTuples
? `contextual_tuples = [ // Assuming the following is true
? `
contextual_tuples = [ // Assuming the following is true
${contextualTuples
.map((tuple) => `{user = "${tuple.user}", relation = "${tuple.relation}", object = "${tuple.object}"}`)
.map((tuple) => `{\n user = "${tuple.user}",\n relation = "${tuple.relation}",\n object = "${tuple.object}",\n }`)
.join(',\n ')}
],`
: ''
Expand All @@ -272,13 +273,6 @@ response = await fga_client.check(body, options)
.map(([k, v]) => `${k} = "${v}"`)
.join(', ')} },`
: ''
} authorization_id = "${modelId}"${
headers && Object.keys(headers).length > 0
? `
extra_headers = { ${Object.entries(headers)
.map(([k, v]) => `"${k}": "${v}"`)
.join(', ')} },`
: ''
}
);

Expand Down
85 changes: 81 additions & 4 deletions src/components/Docs/SnippetViewer/DefaultTabbedViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
Expand All @@ -8,6 +8,66 @@ import { GenerateSetupHeader, LanguageWrapper } from './SdkSetup';

export interface DefaultTabbedViewerOpts {
skipSetup?: boolean;
pseudoCodeMode?: boolean;
}

function SdkToggle<T extends DefaultTabbedViewerOpts>({
allowedLanguages,
opts,
tabViewFn,
langMappings,
}: {
allowedLanguages: SupportedLanguage[];
opts: T;
tabViewFn: (lang: SupportedLanguage, opts: T, langMappings: LanguageMappings) => string;
langMappings: LanguageMappings;
}): JSX.Element {
const [showSdk, setShowSdk] = useState(false);

const sdkLanguages = allowedLanguages.filter((l) => l !== SupportedLanguage.RPC);

Comment thread
aaguiarz marked this conversation as resolved.
Outdated
const toggleLink = (
<a
href="#"
onClick={(e) => {
e.preventDefault();
setShowSdk(!showSdk);
}}
style={{ fontSize: 'calc(1em - 4px)', textDecoration: 'none' }}
>
{showSdk ? 'View Pseudocode' : 'View SDK syntax'}
</a>
Comment thread
aaguiarz marked this conversation as resolved.
Outdated
);

Comment on lines +14 to +29
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SdkToggle, sdkLanguages, and showSdk are named as if the toggle only switches SDK languages, but the implementation includes all non-RPC languages (e.g., CLI/curl) by filtering only SupportedLanguage.RPC. Consider renaming to reflect the actual behavior (e.g., CodeToggle, codeLanguages, showCode) or tighten the filter to SDK languages if that’s the intent.

Copilot uses AI. Check for mistakes.
return (
<div style={{ position: 'relative' }}>
<div style={{ position: 'absolute', right: 0, top: 14, zIndex: 1 }}>
{toggleLink}
</div>
{showSdk ? (
sdkLanguages.length > 0 && (
<Tabs groupId="languages" values={getAllowedValuesLabels({ allowedLanguages: sdkLanguages })}>
{sdkLanguages.map((allowedLanguage) => (
<TabItem value={allowedLanguage} key={allowedLanguage}>
{GenerateSetupHeader(allowedLanguage, opts.skipSetup)}
{LanguageWrapper({
allowedLanguage: allowedLanguage,
content: tabViewFn(allowedLanguage, opts, langMappings),
})}
</TabItem>
))}
</Tabs>
)
) : (
<div style={{ paddingTop: '1.5rem' }}>
{LanguageWrapper({
allowedLanguage: SupportedLanguage.RPC,
content: tabViewFn(SupportedLanguage.RPC, opts, langMappings),
})}
</div>
)}
</div>
);
}

export function defaultOperationsViewer<T extends DefaultTabbedViewerOpts>(
Expand All @@ -16,9 +76,26 @@ export function defaultOperationsViewer<T extends DefaultTabbedViewerOpts>(
tabViewFn: (lang: SupportedLanguage, opts: T, langMappings: LanguageMappings) => string,
): JSX.Element {
const { siteConfig } = useDocusaurusContext();
const configuredLanguage = siteConfig.customFields.languageMapping as LanguageMappings;
const configuredLanguage = siteConfig.customFields?.languageMapping as LanguageMappings;

Comment thread
aaguiarz marked this conversation as resolved.
Outdated
const pseudoCodeMode = opts.pseudoCodeMode ?? false;
const hasRpc = allowedLanguages.includes(SupportedLanguage.RPC);

if (pseudoCodeMode && hasRpc) {
return (
<div style={{ marginTop: - 20}}>
Comment thread
aaguiarz marked this conversation as resolved.
Outdated
<SdkToggle
allowedLanguages={allowedLanguages}
opts={opts}
tabViewFn={tabViewFn}
langMappings={configuredLanguage}
/>
</div>
Comment thread
aaguiarz marked this conversation as resolved.
);
}
Comment thread
aaguiarz marked this conversation as resolved.

return (
<>
<div style={{ marginTop: -5 }}>
<Tabs groupId="languages" values={getAllowedValuesLabels({ allowedLanguages })}>
{allowedLanguages.map((allowedLanguage) => (
<TabItem value={allowedLanguage} key={allowedLanguage}>
Expand All @@ -30,6 +107,6 @@ export function defaultOperationsViewer<T extends DefaultTabbedViewerOpts>(
</TabItem>
))}
</Tabs>
</>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface ListObjectsRequestViewerOpts {
context?: Record<string, any>;
expectedResults: string[];
skipSetup?: boolean;
pseudoCodeMode?: boolean;
allowedLanguages?: SupportedLanguage[];
}

Expand Down Expand Up @@ -206,8 +207,7 @@ response = await fga_client.list_objects(body, options)
return `listObjects(
"${user}", // list the objects that the user \`${user}\`
"${relation}", // has an \`${relation}\` relation
"${objectType}", // and that are of type \`${objectType}\`
authorization_model_id = "${modelId}", // for this particular authorization model id ${
"${objectType}", // and that are of type \`${objectType}\` ${
contextualTuples
? `
contextual_tuples = [ // Assuming the following is true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface ListUsersRequestViewerOpts {
context?: Record<string, any>;
expectedResults: ListUsersResponse;
skipSetup?: boolean;
pseudoCodeMode?: boolean;
allowedLanguages?: SupportedLanguage[];
}

Expand Down Expand Up @@ -263,8 +264,7 @@ var response = await fgaClient.ListUsers(body, options);
return `listUsers(
user_filter=[ "${userFilterType}" ], // list users of type \`${userFilterType}\`
"${relation}", // that have the \`${relation}\` relation
"${objectType}:${objectId}", // for the object \`${objectType}:${objectId}\`
authorization_model_id = "${modelId}", // for this particular authorization model id ${
"${objectType}:${objectId}", // for the object \`${objectType}:${objectId}\` ${
contextualTuples
? `
contextual_tuples = [ // Assuming the following is true
Expand Down
4 changes: 2 additions & 2 deletions src/components/Docs/SnippetViewer/WriteRequestViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,8 @@ response = await fga_client.write(body, options)
}`,
)
.join(',');
const writes = `write([${writeTuples}\n], authorization_model_id="${modelId}")`;
const deletes = `delete([${deleteTuples}\n], authorization_model_id="${modelId}")`;
const writes = `write([${writeTuples}\n])`;
const deletes = `delete([${deleteTuples}\n])`;
Comment thread
aaguiarz marked this conversation as resolved.
const separator = `${opts.deleteRelationshipTuples && opts.relationshipTuples ? ',' : ''}`;

return `${opts.relationshipTuples ? writes : ''}${separator}
Expand Down
Loading