@rebasepro/server 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/rest/query-parser.d.ts +37 -1
- package/dist/api/rest/write-validation.d.ts +26 -0
- package/dist/auth/index.d.ts +3 -1
- package/dist/auth/interfaces.d.ts +14 -1
- package/dist/auth/jwks-routes.d.ts +17 -0
- package/dist/auth/jwt-keys.d.ts +108 -0
- package/dist/auth/jwt.d.ts +62 -2
- package/dist/{auth-CYoPVf-E.js → auth-BobZVd0j.js} +142 -167
- package/dist/auth-BobZVd0j.js.map +1 -0
- package/dist/boot/boot.d.ts +36 -50
- package/dist/boot/ddl-bootstrap.d.ts +15 -0
- package/dist/boot/env.d.ts +20 -0
- package/dist/boot/provision.d.ts +182 -0
- package/dist/boot/role.d.ts +88 -0
- package/dist/{cron-store-Dvr4Y1sZ.js → cron-store-CB1x-Ken.js} +3 -3
- package/dist/{cron-store-Dvr4Y1sZ.js.map → cron-store-CB1x-Ken.js.map} +1 -1
- package/dist/{ddl-bootstrap-BhXbTnBl.js → ddl-bootstrap-Cywoj8Ta.js} +40 -2
- package/dist/ddl-bootstrap-Cywoj8Ta.js.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/functions/proxy.d.ts +41 -0
- package/dist/functions/selection.d.ts +45 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.es.js +1113 -661
- package/dist/index.es.js.map +1 -1
- package/dist/init/shutdown.d.ts +4 -0
- package/dist/init/surfaces.d.ts +79 -0
- package/dist/init.d.ts +121 -1
- package/dist/jobs/index.d.ts +5 -0
- package/dist/jobs/job-queue.d.ts +14 -0
- package/dist/jobs/job-store.d.ts +22 -0
- package/dist/jobs/types.d.ts +125 -0
- package/dist/jobs-DR4SjGrD.js +326 -0
- package/dist/jobs-DR4SjGrD.js.map +1 -0
- package/dist/{jwt-_IFqfTOg.js → jwt-VJyXTdQQ.js} +447 -11
- package/dist/jwt-VJyXTdQQ.js.map +1 -0
- package/dist/{openapi-generator-DPKtUC9X.js → openapi-generator-DQeQ_q2f.js} +68 -3
- package/dist/openapi-generator-DQeQ_q2f.js.map +1 -0
- package/dist/proxy-Bj5DVllb.js +139 -0
- package/dist/proxy-Bj5DVllb.js.map +1 -0
- package/dist/{request-timeout-RivJsME0.js → request-timeout-BuFoEKwT.js} +6 -3
- package/dist/request-timeout-BuFoEKwT.js.map +1 -0
- package/dist/selection-_z6TM1DB.js +64 -0
- package/dist/selection-_z6TM1DB.js.map +1 -0
- package/dist/services/webhook-service.d.ts +43 -5
- package/dist/{src-C7rkDGxA.js → src-8XDWyDfR.js} +84 -13
- package/dist/src-8XDWyDfR.js.map +1 -0
- package/dist/src-Cz9nMgUR.js.map +1 -1
- package/dist/storage/keys.d.ts +17 -0
- package/dist/storage/routes.d.ts +1 -1
- package/dist/storage/storage-registry.d.ts +46 -4
- package/dist/storage/tus-handler.d.ts +1 -1
- package/package.json +5 -5
- package/dist/auth-CYoPVf-E.js.map +0 -1
- package/dist/ddl-bootstrap-BhXbTnBl.js.map +0 -1
- package/dist/jwt-_IFqfTOg.js.map +0 -1
- package/dist/openapi-generator-DPKtUC9X.js.map +0 -1
- package/dist/request-timeout-RivJsME0.js.map +0 -1
- package/dist/src-C7rkDGxA.js.map +0 -1
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import type { JobQueueClient } from "../jobs/types";
|
|
2
|
+
/**
|
|
3
|
+
* The task name a queued webhook delivery is stored under.
|
|
4
|
+
*
|
|
5
|
+
* Namespaced, and frozen: it is written into `rebase.jobs` rows that outlive
|
|
6
|
+
* the deploy that wrote them, so renaming it would strand every delivery
|
|
7
|
+
* already queued under the old name until they dead-lettered.
|
|
8
|
+
*/
|
|
9
|
+
export declare const WEBHOOK_DELIVERY_TASK = "rebase.webhook.deliver";
|
|
1
10
|
export interface WebhookConfig {
|
|
2
11
|
id: string;
|
|
3
12
|
url: string;
|
|
@@ -43,6 +52,14 @@ export interface WebhookDispatcherOptions {
|
|
|
43
52
|
* `dns.lookup`; injected by tests so a unit suite never asks a resolver.
|
|
44
53
|
*/
|
|
45
54
|
lookup?: (hostname: string) => Promise<string[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Where {@link WebhookDispatcher.enqueueEntityChange} puts deliveries.
|
|
57
|
+
*
|
|
58
|
+
* Without it they go to an in-memory array that a crash or a deploy
|
|
59
|
+
* empties. With it they are rows, retried with backoff by a worker that
|
|
60
|
+
* may not even be the process that queued them.
|
|
61
|
+
*/
|
|
62
|
+
jobQueue?: JobQueueClient;
|
|
46
63
|
}
|
|
47
64
|
export declare class WebhookDispatcher {
|
|
48
65
|
private webhooks;
|
|
@@ -77,16 +94,37 @@ export declare class WebhookDispatcher {
|
|
|
77
94
|
* for a third party. It also means a receiver that is down can no longer
|
|
78
95
|
* fail the customer's write.
|
|
79
96
|
*
|
|
80
|
-
* The cost,
|
|
81
|
-
* or a deploy between the enqueue and the delivery drops
|
|
82
|
-
* receiver may see the notification a few milliseconds
|
|
83
|
-
* describes is committed. Use {@link flush} on shutdown,
|
|
84
|
-
* `onDelivery` to record failures.
|
|
97
|
+
* The cost, when no `jobQueue` is configured: the queue is in-process and
|
|
98
|
+
* in-memory. A crash or a deploy between the enqueue and the delivery drops
|
|
99
|
+
* the event, and a receiver may see the notification a few milliseconds
|
|
100
|
+
* before the row it describes is committed. Use {@link flush} on shutdown,
|
|
101
|
+
* and `onDelivery` to record failures.
|
|
102
|
+
*
|
|
103
|
+
* With `jobQueue` set, only the second half of that remains: the delivery
|
|
104
|
+
* becomes a row in `rebase.jobs` and survives the crash, the deploy and the
|
|
105
|
+
* pod being rescheduled.
|
|
85
106
|
*/
|
|
86
107
|
enqueueEntityChange(table: string, event: "INSERT" | "UPDATE" | "DELETE", id: string, entity: Record<string, unknown> | null, previousEntity?: Record<string, unknown> | null): void;
|
|
108
|
+
/**
|
|
109
|
+
* Deliver one queued job, as the worker runs it.
|
|
110
|
+
*
|
|
111
|
+
* One attempt, and it throws on failure. The retries belong to the queue
|
|
112
|
+
* now: keeping both would multiply — three in-process attempts inside each
|
|
113
|
+
* of three job attempts is nine deliveries and about two minutes of holding
|
|
114
|
+
* a worker slot — and only the queue's retries survive a restart, which is
|
|
115
|
+
* the whole reason for moving.
|
|
116
|
+
*/
|
|
117
|
+
deliverQueuedJob(job: {
|
|
118
|
+
webhookId: string;
|
|
119
|
+
event: string;
|
|
120
|
+
payload: Record<string, unknown>;
|
|
121
|
+
}): Promise<void>;
|
|
87
122
|
/**
|
|
88
123
|
* Wait for every queued delivery to finish. For graceful shutdown, and for
|
|
89
124
|
* tests that need to observe what {@link enqueueEntityChange} sent.
|
|
125
|
+
*
|
|
126
|
+
* In-process deliveries only — with a `jobQueue` configured there is
|
|
127
|
+
* nothing here to wait for, because the deliveries are rows.
|
|
90
128
|
*/
|
|
91
129
|
flush(): Promise<void>;
|
|
92
130
|
private startDraining;
|
|
@@ -3078,6 +3078,70 @@ var CollectionRegistry = class {
|
|
|
3078
3078
|
}
|
|
3079
3079
|
};
|
|
3080
3080
|
//#endregion
|
|
3081
|
+
//#region ../common/src/data/sort-dialect.ts
|
|
3082
|
+
/**
|
|
3083
|
+
* Sort-order wire codec.
|
|
3084
|
+
*
|
|
3085
|
+
* This is the ONLY module that knows about the colon-delimited wire format
|
|
3086
|
+
* (`"field:direction"`) used in HTTP query parameters, and about the JSON-array
|
|
3087
|
+
* form that carries a multi-column sort over the same parameter.
|
|
3088
|
+
* Everything else speaks {@link OrderByTuple} exclusively.
|
|
3089
|
+
*
|
|
3090
|
+
* Mirrors the filter architecture in `filter-dialect.ts`.
|
|
3091
|
+
*
|
|
3092
|
+
* @module
|
|
3093
|
+
*/
|
|
3094
|
+
/**
|
|
3095
|
+
* Collapse the one-key and many-key spellings of a sort into the list form.
|
|
3096
|
+
*
|
|
3097
|
+
* `["a", "desc"]` and `[["a", "desc"]]` mean the same thing and normalize to
|
|
3098
|
+
* the same value; the two are told apart by whether the first element is
|
|
3099
|
+
* itself an array, which no field name ever is.
|
|
3100
|
+
*
|
|
3101
|
+
* @returns The keys in order of significance, or `undefined` for no sort. An
|
|
3102
|
+
* empty list also returns `undefined` — "sort by nothing" is no sort, and
|
|
3103
|
+
* letting `[]` through would have every layer below re-deciding what it meant.
|
|
3104
|
+
*/
|
|
3105
|
+
function normalizeOrderBy(orderBy) {
|
|
3106
|
+
if (!orderBy || orderBy.length === 0) return void 0;
|
|
3107
|
+
const list = Array.isArray(orderBy[0]) ? orderBy : [orderBy];
|
|
3108
|
+
return list.length > 0 ? list : void 0;
|
|
3109
|
+
}
|
|
3110
|
+
/**
|
|
3111
|
+
* Serialize a sort to the wire.
|
|
3112
|
+
*
|
|
3113
|
+
* A single key keeps the `"field:direction"` shorthand it has always used —
|
|
3114
|
+
* short, readable in a URL, and what every existing client and test expects.
|
|
3115
|
+
* Several keys are emitted as the canonical JSON array the server already
|
|
3116
|
+
* accepts, because the shorthand has no separator to spare: a comma-joined
|
|
3117
|
+
* `"a:asc,b:desc"` parses as one field named `a` with the direction
|
|
3118
|
+
* `"asc,b:desc"`, which the server refuses.
|
|
3119
|
+
*
|
|
3120
|
+
* **Runtime tolerance:** if the input is already a well-formed wire string
|
|
3121
|
+
* (from an untyped JS caller), it is returned unchanged.
|
|
3122
|
+
* This is undocumented tolerance, not public API — don't rely on it.
|
|
3123
|
+
*
|
|
3124
|
+
* @param orderBy - A canonical tuple or list of tuples, or at runtime
|
|
3125
|
+
* possibly a pre-serialized string (undocumented tolerance).
|
|
3126
|
+
* @returns The wire-format string, or `undefined` if the input is falsy.
|
|
3127
|
+
*
|
|
3128
|
+
* @remarks
|
|
3129
|
+
* Field names containing `:` are representable in the tuple form but
|
|
3130
|
+
* **not** in the single-key wire encoding — this is an inherent limitation of
|
|
3131
|
+
* the colon-delimited shorthand and is not resolved here.
|
|
3132
|
+
*/
|
|
3133
|
+
function serializeOrderBy(orderBy) {
|
|
3134
|
+
if (!orderBy) return void 0;
|
|
3135
|
+
if (typeof orderBy === "string") return orderBy;
|
|
3136
|
+
const list = normalizeOrderBy(orderBy);
|
|
3137
|
+
if (!list) return void 0;
|
|
3138
|
+
if (list.length === 1) return `${list[0][0]}:${list[0][1]}`;
|
|
3139
|
+
return JSON.stringify(list.map(([field, direction]) => ({
|
|
3140
|
+
field,
|
|
3141
|
+
direction
|
|
3142
|
+
})));
|
|
3143
|
+
}
|
|
3144
|
+
//#endregion
|
|
3081
3145
|
//#region ../common/src/data/query_builder.ts
|
|
3082
3146
|
var QueryBuilder = class {
|
|
3083
3147
|
collection;
|
|
@@ -3106,11 +3170,18 @@ var QueryBuilder = class {
|
|
|
3106
3170
|
}
|
|
3107
3171
|
/**
|
|
3108
3172
|
* Order the results by a specific column.
|
|
3173
|
+
*
|
|
3174
|
+
* Called again, this adds a tie-breaker rather than replacing the sort:
|
|
3175
|
+
* keys apply in the order they were added.
|
|
3176
|
+
*
|
|
3109
3177
|
* @example
|
|
3110
3178
|
* client.collection('users').orderBy('createdAt', 'desc').find()
|
|
3179
|
+
* @example
|
|
3180
|
+
* client.collection('users').orderBy('roles').orderBy('createdAt', 'desc').find()
|
|
3111
3181
|
*/
|
|
3112
3182
|
orderBy(column, direction = "asc") {
|
|
3113
|
-
this.params.orderBy
|
|
3183
|
+
const existing = normalizeOrderBy(this.params.orderBy) ?? [];
|
|
3184
|
+
this.params.orderBy = [...existing, [column, direction]];
|
|
3114
3185
|
return this;
|
|
3115
3186
|
}
|
|
3116
3187
|
/**
|
|
@@ -3284,9 +3355,10 @@ async function* paginateFind(find, params, label = "collection") {
|
|
|
3284
3355
|
const requestedDirection = typeof cursor === "object" && cursor !== null ? cursor.direction : void 0;
|
|
3285
3356
|
let direction = "asc";
|
|
3286
3357
|
if (cursorField) {
|
|
3287
|
-
const orderBy = findParams.orderBy;
|
|
3288
|
-
if (orderBy && orderBy
|
|
3289
|
-
|
|
3358
|
+
const orderBy = normalizeOrderBy(findParams.orderBy);
|
|
3359
|
+
if (orderBy && orderBy.length > 1) throw new RebasePaginationError("cursor-order-mismatch", `Cannot seek on "${cursorField}" while ordering "${label}" by ${orderBy.map(([field]) => `"${field}"`).join(", ")}: keyset pagination advances along a single column. Order by "${cursorField}" alone, or drop the cursor and page by offset.`);
|
|
3360
|
+
if (orderBy && orderBy[0][0] !== cursorField) throw new RebasePaginationError("cursor-order-mismatch", `Cannot seek on "${cursorField}" while ordering "${label}" by "${orderBy[0][0]}": keyset pagination only advances along the column the query is sorted by. Order by "${cursorField}", or drop the cursor and page by offset.`);
|
|
3361
|
+
direction = requestedDirection ?? orderBy?.[0][1] ?? "asc";
|
|
3290
3362
|
findParams.orderBy = [cursorField, direction];
|
|
3291
3363
|
}
|
|
3292
3364
|
const seekOp = direction === "desc" ? "<" : ">";
|
|
@@ -3936,8 +4008,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
3936
4008
|
logical: params?.logical,
|
|
3937
4009
|
limit,
|
|
3938
4010
|
offset: driverOffset,
|
|
3939
|
-
orderBy: params?.orderBy
|
|
3940
|
-
order: params?.orderBy?.[1],
|
|
4011
|
+
orderBy: normalizeOrderBy(params?.orderBy),
|
|
3941
4012
|
searchString: params?.searchString
|
|
3942
4013
|
}, params?.include) : await driver.fetchCollection({
|
|
3943
4014
|
path: slug,
|
|
@@ -3945,8 +4016,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
3945
4016
|
offset: driverOffset,
|
|
3946
4017
|
filter,
|
|
3947
4018
|
logical: params?.logical,
|
|
3948
|
-
orderBy: params?.orderBy
|
|
3949
|
-
order: params?.orderBy?.[1],
|
|
4019
|
+
orderBy: normalizeOrderBy(params?.orderBy),
|
|
3950
4020
|
searchString: params?.searchString
|
|
3951
4021
|
});
|
|
3952
4022
|
let total = rows.length + offset;
|
|
@@ -4041,8 +4111,7 @@ function createDriverAccessor(driver, slug, getPks = () => []) {
|
|
|
4041
4111
|
offset: driverOffset,
|
|
4042
4112
|
filter: params?.where,
|
|
4043
4113
|
logical: params?.logical,
|
|
4044
|
-
orderBy: params?.orderBy
|
|
4045
|
-
order: params?.orderBy?.[1],
|
|
4114
|
+
orderBy: normalizeOrderBy(params?.orderBy),
|
|
4046
4115
|
searchString: params?.searchString,
|
|
4047
4116
|
searchExplain: params?.searchExplain,
|
|
4048
4117
|
onUpdate: (entities) => {
|
|
@@ -4162,8 +4231,10 @@ var SdkQueryBuilder = class {
|
|
|
4162
4231
|
}
|
|
4163
4232
|
return this;
|
|
4164
4233
|
}
|
|
4234
|
+
/** Called again, this adds a tie-breaker rather than replacing the sort. */
|
|
4165
4235
|
orderBy(column, direction = "asc") {
|
|
4166
|
-
this.params.orderBy
|
|
4236
|
+
const existing = normalizeOrderBy(this.params.orderBy) ?? [];
|
|
4237
|
+
this.params.orderBy = [...existing, [column, direction]];
|
|
4167
4238
|
return this;
|
|
4168
4239
|
}
|
|
4169
4240
|
limit(count) {
|
|
@@ -4361,6 +4432,6 @@ function buildRoutedRebaseData({ defaultData, sources, resolveKey }) {
|
|
|
4361
4432
|
} });
|
|
4362
4433
|
}
|
|
4363
4434
|
//#endregion
|
|
4364
|
-
export {
|
|
4435
|
+
export { GeoPoint as A, ListLimitError as C, isAnonymousUid as D, ANONYMOUS_USER_ID as E, RebaseApiError as M, RebaseClientError as N, EntityReference as O, toSnakeCase as S, resolveClientListLimit as T, fieldKeyForColumn as _, deserializeLogicalCondition as a, buildCompositeId as b, collectAllPages as c, normalizeOrderBy as d, serializeOrderBy as f, getEffectiveSecurityRules as g, resolveDataSource as h, deserializeFilter as i, Vector as j, EntityRelation as k, paginateFind as l, createDataSourceRegistry as m, buildSdkData as n, serializeFilter as o, CollectionRegistry as p, UnknownFilterOperatorError as r, serializeLogicalCondition as s, buildRoutedRebaseData as t, resolveFindWindow as u, findRelation as v, MAX_LIST_LIMIT as w, resolvePrimaryKeys as x, resolveCollectionRelations as y };
|
|
4365
4436
|
|
|
4366
|
-
//# sourceMappingURL=src-
|
|
4437
|
+
//# sourceMappingURL=src-8XDWyDfR.js.map
|