@greatwait/contracts 0.1.0-alpha.5 → 0.1.0-alpha.7
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/README.md +1 -1
- package/dist/attempt-diagnostics.d.ts +8 -0
- package/dist/attempt-diagnostics.js +68 -0
- package/dist/authority.d.ts +4 -1
- package/dist/authority.js +1 -0
- package/dist/billing.d.ts +11 -10
- package/dist/billing.js +7 -4
- package/dist/data-export.d.ts +2 -0
- package/dist/delivery.d.ts +43 -40
- package/dist/delivery.js +14 -37
- package/dist/effective-limits.d.ts +4 -4
- package/dist/endpoints.d.ts +173 -5
- package/dist/endpoints.js +72 -1
- package/dist/first-value-journey.js +4 -4
- package/dist/http-request.d.ts +193 -0
- package/dist/http-request.js +305 -0
- package/dist/identity.d.ts +7 -7
- package/dist/index.d.ts +6 -3
- package/dist/index.js +5 -2
- package/dist/mcp.d.ts +2 -1
- package/dist/members.d.ts +141 -0
- package/dist/members.js +223 -0
- package/dist/oauth.d.ts +7 -0
- package/dist/operation-definitions.d.ts +20 -4
- package/dist/operation-definitions.js +9 -1
- package/dist/operations.d.ts +999 -135
- package/dist/operations.js +83 -10
- package/dist/organization-lifecycle.d.ts +10 -0
- package/dist/policy.js +5 -2
- package/dist/scheduling-records.d.ts +332 -8
- package/dist/scheduling-records.js +5 -0
- package/dist/scheduling.d.ts +485 -18
- package/dist/scheduling.js +77 -5
- package/dist/secrets.d.ts +7 -0
- package/dist/signatures.d.ts +1 -1
- package/dist/tenancy.d.ts +1 -1
- package/dist/tenancy.js +1 -1
- package/dist/test-sink.d.ts +27 -41
- package/dist/test-sink.js +12 -31
- package/dist/zod-values.d.ts +2 -2
- package/dist/zod-values.js +1 -1
- package/generated/v1/callback-receiver.json +4 -4
- package/generated/v1/examples/endpoints.ensure.request.json +3 -0
- package/generated/v1/examples/endpoints.ensure.response.json +20 -0
- package/generated/v1/examples/invitations.create.request.json +5 -0
- package/generated/v1/examples/invitations.create.response.json +7 -0
- package/generated/v1/examples/invitations.list.response.json +11 -0
- package/generated/v1/examples/invitations.resend.request.json +1 -0
- package/generated/v1/examples/invitations.resend.response.json +4 -0
- package/generated/v1/examples/invitations.revoke.request.json +3 -0
- package/generated/v1/examples/invitations.revoke.response.json +4 -0
- package/generated/v1/examples/members.list.response.json +13 -0
- package/generated/v1/examples/members.remove.request.json +3 -0
- package/generated/v1/examples/members.remove.response.json +4 -0
- package/generated/v1/examples/members.role.request.json +3 -0
- package/generated/v1/examples/members.role.response.json +4 -0
- package/generated/v1/examples/projectmembers.add.request.json +1 -0
- package/generated/v1/examples/projectmembers.add.response.json +4 -0
- package/generated/v1/examples/projectmembers.remove.request.json +3 -0
- package/generated/v1/examples/projectmembers.remove.response.json +4 -0
- package/generated/v1/first-value-journey.json +4 -4
- package/generated/v1/manifest.json +284 -0
- package/generated/v1/openapi.json +9387 -1021
- package/generated/v1/policy-matrix.json +72 -0
- package/generated/v1/schemas/attempts.list.response.json +105 -0
- package/generated/v1/schemas/attempts.read.response.json +105 -0
- package/generated/v1/schemas/billing.notices.response.json +16 -6
- package/generated/v1/schemas/context.read.response.json +1 -0
- package/generated/v1/schemas/credentials.connection.response.json +1 -0
- package/generated/v1/schemas/credentials.create.request.json +1 -0
- package/generated/v1/schemas/credentials.create.response.json +1 -0
- package/generated/v1/schemas/credentials.list.response.json +1 -0
- package/generated/v1/schemas/credentials.revoke.response.json +1 -0
- package/generated/v1/schemas/credentials.rotate.response.json +2 -0
- package/generated/v1/schemas/endpoints.acknowledgeSigningKeyRotation.response.json +59 -0
- package/generated/v1/schemas/endpoints.create.request.json +74 -0
- package/generated/v1/schemas/endpoints.create.response.json +59 -0
- package/generated/v1/schemas/endpoints.disable.response.json +59 -0
- package/generated/v1/schemas/endpoints.enable.response.json +59 -0
- package/generated/v1/schemas/endpoints.ensure.request.json +91 -0
- package/generated/v1/schemas/endpoints.ensure.response.json +169 -0
- package/generated/v1/schemas/endpoints.list.response.json +59 -0
- package/generated/v1/schemas/endpoints.read.response.json +59 -0
- package/generated/v1/schemas/endpoints.rotateSigningKey.response.json +59 -0
- package/generated/v1/schemas/endpoints.update.request.json +74 -0
- package/generated/v1/schemas/endpoints.update.response.json +59 -0
- package/generated/v1/schemas/grants.list.response.json +1 -0
- package/generated/v1/schemas/grants.revoke.response.json +1 -0
- package/generated/v1/schemas/invitations.create.request-headers.json +13 -0
- package/generated/v1/schemas/invitations.create.request.json +24 -0
- package/generated/v1/schemas/invitations.create.response.json +31 -0
- package/generated/v1/schemas/invitations.list.response.json +40 -0
- package/generated/v1/schemas/invitations.resend.request-headers.json +13 -0
- package/generated/v1/schemas/invitations.resend.request.json +6 -0
- package/generated/v1/schemas/invitations.resend.response.json +27 -0
- package/generated/v1/schemas/invitations.revoke.request-headers.json +13 -0
- package/generated/v1/schemas/invitations.revoke.request.json +12 -0
- package/generated/v1/schemas/invitations.revoke.response.json +27 -0
- package/generated/v1/schemas/members.list.response.json +53 -0
- package/generated/v1/schemas/members.remove.request-headers.json +13 -0
- package/generated/v1/schemas/members.remove.request.json +12 -0
- package/generated/v1/schemas/members.remove.response.json +27 -0
- package/generated/v1/schemas/members.role.request-headers.json +13 -0
- package/generated/v1/schemas/members.role.request.json +12 -0
- package/generated/v1/schemas/members.role.response.json +27 -0
- package/generated/v1/schemas/occurrences.redeliver.response.json +105 -0
- package/generated/v1/schemas/projectmembers.add.request-headers.json +13 -0
- package/generated/v1/schemas/projectmembers.add.request.json +6 -0
- package/generated/v1/schemas/projectmembers.add.response.json +27 -0
- package/generated/v1/schemas/projectmembers.remove.request-headers.json +13 -0
- package/generated/v1/schemas/projectmembers.remove.request.json +12 -0
- package/generated/v1/schemas/projectmembers.remove.response.json +27 -0
- package/generated/v1/schemas/schedules.archive.response.json +188 -1
- package/generated/v1/schemas/schedules.cancel.response.json +188 -1
- package/generated/v1/schemas/schedules.create.request.json +164 -1
- package/generated/v1/schemas/schedules.create.response.json +206 -1
- package/generated/v1/schemas/schedules.list.response.json +188 -1
- package/generated/v1/schemas/schedules.pause.response.json +188 -1
- package/generated/v1/schemas/schedules.read.response.json +188 -1
- package/generated/v1/schemas/schedules.replace.request.json +164 -1
- package/generated/v1/schemas/schedules.replace.response.json +206 -1
- package/generated/v1/schemas/schedules.resume.response.json +188 -1
- package/generated/v1/snippets/endpoints.create.json +1 -1
- package/generated/v1/snippets/endpoints.ensure.json +6 -0
- package/generated/v1/snippets/invitations.create.json +6 -0
- package/generated/v1/snippets/invitations.list.json +6 -0
- package/generated/v1/snippets/invitations.resend.json +6 -0
- package/generated/v1/snippets/invitations.revoke.json +6 -0
- package/generated/v1/snippets/journey/create-destination.json +1 -1
- package/generated/v1/snippets/members.list.json +6 -0
- package/generated/v1/snippets/members.remove.json +6 -0
- package/generated/v1/snippets/members.role.json +6 -0
- package/generated/v1/snippets/projectmembers.add.json +6 -0
- package/generated/v1/snippets/projectmembers.remove.json +6 -0
- package/package.json +1 -1
package/dist/operations.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { effectiveCustomerLimitsSchema } from "./effective-limits.js";
|
|
2
2
|
import { z } from "./zod.js";
|
|
3
|
+
import { MEMBER_OPERATIONS } from "./members.js";
|
|
3
4
|
import { DATA_EXPORT_OPERATIONS } from "./data-export.js";
|
|
4
5
|
import { ORGANIZATION_LIFECYCLE_OPERATIONS } from "./organization-lifecycle.js";
|
|
5
6
|
import { API_UNUSED_RESPONSE_SCHEMA } from "./operation-definitions.js";
|
|
6
7
|
import { credentialContextSchema } from "./authority.js";
|
|
7
|
-
import { callbackEndpointCreatedSchema, callbackEndpointPageSchema, callbackEndpointRequestSchema, callbackEndpointRotatedSchema, callbackEndpointSchema, callbackEndpointSigningSecretsSchema, callbackSigningKeyRotationRequestSchema, } from "./endpoints.js";
|
|
8
|
+
import { callbackEndpointCreatedSchema, callbackEndpointEnsuredSchema, callbackEndpointPageSchema, callbackEndpointRequestSchema, callbackEndpointRotatedSchema, callbackEndpointSchema, callbackEndpointSigningSecretsSchema, callbackSigningKeyRotationRequestSchema, } from "./endpoints.js";
|
|
8
9
|
import { FORECAST_WINDOW_VERSION, forecastRequestSchema, forecastSchema, forecastRequestHeadersSchema, forecastWindowsSchema, } from "./forecast.js";
|
|
9
10
|
import { usageRequestSchema, usageSchema } from "./usage.js";
|
|
10
11
|
import { deliveryTimingSummarySchema } from "./timing.js";
|
|
@@ -12,7 +13,7 @@ import { billingAutoTopUpApplyRequestSchema, billingAutoTopUpPreviewRequestSchem
|
|
|
12
13
|
import { conditionalRequestHeaderSchema, idempotencyReplayResponseHeaderSchema, idempotencyRequestHeaderSchema, historyPageRequestSchema, pageRequestSchema, scheduleListRequestSchema, replayedResponseHeaderSchema, requiredConditionalRequestHeaderSchema, requiredIdempotencyRequestHeaderSchema, versionResponseHeaderSchema, } from "./protocol.js";
|
|
13
14
|
import { oauthGrantListSchema, oauthGrantRevokedSchema } from "./oauth.js";
|
|
14
15
|
import { credentialCreatedSchema, credentialPageSchema, credentialRequestSchema, credentialRevokedSchema, credentialRotatedSchema, credentialRotationRequestSchema, } from "./secrets.js";
|
|
15
|
-
import { attemptPageSchema, attemptViewSchema, occurrencePageSchema, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceViewSchema, schedulePageSchema, scheduleRequestSchema, scheduleViewSchema, } from "./scheduling.js";
|
|
16
|
+
import { attemptPageSchema, attemptViewSchema, occurrencePageSchema, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceViewSchema, schedulePageSchema, scheduleRequestSchema, scheduleViewSchema, scheduleWrittenViewSchema, } from "./scheduling.js";
|
|
16
17
|
import { testSinkCreateRequestSchema, testSinkDeliveryBodySchema, testSinkDeliveryPageSchema, testSinkPageSchema, testSinkProgramSchema, testSinkSchema, } from "./test-sink.js";
|
|
17
18
|
import { projectArchiveRequestSchema, projectCreateRequestSchema, projectDeletedSchema, projectListSchema, projectSummarySchema, projectUpdateRequestSchema, } from "./tenancy.js";
|
|
18
19
|
import { mcpConnectionSchema } from "./mcp.js";
|
|
@@ -525,6 +526,7 @@ export const OPERATIONS = [
|
|
|
525
526
|
surfaces: ["api", "mock"],
|
|
526
527
|
},
|
|
527
528
|
...DATA_EXPORT_OPERATIONS,
|
|
529
|
+
...MEMBER_OPERATIONS,
|
|
528
530
|
...ORGANIZATION_LIFECYCLE_OPERATIONS,
|
|
529
531
|
{
|
|
530
532
|
creates: false,
|
|
@@ -659,7 +661,7 @@ export const OPERATIONS = [
|
|
|
659
661
|
creates: true,
|
|
660
662
|
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
661
663
|
? ""
|
|
662
|
-
: "Creates a reusable callback endpoint in the caller's project and environment. The destination must be HTTPS on effective port 443, contain no URL credentials or fragment, and resolve only to public unicast addresses. The endpoint is active and usable the moment it exists; there is nothing to verify. A disabled endpoint is never delivered to, and a schedule write naming one answers not_found, because disabling is terminal rather than a state to recover from. The per-endpoint secret is returned to this call and to no other call an API credential or an OAuth token can make; a signed-in member can read it again through endpoints.revealSigningSecret. There is no endpoint-count ceiling. Disabled endpoints remain readable for audit; request and DNS inspection admission bound creation work and reads are paged.",
|
|
664
|
+
: "Creates a reusable callback endpoint in the caller's project and environment. The destination must be HTTPS on effective port 443, contain no URL credentials or fragment, and resolve only to public unicast addresses. The endpoint is active and usable the moment it exists; there is nothing to verify. A disabled endpoint is never delivered to, and a schedule write naming one answers not_found, because disabling is terminal rather than a state to recover from. The per-endpoint secret is returned to this call and to no other call an API credential or an OAuth token can make; a signed-in member can read it again through endpoints.revealSigningSecret. There is no endpoint-count ceiling. Disabled endpoints remain readable for audit; request and DNS inspection admission bound creation work and reads are paged. Optional `headers` set reusable defaults. Ordinary values remain readable; `secret: true` encrypts a write-only value that is never returned. Header edits use explicit `set`, `keep`, and `remove` actions.",
|
|
663
665
|
example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
664
666
|
? {}
|
|
665
667
|
: {
|
|
@@ -680,7 +682,7 @@ export const OPERATIONS = [
|
|
|
680
682
|
idempotent: false,
|
|
681
683
|
mcp: {
|
|
682
684
|
kind: "unavailable",
|
|
683
|
-
reason: "Creation returns a one-time endpoint signing secret, and MCP has no negotiated secure-result channel that can keep it out of ordinary tool history.",
|
|
685
|
+
reason: "Creation returns a one-time endpoint signing secret, and MCP has no negotiated secure-result channel that can keep it out of ordinary tool history. Agents use endpoints_ensure, or schedules_create with a `url`, which create an endpoint without returning its secret.",
|
|
684
686
|
},
|
|
685
687
|
method: "POST",
|
|
686
688
|
mutates: true,
|
|
@@ -707,6 +709,67 @@ export const OPERATIONS = [
|
|
|
707
709
|
: "Create a callback endpoint",
|
|
708
710
|
surfaces: ["api", "mock"],
|
|
709
711
|
},
|
|
712
|
+
{
|
|
713
|
+
// Sometimes brings an endpoint into being and sometimes finds one, and a
|
|
714
|
+
// single success status has to be true of both, so it answers 200 and
|
|
715
|
+
// says which in `created`. `schedules.pause` set the precedent for a
|
|
716
|
+
// mutating POST that is not a 201.
|
|
717
|
+
creates: false,
|
|
718
|
+
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
719
|
+
? ""
|
|
720
|
+
: "Finds or creates the callback endpoint at a URL in the caller's project and environment, without returning its signing secret. With no `name`, an existing endpoint that is not disabled at exactly this address is returned unchanged, preferring the one named after its URL; with a `name`, the endpoint must also carry that name. Otherwise one is created under the same rules as endpoints.create — HTTPS on effective port 443, no URL credentials or fragment, resolving only to public unicast addresses — and `created` is true. Optional `headers` apply only to an endpoint this call creates. Sent when the endpoint already exists, they are accepted if they are exactly its ordinary headers — what a retry of the creating call sends — and otherwise refused as `state_conflict` naming it; endpoints.update changes them. A secret value cannot be compared, so a call carrying one is refused for an endpoint that already exists. The result is metadata only: `signingSecret` says that the secret is not returned and where a signed-in member reveals it (`revealUrl`, the endpoint's dashboard page). Every callback is signed with that secret whether or not the receiver checks it. This is the endpoint operation agents use over MCP; endpoints.create, which returns the secret once, is withheld there.",
|
|
721
|
+
example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
722
|
+
? {}
|
|
723
|
+
: {
|
|
724
|
+
created: true,
|
|
725
|
+
createdAt: "2026-08-05T15:00:00.000Z",
|
|
726
|
+
environmentKind: "test",
|
|
727
|
+
id: "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
728
|
+
name: "https://hooks.example.com/greatwait",
|
|
729
|
+
project: "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
730
|
+
signingKeys: { current: "csk_01h8xyz9k2m4n6p8r0t2v4w6y8" },
|
|
731
|
+
signingSecret: {
|
|
732
|
+
guidance: "GreatWait signs every callback to this endpoint. The signing secret is never returned here; a signed-in member of the project reveals it on the endpoint's page in the GreatWait dashboard, and your receiver uses it to verify that a callback came from GreatWait.",
|
|
733
|
+
returned: false,
|
|
734
|
+
revealUrl: "https://app.greatwait.dev/o/org_2example0organization0id/p/proj_01h8xyz9k2m4n6p8r0t2v4w6y8/test/settings/endpoints/ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
735
|
+
},
|
|
736
|
+
status: "active",
|
|
737
|
+
updatedAt: "2026-08-05T15:00:00.000Z",
|
|
738
|
+
url: "https://hooks.example.com/greatwait",
|
|
739
|
+
version: 1,
|
|
740
|
+
},
|
|
741
|
+
id: "endpoints.ensure",
|
|
742
|
+
// Repeating it returns the same endpoint: the second call finds what the
|
|
743
|
+
// first created. That is the property this field states, with no key.
|
|
744
|
+
idempotent: true,
|
|
745
|
+
// Additive, and open-world for the reason endpoints.update is: deliveries
|
|
746
|
+
// go to the customer's receiver afterwards.
|
|
747
|
+
mcp: { destructive: false, kind: "tool", openWorld: true },
|
|
748
|
+
method: "POST",
|
|
749
|
+
mutates: true,
|
|
750
|
+
path: "/v1/endpoints/ensure",
|
|
751
|
+
principals: ["api-credential", "oauth", "session"],
|
|
752
|
+
problems: [
|
|
753
|
+
"state_conflict",
|
|
754
|
+
"invalid_request",
|
|
755
|
+
"plan_limit_reached",
|
|
756
|
+
"rate_limited",
|
|
757
|
+
],
|
|
758
|
+
request: callbackEndpointRequestSchema,
|
|
759
|
+
requestExample: globalThis
|
|
760
|
+
.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
761
|
+
? {}
|
|
762
|
+
: { url: "https://hooks.example.com/greatwait" },
|
|
763
|
+
response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
|
|
764
|
+
? API_UNUSED_RESPONSE_SCHEMA
|
|
765
|
+
: callbackEndpointEnsuredSchema,
|
|
766
|
+
scopes: ["endpoints:write"],
|
|
767
|
+
sessionAuthority: "headers",
|
|
768
|
+
summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
|
|
769
|
+
? ""
|
|
770
|
+
: "Find or create a callback endpoint by URL",
|
|
771
|
+
surfaces: ["api", "mock"],
|
|
772
|
+
},
|
|
710
773
|
{
|
|
711
774
|
creates: false,
|
|
712
775
|
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
@@ -796,7 +859,7 @@ export const OPERATIONS = [
|
|
|
796
859
|
creates: false,
|
|
797
860
|
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
798
861
|
? ""
|
|
799
|
-
: "Replaces an endpoint's destination after applying the complete URL and DNS policy, and renames it when a name is given.
|
|
862
|
+
: "Replaces an endpoint's destination after applying the complete URL and DNS policy, and renames it when a name is given. Optional `headers` patch endpoint defaults with `set`, `keep`, or `remove`; omitted headers preserve them. A secret value can be retained, replaced (including an empty string), or removed, but cannot be revealed. Header and destination edits apply to newly admitted attempts, including retries; recovery of the same admitted attempt keeps its snapshot. Disabled endpoints cannot be updated. Send If-Match with the version the endpoint was read at to be refused rather than overwrite a destination somebody else changed in the meantime.",
|
|
800
863
|
example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
801
864
|
? {}
|
|
802
865
|
: {
|
|
@@ -2088,7 +2151,7 @@ export const OPERATIONS = [
|
|
|
2088
2151
|
creates: true,
|
|
2089
2152
|
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
2090
2153
|
? ""
|
|
2091
|
-
: "Creates a schedule and returns it together with its first planned occurrence. Give exactly one of `at`, `delaySeconds`, `everySeconds` and `cron`. An optional `partitionKey` selects a fairness lane inside this project and environment; it is fixed after create. Add a verified `endpoint` to deliver each occurrence there;
|
|
2154
|
+
: "Creates a schedule and returns it together with its first planned occurrence. Give exactly one of `at`, `delaySeconds`, `everySeconds` and `cron`. An optional `partitionKey` selects a fairness lane inside this project and environment; it is fixed after create. Add a verified `endpoint` to deliver each occurrence there. Instead of `endpoint`, give a `url`: the service uses this project and environment's existing endpoint at exactly that address, or creates one silently. Its signing secret is never returned; the response's `endpointSigningSecret` says where a signed-in member reveals it. Reusing an endpoint needs only `schedules:write`; creating one also needs `endpoints:write`, and without it the request is refused as `scope_missing`. Optional JSON `data` is encrypted before PostgreSQL persistence, placed in the signed callback, and returned as given by a schedule read. Optional `http` selects POST (default), PUT, or bodyless GET and schedule header overrides. Omitted HTTP settings preserve the signed structured envelope; `body: { mode: 'json', value: ... }` sends that JSON directly without interpolation. Ordinary headers remain readable and secret values are encrypted and write-only. Schedule headers override endpoint defaults case-insensitively, with `suppress` to omit an inherited header and `remove` to resume inheritance. Product signing, content and transport headers are reserved. Raw JSON and GET carry asynchronous completion details in reserved Callback-Completion headers. `at` and `delaySeconds` fire once; a delay is converted to an absolute instant when the request is accepted, so a schedule created either way reads back the same afterwards. `everySeconds` is a fixed duration and its first occurrence falls one interval after acceptance — it stays the same length across a daylight-saving change, and takes no timezone for that reason. `cron` is a wall clock: it is read against the IANA `timeZone` sent with it, `UTC` when none is, and the first occurrence is the first instant the expression names after acceptance. Where the clocks go forward and the wall time named does not exist that day, the occurrence falls at the first instant after the gap; where they go back and it happens twice, it falls once, at the earlier of the two. A recurring schedule is materialized one occurrence at a time: the next one is planned once the current one is due, so a read always shows one occurrence still to come. `lateness.policy` decides what happens when an occurrence reaches its first attempt after its planned instant: `skipAhead` never carries a recurring arrival across its next scheduled instant (and a shorter custom window may retire it earlier), while `catchUp` admits one arrival within `maxStalenessSeconds` even after later recurrence instants passed. A one-shot has no next recurrence, so either explicit policy uses its window and the default is `catchUp` with 24 hours; recurring schedules default to `skipAhead`, and a `catchUp` without an override has a one-interval window. A retry already in progress is exempt because it arrived and failed; its retry and give-up policy still decide the outcome. The organization, project and environment come from the verified principal; a body cannot name them, and the endpoint must belong to the same tuple, so a credential issued for one project can only ever create schedules in that project. Send an `Idempotency-Key` to make a retry safe: the identical request returns the schedule that key already created, marked `Idempotency-Replayed: true`, and creates nothing further; the same key with a different request is refused `idempotency_key_reused`. A replay reports the schedule **as it stands now**, not a frozen copy of the first response — if it was paused in between, the replay says so.",
|
|
2092
2155
|
example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
2093
2156
|
? {}
|
|
2094
2157
|
: {
|
|
@@ -2131,6 +2194,9 @@ export const OPERATIONS = [
|
|
|
2131
2194
|
method: "POST",
|
|
2132
2195
|
mutates: true,
|
|
2133
2196
|
path: "/v1/schedules",
|
|
2197
|
+
// Creating the endpoint a `url` names is an endpoint write (W9-44).
|
|
2198
|
+
conditionalScopes: ["endpoints:write"],
|
|
2199
|
+
conditionalScopesWhen: "the request names a `url` this project and environment has no endpoint at yet",
|
|
2134
2200
|
principals: ["api-credential", "oauth", "session"],
|
|
2135
2201
|
problems: [
|
|
2136
2202
|
"idempotency_key_reused",
|
|
@@ -2144,6 +2210,8 @@ export const OPERATIONS = [
|
|
|
2144
2210
|
// the schedule they asked for. How many schedules an organization holds
|
|
2145
2211
|
// is not bounded (FXO-2556).
|
|
2146
2212
|
"plan_limit_reached",
|
|
2213
|
+
"rate_limited",
|
|
2214
|
+
"scope_missing",
|
|
2147
2215
|
"service_unavailable",
|
|
2148
2216
|
// A schedule against a disabled endpoint. Refused rather than accepted
|
|
2149
2217
|
// and never fired, and refused by its state rather than as `not_found`,
|
|
@@ -2165,7 +2233,7 @@ export const OPERATIONS = [
|
|
|
2165
2233
|
requestHeaders: idempotencyRequestHeaderSchema,
|
|
2166
2234
|
response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
|
|
2167
2235
|
? API_UNUSED_RESPONSE_SCHEMA
|
|
2168
|
-
:
|
|
2236
|
+
: scheduleWrittenViewSchema,
|
|
2169
2237
|
...(globalThis.GREATWAIT_API_REQUEST_REGISTRY
|
|
2170
2238
|
? {}
|
|
2171
2239
|
: { responseHeaders: replayedResponseHeaderSchema }),
|
|
@@ -2180,7 +2248,7 @@ export const OPERATIONS = [
|
|
|
2180
2248
|
creates: false,
|
|
2181
2249
|
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
2182
2250
|
? ""
|
|
2183
|
-
: "Reads one schedule and its next occurrence from the partition that owns it. A schedule belonging to another organization, project or environment answers not_found rather than a refusal that would confirm it exists. The response carries the schedule's version as a strong ETag; send it back in `If-Match` to make a later write conditional on nothing having changed in between. The response carries the schedule's `data` when it has one, exactly as it was given; the listing leaves it off.",
|
|
2251
|
+
: "Reads one schedule and its next occurrence from the partition that owns it. A schedule belonging to another organization, project or environment answers not_found rather than a refusal that would confirm it exists. The response carries the schedule's version as a strong ETag; send it back in `If-Match` to make a later write conditional on nothing having changed in between. The response carries the schedule's `data` when it has one, exactly as it was given; the listing leaves it off. Detail reads also include the custom JSON body; listings and mutation responses omit its content. HTTP settings expose ordinary values and configured secret markers, never secret values.",
|
|
2184
2252
|
example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
2185
2253
|
? {}
|
|
2186
2254
|
: {
|
|
@@ -3614,7 +3682,7 @@ export const OPERATIONS = [
|
|
|
3614
3682
|
creates: false,
|
|
3615
3683
|
description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
|
|
3616
3684
|
? ""
|
|
3617
|
-
: "Replaces a schedule's definition, starting a new generation. Takes the same four ways of saying when as a create, so a one-shot can be replaced by a recurring definition and the other way round. An omitted callback endpoint/data pair preserves the stored callback; sending `data` alone replaces the encrypted data for the current endpoint, and sending `endpoint` selects a verified endpoint in the same authority tuple. The occurrence planned under the old definition is settled `skipped_stale` and can never fire unless it was already in flight, in which case its immutable attempt is allowed to settle honestly; a fresh occurrence is planned under the new definition, and the old definition's series stops advancing. `lateness` is resolved afresh against the replacement recurrence: omit it for that kind's default, or state `skipAhead`, `catchUp`, and an optional `maxStalenessSeconds` override. The policy applies only before an occurrence's first attempt; a retry already in progress remains on its retry and give-up ladder. Send `If-Match` with the version you read to make this conditional; without it the replace is unconditional and the last writer wins. A cancelled or completed schedule cannot be replaced. `partitionKey` is fixed when the schedule is created: omit it to preserve the stored value or echo that exact value in a GET → modify → PUT flow. Adding, changing, or clearing it is refused as `invalid_request` with `/partitionKey` identified. `latencyClass` remains derived from the replacement recurrence when the caller omits it.",
|
|
3685
|
+
: "Replaces a schedule's definition, starting a new generation. Takes the same four ways of saying when as a create, so a one-shot can be replaced by a recurring definition and the other way round. An omitted callback endpoint/data pair preserves the stored callback; sending `data` alone replaces the encrypted data for the current endpoint, and sending `endpoint` selects a verified endpoint in the same authority tuple. Sending `url` instead selects the endpoint at that address in the same tuple, creating one silently when there is none; creating needs `endpoints:write` as well, and the response's `endpointSigningSecret` says where its signing secret is revealed. Omitted `http` preserves HTTP settings. Its headers are a patch: `set` replaces a value, `keep` retains a configured value, `suppress` omits an endpoint default, and `remove` resumes inheritance. Explicit GET with no body clears a saved custom template; POST/PUT with `body: { mode: 'envelope' }` restores the structured callback. The occurrence planned under the old definition is settled `skipped_stale` and can never fire unless it was already in flight, in which case its immutable attempt is allowed to settle honestly; a fresh occurrence is planned under the new definition, and the old definition's series stops advancing. `lateness` is resolved afresh against the replacement recurrence: omit it for that kind's default, or state `skipAhead`, `catchUp`, and an optional `maxStalenessSeconds` override. The policy applies only before an occurrence's first attempt; a retry already in progress remains on its retry and give-up ladder. Send `If-Match` with the version you read to make this conditional; without it the replace is unconditional and the last writer wins. A cancelled or completed schedule cannot be replaced. `partitionKey` is fixed when the schedule is created: omit it to preserve the stored value or echo that exact value in a GET → modify → PUT flow. Adding, changing, or clearing it is refused as `invalid_request` with `/partitionKey` identified. `latencyClass` remains derived from the replacement recurrence when the caller omits it.",
|
|
3618
3686
|
example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
|
|
3619
3687
|
? {}
|
|
3620
3688
|
: {
|
|
@@ -3650,6 +3718,9 @@ export const OPERATIONS = [
|
|
|
3650
3718
|
method: "PUT",
|
|
3651
3719
|
mutates: true,
|
|
3652
3720
|
path: "/v1/schedules/{scheduleId}",
|
|
3721
|
+
// Creating the endpoint a `url` names is an endpoint write (W9-44).
|
|
3722
|
+
conditionalScopes: ["endpoints:write"],
|
|
3723
|
+
conditionalScopesWhen: "the request names a `url` this project and environment has no endpoint at yet",
|
|
3653
3724
|
principals: ["api-credential", "oauth", "session"],
|
|
3654
3725
|
problems: [
|
|
3655
3726
|
"invalid_request",
|
|
@@ -3658,6 +3729,8 @@ export const OPERATIONS = [
|
|
|
3658
3729
|
// schedule and cannot change `partitionKey`, so neither counted ceiling
|
|
3659
3730
|
// can move; what it can do is carry a larger body than the plan admits.
|
|
3660
3731
|
"plan_limit_reached",
|
|
3732
|
+
"rate_limited",
|
|
3733
|
+
"scope_missing",
|
|
3661
3734
|
"service_unavailable",
|
|
3662
3735
|
"state_conflict",
|
|
3663
3736
|
"version_conflict",
|
|
@@ -3679,7 +3752,7 @@ export const OPERATIONS = [
|
|
|
3679
3752
|
requestHeaders: conditionalRequestHeaderSchema,
|
|
3680
3753
|
response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
|
|
3681
3754
|
? API_UNUSED_RESPONSE_SCHEMA
|
|
3682
|
-
:
|
|
3755
|
+
: scheduleWrittenViewSchema,
|
|
3683
3756
|
...(globalThis.GREATWAIT_API_REQUEST_REGISTRY
|
|
3684
3757
|
? {}
|
|
3685
3758
|
: { responseHeaders: versionResponseHeaderSchema }),
|
|
@@ -29,6 +29,16 @@ export declare const ORGANIZATION_LIFECYCLE_OPERATIONS: readonly [import("./oper
|
|
|
29
29
|
readonly id: "organizations.lifecycle";
|
|
30
30
|
}, import("./operations.js").OperationDefinition & {
|
|
31
31
|
readonly id: "organizations.close";
|
|
32
|
+
} & {
|
|
33
|
+
readonly request: import("zod").ZodObject<{
|
|
34
|
+
expectedGeneration: import("zod").ZodNumber;
|
|
35
|
+
immediate: import("zod").ZodBoolean;
|
|
36
|
+
confirmation: import("zod").ZodLiteral<"delete organization">;
|
|
37
|
+
}, import("zod/v4/core").$strict>;
|
|
32
38
|
}, import("./operations.js").OperationDefinition & {
|
|
33
39
|
readonly id: "organizations.restore";
|
|
40
|
+
} & {
|
|
41
|
+
readonly request: import("zod").ZodObject<{
|
|
42
|
+
expectedGeneration: import("zod").ZodNumber;
|
|
43
|
+
}, import("zod/v4/core").$strict>;
|
|
34
44
|
}];
|
package/dist/policy.js
CHANGED
|
@@ -50,10 +50,13 @@ function allOperations() {
|
|
|
50
50
|
* Clerk's and this product does not do it, so this is the whole of what `admin`
|
|
51
51
|
* means here.
|
|
52
52
|
*/
|
|
53
|
-
const MEMBER_SCOPES = SCOPES.filter((scope) => scope !== "
|
|
53
|
+
const MEMBER_SCOPES = SCOPES.filter((scope) => scope !== "members:manage" &&
|
|
54
|
+
scope !== "billing:write" &&
|
|
55
|
+
scope !== "credentials:administer" &&
|
|
56
|
+
scope !== "projects:administer");
|
|
57
|
+
const BILLING_SCOPES = SCOPES.filter((scope) => scope !== "members:manage" &&
|
|
54
58
|
scope !== "credentials:administer" &&
|
|
55
59
|
scope !== "projects:administer");
|
|
56
|
-
const BILLING_SCOPES = SCOPES.filter((scope) => scope !== "credentials:administer" && scope !== "projects:administer");
|
|
57
60
|
export const ROLE_SCOPE_CEILINGS = {
|
|
58
61
|
admin: SCOPES,
|
|
59
62
|
billing: BILLING_SCOPES,
|