@automate.ax/integration-contracts 0.150.0 → 0.150.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/dist/kit/schemas.js +101 -0
- package/dist/kit/types.d.ts +19 -2
- package/package.json +2 -2
- package/src/kit/schemas.ts +116 -0
- package/src/kit/types.ts +39 -2
package/dist/kit/schemas.js
CHANGED
|
@@ -4,6 +4,13 @@ import * as z from "zod";
|
|
|
4
4
|
import { KIT_OPENAPI_DATA } from "./openapi-operations.generated";
|
|
5
5
|
/** Runtime Kit contract narrowed once from the opaque generated payload. */
|
|
6
6
|
const operationData = KIT_OPENAPI_DATA;
|
|
7
|
+
for (const operation of Object.values(operationData.operations)) {
|
|
8
|
+
if (typeof operation !== "object" || operation === null)
|
|
9
|
+
continue;
|
|
10
|
+
const record = operation;
|
|
11
|
+
normalizeObservedKitSchema(record.outputSchema);
|
|
12
|
+
normalizeObservedKitSchema(record.outputWireSchema);
|
|
13
|
+
}
|
|
7
14
|
const OPERATIONS = operationData.operations;
|
|
8
15
|
const VALIDATOR = new Validator({
|
|
9
16
|
$defs: operationData.definitions,
|
|
@@ -41,3 +48,97 @@ export function kitOperationOutputSchema(key) {
|
|
|
41
48
|
}
|
|
42
49
|
/** Provider-native component schemas used for schema-guided key mapping. */
|
|
43
50
|
export const KIT_WIRE_DEFINITIONS = operationData.wireDefinitions;
|
|
51
|
+
/**
|
|
52
|
+
* Accepts successful Kit response variants omitted from its OpenAPI metadata.
|
|
53
|
+
*
|
|
54
|
+
* @param value Generated operation metadata.
|
|
55
|
+
*/
|
|
56
|
+
function normalizeObservedKitSchema(value) {
|
|
57
|
+
if (Array.isArray(value)) {
|
|
58
|
+
for (const item of value)
|
|
59
|
+
normalizeObservedKitSchema(item);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (typeof value !== "object" || value === null)
|
|
63
|
+
return;
|
|
64
|
+
const record = value;
|
|
65
|
+
const properties = record.properties;
|
|
66
|
+
if (typeof properties === "object" && properties !== null) {
|
|
67
|
+
const propertyRecord = properties;
|
|
68
|
+
for (const name of [
|
|
69
|
+
"bio",
|
|
70
|
+
"byline",
|
|
71
|
+
"emailTemplateId",
|
|
72
|
+
"email_template_id",
|
|
73
|
+
"endCursor",
|
|
74
|
+
"end_cursor",
|
|
75
|
+
"startCursor",
|
|
76
|
+
"start_cursor",
|
|
77
|
+
"valueHtml",
|
|
78
|
+
"value_html",
|
|
79
|
+
]) {
|
|
80
|
+
const property = propertyRecord[name];
|
|
81
|
+
if (typeof property !== "object" ||
|
|
82
|
+
property === null ||
|
|
83
|
+
isNullableSchema(property)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
propertyRecord[name] = { anyOf: [property, { type: "null" }] };
|
|
87
|
+
}
|
|
88
|
+
removeSpuriousCategoryRequirement(propertyRecord.fields);
|
|
89
|
+
acceptAllSubscribersFilter(record, propertyRecord);
|
|
90
|
+
}
|
|
91
|
+
for (const child of Object.values(record))
|
|
92
|
+
normalizeObservedKitSchema(child);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Removes a concrete example key incorrectly promoted into map requirements.
|
|
96
|
+
*
|
|
97
|
+
* @param value Generated map schema.
|
|
98
|
+
*/
|
|
99
|
+
function removeSpuriousCategoryRequirement(value) {
|
|
100
|
+
if (typeof value !== "object" || value === null)
|
|
101
|
+
return;
|
|
102
|
+
const record = value;
|
|
103
|
+
if (!("additionalProperties" in record) || !Array.isArray(record.required)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
record.required = record.required.filter((name) => name !== "category");
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Accepts Kit's provider-native condition for an unfiltered broadcast.
|
|
110
|
+
*
|
|
111
|
+
* @param schema Generated condition schema.
|
|
112
|
+
* @param properties Generated condition properties.
|
|
113
|
+
*/
|
|
114
|
+
function acceptAllSubscribersFilter(schema, properties) {
|
|
115
|
+
const type = properties.type;
|
|
116
|
+
if (typeof type !== "object" ||
|
|
117
|
+
type === null ||
|
|
118
|
+
!("ids" in properties) ||
|
|
119
|
+
!Array.isArray(schema.required)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const enumValues = type.enum;
|
|
123
|
+
if (!Array.isArray(enumValues) ||
|
|
124
|
+
enumValues.length !== 2 ||
|
|
125
|
+
!enumValues.includes("segment") ||
|
|
126
|
+
!enumValues.includes("tag")) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
;
|
|
130
|
+
type.enum = [...enumValues, "all_subscribers"];
|
|
131
|
+
schema.required = schema.required.filter((name) => name !== "ids");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Returns whether one JSON Schema fragment already accepts null.
|
|
135
|
+
*
|
|
136
|
+
* @param value JSON Schema fragment.
|
|
137
|
+
*/
|
|
138
|
+
function isNullableSchema(value) {
|
|
139
|
+
const anyOf = value.anyOf;
|
|
140
|
+
return (Array.isArray(anyOf) &&
|
|
141
|
+
anyOf.some((branch) => typeof branch === "object" &&
|
|
142
|
+
branch !== null &&
|
|
143
|
+
branch.type === "null"));
|
|
144
|
+
}
|
package/dist/kit/types.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { KitOperationKey } from "./operation-manifest.js";
|
|
|
4
4
|
type Operation<TKey extends KitOperationKey> = TKey extends keyof KitOperationMap ? KitOperationMap[TKey] : never;
|
|
5
5
|
/** Converts absent generated operation sections into intersection identities. */
|
|
6
6
|
type InputPart<TValue> = [NonNullable<TValue>] extends [never] ? unknown : NonNullable<TValue>;
|
|
7
|
+
/** Converts generated empty JSON objects into intersection identities. */
|
|
8
|
+
type JsonBodyPart<TValue> = TValue extends Record<string, never> ? unknown : TValue;
|
|
7
9
|
type Parameters<TOperation, TLocation extends string> = TOperation extends {
|
|
8
10
|
parameters?: infer TParameters;
|
|
9
11
|
} ? TLocation extends keyof NonNullable<TParameters> ? InputPart<NonNullable<TParameters>[TLocation]> : unknown : unknown;
|
|
@@ -12,7 +14,7 @@ type JsonBody<TOperation> = TOperation extends {
|
|
|
12
14
|
requestBody?: infer TBody;
|
|
13
15
|
} ? [NonNullable<TBody>] extends [never] ? unknown : NonNullable<TBody> extends {
|
|
14
16
|
content: infer TContent;
|
|
15
|
-
} ? "application/json" extends keyof TContent ? TContent["application/json"] : unknown : unknown : unknown;
|
|
17
|
+
} ? "application/json" extends keyof TContent ? JsonBodyPart<TContent["application/json"]> : unknown : unknown : unknown;
|
|
16
18
|
/** Extracts the JSON response body from one generated response. */
|
|
17
19
|
type JsonResponse<TResponse> = TResponse extends {
|
|
18
20
|
content: infer TContent;
|
|
@@ -28,6 +30,21 @@ type Simplify<TValue> = {
|
|
|
28
30
|
type EncodableValue<TValue> = unknown extends TValue ? Encodable : TValue extends undefined | null | boolean | number | string ? TValue : TValue extends readonly (infer TItem)[] ? EncodableValue<TItem>[] : TValue extends object ? keyof TValue extends never ? Record<string, Encodable> : {
|
|
29
31
|
[TKey in keyof TValue]: EncodableValue<TValue[TKey]>;
|
|
30
32
|
} : never;
|
|
33
|
+
/** Fields whose live Kit nullability is missing from its OpenAPI document. */
|
|
34
|
+
type ObservedNullableField = "bio" | "byline" | "emailTemplateId" | "endCursor" | "startCursor" | "valueHtml";
|
|
35
|
+
/** Generated broadcast filter shape extended with Kit's unfiltered variant. */
|
|
36
|
+
type BroadcastSubscriberFilterCondition = {
|
|
37
|
+
ids: number[];
|
|
38
|
+
type: "segment" | "tag";
|
|
39
|
+
};
|
|
40
|
+
type NormalizeObservedKitObject<TValue extends object> = {
|
|
41
|
+
[TKey in keyof TValue]: NormalizeObservedKitOutput<TValue[TKey]> | (TKey extends ObservedNullableField ? null : never);
|
|
42
|
+
};
|
|
43
|
+
/** Applies response variants observed in Kit but omitted from its OpenAPI. */
|
|
44
|
+
type NormalizeObservedKitOutput<TValue> = TValue extends readonly (infer TItem)[] ? NormalizeObservedKitOutput<TItem>[] : TValue extends BroadcastSubscriberFilterCondition ? NormalizeObservedKitObject<TValue> | {
|
|
45
|
+
ids?: never;
|
|
46
|
+
type: "all_subscribers";
|
|
47
|
+
} : TValue extends object ? NormalizeObservedKitObject<TValue> : TValue;
|
|
31
48
|
/** Flattens one generated operation's path, query, and body fields. */
|
|
32
49
|
type RawKitOperationInput<TKey extends KitOperationKey> = Simplify<Parameters<Operation<TKey>, "path"> & Parameters<Operation<TKey>, "query"> & JsonBody<Operation<TKey>>>;
|
|
33
50
|
/** Preserves operation unions and rejects fields on truly empty inputs. */
|
|
@@ -37,5 +54,5 @@ type PublicInput<TValue> = TValue extends unknown ? keyof TValue extends never ?
|
|
|
37
54
|
/** Flattened camelCase input for one frozen Kit V4 operation. */
|
|
38
55
|
export type KitOperationInput<TKey extends KitOperationKey> = PublicInput<RawKitOperationInput<TKey>>;
|
|
39
56
|
/** CamelCase successful response for one frozen Kit V4 operation. */
|
|
40
|
-
export type KitOperationOutput<TKey extends KitOperationKey> = EncodableValue<SuccessResponse<Operation<TKey
|
|
57
|
+
export type KitOperationOutput<TKey extends KitOperationKey> = EncodableValue<NormalizeObservedKitOutput<SuccessResponse<Operation<TKey>>>>;
|
|
41
58
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automate.ax/integration-contracts",
|
|
3
|
-
"version": "0.150.
|
|
3
|
+
"version": "0.150.2",
|
|
4
4
|
"description": "Shared integration payload contracts and provider primitives for Automate.ax.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@anthropic-ai/sdk": "0.123.0",
|
|
74
|
-
"@automate.ax/codec": "0.150.
|
|
74
|
+
"@automate.ax/codec": "0.150.2",
|
|
75
75
|
"@cfworker/json-schema": "^4.1.1",
|
|
76
76
|
"@googleapis/calendar": "^16.0.0",
|
|
77
77
|
"@googleapis/forms": "^6.0.1",
|
package/src/kit/schemas.ts
CHANGED
|
@@ -32,6 +32,12 @@ const operationData = KIT_OPENAPI_DATA as {
|
|
|
32
32
|
operations: Record<string, unknown>
|
|
33
33
|
wireDefinitions: Record<string, Record<string, unknown>>
|
|
34
34
|
}
|
|
35
|
+
for (const operation of Object.values(operationData.operations)) {
|
|
36
|
+
if (typeof operation !== "object" || operation === null) continue
|
|
37
|
+
const record = operation as Record<string, unknown>
|
|
38
|
+
normalizeObservedKitSchema(record.outputSchema)
|
|
39
|
+
normalizeObservedKitSchema(record.outputWireSchema)
|
|
40
|
+
}
|
|
35
41
|
const OPERATIONS = operationData.operations as unknown as Record<
|
|
36
42
|
KitOperationKey,
|
|
37
43
|
KitRuntimeOperation
|
|
@@ -91,3 +97,113 @@ export function kitOperationOutputSchema<TKey extends KitOperationKey>(
|
|
|
91
97
|
|
|
92
98
|
/** Provider-native component schemas used for schema-guided key mapping. */
|
|
93
99
|
export const KIT_WIRE_DEFINITIONS = operationData.wireDefinitions
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Accepts successful Kit response variants omitted from its OpenAPI metadata.
|
|
103
|
+
*
|
|
104
|
+
* @param value Generated operation metadata.
|
|
105
|
+
*/
|
|
106
|
+
function normalizeObservedKitSchema(value: unknown) {
|
|
107
|
+
if (Array.isArray(value)) {
|
|
108
|
+
for (const item of value) normalizeObservedKitSchema(item)
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
if (typeof value !== "object" || value === null) return
|
|
112
|
+
|
|
113
|
+
const record = value as Record<string, unknown>
|
|
114
|
+
const properties = record.properties
|
|
115
|
+
if (typeof properties === "object" && properties !== null) {
|
|
116
|
+
const propertyRecord = properties as Record<string, unknown>
|
|
117
|
+
for (const name of [
|
|
118
|
+
"bio",
|
|
119
|
+
"byline",
|
|
120
|
+
"emailTemplateId",
|
|
121
|
+
"email_template_id",
|
|
122
|
+
"endCursor",
|
|
123
|
+
"end_cursor",
|
|
124
|
+
"startCursor",
|
|
125
|
+
"start_cursor",
|
|
126
|
+
"valueHtml",
|
|
127
|
+
"value_html",
|
|
128
|
+
]) {
|
|
129
|
+
const property = propertyRecord[name]
|
|
130
|
+
if (
|
|
131
|
+
typeof property !== "object" ||
|
|
132
|
+
property === null ||
|
|
133
|
+
isNullableSchema(property)
|
|
134
|
+
) {
|
|
135
|
+
continue
|
|
136
|
+
}
|
|
137
|
+
propertyRecord[name] = { anyOf: [property, { type: "null" }] }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
removeSpuriousCategoryRequirement(propertyRecord.fields)
|
|
141
|
+
acceptAllSubscribersFilter(record, propertyRecord)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const child of Object.values(record)) normalizeObservedKitSchema(child)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Removes a concrete example key incorrectly promoted into map requirements.
|
|
149
|
+
*
|
|
150
|
+
* @param value Generated map schema.
|
|
151
|
+
*/
|
|
152
|
+
function removeSpuriousCategoryRequirement(value: unknown) {
|
|
153
|
+
if (typeof value !== "object" || value === null) return
|
|
154
|
+
const record = value as Record<string, unknown>
|
|
155
|
+
if (!("additionalProperties" in record) || !Array.isArray(record.required)) {
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
record.required = record.required.filter((name) => name !== "category")
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Accepts Kit's provider-native condition for an unfiltered broadcast.
|
|
163
|
+
*
|
|
164
|
+
* @param schema Generated condition schema.
|
|
165
|
+
* @param properties Generated condition properties.
|
|
166
|
+
*/
|
|
167
|
+
function acceptAllSubscribersFilter(
|
|
168
|
+
schema: Record<string, unknown>,
|
|
169
|
+
properties: Record<string, unknown>,
|
|
170
|
+
) {
|
|
171
|
+
const type = properties.type
|
|
172
|
+
if (
|
|
173
|
+
typeof type !== "object" ||
|
|
174
|
+
type === null ||
|
|
175
|
+
!("ids" in properties) ||
|
|
176
|
+
!Array.isArray(schema.required)
|
|
177
|
+
) {
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
const enumValues = (type as { enum?: unknown }).enum
|
|
181
|
+
if (
|
|
182
|
+
!Array.isArray(enumValues) ||
|
|
183
|
+
enumValues.length !== 2 ||
|
|
184
|
+
!enumValues.includes("segment") ||
|
|
185
|
+
!enumValues.includes("tag")
|
|
186
|
+
) {
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
;(type as { enum: unknown[] }).enum = [...enumValues, "all_subscribers"]
|
|
190
|
+
schema.required = schema.required.filter((name) => name !== "ids")
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Returns whether one JSON Schema fragment already accepts null.
|
|
195
|
+
*
|
|
196
|
+
* @param value JSON Schema fragment.
|
|
197
|
+
*/
|
|
198
|
+
function isNullableSchema(value: object) {
|
|
199
|
+
const anyOf = (value as { anyOf?: unknown }).anyOf
|
|
200
|
+
return (
|
|
201
|
+
Array.isArray(anyOf) &&
|
|
202
|
+
anyOf.some(
|
|
203
|
+
(branch) =>
|
|
204
|
+
typeof branch === "object" &&
|
|
205
|
+
branch !== null &&
|
|
206
|
+
(branch as { type?: unknown }).type === "null",
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
}
|
package/src/kit/types.ts
CHANGED
|
@@ -10,6 +10,10 @@ type InputPart<TValue> = [NonNullable<TValue>] extends [never]
|
|
|
10
10
|
? unknown
|
|
11
11
|
: NonNullable<TValue>
|
|
12
12
|
|
|
13
|
+
/** Converts generated empty JSON objects into intersection identities. */
|
|
14
|
+
type JsonBodyPart<TValue> =
|
|
15
|
+
TValue extends Record<string, never> ? unknown : TValue
|
|
16
|
+
|
|
13
17
|
type Parameters<TOperation, TLocation extends string> = TOperation extends {
|
|
14
18
|
parameters?: infer TParameters
|
|
15
19
|
}
|
|
@@ -24,7 +28,7 @@ type JsonBody<TOperation> = TOperation extends { requestBody?: infer TBody }
|
|
|
24
28
|
? unknown
|
|
25
29
|
: NonNullable<TBody> extends { content: infer TContent }
|
|
26
30
|
? "application/json" extends keyof TContent
|
|
27
|
-
? TContent["application/json"]
|
|
31
|
+
? JsonBodyPart<TContent["application/json"]>
|
|
28
32
|
: unknown
|
|
29
33
|
: unknown
|
|
30
34
|
: unknown
|
|
@@ -60,6 +64,39 @@ type EncodableValue<TValue> = unknown extends TValue
|
|
|
60
64
|
: { [TKey in keyof TValue]: EncodableValue<TValue[TKey]> }
|
|
61
65
|
: never
|
|
62
66
|
|
|
67
|
+
/** Fields whose live Kit nullability is missing from its OpenAPI document. */
|
|
68
|
+
type ObservedNullableField =
|
|
69
|
+
| "bio"
|
|
70
|
+
| "byline"
|
|
71
|
+
| "emailTemplateId"
|
|
72
|
+
| "endCursor"
|
|
73
|
+
| "startCursor"
|
|
74
|
+
| "valueHtml"
|
|
75
|
+
|
|
76
|
+
/** Generated broadcast filter shape extended with Kit's unfiltered variant. */
|
|
77
|
+
type BroadcastSubscriberFilterCondition = {
|
|
78
|
+
ids: number[]
|
|
79
|
+
type: "segment" | "tag"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type NormalizeObservedKitObject<TValue extends object> = {
|
|
83
|
+
[TKey in keyof TValue]:
|
|
84
|
+
| NormalizeObservedKitOutput<TValue[TKey]>
|
|
85
|
+
| (TKey extends ObservedNullableField ? null : never)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Applies response variants observed in Kit but omitted from its OpenAPI. */
|
|
89
|
+
type NormalizeObservedKitOutput<TValue> =
|
|
90
|
+
TValue extends readonly (infer TItem)[]
|
|
91
|
+
? NormalizeObservedKitOutput<TItem>[]
|
|
92
|
+
: TValue extends BroadcastSubscriberFilterCondition
|
|
93
|
+
?
|
|
94
|
+
| NormalizeObservedKitObject<TValue>
|
|
95
|
+
| { ids?: never; type: "all_subscribers" }
|
|
96
|
+
: TValue extends object
|
|
97
|
+
? NormalizeObservedKitObject<TValue>
|
|
98
|
+
: TValue
|
|
99
|
+
|
|
63
100
|
/** Flattens one generated operation's path, query, and body fields. */
|
|
64
101
|
type RawKitOperationInput<TKey extends KitOperationKey> = Simplify<
|
|
65
102
|
Parameters<Operation<TKey>, "path"> &
|
|
@@ -83,5 +120,5 @@ export type KitOperationInput<TKey extends KitOperationKey> = PublicInput<
|
|
|
83
120
|
|
|
84
121
|
/** CamelCase successful response for one frozen Kit V4 operation. */
|
|
85
122
|
export type KitOperationOutput<TKey extends KitOperationKey> = EncodableValue<
|
|
86
|
-
SuccessResponse<Operation<TKey
|
|
123
|
+
NormalizeObservedKitOutput<SuccessResponse<Operation<TKey>>>
|
|
87
124
|
>
|