From 8a15a74665303f79f60fe5aacb4d5b2e02d6234e Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 16:42:14 +0000 Subject: [PATCH 1/2] Update base44-sdk skill to v0.8.22 Co-Authored-By: Claude Sonnet 4.6 --- skills/base44-sdk/SKILL.md | 12 +- .../base44-sdk/references/QUICK_REFERENCE.md | 43 +++- skills/base44-sdk/references/app-logs.md | 42 ++++ skills/base44-sdk/references/client.md | 10 +- skills/base44-sdk/references/connectors.md | 217 ++++++++++++++---- skills/base44-sdk/references/entities.md | 48 ++++ skills/base44-sdk/references/functions.md | 63 ++++- skills/base44-sdk/references/sso.md | 75 ++++++ 8 files changed, 448 insertions(+), 62 deletions(-) create mode 100644 skills/base44-sdk/references/sso.md diff --git a/skills/base44-sdk/SKILL.md b/skills/base44-sdk/SKILL.md index f71fe39..a85c1fc 100644 --- a/skills/base44-sdk/SKILL.md +++ b/skills/base44-sdk/SKILL.md @@ -133,10 +133,12 @@ Base44 SDK has unique method names. Do NOT assume patterns from Firebase, Supaba | `agents` | AI conversations and messages | [base44-agents.md](references/base44-agents.md) | | `functions` | Backend function invocation | [functions.md](references/functions.md) | | `integrations` | AI, email, file uploads, custom APIs | [integrations.md](references/integrations.md) | -| `connectors` | OAuth tokens (service role only) | [connectors.md](references/connectors.md) | +| `connectors` | Per-user OAuth flows (frontend & backend) | [connectors.md](references/connectors.md) | | `analytics` | Track custom events and user activity | [analytics.md](references/analytics.md) | | `appLogs` | Log user activity in app | [app-logs.md](references/app-logs.md) | | `users` | Invite users to the app | [users.md](references/users.md) | +| `asServiceRole.connectors` | App-scoped OAuth tokens (service role only) | [connectors.md](references/connectors.md) | +| `asServiceRole.sso` | SSO token generation (service role only) | [sso.md](references/sso.md) | For client setup and authentication modes, see [client.md](references/client.md). @@ -220,7 +222,8 @@ const base44 = createClient({ - Send emails → `integrations.Core.SendEmail()` - Upload files → `integrations.Core.UploadFile()` - Custom APIs → `integrations.custom.call()` -- OAuth tokens (Google, Slack) → `connectors` (backend only) +- Per-user OAuth (user connects their own account) → `connectors.connectAppUser()` / `connectors.getCurrentAppUserAccessToken()` +- App-scoped OAuth (app builder's account) → `asServiceRole.connectors.getConnection()` (backend only) **Tracking and analytics?** - Track custom events → `analytics.track()` @@ -292,11 +295,14 @@ const token = await base44.asServiceRole.connectors.getAccessToken("slack"); | `auth` | Yes | Yes | | `agents` | Yes | Yes | | `functions.invoke()` | Yes | Yes | +| `functions.fetch()` | Yes | Yes | | `integrations` | Yes | Yes | | `analytics` | Yes | Yes | | `appLogs` | Yes | Yes | | `users` | Yes | Yes | +| `connectors` (user OAuth flows) | Yes | Yes | | `asServiceRole.*` | No | Yes | -| `connectors` | No | Yes | +| `asServiceRole.connectors` (app OAuth) | No | Yes | +| `asServiceRole.sso` | No | Yes | Backend functions use `Deno.serve()` and `createClientFromRequest(req)` to get a properly authenticated client. diff --git a/skills/base44-sdk/references/QUICK_REFERENCE.md b/skills/base44-sdk/references/QUICK_REFERENCE.md index a9991e5..1c21b99 100644 --- a/skills/base44-sdk/references/QUICK_REFERENCE.md +++ b/skills/base44-sdk/references/QUICK_REFERENCE.md @@ -35,10 +35,12 @@ list(sort?, limit?, skip?, fields?) → Promise[]> filter(query, sort?, limit?, skip?, fields?) → Promise[]> get(id) → Promise update(id, data) → Promise +updateMany(query, mongoUpdateOp) → Promise // e.g. { $set: { field: val } } +bulkUpdate(dataArray) → Promise // each item must have id delete(id) → Promise deleteMany(query) → Promise -importEntities(file) → Promise> // frontend only -subscribe(callback) → () => void // returns unsubscribe fn +importEntities(file) → Promise> // frontend only +subscribe(callback) → () => void // returns unsubscribe fn ``` **Sort:** Use `SortField`: `-fieldName` for descending (e.g., `-created_date`). Max 5,000 per request for list/filter. @@ -49,6 +51,7 @@ subscribe(callback) → () => void // returns unsubscribe fn ``` invoke(functionName, data?) → Promise +fetch(path, init?) → Promise // low-level, for streaming/custom methods ``` **Backend:** Use `base44.asServiceRole.functions.invoke()` for admin access. @@ -89,6 +92,8 @@ track({eventName, properties?}) → void ``` logUserInApp(pageName) → Promise +fetchLogs(params?) → Promise +getStats(params?) → Promise ``` --- @@ -101,18 +106,43 @@ inviteUser(userEmail, role) → Promise // role: 'user' | 'admin' --- -## Connectors (`base44.asServiceRole.connectors.*`) +## User Connectors (`base44.connectors.*`) -**Backend only, service role required.** +Per-user OAuth flows. Frontend and backend. + +``` +getCurrentAppUserAccessToken(connectorId) → Promise +connectAppUser(connectorId) → Promise // returns redirect URL +disconnectAppUser(connectorId) → Promise +``` + +> `connectorId` is the OrgConnector database ID (not the integration type string). + +--- + +## Service Role Connectors (`base44.asServiceRole.connectors.*`) + +**Backend only, service role required.** App-scoped (shared account). ``` -getAccessToken(integrationType) → Promise +getConnection(integrationType) → Promise<{accessToken, connectionConfig}> // recommended +getAccessToken(integrationType) → Promise // deprecated ``` **Types:** Run `npx base44 connectors list-available` to see all available integration types. --- +## SSO (`base44.asServiceRole.sso.*`) + +**Backend only, service role required.** + +``` +getAccessToken(userId) → Promise<{access_token}> +``` + +--- + ## Service Role Access **Backend functions only.** Prefix any module with `asServiceRole` for admin access: @@ -120,7 +150,8 @@ getAccessToken(integrationType) → Promise ```javascript base44.asServiceRole.entities.Task.list() base44.asServiceRole.functions.invoke('name', data) -base44.asServiceRole.connectors.getAccessToken('slack') +base44.asServiceRole.connectors.getConnection('slack') +base44.asServiceRole.sso.getAccessToken(userId) ``` --- diff --git a/skills/base44-sdk/references/app-logs.md b/skills/base44-sdk/references/app-logs.md index 0439805..9865bb0 100644 --- a/skills/base44-sdk/references/app-logs.md +++ b/skills/base44-sdk/references/app-logs.md @@ -12,6 +12,8 @@ Log user activity in your app via `base44.appLogs`. | Method | Signature | Description | |--------|-----------|-------------| | `logUserInApp(pageName)` | `Promise` | Log user activity on a page | +| `fetchLogs(params?)` | `Promise` | Fetch app logs with optional filter parameters | +| `getStats(params?)` | `Promise` | Get app usage statistics | ## Examples @@ -57,6 +59,32 @@ function handleSettingsChange() { } ``` +### Fetch Logs + +```javascript +// Fetch all logs +const logs = await base44.appLogs.fetchLogs(); + +// Fetch logs with filters +const recentLogs = await base44.appLogs.fetchLogs({ + limit: 50, + page: "/dashboard" +}); +``` + +### Get Stats + +```javascript +// Get usage statistics for the app +const stats = await base44.appLogs.getStats(); + +// Get stats with date range params +const weekStats = await base44.appLogs.getStats({ + from: "2024-01-01", + to: "2024-01-07" +}); +``` + ## Notes - Logs appear in the Analytics page of your app dashboard @@ -74,5 +102,19 @@ interface AppLogsModule { * @returns Promise that resolves when the log is recorded. */ logUserInApp(pageName: string): Promise; + + /** + * Fetch app logs with optional filter parameters. + * @param params - Optional filter parameters (e.g., limit, page name, date range). + * @returns Promise resolving to the logs data. + */ + fetchLogs(params?: Record): Promise; + + /** + * Get app usage statistics. + * @param params - Optional filter parameters (e.g., date range). + * @returns Promise resolving to the statistics data. + */ + getStats(params?: Record): Promise; } ``` diff --git a/skills/base44-sdk/references/client.md b/skills/base44-sdk/references/client.md index cea56a4..27cd623 100644 --- a/skills/base44-sdk/references/client.md +++ b/skills/base44-sdk/references/client.md @@ -131,6 +131,7 @@ base44.agents // AI conversations base44.analytics // Event tracking base44.appLogs // App usage logging base44.auth // Authentication +base44.connectors // Per-user OAuth flows (UserConnectorsModule) base44.entities // CRUD operations base44.functions // Backend function invocation base44.integrations // Third-party services @@ -139,10 +140,11 @@ base44.users // User invitations // Service role only (backend) base44.asServiceRole.agents base44.asServiceRole.appLogs -base44.asServiceRole.connectors +base44.asServiceRole.connectors // App-scoped OAuth tokens (ConnectorsModule) base44.asServiceRole.entities base44.asServiceRole.functions base44.asServiceRole.integrations +base44.asServiceRole.sso // SSO token generation ``` ## Client Methods @@ -243,14 +245,20 @@ interface Base44Client { /** Sets a new authentication token for all subsequent requests. */ setToken(newToken: string): void; + /** Per-user OAuth flows. Each end user has their own connection. */ + connectors: UserConnectorsModule; + /** Provides access to modules with elevated service role permissions (backend only). */ readonly asServiceRole: { agents: AgentsModule; appLogs: AppLogsModule; + /** App-scoped OAuth tokens. All users share the same connected account. */ connectors: ConnectorsModule; entities: EntitiesModule; functions: FunctionsModule; integrations: IntegrationsModule; + /** SSO token generation for users. */ + sso: SsoModule; cleanup(): void; }; } diff --git a/skills/base44-sdk/references/connectors.md b/skills/base44-sdk/references/connectors.md index 4239e4c..4721c5d 100644 --- a/skills/base44-sdk/references/connectors.md +++ b/skills/base44-sdk/references/connectors.md @@ -1,103 +1,218 @@ # Connectors Module -OAuth token management for external services. **Service role only** (backend functions). +OAuth token management for external services. The SDK exposes **two** connectors modules: -## Method +- **`base44.connectors`** — User-scoped OAuth flows (frontend & backend). Manages per-user connections. +- **`base44.asServiceRole.connectors`** — App-scoped OAuth tokens (backend/service role only). All users share the same connected account. + +## Contents +- [User Connectors (`base44.connectors`)](#user-connectors-base44connectors) +- [Service Role Connectors (`base44.asServiceRole.connectors`)](#service-role-connectors-base44asserviceroleconnectors) +- [Available Services](#available-services) +- [Type Definitions](#type-definitions) + +--- + +## User Connectors (`base44.connectors`) + +Per-user OAuth flows. Each end user has their own connection. Available in frontend and backend. + +### Methods + +| Method | Signature | Description | +|--------|-----------|-------------| +| `getCurrentAppUserAccessToken(connectorId)` | `Promise` | Get OAuth access token for the current user's connection | +| `connectAppUser(connectorId)` | `Promise` | Initiate OAuth flow — returns redirect URL | +| `disconnectAppUser(connectorId)` | `Promise` | Remove current user's OAuth connection | + +> **Note:** `connectorId` is the OrgConnector database ID (set in the Base44 dashboard), not the integration type string. + +### Examples + +```javascript +// Check if the current user has connected — get their token +const token = await base44.connectors.getCurrentAppUserAccessToken("abc123def"); + +const response = await fetch("https://www.googleapis.com/calendar/v3/calendars/primary/events", { + headers: { "Authorization": `Bearer ${token}` } +}); +``` + +```javascript +// Initiate OAuth flow — redirect the user to authorize +const redirectUrl = await base44.connectors.connectAppUser("abc123def"); +window.location.href = redirectUrl; +``` ```javascript -base44.asServiceRole.connectors.getAccessToken(integrationType): Promise +// Disconnect the current user's OAuth connection +await base44.connectors.disconnectAppUser("abc123def"); ``` -Returns a raw OAuth access token for the specified service. +--- + +## Service Role Connectors (`base44.asServiceRole.connectors`) -## Supported Services +App-scoped OAuth tokens. The app builder connects the account once; all users share it. **Backend/service role only.** -Run `npx base44 connectors list-available` from the CLI to see all available integration types and their details. +### Methods -## Example Usage +| Method | Signature | Description | +|--------|-----------|-------------| +| `getConnection(integrationType)` | `Promise` | Get access token and optional connection config | +| `getAccessToken(integrationType)` | `Promise` | ⚠️ **Deprecated** — use `getConnection()` instead | + +### Examples ```javascript // Backend function only Deno.serve(async (req) => { const base44 = createClientFromRequest(req); - - // Get OAuth token for Slack - const slackToken = await base44.asServiceRole.connectors.getAccessToken("slack"); - - // Use token directly with Slack API + + // Recommended: use getConnection() for token + optional config + const { accessToken, connectionConfig } = await base44.asServiceRole.connectors.getConnection("slack"); + const response = await fetch("https://slack.com/api/chat.postMessage", { method: "POST", headers: { - "Authorization": `Bearer ${slackToken}`, + "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json" }, - body: JSON.stringify({ - channel: "#general", - text: "Hello from Base44!" - }) + body: JSON.stringify({ channel: "#general", text: "Hello from Base44!" }) }); - + return Response.json(await response.json()); }); ``` -## Google Calendar Example - ```javascript -Deno.serve(async (req) => { - const base44 = createClientFromRequest(req); - - const token = await base44.asServiceRole.connectors.getAccessToken("googlecalendar"); - - // List upcoming events - const response = await fetch( - "https://www.googleapis.com/calendar/v3/calendars/primary/events?" + - new URLSearchParams({ - maxResults: "10", - orderBy: "startTime", - singleEvents: "true", - timeMin: new Date().toISOString() - }), - { - headers: { "Authorization": `Bearer ${token}` } - } - ); - - const events = await response.json(); - return Response.json(events); +// Using connectionConfig (for services that need extra params, e.g. a subdomain) +const { accessToken, connectionConfig } = await base44.asServiceRole.connectors.getConnection("myservice"); +const subdomain = connectionConfig?.subdomain; +const response = await fetch(`https://${subdomain}.example.com/api/v1/data`, { + headers: { "Authorization": `Bearer ${accessToken}` } }); ``` +```javascript +// Google Calendar example +const { accessToken } = await base44.asServiceRole.connectors.getConnection("googlecalendar"); + +const events = await fetch( + "https://www.googleapis.com/calendar/v3/calendars/primary/events?" + + new URLSearchParams({ maxResults: "10", orderBy: "startTime", singleEvents: "true", timeMin: new Date().toISOString() }), + { headers: { "Authorization": `Bearer ${accessToken}` } } +).then(r => r.json()); +``` + +--- + +## Available Services + +| Service | Type identifier | +|---------|----------------| +| Airtable | `airtable` | +| Box | `box` | +| ClickUp | `clickup` | +| Discord | `discord` | +| Dropbox | `dropbox` | +| GitHub | `github` | +| Gmail | `gmail` | +| Google Analytics | `google_analytics` | +| Google BigQuery | `googlebigquery` | +| Google Calendar | `googlecalendar` | +| Google Classroom | `google_classroom` | +| Google Docs | `googledocs` | +| Google Drive | `googledrive` | +| Google Search Console | `google_search_console` | +| Google Sheets | `googlesheets` | +| Google Slides | `googleslides` | +| HubSpot | `hubspot` | +| Linear | `linear` | +| LinkedIn | `linkedin` | +| Microsoft Teams | `microsoft_teams` | +| Microsoft OneDrive | `one_drive` | +| Notion | `notion` | +| Outlook | `outlook` | +| Salesforce | `salesforce` | +| SharePoint | `share_point` | +| Slack User | `slack` | +| Slack Bot | `slackbot` | +| Splitwise | `splitwise` | +| TikTok | `tiktok` | +| Typeform | `typeform` | +| Wix | `wix` | +| Wrike | `wrike` | + +Run `npx base44 connectors list-available` from the CLI to see all available types. + +--- + ## Setup Requirements 1. **Builder plan** or higher -2. **Backend functions** enabled +2. **Backend functions** enabled (for service role connectors) 3. **Connector configured** in Base44 dashboard (OAuth flow completed) ## Important Notes -- **One account per connector per app**: All users share the same connected account -- **Backend only**: `connectors` module not available in frontend code -- **Service role required**: Must use `base44.asServiceRole.connectors` -- **You handle the API calls**: Base44 only provides the token; you make the actual API requests +- **Service role connectors**: One account per connector per app — all users share the same connected account +- **User connectors**: Each end user connects their own account +- **You handle the API calls**: Base44 provides the token; you make the actual API requests - **Token refresh**: Base44 handles token refresh automatically +--- + ## Type Definitions ```typescript /** - * The type of external integration/connector. + * The type of external integration/connector (for service role connectors). * Examples: 'googlecalendar', 'slack', 'github', 'notion', etc. */ type ConnectorIntegrationType = string; -/** Connectors module for managing OAuth tokens for external services. */ +/** Connection details returned by getConnection(). */ +interface ConnectorConnectionResponse { + /** The OAuth access token for the external service. */ + accessToken: string; + /** Key-value configuration for the connection, or null if not needed. */ + connectionConfig: Record | null; +} + +/** Service role connectors module (app-scoped OAuth). Backend only. */ interface ConnectorsModule { /** - * Retrieves an OAuth access token for a specific external integration type. - * @param integrationType - The type of integration (e.g., 'googlecalendar', 'slack'). - * @returns Promise resolving to the access token string. + * Retrieves the OAuth access token and optional connection config. + * @param integrationType - e.g., 'googlecalendar', 'slack', 'github'. + */ + getConnection(integrationType: ConnectorIntegrationType): Promise; + + /** + * @deprecated Use getConnection() instead. + * Retrieves only the OAuth access token string. */ getAccessToken(integrationType: ConnectorIntegrationType): Promise; } + +/** User connectors module (per-user OAuth). Frontend and backend. */ +interface UserConnectorsModule { + /** + * Retrieves the OAuth access token for the current user's connection. + * @param connectorId - The OrgConnector database ID. + */ + getCurrentAppUserAccessToken(connectorId: string): Promise; + + /** + * Initiates OAuth flow for the current user. Returns a redirect URL. + * @param connectorId - The OrgConnector database ID. + */ + connectAppUser(connectorId: string): Promise; + + /** + * Removes the current user's OAuth connection. + * @param connectorId - The OrgConnector database ID. + */ + disconnectAppUser(connectorId: string): Promise; +} ``` diff --git a/skills/base44-sdk/references/entities.md b/skills/base44-sdk/references/entities.md index 6d9dcad..8a2f51c 100644 --- a/skills/base44-sdk/references/entities.md +++ b/skills/base44-sdk/references/entities.md @@ -21,6 +21,8 @@ CRUD operations on data models. Access via `base44.entities.EntityName.method()` | `filter(query, sort?, limit?, skip?, fields?)` | `Promise[]>` | Get records matching conditions | | `get(id)` | `Promise` | Get single record by ID | | `update(id, data)` | `Promise` | Update record (partial update) | +| `updateMany(query, data)` | `Promise` | Update all matching records using MongoDB update operators | +| `bulkUpdate(dataArray)` | `Promise` | Update multiple records by ID, each with its own data | | `delete(id)` | `Promise` | Delete record by ID | | `deleteMany(query)` | `Promise` | Delete all matching records | | `importEntities(file)` | `Promise>` | Import from CSV (frontend only) | @@ -119,6 +121,34 @@ const manyResult = await base44.entities.Task.deleteMany({ status: "archived" }) console.log("Deleted:", manyResult.deleted); ``` +### Update Many (MongoDB-style) + +```javascript +// Update all pending tasks to status "in-progress" +const result = await base44.entities.Task.updateMany( + { status: "pending" }, // query: which records to update + { $set: { status: "in-progress" } } // MongoDB update operator +); +console.log("Updated:", result.updated); + +// Increment a counter field +await base44.entities.Task.updateMany( + { category: "bugs" }, + { $inc: { priority: 1 } } +); +``` + +### Bulk Update (by ID) + +```javascript +// Update multiple records, each with different data +const updated = await base44.entities.Task.bulkUpdate([ + { id: "task-1", status: "done", completedAt: new Date().toISOString() }, + { id: "task-2", status: "in-progress", assignedTo: userId }, + { id: "task-3", priority: 5 } +]); +``` + ### Import from File ```javascript @@ -221,6 +251,14 @@ type RealtimeCallback = (event: RealtimeEvent) => void; ### Result Types ```typescript +/** Result returned when updating multiple entities. */ +interface UpdateManyResult { + /** Whether the update was successful. */ + success: boolean; + /** Number of entities that were updated. */ + updated: number; +} + /** Result returned when deleting a single entity. */ interface DeleteResult { /** Whether the deletion was successful. */ @@ -327,6 +365,16 @@ interface EntityHandler { /** Creates multiple records in a single request. */ bulkCreate(data: Partial[]): Promise; + /** + * Updates multiple records matching a query using MongoDB update operators. + * @param query - Filter to select which records to update. + * @param data - MongoDB update operator object (e.g., `{ $set: { field: value } }`). + */ + updateMany(query: Partial, data: Record>): Promise; + + /** Updates multiple records by ID, each with its own update data. */ + bulkUpdate(data: (Partial & { id: string })[]): Promise; + /** Imports records from a file (frontend only). */ importEntities(file: File): Promise>; diff --git a/skills/base44-sdk/references/functions.md b/skills/base44-sdk/references/functions.md index 3e3e690..54ac09d 100644 --- a/skills/base44-sdk/references/functions.md +++ b/skills/base44-sdk/references/functions.md @@ -9,7 +9,9 @@ Invoke custom backend functions via `base44.functions`. - [Setup Requirements](#setup-requirements) - [Authentication Modes](#authentication-modes) -## Method +## Methods + +### `invoke` ```javascript base44.functions.invoke(functionName, data?): Promise @@ -19,6 +21,18 @@ base44.functions.invoke(functionName, data?): Promise - `data`: Optional object of parameters (sent as JSON, or multipart if contains File objects) - Returns: Whatever the function returns +### `fetch` + +```javascript +base44.functions.fetch(path, init?): Promise +``` + +Low-level method that performs a direct HTTP request to a backend function path and returns the native `Response` object. Use when you need streaming responses, custom HTTP methods, or raw response access. + +- `path`: Function path (e.g., `/streaming_demo` or `/my-function/endpoint`) +- `init`: Optional native fetch options (`RequestInit`) +- Returns: Native `Response` object + ## Invoking Functions ### From Frontend @@ -32,6 +46,36 @@ const result = await base44.functions.invoke("processOrder", { console.log(result); ``` +### Streaming Response (using fetch) + +```javascript +// Use fetch() for streaming responses (SSE, chunked text, etc.) +const response = await base44.functions.fetch("/stream-data", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ prompt: "Tell me a story" }) +}); + +// Read as a stream +const reader = response.body.getReader(); +const decoder = new TextDecoder(); +while (true) { + const { done, value } = await reader.read(); + if (done) break; + console.log(decoder.decode(value)); +} +``` + +### Custom HTTP Methods (using fetch) + +```javascript +// PUT, PATCH, DELETE, or other methods +const response = await base44.functions.fetch("/my-resource/123", { + method: "DELETE" +}); +console.log(response.status); // 204 +``` + ### With File Upload ```javascript @@ -213,6 +257,11 @@ interface FunctionNameRegistry {} */ type FunctionName = keyof FunctionNameRegistry extends never ? string : keyof FunctionNameRegistry; +/** + * Options for functions.fetch(). Uses native fetch options directly. + */ +type FunctionsFetchInit = RequestInit; + /** Functions module for invoking custom backend functions. */ interface FunctionsModule { /** @@ -226,5 +275,17 @@ interface FunctionsModule { * @returns Promise resolving to the function's response. */ invoke(functionName: FunctionName, data?: Record): Promise; + + /** + * Performs a direct HTTP request to a backend function path and returns the native Response. + * + * Use for streaming responses (SSE, chunked text), custom HTTP methods, + * or when you need raw access to the response. + * + * @param path - Function path, e.g. `/streaming_demo` or `/my-function/endpoint` + * @param init - Optional native fetch options. + * @returns Promise resolving to a native fetch Response. + */ + fetch(path: string, init?: FunctionsFetchInit): Promise; } ``` diff --git a/skills/base44-sdk/references/sso.md b/skills/base44-sdk/references/sso.md new file mode 100644 index 0000000..c7a5d70 --- /dev/null +++ b/skills/base44-sdk/references/sso.md @@ -0,0 +1,75 @@ +# SSO Module + +Single Sign-On (SSO) support for authenticating Base44 users with external systems. Available via `base44.asServiceRole.sso`. + +> **Backend only**: This module requires service role access and can only be used in Base44-hosted backend functions. + +## Methods + +| Method | Signature | Description | +|--------|-----------|-------------| +| `getAccessToken(userId)` | `Promise` | Get an SSO access token for a specific user | + +## Examples + +### Get SSO Access Token + +```javascript +import { createClientFromRequest } from "npm:@base44/sdk"; + +Deno.serve(async (req) => { + const base44 = createClientFromRequest(req); + + // Get the current user + const user = await base44.auth.me(); + if (!user) { + return Response.json({ error: "Unauthorized" }, { status: 401 }); + } + + // Get SSO access token for this user + const { access_token } = await base44.asServiceRole.sso.getAccessToken(user.id); + + // Use the token to authenticate with an external system + return Response.json({ ssoToken: access_token }); +}); +``` + +### Get Token for a Specific User (Service Role) + +```javascript +Deno.serve(async (req) => { + const base44 = createClientFromRequest(req); + const { userId } = await req.json(); + + // Get SSO token for any user (service role has access to all users) + const { access_token } = await base44.asServiceRole.sso.getAccessToken(userId); + + return Response.json({ token: access_token }); +}); +``` + +## Use Cases + +- Authenticating Base44 users with external SaaS tools (e.g., Okta, Azure AD) +- Building SSO bridges between Base44 and third-party systems +- Generating tokens for backend-to-backend authenticated calls + +## Type Definitions + +```typescript +/** Response from the SSO access token endpoint. */ +interface SsoAccessTokenResponse { + /** The SSO access token for the specified user. */ + access_token: string; +} + +/** SSO module for managing SSO authentication (service role only). */ +interface SsoModule { + /** + * Gets an SSO access token for a specific user. + * @param userid - The Base44 user ID to get the SSO token for. + * @returns Promise resolving to the SSO access token response. + */ + getAccessToken(userid: string): Promise; +} +``` From ebffb5e279daa65cf41df20f562c9ed68912cb01 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 19:15:51 +0000 Subject: [PATCH 2/2] Remove app user connectors documentation (not yet public) Co-authored-by: Netanel Gilad --- skills/base44-sdk/SKILL.md | 3 - .../base44-sdk/references/QUICK_REFERENCE.md | 14 ----- skills/base44-sdk/references/connectors.md | 63 +------------------ 3 files changed, 1 insertion(+), 79 deletions(-) diff --git a/skills/base44-sdk/SKILL.md b/skills/base44-sdk/SKILL.md index a85c1fc..c4cfbac 100644 --- a/skills/base44-sdk/SKILL.md +++ b/skills/base44-sdk/SKILL.md @@ -133,7 +133,6 @@ Base44 SDK has unique method names. Do NOT assume patterns from Firebase, Supaba | `agents` | AI conversations and messages | [base44-agents.md](references/base44-agents.md) | | `functions` | Backend function invocation | [functions.md](references/functions.md) | | `integrations` | AI, email, file uploads, custom APIs | [integrations.md](references/integrations.md) | -| `connectors` | Per-user OAuth flows (frontend & backend) | [connectors.md](references/connectors.md) | | `analytics` | Track custom events and user activity | [analytics.md](references/analytics.md) | | `appLogs` | Log user activity in app | [app-logs.md](references/app-logs.md) | | `users` | Invite users to the app | [users.md](references/users.md) | @@ -222,7 +221,6 @@ const base44 = createClient({ - Send emails → `integrations.Core.SendEmail()` - Upload files → `integrations.Core.UploadFile()` - Custom APIs → `integrations.custom.call()` -- Per-user OAuth (user connects their own account) → `connectors.connectAppUser()` / `connectors.getCurrentAppUserAccessToken()` - App-scoped OAuth (app builder's account) → `asServiceRole.connectors.getConnection()` (backend only) **Tracking and analytics?** @@ -300,7 +298,6 @@ const token = await base44.asServiceRole.connectors.getAccessToken("slack"); | `analytics` | Yes | Yes | | `appLogs` | Yes | Yes | | `users` | Yes | Yes | -| `connectors` (user OAuth flows) | Yes | Yes | | `asServiceRole.*` | No | Yes | | `asServiceRole.connectors` (app OAuth) | No | Yes | | `asServiceRole.sso` | No | Yes | diff --git a/skills/base44-sdk/references/QUICK_REFERENCE.md b/skills/base44-sdk/references/QUICK_REFERENCE.md index 1c21b99..0d2271a 100644 --- a/skills/base44-sdk/references/QUICK_REFERENCE.md +++ b/skills/base44-sdk/references/QUICK_REFERENCE.md @@ -106,20 +106,6 @@ inviteUser(userEmail, role) → Promise // role: 'user' | 'admin' --- -## User Connectors (`base44.connectors.*`) - -Per-user OAuth flows. Frontend and backend. - -``` -getCurrentAppUserAccessToken(connectorId) → Promise -connectAppUser(connectorId) → Promise // returns redirect URL -disconnectAppUser(connectorId) → Promise -``` - -> `connectorId` is the OrgConnector database ID (not the integration type string). - ---- - ## Service Role Connectors (`base44.asServiceRole.connectors.*`) **Backend only, service role required.** App-scoped (shared account). diff --git a/skills/base44-sdk/references/connectors.md b/skills/base44-sdk/references/connectors.md index 4721c5d..ca90664 100644 --- a/skills/base44-sdk/references/connectors.md +++ b/skills/base44-sdk/references/connectors.md @@ -1,56 +1,16 @@ # Connectors Module -OAuth token management for external services. The SDK exposes **two** connectors modules: +OAuth token management for external services. -- **`base44.connectors`** — User-scoped OAuth flows (frontend & backend). Manages per-user connections. - **`base44.asServiceRole.connectors`** — App-scoped OAuth tokens (backend/service role only). All users share the same connected account. ## Contents -- [User Connectors (`base44.connectors`)](#user-connectors-base44connectors) - [Service Role Connectors (`base44.asServiceRole.connectors`)](#service-role-connectors-base44asserviceroleconnectors) - [Available Services](#available-services) - [Type Definitions](#type-definitions) --- -## User Connectors (`base44.connectors`) - -Per-user OAuth flows. Each end user has their own connection. Available in frontend and backend. - -### Methods - -| Method | Signature | Description | -|--------|-----------|-------------| -| `getCurrentAppUserAccessToken(connectorId)` | `Promise` | Get OAuth access token for the current user's connection | -| `connectAppUser(connectorId)` | `Promise` | Initiate OAuth flow — returns redirect URL | -| `disconnectAppUser(connectorId)` | `Promise` | Remove current user's OAuth connection | - -> **Note:** `connectorId` is the OrgConnector database ID (set in the Base44 dashboard), not the integration type string. - -### Examples - -```javascript -// Check if the current user has connected — get their token -const token = await base44.connectors.getCurrentAppUserAccessToken("abc123def"); - -const response = await fetch("https://www.googleapis.com/calendar/v3/calendars/primary/events", { - headers: { "Authorization": `Bearer ${token}` } -}); -``` - -```javascript -// Initiate OAuth flow — redirect the user to authorize -const redirectUrl = await base44.connectors.connectAppUser("abc123def"); -window.location.href = redirectUrl; -``` - -```javascript -// Disconnect the current user's OAuth connection -await base44.connectors.disconnectAppUser("abc123def"); -``` - ---- - ## Service Role Connectors (`base44.asServiceRole.connectors`) App-scoped OAuth tokens. The app builder connects the account once; all users share it. **Backend/service role only.** @@ -157,7 +117,6 @@ Run `npx base44 connectors list-available` from the CLI to see all available typ ## Important Notes - **Service role connectors**: One account per connector per app — all users share the same connected account -- **User connectors**: Each end user connects their own account - **You handle the API calls**: Base44 provides the token; you make the actual API requests - **Token refresh**: Base44 handles token refresh automatically @@ -195,24 +154,4 @@ interface ConnectorsModule { getAccessToken(integrationType: ConnectorIntegrationType): Promise; } -/** User connectors module (per-user OAuth). Frontend and backend. */ -interface UserConnectorsModule { - /** - * Retrieves the OAuth access token for the current user's connection. - * @param connectorId - The OrgConnector database ID. - */ - getCurrentAppUserAccessToken(connectorId: string): Promise; - - /** - * Initiates OAuth flow for the current user. Returns a redirect URL. - * @param connectorId - The OrgConnector database ID. - */ - connectAppUser(connectorId: string): Promise; - - /** - * Removes the current user's OAuth connection. - * @param connectorId - The OrgConnector database ID. - */ - disconnectAppUser(connectorId: string): Promise; -} ```