apiblaze 0.11.0 → 0.11.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/index.js +133 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -305,7 +305,7 @@ var import_commander = require("commander");
|
|
|
305
305
|
var import_chalk32 = __toESM(require("chalk"));
|
|
306
306
|
|
|
307
307
|
// package.json
|
|
308
|
-
var version = "0.11.
|
|
308
|
+
var version = "0.11.1";
|
|
309
309
|
|
|
310
310
|
// src/index.ts
|
|
311
311
|
init_types();
|
|
@@ -3418,6 +3418,102 @@ async function settingsGroup(proj2, cfg, group) {
|
|
|
3418
3418
|
cfg = await fetchConfigBlob(proj2);
|
|
3419
3419
|
}
|
|
3420
3420
|
}
|
|
3421
|
+
var FN_CHOICES = [
|
|
3422
|
+
{ name: "uppercase", value: "uppercase" },
|
|
3423
|
+
{ name: "lowercase", value: "lowercase" },
|
|
3424
|
+
{ name: "trim", value: "trim" },
|
|
3425
|
+
{ name: "url_encode", value: "url_encode" },
|
|
3426
|
+
{ name: "url_decode", value: "url_decode" },
|
|
3427
|
+
{ name: "base64url_encode", value: "base64url_encode" },
|
|
3428
|
+
{ name: "base64url_decode", value: "base64url_decode" },
|
|
3429
|
+
{ name: "hash \u2014 sha256/md5 digest", value: "hash" },
|
|
3430
|
+
{ name: "regex_extract \u2014 pull out a capture group", value: "regex_extract" },
|
|
3431
|
+
{ name: "concat \u2014 prepend/append text", value: "concat" }
|
|
3432
|
+
];
|
|
3433
|
+
async function buildFns(which) {
|
|
3434
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
3435
|
+
const fns = [];
|
|
3436
|
+
for (; ; ) {
|
|
3437
|
+
const { fn } = await inquirer2.prompt([{
|
|
3438
|
+
type: "list",
|
|
3439
|
+
name: "fn",
|
|
3440
|
+
message: fns.length ? `${which}: ${fns.map((f) => f.fn).join(" \u2192 ")} \u2014 add another?` : `${which} \u2014 add a function?`,
|
|
3441
|
+
choices: [{ name: fns.length ? "\u2713 Done" : "No functions", value: null }, ...FN_CHOICES]
|
|
3442
|
+
}]);
|
|
3443
|
+
if (!fn) return fns;
|
|
3444
|
+
if (fn === "hash") {
|
|
3445
|
+
const { algorithm } = await inquirer2.prompt([{ type: "list", name: "algorithm", message: "Algorithm:", choices: ["sha256", "md5"] }]);
|
|
3446
|
+
fns.push({ fn, algorithm });
|
|
3447
|
+
} else if (fn === "regex_extract") {
|
|
3448
|
+
const a = await inquirer2.prompt([
|
|
3449
|
+
{ type: "input", name: "pattern", message: "Regex pattern:", validate: (s) => {
|
|
3450
|
+
try {
|
|
3451
|
+
new RegExp(s);
|
|
3452
|
+
return true;
|
|
3453
|
+
} catch {
|
|
3454
|
+
return "invalid regex";
|
|
3455
|
+
}
|
|
3456
|
+
} },
|
|
3457
|
+
{ type: "input", name: "group", message: "Capture group (default 1):", default: "1" }
|
|
3458
|
+
]);
|
|
3459
|
+
fns.push({ fn, pattern: a.pattern, ...Number(a.group) !== 1 ? { group: Number(a.group) } : {} });
|
|
3460
|
+
} else if (fn === "concat") {
|
|
3461
|
+
const a = await inquirer2.prompt([
|
|
3462
|
+
{ type: "input", name: "before", message: "Text before (empty = none):" },
|
|
3463
|
+
{ type: "input", name: "after", message: "Text after (empty = none):" }
|
|
3464
|
+
]);
|
|
3465
|
+
fns.push({ fn, ...a.before ? { before: a.before } : {}, ...a.after ? { after: a.after } : {} });
|
|
3466
|
+
} else {
|
|
3467
|
+
fns.push({ fn });
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
async function buildCondition(phase) {
|
|
3472
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
3473
|
+
const { want } = await inquirer2.prompt([{
|
|
3474
|
+
type: "confirm",
|
|
3475
|
+
name: "want",
|
|
3476
|
+
default: false,
|
|
3477
|
+
message: "Only apply when a condition matches?"
|
|
3478
|
+
}]);
|
|
3479
|
+
if (!want) return void 0;
|
|
3480
|
+
const srcHint = phase === "response" ? "(header:x-foo, bodyvar:user.id, status:)" : "(header:x-foo, param:limit, bodyvar:user.id, jwt:sub)";
|
|
3481
|
+
const items = [];
|
|
3482
|
+
for (; ; ) {
|
|
3483
|
+
const a = await inquirer2.prompt([
|
|
3484
|
+
{ type: "input", name: "source", message: `Condition field ${import_chalk26.default.dim(srcHint)}:`, validate: (s) => !!s || "required" },
|
|
3485
|
+
{ type: "list", name: "operator", message: "Operator:", choices: [
|
|
3486
|
+
"eq",
|
|
3487
|
+
"neq",
|
|
3488
|
+
"contains",
|
|
3489
|
+
"starts_with",
|
|
3490
|
+
"ends_with",
|
|
3491
|
+
"exists",
|
|
3492
|
+
"not_exists",
|
|
3493
|
+
"regex"
|
|
3494
|
+
] }
|
|
3495
|
+
]);
|
|
3496
|
+
let value;
|
|
3497
|
+
if (a.operator !== "exists" && a.operator !== "not_exists") {
|
|
3498
|
+
const v = await inquirer2.prompt([{ type: "input", name: "value", message: a.operator === "regex" ? "Pattern:" : "Value:" }]);
|
|
3499
|
+
value = v.value;
|
|
3500
|
+
}
|
|
3501
|
+
items.push({ id: `c${items.length + 1}`, openParen: false, closeParen: false, source: a.source, operator: a.operator, ...value !== void 0 ? { value } : {} });
|
|
3502
|
+
const { more } = await inquirer2.prompt([{
|
|
3503
|
+
type: "list",
|
|
3504
|
+
name: "more",
|
|
3505
|
+
message: "Combine with another condition?",
|
|
3506
|
+
choices: [{ name: "\u2713 Done", value: null }, { name: "AND \u2026", value: "AND" }, { name: "OR \u2026", value: "OR" }]
|
|
3507
|
+
}]);
|
|
3508
|
+
if (!more) return items;
|
|
3509
|
+
items[items.length - 1].logicOp = more;
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
function showCondition(cond) {
|
|
3513
|
+
if (!Array.isArray(cond) || !cond.length) return "";
|
|
3514
|
+
const s = cond.map((c) => `${c.source} ${c.operator}${c.value !== void 0 ? ` "${c.value}"` : ""}${c.logicOp ? ` ${c.logicOp}` : ""}`).join(" ");
|
|
3515
|
+
return import_chalk26.default.dim(` when ${s}`);
|
|
3516
|
+
}
|
|
3421
3517
|
async function transformsMenu(proj2) {
|
|
3422
3518
|
const { default: inquirer2 } = await import("inquirer");
|
|
3423
3519
|
const base = `/projects/${proj2.projectId}/${proj2.apiVersion}/transforms`;
|
|
@@ -3428,8 +3524,9 @@ async function transformsMenu(proj2) {
|
|
|
3428
3524
|
if (!rules.length) console.log(import_chalk26.default.dim(" No transform rules yet."));
|
|
3429
3525
|
for (const r of rules) {
|
|
3430
3526
|
const a = r.action ?? {};
|
|
3431
|
-
const
|
|
3432
|
-
|
|
3527
|
+
const fns = [...a.source_fns ?? [], ...a.dest_fns ?? []].map((f) => f.fn);
|
|
3528
|
+
const what = a.type === "hardcode" ? `${a.destination} = "${a.value}"` : a.type === "remove" ? `remove ${a.field}` : `${a.source} \u2192 ${a.destination}${a.lookup ? " (mapped)" : ""}${fns.length ? import_chalk26.default.dim(` via ${fns.join("\u2192")}`) : ""}`;
|
|
3529
|
+
console.log(` ${r.enabled ? import_chalk26.default.green("\u25CF") : import_chalk26.default.dim("\u25CB")} ${import_chalk26.default.bold(r.name)} ${import_chalk26.default.dim(`[${r.phase ?? "request"}]`)} ${what}${showCondition(r.condition)}`);
|
|
3433
3530
|
}
|
|
3434
3531
|
const { act } = await inquirer2.prompt([{
|
|
3435
3532
|
type: "list",
|
|
@@ -3441,10 +3538,26 @@ async function transformsMenu(proj2) {
|
|
|
3441
3538
|
{ name: "Enable/disable a rule", value: "toggle" },
|
|
3442
3539
|
{ name: "Delete a rule", value: "delete" }
|
|
3443
3540
|
] : [],
|
|
3541
|
+
{ name: import_chalk26.default.dim("Add from raw JSON (grouped conditions, lookup tables, \u2026)"), value: "raw" },
|
|
3444
3542
|
{ name: "\u2190 Back", value: "back" }
|
|
3445
3543
|
]
|
|
3446
3544
|
}]);
|
|
3447
3545
|
if (act === "back") return;
|
|
3546
|
+
if (act === "raw") {
|
|
3547
|
+
const { raw } = await inquirer2.prompt([{
|
|
3548
|
+
type: "input",
|
|
3549
|
+
name: "raw",
|
|
3550
|
+
message: "Rule JSON ({name, phase, enabled, action, condition?}):"
|
|
3551
|
+
}]);
|
|
3552
|
+
const body = parseValue(raw);
|
|
3553
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
3554
|
+
console.log(import_chalk26.default.yellow(" Not a JSON object \u2014 skipped."));
|
|
3555
|
+
continue;
|
|
3556
|
+
}
|
|
3557
|
+
await admin({ method: "POST", path: base, body, summary: "Create transform rule (raw JSON)" });
|
|
3558
|
+
console.log(import_chalk26.default.green(" Rule created."));
|
|
3559
|
+
continue;
|
|
3560
|
+
}
|
|
3448
3561
|
if (act === "add") {
|
|
3449
3562
|
const ans = await inquirer2.prompt([
|
|
3450
3563
|
{ type: "input", name: "name", message: "Rule name:", validate: (s) => !!s || "required" },
|
|
@@ -3477,11 +3590,26 @@ async function transformsMenu(proj2) {
|
|
|
3477
3590
|
{ type: "input", name: "destination", message: `Destination field ${fieldHint}:`, validate: (s) => !!s || "required" },
|
|
3478
3591
|
{ type: "confirm", name: "strip", message: "Remove the source field after copying?", default: false }
|
|
3479
3592
|
]);
|
|
3480
|
-
|
|
3593
|
+
const source_fns = await buildFns("Transform the value as it is READ (source functions)");
|
|
3594
|
+
const dest_fns = await buildFns("Transform the value as it is WRITTEN (destination functions)");
|
|
3595
|
+
action2 = {
|
|
3596
|
+
type: "copy",
|
|
3597
|
+
source: a.source,
|
|
3598
|
+
destination: a.destination,
|
|
3599
|
+
...a.strip ? { strip_source: true } : {},
|
|
3600
|
+
...source_fns.length ? { source_fns } : {},
|
|
3601
|
+
...dest_fns.length ? { dest_fns } : {}
|
|
3602
|
+
};
|
|
3481
3603
|
}
|
|
3604
|
+
const condition = await buildCondition(ans.phase);
|
|
3482
3605
|
const spinner = (0, import_ora11.default)("Creating rule...").start();
|
|
3483
3606
|
try {
|
|
3484
|
-
await admin({
|
|
3607
|
+
await admin({
|
|
3608
|
+
method: "POST",
|
|
3609
|
+
path: base,
|
|
3610
|
+
body: { name: ans.name, phase: ans.phase, enabled: true, action: action2, ...condition ? { condition } : {} },
|
|
3611
|
+
summary: `Create transform "${ans.name}"`
|
|
3612
|
+
});
|
|
3485
3613
|
spinner.succeed(`Rule "${ans.name}" created.`);
|
|
3486
3614
|
} catch (err) {
|
|
3487
3615
|
spinner.fail("Create failed.");
|
package/package.json
CHANGED