@rebasepro/server 0.22.0 → 0.23.0

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 (114) hide show
  1. package/dist/{GCSStorageController-CLIJXwGS.js → GCSStorageController-CjrA4PMo.js} +37 -23
  2. package/dist/GCSStorageController-CjrA4PMo.js.map +1 -0
  3. package/dist/{S3StorageController-Dcuf8lMA.js → S3StorageController-B6pKDNVj.js} +2 -2
  4. package/dist/{S3StorageController-Dcuf8lMA.js.map → S3StorageController-B6pKDNVj.js.map} +1 -1
  5. package/dist/api/ast-schema-editor.d.ts +35 -0
  6. package/dist/api/live-schema-routes.d.ts +14 -0
  7. package/dist/api/rest/api-generator.d.ts +117 -35
  8. package/dist/api/rest/auth-collection-writes.d.ts +85 -0
  9. package/dist/api/rest/field-access-query.d.ts +6 -2
  10. package/dist/api/rest/idempotency.d.ts +7 -1
  11. package/dist/api/rest/nested-write-access.d.ts +46 -0
  12. package/dist/api/rest/write-validation.d.ts +32 -0
  13. package/dist/{ast-schema-editor-CslO8Oje.js → ast-schema-editor-Mvr50v_S.js} +104 -4
  14. package/dist/ast-schema-editor-Mvr50v_S.js.map +1 -0
  15. package/dist/auth/address-ownership.d.ts +53 -0
  16. package/dist/auth/admin-user-ops.d.ts +35 -2
  17. package/dist/auth/auth-hooks.d.ts +4 -0
  18. package/dist/auth/captcha.d.ts +5 -0
  19. package/dist/auth/interfaces.d.ts +36 -6
  20. package/dist/auth/jwt.d.ts +17 -0
  21. package/dist/auth/oauth-signin-policy.d.ts +25 -8
  22. package/dist/auth/rate-limiter.d.ts +31 -1
  23. package/dist/auth/session-routes.d.ts +7 -0
  24. package/dist/auth/token-revocation.d.ts +4 -1
  25. package/dist/{auth-CCDpk2rn.js → auth-B-GIMpDG.js} +639 -228
  26. package/dist/auth-B-GIMpDG.js.map +1 -0
  27. package/dist/backend-DTAOsLQc.js +30 -0
  28. package/dist/backend-DTAOsLQc.js.map +1 -0
  29. package/dist/backup/backup-common.d.ts +19 -0
  30. package/dist/{backup-DzI9jLwc.js → backup-D7YR94N3.js} +69 -8
  31. package/dist/backup-D7YR94N3.js.map +1 -0
  32. package/dist/boot/driver.d.ts +10 -0
  33. package/dist/boot/env.d.ts +2 -2
  34. package/dist/boot/fetch-bundle.d.ts +18 -1
  35. package/dist/boot/rls-audit-option.d.ts +26 -0
  36. package/dist/boot/sources.d.ts +1 -0
  37. package/dist/{contract-routes-eLxV0le1.js → contract-routes-CbFjuBwa.js} +2 -2
  38. package/dist/{contract-routes-eLxV0le1.js.map → contract-routes-CbFjuBwa.js.map} +1 -1
  39. package/dist/cron/cron-routes.d.ts +7 -2
  40. package/dist/cron/cron-scheduler.d.ts +128 -8
  41. package/dist/cron/cron-store.d.ts +72 -8
  42. package/dist/cron/index.d.ts +1 -1
  43. package/dist/{cron-loader-CQjvjpEw.js → cron-loader-DfTj2Hbi.js} +2 -2
  44. package/dist/{cron-loader-CQjvjpEw.js.map → cron-loader-DfTj2Hbi.js.map} +1 -1
  45. package/dist/{cron-routes-B7CRGfiq.js → cron-routes-eE8nif_b.js} +33 -12
  46. package/dist/cron-routes-eE8nif_b.js.map +1 -0
  47. package/dist/{cron-scheduler-COPQxlEq.js → cron-scheduler-B0pLfAix.js} +394 -68
  48. package/dist/cron-scheduler-B0pLfAix.js.map +1 -0
  49. package/dist/{cron-store-BYGZFNWk.js → cron-store-TcoGz-xS.js} +133 -12
  50. package/dist/cron-store-TcoGz-xS.js.map +1 -0
  51. package/dist/{ddl-bootstrap-CfNvxMuK.js → ddl-bootstrap-C6mo0Kmz.js} +2 -25
  52. package/dist/ddl-bootstrap-C6mo0Kmz.js.map +1 -0
  53. package/dist/email/link-base.d.ts +5 -4
  54. package/dist/email/smtp-email-service.d.ts +13 -1
  55. package/dist/email/templates.d.ts +9 -0
  56. package/dist/email/types.d.ts +3 -2
  57. package/dist/env.d.ts +24 -5
  58. package/dist/{history-recorder-BQmB0P_j.js → history-recorder-B4MpJfJK.js} +8 -6
  59. package/dist/history-recorder-B4MpJfJK.js.map +1 -0
  60. package/dist/{history-store-CetkrBBD.js → history-store-BhxWOuz9.js} +2 -2
  61. package/dist/{history-store-CetkrBBD.js.map → history-store-BhxWOuz9.js.map} +1 -1
  62. package/dist/index.d.ts +6 -2
  63. package/dist/index.es.js +2717 -866
  64. package/dist/index.es.js.map +1 -1
  65. package/dist/init/docs.d.ts +5 -2
  66. package/dist/init/shutdown.d.ts +8 -3
  67. package/dist/jobs/index.d.ts +2 -2
  68. package/dist/jobs/job-queue.d.ts +23 -2
  69. package/dist/jobs/job-store.d.ts +37 -5
  70. package/dist/jobs/types.d.ts +8 -6
  71. package/dist/{jobs-Bjr8DZAi.js → jobs-CazMYhyy.js} +305 -166
  72. package/dist/jobs-CazMYhyy.js.map +1 -0
  73. package/dist/{jwt-C4OW-DNq.js → jwt-DnQHNFCl.js} +77 -25
  74. package/dist/{jwt-C4OW-DNq.js.map → jwt-DnQHNFCl.js.map} +1 -1
  75. package/dist/{keys-Qfc4XieN.js → keys-CogCQpxG.js} +18 -3
  76. package/dist/{keys-Qfc4XieN.js.map → keys-CogCQpxG.js.map} +1 -1
  77. package/dist/{logs-routes-3EEzPjhl.js → logs-routes-Bj4TYYUl.js} +7 -4
  78. package/dist/{logs-routes-3EEzPjhl.js.map → logs-routes-Bj4TYYUl.js.map} +1 -1
  79. package/dist/mcp/mcp-routes.d.ts +38 -2
  80. package/dist/mcp/mcp-tools.d.ts +7 -1
  81. package/dist/mcp/oauth-routes.d.ts +27 -0
  82. package/dist/mcp/oauth-store.d.ts +29 -13
  83. package/dist/metrics/history-recorder.d.ts +1 -1
  84. package/dist/{openapi-generator-D8uFz-LW.js → openapi-generator-O_O24MAT.js} +34 -12
  85. package/dist/openapi-generator-O_O24MAT.js.map +1 -0
  86. package/dist/{query-parser-BleZmY18.js → query-parser-DGRVFNM3.js} +39 -30
  87. package/dist/query-parser-DGRVFNM3.js.map +1 -0
  88. package/dist/rls-audit/index.d.ts +4 -0
  89. package/dist/{schema-editor-routes-DdLihzp0.js → schema-editor-routes-C5-lh_jO.js} +2 -2
  90. package/dist/{schema-editor-routes-DdLihzp0.js.map → schema-editor-routes-C5-lh_jO.js.map} +1 -1
  91. package/dist/{src-1vL-I1Po.js → src-pmvW7BFx.js} +122 -14
  92. package/dist/src-pmvW7BFx.js.map +1 -0
  93. package/dist/{src-Br6ARbs6.js → src-vkcwKXbT.js} +2 -27
  94. package/dist/{src-Br6ARbs6.js.map → src-vkcwKXbT.js.map} +1 -1
  95. package/dist/storage/GCSStorageController.d.ts +11 -1
  96. package/dist/storage/keys.d.ts +12 -0
  97. package/dist/storage/rendition-cache.d.ts +11 -1
  98. package/dist/storage/request-keys.d.ts +67 -0
  99. package/dist/storage/types.d.ts +17 -1
  100. package/dist/types-BfKcm9do.js.map +1 -1
  101. package/package.json +9 -9
  102. package/dist/GCSStorageController-CLIJXwGS.js.map +0 -1
  103. package/dist/ast-schema-editor-CslO8Oje.js.map +0 -1
  104. package/dist/auth-CCDpk2rn.js.map +0 -1
  105. package/dist/backup-DzI9jLwc.js.map +0 -1
  106. package/dist/cron-routes-B7CRGfiq.js.map +0 -1
  107. package/dist/cron-scheduler-COPQxlEq.js.map +0 -1
  108. package/dist/cron-store-BYGZFNWk.js.map +0 -1
  109. package/dist/ddl-bootstrap-CfNvxMuK.js.map +0 -1
  110. package/dist/history-recorder-BQmB0P_j.js.map +0 -1
  111. package/dist/jobs-Bjr8DZAi.js.map +0 -1
  112. package/dist/openapi-generator-D8uFz-LW.js.map +0 -1
  113. package/dist/query-parser-BleZmY18.js.map +0 -1
  114. package/dist/src-1vL-I1Po.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Hono } from "hono";
