### Setup Test Environment Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md Steps to set up the test environment by copying the example environment file and updating it with necessary test credentials. ```bash # Copy the environment template cp env.example .env.test # Update .env.test with your test environment details # Edit the file with your actual test environment details nano .env.test # Required environment variables: # TEST_WORKSPACE_SLUG: Your test workspace slug # TEST_PROJECT_ID: Your test project ID # TEST_USER_ID: Your test user ID # TEST_WORK_ITEM_ID: A test work item ID # TEST_CUSTOMER_ID: A test customer ID # And other test-specific IDs as needed ``` -------------------------------- ### Example: Fetching App Installations Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Demonstrates how to fetch all app installations for a bot or a specific installation using a bot token. This is useful for managing bot deployments across different workspaces. ```typescript const botToken = (await oauth.getBotToken("installation-123")).access_token; // Get all installations for this bot const allInstallations = await oauth.getAppInstallations(botToken); console.log(`Bot installed in ${allInstallations.length} workspaces`); // Get specific installation const installation = await oauth.getAppInstallations( botToken, "installation-123" ); console.log(`Workspace: ${installation[0].workspace_detail.name}`); ``` -------------------------------- ### Complete Project Setup with States, Labels, and Members Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/States-Labels-Members.md This comprehensive example demonstrates how to set up a project by creating workflow states, labels, and adding team members using the Plane Node.js SDK. It also shows how to create a work item with assigned states and labels, and finally lists the created resources. ```typescript import { PlaneClient, HttpError } from "@makeplane/plane-node-sdk"; const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY }); async function setupProject() { const workspace = "my-workspace"; const projectId = "project-123"; try { // 1. Create workflow states console.log("Creating workflow states..."); const backlogState = await client.states.create(workspace, projectId, { name: "Backlog", group: "backlog", color: "#CCCCCC", }); const inProgressState = await client.states.create(workspace, projectId, { name: "In Progress", group: "in_progress", color: "#FFA500", }); const doneState = await client.states.create(workspace, projectId, { name: "Done", group: "completed", color: "#00AA00", }); // 2. Create labels console.log("Creating labels..."); const bugLabel = await client.labels.create(workspace, projectId, { name: "bug", color: "#FF0000", description: "Something isn't working", }); const featureLabel = await client.labels.create(workspace, projectId, { name: "feature", color: "#0000FF", description: "New functionality", }); const docLabel = await client.labels.create(workspace, projectId, { name: "documentation", color: "#00FF00", description: "Documentation updates", }); // 3. Add team members console.log("Adding team members..."); const member1 = await client.members.add(workspace, projectId, { member: "user-1", role: 15, }); const member2 = await client.members.add(workspace, projectId, { member: "user-2", role: 10, }); // 4. Create work items with states and labels console.log("Creating work items..."); const issue = await client.workItems.create(workspace, projectId, { name: "Fix login button styling", description_html: "

Login button is misaligned on mobile

", state: backlogState.id, labels: [bugLabel.id], priority: "high", }); // 5. List all project resources console.log("\nProject Setup Complete:"); console.log(`States: ${(await client.states.list(workspace, projectId)).length}`); console.log(`Labels: ${(await client.labels.list(workspace, projectId)).length}`); console.log(`Members: ${(await client.members.list(workspace, projectId)).length}`); } catch (error) { if (error instanceof HttpError) { console.error(`HTTP ${error.statusCode}: ${error.message}`); } } } setupProject(); ``` -------------------------------- ### Run an Example Script Source: https://github.com/makeplane/plane-node-sdk/blob/main/examples/README.md Execute a TypeScript example script using ts-node. ```bash npx ts-node examples/bootstrap-project.ts ``` -------------------------------- ### Copy Example .env File Source: https://github.com/makeplane/plane-node-sdk/blob/main/tests/unit/README.md Create a .env file in the project root by copying the example file. Update this file with your specific test environment details. ```bash # Copy the example and update with your values cp env.example .env ``` -------------------------------- ### Bot/App Installation Flow Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Demonstrates the complete flow for setting up a bot or application, including obtaining a bot token, retrieving installation details, and performing operations with a bot client. ```typescript import { OAuthClient, PlaneClient } from "@makeplane/plane-node-sdk"; const oauth = new OAuthClient({ clientId: "bot-app-id", clientSecret: "bot-app-secret", redirectUri: "https://bot.example.com/oauth/callback", }); async function setupBot() { // 1. Get bot token for app installation const tokenResponse = await oauth.getBotToken("app-installation-456"); const botToken = tokenResponse.access_token; // 2. Check installation details const installation = await oauth.getAppInstallations(botToken); console.log(`Bot installed in workspace: ${installation[0].workspace_detail.name}`); // 3. Create client for bot operations const botClient = new PlaneClient({ accessToken: botToken }); // 4. Perform bot operations const workItem = await botClient.workItems.create( installation[0].workspace_detail.slug, "project-id", { name: "Auto-generated from bot", description_html: "

