@selvajs/server 1.5.0-beta.12 → 1.5.0-beta.14

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.
Files changed (48) hide show
  1. package/dist/api/idempotency.d.ts +7 -1
  2. package/dist/api/idempotency.d.ts.map +1 -1
  3. package/dist/api/idempotency.js +17 -3
  4. package/dist/api/idempotency.js.map +1 -1
  5. package/dist/api/index.d.ts +1 -1
  6. package/dist/api/index.d.ts.map +1 -1
  7. package/dist/api/index.js +1 -1
  8. package/dist/api/index.js.map +1 -1
  9. package/dist/api/request.d.ts +6 -4
  10. package/dist/api/request.d.ts.map +1 -1
  11. package/dist/api/request.js +22 -7
  12. package/dist/api/request.js.map +1 -1
  13. package/dist/api/scope.d.ts +7 -0
  14. package/dist/api/scope.d.ts.map +1 -1
  15. package/dist/api/scope.js +15 -1
  16. package/dist/api/scope.js.map +1 -1
  17. package/dist/compute/idempotency.d.ts +8 -1
  18. package/dist/compute/idempotency.d.ts.map +1 -1
  19. package/dist/compute/idempotency.js +35 -5
  20. package/dist/compute/idempotency.js.map +1 -1
  21. package/dist/compute/limits.d.ts +0 -7
  22. package/dist/compute/limits.d.ts.map +1 -1
  23. package/dist/compute/limits.js +0 -1
  24. package/dist/compute/limits.js.map +1 -1
  25. package/dist/handlers/definitions.d.ts.map +1 -1
  26. package/dist/handlers/definitions.js +25 -13
  27. package/dist/handlers/definitions.js.map +1 -1
  28. package/dist/handlers/invites.d.ts +4 -3
  29. package/dist/handlers/invites.d.ts.map +1 -1
  30. package/dist/handlers/invites.js +17 -3
  31. package/dist/handlers/invites.js.map +1 -1
  32. package/dist/handlers/orgMembers.d.ts.map +1 -1
  33. package/dist/handlers/orgMembers.js +85 -52
  34. package/dist/handlers/orgMembers.js.map +1 -1
  35. package/dist/http/api-token.d.ts +2 -0
  36. package/dist/http/api-token.d.ts.map +1 -1
  37. package/dist/http/api-token.js +2 -1
  38. package/dist/http/api-token.js.map +1 -1
  39. package/dist/http/csrf.d.ts.map +1 -1
  40. package/dist/http/csrf.js +4 -4
  41. package/dist/http/csrf.js.map +1 -1
  42. package/dist/http/redirect.d.ts.map +1 -1
  43. package/dist/http/redirect.js +5 -0
  44. package/dist/http/redirect.js.map +1 -1
  45. package/dist/oauth/index.d.ts.map +1 -1
  46. package/dist/oauth/index.js +8 -6
  47. package/dist/oauth/index.js.map +1 -1
  48. package/package.json +5 -4
@@ -18,12 +18,18 @@ export declare const IDEMPOTENCY_KEY_HEADER = "Idempotency-Key";
18
18
  export declare const MAX_IDEMPOTENCY_KEY_LENGTH = 255;
19
19
  /** Covers a client's retry-on-timeout window without turning into a result cache. */
20
20
  export declare const DEFAULT_API_IDEMPOTENCY_TTL_MS: number;
21
+ /**
22
+ * Replayable response bytes one store keeps. A solve response can run to
23
+ * hundreds of MB, so the key cap alone would let a client that sends a fresh
24
+ * key per solve hold gigabytes for the whole TTL. Evicting costs a re-run.
25
+ */
26
+ export declare const DEFAULT_API_IDEMPOTENCY_MAX_BYTES: number;
21
27
  export interface IdempotentEntry {
22
28
  fingerprint: string;
23
29
  response: StoredResponse;
24
30
  }
25
31
  export type ApiIdempotencyStore = IdempotencyStore<IdempotentEntry>;
26
- export declare function createApiIdempotencyStore(ttlMs?: number): ApiIdempotencyStore;
32
+ export declare function createApiIdempotencyStore(ttlMs?: number, maxBytes?: number): ApiIdempotencyStore;
27
33
  /** The store `depsFromConfig` wires when the host passes none. One per process. */
28
34
  export declare function defaultApiIdempotencyStore(): ApiIdempotencyStore;