1
+ import { Hono, type MiddlewareHandler } from "hono";
2
2
  import { CollectionConfig } from "@rebasepro/types";
3
3
  import { HonoEnv } from "../api/types.js";
4
4
  /**
@@ -9,5 +9,8 @@ import { HonoEnv } from "../api/types.js";
9
9
  * active collection. A direct-transport collection is served by the client
10
10
  * against its own backend; documenting it here publishes a full set of CRUD
11
11
  * paths that 404, with a Try-It button next to each.
12
+ *
13
+ * `adminGate` is the runtime's admin gate — the middlewares every admin surface
14
+ * sits behind — for the spec when it is not public.
12
15
  */
13
- export declare function mountOpenApiDocs(app: Hono<HonoEnv>, basePath: string, enableSwagger: boolean | undefined, serverCollections: CollectionConfig[], requireAuth: boolean): Promise<void>;
16
+ export declare function mountOpenApiDocs(app: Hono<HonoEnv>, basePath: string, enableSwagger: boolean | undefined, serverCollections: CollectionConfig[], requireAuth: boolean, adminGate: MiddlewareHandler<HonoEnv>[]): Promise<void>;
@@ -2,17 +2,20 @@ import { Server } from "http";
2
2
  import { RealtimeProvider } from "@rebasepro/types";
