@checkstack/integration-jira-common 0.0.2
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.
- package/CHANGELOG.md +23 -0
- package/package.json +22 -0
- package/src/index.ts +30 -0
- package/src/plugin-metadata.ts +5 -0
- package/src/rpc-contract.ts +151 -0
- package/src/schemas.ts +176 -0
- package/tsconfig.json +6 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @checkstack/integration-jira-common
|
|
2
|
+
|
|
3
|
+
## 0.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d20d274: Initial release of all @checkstack packages. Rebranded from Checkmate to Checkstack with new npm organization @checkstack and domain checkstack.dev.
|
|
8
|
+
- Updated dependencies [d20d274]
|
|
9
|
+
- @checkstack/common@0.0.2
|
|
10
|
+
|
|
11
|
+
## 0.0.3
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [a65e002]
|
|
16
|
+
- @checkstack/common@0.2.0
|
|
17
|
+
|
|
18
|
+
## 0.0.2
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [ffc28f6]
|
|
23
|
+
- @checkstack/common@0.1.0
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@checkstack/integration-jira-common",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"typecheck": "tsc --noEmit",
|
|
8
|
+
"lint": "bun run lint:code",
|
|
9
|
+
"lint:code": "eslint . --max-warnings 0"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@checkstack/common": "workspace:*",
|
|
13
|
+
"@orpc/contract": "^1.13.2",
|
|
14
|
+
"zod": "^4.2.1"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/bun": "^1.0.0",
|
|
18
|
+
"typescript": "^5.0.0",
|
|
19
|
+
"@checkstack/tsconfig": "workspace:*",
|
|
20
|
+
"@checkstack/scripts": "workspace:*"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Plugin Metadata
|
|
2
|
+
export { pluginMetadata } from "./plugin-metadata";
|
|
3
|
+
|
|
4
|
+
// Schemas
|
|
5
|
+
export {
|
|
6
|
+
// Legacy connection schemas (deprecated - use generic connection management)
|
|
7
|
+
JiraConnectionSchema,
|
|
8
|
+
type JiraConnection,
|
|
9
|
+
CreateJiraConnectionInputSchema,
|
|
10
|
+
type CreateJiraConnectionInput,
|
|
11
|
+
UpdateJiraConnectionInputSchema,
|
|
12
|
+
type UpdateJiraConnectionInput,
|
|
13
|
+
JiraConnectionRedactedSchema,
|
|
14
|
+
type JiraConnectionRedacted,
|
|
15
|
+
// API response schemas
|
|
16
|
+
JiraProjectSchema,
|
|
17
|
+
type JiraProject,
|
|
18
|
+
JiraIssueTypeSchema,
|
|
19
|
+
type JiraIssueType,
|
|
20
|
+
JiraFieldSchema,
|
|
21
|
+
type JiraField,
|
|
22
|
+
// Subscription config schemas
|
|
23
|
+
JiraFieldMappingSchema,
|
|
24
|
+
type JiraFieldMapping,
|
|
25
|
+
JiraSubscriptionConfigSchema,
|
|
26
|
+
type JiraSubscriptionConfig,
|
|
27
|
+
} from "./schemas";
|
|
28
|
+
|
|
29
|
+
// RPC Contract
|
|
30
|
+
export { jiraContract, JiraApi, type JiraContract } from "./rpc-contract";
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { oc } from "@orpc/contract";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { pluginMetadata } from "./plugin-metadata";
|
|
4
|
+
import {
|
|
5
|
+
createClientDefinition,
|
|
6
|
+
type ProcedureMetadata,
|
|
7
|
+
} from "@checkstack/common";
|
|
8
|
+
import {
|
|
9
|
+
JiraConnectionRedactedSchema,
|
|
10
|
+
CreateJiraConnectionInputSchema,
|
|
11
|
+
UpdateJiraConnectionInputSchema,
|
|
12
|
+
JiraProjectSchema,
|
|
13
|
+
JiraIssueTypeSchema,
|
|
14
|
+
JiraFieldSchema,
|
|
15
|
+
} from "./schemas";
|
|
16
|
+
|
|
17
|
+
// Base builder with full metadata support
|
|
18
|
+
const _base = oc.$meta<ProcedureMetadata>({});
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* RPC contract for Jira-specific operations.
|
|
22
|
+
* These endpoints are in addition to the generic integration endpoints.
|
|
23
|
+
*/
|
|
24
|
+
export const jiraContract = {
|
|
25
|
+
// ==========================================================================
|
|
26
|
+
// CONNECTION MANAGEMENT (Site-wide Jira configurations)
|
|
27
|
+
// ==========================================================================
|
|
28
|
+
|
|
29
|
+
/** List all Jira connections (redacted - no API tokens) */
|
|
30
|
+
listConnections: _base
|
|
31
|
+
.meta({
|
|
32
|
+
userType: "user",
|
|
33
|
+
permissions: ["integration.manage"],
|
|
34
|
+
})
|
|
35
|
+
.output(z.array(JiraConnectionRedactedSchema)),
|
|
36
|
+
|
|
37
|
+
/** Get a single connection (redacted) */
|
|
38
|
+
getConnection: _base
|
|
39
|
+
.meta({
|
|
40
|
+
userType: "user",
|
|
41
|
+
permissions: ["integration.manage"],
|
|
42
|
+
})
|
|
43
|
+
.input(z.object({ id: z.string() }))
|
|
44
|
+
.output(JiraConnectionRedactedSchema),
|
|
45
|
+
|
|
46
|
+
/** Create a new Jira connection */
|
|
47
|
+
createConnection: _base
|
|
48
|
+
.meta({
|
|
49
|
+
userType: "user",
|
|
50
|
+
permissions: ["integration.manage"],
|
|
51
|
+
})
|
|
52
|
+
.input(CreateJiraConnectionInputSchema)
|
|
53
|
+
.output(JiraConnectionRedactedSchema),
|
|
54
|
+
|
|
55
|
+
/** Update a Jira connection */
|
|
56
|
+
updateConnection: _base
|
|
57
|
+
.meta({
|
|
58
|
+
userType: "user",
|
|
59
|
+
permissions: ["integration.manage"],
|
|
60
|
+
})
|
|
61
|
+
.input(UpdateJiraConnectionInputSchema)
|
|
62
|
+
.output(JiraConnectionRedactedSchema),
|
|
63
|
+
|
|
64
|
+
/** Delete a Jira connection */
|
|
65
|
+
deleteConnection: _base
|
|
66
|
+
.meta({
|
|
67
|
+
userType: "user",
|
|
68
|
+
permissions: ["integration.manage"],
|
|
69
|
+
})
|
|
70
|
+
.input(z.object({ id: z.string() }))
|
|
71
|
+
.output(z.object({ success: z.boolean() })),
|
|
72
|
+
|
|
73
|
+
/** Test a Jira connection */
|
|
74
|
+
testConnection: _base
|
|
75
|
+
.meta({
|
|
76
|
+
userType: "user",
|
|
77
|
+
permissions: ["integration.manage"],
|
|
78
|
+
})
|
|
79
|
+
.input(z.object({ id: z.string() }))
|
|
80
|
+
.output(
|
|
81
|
+
z.object({
|
|
82
|
+
success: z.boolean(),
|
|
83
|
+
message: z.string().optional(),
|
|
84
|
+
})
|
|
85
|
+
),
|
|
86
|
+
|
|
87
|
+
// ==========================================================================
|
|
88
|
+
// JIRA API PROXIES (Fetch data from Jira using a connection)
|
|
89
|
+
// ==========================================================================
|
|
90
|
+
|
|
91
|
+
/** Get projects available in a Jira connection */
|
|
92
|
+
getProjects: _base
|
|
93
|
+
.meta({
|
|
94
|
+
userType: "user",
|
|
95
|
+
permissions: ["integration.manage"],
|
|
96
|
+
})
|
|
97
|
+
.input(z.object({ connectionId: z.string() }))
|
|
98
|
+
.output(z.array(JiraProjectSchema)),
|
|
99
|
+
|
|
100
|
+
/** Get issue types available for a project */
|
|
101
|
+
getIssueTypes: _base
|
|
102
|
+
.meta({
|
|
103
|
+
userType: "user",
|
|
104
|
+
permissions: ["integration.manage"],
|
|
105
|
+
})
|
|
106
|
+
.input(
|
|
107
|
+
z.object({
|
|
108
|
+
connectionId: z.string(),
|
|
109
|
+
projectKey: z.string(),
|
|
110
|
+
})
|
|
111
|
+
)
|
|
112
|
+
.output(z.array(JiraIssueTypeSchema)),
|
|
113
|
+
|
|
114
|
+
/** Get fields available for a project and issue type */
|
|
115
|
+
getFields: _base
|
|
116
|
+
.meta({
|
|
117
|
+
userType: "user",
|
|
118
|
+
permissions: ["integration.manage"],
|
|
119
|
+
})
|
|
120
|
+
.input(
|
|
121
|
+
z.object({
|
|
122
|
+
connectionId: z.string(),
|
|
123
|
+
projectKey: z.string(),
|
|
124
|
+
issueTypeId: z.string(),
|
|
125
|
+
})
|
|
126
|
+
)
|
|
127
|
+
.output(z.array(JiraFieldSchema)),
|
|
128
|
+
|
|
129
|
+
/** Get priorities available in Jira */
|
|
130
|
+
getPriorities: _base
|
|
131
|
+
.meta({
|
|
132
|
+
userType: "user",
|
|
133
|
+
permissions: ["integration.manage"],
|
|
134
|
+
})
|
|
135
|
+
.input(z.object({ connectionId: z.string() }))
|
|
136
|
+
.output(
|
|
137
|
+
z.array(
|
|
138
|
+
z.object({
|
|
139
|
+
id: z.string(),
|
|
140
|
+
name: z.string(),
|
|
141
|
+
iconUrl: z.string().optional(),
|
|
142
|
+
})
|
|
143
|
+
)
|
|
144
|
+
),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Export contract type
|
|
148
|
+
export type JiraContract = typeof jiraContract;
|
|
149
|
+
|
|
150
|
+
// Export client definition for type-safe forPlugin usage
|
|
151
|
+
export const JiraApi = createClientDefinition(jiraContract, pluginMetadata);
|
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Jira Connection (Site-wide Configuration) - DEPRECATED
|
|
5
|
+
// Use the generic connection management system instead.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Schema for a Jira Cloud connection configuration.
|
|
10
|
+
* @deprecated Use generic connection management with JiraConnectionConfigSchema from jira-backend.
|
|
11
|
+
*/
|
|
12
|
+
export const JiraConnectionSchema = z.object({
|
|
13
|
+
/** Unique identifier for this connection */
|
|
14
|
+
id: z.string(),
|
|
15
|
+
/** User-friendly name for the connection */
|
|
16
|
+
name: z.string().min(1).max(100).describe("Connection name"),
|
|
17
|
+
/** Jira Cloud base URL (e.g., https://yourcompany.atlassian.net) */
|
|
18
|
+
baseUrl: z.string().url().describe("Jira Cloud base URL"),
|
|
19
|
+
/** Email address for authentication */
|
|
20
|
+
email: z.string().email().describe("Jira user email"),
|
|
21
|
+
/** API token - will be marked as secret in backend */
|
|
22
|
+
apiToken: z.string().min(1).describe("Jira API token"),
|
|
23
|
+
/** Created timestamp */
|
|
24
|
+
createdAt: z.coerce.date(),
|
|
25
|
+
/** Updated timestamp */
|
|
26
|
+
updatedAt: z.coerce.date(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export type JiraConnection = z.infer<typeof JiraConnectionSchema>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Input for creating a new Jira connection.
|
|
33
|
+
*/
|
|
34
|
+
export const CreateJiraConnectionInputSchema = z.object({
|
|
35
|
+
name: z.string().min(1).max(100),
|
|
36
|
+
baseUrl: z.string().url(),
|
|
37
|
+
email: z.string().email(),
|
|
38
|
+
apiToken: z.string().min(1),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export type CreateJiraConnectionInput = z.infer<
|
|
42
|
+
typeof CreateJiraConnectionInputSchema
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Input for updating a Jira connection.
|
|
47
|
+
* API token is optional - if not provided, existing token is preserved.
|
|
48
|
+
*/
|
|
49
|
+
export const UpdateJiraConnectionInputSchema = z.object({
|
|
50
|
+
id: z.string(),
|
|
51
|
+
updates: z.object({
|
|
52
|
+
name: z.string().min(1).max(100).optional(),
|
|
53
|
+
baseUrl: z.string().url().optional(),
|
|
54
|
+
email: z.string().email().optional(),
|
|
55
|
+
/** If provided, replaces the existing token */
|
|
56
|
+
apiToken: z.string().min(1).optional(),
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export type UpdateJiraConnectionInput = z.infer<
|
|
61
|
+
typeof UpdateJiraConnectionInputSchema
|
|
62
|
+
>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Redacted connection for frontend display (no API token).
|
|
66
|
+
*/
|
|
67
|
+
export const JiraConnectionRedactedSchema = JiraConnectionSchema.omit({
|
|
68
|
+
apiToken: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export type JiraConnectionRedacted = z.infer<
|
|
72
|
+
typeof JiraConnectionRedactedSchema
|
|
73
|
+
>;
|
|
74
|
+
|
|
75
|
+
// =============================================================================
|
|
76
|
+
// Jira API Response Types
|
|
77
|
+
// =============================================================================
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Jira project from the API.
|
|
81
|
+
*/
|
|
82
|
+
export const JiraProjectSchema = z.object({
|
|
83
|
+
id: z.string(),
|
|
84
|
+
key: z.string(),
|
|
85
|
+
name: z.string(),
|
|
86
|
+
avatarUrls: z.record(z.string(), z.string()).optional(),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
export type JiraProject = z.infer<typeof JiraProjectSchema>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Jira issue type from the API.
|
|
93
|
+
*/
|
|
94
|
+
export const JiraIssueTypeSchema = z.object({
|
|
95
|
+
id: z.string(),
|
|
96
|
+
name: z.string(),
|
|
97
|
+
description: z.string().optional(),
|
|
98
|
+
iconUrl: z.string().optional(),
|
|
99
|
+
subtask: z.boolean(),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export type JiraIssueType = z.infer<typeof JiraIssueTypeSchema>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Jira field metadata from the API.
|
|
106
|
+
*/
|
|
107
|
+
export const JiraFieldSchema = z.object({
|
|
108
|
+
key: z.string(),
|
|
109
|
+
name: z.string(),
|
|
110
|
+
required: z.boolean(),
|
|
111
|
+
schema: z
|
|
112
|
+
.object({
|
|
113
|
+
type: z.string(),
|
|
114
|
+
system: z.string().optional(),
|
|
115
|
+
custom: z.string().optional(),
|
|
116
|
+
customId: z.number().optional(),
|
|
117
|
+
})
|
|
118
|
+
.optional(),
|
|
119
|
+
allowedValues: z
|
|
120
|
+
.array(
|
|
121
|
+
z.object({
|
|
122
|
+
id: z.string(),
|
|
123
|
+
name: z.string().optional(),
|
|
124
|
+
value: z.string().optional(),
|
|
125
|
+
})
|
|
126
|
+
)
|
|
127
|
+
.optional(),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
export type JiraField = z.infer<typeof JiraFieldSchema>;
|
|
131
|
+
|
|
132
|
+
// =============================================================================
|
|
133
|
+
// Jira Subscription Configuration (Per-subscription)
|
|
134
|
+
// =============================================================================
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Field mapping for template-based value population.
|
|
138
|
+
*/
|
|
139
|
+
export const JiraFieldMappingSchema = z.object({
|
|
140
|
+
/** Jira field key */
|
|
141
|
+
fieldKey: z.string(),
|
|
142
|
+
/** Template string with {{payload.property}} placeholders */
|
|
143
|
+
template: z.string(),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
export type JiraFieldMapping = z.infer<typeof JiraFieldMappingSchema>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Provider configuration for Jira subscriptions.
|
|
150
|
+
*/
|
|
151
|
+
export const JiraSubscriptionConfigSchema = z.object({
|
|
152
|
+
/** ID of the site-wide Jira connection to use */
|
|
153
|
+
connectionId: z.string().describe("Jira connection to use"),
|
|
154
|
+
/** Jira project key to create issues in */
|
|
155
|
+
projectKey: z.string().describe("Project key"),
|
|
156
|
+
/** Issue type ID for created issues */
|
|
157
|
+
issueTypeId: z.string().describe("Issue type"),
|
|
158
|
+
/** Summary template (required - uses {{payload.field}} syntax) */
|
|
159
|
+
summaryTemplate: z.string().min(1).describe("Issue summary template"),
|
|
160
|
+
/** Description template (optional) */
|
|
161
|
+
descriptionTemplate: z
|
|
162
|
+
.string()
|
|
163
|
+
.optional()
|
|
164
|
+
.describe("Issue description template"),
|
|
165
|
+
/** Priority ID (optional) */
|
|
166
|
+
priorityId: z.string().optional().describe("Priority"),
|
|
167
|
+
/** Additional field mappings */
|
|
168
|
+
fieldMappings: z
|
|
169
|
+
.array(JiraFieldMappingSchema)
|
|
170
|
+
.optional()
|
|
171
|
+
.describe("Additional field mappings"),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
export type JiraSubscriptionConfig = z.infer<
|
|
175
|
+
typeof JiraSubscriptionConfigSchema
|
|
176
|
+
>;
|