@ekodb/ekodb-client 0.17.0 → 0.18.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/functions.d.ts +275 -0
- package/dist/functions.js +195 -0
- package/dist/functions.test.js +215 -0
- package/package.json +1 -1
- package/src/functions.test.ts +282 -0
- package/src/functions.ts +501 -0
package/src/functions.ts
CHANGED
|
@@ -14,6 +14,19 @@ export interface UserFunction {
|
|
|
14
14
|
tags?: string[];
|
|
15
15
|
created_at?: string;
|
|
16
16
|
updated_at?: string;
|
|
17
|
+
/**
|
|
18
|
+
* REST method this function answers — `"GET"`, `"POST"`, etc.
|
|
19
|
+
* Pair with `http_path` to expose the function under the
|
|
20
|
+
* path-routed dispatcher at `/api/route/{path}`.
|
|
21
|
+
* Requires ekoDB >= 0.42.0.
|
|
22
|
+
*/
|
|
23
|
+
http_method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
24
|
+
/**
|
|
25
|
+
* REST path pattern (e.g. `"/users/:id"`). Path segments
|
|
26
|
+
* starting with `:` are extracted into the function's params
|
|
27
|
+
* map at call time. Requires ekoDB >= 0.42.0.
|
|
28
|
+
*/
|
|
29
|
+
http_path?: string;
|
|
17
30
|
}
|
|
18
31
|
|
|
19
32
|
export interface ParameterDefinition {
|
|
@@ -258,6 +271,186 @@ export type FunctionStageConfig =
|
|
|
258
271
|
encoding?: "hex" | "base64" | "base64url";
|
|
259
272
|
output_field: string;
|
|
260
273
|
}
|
|
274
|
+
| {
|
|
275
|
+
/**
|
|
276
|
+
* Sign a JWT and write the resulting token to every working
|
|
277
|
+
* record. Pair with `BcryptVerify` to issue a session token
|
|
278
|
+
* after login. Use `"{{env.JWT_SECRET}}"` for `secret` so the
|
|
279
|
+
* LLM never sees the operator-owned signing key. `iat` and
|
|
280
|
+
* `exp` are auto-stamped when `expires_in_secs` is set.
|
|
281
|
+
* Requires ekoDB >= 0.42.0.
|
|
282
|
+
*/
|
|
283
|
+
type: "JwtSign";
|
|
284
|
+
claims: Record<string, unknown>;
|
|
285
|
+
secret: string;
|
|
286
|
+
algorithm?: "HS256" | "HS384" | "HS512";
|
|
287
|
+
expires_in_secs?: number;
|
|
288
|
+
output_field: string;
|
|
289
|
+
}
|
|
290
|
+
| {
|
|
291
|
+
/**
|
|
292
|
+
* Verify a JWT held in `token_field` on the first working
|
|
293
|
+
* record. On success, writes the decoded claims object into
|
|
294
|
+
* `output_field`. On failure, writes `null` so callers can
|
|
295
|
+
* branch with `If { FieldEquals { value: null } }` to reject.
|
|
296
|
+
* Requires ekoDB >= 0.42.0.
|
|
297
|
+
*/
|
|
298
|
+
type: "JwtVerify";
|
|
299
|
+
token_field: string;
|
|
300
|
+
secret: string;
|
|
301
|
+
algorithm?: "HS256" | "HS384" | "HS512";
|
|
302
|
+
output_field: string;
|
|
303
|
+
}
|
|
304
|
+
| {
|
|
305
|
+
/**
|
|
306
|
+
* Send a transactional email through a provider's REST API.
|
|
307
|
+
* Today only `provider = "sendgrid"` is supported. Pull the
|
|
308
|
+
* API key from `"{{env.SENDGRID_API_KEY}}"` so the LLM never
|
|
309
|
+
* sees the operator-owned secret. Result envelope
|
|
310
|
+
* `{provider_status, provider_message, provider}` is written
|
|
311
|
+
* to `output_field` (defaults to `"email_send"`).
|
|
312
|
+
* Requires ekoDB >= 0.42.0.
|
|
313
|
+
*/
|
|
314
|
+
type: "EmailSend";
|
|
315
|
+
to: string;
|
|
316
|
+
subject: string;
|
|
317
|
+
body: string;
|
|
318
|
+
from: string;
|
|
319
|
+
reply_to?: string;
|
|
320
|
+
api_key: string;
|
|
321
|
+
provider?: "sendgrid";
|
|
322
|
+
html?: boolean;
|
|
323
|
+
output_field?: string;
|
|
324
|
+
}
|
|
325
|
+
| {
|
|
326
|
+
/** HMAC-SHA256/384/512 sign. Requires ekoDB >= 0.42.0. */
|
|
327
|
+
type: "HmacSign";
|
|
328
|
+
input: string;
|
|
329
|
+
secret: string;
|
|
330
|
+
algorithm?: "sha256" | "sha384" | "sha512";
|
|
331
|
+
output_field: string;
|
|
332
|
+
encoding?: "hex" | "base64";
|
|
333
|
+
}
|
|
334
|
+
| {
|
|
335
|
+
/** HMAC verify (constant-time). Writes a boolean. */
|
|
336
|
+
type: "HmacVerify";
|
|
337
|
+
input: string;
|
|
338
|
+
provided_mac: string;
|
|
339
|
+
secret: string;
|
|
340
|
+
algorithm?: "sha256" | "sha384" | "sha512";
|
|
341
|
+
encoding?: "hex" | "base64";
|
|
342
|
+
output_field: string;
|
|
343
|
+
}
|
|
344
|
+
| {
|
|
345
|
+
/** AES-256-GCM authenticated encryption. */
|
|
346
|
+
type: "AesEncrypt";
|
|
347
|
+
plaintext: string;
|
|
348
|
+
key: string;
|
|
349
|
+
key_encoding?: "hex" | "base64" | "base64url";
|
|
350
|
+
output_field: string;
|
|
351
|
+
}
|
|
352
|
+
| {
|
|
353
|
+
/** AES-256-GCM decrypt. Reads `{ciphertext, nonce}` envelope from `ciphertext_field`. */
|
|
354
|
+
type: "AesDecrypt";
|
|
355
|
+
ciphertext_field: string;
|
|
356
|
+
key: string;
|
|
357
|
+
key_encoding?: "hex" | "base64" | "base64url";
|
|
358
|
+
output_field: string;
|
|
359
|
+
}
|
|
360
|
+
| {
|
|
361
|
+
/** Generate a v4 UUID into `output_field`. */
|
|
362
|
+
type: "UuidGenerate";
|
|
363
|
+
output_field: string;
|
|
364
|
+
}
|
|
365
|
+
| {
|
|
366
|
+
/** TOTP code generation (RFC 6238). */
|
|
367
|
+
type: "TotpGenerate";
|
|
368
|
+
secret: string;
|
|
369
|
+
digits?: 6 | 8;
|
|
370
|
+
period?: number;
|
|
371
|
+
algorithm?: "sha1" | "sha256" | "sha512";
|
|
372
|
+
output_field: string;
|
|
373
|
+
}
|
|
374
|
+
| {
|
|
375
|
+
/** TOTP verify; tolerates `skew` time-steps either side. */
|
|
376
|
+
type: "TotpVerify";
|
|
377
|
+
code: string;
|
|
378
|
+
secret: string;
|
|
379
|
+
digits?: 6 | 8;
|
|
380
|
+
period?: number;
|
|
381
|
+
algorithm?: "sha1" | "sha256" | "sha512";
|
|
382
|
+
skew?: number;
|
|
383
|
+
output_field: string;
|
|
384
|
+
}
|
|
385
|
+
| {
|
|
386
|
+
/** Base64 encode (`url_safe = true` for URL-safe / no-pad). */
|
|
387
|
+
type: "Base64Encode";
|
|
388
|
+
input: string;
|
|
389
|
+
url_safe?: boolean;
|
|
390
|
+
output_field: string;
|
|
391
|
+
}
|
|
392
|
+
| {
|
|
393
|
+
/** Base64 decode → UTF-8 string. Fail-closed. */
|
|
394
|
+
type: "Base64Decode";
|
|
395
|
+
input: string;
|
|
396
|
+
url_safe?: boolean;
|
|
397
|
+
output_field: string;
|
|
398
|
+
}
|
|
399
|
+
| {
|
|
400
|
+
/** Hex encode (lowercase). */
|
|
401
|
+
type: "HexEncode";
|
|
402
|
+
input: string;
|
|
403
|
+
output_field: string;
|
|
404
|
+
}
|
|
405
|
+
| {
|
|
406
|
+
/** Hex decode → UTF-8 string. Fail-closed. */
|
|
407
|
+
type: "HexDecode";
|
|
408
|
+
input: string;
|
|
409
|
+
output_field: string;
|
|
410
|
+
}
|
|
411
|
+
| {
|
|
412
|
+
/** URL-friendly slug. */
|
|
413
|
+
type: "Slugify";
|
|
414
|
+
input: string;
|
|
415
|
+
output_field: string;
|
|
416
|
+
}
|
|
417
|
+
| {
|
|
418
|
+
/**
|
|
419
|
+
* Idempotency-key claim (KV SETNX with TTL). Writes
|
|
420
|
+
* `{claimed: true, key}` on first call, `{claimed: false, key,
|
|
421
|
+
* response}` on replay. Requires ekoDB >= 0.42.0.
|
|
422
|
+
*/
|
|
423
|
+
type: "IdempotencyClaim";
|
|
424
|
+
key: string;
|
|
425
|
+
ttl_secs: number;
|
|
426
|
+
output_field: string;
|
|
427
|
+
}
|
|
428
|
+
| {
|
|
429
|
+
/**
|
|
430
|
+
* Fixed-window rate-limit gate. `on_exceed` either errors
|
|
431
|
+
* (`"fail"`, default) or writes `allowed: false` (`"skip"`).
|
|
432
|
+
*/
|
|
433
|
+
type: "RateLimit";
|
|
434
|
+
key: string;
|
|
435
|
+
limit: number;
|
|
436
|
+
window_secs: number;
|
|
437
|
+
on_exceed?: "fail" | "skip";
|
|
438
|
+
output_field: string;
|
|
439
|
+
}
|
|
440
|
+
| {
|
|
441
|
+
/** Distributed-lock acquire (token-fenced). */
|
|
442
|
+
type: "LockAcquire";
|
|
443
|
+
key: string;
|
|
444
|
+
ttl_secs: number;
|
|
445
|
+
output_field: string;
|
|
446
|
+
}
|
|
447
|
+
| {
|
|
448
|
+
/** Distributed-lock release; token-fenced (no foreign release). */
|
|
449
|
+
type: "LockRelease";
|
|
450
|
+
key: string;
|
|
451
|
+
token: string;
|
|
452
|
+
output_field: string;
|
|
453
|
+
}
|
|
261
454
|
| {
|
|
262
455
|
/**
|
|
263
456
|
* Try/Catch error handling for graceful failure recovery.
|
|
@@ -867,6 +1060,93 @@ export const Stage = {
|
|
|
867
1060
|
output_field,
|
|
868
1061
|
}),
|
|
869
1062
|
|
|
1063
|
+
/**
|
|
1064
|
+
* Sign a JWT and write the resulting token to every working
|
|
1065
|
+
* record. Pair with `Stage.bcryptVerify` to issue a session
|
|
1066
|
+
* token after login. Use `"{{env.JWT_SECRET}}"` for `secret` so
|
|
1067
|
+
* the LLM never sees the operator-owned signing key. `iat` and
|
|
1068
|
+
* `exp` are auto-stamped when `expires_in_secs` is set.
|
|
1069
|
+
* Requires ekoDB >= 0.42.0.
|
|
1070
|
+
*
|
|
1071
|
+
* @param claims - JWT payload claims.
|
|
1072
|
+
* @param secret - Signing secret (typically `"{{env.JWT_SECRET}}"`).
|
|
1073
|
+
* @param output_field - Field name to write the signed JWT into.
|
|
1074
|
+
* @param expires_in_secs - Lifetime in seconds (auto-stamps `iat` + `exp`).
|
|
1075
|
+
* @param algorithm - `"HS256"` (default) | `"HS384"` | `"HS512"`.
|
|
1076
|
+
*/
|
|
1077
|
+
jwtSign: (
|
|
1078
|
+
claims: Record<string, unknown>,
|
|
1079
|
+
secret: string,
|
|
1080
|
+
output_field: string,
|
|
1081
|
+
expires_in_secs?: number,
|
|
1082
|
+
algorithm?: "HS256" | "HS384" | "HS512",
|
|
1083
|
+
): FunctionStageConfig => ({
|
|
1084
|
+
type: "JwtSign",
|
|
1085
|
+
claims,
|
|
1086
|
+
secret,
|
|
1087
|
+
algorithm,
|
|
1088
|
+
expires_in_secs,
|
|
1089
|
+
output_field,
|
|
1090
|
+
}),
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Verify a JWT held in `token_field` on the first working record.
|
|
1094
|
+
* On success writes the decoded claims object into `output_field`;
|
|
1095
|
+
* on failure writes `null`. Branch with `Stage.if` matching
|
|
1096
|
+
* `output_field == null` to reject. Requires ekoDB >= 0.42.0.
|
|
1097
|
+
*
|
|
1098
|
+
* @param token_field - Field on the working record holding the JWT.
|
|
1099
|
+
* @param secret - Verification secret (must match the signing secret).
|
|
1100
|
+
* @param output_field - Field name to write decoded claims into.
|
|
1101
|
+
* @param algorithm - Expected algorithm (default `"HS256"`).
|
|
1102
|
+
*/
|
|
1103
|
+
jwtVerify: (
|
|
1104
|
+
token_field: string,
|
|
1105
|
+
secret: string,
|
|
1106
|
+
output_field: string,
|
|
1107
|
+
algorithm?: "HS256" | "HS384" | "HS512",
|
|
1108
|
+
): FunctionStageConfig => ({
|
|
1109
|
+
type: "JwtVerify",
|
|
1110
|
+
token_field,
|
|
1111
|
+
secret,
|
|
1112
|
+
algorithm,
|
|
1113
|
+
output_field,
|
|
1114
|
+
}),
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* Send a transactional email. Today only the `"sendgrid"`
|
|
1118
|
+
* provider is supported. Use `"{{env.SENDGRID_API_KEY}}"` for
|
|
1119
|
+
* `api_key` so the LLM never sees the operator-owned secret.
|
|
1120
|
+
* Set `html: true` to send `text/html`. The result envelope
|
|
1121
|
+
* (`{provider_status, provider_message, provider}`) is written
|
|
1122
|
+
* to `output_field` (default `"email_send"`).
|
|
1123
|
+
* Requires ekoDB >= 0.42.0.
|
|
1124
|
+
*/
|
|
1125
|
+
emailSend: (
|
|
1126
|
+
to: string,
|
|
1127
|
+
subject: string,
|
|
1128
|
+
body: string,
|
|
1129
|
+
from: string,
|
|
1130
|
+
api_key: string,
|
|
1131
|
+
options?: {
|
|
1132
|
+
reply_to?: string;
|
|
1133
|
+
provider?: "sendgrid";
|
|
1134
|
+
html?: boolean;
|
|
1135
|
+
output_field?: string;
|
|
1136
|
+
},
|
|
1137
|
+
): FunctionStageConfig => ({
|
|
1138
|
+
type: "EmailSend",
|
|
1139
|
+
to,
|
|
1140
|
+
subject,
|
|
1141
|
+
body,
|
|
1142
|
+
from,
|
|
1143
|
+
reply_to: options?.reply_to,
|
|
1144
|
+
api_key,
|
|
1145
|
+
provider: options?.provider,
|
|
1146
|
+
html: options?.html,
|
|
1147
|
+
output_field: options?.output_field,
|
|
1148
|
+
}),
|
|
1149
|
+
|
|
870
1150
|
/**
|
|
871
1151
|
* Try/Catch error handling for graceful failure recovery.
|
|
872
1152
|
* Executes tryFunctions, and if any fail, executes catchFunctions.
|
|
@@ -945,4 +1225,225 @@ export const Stage = {
|
|
|
945
1225
|
data_field: dataField,
|
|
946
1226
|
on_error: onError,
|
|
947
1227
|
}),
|
|
1228
|
+
|
|
1229
|
+
/**
|
|
1230
|
+
* HMAC-SHA256/384/512 sign. Use for outbound webhook signing or
|
|
1231
|
+
* pre-signed URL generation. Requires ekoDB >= 0.42.0.
|
|
1232
|
+
*/
|
|
1233
|
+
hmacSign: (
|
|
1234
|
+
input: string,
|
|
1235
|
+
secret: string,
|
|
1236
|
+
output_field: string,
|
|
1237
|
+
options?: {
|
|
1238
|
+
algorithm?: "sha256" | "sha384" | "sha512";
|
|
1239
|
+
encoding?: "hex" | "base64";
|
|
1240
|
+
},
|
|
1241
|
+
): FunctionStageConfig => ({
|
|
1242
|
+
type: "HmacSign",
|
|
1243
|
+
input,
|
|
1244
|
+
secret,
|
|
1245
|
+
algorithm: options?.algorithm,
|
|
1246
|
+
output_field,
|
|
1247
|
+
encoding: options?.encoding,
|
|
1248
|
+
}),
|
|
1249
|
+
|
|
1250
|
+
/** HMAC verify (constant-time). Writes a boolean. */
|
|
1251
|
+
hmacVerify: (
|
|
1252
|
+
input: string,
|
|
1253
|
+
provided_mac: string,
|
|
1254
|
+
secret: string,
|
|
1255
|
+
output_field: string,
|
|
1256
|
+
options?: {
|
|
1257
|
+
algorithm?: "sha256" | "sha384" | "sha512";
|
|
1258
|
+
encoding?: "hex" | "base64";
|
|
1259
|
+
},
|
|
1260
|
+
): FunctionStageConfig => ({
|
|
1261
|
+
type: "HmacVerify",
|
|
1262
|
+
input,
|
|
1263
|
+
provided_mac,
|
|
1264
|
+
secret,
|
|
1265
|
+
algorithm: options?.algorithm,
|
|
1266
|
+
encoding: options?.encoding,
|
|
1267
|
+
output_field,
|
|
1268
|
+
}),
|
|
1269
|
+
|
|
1270
|
+
/** AES-256-GCM encrypt; writes `{ciphertext, nonce}` envelope. */
|
|
1271
|
+
aesEncrypt: (
|
|
1272
|
+
plaintext: string,
|
|
1273
|
+
key: string,
|
|
1274
|
+
output_field: string,
|
|
1275
|
+
key_encoding?: "hex" | "base64" | "base64url",
|
|
1276
|
+
): FunctionStageConfig => ({
|
|
1277
|
+
type: "AesEncrypt",
|
|
1278
|
+
plaintext,
|
|
1279
|
+
key,
|
|
1280
|
+
key_encoding,
|
|
1281
|
+
output_field,
|
|
1282
|
+
}),
|
|
1283
|
+
|
|
1284
|
+
/** AES-256-GCM decrypt; reads envelope from `ciphertext_field`. */
|
|
1285
|
+
aesDecrypt: (
|
|
1286
|
+
ciphertext_field: string,
|
|
1287
|
+
key: string,
|
|
1288
|
+
output_field: string,
|
|
1289
|
+
key_encoding?: "hex" | "base64" | "base64url",
|
|
1290
|
+
): FunctionStageConfig => ({
|
|
1291
|
+
type: "AesDecrypt",
|
|
1292
|
+
ciphertext_field,
|
|
1293
|
+
key,
|
|
1294
|
+
key_encoding,
|
|
1295
|
+
output_field,
|
|
1296
|
+
}),
|
|
1297
|
+
|
|
1298
|
+
/** Generate a v4 UUID into `output_field`. */
|
|
1299
|
+
uuidGenerate: (output_field: string): FunctionStageConfig => ({
|
|
1300
|
+
type: "UuidGenerate",
|
|
1301
|
+
output_field,
|
|
1302
|
+
}),
|
|
1303
|
+
|
|
1304
|
+
/** TOTP code generation (RFC 6238). */
|
|
1305
|
+
totpGenerate: (
|
|
1306
|
+
secret: string,
|
|
1307
|
+
output_field: string,
|
|
1308
|
+
options?: {
|
|
1309
|
+
digits?: 6 | 8;
|
|
1310
|
+
period?: number;
|
|
1311
|
+
algorithm?: "sha1" | "sha256" | "sha512";
|
|
1312
|
+
},
|
|
1313
|
+
): FunctionStageConfig => ({
|
|
1314
|
+
type: "TotpGenerate",
|
|
1315
|
+
secret,
|
|
1316
|
+
digits: options?.digits,
|
|
1317
|
+
period: options?.period,
|
|
1318
|
+
algorithm: options?.algorithm,
|
|
1319
|
+
output_field,
|
|
1320
|
+
}),
|
|
1321
|
+
|
|
1322
|
+
/** TOTP verify; tolerates `skew` time-steps either side (default 1). */
|
|
1323
|
+
totpVerify: (
|
|
1324
|
+
code: string,
|
|
1325
|
+
secret: string,
|
|
1326
|
+
output_field: string,
|
|
1327
|
+
options?: {
|
|
1328
|
+
digits?: 6 | 8;
|
|
1329
|
+
period?: number;
|
|
1330
|
+
algorithm?: "sha1" | "sha256" | "sha512";
|
|
1331
|
+
skew?: number;
|
|
1332
|
+
},
|
|
1333
|
+
): FunctionStageConfig => ({
|
|
1334
|
+
type: "TotpVerify",
|
|
1335
|
+
code,
|
|
1336
|
+
secret,
|
|
1337
|
+
digits: options?.digits,
|
|
1338
|
+
period: options?.period,
|
|
1339
|
+
algorithm: options?.algorithm,
|
|
1340
|
+
skew: options?.skew,
|
|
1341
|
+
output_field,
|
|
1342
|
+
}),
|
|
1343
|
+
|
|
1344
|
+
/** Base64 encode (`url_safe = true` for URL-safe / no-pad). */
|
|
1345
|
+
base64Encode: (
|
|
1346
|
+
input: string,
|
|
1347
|
+
output_field: string,
|
|
1348
|
+
url_safe?: boolean,
|
|
1349
|
+
): FunctionStageConfig => ({
|
|
1350
|
+
type: "Base64Encode",
|
|
1351
|
+
input,
|
|
1352
|
+
url_safe,
|
|
1353
|
+
output_field,
|
|
1354
|
+
}),
|
|
1355
|
+
|
|
1356
|
+
/** Base64 decode → UTF-8 string. Fail-closed. */
|
|
1357
|
+
base64Decode: (
|
|
1358
|
+
input: string,
|
|
1359
|
+
output_field: string,
|
|
1360
|
+
url_safe?: boolean,
|
|
1361
|
+
): FunctionStageConfig => ({
|
|
1362
|
+
type: "Base64Decode",
|
|
1363
|
+
input,
|
|
1364
|
+
url_safe,
|
|
1365
|
+
output_field,
|
|
1366
|
+
}),
|
|
1367
|
+
|
|
1368
|
+
/** Hex encode (lowercase). */
|
|
1369
|
+
hexEncode: (input: string, output_field: string): FunctionStageConfig => ({
|
|
1370
|
+
type: "HexEncode",
|
|
1371
|
+
input,
|
|
1372
|
+
output_field,
|
|
1373
|
+
}),
|
|
1374
|
+
|
|
1375
|
+
/** Hex decode → UTF-8 string. Fail-closed. */
|
|
1376
|
+
hexDecode: (input: string, output_field: string): FunctionStageConfig => ({
|
|
1377
|
+
type: "HexDecode",
|
|
1378
|
+
input,
|
|
1379
|
+
output_field,
|
|
1380
|
+
}),
|
|
1381
|
+
|
|
1382
|
+
/** URL-friendly slug. */
|
|
1383
|
+
slugify: (input: string, output_field: string): FunctionStageConfig => ({
|
|
1384
|
+
type: "Slugify",
|
|
1385
|
+
input,
|
|
1386
|
+
output_field,
|
|
1387
|
+
}),
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Idempotency-key claim (KV SETNX with TTL). Pass an idempotency
|
|
1391
|
+
* key (typically `"{{idempotency_key}}"`) and a TTL; first call
|
|
1392
|
+
* writes `{claimed: true, key}`, subsequent calls within the TTL
|
|
1393
|
+
* write `{claimed: false, key, response}` so the caller can
|
|
1394
|
+
* short-circuit. Requires ekoDB >= 0.42.0.
|
|
1395
|
+
*/
|
|
1396
|
+
idempotencyClaim: (
|
|
1397
|
+
key: string,
|
|
1398
|
+
ttl_secs: number,
|
|
1399
|
+
output_field: string,
|
|
1400
|
+
): FunctionStageConfig => ({
|
|
1401
|
+
type: "IdempotencyClaim",
|
|
1402
|
+
key,
|
|
1403
|
+
ttl_secs,
|
|
1404
|
+
output_field,
|
|
1405
|
+
}),
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* Fixed-window rate-limit gate. `on_exceed` either errors
|
|
1409
|
+
* (`"fail"`, default) or writes `allowed: false` (`"skip"`).
|
|
1410
|
+
*/
|
|
1411
|
+
rateLimit: (
|
|
1412
|
+
key: string,
|
|
1413
|
+
limit: number,
|
|
1414
|
+
window_secs: number,
|
|
1415
|
+
output_field: string,
|
|
1416
|
+
on_exceed?: "fail" | "skip",
|
|
1417
|
+
): FunctionStageConfig => ({
|
|
1418
|
+
type: "RateLimit",
|
|
1419
|
+
key,
|
|
1420
|
+
limit,
|
|
1421
|
+
window_secs,
|
|
1422
|
+
on_exceed,
|
|
1423
|
+
output_field,
|
|
1424
|
+
}),
|
|
1425
|
+
|
|
1426
|
+
/** Distributed-lock acquire (token-fenced). */
|
|
1427
|
+
lockAcquire: (
|
|
1428
|
+
key: string,
|
|
1429
|
+
ttl_secs: number,
|
|
1430
|
+
output_field: string,
|
|
1431
|
+
): FunctionStageConfig => ({
|
|
1432
|
+
type: "LockAcquire",
|
|
1433
|
+
key,
|
|
1434
|
+
ttl_secs,
|
|
1435
|
+
output_field,
|
|
1436
|
+
}),
|
|
1437
|
+
|
|
1438
|
+
/** Distributed-lock release; only releases on token match. */
|
|
1439
|
+
lockRelease: (
|
|
1440
|
+
key: string,
|
|
1441
|
+
token: string,
|
|
1442
|
+
output_field: string,
|
|
1443
|
+
): FunctionStageConfig => ({
|
|
1444
|
+
type: "LockRelease",
|
|
1445
|
+
key,
|
|
1446
|
+
token,
|
|
1447
|
+
output_field,
|
|
1448
|
+
}),
|
|
948
1449
|
};
|