3
3
  interface ShutdownConfig {
4
4
  server: Server;
5
+ /** Structural, for the same no-circular-imports reason as the backend below. */
5
6
  cronScheduler?: {
6
- stop(): void;
7
+ stop(timeoutMs?: number): Promise<void> | void;
7
8
  };
8
9
  /** Structural, for the same no-circular-imports reason as the backend below. */
9
10
  jobQueue?: {
10
- stop(): Promise<void>;
11
+ stop(timeoutMs?: number): Promise<void>;
11
12
  };
12
13
  /** Structural, same reason. */
13
14
  rlsAudit?: {
14
15
  stop(): void;
15
16
  };
17
+ /** The stop `MetricsHistory.start()` returned: its interval writes to the pool. */
18
+ stopMetricsSampler?: () => void;
16
19
  realtimeServices: Record<string, RealtimeProvider>;
17
20
  }
18
21
  /**
@@ -32,7 +35,9 @@ export interface ShutdownHandlerOptions {
32
35
  /**
33
36
  * Hard force-exit timeout in milliseconds. If the shutdown sequence
34
37
  * (drain + cleanup) has not completed by then, the process exits with
35
- * code 1. Also passed to `backend.shutdown()` as its drain timeout.
38
+ * code 1. `backend.shutdown()` is given this budget less a reserve for
39
+ * `onCleanup` (the smaller of 2s and a fifth of it), so a drain the
40
+ * backend has to force still ends in the pool close.
36
41
  *
37
42
  * @default 15000
38
43
  */
