### Install npm packages for Huly API Source: https://github.com/hcengineering/huly-examples/blob/main/README.md Installs required npm packages for interacting with the Huly API. Requires a GitHub access token for authentication with the npm registry. ```bash npm install ``` -------------------------------- ### Run Huly API issue list example Source: https://github.com/hcengineering/huly-examples/blob/main/README.md Executes a TypeScript example script to list issues from the Huly API. This requires prior installation of npm packages. ```bash npx ts-node examples/issue-list.ts ``` -------------------------------- ### Create Document Teamspace (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt Creates a new teamspace specifically for organizing documents. This function also includes setting up initial members and owners for the teamspace. ```typescript import { NodeWebSocketFactory, connect } from '@hcengineering/api-client' import core from '@hcengineering/core' import document from '@hcengineering/document' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { const account = client.getAccount() // Create teamspace const teamspaceId = await client.createDoc( document.class.Teamspace, core.space.Space, { name: 'My Documents', description: 'Space for my shared documents', private: false, archived: false, members: [account._id], owners: [account._id], icon: document.icon.Teamspace, type: document.spaceType.DefaultTeamspaceType } ) const teamspace = await client.findOne( document.class.Teamspace, { _id: teamspaceId } ) console.log('Created teamspace:', teamspace) } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Connect to Huly API using Token Source: https://github.com/hcengineering/huly-examples/blob/main/README.md Establishes a connection to the Huly API using an authentication token and a workspace. The connection is managed by a client object, which must be closed after use. ```typescript const client = await connect('http://localhost:8087', { token: '...', workspace: 'ws1' }) ... await client.close() ``` -------------------------------- ### Connect to Huly API using Email and Password Source: https://github.com/hcengineering/huly-examples/blob/main/README.md Establishes a connection to the Huly API using user credentials (email and password) and a workspace. The connection is managed by a client object, which must be closed after use. ```typescript const client = await connect('http://localhost:8087', { email: 'user1', password: '1234', workspace: 'ws1' }) ... await client.close() ``` -------------------------------- ### Query Huly Issues with Lookup and Markup (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt Retrieves issues from a Huly project, demonstrating filtering, sorting, pagination, and relational data lookup. It also shows how to fetch and render markdown content for issue descriptions using the Huly Platform API client. Dependencies include '@hcengineering/api-client', '@hcengineering/core', '@hcengineering/task', and '@hcengineering/tracker'. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import { SortingOrder } from '@hcengineering/core' import task from '@hcengineering/task' import tracker from '@hcengineering/tracker' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { // Find project with lookup const project = await client.findOne( tracker.class.Project, { identifier: 'HULY' }, { lookup: { type: task.class.ProjectType } } ) if (!project) throw new Error('Project not found') console.log('Project:', project.identifier, project.description) if (project.$lookup?.type) { console.log('Statuses:') for (const status of project.$lookup.type.statuses) { console.log('-', status) } } // Query issues with sorting and pagination const issues = await client.findAll( tracker.class.Issue, { space: project._id }, { limit: 20, sort: { modifiedOn: SortingOrder.Descending } } ) console.log('Found issues:', issues.length) for (const issue of issues) { console.log('-', issue.identifier, issue.title) if (issue.description) { const markup = await client.fetchMarkup( issue._class, issue._id, 'description', issue.description, 'markdown' ) console.log(' ', markup) } } } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Query Persons with Contact Channels (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt Retrieves all persons from the contact database along with their associated communication channels. It demonstrates fetching nested data and iterating through relationships. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import contact from '@hcengineering/contact' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { const persons = await client.findAll(contact.class.Person, {}) console.log('Found persons:', persons.length) for (const person of persons) { const channels = await client.findAll( contact.class.Channel, { attachedTo: person._id, attachedToClass: person._class } ) console.log('-', person.name, person.city) for (const channel of channels) { console.log(' -', channel.value) } } } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Create Person with Email Channel (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt Creates a new person record and then adds an email communication channel to that person. This showcases entity creation and appending to nested collections. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import contact, { AvatarType, Person } from '@hcengineering/contact' import { generateId } from '@hcengineering/core' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { const personId = generateId() // Create person await client.createDoc( contact.class.Person, contact.space.Contacts, { name: 'Doe,John', city: 'New York', avatarType: AvatarType.COLOR }, personId ) // Add email channel to person await client.addCollection( contact.class.Channel, contact.space.Contacts, personId, contact.class.Person, 'channels', { provider: contact.channelProvider.Email, value: 'john.doe@example.com' } ) const person = await client.findOne(contact.class.Person, { _id: personId }) console.log('Created person:', person) } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### List Documents in Teamspace with Sorting and Pagination (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt This snippet demonstrates how to query and retrieve a list of documents from a specific teamspace. It supports sorting documents by name in ascending order and implements pagination with a limit of 20 documents. The markdown content for each document is also fetched for display. It requires the '@hcengineering/api-client', '@hcengineering/core', and '@hcengineering/document' libraries. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import { SortingOrder } from '@hcengineering/core' import document from '@hcengineering/document' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { // Find teamspace const teamspace = await client.findOne( document.class.Teamspace, { name: 'My Documents', archived: false } ) if (!teamspace) throw new Error('Teamspace not found') // Query documents with sorting const documents = await client.findAll( document.class.Document, { space: teamspace._id }, { limit: 20, sort: { name: SortingOrder.Ascending } } ) console.log('Documents:', documents.length) for (const doc of documents) { console.log('-', doc.title) if (doc.content) { const markup = await client.fetchMarkup( doc._class, doc._id, 'content', doc.content, 'markdown' ) console.log(' ', markup) } } } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Connect to Huly with Email Authentication (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt Establishes a WebSocket connection to a Huly instance using email and password credentials. This connection enables subsequent API operations within a specified workspace. It requires the '@hcengineering/api-client' package and specifies connection options including the socket factory and timeout. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' const url = 'http://localhost:8087' const options: ConnectOptions = { email: 'user1', password: '1234', workspace: 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { // Perform operations with the client const account = client.getAccount() console.log('Connected as:', account) } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Connect to Huly with Token Authentication (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt Connects to a Huly instance using a pre-generated authentication token. This method is a secure alternative for service integrations compared to credential-based authentication. It requires connection options such as the token, workspace, socket factory, and connection timeout. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' const url = 'http://localhost:8087' const options: ConnectOptions = { token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', workspace: 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { // Token-based operations console.log('Connected successfully with token') } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Create Markdown Document in Teamspace (TypeScript) Source: https://context7.com/hcengineering/huly-examples/llms.txt This snippet demonstrates how to create a new markdown document within a specified teamspace. It includes logic for finding a teamspace, determining the correct ranking for the new document based on existing ones, uploading content, and finally creating the document. Dependencies include the '@hcengineering/api-client', '@hcengineering/core', '@hcengineering/document', and '@hcengineering/rank' libraries. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import { Ref, SortingOrder, generateId } from '@hcengineering/core' import document, { Document } from '@hcengineering/document' import { makeRank } from '@hcengineering/rank' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { // Find teamspace const teamspace = await client.findOne( document.class.Teamspace, { name: 'My Documents', archived: false } ) if (!teamspace) throw new Error('Teamspace not found') // Get last document for ranking const lastOne = await client.findOne( document.class.Document, { space: teamspace._id }, { sort: { rank: SortingOrder.Descending } } ) const documentId: Ref = generateId() // Upload markdown content const content = await client.uploadMarkup( document.class.Document, documentId, 'content', `# Make coffee Do morning coffee using drip coffee maker. * Fill tank with fresh water * Put 2 scoops ground coffee * Press start button Enjoy your coffee.`, 'markdown' ) // Create document await client.createDoc( document.class.Document, teamspace._id, { title: 'Make coffee', content, parent: document.ids.NoParent, rank: makeRank(lastOne?.rank, undefined) }, documentId ) const doc = await client.findOne(document.class.Document, { _id: documentId }) if (!doc) throw new Error('Document not found') console.log('Created document:', doc.title) if (doc.content) { const markup = await client.fetchMarkup( doc._class, doc._id, 'content', doc.content, 'markdown' ) console.log(markup) } } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Assign Labels to Issues in TypeScript Source: https://context7.com/hcengineering/huly-examples/llms.txt This script demonstrates how to create and assign labels (tags) to issues. It first creates a new label and then associates it with a specific issue. The script utilizes dependencies such as '@hcengineering/api-client', '@hcengineering/core', '@hcengineering/tracker', and '@hcengineering/tags'. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import core, { type Ref, generateId } from '@hcengineering/core' import tracker, { type Issue } from '@hcengineering/tracker' import tags, { type TagElement } from '@hcengineering/tags' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { const project = await client.findOne( tracker.class.Project, { identifier: 'HULY' } ) if (!project) throw new Error('Project not found') const issueId: Ref = generateId() // Create issue (abbreviated for brevity) await client.addCollection( tracker.class.Issue, project._id, project._id, project._class, 'issues', { title: 'Make coffee', status: project.defaultIssueStatus, number: 1, kind: tracker.taskTypes.Issue, identifier: `${project.identifier}-1` }, issueId ) // Create label const labelId: Ref = generateId() await client.createDoc( tags.class.TagElement, core.space.Workspace, { title: 'coffee', description: '', targetClass: tracker.class.Issue, color: 11, category: tracker.category.Other }, labelId ) // Assign label to issue await client.addCollection( tags.class.TagReference, project._id, issueId, tracker.class.Issue, 'labels', { title: 'coffee', color: 11, tag: labelId } ) // Retrieve labels for the issue const labels = await client.findAll( tags.class.TagReference, { attachedTo: issueId, attachedToClass: tracker.class.Issue } ) console.log('Assigned labels:') for (const label of labels) { console.log('-', label.title) } } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Update Issues and Create Milestone in TypeScript Source: https://context7.com/hcengineering/huly-examples/llms.txt This script updates multiple issues by assigning them to a new milestone and setting due dates. It first completes all existing milestones and then creates a new one, followed by assigning all open issues to this new milestone. Dependencies include '@hcengineering/api-client', '@hcengineering/core', and '@hcengineering/tracker'. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import { generateId } from '@hcengineering/core' import tracker, { Milestone, MilestoneStatus } from '@hcengineering/tracker' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const targetDate = Date.now() + 1000 * 60 * 60 * 24 * 14 // 14 days const client = await connect(url, options) try { // Find project const project = await client.findOne( tracker.class.Project, { identifier: 'HULY' } ) if (!project) throw new Error('Project not found') // Get all existing milestones const milestones = await client.findAll( tracker.class.Milestone, { space: project._id } ) // Mark all existing milestones as completed for (const milestone of milestones) { if (milestone.status !== MilestoneStatus.Completed) { await client.updateDoc( tracker.class.Milestone, project._id, milestone._id, { status: MilestoneStatus.Completed } ) } } // Create new milestone const milestoneId = generateId() await client.createDoc( tracker.class.Milestone, project._id, { label: `Milestone #${milestones.length + 1}`, status: MilestoneStatus.InProgress, targetDate, comments: 0 }, milestoneId ) // Get all open issues const issues = await client.findAll(tracker.class.Issue, { space: project._id, status: { $nin: [tracker.status.Done, tracker.status.Canceled] } }) // Assign all open issues to new milestone for (const issue of issues) { await client.updateDoc( tracker.class.Issue, project._id, issue._id, { milestone: milestoneId, dueDate: targetDate } ) } console.log('Updated issues:', issues.length) } finally { await client.close() } } main().catch(console.error) ``` -------------------------------- ### Create Issue with Markdown Description in TypeScript Source: https://context7.com/hcengineering/huly-examples/llms.txt This TypeScript code snippet demonstrates how to create a new issue with a markdown description. It utilizes the '@hcengineering/api-client', '@hcengineering/core', and '@hcengineering/tracker' libraries. The process involves finding a project, generating a unique issue ID, incrementing a sequence number, uploading the markdown description, and finally creating the issue with various properties including title, description, status, number, priority, and rank. ```typescript import { ConnectOptions, NodeWebSocketFactory, connect } from '@hcengineering/api-client' import core, { type Ref, SortingOrder, generateId } from '@hcengineering/core' import { makeRank } from '@hcengineering/rank' import tracker, { type Issue, IssuePriority } from '@hcengineering/tracker' const url = process.env.HULY_URL ?? 'http://localhost:8087' const options: ConnectOptions = { email: process.env.HULY_EMAIL ?? 'user1', password: process.env.HULY_PASSWORD ?? '1234', workspace: process.env.HULY_WORKSPACE ?? 'ws1', socketFactory: NodeWebSocketFactory, connectionTimeout: 30000 } async function main() { const client = await connect(url, options) try { // Find project const project = await client.findOne( tracker.class.Project, { identifier: 'HULY' } ) if (!project) throw new Error('Project not found') // Generate unique issue ID const issueId: Ref = generateId() // Increment project sequence for issue number const incResult = await client.updateDoc( tracker.class.Project, core.space.Space, project._id, { $inc: { sequence: 1 } }, true ) const sequence = (incResult as any).object.sequence // Get last issue rank for proper ordering const lastOne = await client.findOne( tracker.class.Issue, { space: project._id }, { sort: { rank: SortingOrder.Descending } } ) // Upload markdown description const description = await client.uploadMarkup( tracker.class.Issue, issueId, 'description', `# Make coffee Do morning coffee using drip coffee maker. * Fill tank with fresh water * Put 2 scoops ground coffee * Press start button Enjoy your coffee.`, 'markdown' ) // Create issue await client.addCollection( tracker.class.Issue, project._id, project._id, project._class, 'issues', { title: 'Make coffee', description, status: project.defaultIssueStatus, number: sequence, kind: tracker.taskTypes.Issue, identifier: `${project.identifier}-${sequence}`, priority: IssuePriority.Urgent, assignee: null, component: null, estimation: 0, remainingTime: 0, reportedTime: 0, reports: 0, subIssues: 0, parents: [], childInfo: [], dueDate: null, rank: makeRank(lastOne?.rank, undefined) }, issueId ) const issue = await client.findOne(tracker.class.Issue, { _id: issueId }) if (!issue) throw new Error('Issue not found') console.log('Created issue:', issue.identifier) if (issue.description) { const markup = await client.fetchMarkup( issue._class, issue._id, 'description', issue.description, 'markdown' ) console.log(markup) } } finally { await client.close() } } main().catch(console.error) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.