@relayfile/adapter-linear 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,69 @@
1
+ export const LINEAR_PATH_ROOT = '/linear';
2
+
3
+ export const LINEAR_OBJECT_TYPES = ['comment', 'cycle', 'issue', 'project'] as const;
4
+
5
+ export type LinearPathObjectType = (typeof LINEAR_OBJECT_TYPES)[number];
6
+
7
+ const OBJECT_TYPE_ALIASES: Readonly<Record<string, LinearPathObjectType>> = {
8
+ comment: 'comment',
9
+ comments: 'comment',
10
+ cycle: 'cycle',
11
+ cycles: 'cycle',
12
+ issue: 'issue',
13
+ issues: 'issue',
14
+ project: 'project',
15
+ projects: 'project',
16
+ };
17
+
18
+ function assertNonEmptySegment(value: string, label: string): string {
19
+ const trimmed = value.trim();
20
+ if (!trimmed) {
21
+ throw new Error(`Linear ${label} must be a non-empty string`);
22
+ }
23
+ return trimmed;
24
+ }
25
+
26
+ export function encodeLinearPathSegment(value: string): string {
27
+ return encodeURIComponent(assertNonEmptySegment(value, 'path segment'));
28
+ }
29
+
30
+ export function normalizeLinearObjectType(objectType: string): LinearPathObjectType {
31
+ const normalized = objectType.trim().toLowerCase();
32
+ const mapped = OBJECT_TYPE_ALIASES[normalized];
33
+ if (!mapped) {
34
+ throw new Error(`Unsupported Linear object type: ${objectType}`);
35
+ }
36
+ return mapped;
37
+ }
38
+
39
+ export function linearIssuePath(issueId: string): string {
40
+ return `${LINEAR_PATH_ROOT}/issues/${encodeLinearPathSegment(issueId)}.json`;
41
+ }
42
+
43
+ export function linearCommentPath(commentId: string): string {
44
+ return `${LINEAR_PATH_ROOT}/comments/${encodeLinearPathSegment(commentId)}.json`;
45
+ }
46
+
47
+ export function linearProjectPath(projectId: string): string {
48
+ return `${LINEAR_PATH_ROOT}/projects/${encodeLinearPathSegment(projectId)}.json`;
49
+ }
50
+
51
+ export function linearCyclePath(cycleId: string): string {
52
+ return `${LINEAR_PATH_ROOT}/cycles/${encodeLinearPathSegment(cycleId)}.json`;
53
+ }
54
+
55
+ export function computeLinearPath(objectType: string, objectId: string): string {
56
+ const normalizedType = normalizeLinearObjectType(objectType);
57
+ const normalizedId = assertNonEmptySegment(objectId, 'object id');
58
+
59
+ switch (normalizedType) {
60
+ case 'issue':
61
+ return linearIssuePath(normalizedId);
62
+ case 'comment':
63
+ return linearCommentPath(normalizedId);
64
+ case 'project':
65
+ return linearProjectPath(normalizedId);
66
+ case 'cycle':
67
+ return linearCyclePath(normalizedId);
68
+ }
69
+ }
package/src/types.ts ADDED
@@ -0,0 +1,164 @@
1
+ export const LINEAR_WEBHOOK_OBJECT_TYPES = ['comment', 'cycle', 'issue', 'project'] as const;
2
+ export const LINEAR_WEBHOOK_ACTIONS = ['create', 'remove', 'update'] as const;
3
+
4
+ export type LinearWebhookObjectType = (typeof LINEAR_WEBHOOK_OBJECT_TYPES)[number];
5
+ export type LinearWebhookAction = (typeof LINEAR_WEBHOOK_ACTIONS)[number];
6
+
7
+ export type JsonPrimitive = boolean | number | null | string;
8
+ export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
9
+ export type JsonArray = JsonValue[];
10
+ export type JsonObject = { [key: string]: JsonValue };
11
+
12
+ export interface LinearAdapterConfig {
13
+ apiUrl?: string;
14
+ appName?: string;
15
+ connectionId?: string;
16
+ provider?: string;
17
+ providerConfigKey?: string;
18
+ webhookSecret?: string;
19
+ }
20
+
21
+ export interface LinearUser {
22
+ id: string;
23
+ name?: string;
24
+ displayName?: string;
25
+ email?: string;
26
+ avatarUrl?: string;
27
+ url?: string;
28
+ }
29
+
30
+ export interface LinearTeam {
31
+ id: string;
32
+ key?: string;
33
+ name?: string;
34
+ }
35
+
36
+ export interface LinearState {
37
+ id: string;
38
+ name?: string;
39
+ type?: string;
40
+ color?: string;
41
+ }
42
+
43
+ export interface LinearLabel {
44
+ id: string;
45
+ name: string;
46
+ color?: string;
47
+ }
48
+
49
+ export interface LinearProjectReference {
50
+ id: string;
51
+ name?: string;
52
+ state?: string;
53
+ url?: string;
54
+ }
55
+
56
+ export interface LinearCycleReference {
57
+ id: string;
58
+ number?: number;
59
+ name?: string;
60
+ }
61
+
62
+ export interface LinearIssueReference {
63
+ id: string;
64
+ identifier?: string;
65
+ title?: string;
66
+ url?: string;
67
+ }
68
+
69
+ export interface LinearRelation {
70
+ id?: string;
71
+ type?: string;
72
+ relatedIssueId?: string;
73
+ }
74
+
75
+ export interface LinearProject {
76
+ id: string;
77
+ name: string;
78
+ description?: string | null;
79
+ state?: string;
80
+ progress?: number | null;
81
+ targetDate?: string | null;
82
+ startedAt?: string | null;
83
+ completedAt?: string | null;
84
+ url?: string;
85
+ }
86
+
87
+ export interface LinearCycle {
88
+ id: string;
89
+ number?: number;
90
+ name?: string;
91
+ startsAt?: string | null;
92
+ endsAt?: string | null;
93
+ completedAt?: string | null;
94
+ }
95
+
96
+ export interface LinearComment {
97
+ id: string;
98
+ body?: string | null;
99
+ createdAt?: string;
100
+ updatedAt?: string;
101
+ url?: string;
102
+ user?: LinearUser | null;
103
+ issue?: LinearIssueReference | null;
104
+ }
105
+
106
+ export interface LinearIssue {
107
+ id: string;
108
+ identifier?: string;
109
+ title?: string;
110
+ description?: string | null;
111
+ priority?: number | null;
112
+ estimate?: number | null;
113
+ branchName?: string | null;
114
+ dueDate?: string | null;
115
+ createdAt?: string;
116
+ updatedAt?: string;
117
+ completedAt?: string | null;
118
+ canceledAt?: string | null;
119
+ url?: string;
120
+ state?: LinearState | null;
121
+ assignee?: LinearUser | null;
122
+ creator?: LinearUser | null;
123
+ team?: LinearTeam | null;
124
+ project?: LinearProjectReference | null;
125
+ cycle?: LinearCycleReference | null;
126
+ labels?: LinearLabel[];
127
+ parent?: LinearIssueReference | null;
128
+ children?: LinearIssueReference[];
129
+ relations?: LinearRelation[];
130
+ }
131
+
132
+ export interface LinearOrganization {
133
+ id?: string;
134
+ key?: string;
135
+ name?: string;
136
+ }
137
+
138
+ export interface LinearWebhookActor extends LinearUser {}
139
+
140
+ export interface LinearWebhookBase<TData> {
141
+ action: LinearWebhookAction | string;
142
+ type: LinearWebhookObjectType | string;
143
+ createdAt?: string;
144
+ organizationId?: string;
145
+ organization?: LinearOrganization;
146
+ url?: string;
147
+ actionBy?: LinearWebhookActor | null;
148
+ data: TData;
149
+ previousData?: Partial<TData>;
150
+ }
151
+
152
+ export type LinearPayloadRecord = Record<string, JsonValue | undefined>;
153
+
154
+ export type LinearIssueWebhookPayload = LinearWebhookBase<LinearIssue>;
155
+ export type LinearCommentWebhookPayload = LinearWebhookBase<LinearComment>;
156
+ export type LinearProjectWebhookPayload = LinearWebhookBase<LinearProject>;
157
+ export type LinearCycleWebhookPayload = LinearWebhookBase<LinearCycle>;
158
+
159
+ export type LinearWebhookPayload =
160
+ | LinearCommentWebhookPayload
161
+ | LinearCycleWebhookPayload
162
+ | LinearIssueWebhookPayload
163
+ | LinearProjectWebhookPayload
164
+ | LinearWebhookBase<LinearPayloadRecord>;