@@ -1,5 +1,5 @@
1
1
  export { createJobStore } from "./job-store.js";
2
- export type { JobStore } from "./job-store.js";
3
- export { createJobQueue, defaultBackoff } from "./job-queue.js";
2
+ export type { JobClaim, JobStore } from "./job-store.js";
3
+ export { createJobQueue, defaultBackoff, PermanentJobError } from "./job-queue.js";
4
4
  export type { JobQueue } from "./job-queue.js";
5
5
  export type { EnqueueOptions, JobContext, JobHandler, JobQueueClient, JobQueueOptions, JobRecord, JobStatus } from "./types.js";
@@ -2,10 +2,31 @@ import type { JobStore } from "./job-store.js";
2
2
  import type { JobHandler, JobQueueClient, JobQueueOptions } from "./types.js";
3
3
  /** 1s, 5s, 25s, 125s … capped at an hour. */
4
4
  export declare function defaultBackoff(attempt: number): number;
5
+ /**
6
+ * Thrown by a handler for a failure no retry can change — a destination that
7
+ * is refused, a receiver that redirects. The job is dead-lettered on this
8
+ * attempt, with the message as its `last_error`, instead of spending its
9
+ * remaining attempts proving the same thing. Returning normally is not the
10
+ * alternative: that records the job as succeeded.
11
+ */
12
+ export declare class PermanentJobError extends Error {
13
+ constructor(message: string, options?: {
14
+ cause?: unknown;
15
+ });
16
+ }
5
17
  export interface JobQueue extends JobQueueClient {
6
18
  start(): void;
7
- stop(): Promise<void>;
8
- /** Run one poll's worth of work and return how many jobs ran. For tests and for `/jobs/drain`. */
19
+ /**
20
+ * Stop claiming, and wait for the jobs in flight — for at most `timeoutMs`
21
+ * when given. A job still running when the budget runs out keeps its claim
22
+ * and is recovered by the visibility timeout; waiting on it without a bound
23
+ * would let one handler that never settles hold the whole shutdown.
24
+ */
25
+ stop(timeoutMs?: number): Promise<void>;
26
+ /**
27
+ * Claim what fits in the free slots, run it, and resolve with how many jobs
28
+ * ran. For tests and for `/jobs/drain`; not meant to run beside `start()`.
29
+ */
9
30
  runOnce(): Promise<number>;
10
31
  /** Registered after construction — how `tasks` from config and internal producers meet. */
11
32
  register<P = unknown>(task: string, handler: JobHandler<P>): void;
@@ -1,5 +1,21 @@
1
1
  import type { DataDriver } from "@rebasepro/types";
2
2
  import type { JobRecord } from "./types.js";
3
+ /**
4
+ * Which claim an outcome belongs to: the worker holding the job, and the
5
+ * attempt that claim spent.
6
+ *
7
+ * The visibility timeout hands a job to a second worker when the first stops
8
+ * renewing its claim, and the first may still be running — slow, not dead. Its
9
+ * outcome is then about an attempt the table has moved past, and writing it
10
+ * would mark a running job `succeeded`, or send a finished one back to
11
+ * `pending` for another run. Both writes therefore apply only while the claim
12
+ * they name still holds the row. The attempt is part of the identity because a
13
+ * worker's own reaper can hand a job back to the same worker in another slot.
14
+ */
15
+ export interface JobClaim {
16
+ workerId: string;
17
+ attempt: number;
18
+ }
3
19
  export interface JobStore {
4
20
  ensureTable(): Promise<void>;
5
21
  /** Returns the new job's id, or `null` if an idempotency key matched unfinished work. */
@@ -10,11 +26,27 @@ export interface JobStore {
10
26
  maxAttempts: number;
11
27
  idempotencyKey?: string;
12
28
  }): Promise<string | null>;
13
- /** Atomically take up to `limit` runnable jobs for this worker. */
14
- claim(limit: number, workerId: string): Promise<JobRecord[]>;
15
- complete(id: string): Promise<void>;
16
- /** Back to `pending` with a later `runAt`, or `failed` when out of attempts. */
17
- fail(id: string, error: string, retryAt: Date | null): Promise<void>;
29
+ /**
30
+ * Atomically take up to `limit` runnable jobs for this worker — only jobs
31
+ * whose task is in `tasks`, when it is given. A worker never claims work it
32
+ * cannot run: a claim spends an attempt, so an instance running older code
33
+ * during a rollout would otherwise dead-letter the newer code's jobs.
34
+ */
35
+ claim(limit: number, workerId: string, tasks?: readonly string[]): Promise<JobRecord[]>;
36
+ /** Mark the job `succeeded` — a no-op once `claim` no longer holds it. */
37
+ complete(id: string, claim: JobClaim): Promise<void>;
38
+ /**
39
+ * Back to `pending` with a later `runAt`, or `failed` when out of attempts —
40
+ * a no-op once `claim` no longer holds it.
41
+ */
42
+ fail(id: string, error: string, retryAt: Date | null, claim: JobClaim): Promise<void>;
43
+ /**
44
+ * Renew `claim` on a job whose handler is still running, so the visibility
45
+ * timeout only ever reclaims a job from a worker that stopped renewing.
46
+ * Resolves with whether the claim still held. A store without it leaves a
47
+ * handler that outlives the timeout to be run a second time beside itself.
48
+ */
49
+ heartbeat?(id: string, claim: JobClaim): Promise<boolean>;
18
50
  /** Return jobs stranded by a worker that died holding them. Resolves with how many. */
19
51
  reapExpired(visibilityTimeoutMs: number): Promise<number>;
20
52
  fetch(id: string): Promise<JobRecord | null>;
@@ -101,14 +101,16 @@ export interface JobQueueOptions {
101
101
  /** How often to look for work when the last look found none. Default 2000ms. */
102
102
  pollIntervalMs?: number;
103
103
  /**
104
- * How long a claimed job may stay claimed before another worker may take
105
- * it. Default 5 minutes.
104
+ * How long a claim may go unrenewed before another worker may take the job.
105
+ * Default 5 minutes.
106
106
  *
107
107
  * This is the only thing that recovers work from a worker that died holding
108
- * it — a `SIGKILL`ed pod cannot release its own claim. It is therefore also
109
- * the interval after which a job that legitimately runs longer than this
110
- * gets a *second* worker running it concurrently, so it must exceed the
111
- * slowest handler.
108
+ * it — a `SIGKILL`ed pod cannot release its own claim. A live worker renews
109
+ * the claim every third of this while the handler runs, so a handler may
110
+ * run longer than it; what it bounds is how long a dead worker's job waits.
111
+ * A worker whose event loop is blocked for longer than this cannot renew,
112
+ * and its job is run again beside it — though only the claim that holds
113
+ * the job when a run finishes gets to record its outcome.
112
114
  */
113
115
  visibilityTimeoutMs?: number;
114
116
  /** Attempts before a job is left `failed`. Default 3. */