Skip to content
Merged
5 changes: 5 additions & 0 deletions .claude/skills/sdk-docs-writing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ const records = await base44.entities.MyEntity.list();
- **Avoid gerunds** in section headings within JSDoc. Prefer imperatives or noun phrases.
- **State environment constraints** when a method is browser-only: "Requires a browser environment and can't be used in the backend."
- **Document side effects** explicitly (e.g., "automatically sets the token for subsequent requests").
- **Link method references.** When mentioning another SDK method or module by name in JSDoc prose, always use `{@link}` or `{@linkcode}` to create a cross-reference. Never leave a method name as plain text when a link target exists.

## Doc generation pipeline

Expand All @@ -196,6 +197,10 @@ mint dev

When adding a new public type, add it to `types-to-expose.json`. When a helper type should live inside another page, add it to `appended-articles.json`.

## Review checklist for multi-page changes

When a docs task touches three or more pages in `mintlify-docs` (including pages regenerated by `create-docs-local`), create a `REVIEW-CHECKLIST.md` file in the mintlify-docs repo root listing every affected page with its URL path and what to verify. Split the list into intentional changes and side-effect changes from regeneration. Add a reminder to delete the file before committing. Tell the user the checklist exists so they can work through it at their own pace.

## Checklist before submitting a PR

1. **JSDoc completeness:** Every public method has description, `@param`, `@returns`, and `@example`.
Expand Down
4 changes: 4 additions & 0 deletions scripts/mintlify-post-processing/appended-articles.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"interfaces/ConnectorsModule": [
"type-aliases/ConnectorIntegrationType",
"interfaces/ConnectorIntegrationTypeRegistry"
],
"type-aliases/EntitiesModule": [
"interfaces/EntityHandler",
"type-aliases/EntityRecord",
Expand Down
13 changes: 7 additions & 6 deletions scripts/mintlify-post-processing/copy-to-local-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ function updateDocsJson(repoDir, sdkFiles) {
`SDK Reference pages: ${JSON.stringify(sdkReferencePages, null, 2)}`
);

// Navigate to: Developers tab -> anchors -> SDK anchor -> groups -> SDK Reference
// Navigate to: Developers tab -> SDK section -> groups -> SDK Reference
// Supports both legacy "anchors" format and current "dropdowns" format.
const developersTab = docs.navigation.tabs.find(
(tab) => tab.tab === "Developers"
);
Expand All @@ -170,13 +171,13 @@ function updateDocsJson(repoDir, sdkFiles) {
process.exit(1);
}

// Find the SDK anchor
const sdkAnchor = developersTab.anchors?.find(
(anchor) => anchor.anchor === "SDK"
);
// Find the SDK section (try dropdowns first, then fall back to anchors)
const sdkAnchor =
developersTab.dropdowns?.find((d) => d.dropdown === "SDK") ??
developersTab.anchors?.find((a) => a.anchor === "SDK");

if (!sdkAnchor) {
console.error("Could not find 'SDK' anchor in Developers tab");
console.error("Could not find 'SDK' dropdown or anchor in Developers tab");
process.exit(1);
}

Expand Down
125 changes: 125 additions & 0 deletions scripts/mintlify-post-processing/file-processing/file-processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,123 @@ function applySignatureCleanup(dir) {
}
}

/**
* Transforms deprecated method sections:
* 1. Removes ~~strikethrough~~ and prepends a warning emoji to the heading
* 2. Extracts the #### Deprecated block, removes it, and re-inserts it as a
* <Danger> callout between the heading and the signature blockquote
*/
function processDeprecatedMethods(content) {
const lines = content.split("\n");
let modified = false;
let inFence = false;

// First pass: find all deprecated sections and collect their info
const deprecatedSections = [];
for (let i = 0; i < lines.length; i++) {
const trimmed = lines[i].trim();
if (trimmed.startsWith("```")) {
inFence = !inFence;
continue;
}
if (inFence) continue;

if (trimmed === "#### Deprecated") {
const start = i;
let end = i + 1;
let message = "";
// The first non-empty line after "#### Deprecated" is the deprecation message.
// Any subsequent lines are description text that TypeDoc misplaced here.
while (end < lines.length) {
const t = lines[end].trim();
if (t.startsWith("#### ") || t.startsWith("### ") || t.startsWith("## ") || t === "***") break;
if (!message && t) {
message = t;
}
end++;
}
deprecatedSections.push({ start, end, message });
}
}

if (deprecatedSections.length === 0) {
return { content, modified: false };
}

// Remove deprecated sections bottom-up so indices stay valid
for (let s = deprecatedSections.length - 1; s >= 0; s--) {
const { start, end } = deprecatedSections[s];
lines.splice(start, end - start);
modified = true;
}

// Second pass: transform headings and insert Danger callouts
inFence = false;
for (let i = 0; i < lines.length; i++) {
const trimmed = lines[i].trim();
if (trimmed.startsWith("```")) {
inFence = !inFence;
continue;
}
if (inFence) continue;

// Match deprecated heading: ### ~~methodName()~~ (TypeDoc wraps deprecated names in ~~)
const headingMatch = trimmed.match(/^###\s+~~(.+?)~~\s*$/);
if (!headingMatch) continue;

// Remove strikethrough and prepend warning emoji
lines[i] = lines[i].replace(
/^(###\s+)~~(.+?)~~\s*$/,
"$1\u26A0\uFE0F $2"
);
modified = true;

// Find the matching deprecated message by method name
const methodName = headingMatch[1].replace(/\(\)$/, "");
const section = deprecatedSections.find((sec) =>
sec.message.toLowerCase().includes(methodName.toLowerCase()) ||
deprecatedSections.length === 1
) || deprecatedSections.shift();

if (!section || !section.message) continue;

// Insert Danger callout right after the heading (before the signature)
const dangerBlock = [
"",
"<Danger>",
`**Deprecated:** ${section.message}`,
"</Danger>",
"",
];
lines.splice(i + 1, 0, ...dangerBlock);
}

return { content: lines.join("\n"), modified };
}

function applyDeprecatedMethodProcessing(dir) {
if (!fs.existsSync(dir)) return;
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const entryPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
applyDeprecatedMethodProcessing(entryPath);
} else if (
entry.isFile() &&
(entry.name.endsWith(".mdx") || entry.name.endsWith(".md"))
) {
const content = fs.readFileSync(entryPath, "utf-8");
const { content: updated, modified } = processDeprecatedMethods(content);
if (modified) {
fs.writeFileSync(entryPath, updated, "utf-8");
console.log(
`Processed deprecated methods: ${path.relative(DOCS_DIR, entryPath)}`
);
}
}
}
}