Created by bot integration

", } ); console.log(`Created work item: ${workItem.id}`); } setupBot().catch(console.error); ``` -------------------------------- ### Get App Installations Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Retrieve a list of app installations associated with a bot token. Optionally, filter the results to a specific app installation ID. ```typescript async getAppInstallations(token: string, appInstallationId?: string): Promise ``` -------------------------------- ### Install Dependencies Source: https://github.com/makeplane/plane-node-sdk/blob/main/examples/README.md Run this command to install the necessary Node.js dependencies for the Plane SDK. ```bash npm install ``` -------------------------------- ### getAppInstallations Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Fetches app installation(s) associated with a bot token. This method can retrieve all installations or filter down to a specific one if an ID is provided. ```APIDOC ## getAppInstallations ### Description Get app installation(s) using a bot token. ### Method ```typescript async getAppInstallations(token: string, appInstallationId?: string): Promise ``` ### Parameters #### Path Parameters - **token** (string) - Required - Bot token from getBotToken method - **appInstallationId** (string) - Optional - Filter to specific installation (optional) ### Returns `PlaneOAuthAppInstallation[]` ### PlaneOAuthAppInstallation Type ```typescript interface PlaneOAuthAppInstallation { id: string; workspace: string; workspace_detail: { name: string; slug: string; id: string; logo_url?: string; }; application: string; status: string; created_at: string; updated_at: string; deleted_at?: string; created_by?: string; updated_by?: string; installed_by: string; app_bot: string; webhook?: string; } ``` ### Throws `Error` if no installations found with the given ID ### Example ```typescript const botToken = (await oauth.getBotToken("installation-123")).access_token; // Get all installations for this bot const allInstallations = await oauth.getAppInstallations(botToken); console.log(`Bot installed in ${allInstallations.length} workspaces`); // Get specific installation const installation = await oauth.getAppInstallations( botToken, "installation-123" ); console.log(`Workspace: ${installation[0].workspace_detail.name}`); ``` ``` -------------------------------- ### Install Dependencies with pnpm Source: https://github.com/makeplane/plane-node-sdk/blob/main/CLAUDE.md Use this command to install all project dependencies using pnpm. ```bash pnpm install ``` -------------------------------- ### Install Plane Node SDK Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md Install the Plane Node.js SDK using npm. This command downloads and installs the necessary package for your project. ```bash npm install @makeplane/plane-node-sdk ``` -------------------------------- ### Example HTTP Headers Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Provides an example of the HTTP headers object constructed by the `getHeaders` method. This includes `Content-Type` and authentication headers like `X-Api-Key` or `Authorization`. ```typescript { "Content-Type": "application/json", "X-Api-Key": "your-api-key" // or "Authorization": "Bearer ..." } ``` -------------------------------- ### Quick Start with PlaneClient Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md Initialize the PlaneClient and perform basic operations like listing and creating projects. Ensure you replace placeholders with your actual API key or access token and workspace slug. ```typescript import { PlaneClient } from "@plane/node-sdk"; const client = new PlaneClient({ apiKey: "your-api-key", }); // Or with custom base URL const client = new PlaneClient({ baseUrl: "https://your-custom-api.plane.so", accessToken: "your-access-token", }); // List projects const projects = await client.projects.list(); // Create a project const project = await client.projects.create("workspace-slug", { name: "My Project", description: "A new project", }); ``` -------------------------------- ### Example: Using getBotToken and Creating a Client Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Demonstrates how to retrieve a bot access token and then use it to instantiate a PlaneClient for performing bot operations. This is useful for automating tasks or integrating bot functionalities. ```typescript // Get token for bot/app operations const botTokenResponse = await oauth.getBotToken("app-installation-123"); const botAccessToken = botTokenResponse.access_token; // Create client for bot operations const botClient = new PlaneClient({ accessToken: botAccessToken }); // Perform bot operations await botClient.workItems.create("workspace", "project", { name: "Auto-created work item", }); ``` -------------------------------- ### Error Logging Example Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Illustrates the format for logged errors, including the HTTP status and message. ```json ❌ [ERROR] HttpError: 404 Not Found ``` -------------------------------- ### Complete Project Management Example Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Demonstrates the full lifecycle of a project using the Plane Node.js SDK, including creation, retrieval, member listing, feature checking, updating, and archiving. Ensure your PLANE_API_KEY is set in your environment variables. ```typescript import { PlaneClient, HttpError } from "@makeplane/plane-node-sdk"; const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY }); async function manageProject() { try { // Create a new project const project = await client.projects.create("my-workspace", { name: "Web Platform", identifier: "WEB", description: "Main web application", }); console.log(`Created project: ${project.id}`); // Get project details const details = await client.projects.retrieve("my-workspace", project.id); console.log(`Name: ${details.name}`); // List team members const members = await client.projects.getMembers("my-workspace", project.id); console.log(`Team size: ${members.length}`); // Check features const features = await client.projects.retrieveFeatures("my-workspace", project.id); console.log(`Cycles enabled: ${features.cycles}`); // Update project const updated = await client.projects.update("my-workspace", project.id, { description: "Updated main web application", }); // Archive project await client.projects.archive("my-workspace", project.id); console.log("Project archived"); } catch (error) { if (error instanceof HttpError) { console.error(`Error: ${error.statusCode} - ${error.message}`); } } } manageProject(); ``` -------------------------------- ### Request Logging Example Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Shows the format of logged requests when enableLogging is true. Sensitive headers are redacted. ```json 🚀 [REQUEST] { method: "POST", url: "https://api.plane.so/api/v1/workspaces/", headers: { "X-Api-Key": "[REDACTED]", ... }, data: { name: "Project", ... }, params: { ... } } ``` -------------------------------- ### Example of buildUrl Method Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Illustrates the expected output of the `buildUrl` helper method when constructing a full URL for a request, combining the base path with an endpoint. ```typescript // buildUrl("/workspaces/my-ws/projects/") returns: // "https://api.plane.so/api/v1/workspaces/my-ws/projects/" ``` -------------------------------- ### Example Usage of PaginatedResponse Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/types.md Demonstrates how to fetch a paginated list of projects and iterate over the results. ```typescript const response = await client.projects.list("workspace", { limit: 20, offset: 0, }); response.results.forEach(project => console.log(project.name)); ``` -------------------------------- ### Run Development Watch Mode with pnpm Source: https://github.com/makeplane/plane-node-sdk/blob/main/CLAUDE.md Starts the project in watch mode for active development, automatically recompiling on changes. ```bash pnpm dev ``` -------------------------------- ### PlaneOAuthAppInstallation Type Definition Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Defines the structure of an app installation object returned by the getAppInstallations method. This includes details about the workspace, application, and installation status. ```typescript interface PlaneOAuthAppInstallation { id: string; workspace: string; workspace_detail: { name: string; slug: string; id: string; logo_url?: string; }; application: string; status: string; created_at: string; updated_at: string; deleted_at?: string; created_by?: string; updated_by?: string; installed_by: string; app_bot: string; webhook?: string; } ``` -------------------------------- ### Custom Resource Example Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Demonstrates how to extend BaseResource to create a custom API resource, such as `CustomResource`, with methods for listing, creating, retrieving, updating, and deleting custom entities. ```APIDOC ## Example: Creating a Custom Resource ### Description This example shows how to create a custom API resource by extending the `BaseResource` class. It defines methods like `list`, `create`, `retrieve`, `update`, and `delete` that leverage the inherited `get`, `post`, `patch`, and `httpDelete` methods. ### Class Definition ```typescript import { BaseResource } from "@makeplane/plane-node-sdk"; import { Configuration } from "../Configuration"; interface CustomEntity { id: string; name: string; // ... other fields } export class CustomResource extends BaseResource { constructor(config: Configuration) { super(config); } async list(workspaceSlug: string): Promise { // Use inherited get() method return this.get(`/workspaces/${workspaceSlug}/custom-entities/`); } async create( workspaceSlug: string, data: Omit ): Promise { // Use inherited post() method return this.post( `/workspaces/${workspaceSlug}/custom-entities/`, data ); } async retrieve( workspaceSlug: string, entityId: string ): Promise { // Use inherited get() method return this.get( `/workspaces/${workspaceSlug}/custom-entities/${entityId}/` ); } async update( workspaceSlug: string, entityId: string, updates: Partial ): Promise { // Use inherited patch() method return this.patch( `/workspaces/${workspaceSlug}/custom-entities/${entityId}/`, updates ); } async delete(workspaceSlug: string, entityId: string): Promise { // Use inherited httpDelete() method return this.httpDelete( `/workspaces/${workspaceSlug}/custom-entities/${entityId}/` ); } } ``` ``` -------------------------------- ### Retrieve Work Item Examples Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/types.md Demonstrates retrieving a basic work item versus a work item with expanded labels and assignees. ```typescript // Type: WorkItemBase with string arrays for labels/assignees const item = await client.workItems.retrieve("ws", "proj", "id"); // Type: WorkItem with labels: Label[], assignees: User[] const expanded = await client.workItems.retrieve( "ws", "proj", "id", ["labels", "assignees"] ); ``` -------------------------------- ### Complete OAuth Flow Example Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md This example demonstrates a full OAuth 2.0 authorization code flow using Express.js. It includes redirecting users to Plane for authorization, handling the callback, exchanging the authorization code for access and refresh tokens, storing them in the session, and using a middleware to ensure the access token is valid before making API calls. ```typescript import express from "express"; import { OAuthClient, PlaneClient } from "@makeplane/plane-node-sdk"; const app = express(); const oauth = new OAuthClient({ clientId: process.env.PLANE_CLIENT_ID!, clientSecret: process.env.PLANE_CLIENT_SECRET!, redirectUri: "http://localhost:3000/oauth/callback", }); // Step 1: Redirect user to authorization app.get("/login", (req, res) => { const state = Math.random().toString(36).substring(7); req.session.oauthState = state; // Store for verification const authUrl = oauth.getAuthorizationUrl("code", state); res.redirect(authUrl); }); // Step 2: Handle OAuth callback app.get("/oauth/callback", async (req, res) => { const code = req.query.code as string; const state = req.query.state as string; const error = req.query.error as string; if (error) { return res.status(400).send(`Authorization denied: ${error}`); } if (state !== req.session.oauthState) { return res.status(400).send("State mismatch - CSRF attack detected"); } try { // Exchange code for tokens const tokenResponse = await oauth.exchangeCodeForToken(code); // Store in session req.session.accessToken = tokenResponse.access_token; req.session.refreshToken = tokenResponse.refresh_token; req.session.expiresAt = Date.now() + ((tokenResponse.expires_in || 3600) * 1000); res.redirect("/dashboard"); } catch (error) { console.error("OAuth error:", error); res.status(500).send("Authentication failed"); } }); // Middleware to ensure token is fresh app.use(async (req, res, next) => { if (!req.session.accessToken) { return res.redirect("/login"); } if (req.session.expiresAt < Date.now()) { try { const newToken = await oauth.getRefreshToken(req.session.refreshToken); req.session.accessToken = newToken.access_token; req.session.expiresAt = Date.now() + ((newToken.expires_in || 3600) * 1000); } catch (error) { return res.redirect("/login"); } } next(); }); // Step 3: Use access token for API calls app.get("/api/projects", async (req, res) => { try { const client = new PlaneClient({ accessToken: req.session.accessToken, }); const projects = await client.projects.list("workspace-slug"); res.json(projects); } catch (error) { res.status(500).json({ error: "Failed to fetch projects" }); } }); app.listen(3000, () => { console.log("OAuth server running on http://localhost:3000"); }); ``` -------------------------------- ### Projects Class Extending BaseResource Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Example of a subclass calling the BaseResource constructor. ```typescript class Projects extends BaseResource { constructor(config: Configuration) { super(config); // Call parent constructor } } ``` -------------------------------- ### Development Commands Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md Common commands for developing the Plane Node.js SDK, including installing dependencies, building the project, running tests, linting, and formatting code. ```bash # Install dependencies pnpm install # Build the project pnpm build # Run tests pnpm test # Lint code pnpm lint # Format code pnpm format ``` -------------------------------- ### Assign Work Item with States, Labels, and Members Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/States-Labels-Members.md This example demonstrates how to fetch states, labels, and members, and then use them to create and assign a new work item. Ensure you have your PLANE_API_KEY set in your environment variables. ```typescript import { PlaneClient } from "@makeplane/plane-node-sdk"; const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY }); async function assignWorkItem() { const workspace = "my-workspace"; const projectId = "project-123"; try { // Get states const states = await client.states.list(workspace, projectId); const inProgressState = states.find(s => s.group === "in_progress"); // Get labels const labels = await client.labels.list(workspace, projectId); const bugLabel = labels.find(l => l.name === "bug"); const priorityLabel = labels.find(l => l.name === "critical"); // Get members const members = await client.members.list(workspace, projectId); const lead = members[0]; // Create and assign work item const item = await client.workItems.create(workspace, projectId, { name: "Critical production bug", state: inProgressState?.id, labels: [bugLabel?.id, priorityLabel?.id].filter(Boolean) as string[], assignees: [lead.user], priority: "urgent", }); console.log(`Created and assigned: ${item.id}`); } catch (error) { console.error(error); } } assignWorkItem(); ``` -------------------------------- ### Get Bot Access Token Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Obtain an access token for bot or application installations using the client credentials grant. This token is required for subsequent bot operations. ```typescript async getBotToken(appInstallationId: string): Promise ``` -------------------------------- ### Client Initialization Source: https://github.com/makeplane/plane-node-sdk/blob/main/AGENTS.MD Demonstrates how to initialize the Plane Node.js SDK client with necessary configuration. ```APIDOC ## Client Initialization ### Description Initialize the `PlaneClient` by providing your Plane API base URL, API key, or access token. ### Code Example ```typescript import { PlaneClient } from "@plane/node-sdk"; const client = new PlaneClient({ baseUrl: process.env.PLANE_BASE_URL, // e.g., "https://api.plane.com/v1" apiKey: process.env.PLANE_API_KEY, // Optional: for API key authentication accessToken: process.env.PLANE_ACCESS_TOKEN // Optional: for OAuth/JWT authentication }); ``` ### Configuration Parameters - **baseUrl** (string) - Required - The base URL of the Plane API. - **apiKey** (string) - Optional - Your Plane API key for authentication. - **accessToken** (string) - Optional - Your access token for authentication (e.g., JWT or OAuth). ### Usage Once initialized, the `client` object can be used to access various API resources like `client.projects`, `client.workItems`, etc. ``` -------------------------------- ### Initialize PlaneClient Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md Demonstrates the recommended pattern for initializing the PlaneClient. Ensure PLANE_API_KEY or PLANE_ACCESS_TOKEN environment variables are set. Logging is enabled in development environments. ```typescript function initializePlaneClient(): PlaneClient { const apiKey = process.env.PLANE_API_KEY; const accessToken = process.env.PLANE_ACCESS_TOKEN; if (!apiKey && !accessToken) { throw new Error("PLANE_API_KEY or PLANE_ACCESS_TOKEN environment variable required"); } return new PlaneClient({ baseUrl: process.env.PLANE_BASE_URL, // Optional, defaults to https://api.plane.so apiKey: apiKey, accessToken: accessToken, enableLogging: process.env.NODE_ENV === "development", }); } const client = initializePlaneClient(); export default client; ``` -------------------------------- ### Get Total Work Logs Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Retrieves the total work logs for a specific project within a workspace. Use this to get aggregated time tracking data. ```typescript async getTotalWorkLogs(workspaceSlug: string, projectId: string): Promise ``` ```typescript const workLogs = await client.projects.getTotalWorkLogs("my-workspace", "project-123"); console.log(`Total hours logged: ${workLogs.total_duration}`); ``` -------------------------------- ### Initialize Configuration with API Key Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md Create a new Configuration instance, specifying the base URL and API key for authentication. Always call the validate method after initialization to ensure configuration is correct. ```typescript const config = new Configuration({ baseUrl: "https://api.plane.so", apiKey: "your-api-key", }); config.validate(); // Throws if invalid ``` -------------------------------- ### Perform GET Request Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Use the `get` method to retrieve data from a specified API endpoint. It accepts query parameters for filtering or sorting results. This method is intended for internal use within subclasses. ```typescript protected async get(endpoint: string, params?: any): Promise ``` ```typescript return this.get( `/workspaces/${workspaceSlug}/projects/${projectId}/` ); ``` -------------------------------- ### create Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Creates a new project within a specified workspace. You can provide details like name, identifier, description, and timezone. ```APIDOC ## create ### Description Create a new project in a workspace. ### Method `POST` (Implicit, SDK method) ### Endpoint `/workspaces/{workspaceSlug}/projects` (Conceptual) ### Parameters #### Path Parameters - **workspaceSlug** (string) - Yes - The workspace identifier (slug) #### Request Body - **createProject** (CreateProject) - Yes - Project creation data - **name** (string) - Yes - Project name - **identifier** (string) - Optional - Project identifier (auto-generated from name if omitted) - **description** (string) - Optional - Project description - **timezone** (string) - Optional - Project timezone - **cover_image** (string) - Optional - Cover image URL - **icon_prop** (any) - Optional - Icon properties ### Request Example ```typescript await client.projects.create("my-workspace", { name: "Mobile App", identifier: "MOBILE", description: "iOS and Android application", timezone: "America/New_York", }); ``` ### Response #### Success Response (200) - **Project** (object) - The created project ``` -------------------------------- ### Initialize Plane Client and List Projects Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/README.md Initializes the PlaneClient with an API key and demonstrates how to list projects within a workspace. Ensure you replace 'your-api-key' and 'workspace-slug' with your actual credentials and workspace identifier. ```typescript import { PlaneClient } from "@makeplane/plane-node-sdk"; const client = new PlaneClient({ apiKey: "your-api-key", }); // List projects const projects = await client.projects.list("workspace-slug"); ``` -------------------------------- ### Get Project Members Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Retrieves a list of members associated with a specific project within a workspace. ```APIDOC ## GET /projects/{workspace_id}/{project_id}/members ### Description Retrieves a list of members associated with a specific project within a workspace. ### Method GET ### Endpoint `/projects/{workspace_id}/{project_id}/members` ### Parameters #### Path Parameters - **workspace_id** (string) - Required - The ID of the workspace. - **project_id** (string) - Required - The ID of the project. ### Response #### Success Response (200 OK) - **members** (array) - An array of member objects. #### Response Example ```json [ { "id": "user_abc", "username": "john.doe", "display_name": "John Doe", "email": "john.doe@example.com", "avatar_url": "https://example.com/avatar.png", "role": 1 } ] ``` ``` -------------------------------- ### List Projects with Pagination Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/README.md Demonstrates how to list projects and access pagination details like total count, items per page, and cursor for loading the next page. ```typescript const response = await client.projects.list(workspace); console.log(response.total_count); // Total items console.log(response.count); // Items in page console.log(response.results); // Array of items console.log(response.total_pages); // Total pages if (response.next_cursor) { // Load next page } ``` -------------------------------- ### retrieve Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Cycles.md Get a cycle by its ID. Requires workspace slug, project ID, and cycle ID. ```APIDOC ## retrieve ### Description Get a cycle by ID. ### Method GET (Assumed based on retrieve operation) ### Endpoint `/workspaces/{workspaceSlug}/projects/{projectId}/cycles/{cycleId}` (Assumed based on parameters) ### Parameters #### Path Parameters - **workspaceSlug** (string) - Required - The workspace identifier - **projectId** (string) - Required - The project ID - **cycleId** (string) - Required - The cycle ID ### Response #### Success Response (200 OK) - **id** (string) - The unique identifier for the cycle - **name** (string) - Cycle name - **description** (string) - Cycle description - **start_date** (string) - Start date (YYYY-MM-DD) - **end_date** (string) - End date (YYYY-MM-DD) - **status** (string) - Cycle status #### Response Example ```json { "id": "cycle-123", "name": "Sprint 1", "description": "First development sprint", "start_date": "2024-01-15", "end_date": "2024-01-29", "status": "open" } ``` ``` -------------------------------- ### Create Project Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Creates a new project within a specified workspace. Requires workspace ID and project details including name, identifier, and description. ```APIDOC ## POST /projects/create ### Description Creates a new project within a specified workspace. ### Method POST ### Endpoint `/projects/create` ### Parameters #### Path Parameters - **workspace_id** (string) - Required - The ID of the workspace to create the project in. #### Request Body - **name** (string) - Required - The name of the project. - **identifier** (string) - Required - A unique identifier for the project (e.g., "WEB"). - **description** (string) - Optional - A description of the project. ### Response #### Success Response (201 Created) - **project** (Project) - The created project object. #### Response Example ```json { "id": "proj_123", "name": "Web Platform", "identifier": "WEB", "description": "Main web application", "workspace": "my-workspace", "is_member": true, "member_role": 1, "total_members": 1, "total_cycles": 0, "total_modules": 0, "timezone": "UTC", "is_deployed": false, "module_view": true, "cycle_view": true, "issue_views_view": true, "page_view": true, "intake_view": false, "archive_in": 30, "close_in": 60 } ``` ``` -------------------------------- ### Retrieve Project Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md Retrieves a specific project by its ID within a workspace. Used for error handling examples. ```APIDOC ## Retrieve Project ### Description Retrieves a specific project by its ID within a workspace. Used for error handling examples. ### Method GET ### Endpoint `/api/v1/workspaces/{workspace_id}/projects/{project_id}` ### Parameters #### Path Parameters - **workspace_id** (string) - Required - The identifier of the workspace. - **project_id** (string) - Required - The identifier of the project. ### Response #### Success Response (200) - **id** (string) - The unique identifier of the project. - **name** (string) - The name of the project. ### Request Example ```typescript try { const project = await client.projects.retrieve( "workspace", "non-existent-id" ); } catch (error) { // Error handling logic } ``` ``` -------------------------------- ### Constructor Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md Initializes the BaseResource with a configuration object. This constructor is called by all subclasses. ```APIDOC ## Constructor ### Description Initializes the BaseResource with a configuration object containing authentication and base URL details. ### Signature ```typescript constructor(config: Configuration) ``` ### Parameters #### Path Parameters - **config** (`Configuration`) - Required - Configuration object with auth and base URL ``` -------------------------------- ### Create Work Item with Priority Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/types.md Example of creating a work item and assigning it an 'urgent' priority using the PriorityEnum. ```typescript await client.workItems.create("workspace", "project", { name: "Fix critical bug", priority: "urgent", }); ``` -------------------------------- ### retrieveFeatures Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Get project features (enabled/disabled capabilities). This method fetches the current feature status for a given project. ```APIDOC ## retrieveFeatures ### Description Get project features (enabled/disabled capabilities). ### Method `async` ### Endpoint `client.projects.retrieveFeatures(workspaceSlug: string, projectId: string)` ### Parameters #### Path Parameters - **workspaceSlug** (string) - Yes - The workspace identifier - **projectId** (string) - Yes - The project ID ### Response #### Success Response - **ProjectFeatures** ``` -------------------------------- ### Create Sprint Cycle Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/README.md Create a new sprint cycle with a specified name, start date, and end date. ```typescript const cycle = await client.cycles.create(workspace, projectId, { name: "Sprint 5", start_date: "2024-02-01", end_date: "2024-02-15", }); ``` -------------------------------- ### Initialize PlaneClient with API Key Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md Initialize the client using an API key for authentication. Ensure 'your-api-key' is replaced with your actual key. ```typescript const client = new PlaneClient({ apiKey: "your-api-key", }); ``` -------------------------------- ### Set API Key Environment Variable Source: https://github.com/makeplane/plane-node-sdk/blob/main/examples/README.md Configure your Plane API key as an environment variable before running SDK examples. ```bash export PLANE_API_KEY="your-api-key" ``` -------------------------------- ### Get Project Members Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Fetches the members of a project along with their role information, using the workspace slug and project ID. ```typescript async getMembers(workspaceSlug: string, projectId: string): Promise ``` ```typescript const members = await client.projects.getMembers("my-workspace", "project-123"); members.forEach(member => { console.log(`${member.member_detail?.display_name}: ${member.role}`); }); ``` -------------------------------- ### Import and Initialize PlaneClient Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Cycles.md Import the PlaneClient and initialize it with your API key to access the SDK's functionalities. ```typescript import { PlaneClient } from "@makeplane/plane-node-sdk"; const client = new PlaneClient({ apiKey: "..." }); ``` -------------------------------- ### OAuth Flow: Get Authorization URL Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md Generate the authorization URL required to initiate the OAuth flow and redirect the user. ```typescript const oauth = new OAuthClient({ clientId: "your-client-id", clientSecret: "your-client-secret", redirectUri: "https://yourapp.com/oauth/callback", }); // 1. Get authorization URL const authUrl = oauth.getAuthorizationUrl("code", "unique-state-id"); // Redirect user to this URL ``` -------------------------------- ### Configuration Class Source: https://github.com/makeplane/plane-node-sdk/blob/main/AGENTS.MD Details the `Configuration` class used for setting up the Plane client. ```APIDOC ## Configuration Class ### Description The `Configuration` class holds the necessary details to connect to the Plane API, including the base URL and authentication credentials. ### Code Example ```typescript // src/Configuration.ts export class Configuration { public basePath: string; public apiKey?: string; public accessToken?: string; constructor(config: { basePath: string; apiKey?: string; accessToken?: string; }) { this.basePath = config.basePath; this.apiKey = config.apiKey; this.accessToken = config.accessToken; } } ``` ### Constructor Parameters - **basePath** (string) - Required - The base URL for the API. - **apiKey** (string) - Optional - The API key for authentication. - **accessToken** (string) - Optional - The access token for authentication. ``` -------------------------------- ### Initialize PlaneClient with API Key Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/INDEX.md Instantiate the PlaneClient using an API key for authentication. Ensure the PLANE_API_KEY environment variable is set. ```typescript import { PlaneClient } from "@makeplane/plane-node-sdk"; // API Key authentication const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY, }); ``` -------------------------------- ### Manage Projects Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/INDEX.md Perform CRUD operations on projects within a workspace. Examples include listing, creating, retrieving, and updating projects. ```typescript // List projects const projects = await client.projects.list("workspace-slug"); // Create project const project = await client.projects.create("workspace-slug", { name: "My Project", identifier: "PROJ", }); // Get project details const details = await client.projects.retrieve("workspace-slug", "project-id"); // Update project const updated = await client.projects.update("workspace-slug", "project-id", { description: "Updated description", }); ``` -------------------------------- ### Paginate Projects Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/INDEX.md Demonstrates how to fetch a paginated list of projects from a workspace. Includes loading the next page using a cursor. ```typescript const response = await client.projects.list("workspace", { limit: 20, offset: 0, }); console.log(`Page 1 of ${response.total_pages}`); response.results.forEach(item => console.log(item)); if (response.next_cursor) { // Load next page using cursor } ``` -------------------------------- ### getBotToken Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md Retrieves an access token for bot or application installations using the client credentials grant. This token is essential for authenticating bot operations. ```APIDOC ## getBotToken ### Description Get an access token for bot/app installations using client credentials grant. ### Method ```typescript async getBotToken(appInstallationId: string): Promise ``` ### Parameters #### Path Parameters - **appInstallationId** (string) - Required - The app installation ID ### Returns `PlaneOAuthTokenResponse` - Bot token response ### Example ```typescript // Get token for bot/app operations const botTokenResponse = await oauth.getBotToken("app-installation-123"); const botAccessToken = botTokenResponse.access_token; // Create client for bot operations const botClient = new PlaneClient({ accessToken: botAccessToken }); // Perform bot operations await botClient.workItems.create("workspace", "project", { name: "Auto-created work item", }); ``` ``` -------------------------------- ### Enable Request Logging in PlaneClient Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/README.md Shows how to initialize the PlaneClient with request and response logging enabled. Sensitive headers like Authorization and X-Api-Key are automatically redacted in the logs. ```typescript const client = new PlaneClient({ apiKey: "your-api-key", enableLogging: true, // Logs with sensitive data redaction }); ``` -------------------------------- ### Example Validation Error Response Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/errors.md A sample JSON response illustrating validation errors, which may include a 'detail' field or an 'errors' object. ```json { "detail": "Project identifier must be unique within workspace", "errors": { "identifier": ["This field may not be blank."] } } ``` -------------------------------- ### getTotalWorkLogs Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md Get total work logs for a project. This method retrieves aggregated work log statistics for a specified project within a workspace. ```APIDOC ## getTotalWorkLogs ### Description Get total work logs for a project. ### Method `async` ### Endpoint `client.projects.getTotalWorkLogs(workspaceSlug: string, projectId: string)` ### Parameters #### Path Parameters - **workspaceSlug** (string) - Yes - The workspace identifier - **projectId** (string) - Yes - The project ID ### Response #### Success Response - **any** - Total work log statistics ``` -------------------------------- ### Create Sprint Cycle Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/README.md Creates a new sprint cycle for a project, specifying the cycle's name, start date, and end date. ```APIDOC ## POST /cycles.create ### Description Creates a new sprint cycle. ### Method POST ### Endpoint `/cycles.create` ### Parameters #### Path Parameters - **workspace** (string) - Required - The workspace ID. - **projectId** (string) - Required - The project ID. #### Request Body - **name** (string) - Required - The name of the sprint cycle (e.g., "Sprint 5"). - **start_date** (string) - Required - The start date of the cycle (YYYY-MM-DD). - **end_date** (string) - Required - The end date of the cycle (YYYY-MM-DD). ``` -------------------------------- ### Initialize PlaneClient with Access Token Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md Initialize the client using an OAuth access token for authentication. Replace 'your-access-token' with your actual token. ```typescript const client = new PlaneClient({ accessToken: "your-access-token", }); ``` -------------------------------- ### Create Cycle Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md Creates a new cycle (sprint) within a specified project and workspace. Requires name, start date, and end date. ```APIDOC ## Create Cycle ### Description Creates a new cycle (sprint) within a specified project and workspace. Requires name, start date, and end date. ### Method POST ### Endpoint `/api/v1/workspaces/{workspace_id}/projects/{project_id}/cycles` ### Parameters #### Path Parameters - **workspace_id** (string) - Required - The identifier of the workspace. - **project_id** (string) - Required - The identifier of the project. #### Request Body - **name** (string) - Required - The name of the cycle. - **start_date** (string) - Required - The start date of the cycle (YYYY-MM-DD). - **end_date** (string) - Required - The end date of the cycle (YYYY-MM-DD). ### Response #### Success Response (201) - **id** (string) - The unique identifier of the created cycle. - **name** (string) - The name of the cycle. - **start_date** (string) - The start date of the cycle. - **end_date** (string) - The end date of the cycle. ### Request Example ```typescript const cycle = await client.cycles.create( "my-workspace", "project-123", { name: "Sprint 1", start_date: "2024-01-15", end_date: "2024-01-29", } ); ``` ### Response Example ```json { "id": "cycle-abcde", "name": "Sprint 1", "start_date": "2024-01-15", "end_date": "2024-01-29" } ``` ``` -------------------------------- ### PlaneClient Constructor Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md Initializes a new instance of the PlaneClient. It requires authentication credentials and optionally accepts a base URL and logging configuration. ```APIDOC ## PlaneClient Constructor ### Description Initializes a new instance of the PlaneClient. It requires authentication credentials and optionally accepts a base URL and logging configuration. ### Method `new PlaneClient(config: { baseUrl?: string; apiKey?: string; accessToken?: string; enableLogging?: boolean; })` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |---|---|---|---|---| | baseUrl | `string` | No | `"https://api.plane.so"` | Base URL for the Plane API. Use for self-hosted instances. | | apiKey | `string` | No (1) | — | API key for authentication (X-Api-Key header). | | accessToken | `string` | No (1) | — | OAuth access token (Authorization: Bearer header). | | enableLogging | `boolean` | No | `false` | Enable request/response logging with sensitive data redaction. | **(1)** Either `apiKey` or `accessToken` is required. ### Throws `Error` if neither apiKey nor accessToken is provided, or if baseUrl is invalid. ### Example ```typescript const client = new PlaneClient({ apiKey: "your-api-key", enableLogging: true, }); ``` ``` -------------------------------- ### create Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Cycles.md Create a new cycle in a project. Requires workspace slug, project ID, and cycle creation data. ```APIDOC ## create ### Description Create a new cycle in a project. ### Method POST (Assumed based on create operation) ### Endpoint `/workspaces/{workspaceSlug}/projects/{projectId}/cycles` (Assumed based on parameters) ### Parameters #### Path Parameters - **workspaceSlug** (string) - Required - The workspace identifier - **projectId** (string) - Required - The project ID #### Request Body - **name** (string) - Required - Cycle name - **description** (string) - Optional - Cycle description - **start_date** (string) - Optional - Start date (YYYY-MM-DD) - **end_date** (string) - Optional - End date (YYYY-MM-DD) - **status** (string) - Optional - Cycle status ### Request Example ```json { "name": "Sprint 1", "description": "First development sprint", "start_date": "2024-01-15", "end_date": "2024-01-29" } ``` ### Response #### Success Response (201 Created - Assumed) - **id** (string) - The unique identifier for the created cycle - **name** (string) - Cycle name - **description** (string) - Cycle description - **start_date** (string) - Start date (YYYY-MM-DD) - **end_date** (string) - End date (YYYY-MM-DD) - **status** (string) - Cycle status #### Response Example ```json { "id": "cycle-abc", "name": "Sprint 1", "description": "First development sprint", "start_date": "2024-01-15", "end_date": "2024-01-29", "status": "open" } ``` ``` -------------------------------- ### Retrieve a Work Item by Identifier Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/WorkItems.md Get a single work item using its unique identifier, which can span across projects. Optionally expand fields for more detailed information. ```typescript const item = await client.workItems.retrieveByIdentifier( "my-workspace", "PROJ-123" ); console.log(`Retrieved: ${item.name}`); ```