Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions openapi/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -22515,18 +22515,29 @@
"metric": {
"type": "string",
"example": "compute/machines",
"description": "Metric: service/resource"
"description": "Metric: service/resource. Not unique on its own — see the `scope` field. Index by `(metric, scope)`."
},
"type": {
"type": "string",
"enum": [
"allocation",
"rate",
"concurrency"
"concurrency",
"lifetime"
],
"description": "Allocation = max owned, rate = max per time window, concurrency = max in-flight.",
"description": "Allocation = max owned, rate = max per time window, concurrency = max in-flight, lifetime = a one-time grant. Only `rate` has a `resets_at`: a lifetime entitlement has no period, is never released by deleting the resource it funded, and reports its position in that one-way lifecycle as `grant_state`.",
"example": "allocation"
},
"scope": {
"type": "string",
"enum": [
"workspace",
"principal",
"cluster"
],
"description": "Identity the limit/usage numbers are bound to, and the second half of an entry's key. `workspace` is occupancy inside the workspace; `principal` aggregates across every workspace and organization owned by the same authenticated identity, so a new workspace does not grant fresh free capacity; `cluster` bounds in-flight work for one cluster. A metric enforced against more than one identity — every free-tier allocation, for example — returns one entry per scope, so `(metric, scope)` is the composite key. Indexing a listing by `metric` alone silently drops entries.",
"example": "workspace"
},
"display_name": {
"type": "string",
"example": "Compute machines"
Expand Down Expand Up @@ -22560,12 +22571,23 @@
"resets_at": {
"type": "integer",
"minimum": 0,
"description": "For rate quotas: Unix timestamp (seconds) reset time"
"description": "For rate quotas only: Unix timestamp (seconds) at which the window resets. Absent on every other type, including `lifetime`, which has no period."
},
"grant_state": {
"type": "string",
"enum": [
"available",
"consumed",
"revoked"
],
"description": "For `lifetime` quotas only: state of the one-time grant.",
"example": "available"
}
},
"required": [
"metric",
"type",
"scope",
"display_name",
"unit",
"limit",
Expand Down
8 changes: 4 additions & 4 deletions src/generated/openapi-api.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,10 @@ export type NotificationList = { readonly "data": ReadonlyArray<{ readonly "id":
export const NotificationList = Schema.Struct({ "data": Schema.Array(Schema.Struct({ "id": Schema.String.check(Schema.isMinLength(1).annotate({ "expected": "a value with a length of at least 1" })).check(Schema.isMaxLength(54).annotate({ "expected": "a value with a length of at most 54" })), "type": Schema.String, "resource_type": Schema.String, "resource_id": Schema.String, "title": Schema.Union([Schema.String, Schema.Null]), "body": Schema.Union([Schema.String, Schema.Null]), "severity": Schema.Union([Schema.Literal("info"), Schema.Literal("warning"), Schema.Literal("critical"), Schema.Null]).annotate({ "description": "Severity level surfaced to UI indicators." }), "context": Schema.Union([Schema.Record(Schema.String, Schema.String), Schema.Null]), "read_at": Schema.Union([Schema.Number.check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" })), Schema.Null]).annotate({ "description": "Unix timestamp (seconds) when read, null if unread" }), "created_at": Schema.Number.annotate({ "description": "Unix timestamp (seconds)" }).check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" })) })), "has_more": Schema.Boolean.annotate({ "description": "True if more items exist after this page." }), "next_cursor": Schema.Union([Schema.String, Schema.Null]).annotate({ "description": "Opaque cursor for the next page, or null if no more pages." }) }).annotate({ "identifier": "NotificationList" })
export type UnreadCount = { readonly "count": number }
export const UnreadCount = Schema.Struct({ "count": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })) }).annotate({ "identifier": "UnreadCount" })
export type QuotaInfoList = { readonly "data": ReadonlyArray<{ readonly "metric": string, readonly "type": "allocation" | "rate" | "concurrency", readonly "display_name": string, readonly "unit": "count" | "cores" | "bytes" | "seconds" | "count/day" | "count/minute" | "cents/day", readonly "limit": number, readonly "usage": number, readonly "remaining": number, readonly "resets_at"?: number }>, readonly "has_more": boolean, readonly "next_cursor": string | null }
export const QuotaInfoList = Schema.Struct({ "data": Schema.Array(Schema.Struct({ "metric": Schema.String.annotate({ "description": "Metric: service/resource" }), "type": Schema.Literals(["allocation", "rate", "concurrency"]).annotate({ "description": "Allocation = max owned, rate = max per time window, concurrency = max in-flight." }), "display_name": Schema.String, "unit": Schema.Literals(["count", "cores", "bytes", "seconds", "count/day", "count/minute", "cents/day"]).annotate({ "description": "Unit the limit/usage numbers are measured in." }), "limit": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "usage": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "remaining": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "resets_at": Schema.optionalKey(Schema.Number.annotate({ "description": "For rate quotas: Unix timestamp (seconds) reset time" }).check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" }))) })), "has_more": Schema.Boolean.annotate({ "description": "True if more items exist after this page." }), "next_cursor": Schema.Union([Schema.String, Schema.Null]).annotate({ "description": "Opaque cursor for the next page, or null if no more pages." }) }).annotate({ "identifier": "QuotaInfoList" })
export type QuotaInfo = { readonly "metric": string, readonly "type": "allocation" | "rate" | "concurrency", readonly "display_name": string, readonly "unit": "count" | "cores" | "bytes" | "seconds" | "count/day" | "count/minute" | "cents/day", readonly "limit": number, readonly "usage": number, readonly "remaining": number, readonly "resets_at"?: number }
export const QuotaInfo = Schema.Struct({ "metric": Schema.String.annotate({ "description": "Metric: service/resource" }), "type": Schema.Literals(["allocation", "rate", "concurrency"]).annotate({ "description": "Allocation = max owned, rate = max per time window, concurrency = max in-flight." }), "display_name": Schema.String, "unit": Schema.Literals(["count", "cores", "bytes", "seconds", "count/day", "count/minute", "cents/day"]).annotate({ "description": "Unit the limit/usage numbers are measured in." }), "limit": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "usage": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "remaining": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "resets_at": Schema.optionalKey(Schema.Number.annotate({ "description": "For rate quotas: Unix timestamp (seconds) reset time" }).check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" }))) }).annotate({ "identifier": "QuotaInfo" })
export type QuotaInfoList = { readonly "data": ReadonlyArray<{ readonly "metric": string, readonly "type": "allocation" | "rate" | "concurrency" | "lifetime", readonly "scope": "workspace" | "principal" | "cluster", readonly "display_name": string, readonly "unit": "count" | "cores" | "bytes" | "seconds" | "count/day" | "count/minute" | "cents/day", readonly "limit": number, readonly "usage": number, readonly "remaining": number, readonly "resets_at"?: number, readonly "grant_state"?: "available" | "consumed" | "revoked" }>, readonly "has_more": boolean, readonly "next_cursor": string | null }
export const QuotaInfoList = Schema.Struct({ "data": Schema.Array(Schema.Struct({ "metric": Schema.String.annotate({ "description": "Metric: service/resource. Not unique on its own — see the `scope` field. Index by `(metric, scope)`." }), "type": Schema.Literals(["allocation", "rate", "concurrency", "lifetime"]).annotate({ "description": "Allocation = max owned, rate = max per time window, concurrency = max in-flight, lifetime = a one-time grant. Only `rate` has a `resets_at`: a lifetime entitlement has no period, is never released by deleting the resource it funded, and reports its position in that one-way lifecycle as `grant_state`." }), "scope": Schema.Literals(["workspace", "principal", "cluster"]).annotate({ "description": "Identity the limit/usage numbers are bound to, and the second half of an entry's key. `workspace` is occupancy inside the workspace; `principal` aggregates across every workspace and organization owned by the same authenticated identity, so a new workspace does not grant fresh free capacity; `cluster` bounds in-flight work for one cluster. A metric enforced against more than one identity — every free-tier allocation, for example — returns one entry per scope, so `(metric, scope)` is the composite key. Indexing a listing by `metric` alone silently drops entries." }), "display_name": Schema.String, "unit": Schema.Literals(["count", "cores", "bytes", "seconds", "count/day", "count/minute", "cents/day"]).annotate({ "description": "Unit the limit/usage numbers are measured in." }), "limit": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "usage": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "remaining": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "resets_at": Schema.optionalKey(Schema.Number.annotate({ "description": "For rate quotas only: Unix timestamp (seconds) at which the window resets. Absent on every other type, including `lifetime`, which has no period." }).check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" }))), "grant_state": Schema.optionalKey(Schema.Literals(["available", "consumed", "revoked"]).annotate({ "description": "For `lifetime` quotas only: state of the one-time grant." })) })), "has_more": Schema.Boolean.annotate({ "description": "True if more items exist after this page." }), "next_cursor": Schema.Union([Schema.String, Schema.Null]).annotate({ "description": "Opaque cursor for the next page, or null if no more pages." }) }).annotate({ "identifier": "QuotaInfoList" })
export type QuotaInfo = { readonly "metric": string, readonly "type": "allocation" | "rate" | "concurrency" | "lifetime", readonly "scope": "workspace" | "principal" | "cluster", readonly "display_name": string, readonly "unit": "count" | "cores" | "bytes" | "seconds" | "count/day" | "count/minute" | "cents/day", readonly "limit": number, readonly "usage": number, readonly "remaining": number, readonly "resets_at"?: number, readonly "grant_state"?: "available" | "consumed" | "revoked" }
export const QuotaInfo = Schema.Struct({ "metric": Schema.String.annotate({ "description": "Metric: service/resource. Not unique on its own — see the `scope` field. Index by `(metric, scope)`." }), "type": Schema.Literals(["allocation", "rate", "concurrency", "lifetime"]).annotate({ "description": "Allocation = max owned, rate = max per time window, concurrency = max in-flight, lifetime = a one-time grant. Only `rate` has a `resets_at`: a lifetime entitlement has no period, is never released by deleting the resource it funded, and reports its position in that one-way lifecycle as `grant_state`." }), "scope": Schema.Literals(["workspace", "principal", "cluster"]).annotate({ "description": "Identity the limit/usage numbers are bound to, and the second half of an entry's key. `workspace` is occupancy inside the workspace; `principal` aggregates across every workspace and organization owned by the same authenticated identity, so a new workspace does not grant fresh free capacity; `cluster` bounds in-flight work for one cluster. A metric enforced against more than one identity — every free-tier allocation, for example — returns one entry per scope, so `(metric, scope)` is the composite key. Indexing a listing by `metric` alone silently drops entries." }), "display_name": Schema.String, "unit": Schema.Literals(["count", "cores", "bytes", "seconds", "count/day", "count/minute", "cents/day"]).annotate({ "description": "Unit the limit/usage numbers are measured in." }), "limit": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "usage": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "remaining": Schema.Number.check(Schema.isFinite().annotate({ "expected": "a finite number" })), "resets_at": Schema.optionalKey(Schema.Number.annotate({ "description": "For rate quotas only: Unix timestamp (seconds) at which the window resets. Absent on every other type, including `lifetime`, which has no period." }).check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" }))), "grant_state": Schema.optionalKey(Schema.Literals(["available", "consumed", "revoked"]).annotate({ "description": "For `lifetime` quotas only: state of the one-time grant." })) }).annotate({ "identifier": "QuotaInfo" })
export type RegionList = { readonly "data": ReadonlyArray<{ readonly "id": string, readonly "name": string, readonly "icon": string | null, readonly "workspace_id": string, readonly "created_at": number }>, readonly "has_more": boolean, readonly "next_cursor": string | null }
export const RegionList = Schema.Struct({ "data": Schema.Array(Schema.Struct({ "id": Schema.String.check(Schema.isMinLength(1).annotate({ "expected": "a value with a length of at least 1" })).check(Schema.isMaxLength(54).annotate({ "expected": "a value with a length of at most 54" })), "name": Schema.String, "icon": Schema.Union([Schema.String, Schema.Null]).annotate({ "description": "Icon URL" }), "workspace_id": Schema.String.check(Schema.isMinLength(1).annotate({ "expected": "a value with a length of at least 1" })).check(Schema.isMaxLength(53).annotate({ "expected": "a value with a length of at most 53" })), "created_at": Schema.Number.annotate({ "description": "Unix timestamp (seconds)" }).check(Schema.isInt().annotate({ "expected": "an integer" })).check(Schema.isGreaterThanOrEqualTo(0).annotate({ "expected": "a value greater than or equal to 0" })) })), "has_more": Schema.Boolean.annotate({ "description": "True if more items exist after this page." }), "next_cursor": Schema.Union([Schema.String, Schema.Null]).annotate({ "description": "Opaque cursor for the next page, or null if no more pages." }) }).annotate({ "identifier": "RegionList" })
export type Region = { readonly "id": string, readonly "name": string, readonly "icon": string | null, readonly "workspace_id": string, readonly "created_at": number }
Expand Down
29 changes: 29 additions & 0 deletions test/generated-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,35 @@ describe("generated public commands", () => {
expect(received?.headers.get("akua-context")).toBe("ws_123");
});

test("quotas.list accepts a lifetime quota response", async () => {
const quotas = {
data: [
{
metric: "compute/managed_vm_trial",
type: "lifetime",
scope: "principal",
display_name: "Managed VM trial",
unit: "count",
limit: 1,
usage: 0,
remaining: 1,
grant_state: "available",
},
],
has_more: false,
next_cursor: null,
};

const result = await runGenerated(
"quotas.list",
["--input", "-"],
JSON.stringify({ headers: { "akua-context": "ws_123" } }),
() => Promise.resolve(Response.json(quotas)),
);

expect(result.data).toEqual(quotas);
});

test("clusters.resume builds the literal :action-suffixed request path", async () => {
let received: Request | undefined;
const operation = clusterOperation();
Expand Down
Loading