@sealant/api-contracts-next 0.40.0-next.770 → 0.40.0-next.772
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.
|
@@ -26,9 +26,82 @@
|
|
|
26
26
|
* keeps the member's row, with its version. One member reads at `GET …/members/:userId`, and the
|
|
27
27
|
* list pages by user id: `limit` (100 unless named, at most 500) and the previous page's
|
|
28
28
|
* `nextCursor` as `cursor`.
|
|
29
|
+
*
|
|
30
|
+
* A budget caps CPU (millicores), memory and storage (bytes): ceilings, not measurements, and
|
|
31
|
+
* zero allows nothing. Storage is one allowance for volumes, archived ones included, and the
|
|
32
|
+
* backups and snapshots that protect them. `ensureResourceDomain` may name a new domain's budget
|
|
33
|
+
* and never changes one: naming another gets `409`, carrying the domain and its revision.
|
|
34
|
+
* `setResourceDomainBudget` takes the `revision` it read: a change made since gets `409`, so a
|
|
35
|
+
* delayed update never overwrites a newer one, and it answers the budget it wrote. Changing a
|
|
36
|
+
* budget changes nothing the domain holds. The read is one snapshot. It reports, per dimension,
|
|
37
|
+
* `used` (confirmed to exist), `reserved` (admitted, not yet confirmed), the `limit` and a `warning`
|
|
38
|
+
* once both reach 80%, 95% or all of it; storage also reports its `archived` and `protection` bytes.
|
|
29
39
|
*/
|
|
30
40
|
import { Schema } from "effect";
|
|
31
41
|
import { HttpApiEndpoint, HttpApiGroup } from "effect/http-api";
|
|
42
|
+
/**
|
|
43
|
+
* The dimensions a budget caps, defined once: the contract's schemas, the database's budget, the
|
|
44
|
+
* admission check and the SDK all take theirs from these keys. `freedBy` is what makes room in a
|
|
45
|
+
* dimension besides raising its limit.
|
|
46
|
+
*/
|
|
47
|
+
export declare const RESOURCE_DOMAIN_BUDGET_DIMENSIONS: {
|
|
48
|
+
readonly cpuMillicores: {
|
|
49
|
+
readonly name: "CPU";
|
|
50
|
+
readonly freedBy: "stop-objects";
|
|
51
|
+
};
|
|
52
|
+
readonly memoryBytes: {
|
|
53
|
+
readonly name: "memory";
|
|
54
|
+
readonly freedBy: "stop-objects";
|
|
55
|
+
};
|
|
56
|
+
readonly storageBytes: {
|
|
57
|
+
readonly name: "storage";
|
|
58
|
+
readonly freedBy: "purge-objects";
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export type ResourceDomainBudgetDimension = keyof typeof RESOURCE_DOMAIN_BUDGET_DIMENSIONS;
|
|
62
|
+
export declare const resourceDomainBudgetLimitsSchema: Schema.Struct<Record<"cpuMillicores" | "memoryBytes" | "storageBytes", Schema.Int>>;
|
|
63
|
+
export type ResourceDomainBudgetLimits = typeof resourceDomainBudgetLimitsSchema.Type;
|
|
64
|
+
/** The share of a limit at which the budget read starts to warn. */
|
|
65
|
+
export declare const RESOURCE_DOMAIN_BUDGET_WARNINGS: {
|
|
66
|
+
readonly "80-percent": 80;
|
|
67
|
+
readonly "95-percent": 95;
|
|
68
|
+
};
|
|
69
|
+
declare const BudgetWarning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
70
|
+
export type ResourceDomainBudgetWarning = typeof BudgetWarning.Type;
|
|
71
|
+
export declare const resourceDomainBudgetSchema: Schema.Struct<{
|
|
72
|
+
readonly revision: Schema.Int;
|
|
73
|
+
readonly storageBytes: Schema.Struct<{
|
|
74
|
+
readonly limit: Schema.Int;
|
|
75
|
+
readonly used: Schema.Int;
|
|
76
|
+
readonly reserved: Schema.Int;
|
|
77
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
78
|
+
/** Archived volumes' data bytes, part of `used`: kept until a person purges them. */
|
|
79
|
+
readonly archived: Schema.Int;
|
|
80
|
+
/** Bytes that backups and snapshots hold, not a volume's unused reserve for them. */
|
|
81
|
+
readonly protection: Schema.Int;
|
|
82
|
+
}>;
|
|
83
|
+
readonly cpuMillicores: Schema.Struct<{
|
|
84
|
+
readonly limit: Schema.Int;
|
|
85
|
+
readonly used: Schema.Int;
|
|
86
|
+
readonly reserved: Schema.Int;
|
|
87
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
88
|
+
}>;
|
|
89
|
+
readonly memoryBytes: Schema.Struct<{
|
|
90
|
+
readonly limit: Schema.Int;
|
|
91
|
+
readonly used: Schema.Int;
|
|
92
|
+
readonly reserved: Schema.Int;
|
|
93
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
94
|
+
}>;
|
|
95
|
+
}>;
|
|
96
|
+
export type ResourceDomainBudgetWire = typeof resourceDomainBudgetSchema.Type;
|
|
97
|
+
export declare const setResourceDomainBudgetRequestSchema: Schema.Struct<{
|
|
98
|
+
/** The revision this change replaces: the one the caller last read. */
|
|
99
|
+
readonly revision: Schema.Int;
|
|
100
|
+
readonly cpuMillicores: Schema.Int;
|
|
101
|
+
readonly memoryBytes: Schema.Int;
|
|
102
|
+
readonly storageBytes: Schema.Int;
|
|
103
|
+
}>;
|
|
104
|
+
export type SetResourceDomainBudgetRequest = typeof setResourceDomainBudgetRequestSchema.Type;
|
|
32
105
|
export declare const resourceDomainSchema: Schema.Struct<{
|
|
33
106
|
readonly resourceDomainId: Schema.String;
|
|
34
107
|
readonly key: Schema.String;
|
|
@@ -37,6 +110,8 @@ export declare const resourceDomainSchema: Schema.Struct<{
|
|
|
37
110
|
export type ResourceDomainWire = typeof resourceDomainSchema.Type;
|
|
38
111
|
export declare const ensureResourceDomainRequestSchema: Schema.Struct<{
|
|
39
112
|
readonly key: Schema.String;
|
|
113
|
+
/** The budget a new domain starts with; none starts it at zero. */
|
|
114
|
+
readonly budget: Schema.optional<Schema.Struct<Record<"cpuMillicores" | "memoryBytes" | "storageBytes", Schema.Int>>>;
|
|
40
115
|
}>;
|
|
41
116
|
export type EnsureResourceDomainRequest = typeof ensureResourceDomainRequestSchema.Type;
|
|
42
117
|
export declare const ensureResourceDomainResponseSchema: Schema.Struct<{
|
|
@@ -116,6 +191,21 @@ declare const ResourceDomainMemberVersionConflictError_base: Schema.Class<Resour
|
|
|
116
191
|
*/
|
|
117
192
|
export declare class ResourceDomainMemberVersionConflictError extends ResourceDomainMemberVersionConflictError_base {
|
|
118
193
|
}
|
|
194
|
+
declare const ResourceDomainBudgetDiffersError_base: Schema.Class<ResourceDomainBudgetDiffersError, Schema.TaggedStruct<"ResourceDomainBudgetDiffersError", {
|
|
195
|
+
readonly message: Schema.String;
|
|
196
|
+
readonly resourceDomainId: Schema.String;
|
|
197
|
+
readonly revision: Schema.Int;
|
|
198
|
+
}>, import("effect/Cause").YieldableError>;
|
|
199
|
+
/** The domain exists with another budget, at `revision`; nothing changed. */
|
|
200
|
+
export declare class ResourceDomainBudgetDiffersError extends ResourceDomainBudgetDiffersError_base {
|
|
201
|
+
}
|
|
202
|
+
declare const ResourceDomainBudgetRevisionConflictError_base: Schema.Class<ResourceDomainBudgetRevisionConflictError, Schema.TaggedStruct<"ResourceDomainBudgetRevisionConflictError", {
|
|
203
|
+
readonly message: Schema.String;
|
|
204
|
+
readonly revision: Schema.Int;
|
|
205
|
+
}>, import("effect/Cause").YieldableError>;
|
|
206
|
+
/** `revision` is the current one. */
|
|
207
|
+
export declare class ResourceDomainBudgetRevisionConflictError extends ResourceDomainBudgetRevisionConflictError_base {
|
|
208
|
+
}
|
|
119
209
|
declare const ResourceDomainInternalServerError_base: Schema.Class<ResourceDomainInternalServerError, Schema.TaggedStruct<"ResourceDomainInternalServerError", {
|
|
120
210
|
readonly message: Schema.String;
|
|
121
211
|
}>, import("effect/Cause").YieldableError>;
|
|
@@ -123,18 +213,46 @@ export declare class ResourceDomainInternalServerError extends ResourceDomainInt
|
|
|
123
213
|
}
|
|
124
214
|
export declare const ResourceDomainsGroup: HttpApiGroup.HttpApiGroup<"resourceDomains", HttpApiEndpoint.HttpApiEndpoint<"ensureResourceDomain", "POST", "/", never, never, Schema.toCodecJson<Schema.Struct<{
|
|
125
215
|
readonly key: Schema.String;
|
|
216
|
+
/** The budget a new domain starts with; none starts it at zero. */
|
|
217
|
+
readonly budget: Schema.optional<Schema.Struct<Record<"cpuMillicores" | "memoryBytes" | "storageBytes", Schema.Int>>>;
|
|
126
218
|
}>>, never, Schema.toCodecJson<Schema.Struct<{
|
|
127
219
|
readonly resourceDomainId: Schema.String;
|
|
128
220
|
readonly key: Schema.String;
|
|
129
221
|
readonly createdAt: Schema.String;
|
|
130
222
|
/** True when this call created the domain. */
|
|
131
223
|
readonly created: Schema.Boolean;
|
|
132
|
-
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"getResourceDomain", "GET", "/:resourceDomainId", Schema.toCodecStringTree<Schema.Struct<{
|
|
224
|
+
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainBudgetDiffersError | typeof ResourceDomainInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"getResourceDomain", "GET", "/:resourceDomainId", Schema.toCodecStringTree<Schema.Struct<{
|
|
133
225
|
readonly resourceDomainId: Schema.String;
|
|
134
226
|
}>>, never, never, never, Schema.toCodecJson<Schema.Struct<{
|
|
135
227
|
readonly resourceDomainId: Schema.String;
|
|
136
228
|
readonly key: Schema.String;
|
|
137
229
|
readonly createdAt: Schema.String;
|
|
230
|
+
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainNotFoundError | typeof ResourceDomainInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"getResourceDomainBudget", "GET", "/:resourceDomainId/budget", Schema.toCodecStringTree<Schema.Struct<{
|
|
231
|
+
readonly resourceDomainId: Schema.String;
|
|
232
|
+
}>>, never, never, never, Schema.toCodecJson<Schema.Struct<{
|
|
233
|
+
readonly revision: Schema.Int;
|
|
234
|
+
readonly storageBytes: Schema.Struct<{
|
|
235
|
+
readonly limit: Schema.Int;
|
|
236
|
+
readonly used: Schema.Int;
|
|
237
|
+
readonly reserved: Schema.Int;
|
|
238
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
239
|
+
/** Archived volumes' data bytes, part of `used`: kept until a person purges them. */
|
|
240
|
+
readonly archived: Schema.Int;
|
|
241
|
+
/** Bytes that backups and snapshots hold, not a volume's unused reserve for them. */
|
|
242
|
+
readonly protection: Schema.Int;
|
|
243
|
+
}>;
|
|
244
|
+
readonly cpuMillicores: Schema.Struct<{
|
|
245
|
+
readonly limit: Schema.Int;
|
|
246
|
+
readonly used: Schema.Int;
|
|
247
|
+
readonly reserved: Schema.Int;
|
|
248
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
249
|
+
}>;
|
|
250
|
+
readonly memoryBytes: Schema.Struct<{
|
|
251
|
+
readonly limit: Schema.Int;
|
|
252
|
+
readonly used: Schema.Int;
|
|
253
|
+
readonly reserved: Schema.Int;
|
|
254
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
255
|
+
}>;
|
|
138
256
|
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainNotFoundError | typeof ResourceDomainInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"getResourceDomainMember", "GET", "/:resourceDomainId/members/:userId", Schema.toCodecStringTree<Schema.Struct<{
|
|
139
257
|
readonly resourceDomainId: Schema.String;
|
|
140
258
|
readonly userId: Schema.String;
|
|
@@ -180,5 +298,37 @@ export declare const ResourceDomainsGroup: HttpApiGroup.HttpApiGroup<"resourceDo
|
|
|
180
298
|
readonly state: Schema.Literals<readonly ["member", "revoked"]>;
|
|
181
299
|
readonly version: Schema.Int;
|
|
182
300
|
readonly updatedAt: Schema.String;
|
|
183
|
-
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainNotFoundError | typeof ResourceDomainPersonNotFoundError | typeof ResourceDomainMemberVersionConflictError | typeof ResourceDomainInternalServerError>, never, never
|
|
301
|
+
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainNotFoundError | typeof ResourceDomainPersonNotFoundError | typeof ResourceDomainMemberVersionConflictError | typeof ResourceDomainInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"setResourceDomainBudget", "PUT", "/:resourceDomainId/budget", Schema.toCodecStringTree<Schema.Struct<{
|
|
302
|
+
readonly resourceDomainId: Schema.String;
|
|
303
|
+
}>>, never, Schema.toCodecJson<Schema.Struct<{
|
|
304
|
+
/** The revision this change replaces: the one the caller last read. */
|
|
305
|
+
readonly revision: Schema.Int;
|
|
306
|
+
readonly cpuMillicores: Schema.Int;
|
|
307
|
+
readonly memoryBytes: Schema.Int;
|
|
308
|
+
readonly storageBytes: Schema.Int;
|
|
309
|
+
}>>, never, Schema.toCodecJson<Schema.Struct<{
|
|
310
|
+
readonly revision: Schema.Int;
|
|
311
|
+
readonly storageBytes: Schema.Struct<{
|
|
312
|
+
readonly limit: Schema.Int;
|
|
313
|
+
readonly used: Schema.Int;
|
|
314
|
+
readonly reserved: Schema.Int;
|
|
315
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
316
|
+
/** Archived volumes' data bytes, part of `used`: kept until a person purges them. */
|
|
317
|
+
readonly archived: Schema.Int;
|
|
318
|
+
/** Bytes that backups and snapshots hold, not a volume's unused reserve for them. */
|
|
319
|
+
readonly protection: Schema.Int;
|
|
320
|
+
}>;
|
|
321
|
+
readonly cpuMillicores: Schema.Struct<{
|
|
322
|
+
readonly limit: Schema.Int;
|
|
323
|
+
readonly used: Schema.Int;
|
|
324
|
+
readonly reserved: Schema.Int;
|
|
325
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
326
|
+
}>;
|
|
327
|
+
readonly memoryBytes: Schema.Struct<{
|
|
328
|
+
readonly limit: Schema.Int;
|
|
329
|
+
readonly used: Schema.Int;
|
|
330
|
+
readonly reserved: Schema.Int;
|
|
331
|
+
readonly warning: Schema.Literals<readonly ["none", "80-percent", "95-percent", "full"]>;
|
|
332
|
+
}>;
|
|
333
|
+
}>>, Schema.toCodecJson<typeof ResourceDomainForbiddenError | typeof ResourceDomainNotFoundError | typeof ResourceDomainBudgetRevisionConflictError | typeof ResourceDomainInternalServerError>, never, never>, false>;
|
|
184
334
|
export {};
|
|
@@ -26,9 +26,20 @@
|
|
|
26
26
|
* keeps the member's row, with its version. One member reads at `GET …/members/:userId`, and the
|
|
27
27
|
* list pages by user id: `limit` (100 unless named, at most 500) and the previous page's
|
|
28
28
|
* `nextCursor` as `cursor`.
|
|
29
|
+
*
|
|
30
|
+
* A budget caps CPU (millicores), memory and storage (bytes): ceilings, not measurements, and
|
|
31
|
+
* zero allows nothing. Storage is one allowance for volumes, archived ones included, and the
|
|
32
|
+
* backups and snapshots that protect them. `ensureResourceDomain` may name a new domain's budget
|
|
33
|
+
* and never changes one: naming another gets `409`, carrying the domain and its revision.
|
|
34
|
+
* `setResourceDomainBudget` takes the `revision` it read: a change made since gets `409`, so a
|
|
35
|
+
* delayed update never overwrites a newer one, and it answers the budget it wrote. Changing a
|
|
36
|
+
* budget changes nothing the domain holds. The read is one snapshot. It reports, per dimension,
|
|
37
|
+
* `used` (confirmed to exist), `reserved` (admitted, not yet confirmed), the `limit` and a `warning`
|
|
38
|
+
* once both reach 80%, 95% or all of it; storage also reports its `archived` and `protection` bytes.
|
|
29
39
|
*/
|
|
30
40
|
import { Schema } from "effect";
|
|
31
41
|
import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/http-api";
|
|
42
|
+
import * as Rec from "effect/Record";
|
|
32
43
|
import { PersonId, RESOURCE_DOMAIN_ID_PREFIX } from "./person-id.js";
|
|
33
44
|
const RESOURCE_DOMAIN_ID_PATTERN = new RegExp(`^${RESOURCE_DOMAIN_ID_PREFIX}[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`);
|
|
34
45
|
const RESOURCE_DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]{0,31}:[A-Za-z0-9._:/@+=-]{1,223}$/;
|
|
@@ -36,12 +47,54 @@ const ResourceDomainId = Schema.String.check(Schema.makeFilter((id) => RESOURCE_
|
|
|
36
47
|
const ResourceDomainKey = Schema.String.check(Schema.makeFilter((key) => RESOURCE_DOMAIN_KEY_PATTERN.test(key)
|
|
37
48
|
? undefined
|
|
38
49
|
: "must be <application>:<name>: a lower-case application name (letters, digits, '-'), a colon, then at most 223 letters, digits, '.', '_', ':', '/', '@', '+', '=' or '-'"));
|
|
50
|
+
const Amount = Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }));
|
|
51
|
+
const BudgetRevision = Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER }));
|
|
52
|
+
/**
|
|
53
|
+
* The dimensions a budget caps, defined once: the contract's schemas, the database's budget, the
|
|
54
|
+
* admission check and the SDK all take theirs from these keys. `freedBy` is what makes room in a
|
|
55
|
+
* dimension besides raising its limit.
|
|
56
|
+
*/
|
|
57
|
+
export const RESOURCE_DOMAIN_BUDGET_DIMENSIONS = {
|
|
58
|
+
cpuMillicores: { name: "CPU", freedBy: "stop-objects" },
|
|
59
|
+
memoryBytes: { name: "memory", freedBy: "stop-objects" },
|
|
60
|
+
storageBytes: { name: "storage", freedBy: "purge-objects" },
|
|
61
|
+
};
|
|
62
|
+
export const resourceDomainBudgetLimitsSchema = Schema.Struct(Rec.map(RESOURCE_DOMAIN_BUDGET_DIMENSIONS, () => Amount));
|
|
63
|
+
/** The share of a limit at which the budget read starts to warn. */
|
|
64
|
+
export const RESOURCE_DOMAIN_BUDGET_WARNINGS = { "80-percent": 80, "95-percent": 95 };
|
|
65
|
+
const BudgetWarning = Schema.Literals(["none", "80-percent", "95-percent", "full"]);
|
|
66
|
+
const budgetDimensionSchema = Schema.Struct({
|
|
67
|
+
limit: Amount,
|
|
68
|
+
used: Amount,
|
|
69
|
+
reserved: Amount,
|
|
70
|
+
warning: BudgetWarning,
|
|
71
|
+
});
|
|
72
|
+
export const resourceDomainBudgetSchema = Schema.Struct({
|
|
73
|
+
revision: BudgetRevision,
|
|
74
|
+
...Rec.map(RESOURCE_DOMAIN_BUDGET_DIMENSIONS, () => budgetDimensionSchema),
|
|
75
|
+
storageBytes: Schema.Struct({
|
|
76
|
+
...budgetDimensionSchema.fields,
|
|
77
|
+
/** Archived volumes' data bytes, part of `used`: kept until a person purges them. */
|
|
78
|
+
archived: Amount,
|
|
79
|
+
/** Bytes that backups and snapshots hold, not a volume's unused reserve for them. */
|
|
80
|
+
protection: Amount,
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
export const setResourceDomainBudgetRequestSchema = Schema.Struct({
|
|
84
|
+
...resourceDomainBudgetLimitsSchema.fields,
|
|
85
|
+
/** The revision this change replaces: the one the caller last read. */
|
|
86
|
+
revision: BudgetRevision,
|
|
87
|
+
});
|
|
39
88
|
export const resourceDomainSchema = Schema.Struct({
|
|
40
89
|
resourceDomainId: ResourceDomainId,
|
|
41
90
|
key: ResourceDomainKey,
|
|
42
91
|
createdAt: Schema.String,
|
|
43
92
|
});
|
|
44
|
-
export const ensureResourceDomainRequestSchema = Schema.Struct({
|
|
93
|
+
export const ensureResourceDomainRequestSchema = Schema.Struct({
|
|
94
|
+
key: ResourceDomainKey,
|
|
95
|
+
/** The budget a new domain starts with; none starts it at zero. */
|
|
96
|
+
budget: Schema.optional(resourceDomainBudgetLimitsSchema),
|
|
97
|
+
});
|
|
45
98
|
export const ensureResourceDomainResponseSchema = Schema.Struct({
|
|
46
99
|
...resourceDomainSchema.fields,
|
|
47
100
|
/** True when this call created the domain. */
|
|
@@ -90,6 +143,12 @@ export class ResourceDomainMemberVersionConflictError extends Schema.TaggedError
|
|
|
90
143
|
current: Schema.Struct({ state: MemberState, version: MemberVersion }),
|
|
91
144
|
}, { httpApiStatus: 409 }) {
|
|
92
145
|
}
|
|
146
|
+
/** The domain exists with another budget, at `revision`; nothing changed. */
|
|
147
|
+
export class ResourceDomainBudgetDiffersError extends Schema.TaggedError()("ResourceDomainBudgetDiffersError", { message: Schema.String, resourceDomainId: ResourceDomainId, revision: BudgetRevision }, { httpApiStatus: 409 }) {
|
|
148
|
+
}
|
|
149
|
+
/** `revision` is the current one. */
|
|
150
|
+
export class ResourceDomainBudgetRevisionConflictError extends Schema.TaggedError()("ResourceDomainBudgetRevisionConflictError", { message: Schema.String, revision: BudgetRevision }, { httpApiStatus: 409 }) {
|
|
151
|
+
}
|
|
93
152
|
export class ResourceDomainInternalServerError extends Schema.TaggedError()("ResourceDomainInternalServerError", { message: Schema.String }, { httpApiStatus: 500 }) {
|
|
94
153
|
}
|
|
95
154
|
const memberParams = Schema.Struct({ resourceDomainId: ResourceDomainId, userId: PersonId });
|
|
@@ -104,7 +163,11 @@ export const ResourceDomainsGroup = HttpApiGroup.make("resourceDomains")
|
|
|
104
163
|
.add(HttpApiEndpoint.post("ensureResourceDomain", "/", {
|
|
105
164
|
payload: ensureResourceDomainRequestSchema,
|
|
106
165
|
success: ensureResourceDomainResponseSchema,
|
|
107
|
-
error: [
|
|
166
|
+
error: [
|
|
167
|
+
ResourceDomainForbiddenError,
|
|
168
|
+
ResourceDomainBudgetDiffersError,
|
|
169
|
+
ResourceDomainInternalServerError,
|
|
170
|
+
],
|
|
108
171
|
}))
|
|
109
172
|
.add(HttpApiEndpoint.get("getResourceDomain", "/:resourceDomainId", {
|
|
110
173
|
params: Schema.Struct({ resourceDomainId: ResourceDomainId }),
|
|
@@ -147,6 +210,26 @@ export const ResourceDomainsGroup = HttpApiGroup.make("resourceDomains")
|
|
|
147
210
|
ResourceDomainNotFoundError,
|
|
148
211
|
ResourceDomainInternalServerError,
|
|
149
212
|
],
|
|
213
|
+
}))
|
|
214
|
+
.add(HttpApiEndpoint.get("getResourceDomainBudget", "/:resourceDomainId/budget", {
|
|
215
|
+
params: Schema.Struct({ resourceDomainId: ResourceDomainId }),
|
|
216
|
+
success: resourceDomainBudgetSchema,
|
|
217
|
+
error: [
|
|
218
|
+
ResourceDomainForbiddenError,
|
|
219
|
+
ResourceDomainNotFoundError,
|
|
220
|
+
ResourceDomainInternalServerError,
|
|
221
|
+
],
|
|
222
|
+
}))
|
|
223
|
+
.add(HttpApiEndpoint.put("setResourceDomainBudget", "/:resourceDomainId/budget", {
|
|
224
|
+
params: Schema.Struct({ resourceDomainId: ResourceDomainId }),
|
|
225
|
+
payload: setResourceDomainBudgetRequestSchema,
|
|
226
|
+
success: resourceDomainBudgetSchema,
|
|
227
|
+
error: [
|
|
228
|
+
ResourceDomainForbiddenError,
|
|
229
|
+
ResourceDomainNotFoundError,
|
|
230
|
+
ResourceDomainBudgetRevisionConflictError,
|
|
231
|
+
ResourceDomainInternalServerError,
|
|
232
|
+
],
|
|
150
233
|
}))
|
|
151
234
|
.annotate(HttpApi.PayloadParseOptions, { onExcessProperty: "error" })
|
|
152
235
|
.annotate(OpenApi.Description, "Owners that are projects, not people: they never hold a login or a provider credential.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealant/api-contracts-next",
|
|
3
|
-
"version": "0.40.0-next.
|
|
3
|
+
"version": "0.40.0-next.772",
|
|
4
4
|
"description": "Contract-first HTTP API definitions for Sealant services",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"effect": "^4.0.5"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "722ef7c7d08581db5c9c4de770d5630329063a97",
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
42
42
|
}
|