@automate.ax/api-contract 0.76.0 → 0.77.1

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/src/account.ts CHANGED
@@ -1,9 +1,87 @@
1
1
  import { oc } from "@orpc/contract"
2
2
  import * as z from "zod"
3
+ import { cursorPageOutputSchema, cursorPaginationInputSchema } from "./schemas"
3
4
 
4
- export const integrationAccountOutputSchema = z.object({
5
+ const INTEGRATION_FORM_FIELD_SCHEMA = z.discriminatedUnion("input", [
6
+ z.object({
7
+ default: z.boolean().optional(),
8
+ description: z.string().optional(),
9
+ input: z.literal("boolean"),
10
+ label: z.string(),
11
+ name: z.string(),
12
+ required: z.boolean(),
13
+ }),
14
+ z.object({
15
+ default: z.number().optional(),
16
+ description: z.string().optional(),
17
+ input: z.literal("number"),
18
+ label: z.string(),
19
+ name: z.string(),
20
+ placeholder: z.string().optional(),
21
+ required: z.boolean(),
22
+ }),
23
+ z.object({
24
+ description: z.string().optional(),
25
+ input: z.literal("password"),
26
+ label: z.string(),
27
+ name: z.string(),
28
+ placeholder: z.string().optional(),
29
+ required: z.boolean(),
30
+ }),
31
+ z.object({
32
+ default: z.string().optional(),
33
+ description: z.string().optional(),
34
+ input: z.enum(["email", "text", "url"]),
35
+ label: z.string(),
36
+ name: z.string(),
37
+ placeholder: z.string().optional(),
38
+ required: z.boolean(),
39
+ }),
40
+ ])
41
+
42
+ export const integrationServiceOutputSchema = z.object({
43
+ connectionMethods: z
44
+ .discriminatedUnion("type", [
45
+ z.object({
46
+ description: z.string().optional(),
47
+ id: z.string(),
48
+ name: z.string(),
49
+ type: z.literal("redirect"),
50
+ }),
51
+ z.object({
52
+ description: z.string().optional(),
53
+ fields: INTEGRATION_FORM_FIELD_SCHEMA.array(),
54
+ id: z.string(),
55
+ name: z.string(),
56
+ type: z.literal("form"),
57
+ }),
58
+ ])
59
+ .array(),
60
+ connectionNotice: z
61
+ .object({
62
+ action: z.object({ href: z.string(), label: z.string() }),
63
+ description: z.string(),
64
+ title: z.string(),
65
+ })
66
+ .optional(),
67
+ description: z.string().optional(),
68
+ icon: z.string().optional(),
69
+ id: z.string(),
70
+ name: z.string(),
71
+ preferredConnectionMethodId: z.string().optional(),
72
+ })
73
+
74
+ export const integrationAccountRevocationOutputSchema = z.object({
75
+ completedAt: z.date().nullable(),
76
+ error: z.string().nullable(),
77
+ id: z.string(),
78
+ requestedAt: z.date(),
79
+ status: z.enum(["pending", "succeeded", "failed", "unsupported"]),
80
+ })
81
+
82
+ export const integrationAccountBindingOutputSchema = z.object({
5
83
  checkedAt: z.date().nullable(),
6
- connectionId: z.string().min(1),
84
+ connectionMethodId: z.string().min(1),
7
85
  error: z
8
86
  .object({
9
87
  code: z.string(),
@@ -17,11 +95,90 @@ export const integrationAccountOutputSchema = z.object({
17
95
  serviceSub: z.string(),
18
96
  })
19
97
 
98
+ export const integrationAccountOutputSchema =
99
+ integrationAccountBindingOutputSchema.extend({
100
+ revokedAt: z.date().nullable(),
101
+ revocation: integrationAccountRevocationOutputSchema.nullable(),
102
+ status: z.enum([
103
+ "active",
104
+ "revocation_pending",
105
+ "revocation_failed",
106
+ "revoked",
107
+ ]),
108
+ })
109
+
110
+ export const integrationAccountRevocationImpactOutputSchema = z.object({
111
+ accessibleOrganizations: z
112
+ .object({
113
+ id: z.string(),
114
+ name: z.string(),
115
+ projects: z
116
+ .object({
117
+ automations: z
118
+ .object({
119
+ enabled: z.boolean(),
120
+ id: z.string(),
121
+ identityKey: z.string(),
122
+ })
123
+ .array(),
124
+ id: z.string(),
125
+ name: z.string(),
126
+ pendingDeployments: z
127
+ .object({
128
+ id: z.string(),
129
+ status: z.enum([
130
+ "awaiting_authorization",
131
+ "configuring",
132
+ "publishing",
133
+ ]),
134
+ })
135
+ .array(),
136
+ })
137
+ .array(),
138
+ })
139
+ .array(),
140
+ account: integrationAccountOutputSchema
141
+ .pick({
142
+ id: true,
143
+ label: true,
144
+ revokedAt: true,
145
+ revocation: true,
146
+ serviceId: true,
147
+ serviceSub: true,
148
+ status: true,
149
+ })
150
+ .extend({
151
+ connectionMethodId: z.string(),
152
+ providerRevocationSupported: z.boolean(),
153
+ }),
154
+ hiddenOrganizationCount: z.number().int().nonnegative(),
155
+ totals: z.object({
156
+ automations: z.number().int().nonnegative(),
157
+ organizations: z.number().int().positive(),
158
+ pendingDeployments: z.number().int().nonnegative(),
159
+ projects: z.number().int().nonnegative(),
160
+ }),
161
+ })
162
+
163
+ const organizationAccountInputSchema = z.object({
164
+ accountId: z.string(),
165
+ organizationId: z.string(),
166
+ })
167
+
20
168
  export const accountContract = {
21
169
  beginConnection: oc
170
+ .route({
171
+ description: "Starts an OAuth-style organization account connection.",
172
+ method: "POST",
173
+ operationId: "beginIntegrationAccountConnection",
174
+ path: "/organizations/{organizationId}/integration-account-connections",
175
+ successStatus: 201,
176
+ summary: "Begin integration account connection",
177
+ tags: ["Integration Accounts"],
178
+ })
22
179
  .input(
23
180
  z.object({
24
- connectionId: z.string().min(1),
181
+ connectionMethodId: z.string().min(1),
25
182
  organizationId: z.string(),
26
183
  scopes: z.string().array().default([]),
27
184
  serviceId: z.string().min(1),
@@ -29,6 +186,14 @@ export const accountContract = {
29
186
  )
30
187
  .output(z.object({ flowId: z.string(), url: z.url() })),
31
188
  connectionStatus: oc
189
+ .route({
190
+ description: "Returns the current state of a redirect connection flow.",
191
+ method: "GET",
192
+ operationId: "getIntegrationAccountConnection",
193
+ path: "/organizations/{organizationId}/integration-account-connections/{flowId}",
194
+ summary: "Get integration account connection",
195
+ tags: ["Integration Accounts"],
196
+ })
32
197
  .input(
33
198
  z.object({
34
199
  flowId: z.string(),
@@ -38,27 +203,107 @@ export const accountContract = {
38
203
  .output(
39
204
  z.discriminatedUnion("status", [
40
205
  z.object({ status: z.literal("pending") }),
41
- z.object({ status: z.literal("succeeded") }),
206
+ z.object({
207
+ accountId: z.string().nullable(),
208
+ status: z.literal("succeeded"),
209
+ }),
42
210
  z.object({ message: z.string(), status: z.literal("failed") }),
43
211
  ]),
44
212
  ),
45
- delete: oc
46
- .input(
213
+ disconnect: oc
214
+ .route({
215
+ description:
216
+ "Removes an integration account from one organization without revoking it elsewhere.",
217
+ method: "DELETE",
218
+ operationId: "disconnectIntegrationAccount",
219
+ path: "/organizations/{organizationId}/integration-accounts/{accountId}",
220
+ summary: "Disconnect integration account",
221
+ tags: ["Integration Accounts"],
222
+ })
223
+ .input(organizationAccountInputSchema)
224
+ .output(z.object({ txid: z.number().int().nonnegative() })),
225
+ get: oc
226
+ .route({
227
+ description: "Returns one integration account linked to an organization.",
228
+ method: "GET",
229
+ operationId: "getIntegrationAccount",
230
+ path: "/organizations/{organizationId}/integration-accounts/{accountId}",
231
+ summary: "Get integration account",
232
+ tags: ["Integration Accounts"],
233
+ })
234
+ .input(organizationAccountInputSchema)
235
+ .output(integrationAccountOutputSchema),
236
+ list: oc
237
+ .route({
238
+ description: "Lists integration accounts linked to an organization.",
239
+ method: "GET",
240
+ operationId: "listIntegrationAccounts",
241
+ path: "/organizations/{organizationId}/integration-accounts",
242
+ summary: "List integration accounts",
243
+ tags: ["Integration Accounts"],
244
+ })
245
+ .input(cursorPaginationInputSchema.extend({ organizationId: z.string() }))
246
+ .output(
247
+ cursorPageOutputSchema(
248
+ integrationAccountOutputSchema.extend({ createdAt: z.date() }),
249
+ ),
250
+ ),
251
+ listServices: oc
252
+ .route({
253
+ description:
254
+ "Lists enabled integration services and their connection methods.",
255
+ method: "GET",
256
+ operationId: "listIntegrationServices",
257
+ path: "/integration-services",
258
+ summary: "List integration services",
259
+ tags: ["Integration Accounts"],
260
+ })
261
+ .input(z.object({}).default({}))
262
+ .output(integrationServiceOutputSchema.array()),
263
+ revocationImpact: oc
264
+ .route({
265
+ description:
266
+ "Previews platform-wide revocation while redacting inaccessible organizations.",
267
+ method: "GET",
268
+ operationId: "getIntegrationAccountRevocationImpact",
269
+ path: "/organizations/{organizationId}/integration-accounts/{accountId}/revocation-impact",
270
+ summary: "Preview integration account revocation",
271
+ tags: ["Integration Accounts"],
272
+ })
273
+ .input(organizationAccountInputSchema)
274
+ .output(integrationAccountRevocationImpactOutputSchema),
275
+ revoke: oc
276
+ .route({
277
+ description:
278
+ "Immediately blocks and globally revokes a shared integration account.",
279
+ method: "POST",
280
+ operationId: "revokeIntegrationAccount",
281
+ path: "/organizations/{organizationId}/integration-accounts/{accountId}/revoke",
282
+ successStatus: 202,
283
+ summary: "Revoke integration account",
284
+ tags: ["Integration Accounts"],
285
+ })
286
+ .input(organizationAccountInputSchema)
287
+ .output(
47
288
  z.object({
48
- accountId: z.string(),
49
- organizationId: z.string(),
289
+ revocation: integrationAccountRevocationOutputSchema,
290
+ txid: z.number().int().nonnegative(),
50
291
  }),
51
- )
52
- .output(z.object({ txid: z.number().int().nonnegative() })),
53
- get: oc.input(z.object({ organizationId: z.string() })).output(
54
- z.object({
55
- accounts: integrationAccountOutputSchema.array(),
56
- }),
57
- ),
292
+ ),
58
293
  submitCredentials: oc
294
+ .route({
295
+ description:
296
+ "Validates secret form credentials and links the resulting account.",
297
+ method: "POST",
298
+ operationId: "connectIntegrationAccountCredentials",
299
+ path: "/organizations/{organizationId}/integration-account-credentials",
300
+ successStatus: 201,
301
+ summary: "Connect integration account credentials",
302
+ tags: ["Integration Accounts"],
303
+ })
59
304
  .input(
60
305
  z.object({
61
- connectionId: z.string().min(1),
306
+ connectionMethodId: z.string().min(1),
62
307
  data: z.record(
63
308
  z.string(),
64
309
  z.union([z.string(), z.number(), z.boolean()]),
@@ -67,5 +312,5 @@ export const accountContract = {
67
312
  serviceId: z.string().min(1),
68
313
  }),
69
314
  )
70
- .output(z.void()),
315
+ .output(z.object({ accountId: z.string() })),
71
316
  }
package/src/api-key.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { oc } from "@orpc/contract"
2
2
  import * as z from "zod"
3
- import { reasonableNameSchema } from "./schemas"
3
+ import {
4
+ cursorPageOutputSchema,
5
+ cursorPaginationInputSchema,
6
+ reasonableNameSchema,
7
+ } from "./schemas"
4
8
 
5
9
  export const organizationApiKeyOutputSchema = z.object({
6
10
  id: z.string(),
@@ -59,8 +63,8 @@ export const apiKeyContract = {
59
63
  "Lists API keys owned by an organization. Requires apiKey:read.",
60
64
  tags: ["API Keys"],
61
65
  })
62
- .input(z.object({ organizationId: z.string() }))
63
- .output(organizationApiKeyOutputSchema.array()),
66
+ .input(cursorPaginationInputSchema.extend({ organizationId: z.string() }))
67
+ .output(cursorPageOutputSchema(organizationApiKeyOutputSchema)),
64
68
  update: oc
65
69
  .route({
66
70
  method: "PATCH",
@@ -22,7 +22,7 @@ export const authorizationContract = {
22
22
  .input(
23
23
  z.object({
24
24
  binding: z.string().min(1),
25
- connectionId: z.string().min(1),
25
+ connectionMethodId: z.string().min(1),
26
26
  deploymentId: z.string(),
27
27
  serviceId: z.string().min(1),
28
28
  }),
@@ -47,6 +47,15 @@ export const authorizationContract = {
47
47
  }),
48
48
  ),
49
49
  get: oc
50
+ .route({
51
+ method: "GET",
52
+ path: "/deployments/{deploymentId}/authorization",
53
+ operationId: "getDeploymentAuthorization",
54
+ summary: "Get deployment authorization",
55
+ description:
56
+ "Returns connected accounts and the authorization requirements for a deployment.",
57
+ tags: ["Deployments"],
58
+ })
50
59
  .input(
51
60
  z.object({
52
61
  deploymentId: z.string(),
@@ -57,7 +66,7 @@ export const authorizationContract = {
57
66
  accounts: z
58
67
  .object({
59
68
  checkedAt: z.date().nullable(),
60
- connectionId: z.string().min(1),
69
+ connectionMethodId: z.string().min(1),
61
70
  error: z
62
71
  .object({
63
72
  code: z.string(),
@@ -77,7 +86,7 @@ export const authorizationContract = {
77
86
  binding: z.string(),
78
87
  connections: z
79
88
  .object({
80
- connectionId: z.string().min(1),
89
+ connectionMethodId: z.string().min(1),
81
90
  minimalScopes: z.string().array(),
82
91
  requiredScopes: SCOPE_REQUIREMENT_SCHEMA.array(),
83
92
  })
@@ -91,13 +100,22 @@ export const authorizationContract = {
91
100
  }),
92
101
  ),
93
102
  proceed: oc
103
+ .route({
104
+ method: "POST",
105
+ path: "/deployments/{deploymentId}/authorization/proceed",
106
+ operationId: "proceedWithDeploymentAuthorization",
107
+ summary: "Proceed with deployment authorization",
108
+ description:
109
+ "Continues a deployment after every integration requirement is satisfied.",
110
+ tags: ["Deployments"],
111
+ })
94
112
  .input(z.object({ deploymentId: z.string() }))
95
113
  .output(z.object({ txid: z.number().int().nonnegative() })),
96
114
  submitCredentials: oc
97
115
  .input(
98
116
  z.object({
99
117
  binding: z.string().min(1),
100
- connectionId: z.string().min(1),
118
+ connectionMethodId: z.string().min(1),
101
119
  data: z.record(
102
120
  z.string(),
103
121
  z.union([z.string(), z.number(), z.boolean()]),
package/src/automation.ts CHANGED
@@ -1,24 +1,81 @@
1
1
  import { encodableSchema } from "@automate.ax/codec"
2
2
  import { oc } from "@orpc/contract"
3
3
  import * as z from "zod"
4
+ import { integrationAccountBindingOutputSchema } from "./account"
4
5
  import { automationErrorSchema } from "./errors"
6
+ import { cursorPageOutputSchema, cursorPaginationInputSchema } from "./schemas"
7
+
8
+ const TRIGGER_PRESENTATION_VALUE_SCHEMA = z.object({
9
+ copyable: z.boolean().optional(),
10
+ value: z.string(),
11
+ })
12
+
13
+ export const automationOutputSchema = z.object({
14
+ accountBindings: z
15
+ .object({
16
+ account: integrationAccountBindingOutputSchema.nullable(),
17
+ binding: z.string(),
18
+ serviceId: z.string(),
19
+ })
20
+ .array(),
21
+ activeDeploymentId: z.string(),
22
+ createdAt: z.date(),
23
+ description: z.string(),
24
+ enabled: z.boolean(),
25
+ id: z.string(),
26
+ identityKey: z.string(),
27
+ project: z.object({
28
+ id: z.string(),
29
+ name: z.string(),
30
+ organization: z.object({
31
+ id: z.string(),
32
+ name: z.string(),
33
+ }),
34
+ }),
35
+ triggers: z
36
+ .object({
37
+ details: TRIGGER_PRESENTATION_VALUE_SCHEMA.extend({
38
+ label: z.string(),
39
+ }).array(),
40
+ hookSlot: z.number().int().nonnegative(),
41
+ id: z.string(),
42
+ name: z.string(),
43
+ primary: TRIGGER_PRESENTATION_VALUE_SCHEMA.optional(),
44
+ scopePath: z.number().int().nonnegative().array(),
45
+ type: z.string(),
46
+ })
47
+ .array(),
48
+ updatedAt: z.date(),
49
+ })
5
50
 
6
51
  export const automationExecutionStatusSchema = z.enum([
7
52
  "running",
8
- "completed",
53
+ "settled",
9
54
  "failed",
10
55
  ])
11
56
 
12
57
  const EXECUTION_SUMMARY_SCHEMA = z.object({
13
- completedAt: z.date().nullable(),
14
58
  createdAt: z.date(),
15
59
  eventTypes: z.string().array(),
16
60
  failure: automationErrorSchema.nullable(),
17
61
  id: z.string(),
62
+ settledAt: z.date().nullable(),
18
63
  status: automationExecutionStatusSchema,
19
64
  })
20
65
 
21
66
  export const automationContract = {
67
+ get: oc
68
+ .route({
69
+ method: "GET",
70
+ path: "/automations/{automationId}",
71
+ operationId: "getAutomation",
72
+ summary: "Get automation",
73
+ description:
74
+ "Returns an active automation with its triggers and integration account bindings.",
75
+ tags: ["Automations"],
76
+ })
77
+ .input(z.object({ automationId: z.string() }))
78
+ .output(automationOutputSchema),
22
79
  getExecution: oc
23
80
  .input(
24
81
  z.object({
@@ -62,6 +119,27 @@ export const automationContract = {
62
119
  .array(),
63
120
  }),
64
121
  ),
122
+ list: oc
123
+ .route({
124
+ method: "GET",
125
+ path: "/automations",
126
+ operationId: "listAutomations",
127
+ summary: "List automations",
128
+ description:
129
+ "Lists active automations visible to the caller, optionally filtered by organization, project, state, or query.",
130
+ tags: ["Automations"],
131
+ })
132
+ .input(
133
+ cursorPaginationInputSchema
134
+ .extend({
135
+ enabled: z.boolean().optional(),
136
+ organizationId: z.string().optional(),
137
+ projectId: z.string().optional(),
138
+ query: z.string().min(1).optional(),
139
+ })
140
+ .prefault({}),
141
+ )
142
+ .output(cursorPageOutputSchema(automationOutputSchema)),
65
143
  listExecutions: oc
66
144
  .input(
67
145
  z.object({
@@ -71,6 +149,15 @@ export const automationContract = {
71
149
  )
72
150
  .output(EXECUTION_SUMMARY_SCHEMA.array()),
73
151
  update: oc
152
+ .route({
153
+ method: "PATCH",
154
+ path: "/automations/{automationId}",
155
+ operationId: "updateAutomation",
156
+ summary: "Update automation",
157
+ description:
158
+ "Enables or disables an automation. Requires project:update.",
159
+ tags: ["Automations"],
160
+ })
74
161
  .input(
75
162
  z.object({
76
163
  automationId: z.string(),