@automate.ax/integration-contracts 0.147.1 → 0.150.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.
- package/dist/calcom/events.d.ts +1067 -11
- package/dist/calcom/events.js +66 -32
- package/dist/close/events.d.ts +4 -4
- package/dist/close/schemas.d.ts +6 -6
- package/dist/google-drive/index.d.ts +3 -3
- package/dist/kit/api.d.ts +78 -0
- package/dist/kit/api.js +386 -0
- package/dist/kit/events.d.ts +437 -0
- package/dist/kit/events.js +285 -0
- package/dist/kit/index.d.ts +6 -0
- package/dist/kit/index.js +5 -0
- package/dist/kit/openapi-operations.generated.d.ts +5 -0
- package/dist/kit/openapi-operations.generated.js +5 -0
- package/dist/kit/openapi-types.generated.d.ts +9485 -0
- package/dist/kit/openapi-types.generated.js +1 -0
- package/dist/kit/operation-manifest.d.ts +657 -0
- package/dist/kit/operation-manifest.js +98 -0
- package/dist/kit/schemas.d.ts +42 -0
- package/dist/kit/schemas.js +43 -0
- package/dist/kit/types.d.ts +41 -0
- package/dist/kit/types.js +1 -0
- package/dist/krisp/api.d.ts +61 -0
- package/dist/krisp/api.js +170 -0
- package/dist/krisp/index.d.ts +2 -0
- package/dist/krisp/index.js +2 -0
- package/dist/krisp/schemas.d.ts +145 -0
- package/dist/krisp/schemas.js +97 -0
- package/dist/notion/schemas.d.ts +108 -108
- package/dist/resend/action-schemas.d.ts +14 -14
- package/dist/triggers.d.ts +2 -1
- package/package.json +15 -2
- package/src/calcom/events.ts +149 -30
- package/src/kit/api.ts +523 -0
- package/src/kit/events.ts +352 -0
- package/src/kit/index.ts +6 -0
- package/src/kit/openapi-operations.generated.ts +7 -0
- package/src/kit/openapi-types.generated.ts +9710 -0
- package/src/kit/operation-manifest.ts +771 -0
- package/src/kit/schemas.ts +93 -0
- package/src/kit/types.ts +87 -0
- package/src/krisp/api.ts +215 -0
- package/src/krisp/index.ts +2 -0
- package/src/krisp/schemas.ts +122 -0
- package/src/triggers.ts +2 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* oxlint-disable typescript/no-unsafe-type-assertion -- Generated operation keys index a frozen external contract. */
|
|
2
|
+
import { Validator } from "@cfworker/json-schema"
|
|
3
|
+
import * as z from "zod"
|
|
4
|
+
import { KIT_OPENAPI_DATA } from "./openapi-operations.generated"
|
|
5
|
+
import type { KitOperationKey } from "./operation-manifest"
|
|
6
|
+
import type { KitOperationInput, KitOperationOutput } from "./types"
|
|
7
|
+
|
|
8
|
+
export interface KitRuntimeParameter {
|
|
9
|
+
explode: boolean
|
|
10
|
+
name: string
|
|
11
|
+
providerName: string
|
|
12
|
+
style: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Frozen runtime description of one public Kit operation. */
|
|
16
|
+
export interface KitRuntimeOperation {
|
|
17
|
+
bodyParameters: string[]
|
|
18
|
+
bodyWireSchema?: Record<string, unknown>
|
|
19
|
+
inputSchema: Record<string, unknown>
|
|
20
|
+
method: "DELETE" | "GET" | "PATCH" | "POST" | "PUT"
|
|
21
|
+
outputSchema: Record<string, unknown>
|
|
22
|
+
outputWireSchema: Record<string, unknown>
|
|
23
|
+
path: string
|
|
24
|
+
pathParameters: KitRuntimeParameter[]
|
|
25
|
+
queryParameters: KitRuntimeParameter[]
|
|
26
|
+
responseMode: "json" | "void"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Runtime Kit contract narrowed once from the opaque generated payload. */
|
|
30
|
+
const operationData = KIT_OPENAPI_DATA as {
|
|
31
|
+
definitions: Record<string, Record<string, unknown>>
|
|
32
|
+
operations: Record<string, unknown>
|
|
33
|
+
wireDefinitions: Record<string, Record<string, unknown>>
|
|
34
|
+
}
|
|
35
|
+
const OPERATIONS = operationData.operations as unknown as Record<
|
|
36
|
+
KitOperationKey,
|
|
37
|
+
KitRuntimeOperation
|
|
38
|
+
>
|
|
39
|
+
const VALIDATOR = new Validator(
|
|
40
|
+
{
|
|
41
|
+
$defs: operationData.definitions,
|
|
42
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
43
|
+
additionalProperties: false,
|
|
44
|
+
properties: Object.fromEntries(
|
|
45
|
+
Object.entries(OPERATIONS).flatMap(([key, operation]) => [
|
|
46
|
+
[`${key}:input`, operation.inputSchema],
|
|
47
|
+
[`${key}:output`, operation.outputSchema],
|
|
48
|
+
]),
|
|
49
|
+
),
|
|
50
|
+
type: "object",
|
|
51
|
+
},
|
|
52
|
+
"2020-12",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns the immutable runtime descriptor for one Kit operation.
|
|
57
|
+
*
|
|
58
|
+
* @param key Public operation name.
|
|
59
|
+
*/
|
|
60
|
+
export function kitOperation<TKey extends KitOperationKey>(key: TKey) {
|
|
61
|
+
return OPERATIONS[key]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Validates flattened public input for one Kit operation.
|
|
66
|
+
*
|
|
67
|
+
* @param key Public operation name.
|
|
68
|
+
*/
|
|
69
|
+
export function kitOperationInputSchema<TKey extends KitOperationKey>(
|
|
70
|
+
key: TKey,
|
|
71
|
+
): z.ZodType<KitOperationInput<TKey>> {
|
|
72
|
+
return z.custom<KitOperationInput<TKey>>(
|
|
73
|
+
(value) => VALIDATOR.validate({ [`${key}:input`]: value }).valid,
|
|
74
|
+
{ message: `Input does not match Kit operation ${key}.` },
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Validates a public successful response for one Kit operation.
|
|
80
|
+
*
|
|
81
|
+
* @param key Public operation name.
|
|
82
|
+
*/
|
|
83
|
+
export function kitOperationOutputSchema<TKey extends KitOperationKey>(
|
|
84
|
+
key: TKey,
|
|
85
|
+
): z.ZodType<KitOperationOutput<TKey>> {
|
|
86
|
+
return z.custom<KitOperationOutput<TKey>>(
|
|
87
|
+
(value) => VALIDATOR.validate({ [`${key}:output`]: value }).valid,
|
|
88
|
+
{ message: `Output does not match Kit operation ${key}.` },
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Provider-native component schemas used for schema-guided key mapping. */
|
|
93
|
+
export const KIT_WIRE_DEFINITIONS = operationData.wireDefinitions
|
package/src/kit/types.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Encodable } from "@automate.ax/codec"
|
|
2
|
+
import type { KitOperationMap } from "./openapi-types.generated"
|
|
3
|
+
import type { KitOperationKey } from "./operation-manifest"
|
|
4
|
+
|
|
5
|
+
type Operation<TKey extends KitOperationKey> =
|
|
6
|
+
TKey extends keyof KitOperationMap ? KitOperationMap[TKey] : never
|
|
7
|
+
|
|
8
|
+
/** Converts absent generated operation sections into intersection identities. */
|
|
9
|
+
type InputPart<TValue> = [NonNullable<TValue>] extends [never]
|
|
10
|
+
? unknown
|
|
11
|
+
: NonNullable<TValue>
|
|
12
|
+
|
|
13
|
+
type Parameters<TOperation, TLocation extends string> = TOperation extends {
|
|
14
|
+
parameters?: infer TParameters
|
|
15
|
+
}
|
|
16
|
+
? TLocation extends keyof NonNullable<TParameters>
|
|
17
|
+
? InputPart<NonNullable<TParameters>[TLocation]>
|
|
18
|
+
: unknown
|
|
19
|
+
: unknown
|
|
20
|
+
|
|
21
|
+
/** Extracts the JSON request body from one generated operation. */
|
|
22
|
+
type JsonBody<TOperation> = TOperation extends { requestBody?: infer TBody }
|
|
23
|
+
? [NonNullable<TBody>] extends [never]
|
|
24
|
+
? unknown
|
|
25
|
+
: NonNullable<TBody> extends { content: infer TContent }
|
|
26
|
+
? "application/json" extends keyof TContent
|
|
27
|
+
? TContent["application/json"]
|
|
28
|
+
: unknown
|
|
29
|
+
: unknown
|
|
30
|
+
: unknown
|
|
31
|
+
|
|
32
|
+
/** Extracts the JSON response body from one generated response. */
|
|
33
|
+
type JsonResponse<TResponse> = TResponse extends { content: infer TContent }
|
|
34
|
+
? "application/json" extends keyof TContent
|
|
35
|
+
? TContent["application/json"]
|
|
36
|
+
: object
|
|
37
|
+
: object
|
|
38
|
+
|
|
39
|
+
/** Extracts the union of successful generated operation responses. */
|
|
40
|
+
type SuccessResponse<TOperation> = TOperation extends {
|
|
41
|
+
responses: infer TResponses
|
|
42
|
+
}
|
|
43
|
+
? JsonResponse<
|
|
44
|
+
TResponses[Extract<keyof TResponses, 200 | 201 | 202 | 203 | 204>]
|
|
45
|
+
>
|
|
46
|
+
: never
|
|
47
|
+
|
|
48
|
+
/** Materializes an intersection as one readable object type. */
|
|
49
|
+
type Simplify<TValue> = { [TKey in keyof TValue]: TValue[TKey] } & {}
|
|
50
|
+
|
|
51
|
+
type EncodableValue<TValue> = unknown extends TValue
|
|
52
|
+
? Encodable
|
|
53
|
+
: TValue extends undefined | null | boolean | number | string
|
|
54
|
+
? TValue
|
|
55
|
+
: TValue extends readonly (infer TItem)[]
|
|
56
|
+
? EncodableValue<TItem>[]
|
|
57
|
+
: TValue extends object
|
|
58
|
+
? keyof TValue extends never
|
|
59
|
+
? Record<string, Encodable>
|
|
60
|
+
: { [TKey in keyof TValue]: EncodableValue<TValue[TKey]> }
|
|
61
|
+
: never
|
|
62
|
+
|
|
63
|
+
/** Flattens one generated operation's path, query, and body fields. */
|
|
64
|
+
type RawKitOperationInput<TKey extends KitOperationKey> = Simplify<
|
|
65
|
+
Parameters<Operation<TKey>, "path"> &
|
|
66
|
+
Parameters<Operation<TKey>, "query"> &
|
|
67
|
+
JsonBody<Operation<TKey>>
|
|
68
|
+
>
|
|
69
|
+
|
|
70
|
+
/** Preserves operation unions and rejects fields on truly empty inputs. */
|
|
71
|
+
type PublicInput<TValue> = TValue extends unknown
|
|
72
|
+
? keyof TValue extends never
|
|
73
|
+
? Record<string, never>
|
|
74
|
+
: {
|
|
75
|
+
[TField in keyof TValue]: EncodableValue<TValue[TField]>
|
|
76
|
+
}
|
|
77
|
+
: never
|
|
78
|
+
|
|
79
|
+
/** Flattened camelCase input for one frozen Kit V4 operation. */
|
|
80
|
+
export type KitOperationInput<TKey extends KitOperationKey> = PublicInput<
|
|
81
|
+
RawKitOperationInput<TKey>
|
|
82
|
+
>
|
|
83
|
+
|
|
84
|
+
/** CamelCase successful response for one frozen Kit V4 operation. */
|
|
85
|
+
export type KitOperationOutput<TKey extends KitOperationKey> = EncodableValue<
|
|
86
|
+
SuccessResponse<Operation<TKey>>
|
|
87
|
+
>
|
package/src/krisp/api.ts
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import type { Encodable } from "@automate.ax/codec"
|
|
2
|
+
import { encodableSchema } from "@automate.ax/codec"
|
|
3
|
+
import * as z from "zod"
|
|
4
|
+
|
|
5
|
+
const KRISP_API_BASE_URL = "https://meeting-api.krisp.ai/v1/"
|
|
6
|
+
const KRISP_API_ORIGIN = new URL(KRISP_API_BASE_URL).origin
|
|
7
|
+
const KRISP_SECRET_SCHEMA = z.object({ apiKey: z.string().min(1) })
|
|
8
|
+
|
|
9
|
+
/** Options for one authenticated Krisp REST request. */
|
|
10
|
+
export interface KrispRequestOptions<TSchema extends z.ZodType> {
|
|
11
|
+
/** Public camelCase JSON body. */
|
|
12
|
+
body?: Encodable
|
|
13
|
+
|
|
14
|
+
/** HTTP verb. Defaults to `GET`. */
|
|
15
|
+
method?: "GET" | "POST"
|
|
16
|
+
|
|
17
|
+
/** Public camelCase query parameters. */
|
|
18
|
+
query?: Record<
|
|
19
|
+
string,
|
|
20
|
+
boolean | number | readonly string[] | string | undefined
|
|
21
|
+
>
|
|
22
|
+
|
|
23
|
+
/** Schema for the normalized provider response. */
|
|
24
|
+
responseSchema: TSchema
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Structured Krisp REST failure. */
|
|
28
|
+
export class KrispApiError extends Error {
|
|
29
|
+
/** Normalized provider error payload, when valid JSON was returned. */
|
|
30
|
+
readonly body?: Encodable
|
|
31
|
+
|
|
32
|
+
/** Retry delay in seconds, when Krisp returned one. */
|
|
33
|
+
readonly retryAfter?: number
|
|
34
|
+
|
|
35
|
+
/** HTTP status returned by Krisp. */
|
|
36
|
+
readonly status: number
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates a structured Krisp API error.
|
|
40
|
+
*
|
|
41
|
+
* @param options - Provider status, body, and retry metadata.
|
|
42
|
+
* @param options.body - Normalized provider error body.
|
|
43
|
+
* @param options.retryAfter - Retry delay in seconds.
|
|
44
|
+
* @param options.status - HTTP status.
|
|
45
|
+
*/
|
|
46
|
+
constructor(options: {
|
|
47
|
+
body?: Encodable
|
|
48
|
+
retryAfter?: number
|
|
49
|
+
status: number
|
|
50
|
+
}) {
|
|
51
|
+
super(
|
|
52
|
+
getErrorMessage(options.body) ??
|
|
53
|
+
`Krisp API request failed with status ${options.status}.`,
|
|
54
|
+
)
|
|
55
|
+
this.name = "KrispApiError"
|
|
56
|
+
this.body = options.body
|
|
57
|
+
this.retryAfter = options.retryAfter
|
|
58
|
+
this.status = options.status
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Creates an authenticated Krisp Meeting Assistant REST client.
|
|
64
|
+
*
|
|
65
|
+
* @param secret - Resolved Krisp API-key secret.
|
|
66
|
+
*/
|
|
67
|
+
export function getKrispApi(secret: Record<string, unknown>) {
|
|
68
|
+
const { apiKey } = KRISP_SECRET_SCHEMA.parse(secret)
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
/**
|
|
72
|
+
* Runs one Krisp request and returns its normalized response.
|
|
73
|
+
*
|
|
74
|
+
* @param path - API path relative to the v1 root.
|
|
75
|
+
* @param options - Method, parameters, and response schema.
|
|
76
|
+
*/
|
|
77
|
+
async request<TSchema extends z.ZodType>(
|
|
78
|
+
path: string,
|
|
79
|
+
options: KrispRequestOptions<TSchema>,
|
|
80
|
+
): Promise<z.output<TSchema>> {
|
|
81
|
+
const url = new URL(path.replace(/^\//, ""), KRISP_API_BASE_URL)
|
|
82
|
+
if (url.origin !== KRISP_API_ORIGIN) {
|
|
83
|
+
throw new Error("Krisp API paths must use the Krisp API origin.")
|
|
84
|
+
}
|
|
85
|
+
for (const [name, value] of Object.entries(options.query ?? {})) {
|
|
86
|
+
if (value === undefined) continue
|
|
87
|
+
url.searchParams.set(
|
|
88
|
+
toSnakeCase(name),
|
|
89
|
+
Array.isArray(value) ? value.join(",") : String(value),
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
const response = await fetch(url, {
|
|
93
|
+
body:
|
|
94
|
+
options.body === undefined
|
|
95
|
+
? undefined
|
|
96
|
+
: JSON.stringify(toKrisp(options.body)),
|
|
97
|
+
headers: {
|
|
98
|
+
Accept: "application/json",
|
|
99
|
+
Authorization: `Bearer ${apiKey}`,
|
|
100
|
+
...(options.body === undefined
|
|
101
|
+
? {}
|
|
102
|
+
: { "Content-Type": "application/json" }),
|
|
103
|
+
},
|
|
104
|
+
method: options.method ?? "GET",
|
|
105
|
+
})
|
|
106
|
+
const normalized = fromKrisp(parseJson(await response.text()))
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const body = encodableSchema.safeParse(normalized)
|
|
109
|
+
throw new KrispApiError({
|
|
110
|
+
...(body.success && { body: body.data }),
|
|
111
|
+
retryAfter: parseFiniteNumber(response.headers.get("Retry-After")),
|
|
112
|
+
status: response.status,
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
return options.responseSchema.parse(normalized)
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Converts public camelCase JSON to Krisp wire keys.
|
|
122
|
+
*
|
|
123
|
+
* @param value - Public value to normalize.
|
|
124
|
+
*/
|
|
125
|
+
export function toKrisp(value: Encodable): Encodable {
|
|
126
|
+
if (value instanceof Date) return value.toISOString()
|
|
127
|
+
if (Array.isArray(value)) return value.map(toKrisp)
|
|
128
|
+
if (!isPlainObject(value)) return value
|
|
129
|
+
return Object.fromEntries(
|
|
130
|
+
Object.entries(value).map(([key, item]) => [
|
|
131
|
+
toSnakeCase(key),
|
|
132
|
+
toKrisp(item),
|
|
133
|
+
]),
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Converts Krisp wire JSON to public camelCase keys.
|
|
139
|
+
*
|
|
140
|
+
* @param value - Provider value to normalize.
|
|
141
|
+
*/
|
|
142
|
+
export function fromKrisp(value: unknown): unknown {
|
|
143
|
+
if (Array.isArray(value)) return value.map(fromKrisp)
|
|
144
|
+
if (!isPlainObject(value)) return value
|
|
145
|
+
return Object.fromEntries(
|
|
146
|
+
Object.entries(value).map(([key, item]) => [
|
|
147
|
+
toCamelCase(key),
|
|
148
|
+
fromKrisp(item),
|
|
149
|
+
]),
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Checks whether a value is a key-value object.
|
|
155
|
+
*
|
|
156
|
+
* @param value - Candidate value.
|
|
157
|
+
*/
|
|
158
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
159
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Parses a JSON response body without obscuring the HTTP status on failure.
|
|
164
|
+
*
|
|
165
|
+
* @param value - Raw response text.
|
|
166
|
+
*/
|
|
167
|
+
function parseJson(value: string): unknown {
|
|
168
|
+
try {
|
|
169
|
+
return JSON.parse(value)
|
|
170
|
+
} catch {
|
|
171
|
+
return undefined
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Parses an optional finite numeric header.
|
|
177
|
+
*
|
|
178
|
+
* @param value - Raw header value.
|
|
179
|
+
*/
|
|
180
|
+
function parseFiniteNumber(value: string | null) {
|
|
181
|
+
if (value === null) return undefined
|
|
182
|
+
const number = Number(value)
|
|
183
|
+
return Number.isFinite(number) ? number : undefined
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Extracts Krisp's human-readable error string.
|
|
188
|
+
*
|
|
189
|
+
* @param body - Normalized provider error body.
|
|
190
|
+
*/
|
|
191
|
+
function getErrorMessage(body: Encodable | undefined) {
|
|
192
|
+
return isPlainObject(body) && typeof body.error === "string"
|
|
193
|
+
? body.error
|
|
194
|
+
: undefined
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Converts one public camelCase key to Krisp snake_case.
|
|
199
|
+
*
|
|
200
|
+
* @param value - Public key.
|
|
201
|
+
*/
|
|
202
|
+
function toSnakeCase(value: string) {
|
|
203
|
+
return value.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Converts one Krisp snake_case key to public camelCase.
|
|
208
|
+
*
|
|
209
|
+
* @param value - Provider key.
|
|
210
|
+
*/
|
|
211
|
+
function toCamelCase(value: string) {
|
|
212
|
+
return value.replace(/_([a-z0-9])/g, (_, letter: string) =>
|
|
213
|
+
letter.toUpperCase(),
|
|
214
|
+
)
|
|
215
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import type { Encodable } from "@automate.ax/codec"
|
|
3
|
+
|
|
4
|
+
const DATE_TIME_SCHEMA = z.iso.datetime({ offset: true })
|
|
5
|
+
|
|
6
|
+
/** Krisp profile represented by a personal API key. */
|
|
7
|
+
export const KRISP_PROFILE_SCHEMA = z.object({
|
|
8
|
+
avatar: z.url().nullable().prefault(null),
|
|
9
|
+
email: z.email(),
|
|
10
|
+
firstName: z.string().nullable().prefault(null),
|
|
11
|
+
id: z.number().int().positive(),
|
|
12
|
+
lastName: z.string().nullable().prefault(null),
|
|
13
|
+
teamId: z.number().int().positive(),
|
|
14
|
+
workspaceId: z.number().int().positive(),
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
/** Calendar attendee or diarized speaker attached to a Krisp meeting. */
|
|
18
|
+
export const KRISP_PARTICIPANT_SCHEMA = z.object({
|
|
19
|
+
email: z.string().nullable().prefault(null),
|
|
20
|
+
firstName: z.string().nullable().prefault(null),
|
|
21
|
+
lastName: z.string().nullable().prefault(null),
|
|
22
|
+
photo: z.url().nullable().prefault(null),
|
|
23
|
+
status: z.string().nullable().prefault(null),
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
/** Meeting metadata returned by Krisp list and detail endpoints. */
|
|
27
|
+
export const KRISP_MEETING_SCHEMA = z.object({
|
|
28
|
+
duration: z.number().int().nonnegative().nullable(),
|
|
29
|
+
id: z.string().min(1),
|
|
30
|
+
ownership: z.enum(["owned", "shared"]),
|
|
31
|
+
participants: KRISP_PARTICIPANT_SCHEMA.array().optional(),
|
|
32
|
+
source: z.string().nullable(),
|
|
33
|
+
startedAt: DATE_TIME_SCHEMA.nullable(),
|
|
34
|
+
status: z.string(),
|
|
35
|
+
tags: z.string().array(),
|
|
36
|
+
title: z.string(),
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
/** One diarized transcript segment. Times are seconds from recording start. */
|
|
40
|
+
export const KRISP_TRANSCRIPT_SEGMENT_SCHEMA = z.object({
|
|
41
|
+
end: z.number().nonnegative(),
|
|
42
|
+
speaker: z.number().int().nonnegative(),
|
|
43
|
+
start: z.number().nonnegative(),
|
|
44
|
+
text: z.string(),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const KRISP_NOTE_ASSIGNEE_SCHEMA = z.record(z.string(), z.json())
|
|
48
|
+
|
|
49
|
+
export interface KrispNoteBlock {
|
|
50
|
+
[key: string]: Encodable
|
|
51
|
+
assignee?: z.output<typeof KRISP_NOTE_ASSIGNEE_SCHEMA> | null
|
|
52
|
+
children?: KrispNoteBlock[]
|
|
53
|
+
completed?: boolean | null
|
|
54
|
+
dueDate?: string | null
|
|
55
|
+
text?: string
|
|
56
|
+
type: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Recursive block returned by Krisp's fixed and custom meeting-note sections. */
|
|
60
|
+
export const KRISP_NOTE_BLOCK_SCHEMA: z.ZodType<KrispNoteBlock> = z.lazy(() =>
|
|
61
|
+
z.object({
|
|
62
|
+
assignee: KRISP_NOTE_ASSIGNEE_SCHEMA.nullable().optional(),
|
|
63
|
+
children: KRISP_NOTE_BLOCK_SCHEMA.array().optional(),
|
|
64
|
+
completed: z.boolean().nullable().optional(),
|
|
65
|
+
dueDate: z.string().nullable().optional(),
|
|
66
|
+
text: z.string().optional(),
|
|
67
|
+
type: z.string(),
|
|
68
|
+
}),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
/** Complete Krisp meeting detail with optional heavy transcript and note data. */
|
|
72
|
+
export const KRISP_MEETING_DETAIL_SCHEMA = KRISP_MEETING_SCHEMA.extend({
|
|
73
|
+
language: z.string().nullable().prefault(null),
|
|
74
|
+
meetingType: z.string().nullable().prefault(null),
|
|
75
|
+
notes: z
|
|
76
|
+
.object({ blocks: KRISP_NOTE_BLOCK_SCHEMA.array() })
|
|
77
|
+
.nullable()
|
|
78
|
+
.optional(),
|
|
79
|
+
transcript: z
|
|
80
|
+
.object({
|
|
81
|
+
language: z.string().nullable().prefault(null),
|
|
82
|
+
segments: KRISP_TRANSCRIPT_SEGMENT_SCHEMA.array().prefault([]),
|
|
83
|
+
speakers: z.record(z.string(), KRISP_PARTICIPANT_SCHEMA).prefault({}),
|
|
84
|
+
})
|
|
85
|
+
.nullable()
|
|
86
|
+
.optional(),
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
/** One action item extracted from a Krisp meeting. */
|
|
90
|
+
export const KRISP_ACTION_ITEM_SCHEMA = z.object({
|
|
91
|
+
assignee: KRISP_PARTICIPANT_SCHEMA.nullable().prefault(null),
|
|
92
|
+
completed: z.boolean().nullable().prefault(null),
|
|
93
|
+
dueDate: z.string().nullable().prefault(null),
|
|
94
|
+
id: z.string().min(1),
|
|
95
|
+
meetingId: z.string().min(1),
|
|
96
|
+
meetingStartedAt: DATE_TIME_SCHEMA.nullable().prefault(null),
|
|
97
|
+
meetingTitle: z.string(),
|
|
98
|
+
title: z.string(),
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
/** Tag used to organize Krisp meetings. */
|
|
102
|
+
export const KRISP_TAG_SCHEMA = z.object({
|
|
103
|
+
color: z.string().nullable(),
|
|
104
|
+
createdAt: DATE_TIME_SCHEMA,
|
|
105
|
+
id: z.string().min(1),
|
|
106
|
+
name: z.string(),
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
/** Recording-import identity returned after Krisp issues an upload URL. */
|
|
110
|
+
export const KRISP_IMPORT_SCHEMA = z.object({
|
|
111
|
+
expiresAt: DATE_TIME_SCHEMA,
|
|
112
|
+
importId: z.string().min(1),
|
|
113
|
+
url: z.url(),
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
/** Current processing state for a Krisp recording import. */
|
|
117
|
+
export const KRISP_IMPORT_STATUS_SCHEMA = z.object({
|
|
118
|
+
error: z.string().nullable().prefault(null),
|
|
119
|
+
importId: z.string().min(1),
|
|
120
|
+
meetingId: z.string().min(1).nullable().prefault(null),
|
|
121
|
+
status: z.enum(["uploading", "processing", "ready", "failed"]),
|
|
122
|
+
})
|
package/src/triggers.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type { googleAdsTriggerContracts } from "./google-ads"
|
|
|
22
22
|
import type { googleSheetsTriggerContracts } from "./google-sheets"
|
|
23
23
|
import type { hubspotTriggerContracts } from "./hubspot"
|
|
24
24
|
import type { highLevelTriggerContracts } from "./highlevel"
|
|
25
|
+
import type { kitTriggerContracts } from "./kit"
|
|
25
26
|
import type { linearTriggerContracts } from "./linear"
|
|
26
27
|
import type { millionVerifierTriggerContracts } from "./millionverifier"
|
|
27
28
|
import type { metaAdsTriggerContracts } from "./meta-ads"
|
|
@@ -63,6 +64,7 @@ export type TriggerContractMap = typeof airtableTriggerContracts &
|
|
|
63
64
|
typeof googleSheetsTriggerContracts &
|
|
64
65
|
typeof hubspotTriggerContracts &
|
|
65
66
|
typeof highLevelTriggerContracts &
|
|
67
|
+
typeof kitTriggerContracts &
|
|
66
68
|
typeof linearTriggerContracts &
|
|
67
69
|
typeof millionVerifierTriggerContracts &
|
|
68
70
|
typeof metaAdsTriggerContracts &
|