Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/asana

src/models.ts

91 lines · 3.8 KB · TypeScript
import type {
	AsanaNamedRef,
	AsanaProjectSummary,
	AsanaStorySummary,
	AsanaTaskSummary,
	AsanaWorkspaceSummary,
	JsonRecord,
} from './types.ts'

export const WORKSPACE_FIELDS = 'gid,name,is_organization'
export const PROJECT_FIELDS =
	'gid,name,archived,permalink_url,notes,color,workspace.gid,workspace.name,team.gid,team.name,created_at,modified_at'
export const TASK_FIELDS =
	'gid,name,completed,permalink_url,notes,due_on,due_at,assignee.gid,assignee.name,workspace.gid,workspace.name,projects.gid,projects.name,parent.gid,parent.name,created_at,modified_at'
export const STORY_FIELDS =
	'gid,text,type,resource_subtype,created_at,created_by.gid,created_by.name'
export const VIEWER_FIELDS = 'gid,name'

export function namedRef(value: unknown): AsanaNamedRef | null {
	if (!value || typeof value !== 'object') return null
	const record = value as JsonRecord
	if (typeof record.gid !== 'string' || record.gid.length === 0) return null
	return {
		gid: record.gid,
		name: typeof record.name === 'string' ? record.name : '',
	}
}

export function mapWorkspace(value: unknown): AsanaWorkspaceSummary {
	const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
	return {
		gid: String(record.gid || ''),
		name: String(record.name || ''),
		isOrganization: typeof record.is_organization === 'boolean' ? record.is_organization : null,
	}
}

export function mapProject(value: unknown): AsanaProjectSummary {
	const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
	return {
		gid: String(record.gid || ''),
		name: String(record.name || ''),
		archived: typeof record.archived === 'boolean' ? record.archived : null,
		permalinkUrl: typeof record.permalink_url === 'string' ? record.permalink_url : null,
		notes: typeof record.notes === 'string' ? record.notes : null,
		color: typeof record.color === 'string' ? record.color : null,
		workspace: namedRef(record.workspace),
		team: namedRef(record.team),
		createdAt: typeof record.created_at === 'string' ? record.created_at : null,
		modifiedAt: typeof record.modified_at === 'string' ? record.modified_at : null,
	}
}

export function mapTask(value: unknown): AsanaTaskSummary {
	const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
	const projects = Array.isArray(record.projects)
		? record.projects.map(namedRef).filter((item): item is AsanaNamedRef => item !== null)
		: []
	return {
		gid: String(record.gid || ''),
		name: String(record.name || ''),
		completed: typeof record.completed === 'boolean' ? record.completed : null,
		permalinkUrl: typeof record.permalink_url === 'string' ? record.permalink_url : null,
		notes: typeof record.notes === 'string' ? record.notes : null,
		dueOn: typeof record.due_on === 'string' ? record.due_on : null,
		dueAt: typeof record.due_at === 'string' ? record.due_at : null,
		assignee: namedRef(record.assignee),
		workspace: namedRef(record.workspace),
		projects,
		parent: namedRef(record.parent),
		createdAt: typeof record.created_at === 'string' ? record.created_at : null,
		modifiedAt: typeof record.modified_at === 'string' ? record.modified_at : null,
	}
}

export function mapStory(value: unknown): AsanaStorySummary {
	const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
	return {
		gid: String(record.gid || ''),
		text: typeof record.text === 'string' ? record.text : null,
		type: typeof record.type === 'string' ? record.type : null,
		resourceSubtype: typeof record.resource_subtype === 'string' ? record.resource_subtype : null,
		createdAt: typeof record.created_at === 'string' ? record.created_at : null,
		createdBy: namedRef(record.created_by),
	}
}

export function asArray<T>(value: T | Array<T> | null | undefined): Array<T> {
	if (value === undefined || value === null) return []
	return Array.isArray(value) ? value : [value]
}