29
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/api/idempotency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AACxD,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,qFAAqF;AACrF,eAAO,MAAM,8BAA8B,QAAa,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;AAEpE,wBAAgB,yBAAyB,CACxC,KAAK,SAAiC,GACpC,mBAAmB,CAErB;AAID,mFAAmF;AACnF,wBAAgB,0BAA0B,IAAI,mBAAmB,CAEhE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAE/D;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAWlE;AAOD,2DAA2D;AAC3D,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,WAAW,GAAG,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,CAOjB;AAQD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,CAsBrF;AAmBD;;;;GAIG;AACH,wBAAsB,aAAa,CAClC,EACC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,EAAE;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAC3F,EAAE,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,GACzB,OAAO,CAAC,QAAQ,CAAC,CAiBnB"}
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/api/idempotency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AACxD,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,qFAAqF;AACrF,eAAO,MAAM,8BAA8B,QAAa,CAAC;AACzD;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAoB,CAAC;AAInE,MAAM,WAAW,eAAe;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;AAEpE,wBAAgB,yBAAyB,CACxC,KAAK,SAAiC,EACtC,QAAQ,SAAoC,GAC1C,mBAAmB,CAKrB;AAID,mFAAmF;AACnF,wBAAgB,0BAA0B,IAAI,mBAAmB,CAEhE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAE/D;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAWlE;AAOD,2DAA2D;AAC3D,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,WAAW,GAAG,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,CAOjB;AAQD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,CAsBrF;AAmBD;;;;GAIG;AACH,wBAAsB,aAAa,CAClC,EACC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,EAAE;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAC3F,EAAE,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,GACzB,OAAO,CAAC,QAAQ,CAAC,CAwBnB"}
@@ -20,8 +20,15 @@ export const IDEMPOTENCY_KEY_HEADER = 'Idempotency-Key';
20
20
  export const MAX_IDEMPOTENCY_KEY_LENGTH = 255;
21
21
  /** Covers a client's retry-on-timeout window without turning into a result cache. */
22
22
  export const DEFAULT_API_IDEMPOTENCY_TTL_MS = 5 * 60_000;
