Skip to content

Commit d9e5b2a

Browse files
wixysamcursoragent
andauthored
Improve SortField type documentation and linking (#129)
* Add Apple as supported authentication provider in SDK documentation - Add Apple to loginWithProvider JSDoc with Sign in with Apple link - Include Apple in supported providers list - Add example showing Apple login usage Co-authored-by: Cursor <cursoragent@cursor.com> * Set SDK reference docs groups to expanded by default - Update file-processing.js to add expanded: true to generated groups - Update copy-to-local-docs.js to preserve expanded: true in nested groups - Ensures Client and Modules groups are open by default in docs Co-authored-by: Cursor <cursoragent@cursor.com> * Shorten example descriptions for loginWithProvider Changed from verbose descriptions to simple provider names (Google, Microsoft, Apple) Co-authored-by: Cursor <cursoragent@cursor.com> * Improve SortField type documentation and linking - Export SortField type from SDK index - Configure SortField to be embedded in entities page (not standalone) - Add post-processing to integrate clickable type links naturally into ParamField descriptions - Clean up SortField signature display for better readability - Update JSDoc for SortField with clearer bullet points and improved example - Fix ServerEntityFields JSDoc to accurately list fields - Remove standalone "See" links in favor of integrated description links Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 844f7e6 commit d9e5b2a

7 files changed

Lines changed: 132 additions & 14 deletions

File tree

scripts/mintlify-post-processing/appended-articles.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"type-aliases/EntitiesModule": [
33
"interfaces/EntityHandler",
44
"type-aliases/EntityRecord",
5-
"interfaces/EntityTypeRegistry"
5+
"interfaces/EntityTypeRegistry",
6+
"type-aliases/SortField"
67
],
78
"interfaces/FunctionsModule": [
89
"type-aliases/FunctionName",

scripts/mintlify-post-processing/file-processing/file-processing.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,79 @@ function applyNonExposedTypeLinkRemoval(dir, exposedTypeNames) {
12201220
}
12211221
}
12221222

1223+
/**
1224+
* Add clickable links for types in ParamFields that reference types on the same page
1225+
*/
1226+
function addTypeLinksToParamFields(dir) {
1227+
if (!fs.existsSync(dir)) return;
1228+
const entries = fs.readdirSync(dir, { withFileTypes: true });
1229+
for (const entry of entries) {
1230+
const entryPath = path.join(dir, entry.name);
1231+
if (entry.isDirectory()) {
1232+
addTypeLinksToParamFields(entryPath);
1233+
} else if (
1234+
entry.isFile() &&
1235+
(entry.name.endsWith(".mdx") || entry.name.endsWith(".md"))
1236+
) {
1237+
let content = fs.readFileSync(entryPath, "utf-8");
1238+
let modified = false;
1239+
1240+
// Integrate clickable link into the description for SortField type
1241+
// Pattern: <ParamField ... type="SortField<T>">\n\nSort parameter, ...
1242+
// Replace with: <ParamField ... type="SortField<T>">\n\nA [`SortField<T>`](#sortfield) specifying sort order, ...
1243+
const paramFieldPattern = /(<ParamField [^>]*type=")(SortField<([^>]*)>)("[^>]*>\n\n)Sort parameter,/g;
1244+
1245+
content = content.replace(paramFieldPattern, (match, prefix, fullType, generic, suffix) => {
1246+
modified = true;
1247+
return `${prefix}${fullType}${suffix}A [\`${fullType}\`](#sortfield) specifying sort order,`;
1248+
});
1249+
1250+
if (modified) {
1251+
fs.writeFileSync(entryPath, content, "utf-8");
1252+
console.log(`Added type links to ParamFields: ${path.relative(DOCS_DIR, entryPath)}`);
1253+
}
1254+
}
1255+
}
1256+
}
1257+
1258+
/**
1259+
* Clean up SortField type signature to be more readable
1260+
*/
1261+
function cleanupSortFieldSignature(dir) {
1262+
if (!fs.existsSync(dir)) return;
1263+
const entries = fs.readdirSync(dir, { withFileTypes: true });
1264+
for (const entry of entries) {
1265+
const entryPath = path.join(dir, entry.name);
1266+
if (entry.isDirectory()) {
1267+
cleanupSortFieldSignature(entryPath);
1268+
} else if (
1269+
entry.isFile() &&
1270+
(entry.name.endsWith(".mdx") || entry.name.endsWith(".md"))
1271+
) {
1272+
let content = fs.readFileSync(entryPath, "utf-8");
1273+
let modified = false;
1274+
1275+
// Replace the complex SortField signature with a cleaner version
1276+
// Match: > **SortField**\<`T`\> = ... & ... | `` `+${(...) & (...)}` `` | `` `-${(...) & (...)}` ``
1277+
// Replace with: > **SortField**\<`T`\> = `string` | `` `+${string}` `` | `` `-${string}` ``
1278+
const sortFieldSignaturePattern = /> \*\*SortField\*\*\\<`T`\\> = \.\.\. & \.\.\. \| `` `\+\$\{\(\.\.\.\) & \(\.\.\.\)\}` `` \| `` `-\$\{\(\.\.\.\) & \(\.\.\.\)\}` ``/;
1279+
1280+
if (sortFieldSignaturePattern.test(content)) {
1281+
content = content.replace(
1282+
sortFieldSignaturePattern,
1283+
"> **SortField**\\<`T`\\> = `keyof T` | `` `+${keyof T}` `` | `` `-${keyof T}` ``"
1284+
);
1285+
modified = true;
1286+
}
1287+
1288+
if (modified) {
1289+
fs.writeFileSync(entryPath, content, "utf-8");
1290+
console.log(`Cleaned SortField signature: ${path.relative(DOCS_DIR, entryPath)}`);
1291+
}
1292+
}
1293+
}
1294+
}
1295+
12231296
/**
12241297
* Main function
12251298
*/
@@ -1288,6 +1361,12 @@ function main() {
12881361
const appendedArticles = loadAppendedArticlesConfig();
12891362
applyAppendedArticles(appendedArticles);
12901363

1364+
// Add clickable links for types in ParamFields
1365+
addTypeLinksToParamFields(DOCS_DIR);
1366+
1367+
// Clean up SortField signature specifically (before general signature cleanup)
1368+
cleanupSortFieldSignature(DOCS_DIR);
1369+
12911370
// Clean up signatures: fix truncated generics, simplify keyof constraints, break long lines
12921371
applySignatureCleanup(DOCS_DIR);
12931372

scripts/mintlify-post-processing/typedoc-plugin/typedoc-mintlify-parameters.js

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,23 @@ function parseParametersWithExpansion(
289289
if (!line) return null;
290290
const trimmed = line.trim();
291291

292-
// Handle [`TypeName`](link) format first (backticks inside the link)
292+
// Handle [`TypeName`](link)\<`T`\> format (with generics after the link)
293+
const linkWithBackticksAndGenericsMatch = trimmed.match(/^\[`([^`]+)`\]\(([^)]+)\)(.*)$/);
294+
if (linkWithBackticksAndGenericsMatch) {
295+
const typeName = linkWithBackticksAndGenericsMatch[1];
296+
const link = linkWithBackticksAndGenericsMatch[2];
297+
const generics = linkWithBackticksAndGenericsMatch[3].trim();
298+
299+
// If there are generics, append them to the type name (cleaning up markdown escapes)
300+
const fullType = generics ? typeName + generics.replace(/\\/g, '') : typeName;
301+
302+
return {
303+
type: fullType,
304+
link: link,
305+
};
306+
}
307+
308+
// Handle [`TypeName`](link) format (backticks inside the link, no generics)
293309
const linkWithBackticksMatch = trimmed.match(/^\[`([^`]+)`\]\(([^)]+)\)$/);
294310
if (linkWithBackticksMatch) {
295311
return {
@@ -518,6 +534,7 @@ function parseParametersWithExpansion(
518534
params.push({
519535
name: cleanName,
520536
type: type,
537+
typeLink: typeLink, // Preserve the link
521538
description: descriptionLines.join("\n").trim(),
522539
optional,
523540
nested,
@@ -571,7 +588,23 @@ function parseParameters(
571588
if (!line) return null;
572589
const trimmed = line.trim();
573590

574-
// Handle [`TypeName`](link) format first (backticks inside the link)
591+
// Handle [`TypeName`](link)\<`T`\> format (with generics after the link)
592+
const linkWithBackticksAndGenericsMatch = trimmed.match(/^\[`([^`]+)`\]\(([^)]+)\)(.*)$/);
593+
if (linkWithBackticksAndGenericsMatch) {
594+
const typeName = linkWithBackticksAndGenericsMatch[1];
595+
const link = linkWithBackticksAndGenericsMatch[2];
596+
const generics = linkWithBackticksAndGenericsMatch[3].trim();
597+
598+
// If there are generics, append them to the type name (cleaning up markdown escapes)
599+
const fullType = generics ? typeName + generics.replace(/\\/g, '') : typeName;
600+
601+
return {
602+
type: fullType,
603+
link: link,
604+
};
605+
}
606+
607+
// Handle [`TypeName`](link) format (backticks inside the link, no generics)
575608
const linkWithBackticksMatch = trimmed.match(/^\[`([^`]+)`\]\(([^)]+)\)$/);
576609
if (linkWithBackticksMatch) {
577610
return {
@@ -826,16 +859,16 @@ function buildParamFieldsSection(
826859
for (const param of params) {
827860
const requiredAttr = param.optional ? "" : " required";
828861

829-
// Track non-primitive parameter types for suppression
830-
831-
fieldsOutput += `<ParamField body="${param.name}" type="${param.type}"${requiredAttr}>\n`;
862+
// Clean up the type string by removing markdown backticks
863+
let typeAttr = param.type.replace(/`/g, '');
864+
fieldsOutput += `<ParamField body="${param.name}" type="${typeAttr}"${requiredAttr}>\n`;
832865

833866
// Always show description in ParamField if it exists
834867
if (param.description) {
835-
fieldsOutput += `\n${param.description}\n`;
868+
fieldsOutput += `\n${param.description}`;
836869
}
837870

838-
fieldsOutput += "\n</ParamField>\n";
871+
fieldsOutput += "\n\n</ParamField>\n";
839872

840873
// If param has nested fields, wrap them in an Accordion
841874
if (param.nested.length > 0) {
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[
22
"DeleteManyResult",
33
"DeleteResult",
4-
"ImportResult"
4+
"ImportResult",
5+
"SortField"
56
]

scripts/mintlify-post-processing/types-to-expose.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919
"ImportResult",
2020
"IntegrationsModule",
2121
"CoreIntegrations",
22+
"SortField",
2223
"SsoModule"
2324
]

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export type {
4444
RealtimeEventType,
4545
RealtimeEvent,
4646
RealtimeCallback,
47+
SortField,
4748
} from "./modules/entities.types.js";
4849

4950
export type {

src/modules/entities.types.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,16 @@ export interface ImportResult<T = any> {
6161
/**
6262
* Sort field type for entity queries.
6363
*
64-
* Supports ascending (no prefix or `'+'`) and descending (`'-'`) sorting.
64+
* Accepts any field name from the entity type with an optional prefix:
65+
* - `'+'` prefix or no prefix: ascending sort
66+
* - `'-'` prefix: descending sort
6567
*
6668
* @typeParam T - The entity type to derive sortable fields from.
6769
*
6870
* @example
6971
* ```typescript
70-
* // Ascending sort (default)
72+
* // Specify sort direction by prefixing field names with + or -
73+
* // Ascending sort
7174
* 'created_date'
7275
* '+created_date'
7376
*
@@ -81,7 +84,7 @@ export type SortField<T> =
8184
| `-${keyof T & string}`;
8285

8386
/**
84-
* Fields added by the server to every entity record (id, dates, created_by, etc.).
87+
* Fields added by the server to every entity record, such as `id`, `created_date`, `updated_date`, and `created_by`.
8588
*/
8689
interface ServerEntityFields {
8790
/** Unique identifier of the record */
@@ -108,8 +111,7 @@ export interface EntityTypeRegistry {}
108111
*
109112
* @example
110113
* ```typescript
111-
* import type { EntityRecord } from '@base44/sdk';
112-
*
114+
* // Using EntityRecord to get the complete type for an entity
113115
* // Combine your schema with server fields (id, created_date, etc.)
114116
* type TaskRecord = EntityRecord['Task'];
115117
*

0 commit comments

Comments
 (0)