backlex 0.1.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.
- package/LICENSE +201 -0
- package/README.md +43 -0
- package/dist/chunk-U2MHWV2E.js +44 -0
- package/dist/chunk-UIUS57OR.js +15 -0
- package/dist/index.d.ts +569 -0
- package/dist/index.js +857 -0
- package/dist/types-CbcbXGiA.d.ts +247 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +1 -0
- package/dist/webhook.d.ts +39 -0
- package/dist/webhook.js +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/** Comparison operators for a single field (multi-key maps AND together). */
|
|
2
|
+
interface ComparisonObj {
|
|
3
|
+
_eq?: unknown;
|
|
4
|
+
_neq?: unknown;
|
|
5
|
+
_in?: unknown[];
|
|
6
|
+
_nin?: unknown[];
|
|
7
|
+
_gt?: unknown;
|
|
8
|
+
_gte?: unknown;
|
|
9
|
+
_lt?: unknown;
|
|
10
|
+
_lte?: unknown;
|
|
11
|
+
/** Inclusive range: `col BETWEEN lo AND hi`. */
|
|
12
|
+
_between?: [unknown, unknown];
|
|
13
|
+
_null?: boolean;
|
|
14
|
+
_contains?: string;
|
|
15
|
+
_starts_with?: string;
|
|
16
|
+
_ends_with?: string;
|
|
17
|
+
/** Case-insensitive variants (LOWER() both sides → PG/SQLite parity). */
|
|
18
|
+
_icontains?: string;
|
|
19
|
+
_istarts_with?: string;
|
|
20
|
+
_iends_with?: string;
|
|
21
|
+
/** `_empty: true` ⇒ NULL or empty string; `_nempty: true` ⇒ neither. */
|
|
22
|
+
_empty?: boolean;
|
|
23
|
+
_nempty?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Relative-date value usable anywhere a comparison value is expected, e.g.
|
|
27
|
+
* `{ placed_at: { _gte: { $now: { sub: { months: 1 } } } } }`. Bare `"$now"`
|
|
28
|
+
* still means "this instant"; resolved server-side to the dialect-correct value.
|
|
29
|
+
*/
|
|
30
|
+
interface RelativeNow {
|
|
31
|
+
$now: {
|
|
32
|
+
add?: DurationParts;
|
|
33
|
+
sub?: DurationParts;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
interface DurationParts {
|
|
37
|
+
years?: number;
|
|
38
|
+
months?: number;
|
|
39
|
+
weeks?: number;
|
|
40
|
+
days?: number;
|
|
41
|
+
hours?: number;
|
|
42
|
+
minutes?: number;
|
|
43
|
+
seconds?: number;
|
|
44
|
+
}
|
|
45
|
+
type Condition = {
|
|
46
|
+
$and: Condition[];
|
|
47
|
+
} | {
|
|
48
|
+
$or: Condition[];
|
|
49
|
+
} | {
|
|
50
|
+
$not: Condition;
|
|
51
|
+
} | {
|
|
52
|
+
[field: string]: ComparisonObj;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
interface ListResponse<T> {
|
|
56
|
+
data: T[];
|
|
57
|
+
limit: number;
|
|
58
|
+
offset: number;
|
|
59
|
+
meta?: {
|
|
60
|
+
filter_count?: number;
|
|
61
|
+
total_count?: number;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
interface ItemResponse<T> {
|
|
65
|
+
data: T;
|
|
66
|
+
}
|
|
67
|
+
interface ListQuery {
|
|
68
|
+
filter?: Condition;
|
|
69
|
+
sort?: string | string[];
|
|
70
|
+
fields?: string | string[];
|
|
71
|
+
/** Inline single-hop relations (replaces the FK with the related object). */
|
|
72
|
+
expand?: string | string[];
|
|
73
|
+
limit?: number;
|
|
74
|
+
offset?: number;
|
|
75
|
+
meta?: "filter_count" | "total_count" | "*";
|
|
76
|
+
/** Collapse `i18n_text` fields to one locale, or `"*"` for the full map. */
|
|
77
|
+
locale?: string;
|
|
78
|
+
/** Free-text search — `_contains` OR'd across readable text fields. */
|
|
79
|
+
q?: string;
|
|
80
|
+
/** Versioned collections only. `published` (default for unprivileged callers)
|
|
81
|
+
* returns published items; `draft` / `all` require `publish`/`update`
|
|
82
|
+
* permission, otherwise they're ignored and published-only is enforced. */
|
|
83
|
+
status?: "draft" | "published" | "all";
|
|
84
|
+
}
|
|
85
|
+
/** Per-call options for `from(slug).one(id, ...)`. Mirrors the single-item
|
|
86
|
+
* read endpoint, which accepts the same `expand`/`locale` query params as the
|
|
87
|
+
* list endpoint. */
|
|
88
|
+
interface ItemQuery {
|
|
89
|
+
/** Inline single-hop relations (replaces the FK with the related object). */
|
|
90
|
+
expand?: string | string[];
|
|
91
|
+
/** Collapse `i18n_text` fields to one locale, or `"*"` for the full map. */
|
|
92
|
+
locale?: string;
|
|
93
|
+
}
|
|
94
|
+
/** Body for `from(slug).aggregate(...)`. A single function over one column. */
|
|
95
|
+
interface AggregateQuery {
|
|
96
|
+
agg: "count" | "sum" | "avg" | "min" | "max";
|
|
97
|
+
/** Target column. Required for sum/avg/min/max; omit (or "*") for count. */
|
|
98
|
+
field?: string;
|
|
99
|
+
/** Group by a single column — returns one `{ label, value }` row per group. */
|
|
100
|
+
groupBy?: string;
|
|
101
|
+
filter?: Condition;
|
|
102
|
+
limit?: number;
|
|
103
|
+
}
|
|
104
|
+
/** A row from `aggregate`: `{ value }` ungrouped, or `{ label, value }` grouped. */
|
|
105
|
+
interface AggregateRow {
|
|
106
|
+
value: number;
|
|
107
|
+
label?: unknown;
|
|
108
|
+
}
|
|
109
|
+
/** Body for `from(slug).search(...)` — relevance search over a collection. */
|
|
110
|
+
interface SearchQuery {
|
|
111
|
+
/** The query string. */
|
|
112
|
+
q: string;
|
|
113
|
+
/** `fts` = keyword index, `vector` = semantic embeddings, `hybrid` = both
|
|
114
|
+
* fused with Reciprocal Rank Fusion. Defaults server-side to `hybrid` when
|
|
115
|
+
* both backends are enabled, else whichever single one is. */
|
|
116
|
+
mode?: "fts" | "vector" | "hybrid";
|
|
117
|
+
/** Max rows to return (1–100, default 20). */
|
|
118
|
+
limit?: number;
|
|
119
|
+
/** Collapse `i18n_text` fields to one locale, or `"*"` for the full map. */
|
|
120
|
+
locale?: string;
|
|
121
|
+
}
|
|
122
|
+
/** Response from `from(slug).search(...)` — rows ordered best-first. */
|
|
123
|
+
interface SearchResponse<T> {
|
|
124
|
+
data: T[];
|
|
125
|
+
/** The mode that actually ran (resolved from the request + collection caps). */
|
|
126
|
+
mode: "fts" | "vector" | "hybrid";
|
|
127
|
+
limit: number;
|
|
128
|
+
}
|
|
129
|
+
/** Summary from `from(slug).importItems(...)` — per-row outcome of a bulk
|
|
130
|
+
* import. `errors` is capped to the first 50 failures server-side. */
|
|
131
|
+
interface ImportSummary {
|
|
132
|
+
inserted: number;
|
|
133
|
+
failed: number;
|
|
134
|
+
total: number;
|
|
135
|
+
errors: {
|
|
136
|
+
row: number;
|
|
137
|
+
error: string;
|
|
138
|
+
}[];
|
|
139
|
+
}
|
|
140
|
+
interface ItemEvent<T = Record<string, unknown>> {
|
|
141
|
+
event: "created" | "updated" | "deleted";
|
|
142
|
+
data: T;
|
|
143
|
+
}
|
|
144
|
+
type BatchOperation<T = Record<string, unknown>> = {
|
|
145
|
+
op: "create";
|
|
146
|
+
data: Partial<T>;
|
|
147
|
+
} | {
|
|
148
|
+
op: "update";
|
|
149
|
+
id: string;
|
|
150
|
+
data: Partial<T>;
|
|
151
|
+
} | {
|
|
152
|
+
op: "delete";
|
|
153
|
+
id: string;
|
|
154
|
+
};
|
|
155
|
+
interface BatchRowResult<T = Record<string, unknown>> {
|
|
156
|
+
index: number;
|
|
157
|
+
op: "create" | "update" | "delete";
|
|
158
|
+
ok: boolean;
|
|
159
|
+
id?: string;
|
|
160
|
+
data?: T;
|
|
161
|
+
error?: {
|
|
162
|
+
code: string;
|
|
163
|
+
message: string;
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
interface BatchResponse<T = Record<string, unknown>> {
|
|
167
|
+
data: {
|
|
168
|
+
atomic: boolean;
|
|
169
|
+
total: number;
|
|
170
|
+
succeeded: number;
|
|
171
|
+
failed: number;
|
|
172
|
+
results: BatchRowResult<T>[];
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
interface DeviceToken {
|
|
176
|
+
id: string;
|
|
177
|
+
platform: "fcm" | "apns" | "web-push";
|
|
178
|
+
token: string;
|
|
179
|
+
deviceName: string | null;
|
|
180
|
+
isActive: boolean;
|
|
181
|
+
createdAt: string | number;
|
|
182
|
+
lastSeenAt: string | number | null;
|
|
183
|
+
}
|
|
184
|
+
interface PhoneNumber {
|
|
185
|
+
id: string;
|
|
186
|
+
phoneNumber: string;
|
|
187
|
+
isActive: boolean;
|
|
188
|
+
createdAt: string | number;
|
|
189
|
+
lastSeenAt: string | number | null;
|
|
190
|
+
}
|
|
191
|
+
type JobStatus = "pending" | "active" | "succeeded" | "failed" | "dead_letter" | "cancelled";
|
|
192
|
+
interface Job {
|
|
193
|
+
id: string;
|
|
194
|
+
tenantId: string | null;
|
|
195
|
+
queue: string;
|
|
196
|
+
type: string;
|
|
197
|
+
payload: Record<string, unknown>;
|
|
198
|
+
status: JobStatus;
|
|
199
|
+
priority: number;
|
|
200
|
+
runAt: string | number;
|
|
201
|
+
attempts: number;
|
|
202
|
+
maxAttempts: number;
|
|
203
|
+
lastError: string | null;
|
|
204
|
+
result: unknown;
|
|
205
|
+
createdAt: string | number;
|
|
206
|
+
completedAt: string | number | null;
|
|
207
|
+
}
|
|
208
|
+
type UploadStatus = "pending" | "completed" | "aborted";
|
|
209
|
+
/** A resumable (TUS) upload session, as returned by the management API. */
|
|
210
|
+
interface Upload {
|
|
211
|
+
id: string;
|
|
212
|
+
key: string;
|
|
213
|
+
size: number;
|
|
214
|
+
offset: number;
|
|
215
|
+
status: UploadStatus;
|
|
216
|
+
contentType: string | null;
|
|
217
|
+
folderId: string | null;
|
|
218
|
+
parts: number;
|
|
219
|
+
createdAt: string | number;
|
|
220
|
+
updatedAt: string | number;
|
|
221
|
+
expiresAt: string | number;
|
|
222
|
+
}
|
|
223
|
+
/** Result of a resumable upload — the final key and the TUS session location. */
|
|
224
|
+
interface ResumableUploadResult {
|
|
225
|
+
key: string;
|
|
226
|
+
location: string;
|
|
227
|
+
}
|
|
228
|
+
/** One evaluated feature flag for the calling identity. */
|
|
229
|
+
interface FlagState {
|
|
230
|
+
enabled: boolean;
|
|
231
|
+
value: unknown;
|
|
232
|
+
}
|
|
233
|
+
interface ApiError {
|
|
234
|
+
code: string;
|
|
235
|
+
message: string;
|
|
236
|
+
details?: unknown;
|
|
237
|
+
}
|
|
238
|
+
declare class BacklexError extends Error {
|
|
239
|
+
readonly code: string;
|
|
240
|
+
readonly status: number;
|
|
241
|
+
readonly details?: unknown;
|
|
242
|
+
constructor(status: number, body: {
|
|
243
|
+
error?: ApiError;
|
|
244
|
+
} | undefined);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export { type AggregateQuery as A, BacklexError as B, type Condition as C, type DeviceToken as D, type FlagState as F, type ImportSummary as I, type Job as J, type ListQuery as L, type PhoneNumber as P, type RelativeNow as R, type SearchQuery as S, type Upload as U, type AggregateRow as a, type ApiError as b, type BatchOperation as c, type BatchResponse as d, type BatchRowResult as e, type DurationParts as f, type ItemEvent as g, type ItemQuery as h, type ItemResponse as i, type JobStatus as j, type ListResponse as k, type ResumableUploadResult as l, type SearchResponse as m, type UploadStatus as n };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { A as AggregateQuery, a as AggregateRow, b as ApiError, B as BacklexError, c as BatchOperation, d as BatchResponse, e as BatchRowResult, D as DeviceToken, F as FlagState, I as ImportSummary, g as ItemEvent, h as ItemQuery, i as ItemResponse, J as Job, j as JobStatus, L as ListQuery, k as ListResponse, P as PhoneNumber, l as ResumableUploadResult, S as SearchQuery, m as SearchResponse, U as Upload, n as UploadStatus } from './types-CbcbXGiA.js';
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BacklexError } from './chunk-UIUS57OR.js';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
interface VerifyWebhookOptions {
|
|
2
|
+
/** The hook's signing secret (the `secret` you configured on the webhook). */
|
|
3
|
+
secret: string;
|
|
4
|
+
/** The raw request body, exactly as received — do NOT re-stringify a parsed
|
|
5
|
+
* object, or the bytes (and therefore the HMAC) won't match. */
|
|
6
|
+
body: string;
|
|
7
|
+
/** The signature header value to check. Pass `X-Backlex-Signature-V2`
|
|
8
|
+
* together with `timestamp` for replay protection, or the legacy
|
|
9
|
+
* `X-Backlex-Signature` on its own. */
|
|
10
|
+
signature: string;
|
|
11
|
+
/** The `X-Backlex-Timestamp` header. When present, the replay-safe V2 scheme
|
|
12
|
+
* is verified and the delivery is rejected if the timestamp is too old. */
|
|
13
|
+
timestamp?: string | number;
|
|
14
|
+
/** Allowed clock skew for the timestamp, in seconds (default 300). `0`
|
|
15
|
+
* disables the freshness check. Ignored when no `timestamp` is supplied. */
|
|
16
|
+
toleranceSec?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Verify a backlex webhook delivery's signature.
|
|
20
|
+
*
|
|
21
|
+
* Replay-safe path (recommended) — pass the `X-Backlex-Signature-V2` header as
|
|
22
|
+
* `signature` and the `X-Backlex-Timestamp` header as `timestamp`:
|
|
23
|
+
*
|
|
24
|
+
* ```ts
|
|
25
|
+
* const ok = await verifyWebhook({
|
|
26
|
+
* secret,
|
|
27
|
+
* body: await req.text(),
|
|
28
|
+
* signature: req.headers.get("x-backlex-signature-v2")!,
|
|
29
|
+
* timestamp: req.headers.get("x-backlex-timestamp")!,
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Legacy path — pass only the `X-Backlex-Signature` header (no replay window).
|
|
34
|
+
* Returns `false` (never throws) on any missing input, stale timestamp, or
|
|
35
|
+
* mismatch.
|
|
36
|
+
*/
|
|
37
|
+
declare const verifyWebhook: (opts: VerifyWebhookOptions) => Promise<boolean>;
|
|
38
|
+
|
|
39
|
+
export { type VerifyWebhookOptions, verifyWebhook };
|
package/dist/webhook.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { verifyWebhook } from './chunk-U2MHWV2E.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "backlex",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Typed TypeScript client for the backlex API — auth, collection CRUD, query builder, realtime, storage, jobs, flags, and offline sync. Zero dependencies. On npm as compiled ESM + types; on JSR (@backlex/backlex) as TypeScript source.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"homepage": "https://backlex.com",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/backlex/backlex.git",
|
|
11
|
+
"directory": "packages/client"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/backlex/backlex/issues",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"backlex",
|
|
16
|
+
"backend-as-a-service",
|
|
17
|
+
"baas",
|
|
18
|
+
"sdk",
|
|
19
|
+
"client",
|
|
20
|
+
"typescript",
|
|
21
|
+
"rest",
|
|
22
|
+
"realtime"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./types": {
|
|
33
|
+
"types": "./dist/types.d.ts",
|
|
34
|
+
"default": "./dist/types.js"
|
|
35
|
+
},
|
|
36
|
+
"./webhook": {
|
|
37
|
+
"types": "./dist/webhook.d.ts",
|
|
38
|
+
"default": "./dist/webhook.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md",
|
|
44
|
+
"LICENSE"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"provenance": true
|
|
49
|
+
}
|
|
50
|
+
}
|