23
- export function createApiIdempotencyStore(ttlMs = DEFAULT_API_IDEMPOTENCY_TTL_MS) {
24
- return createIdempotencyStore({ ttlMs });
23
+ /**
24
+ * Replayable response bytes one store keeps. A solve response can run to
25
+ * hundreds of MB, so the key cap alone would let a client that sends a fresh
26
+ * key per solve hold gigabytes for the whole TTL. Evicting costs a re-run.
27
+ */
28
+ export const DEFAULT_API_IDEMPOTENCY_MAX_BYTES = 256 * 1024 * 1024;
29
+ const CLIENT_CLOSED_REQUEST = 499;
30
+ export function createApiIdempotencyStore(ttlMs = DEFAULT_API_IDEMPOTENCY_TTL_MS, maxBytes = DEFAULT_API_IDEMPOTENCY_MAX_BYTES) {
31
+ return createIdempotencyStore({ ttlMs, maxWeight: maxBytes }, (entry) => entry.response.body.byteLength);
25
32
  }
26
33
  let sharedDefault;
27
34
  /** The store `depsFromConfig` wires when the host passes none. One per process. */
@@ -117,8 +124,10 @@ function assertSameRequest(stored, fingerprint) {
117
124
  */
118
125
  export async function runIdempotent({ store, callerId, clientKey, fingerprint }, fn) {
119
126
  let outcome;
127
+ let ranHere = false;
120
128
  try {
121
129
  outcome = await store.run(idempotencyKey(callerId, clientKey), async () => {
130
+ ranHere = true;
122
131
  const res = await fn();
123
132
  const response = await toStoredResponse(res);
124
133
  if (res.status >= 400)
@@ -129,8 +138,13 @@ export async function runIdempotent({ store, callerId, clientKey, fingerprint },
129
138
  catch (err) {
130
139
  if (!(err instanceof NotReplayable))
131
140
  throw err;
132
- // A concurrent retry joining the failed attempt receives the same failure.
133
141
  assertSameRequest(err.fingerprint, fingerprint);
142
+ // 499 is the first client hanging up, which says nothing about this one:
143
+ // its retry is the case the store exists for, so it runs on its own.
144
+ if (!ranHere && err.response.status === CLIENT_CLOSED_REQUEST) {
145
+ return runIdempotent({ store, callerId, clientKey, fingerprint }, fn);
146
+ }
147
+ // A concurrent retry joining the failed attempt receives the same failure.
134
148
  return fromStoredResponse(err.response, false);
135
149
  }
136
150
  assertSameRequest(outcome.value.fingerprint, fingerprint);
@@ -1 +1 @@
1
- {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/api/idempotency.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/api/idempotency.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ export { formText, parseBody, parseParam, readForm, requireCaller, requireParams
7
7
  export { runHandler, toErrorBody, type ApiErrorBody, type RunHandlerOptions } from './respond.js';
8
8
  export { createApiRateLimiter, defaultApiRateLimiter, resolveApiRateLimitConfig, chargeApiRateLimit, rateLimitHeaders, rateLimitedResponse, withRateLimitHeaders, DEFAULT_API_RATE_LIMIT, type ApiRateLimiter, type ApiRateLimitConfig, type ApiRateLimitVerdict } from './rate-limit.js';
9
9
  export { createApiIdempotencyStore, defaultApiIdempotencyStore, idempotencyCallerId, readIdempotencyKey, requestFingerprint, runIdempotent, IDEMPOTENCY_KEY_HEADER, MAX_IDEMPOTENCY_KEY_LENGTH, DEFAULT_API_IDEMPOTENCY_TTL_MS, type ApiIdempotencyStore, type IdempotentEntry } from './idempotency.js';
10
- export { assertScope, actionForMethod, scopeRefusalsToday, projectScopeTarget, definitionScopeTarget } from './scope.js';
10
+ export { assertScope, assertScopeAnywhere, actionForMethod, scopeRefusalsToday, projectScopeTarget, definitionScopeTarget } from './scope.js';
11
11
  export { mapCoreError } from './map-core-error.js';
12
12
  export { buildOpenApiDocument, operationId, type Endpoint, type HttpMethod, type Json, type OpenApiOptions, type ResponseKind } from './openapi.js';
13
13
  export { parseListOptions, parseDefinitionListOptions } from './pagination.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1F,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EACN,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAC9B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACN,oBAAoB,EACpB,WAAW,EACX,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EACN,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,6BAA6B,EAC7B,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,uBAAuB,EACvB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1F,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EACN,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAC9B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACN,oBAAoB,EACpB,WAAW,EACX,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EACN,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,6BAA6B,EAC7B,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,uBAAuB,EACvB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,MAAM,uBAAuB,CAAC"}
package/dist/api/index.js CHANGED
@@ -10,7 +10,7 @@ export { formText, parseBody, parseParam, readForm, requireCaller, requireParams
10
10
  export { runHandler, toErrorBody } from './respond.js';
11
11
  export { createApiRateLimiter, defaultApiRateLimiter, resolveApiRateLimitConfig, chargeApiRateLimit, rateLimitHeaders, rateLimitedResponse, withRateLimitHeaders, DEFAULT_API_RATE_LIMIT } from './rate-limit.js';
12
12
  export { createApiIdempotencyStore, defaultApiIdempotencyStore, idempotencyCallerId, readIdempotencyKey, requestFingerprint, runIdempotent, IDEMPOTENCY_KEY_HEADER, MAX_IDEMPOTENCY_KEY_LENGTH, DEFAULT_API_IDEMPOTENCY_TTL_MS } from './idempotency.js';
13
- export { assertScope, actionForMethod, scopeRefusalsToday, projectScopeTarget, definitionScopeTarget } from './scope.js';
13
+ export { assertScope, assertScopeAnywhere, actionForMethod, scopeRefusalsToday, projectScopeTarget, definitionScopeTarget } from './scope.js';
14
14
  export { mapCoreError } from './map-core-error.js';
15
15
  export { buildOpenApiDocument, operationId } from './openapi.js';
16
16
  export { parseListOptions, parseDefinitionListOptions } from './pagination.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,8EAA8E;AAC9E,kEAAkE;AAElE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1F,OAAO,EAAE,cAAc,EAAkB,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAA6C,MAAM,cAAc,CAAC;AAClG,OAAO,EACN,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAG9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACN,oBAAoB,EACpB,WAAW,EAMX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EACN,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,6BAA6B,EAC7B,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,uBAAuB,EACvB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAE7B,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,8EAA8E;AAC9E,kEAAkE;AAElE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1F,OAAO,EAAE,cAAc,EAAkB,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAA6C,MAAM,cAAc,CAAC;AAClG,OAAO,EACN,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAG9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACN,oBAAoB,EACpB,WAAW,EAMX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EACN,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,6BAA6B,EAC7B,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,uBAAuB,EACvB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAE7B,MAAM,uBAAuB,CAAC"}
@@ -53,12 +53,13 @@ export declare function requireParams<K extends string>(params: Partial<Record<s
53
53
  */
54
54
  export declare function parseParam<T>(value: string | undefined, schema: ZodType<T>, name: string): T;
55
55
  /**
56
- * Parse and validate a JSON body. A malformed body becomes `null` rather than
57
- * throwing, so it fails the schema as a validation error — broken JSON gets a
58
- * 400 naming the problem, not a 500 from `request.json()`.
56
+ * Parse and validate a JSON body. Broken JSON is a 400, not a 500 from
57
+ * `request.json()`.
59
58
  *
60
59
  * `missingAs` covers endpoints whose fields are all optional: passing `{}` lets
61
- * an empty body mean "no changes" instead of a validation failure.
60
+ * an empty body mean "no changes" instead of a validation failure. Only an
61
+ * empty body: a truncated `{"versionId":…` read as "no changes" would publish
62
+ * the draft instead of rolling back.
62
63
  */
63
64
  export declare function parseBody<T>(request: Request, schema: ZodType<T>, { missingAs }?: {
64
65
  missingAs?: unknown;
@@ -67,6 +68,7 @@ export declare function parseBody<T>(request: Request, schema: ZodType<T>, { mis
67
68
  * The request's form body, parsed once: the idempotency fingerprint reads it
68
69
  * before the handler does, and a definition upload is too large to buffer twice.
69
70
  * On an idempotent route, `request.formData()` throws: the body is already used.
71
+ * A conformance test keeps handlers off it.
70
72
  */
71
73
  export declare function readForm(request: Request): Promise<FormData>;
72
74
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/api/request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG;IAAE,GAAG,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAKtF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,CAWlD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACvC,GAAG,KAAK,EAAE,CAAC,EAAE,GACX,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAqBnB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAM5F;AAMD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAChC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,EAAE,SAAS,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,OAAO,CAAC,CAAC,CAAC,CAKZ;AAQD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,EACC,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAc,EACd,EAAE;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,GACC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA4BnC;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CACvB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,EAAE,SAAS,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,MAAM,GAAG,SAAS,CAMpB"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/api/request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG;IAAE,GAAG,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAKtF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,CAWlD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACvC,GAAG,KAAK,EAAE,CAAC,EAAE,GACX,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAqBnB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAM5F;AAMD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAChC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,EAAE,SAAS,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,OAAO,CAAC,CAAC,CAAC,CAaZ;AAQD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAW5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,EACC,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAc,EACd,EAAE;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,GACC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA4BnC;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CACvB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,EAAE,SAAS,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,MAAM,GAAG,SAAS,CAMpB"}
@@ -92,15 +92,25 @@ export function parseParam(value, schema, name) {
92
92
  // Request bodies
93
93
  // ============================================================================
94
94
  /**
95
- * Parse and validate a JSON body. A malformed body becomes `null` rather than
96
- * throwing, so it fails the schema as a validation error — broken JSON gets a
97
- * 400 naming the problem, not a 500 from `request.json()`.
95
+ * Parse and validate a JSON body. Broken JSON is a 400, not a 500 from
96
+ * `request.json()`.
98
97
  *
99
98
  * `missingAs` covers endpoints whose fields are all optional: passing `{}` lets
100
- * an empty body mean "no changes" instead of a validation failure.
99
+ * an empty body mean "no changes" instead of a validation failure. Only an
100
+ * empty body: a truncated `{"versionId":…` read as "no changes" would publish
101
+ * the draft instead of rolling back.
101
102
  */
102
103
  export async function parseBody(request, schema, { missingAs } = {}) {
103
- const raw = await request.json().catch(() => null);
104
+ const text = await request.text().catch(() => '');
105
+ let raw = null;
106
+ if (text.trim()) {
107
+ try {
108
+ raw = JSON.parse(text);
109
+ }
110
+ catch {
111
+ apiError(400, ApiErrorCode.VALIDATION_FAILED, 'The request body is not valid JSON.');
112
+ }
113
+ }
104
114
  const parsed = schema.safeParse(raw ?? missingAs ?? null);
105
115
  if (!parsed.success)
106
116
  throwZodError(parsed.error);
@@ -114,11 +124,16 @@ const parsedForms = new WeakMap();
114
124
  * The request's form body, parsed once: the idempotency fingerprint reads it
115
125
  * before the handler does, and a definition upload is too large to buffer twice.
116
126
  * On an idempotent route, `request.formData()` throws: the body is already used.
127
+ * A conformance test keeps handlers off it.
117
128
  */
118
129
  export function readForm(request) {
119
130
  let form = parsedForms.get(request);
120
- if (!form)
121
- parsedForms.set(request, (form = request.formData()));
131
+ if (!form) {
132
+ form = request
133
+ .formData()
134
+ .catch(() => apiError(400, ApiErrorCode.VALIDATION_FAILED, 'The request body is not a valid form.'));
135
+ parsedForms.set(request, form);
136
+ }
122
137
  return form;
123
138
  }
124
139
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/api/request.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/api/request.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,13 @@ export declare function actionForMethod(method: string): ApiScopeAction;
10
10
  * `Response` must call it itself.
11
11
  */
12
12
  export declare function assertScope(ctx: RequestContext | undefined, action: ApiScopeAction, target?: ScopeTarget): void;
13
+ /**
14
+ * Refuse an API-token request whose key holds `action` on nothing at all. For
15
+ * routes that act only on the caller's own solves and streams, which name no
16
+ * project: a key that may solve in one project must still cancel and watch
17
+ * those solves.
18
+ */
19
+ export declare function assertScopeAnywhere(ctx: RequestContext | undefined, action: ApiScopeAction): void;
13
20
  /** Scope refusals for `tokenId` since midnight UTC, in this process. */
14
21
  export declare function scopeRefusalsToday(tokenId: string): number;
15
22
  /** Scope target for routes addressed by a project id param. */
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/api/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAC1B,GAAG,EAAE,cAAc,GAAG,SAAS,EAC/B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GAClB,IAAI,CAMN;AAeD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAQD,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,KAAK,SAAO,IACtC,KAAK,UAAU,KAAG,WAAW,CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,IACrC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,CAQpD"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/api/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAC1B,GAAG,EAAE,cAAc,GAAG,SAAS,EAC/B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GAClB,IAAI,CAMN;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAKjG;AAeD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAQD,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,KAAK,SAAO,IACtC,KAAK,UAAU,KAAG,WAAW,CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,IACrC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,CAQpD"}
package/dist/api/scope.js CHANGED
@@ -1,4 +1,4 @@
1
- import { outsideTokenOrg, scopeAllows } from '@selvajs/platform';
1
+ import { apiScopeActionCovers, outsideTokenOrg, scopeAllows } from '@selvajs/platform';
2
2
  import { apiError, ApiErrorCode } from './errors.js';
3
3
  /** The default action for a method: reads are `read`, everything else `write`. */
4
4
  export function actionForMethod(method) {
@@ -19,6 +19,20 @@ export function assertScope(ctx, action, target) {
19
19
  requiredScope: requiredScope(ctx, action, target)
20
20
  });
21
21
  }
22
+ /**
23
+ * Refuse an API-token request whose key holds `action` on nothing at all. For
24
+ * routes that act only on the caller's own solves and streams, which name no
25
+ * project: a key that may solve in one project must still cancel and watch
26
+ * those solves.
27
+ */
28
+ export function assertScopeAnywhere(ctx, action) {
29
+ if (!ctx?.apiScope)
30
+ return;
31
+ if (ctx.apiScope.scopes.some((s) => apiScopeActionCovers(s.action, action)))
32
+ return;
33
+ recordRefusal(ctx.apiScope.tokenId);
34
+ apiError(403, ApiErrorCode.FORBIDDEN, `This API token doesn't allow ${action}.`);
35
+ }
22
36
  // Per process and per UTC day, so the token page can flag a misconfigured
23
37
  // integration. Kept in memory on purpose: refusals are not audited.
24
38
  const refusals = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/api/scope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/api/scope.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,12 @@ export interface IdempotencyStoreConfig {
30
30
  * `ttlMs`. `0` disables the sweep, leaving only the cap (test seam).
31
31
  */
32
32
  sweepIntervalMs?: number;
33
+ /**
34
+ * Max total weight of completed entries, as measured by the store's `weigh`.
35
+ * The key cap alone doesn't bound memory when one entry can be a 100 MB
36
+ * solve. Over budget, the entries nearest expiry go first.
37
+ */
38
+ maxWeight?: number;
33
39
  }
34
40
  /** Default {@link IdempotencyStoreConfig.maxKeys}. */
35
41
  export declare const DEFAULT_IDEMPOTENCY_MAX_KEYS = 10000;
@@ -54,6 +60,7 @@ export interface IdempotencyStore<T> {
54
60
  /**
55
61
  * `T` is whatever the caller replays. It must not be a `Response` — a body can
56
62
  * only be read once, so the solve route stores a serialized snapshot instead.
63
+ * `weigh` measures a completed value for `maxWeight`.
57
64
  */
58
- export declare function createIdempotencyStore<T>(config: IdempotencyStoreConfig): IdempotencyStore<T>;
65
+ export declare function createIdempotencyStore<T>(config: IdempotencyStoreConfig, weigh?: (value: T) => number): IdempotencyStore<T>;
59
66
  //# sourceMappingURL=idempotency.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/compute/idempotency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,sBAAsB;IACtC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAEnD,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC;IACT,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;IACd,6DAA6D;IAC7D,IAAI,IAAI,MAAM,CAAC;IACf,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC;CAClD;AAYD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAwE7F"}
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/compute/idempotency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,sBAAsB;IACtC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAEnD,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC;IACT,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;IACd,6DAA6D;IAC7D,IAAI,IAAI,MAAM,CAAC;IACf,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC;CAClD;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EACvC,MAAM,EAAE,sBAAsB,EAC9B,KAAK,GAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAgB,GACnC,gBAAgB,CAAC,CAAC,CAAC,CAoGrB"}
@@ -20,11 +20,13 @@ export const DEFAULT_IDEMPOTENCY_MAX_KEYS = 10_000;
20
20
  /**
21
21
  * `T` is whatever the caller replays. It must not be a `Response` — a body can
22
22
  * only be read once, so the solve route stores a serialized snapshot instead.
23
+ * `weigh` measures a completed value for `maxWeight`.
23
24
  */
24
- export function createIdempotencyStore(config) {
25
+ export function createIdempotencyStore(config, weigh = () => 0) {
25
26
  const ttlMs = Math.max(0, Math.floor(config.ttlMs));
26
27
  const maxKeys = Math.max(1, Math.floor(config.maxKeys ?? DEFAULT_IDEMPOTENCY_MAX_KEYS));
27
28
  const sweepIntervalMs = Math.max(0, Math.floor(config.sweepIntervalMs ?? ttlMs));
29
+ const maxWeight = config.maxWeight ?? Number.POSITIVE_INFINITY;
28
30
  const resolvedConfig = Object.freeze({
29
31
  ...config,
30
32
  ttlMs,
@@ -33,6 +35,27 @@ export function createIdempotencyStore(config) {
33
35
  });
34
36
  const entries = new Map();
35
37
  let nextSweepAt = Number.POSITIVE_INFINITY;
38
+ let totalWeight = 0;
39
+ function drop(key) {
40
+ const entry = entries.get(key);
41
+ if (!entry)
42
+ return;
43
+ totalWeight -= entry.weight;
44
+ entries.delete(key);
45
+ }
46
+ /** Settled entries only, nearest expiry first: in-flight ones have retries awaiting them. */
47
+ function shedWeight() {
48
+ if (totalWeight <= maxWeight)
49
+ return;
50
+ const settled = [...entries.entries()]
51
+ .filter(([, e]) => e.expiresAt !== null)
52
+ .sort((a, b) => a[1].expiresAt - b[1].expiresAt);
53
+ for (const [key] of settled) {
54
+ if (totalWeight <= maxWeight)
55
+ break;
56
+ drop(key);
57
+ }
58
+ }
36
59
  function maybeSweep(now, headroom = 0) {
37
60
  const budget = Math.max(0, maxKeys - headroom);
38
61
  const dueForSweep = sweepIntervalMs > 0 && now >= nextSweepAt;
@@ -40,7 +63,7 @@ export function createIdempotencyStore(config) {
40
63
  return;
41
64
  for (const [key, entry] of entries) {
42
65
  if (entry.expiresAt !== null && now > entry.expiresAt)
43
- entries.delete(key);
66
+ drop(key);
44
67
  }
45
68
  if (sweepIntervalMs > 0)
46
69
  nextSweepAt = now + sweepIntervalMs;
@@ -49,7 +72,7 @@ export function createIdempotencyStore(config) {
49
72
  // awaiting it, so they are given up only when nothing else is left.
50
73
  const byExpiryAsc = [...entries.entries()].sort((a, b) => (a[1].expiresAt ?? Infinity) - (b[1].expiresAt ?? Infinity));
51
74
  for (let i = 0; i < byExpiryAsc.length - budget; i++)
52
- entries.delete(byExpiryAsc[i][0]);
75
+ drop(byExpiryAsc[i][0]);
53
76
  }
54
77
  }
55
78
  return {
@@ -62,7 +85,8 @@ export function createIdempotencyStore(config) {
62
85
  }
63
86
  maybeSweep(now, entries.has(key) ? 0 : 1);
64
87
  const promise = fn();
65
- const entry = { promise, expiresAt: null };
88
+ const entry = { promise, expiresAt: null, weight: 0 };
89
+ drop(key);
66
90
  entries.set(key, entry);
67
91
  if (sweepIntervalMs > 0 && nextSweepAt === Number.POSITIVE_INFINITY) {
68
92
  nextSweepAt = now + sweepIntervalMs;
@@ -70,6 +94,11 @@ export function createIdempotencyStore(config) {
70
94
  try {
71
95
  const value = await promise;
72
96
  entry.expiresAt = Date.now() + ttlMs;
97
+ if (entries.get(key) === entry) {
98
+ entry.weight = weigh(value);
99
+ totalWeight += entry.weight;
100
+ shedWeight();
101
+ }
73
102
  return { value, replayed: false };
74
103
  }
75
104
  catch (err) {
@@ -77,12 +106,13 @@ export function createIdempotencyStore(config) {
77
106
  // replaying the error to every retry for the whole TTL. Only drop our
78
107
  // own entry: a later `run` may already have replaced it.
79
108
  if (entries.get(key) === entry)
80
- entries.delete(key);
109
+ drop(key);
81
110
  throw err;
82
111
  }
83
112
  },
84
113
  reset() {
85
114
  entries.clear();
115
+ totalWeight = 0;
86
116
  nextSweepAt = Number.POSITIVE_INFINITY;
87
117
  },
88
118
  size() {
@@ -1 +1 @@
1
- {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/compute/idempotency.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/compute/idempotency.ts"],"names":[],"mappings":"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"}
@@ -94,13 +94,6 @@ export interface ComputeLimits {
94
94
  * restarts, spans instances). Only helps IDENTICAL re-solves.
95
95
  */
96
96
  computeServerCachesolve: boolean;
97
- /**
98
- * Also cache solves that reported Grasshopper errors — correct for
99
- * error-by-design definitions (guarded Python, pruned branches) that still
100
- * produce valid geometry. Requires `computeServerCachesolve` and a server
101
- * honoring the flag. Conservative default off.
102
- */
103
- computeCacheErroredSolves: boolean;
104
97
  /**
105
98
  * Backpressure — max solves allowed to WAIT in the per-server FIFO queue. This
106
99
  * excludes in-flight solves, which the scheduler caps at `maxConcurrent`,
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAI7D,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAQ3D,sGAAsG;AACtG,wBAAgB,eAAe,CAC9B,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAoBD;;;GAGG;AACH,wBAAgB,QAAQ,CACvB,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,OAAc,GACpB,OAAO,CAaT;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC7B;;;;;;;;;OASG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,oFAAoF;IACpF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,wBAAwB,EAAE,MAAM,CAAC;IACjC,wEAAwE;IACxE,8BAA8B,EAAE,MAAM,CAAC;IACvC;;;;;;;OAOG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,2BAA2B,EAAE,OAAO,CAAC;IACrC;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,yBAAyB,EAAE,OAAO,CAAC;IACnC;;;;;;;;;OASG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,2BAA2B,EAAE,MAAM,CAAC;IACpC;;;;;;;;;;;;OAYG;IACH,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,GAAE,OAAc,GAAG,aAAa,CAmD1F"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAI7D,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAQ3D,sGAAsG;AACtG,wBAAgB,eAAe,CAC9B,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAoBD;;;GAGG;AACH,wBAAgB,QAAQ,CACvB,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,OAAc,GACpB,OAAO,CAaT;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC7B;;;;;;;;;OASG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,oFAAoF;IACpF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,wBAAwB,EAAE,MAAM,CAAC;IACjC,wEAAwE;IACxE,8BAA8B,EAAE,MAAM,CAAC;IACvC;;;;;;;OAOG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,2BAA2B,EAAE,OAAO,CAAC;IACrC;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;;;;;OASG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,2BAA2B,EAAE,MAAM,CAAC;IACpC;;;;;;;;;;;;OAYG;IACH,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,GAAE,OAAc,GAAG,aAAa,CAkD1F"}
@@ -115,7 +115,6 @@ export function resolveComputeLimits(env, logger = noop) {
115
115
  remoteDefinitionCacheTtlMs: readPositiveInt(env, 'REMOTE_DEFINITION_CACHE_TTL_MS', 5 * 60 * 1000, logger),
116
116
  computeReuseDefinitionCache: readBool(env, 'COMPUTE_REUSE_DEFINITION_CACHE', true, logger),
117
117
  computeServerCachesolve: readBool(env, 'COMPUTE_SERVER_CACHESOLVE', true, logger),
118
- computeCacheErroredSolves: readBool(env, 'COMPUTE_CACHE_ERRORED_SOLVES', false, logger),
119
118
  // Both default to off — nothing is rejected until an operator who has measured
120
119
  // their pool opts in. readNonNegativeInt throughout, so `0` reads as "disabled"
121
120
  // rather than as an invalid value that falls back.
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/handlers/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA0BlD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,UA2B7B,CAAC;AAWF,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,EAAE,UA0F9B,CAAC;AAaF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,UAuB3B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,EAAE,UAM9B,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,EAAE,UAa9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAejC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAM/B,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,qBAAqB,EAAE,UAanC,CAAC"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/handlers/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA0BlD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,UA2B7B,CAAC;AAqBF,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,EAAE,UAiG9B,CAAC;AAaF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,UAuB3B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,EAAE,UAM9B,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,EAAE,UAa9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAejC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAM/B,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,qBAAqB,EAAE,UAanC,CAAC"}
@@ -10,7 +10,7 @@ import { apiError, ApiErrorCode, assertScope, collection, created, formText, noC
10
10
  import { toDefinitionListItem, toSourceDocumentId } from '@selvajs/platform';
11
11
  import { CreateDefinitionInputSchema, GuidSchema, PublishVersionInputSchema, UpdateMetadataInputSchema } from '@selvajs/platform/definitions';
12
12
  import { requireCanCreateDefinition, requireEditableDefinition } from '../access/index.js';
13
- import { GH_EXTENSIONS } from '@selvajs/platform';
13
+ import { COVER_IMAGE_CONTENT_TYPES, GH_EXTENSIONS } from '@selvajs/platform';
14
14
  import { resolveServerForOrg } from '../compute/index.js';
15
15
  import { fetchSchemaFromCompute, getVisibleDefinition, listEditableDefinitionsByDocument, listVisibleDefinitions, loadVisibleDefinition, loadVisibleVersion, mayUploadToDefinition, resolveAccessibleProjects } from '../definitions/index.js';
16
16
  import { definitionService } from './services.js';
@@ -52,6 +52,14 @@ function parseTags(raw) {
52
52
  .filter(Boolean);
53
53
  return tags.length ? tags : undefined;
54
54
  }
55
+ const COVER_IMAGE_TYPES = {
56
+ allowed: new Set(Object.values(COVER_IMAGE_CONTENT_TYPES)),
57
+ message: 'Unsupported image type. Allowed: PNG, JPEG, WebP, GIF'
58
+ };
59
+ function requireCoverImage(form, maxBytes) {
60
+ return requireUpload(form, 'image', { maxBytes, contentTypes: COVER_IMAGE_TYPES, label: 'Image' })
61
+ .file;
62
+ }
55
63
  /** Create a definition — metadata and the Grasshopper file in one request. */
56
64
  export const createDefinition = async (req) => {
57
65
  const { ctx, user } = requireCaller(req);
@@ -61,11 +69,11 @@ export const createDefinition = async (req) => {
61
69
  extensions: GH_EXTENSIONS,
62
70
  label: 'Grasshopper (.gh or .ghx) file'
63
71
  });
64
- const imageFile = form.get('image');
65
- const maxImageBytes = req.deps.uploadLimits.maxImageFileSize;
66
- if (imageFile instanceof File && imageFile.size > maxImageBytes) {
67
- apiError(400, ApiErrorCode.VALIDATION_FAILED, `Image too large. Max size: ${maxImageBytes / (1024 * 1024)} MB`);
68
- }
72
+ // Checked before anything is written, like the file itself.
73
+ const imageField = form.get('image');
74
+ const imageFile = imageField instanceof File && imageField.size > 0
75
+ ? requireCoverImage(form, req.deps.uploadLimits.maxImageFileSize)
76
+ : undefined;
69
77
  let projectId = formText(form, 'projectId');
70
78
  if (!projectId) {
71
79
  // The fallback picks a project on the caller's behalf, so it must pick
@@ -121,9 +129,16 @@ export const createDefinition = async (req) => {
121
129
  coverImage: parsed.data.coverImage
122
130
  }, fileData, schema);
123
131
  let coverImage = record.coverImage;
124
- if (imageFile instanceof File && imageFile.size > 0) {
125
- const imageData = new Uint8Array(await imageFile.arrayBuffer());
126
- coverImage = await service.saveCoverImage(ctx, guid, imageData);
132
+ if (imageFile) {
133
+ try {
134
+ coverImage = await service.saveCoverImage(ctx, guid, new Uint8Array(await imageFile.arrayBuffer()));
135
+ }
136
+ catch (err) {
137
+ // A failed request must leave nothing behind: the client's retry would
138
+ // create a second definition next to this one.
139
+ await service.delete(ctx, guid);
140
+ throw err;
141
+ }
127
142
  }
128
143
  return created({ guid, version, coverImage });
129
144
  };
@@ -218,10 +233,7 @@ export const publishDefinition = async (req) => {
218
233
  export const uploadDefinitionImage = async (req) => {
219
234
  const guid = parseParam(req.params.guid, GuidSchema, 'GUID');
220
235
  const { ctx } = await requireEditableDefinition(req, guid);
221
- const { file } = requireUpload(await readForm(req.request), 'image', {
222
- maxBytes: req.deps.uploadLimits.maxImageFileSize,
223
- label: 'Image'
224
- });
236
+ const file = requireCoverImage(await readForm(req.request), req.deps.uploadLimits.maxImageFileSize);
225
237
  const data = new Uint8Array(await file.arrayBuffer());
226
238
  return {
227
239
  body: { coverImage: await definitionService(req.deps).saveCoverImage(ctx, guid, data) }