function demoteNonCallableHeadings(content) {
const lines = content.split("\n");
let inFence = false;
Expand Down Expand Up @@ -1286,6 +1403,11 @@ function groupTypeDefinitions(content) {

// Define type definition patterns for different modules
const typeGroups = [
// Connectors module
{
types: ["ConnectorIntegrationType", "ConnectorIntegrationTypeRegistry"],
indicator: "ConnectorIntegrationType"
},
// Entities module
{
types: ["EntityRecord", "EntityTypeRegistry", "SortField"],
Expand Down Expand Up @@ -1914,6 +2036,9 @@ function main() {
// Clean up signatures: fix truncated generics, simplify keyof constraints, break long lines
applySignatureCleanup(DOCS_DIR);

// Transform deprecated methods: add badge to heading, move deprecation notice to Warning callout
applyDeprecatedMethodProcessing(DOCS_DIR);

applyHeadingDemotion(DOCS_DIR);

// Group intro sections (Built-in User Entity, Generated Types, etc.) under Overview
Expand Down
2 changes: 2 additions & 0 deletions scripts/mintlify-post-processing/types-to-expose.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"AnalyticsModule",
"AppLogsModule",
"AuthModule",
"ConnectorIntegrationType",
"ConnectorIntegrationTypeRegistry",
"ConnectorsModule",
"CustomIntegrationsModule",
"DeleteManyResult",
Expand Down
11 changes: 6 additions & 5 deletions src/modules/auth.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,11 @@ export interface AuthModule {
* Initiates an OAuth login flow with one of the built-in providers. Requires a browser environment and can't be used in the backend.
*
* Supported providers:
* - `'google'` - {@link https://developers.google.com/identity/protocols/oauth2 | Google OAuth}. Enabled by default.
* - `'microsoft'` - {@link https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow | Microsoft OAuth}. Enable Microsoft in your app's authentication settings before specifying this provider.
* - `'facebook'` - {@link https://developers.facebook.com/docs/facebook-login | Facebook Login}. Enable Facebook in your app's authentication settings before using.
* - `'apple'` - {@link https://developer.apple.com/sign-in-with-apple/ | Sign in with Apple}. Enable Apple in your app's authentication settings before using this provider.
* - `'sso'` - Enterprise SSO. Enable SSO in your app's authentication settings before using this provider.
* - `'google'`: {@link https://developers.google.com/identity/protocols/oauth2 | Google OAuth}. Enabled by default.
* - `'microsoft'`: {@link https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow | Microsoft OAuth}. Enable Microsoft in your app's authentication settings before specifying this provider.
* - `'facebook'`: {@link https://developers.facebook.com/docs/facebook-login | Facebook Login}. Enable Facebook in your app's authentication settings before using.
* - `'apple'`: {@link https://developer.apple.com/sign-in-with-apple/ | Sign in with Apple}. Enable Apple in your app's authentication settings before using this provider.
* - `'sso'`: Enterprise SSO. {@link https://docs.base44.com/Setting-up-your-app/Setting-up-SSO | Set up an SSO provider} in your app's authentication settings before using this provider.
*
* @param provider - The authentication provider to use: `'google'`, `'microsoft'`, `'facebook'`, `'apple'`, or `'sso'`.
* @param fromUrl - URL to redirect to after successful authentication. Defaults to `'/'`.
Expand Down Expand Up @@ -227,6 +227,7 @@ export interface AuthModule {
* // SSO
* base44.auth.loginWithProvider('sso', '/dashboard');
* ```
*
*/
loginWithProvider(provider: string, fromUrl?: string): void;

Expand Down
Loading
Loading