orizu 0.0.8 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,115 @@
1
+ export interface TaskCreateErrorPayload {
2
+ error?: string
3
+ invalidAssigneeErrors?: Array<{
4
+ assignee?: string
5
+ reason?: string
6
+ }>
7
+ missingRequiredFields?: string[]
8
+ incompatibleRowCount?: number
9
+ missingRequiredFieldCounts?: Record<string, number>
10
+ versionId?: string
11
+ versionNum?: number
12
+ }
13
+
14
+ export interface CliErrorWithStatus extends Error {
15
+ httpStatus?: number
16
+ structuredPayload?: Record<string, unknown>
17
+ }
18
+
19
+ function createCliError(
20
+ message: string,
21
+ httpStatus?: number,
22
+ structuredPayload?: Record<string, unknown>
23
+ ): CliErrorWithStatus {
24
+ const error = new Error(message) as CliErrorWithStatus
25
+ error.httpStatus = httpStatus
26
+ error.structuredPayload = structuredPayload
27
+ return error
28
+ }
29
+
30
+ export async function formatTaskCreateError(response: Response): Promise<CliErrorWithStatus> {
31
+ const contentType = response.headers.get('content-type') || ''
32
+ const rawBody = await response.text()
33
+ const httpStatus = response.status
34
+ let parsedPayload: Record<string, unknown> | undefined
35
+
36
+ if (!contentType.includes('application/json')) {
37
+ return createCliError(`Failed to create task: ${rawBody}`, httpStatus)
38
+ }
39
+
40
+ try {
41
+ const payload = JSON.parse(rawBody) as TaskCreateErrorPayload
42
+ parsedPayload = payload as unknown as Record<string, unknown>
43
+
44
+ if (
45
+ Array.isArray(payload.invalidAssigneeErrors) &&
46
+ payload.invalidAssigneeErrors.length > 0
47
+ ) {
48
+ const details = payload.invalidAssigneeErrors
49
+ .filter(
50
+ item =>
51
+ typeof item.assignee === 'string' &&
52
+ item.assignee.length > 0 &&
53
+ typeof item.reason === 'string' &&
54
+ item.reason.length > 0
55
+ )
56
+ .map(item => ` - ${item.assignee}: ${item.reason}`)
57
+ .join('\n')
58
+
59
+ if (details) {
60
+ return createCliError(
61
+ `Failed to create task: ${payload.error || 'Invalid assignees'}\n${details}`,
62
+ httpStatus,
63
+ parsedPayload
64
+ )
65
+ }
66
+ }
67
+
68
+ if (
69
+ Array.isArray(payload.missingRequiredFields) &&
70
+ payload.missingRequiredFields.length > 0
71
+ ) {
72
+ const lines: string[] = [
73
+ `Failed to create task: ${payload.error || 'Dataset incompatible'}`,
74
+ ]
75
+
76
+ if (payload.versionNum !== undefined) {
77
+ lines.push(` Version: v${payload.versionNum} (${payload.versionId || 'unknown'})`)
78
+ }
79
+
80
+ lines.push(` Missing required fields: ${payload.missingRequiredFields.join(', ')}`)
81
+
82
+ if (typeof payload.incompatibleRowCount === 'number') {
83
+ lines.push(` Incompatible rows: ${payload.incompatibleRowCount}`)
84
+ }
85
+
86
+ if (
87
+ payload.missingRequiredFieldCounts &&
88
+ Object.keys(payload.missingRequiredFieldCounts).length > 0
89
+ ) {
90
+ const fieldCounts = Object.entries(payload.missingRequiredFieldCounts)
91
+ .map(([field, count]) => ` ${field}: ${count} rows`)
92
+ .join('\n')
93
+ lines.push(` Missing field counts:\n${fieldCounts}`)
94
+ }
95
+
96
+ return createCliError(
97
+ lines.join('\n'),
98
+ httpStatus,
99
+ parsedPayload
100
+ )
101
+ }
102
+
103
+ if (typeof payload.error === 'string' && payload.error.length > 0) {
104
+ return createCliError(
105
+ `Failed to create task: ${payload.error}`,
106
+ httpStatus,
107
+ parsedPayload
108
+ )
109
+ }
110
+ } catch {
111
+ return createCliError(`Failed to create task: ${rawBody}`, httpStatus)
112
+ }
113
+
114
+ return createCliError(`Failed to create task: ${rawBody}`, httpStatus, parsedPayload)
115
+ }