import { asanaRequest } from './client.ts'
import { mapProject, PROJECT_FIELDS } from './models.ts'
import type {
AsanaAuthInput,
AsanaProjectSummary,
DryRunResult,
JsonRecord,
} from './types.ts'
import {
compactRecord,
optionalBoolean,
optionalString,
requireRecord,
requireString,
} from './types.ts'
import { requireAuthMode } from './auth.ts'
export type CreateProjectInput = AsanaAuthInput & {
name: string
/** Workspace GID. Required unless `teamGid` is set. */
workspaceGid?: string
/** Team GID. Required when creating in an organization. */
teamGid?: string
notes?: string
color?: string
dueOn?: string
startOn?: string
confirm?: boolean
dryRun?: boolean
}
function projectCreatePayload(input: CreateProjectInput): JsonRecord {
const payload = compactRecord({
name: requireString(input.name, 'name'),
workspace: optionalString(input.workspaceGid, 'workspaceGid'),
team: optionalString(input.teamGid, 'teamGid'),
notes: optionalString(input.notes, 'notes'),
color: optionalString(input.color, 'color'),
due_on: optionalString(input.dueOn, 'dueOn'),
start_on: optionalString(input.startOn, 'startOn'),
})
if (!payload.workspace && !payload.team) {
throw new Error('create-project requires workspaceGid or teamGid.')
}
return payload
}
/**
* Create an Asana project. Requires `confirm: true`, or use `dryRun: true`.
* Needs `projects:write`.
* @example
* import createProject from 'kody:@kody/asana/create-project'
* const preview = await createProject({
* name: 'Launch checklist',
* workspaceGid: '123',
* dryRun: true,
* })
*/
export async function createProject(
input: CreateProjectInput,
): Promise<AsanaProjectSummary | DryRunResult<{ method: string; path: string; data: JsonRecord }>> {
const payload = projectCreatePayload(input)
if (input.dryRun) {
return { dryRun: true, wouldCall: { method: 'POST', path: '/projects', data: payload } }
}
if (input.confirm !== true) {
throw new Error(
'Creating an Asana project requires confirm: true after explicit user approval, or dryRun: true.',
)
}
const result = await asanaRequest<unknown>({
...input,
operation: 'projects.write',
method: 'POST',
path: '/projects',
query: { opt_fields: PROJECT_FIELDS },
body: payload,
})
if (!result.data) throw new Error('Asana create project did not return a project.')
return mapProject(result.data)
}
/**
* Create an Asana project. Requires `confirm: true`, or use `dryRun: true`.
* @example
* import createProject from 'kody:@kody/asana/create-project'
* const preview = await createProject({ name: 'Launch', workspaceGid: '123', dryRun: true })
*/
export default async function createProjectEntrypoint(
params: Partial<CreateProjectInput> & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'create-project')
return createProject({
name: requireString(input.name, 'name'),
workspaceGid: optionalString(input.workspaceGid, 'workspaceGid'),
teamGid: optionalString(input.teamGid, 'teamGid'),
notes: optionalString(input.notes, 'notes'),
color: optionalString(input.color, 'color'),
dueOn: optionalString(input.dueOn, 'dueOn'),
startOn: optionalString(input.startOn, 'startOn'),
integrationName: optionalString(input.integrationName, 'integrationName'),
integration: optionalString(input.integration, 'integration'),
account: optionalString(input.account, 'account'),
secretName: optionalString(input.secretName, 'secretName'),
auth: requireAuthMode(input.auth),
confirm: optionalBoolean(input.confirm, 'confirm'),
dryRun: optionalBoolean(input.dryRun, 'dryRun'),
})
}