@greatwait/contracts 0.3.1 → 0.3.3
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/attempt-diagnostics.d.ts +1 -1
- package/dist/attempt-diagnostics.js +13 -1
- package/dist/attempt-search.d.ts +2 -0
- package/dist/billing.d.ts +46 -0
- package/dist/billing.js +29 -0
- package/dist/callback-safety.js +5 -1
- package/dist/configuration.d.ts +2 -2
- package/dist/configuration.js +6 -3
- package/dist/delivery.d.ts +12 -1
- package/dist/delivery.js +1 -0
- package/dist/effective-limits.d.ts +4 -4
- package/dist/endpoints.d.ts +29 -0
- package/dist/endpoints.js +32 -1
- package/dist/forecast.d.ts +2 -2
- package/dist/http-request.d.ts +12 -2
- package/dist/http-request.js +31 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +8 -7
- package/dist/mcp.js +1 -0
- package/dist/operational-config.d.ts +174 -22
- package/dist/operational-config.js +207 -74
- package/dist/operations.d.ts +334 -52
- package/dist/operations.js +195 -34
- package/dist/project-notifications.d.ts +35 -9
- package/dist/project-notifications.js +43 -12
- package/dist/protocol.d.ts +28 -0
- package/dist/protocol.js +23 -0
- package/dist/scheduling-records.d.ts +106 -16
- package/dist/scheduling-records.js +36 -12
- package/dist/scheduling.d.ts +155 -43
- package/dist/scheduling.js +188 -50
- package/dist/service-mode.d.ts +88 -0
- package/dist/service-mode.js +130 -0
- package/dist/tenancy.d.ts +54 -30
- package/dist/tenancy.js +35 -17
- package/dist/timing.d.ts +39 -0
- package/dist/timing.js +51 -0
- package/dist/zod-values.d.ts +1 -1
- package/dist/zod-values.js +1 -1
- package/dist/zod.d.ts +1 -1
- package/dist/zod.js +1 -1
- package/generated/v1/examples/billing.noticesdismiss.request.json +3 -0
- package/generated/v1/examples/billing.noticesdismiss.response.json +6 -0
- package/generated/v1/examples/billing.reconcile.response.json +12 -0
- package/generated/v1/examples/billing.summary.response.json +12 -0
- package/generated/v1/examples/executions.list.response.json +1 -0
- package/generated/v1/examples/limits.read.response.json +1 -1
- package/generated/v1/examples/projectnotifications.rotateSigningKey.response.json +1 -0
- package/generated/v1/examples/projects.list.response.json +0 -6
- package/generated/v1/examples/projects.read.response.json +14 -0
- package/generated/v1/examples/schedules.list.response.json +1 -3
- package/generated/v1/examples/schedules.summary.response.json +174 -0
- package/generated/v1/examples/timing.summary.response.json +33 -1
- package/generated/v1/manifest.json +79 -2
- package/generated/v1/openapi.json +4084 -2023
- package/generated/v1/policy-matrix.json +22 -1
- package/generated/v1/schemas/attempts.list.response.json +10 -0
- package/generated/v1/schemas/attempts.read.response.json +10 -0
- package/generated/v1/schemas/attempts.search.response.json +4 -0
- package/generated/v1/schemas/billing.notices.query.json +4 -0
- package/generated/v1/schemas/billing.noticesdismiss.request.json +12 -0
- package/generated/v1/schemas/billing.noticesdismiss.response.json +22 -0
- package/generated/v1/schemas/billing.reconcile.response.json +43 -0
- package/generated/v1/schemas/billing.summary.response.json +43 -0
- package/generated/v1/schemas/endpoints.list.query.json +15 -0
- package/generated/v1/schemas/executions.list.response.json +4 -0
- package/generated/v1/schemas/occurrences.list.response.json +4 -0
- package/generated/v1/schemas/occurrences.read.response.json +4 -0
- package/generated/v1/schemas/occurrences.redeliver.response.json +10 -0
- package/generated/v1/schemas/projectnotifications.read.response.json +4 -0
- package/generated/v1/schemas/projectnotifications.rotateSigningKey.response.json +4 -0
- package/generated/v1/schemas/projectnotifications.update.request.json +41 -17
- package/generated/v1/schemas/projectnotifications.update.response.json +4 -0
- package/generated/v1/schemas/projects.list.response.json +0 -27
- package/generated/v1/schemas/projects.read.response-headers.json +11 -0
- package/generated/v1/schemas/projects.read.response.json +79 -0
- package/generated/v1/schemas/schedules.archive.response.json +8 -0
- package/generated/v1/schemas/schedules.cancel.response.json +8 -0
- package/generated/v1/schemas/schedules.create.request.json +1 -1
- package/generated/v1/schemas/schedules.create.response.json +8 -0
- package/generated/v1/schemas/schedules.list.query.json +6 -0
- package/generated/v1/schemas/schedules.list.response.json +4 -0
- package/generated/v1/schemas/schedules.pause.response.json +8 -0
- package/generated/v1/schemas/schedules.read.response.json +8 -0
- package/generated/v1/schemas/schedules.replace.request.json +1 -1
- package/generated/v1/schemas/schedules.replace.response.json +8 -0
- package/generated/v1/schemas/schedules.resume.response.json +8 -0
- package/generated/v1/schemas/schedules.summary.query.json +11 -0
- package/generated/v1/schemas/schedules.summary.response.json +144 -0
- package/generated/v1/schemas/timing.summary.response.json +69 -0
- package/generated/v1/snippets/billing.noticesdismiss.json +6 -0
- package/generated/v1/snippets/projectnotifications.rotateSigningKey.json +1 -1
- package/generated/v1/snippets/projects.read.json +6 -0
- package/generated/v1/snippets/schedules.summary.json +6 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "./zod.js";
|
|
2
2
|
import { environmentKindSchema } from "./authority.js";
|
|
3
|
-
import { callbackSigningKeyIdSchema, occurrenceIdSchema, projectIdSchema, scheduleIdSchema, } from "./identifiers.js";
|
|
3
|
+
import { callbackSigningKeyIdSchema, endpointIdSchema, occurrenceIdSchema, projectIdSchema, scheduleIdSchema, } from "./identifiers.js";
|
|
4
4
|
import { memberIdSchema } from "./members.js";
|
|
5
5
|
import { timestampSchema } from "./time.js";
|
|
6
6
|
import { pageRequestSchema, requiredIdempotencyRequestHeaderSchema, } from "./protocol.js";
|
|
@@ -23,13 +23,26 @@ export const notificationEmailSettingsSchema = z.strictObject({
|
|
|
23
23
|
scheduleKinds: z.enum(["both", "one-shot", "recurring"]),
|
|
24
24
|
});
|
|
25
25
|
export const statusWebhookEventSchema = z.enum(["failed"]);
|
|
26
|
+
const statusWebhookEventsSchema = z
|
|
27
|
+
.array(statusWebhookEventSchema)
|
|
28
|
+
.min(1)
|
|
29
|
+
.max(1)
|
|
30
|
+
.refine((events) => new Set(events).size === events.length, "events must be unique");
|
|
31
|
+
/**
|
|
32
|
+
* The earlier configuration: a bare URL. Still accepted (W9-84): the endpoint
|
|
33
|
+
* at that URL is found or created, as endpoints.ensure does, and linked.
|
|
34
|
+
*/
|
|
26
35
|
export const statusWebhookConfigurationSchema = z.strictObject({
|
|
27
36
|
url: z.string().url().max(2_048),
|
|
28
|
-
events:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
events: statusWebhookEventsSchema,
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* The status webhook's destination (W9-84): a callback endpoint in this
|
|
41
|
+
* project and environment, whose URL, headers and signing keys apply.
|
|
42
|
+
*/
|
|
43
|
+
export const statusWebhookEndpointConfigurationSchema = z.strictObject({
|
|
44
|
+
endpoint: endpointIdSchema,
|
|
45
|
+
events: statusWebhookEventsSchema,
|
|
33
46
|
});
|
|
34
47
|
export const projectNotificationSettingsSchema = z.strictObject({
|
|
35
48
|
project: projectIdSchema,
|
|
@@ -38,6 +51,9 @@ export const projectNotificationSettingsSchema = z.strictObject({
|
|
|
38
51
|
email: notificationEmailSettingsSchema,
|
|
39
52
|
statusWebhook: statusWebhookConfigurationSchema
|
|
40
53
|
.extend({
|
|
54
|
+
/** The destination endpoint; absent only for a URL saved before W9-84 without a key. */
|
|
55
|
+
endpoint: endpointIdSchema.optional(),
|
|
56
|
+
/** The key that signs: the endpoint's next key while one is staged, else its current one. */
|
|
41
57
|
signingKey: z.strictObject({ id: callbackSigningKeyIdSchema }).optional(),
|
|
42
58
|
revision: z.number().int().positive(),
|
|
43
59
|
})
|
|
@@ -47,7 +63,13 @@ export const projectNotificationSettingsUpdateRequestSchema = z
|
|
|
47
63
|
.strictObject({
|
|
48
64
|
expectedRevision: z.number().int().positive(),
|
|
49
65
|
email: notificationEmailSettingsSchema.optional(),
|
|
50
|
-
statusWebhook:
|
|
66
|
+
statusWebhook: z
|
|
67
|
+
.union([
|
|
68
|
+
statusWebhookEndpointConfigurationSchema,
|
|
69
|
+
statusWebhookConfigurationSchema,
|
|
70
|
+
])
|
|
71
|
+
.nullable()
|
|
72
|
+
.optional(),
|
|
51
73
|
})
|
|
52
74
|
.refine((request) => request.email !== undefined || request.statusWebhook !== undefined, "choose settings to change");
|
|
53
75
|
export const statusSigningKeyRequestSchema = z.strictObject({
|
|
@@ -57,6 +79,11 @@ export const statusSigningKeyCreatedSchema = z.strictObject({
|
|
|
57
79
|
settings: projectNotificationSettingsSchema,
|
|
58
80
|
keyId: callbackSigningKeyIdSchema,
|
|
59
81
|
secret: z.string().min(1),
|
|
82
|
+
/**
|
|
83
|
+
* Kept for compatibility (W9-84). The secret is the destination endpoint's,
|
|
84
|
+
* so a signed-in member can also reveal it on the endpoint's page, as for
|
|
85
|
+
* every endpoint secret; `shownOnce` no longer means this is the only copy.
|
|
86
|
+
*/
|
|
60
87
|
shownOnce: z.literal(true),
|
|
61
88
|
});
|
|
62
89
|
/** Safe notification payload: no customer request or response content. */
|
|
@@ -144,6 +171,8 @@ export const PROJECT_NOTIFICATION_OPERATIONS = defineOperations([
|
|
|
144
171
|
"revision_conflict",
|
|
145
172
|
"idempotency_key_reused",
|
|
146
173
|
"rate_limited",
|
|
174
|
+
"scope_missing",
|
|
175
|
+
"state_conflict",
|
|
147
176
|
],
|
|
148
177
|
requestHeaders: requiredIdempotencyRequestHeaderSchema,
|
|
149
178
|
request: projectNotificationSettingsUpdateRequestSchema,
|
|
@@ -161,7 +190,7 @@ export const PROJECT_NOTIFICATION_OPERATIONS = defineOperations([
|
|
|
161
190
|
: "Update delivery notification settings",
|
|
162
191
|
description: globals.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
163
192
|
? ""
|
|
164
|
-
: "An admin updates this project's environment preferences at an expected revision. Selected recipients must be current organization members; arbitrary email addresses are not accepted.
|
|
193
|
+
: "An admin updates this project's environment preferences at an expected revision. Selected recipients must be current organization members; arbitrary email addresses are not accepted. The status webhook names its destination as `endpoint`, an enabled callback endpoint in this project and environment, which needs `endpoints:read`: failure events go to its URL with its headers, signed with its key, and delivery starts at once. A `url` instead is the earlier form: the endpoint at that address is found or created (the endpoints.ensure rules; creating needs `endpoints:write`) and linked. Without the scope a form needs, the request is refused as `scope_missing`. Null disables the status webhook. No signing secret is returned; a signed-in member reveals it on the endpoint's page. Failed means final unsuccessful settlement. Redelivery never repeats it. Failed-event webhook calls and their retries are free. Every failed occurrence is emailed separately; no summary window suppresses failures.",
|
|
165
194
|
},
|
|
166
195
|
{
|
|
167
196
|
...common,
|
|
@@ -172,14 +201,15 @@ export const PROJECT_NOTIFICATION_OPERATIONS = defineOperations([
|
|
|
172
201
|
mutates: true,
|
|
173
202
|
mcp: {
|
|
174
203
|
kind: "unavailable",
|
|
175
|
-
reason: "
|
|
204
|
+
reason: "Rotating returns a signing secret, and MCP has no negotiated secure-result channel that keeps it out of ordinary tool history. Choose the status webhook's endpoint with projectnotifications_update; reveal or rotate that endpoint's key on its page in the dashboard, or with endpoints.rotateSigningKey through an authenticated REST/SDK/CLI client.",
|
|
176
205
|
},
|
|
177
|
-
scopes: ["projects:administer"],
|
|
206
|
+
scopes: ["projects:administer", "endpoints:write"],
|
|
178
207
|
problems: [
|
|
179
208
|
...common.problems,
|
|
180
209
|
"revision_conflict",
|
|
181
210
|
"state_conflict",
|
|
182
211
|
"capability_not_configured",
|
|
212
|
+
"scope_missing",
|
|
183
213
|
],
|
|
184
214
|
request: statusSigningKeyRequestSchema,
|
|
185
215
|
requestExample: globals.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
@@ -197,6 +227,7 @@ export const PROJECT_NOTIFICATION_OPERATIONS = defineOperations([
|
|
|
197
227
|
statusWebhook: {
|
|
198
228
|
url: "https://hooks.example.com/status",
|
|
199
229
|
events: ["failed"],
|
|
230
|
+
endpoint: "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
200
231
|
revision: 2,
|
|
201
232
|
signingKey: { id: "csk_01h8xyz9k2m4n6p8r0t2v4w6y8" },
|
|
202
233
|
},
|
|
@@ -207,10 +238,10 @@ export const PROJECT_NOTIFICATION_OPERATIONS = defineOperations([
|
|
|
207
238
|
},
|
|
208
239
|
summary: globals.GREATWAIT_API_REQUEST_REGISTRY
|
|
209
240
|
? ""
|
|
210
|
-
: "
|
|
241
|
+
: "Rotate the status webhook endpoint's signing key",
|
|
211
242
|
description: globals.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
212
243
|
? ""
|
|
213
|
-
: "
|
|
244
|
+
: "The earlier form, kept for existing clients: at an expected revision, rotate the signing key of the configured status webhook's endpoint exactly as endpoints.rotateSigningKey does with its default overlap. The key is the endpoint's and is shared with every schedule using it, so this also needs `endpoints:write`; without it the request is refused as `scope_missing`. A webhook saved as a bare URL is first linked to the endpoint at that address. New deliveries are signed with the new key at once, and receivers keep accepting the previous key until the overlap ends. The secret appears in this successful response and, like every endpoint secret, is also revealable by a signed-in member on the endpoint's page; `shownOnce` is kept for compatibility. The request is not automatically replayable; stale retries are refused. The signature covers the exact emitted body bytes.",
|
|
214
245
|
},
|
|
215
246
|
{
|
|
216
247
|
...common,
|
package/dist/protocol.d.ts
CHANGED
|
@@ -39,6 +39,18 @@ export type PageRequest = z.infer<typeof pageRequestSchema>;
|
|
|
39
39
|
*/
|
|
40
40
|
export declare const SCHEDULE_ORDERS: readonly ["created", "due"];
|
|
41
41
|
export type ScheduleOrder = (typeof SCHEDULE_ORDERS)[number];
|
|
42
|
+
/**
|
|
43
|
+
* Which way a schedules listing walks its order (W9-80, FXO-3446).
|
|
44
|
+
*
|
|
45
|
+
* `asc` is what every listing has always done and keeps by default, so a
|
|
46
|
+
* client that never heard of this parameter sees nothing change. `desc` is
|
|
47
|
+
* newest-created first under `created` (the newest schedule is one row away
|
|
48
|
+
* rather than a whole book away) and latest-due first under `due`. A cursor is
|
|
49
|
+
* a position in one direction only: one issued walking `desc` is refused under
|
|
50
|
+
* `asc`, and the other way round.
|
|
51
|
+
*/
|
|
52
|
+
export declare const SCHEDULE_DIRECTIONS: readonly ["asc", "desc"];
|
|
53
|
+
export type ScheduleDirection = (typeof SCHEDULE_DIRECTIONS)[number];
|
|
42
54
|
/**
|
|
43
55
|
* A schedules listing: the page, optionally one endpoint, and how to order it.
|
|
44
56
|
*
|
|
@@ -58,6 +70,10 @@ export declare const scheduleListRequestSchema: import("zod").ZodObject<{
|
|
|
58
70
|
due: "due";
|
|
59
71
|
created: "created";
|
|
60
72
|
}>>;
|
|
73
|
+
direction: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
74
|
+
asc: "asc";
|
|
75
|
+
desc: "desc";
|
|
76
|
+
}>>;
|
|
61
77
|
external_identifier: import("zod").ZodOptional<import("zod").ZodString>;
|
|
62
78
|
tag: import("zod").ZodOptional<import("zod").ZodString>;
|
|
63
79
|
status: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
@@ -245,6 +261,18 @@ export type ScheduleListRequestParse = {
|
|
|
245
261
|
readonly ok: false;
|
|
246
262
|
readonly errors: readonly FieldError[];
|
|
247
263
|
};
|
|
264
|
+
/**
|
|
265
|
+
* Any listing request whose fields are page parameters plus string filters,
|
|
266
|
+
* read from a query string under the same rules as {@link parsePageRequest}
|
|
267
|
+
* (W9-80: the endpoints listing's filters).
|
|
268
|
+
*/
|
|
269
|
+
export declare function parseListingRequest<TSchema extends z.ZodTypeAny>(query: URLSearchParams, schema: TSchema): {
|
|
270
|
+
readonly ok: true;
|
|
271
|
+
readonly page: z.infer<TSchema>;
|
|
272
|
+
} | {
|
|
273
|
+
readonly ok: false;
|
|
274
|
+
readonly errors: readonly FieldError[];
|
|
275
|
+
};
|
|
248
276
|
/** A schedules listing request: the page, and the endpoint filter if given. */
|
|
249
277
|
export declare function parseScheduleListRequest(query: URLSearchParams): ScheduleListRequestParse;
|
|
250
278
|
export type HistoryPageRequestParse = {
|
package/dist/protocol.js
CHANGED
|
@@ -43,6 +43,17 @@ export const pageRequestSchema = /* @__PURE__ */ (() => z.object({
|
|
|
43
43
|
* creation instant.
|
|
44
44
|
*/
|
|
45
45
|
export const SCHEDULE_ORDERS = ["created", "due"];
|
|
46
|
+
/**
|
|
47
|
+
* Which way a schedules listing walks its order (W9-80, FXO-3446).
|
|
48
|
+
*
|
|
49
|
+
* `asc` is what every listing has always done and keeps by default, so a
|
|
50
|
+
* client that never heard of this parameter sees nothing change. `desc` is
|
|
51
|
+
* newest-created first under `created` (the newest schedule is one row away
|
|
52
|
+
* rather than a whole book away) and latest-due first under `due`. A cursor is
|
|
53
|
+
* a position in one direction only: one issued walking `desc` is refused under
|
|
54
|
+
* `asc`, and the other way round.
|
|
55
|
+
*/
|
|
56
|
+
export const SCHEDULE_DIRECTIONS = ["asc", "desc"];
|
|
46
57
|
/**
|
|
47
58
|
* A schedules listing: the page, optionally one endpoint, and how to order it.
|
|
48
59
|
*
|
|
@@ -58,6 +69,10 @@ export const SCHEDULE_ORDERS = ["created", "due"];
|
|
|
58
69
|
export const scheduleListRequestSchema = /* @__PURE__ */ (() => pageRequestSchema.extend({
|
|
59
70
|
...scheduleSelectionSchema.shape,
|
|
60
71
|
order: z.enum(SCHEDULE_ORDERS).default("created"),
|
|
72
|
+
direction: z
|
|
73
|
+
.enum(SCHEDULE_DIRECTIONS)
|
|
74
|
+
.default("asc")
|
|
75
|
+
.describe("asc (default) walks the order oldest-created or soonest-due first; desc walks it newest-created or latest-due first. A cursor continues only in the direction that issued it."),
|
|
61
76
|
}))();
|
|
62
77
|
/**
|
|
63
78
|
* Which end of a history a page walks from.
|
|
@@ -287,6 +302,14 @@ function parametersOf(schema) {
|
|
|
287
302
|
export function parsePageRequest(query) {
|
|
288
303
|
return parseListing(query, pageRequestSchema);
|
|
289
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Any listing request whose fields are page parameters plus string filters,
|
|
307
|
+
* read from a query string under the same rules as {@link parsePageRequest}
|
|
308
|
+
* (W9-80: the endpoints listing's filters).
|
|
309
|
+
*/
|
|
310
|
+
export function parseListingRequest(query, schema) {
|
|
311
|
+
return parseListing(query, schema);
|
|
312
|
+
}
|
|
290
313
|
/** A schedules listing request: the page, and the endpoint filter if given. */
|
|
291
314
|
export function parseScheduleListRequest(query) {
|
|
292
315
|
return parseListing(query, scheduleListRequestSchema);
|
|
@@ -34,11 +34,21 @@ export declare const portableScheduleRecordSchema: import("zod").ZodObject<{
|
|
|
34
34
|
name: import("zod").ZodString;
|
|
35
35
|
suppressed: import("zod").ZodLiteral<true>;
|
|
36
36
|
}, import("zod/v4/core").$strict>]>>;
|
|
37
|
-
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
37
|
+
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
38
38
|
keyId: import("zod").ZodLiteral<"v1">;
|
|
39
39
|
nonce: import("zod").ZodString;
|
|
40
40
|
ciphertext: import("zod").ZodString;
|
|
41
|
-
}, import("zod/v4/core").$strict
|
|
41
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
42
|
+
keyId: import("zod").ZodLiteral<"v1">;
|
|
43
|
+
nonce: import("zod").ZodString;
|
|
44
|
+
ciphertext: import("zod").ZodString;
|
|
45
|
+
version: import("zod").ZodLiteral<2>;
|
|
46
|
+
codec: import("zod").ZodEnum<{
|
|
47
|
+
identity: "identity";
|
|
48
|
+
gzip: "gzip";
|
|
49
|
+
}>;
|
|
50
|
+
originalBytes: import("zod").ZodNumber;
|
|
51
|
+
}, import("zod/v4/core").$strict>]>>;
|
|
42
52
|
}, import("zod/v4/core").$strict>>;
|
|
43
53
|
httpTemplateRetentionDueAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
44
54
|
authority: import("zod").ZodObject<{
|
|
@@ -106,9 +116,14 @@ export declare const portableScheduleRecordSchema: import("zod").ZodObject<{
|
|
|
106
116
|
generation: import("zod").ZodNumber;
|
|
107
117
|
id: import("zod").ZodString;
|
|
108
118
|
latencyClass: import("zod").ZodEnum<{
|
|
109
|
-
realtime: "realtime";
|
|
110
119
|
bulk: "bulk";
|
|
120
|
+
realtime: "realtime";
|
|
111
121
|
}>;
|
|
122
|
+
requestedLatencyClass: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
123
|
+
bulk: "bulk";
|
|
124
|
+
realtime: "realtime";
|
|
125
|
+
auto: "auto";
|
|
126
|
+
}>>;
|
|
112
127
|
lateness: import("zod").ZodObject<{
|
|
113
128
|
maxStalenessSeconds: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
114
129
|
policy: import("zod").ZodEnum<{
|
|
@@ -169,6 +184,7 @@ export declare const portableOccurrenceRecordSchema: import("zod").ZodObject<{
|
|
|
169
184
|
id: import("zod").ZodString;
|
|
170
185
|
plannedFor: import("zod").ZodString;
|
|
171
186
|
schedule: import("zod").ZodString;
|
|
187
|
+
scheduleName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
172
188
|
sequence: import("zod").ZodNumber;
|
|
173
189
|
settledAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
174
190
|
state: import("zod").ZodEnum<{
|
|
@@ -269,6 +285,12 @@ export declare const portableAttemptRecordSchema: import("zod").ZodObject<{
|
|
|
269
285
|
expired: "expired";
|
|
270
286
|
not_captured: "not_captured";
|
|
271
287
|
}>>;
|
|
288
|
+
requestUnavailable: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
289
|
+
schedule_changed: "schedule_changed";
|
|
290
|
+
endpoint_changed: "endpoint_changed";
|
|
291
|
+
endpoint_deleted: "endpoint_deleted";
|
|
292
|
+
payload_deleted: "payload_deleted";
|
|
293
|
+
}>>;
|
|
272
294
|
responseHeaders: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
|
|
273
295
|
name: import("zod").ZodString;
|
|
274
296
|
value: import("zod").ZodString;
|
|
@@ -349,11 +371,21 @@ export declare const portableAttemptRecordSchema: import("zod").ZodObject<{
|
|
|
349
371
|
name: import("zod").ZodString;
|
|
350
372
|
suppressed: import("zod").ZodLiteral<true>;
|
|
351
373
|
}, import("zod/v4/core").$strict>]>>;
|
|
352
|
-
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
374
|
+
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
353
375
|
keyId: import("zod").ZodLiteral<"v1">;
|
|
354
376
|
nonce: import("zod").ZodString;
|
|
355
377
|
ciphertext: import("zod").ZodString;
|
|
356
|
-
}, import("zod/v4/core").$strict
|
|
378
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
379
|
+
keyId: import("zod").ZodLiteral<"v1">;
|
|
380
|
+
nonce: import("zod").ZodString;
|
|
381
|
+
ciphertext: import("zod").ZodString;
|
|
382
|
+
version: import("zod").ZodLiteral<2>;
|
|
383
|
+
codec: import("zod").ZodEnum<{
|
|
384
|
+
identity: "identity";
|
|
385
|
+
gzip: "gzip";
|
|
386
|
+
}>;
|
|
387
|
+
originalBytes: import("zod").ZodNumber;
|
|
388
|
+
}, import("zod/v4/core").$strict>]>>;
|
|
357
389
|
}, import("zod/v4/core").$strict>>;
|
|
358
390
|
httpPayloadRetentionDueAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
359
391
|
authority: import("zod").ZodObject<{
|
|
@@ -371,7 +403,10 @@ export declare const portableAttemptRecordSchema: import("zod").ZodObject<{
|
|
|
371
403
|
}, import("zod/v4/core").$strict>;
|
|
372
404
|
export type PortableAttemptRecord = z.infer<typeof portableAttemptRecordSchema>;
|
|
373
405
|
export declare const portableEncryptedPayloadRecordSchema: import("zod").ZodObject<{
|
|
374
|
-
aadVersion: import("zod").
|
|
406
|
+
aadVersion: import("zod").ZodEnum<{
|
|
407
|
+
"greatwait.schedule-payload.v1": "greatwait.schedule-payload.v1";
|
|
408
|
+
"greatwait.schedule-payload.v2": "greatwait.schedule-payload.v2";
|
|
409
|
+
}>;
|
|
375
410
|
authority: import("zod").ZodObject<{
|
|
376
411
|
environment: import("zod").ZodString;
|
|
377
412
|
environmentKind: import("zod").ZodEnum<{
|
|
@@ -381,11 +416,21 @@ export declare const portableEncryptedPayloadRecordSchema: import("zod").ZodObje
|
|
|
381
416
|
organization: import("zod").ZodString;
|
|
382
417
|
project: import("zod").ZodString;
|
|
383
418
|
}, import("zod/v4/core").$strict>;
|
|
384
|
-
envelope: import("zod").ZodObject<{
|
|
419
|
+
envelope: import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
385
420
|
ciphertext: import("zod").ZodString;
|
|
386
421
|
keyId: import("zod").ZodString;
|
|
387
422
|
nonce: import("zod").ZodString;
|
|
388
|
-
}, import("zod/v4/core").$strict
|
|
423
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
424
|
+
ciphertext: import("zod").ZodString;
|
|
425
|
+
keyId: import("zod").ZodString;
|
|
426
|
+
nonce: import("zod").ZodString;
|
|
427
|
+
version: import("zod").ZodLiteral<2>;
|
|
428
|
+
codec: import("zod").ZodEnum<{
|
|
429
|
+
identity: "identity";
|
|
430
|
+
gzip: "gzip";
|
|
431
|
+
}>;
|
|
432
|
+
originalBytes: import("zod").ZodNumber;
|
|
433
|
+
}, import("zod/v4/core").$strict>]>;
|
|
389
434
|
plaintextBytes: import("zod").ZodNumber;
|
|
390
435
|
retentionDueAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
391
436
|
schedule: import("zod").ZodString;
|
|
@@ -457,6 +502,12 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
457
502
|
expired: "expired";
|
|
458
503
|
not_captured: "not_captured";
|
|
459
504
|
}>>;
|
|
505
|
+
requestUnavailable: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
506
|
+
schedule_changed: "schedule_changed";
|
|
507
|
+
endpoint_changed: "endpoint_changed";
|
|
508
|
+
endpoint_deleted: "endpoint_deleted";
|
|
509
|
+
payload_deleted: "payload_deleted";
|
|
510
|
+
}>>;
|
|
460
511
|
responseHeaders: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
|
|
461
512
|
name: import("zod").ZodString;
|
|
462
513
|
value: import("zod").ZodString;
|
|
@@ -537,11 +588,21 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
537
588
|
name: import("zod").ZodString;
|
|
538
589
|
suppressed: import("zod").ZodLiteral<true>;
|
|
539
590
|
}, import("zod/v4/core").$strict>]>>;
|
|
540
|
-
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
591
|
+
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
541
592
|
keyId: import("zod").ZodLiteral<"v1">;
|
|
542
593
|
nonce: import("zod").ZodString;
|
|
543
594
|
ciphertext: import("zod").ZodString;
|
|
544
|
-
}, import("zod/v4/core").$strict
|
|
595
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
596
|
+
keyId: import("zod").ZodLiteral<"v1">;
|
|
597
|
+
nonce: import("zod").ZodString;
|
|
598
|
+
ciphertext: import("zod").ZodString;
|
|
599
|
+
version: import("zod").ZodLiteral<2>;
|
|
600
|
+
codec: import("zod").ZodEnum<{
|
|
601
|
+
identity: "identity";
|
|
602
|
+
gzip: "gzip";
|
|
603
|
+
}>;
|
|
604
|
+
originalBytes: import("zod").ZodNumber;
|
|
605
|
+
}, import("zod/v4/core").$strict>]>>;
|
|
545
606
|
}, import("zod/v4/core").$strict>>;
|
|
546
607
|
httpPayloadRetentionDueAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
547
608
|
authority: import("zod").ZodObject<{
|
|
@@ -562,6 +623,7 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
562
623
|
id: import("zod").ZodString;
|
|
563
624
|
plannedFor: import("zod").ZodString;
|
|
564
625
|
schedule: import("zod").ZodString;
|
|
626
|
+
scheduleName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
565
627
|
sequence: import("zod").ZodNumber;
|
|
566
628
|
settledAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
567
629
|
state: import("zod").ZodEnum<{
|
|
@@ -599,7 +661,10 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
599
661
|
updatedAt: import("zod").ZodString;
|
|
600
662
|
}, import("zod/v4/core").$strict>>;
|
|
601
663
|
payload: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
602
|
-
aadVersion: import("zod").
|
|
664
|
+
aadVersion: import("zod").ZodEnum<{
|
|
665
|
+
"greatwait.schedule-payload.v1": "greatwait.schedule-payload.v1";
|
|
666
|
+
"greatwait.schedule-payload.v2": "greatwait.schedule-payload.v2";
|
|
667
|
+
}>;
|
|
603
668
|
authority: import("zod").ZodObject<{
|
|
604
669
|
environment: import("zod").ZodString;
|
|
605
670
|
environmentKind: import("zod").ZodEnum<{
|
|
@@ -609,11 +674,21 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
609
674
|
organization: import("zod").ZodString;
|
|
610
675
|
project: import("zod").ZodString;
|
|
611
676
|
}, import("zod/v4/core").$strict>;
|
|
612
|
-
envelope: import("zod").ZodObject<{
|
|
677
|
+
envelope: import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
613
678
|
ciphertext: import("zod").ZodString;
|
|
614
679
|
keyId: import("zod").ZodString;
|
|
615
680
|
nonce: import("zod").ZodString;
|
|
616
|
-
}, import("zod/v4/core").$strict
|
|
681
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
682
|
+
ciphertext: import("zod").ZodString;
|
|
683
|
+
keyId: import("zod").ZodString;
|
|
684
|
+
nonce: import("zod").ZodString;
|
|
685
|
+
version: import("zod").ZodLiteral<2>;
|
|
686
|
+
codec: import("zod").ZodEnum<{
|
|
687
|
+
identity: "identity";
|
|
688
|
+
gzip: "gzip";
|
|
689
|
+
}>;
|
|
690
|
+
originalBytes: import("zod").ZodNumber;
|
|
691
|
+
}, import("zod/v4/core").$strict>]>;
|
|
617
692
|
plaintextBytes: import("zod").ZodNumber;
|
|
618
693
|
retentionDueAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
619
694
|
schedule: import("zod").ZodString;
|
|
@@ -677,11 +752,21 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
677
752
|
name: import("zod").ZodString;
|
|
678
753
|
suppressed: import("zod").ZodLiteral<true>;
|
|
679
754
|
}, import("zod/v4/core").$strict>]>>;
|
|
680
|
-
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
755
|
+
encryptedTemplate: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
756
|
+
keyId: import("zod").ZodLiteral<"v1">;
|
|
757
|
+
nonce: import("zod").ZodString;
|
|
758
|
+
ciphertext: import("zod").ZodString;
|
|
759
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
681
760
|
keyId: import("zod").ZodLiteral<"v1">;
|
|
682
761
|
nonce: import("zod").ZodString;
|
|
683
762
|
ciphertext: import("zod").ZodString;
|
|
684
|
-
|
|
763
|
+
version: import("zod").ZodLiteral<2>;
|
|
764
|
+
codec: import("zod").ZodEnum<{
|
|
765
|
+
identity: "identity";
|
|
766
|
+
gzip: "gzip";
|
|
767
|
+
}>;
|
|
768
|
+
originalBytes: import("zod").ZodNumber;
|
|
769
|
+
}, import("zod/v4/core").$strict>]>>;
|
|
685
770
|
}, import("zod/v4/core").$strict>>;
|
|
686
771
|
httpTemplateRetentionDueAt: import("zod").ZodOptional<import("zod").ZodString>;
|
|
687
772
|
authority: import("zod").ZodObject<{
|
|
@@ -749,9 +834,14 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
749
834
|
generation: import("zod").ZodNumber;
|
|
750
835
|
id: import("zod").ZodString;
|
|
751
836
|
latencyClass: import("zod").ZodEnum<{
|
|
752
|
-
realtime: "realtime";
|
|
753
837
|
bulk: "bulk";
|
|
838
|
+
realtime: "realtime";
|
|
754
839
|
}>;
|
|
840
|
+
requestedLatencyClass: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
841
|
+
bulk: "bulk";
|
|
842
|
+
realtime: "realtime";
|
|
843
|
+
auto: "auto";
|
|
844
|
+
}>>;
|
|
755
845
|
lateness: import("zod").ZodObject<{
|
|
756
846
|
maxStalenessSeconds: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
757
847
|
policy: import("zod").ZodEnum<{
|
|
@@ -116,19 +116,35 @@ const base64UrlBytesSchema = z
|
|
|
116
116
|
.refine((value) => decodeBase64UrlBytes(value) !== undefined, {
|
|
117
117
|
message: "must canonically encode base64url bytes",
|
|
118
118
|
});
|
|
119
|
+
const portableLegacyPayloadEnvelopeSchema = z.strictObject({
|
|
120
|
+
ciphertext: base64UrlBytesSchema,
|
|
121
|
+
keyId: z
|
|
122
|
+
.string()
|
|
123
|
+
.min(1)
|
|
124
|
+
.max(128)
|
|
125
|
+
.regex(/^[A-Za-z0-9._:-]+$/u, "must be a safe key identifier"),
|
|
126
|
+
nonce: base64UrlBytesSchema.refine((value) => decodeBase64UrlBytes(value)?.length === 12, { message: "must encode exactly 12 bytes" }),
|
|
127
|
+
});
|
|
128
|
+
const portableV2PayloadEnvelopeSchema = portableLegacyPayloadEnvelopeSchema.extend({
|
|
129
|
+
version: z.literal(2),
|
|
130
|
+
codec: z.enum(["identity", "gzip"]),
|
|
131
|
+
originalBytes: z
|
|
132
|
+
.number()
|
|
133
|
+
.int()
|
|
134
|
+
.nonnegative()
|
|
135
|
+
.max(SCHEDULING_BOUNDS.payloadBytes),
|
|
136
|
+
});
|
|
119
137
|
export const portableEncryptedPayloadRecordSchema = z
|
|
120
138
|
.strictObject({
|
|
121
|
-
aadVersion: z.
|
|
139
|
+
aadVersion: z.enum([
|
|
140
|
+
SCHEDULE_PAYLOAD_AAD_VERSION,
|
|
141
|
+
"greatwait.schedule-payload.v2",
|
|
142
|
+
]),
|
|
122
143
|
authority: portableAuthoritySchema,
|
|
123
|
-
envelope: z.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
.min(1)
|
|
128
|
-
.max(128)
|
|
129
|
-
.regex(/^[A-Za-z0-9._:-]+$/u, "must be a safe key identifier"),
|
|
130
|
-
nonce: base64UrlBytesSchema.refine((value) => decodeBase64UrlBytes(value)?.length === 12, { message: "must encode exactly 12 bytes" }),
|
|
131
|
-
}),
|
|
144
|
+
envelope: z.union([
|
|
145
|
+
portableLegacyPayloadEnvelopeSchema,
|
|
146
|
+
portableV2PayloadEnvelopeSchema,
|
|
147
|
+
]),
|
|
132
148
|
plaintextBytes: z
|
|
133
149
|
.number()
|
|
134
150
|
.int()
|
|
@@ -142,10 +158,18 @@ export const portableEncryptedPayloadRecordSchema = z
|
|
|
142
158
|
.superRefine((payload, context) => {
|
|
143
159
|
const ciphertext = decodeBase64UrlBytes(payload.envelope.ciphertext);
|
|
144
160
|
if (ciphertext !== undefined &&
|
|
145
|
-
|
|
161
|
+
("version" in payload.envelope
|
|
162
|
+
? payload.aadVersion !== "greatwait.schedule-payload.v2" ||
|
|
163
|
+
payload.envelope.originalBytes !== payload.plaintextBytes ||
|
|
164
|
+
ciphertext.length < 16 ||
|
|
165
|
+
ciphertext.length > payload.plaintextBytes + 16 ||
|
|
166
|
+
(payload.envelope.codec === "identity" &&
|
|
167
|
+
ciphertext.length !== payload.plaintextBytes + 16)
|
|
168
|
+
: payload.aadVersion !== SCHEDULE_PAYLOAD_AAD_VERSION ||
|
|
169
|
+
ciphertext.length !== payload.plaintextBytes + 16)) {
|
|
146
170
|
context.addIssue({
|
|
147
171
|
code: "custom",
|
|
148
|
-
message: "ciphertext must
|
|
172
|
+
message: "ciphertext and authenticated envelope metadata must match the payload version and size",
|
|
149
173
|
path: ["envelope", "ciphertext"],
|
|
150
174
|
});
|
|
151
175
|
}
|