@brainervirus/workit-cursor 8.22.2 → 8.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.
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +517 -1745
- package/dist/mcp-server.js +21 -1644
- package/dist/workit-hook.js +505 -1749
- package/package.json +3 -3
- package/skills/workit-fanout/SKILL.md +4 -4
- package/skills/workit-fanout/references/brief.md +17 -11
- package/skills/workit-fanout/references/orchestration.md +6 -6
- package/skills/workit-implement/SKILL.md +2 -0
package/dist/workit-hook.js
CHANGED
|
@@ -958,8 +958,6 @@ var base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/
|
|
|
958
958
|
var base64url = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/;
|
|
959
959
|
var httpProtocol = /^https?$/;
|
|
960
960
|
var e164 = /^\+[1-9]\d{6,14}$/;
|
|
961
|
-
var creditCard = /^\d(?:[ -]?\d){11,18}$/;
|
|
962
|
-
var iban = /^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/;
|
|
963
961
|
var dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
|
|
964
962
|
function anchor(source) {
|
|
965
963
|
return new RegExp(`^${source}$`);
|
|
@@ -1805,41 +1803,6 @@ var $ZodE164 = /* @__PURE__ */ $constructor("$ZodE164", (inst, def) => {
|
|
|
1805
1803
|
def.pattern ?? (def.pattern = e164);
|
|
1806
1804
|
$ZodStringFormat.init(inst, def);
|
|
1807
1805
|
});
|
|
1808
|
-
var CC_SANITIZE = /[- ]/g;
|
|
1809
|
-
function isLuhnAlgo(digits) {
|
|
1810
|
-
let length = digits.length;
|
|
1811
|
-
let bit = 1;
|
|
1812
|
-
let sum = 0;
|
|
1813
|
-
while (length) {
|
|
1814
|
-
const value = digits.charCodeAt(--length) - 48;
|
|
1815
|
-
bit ^= 1;
|
|
1816
|
-
sum += bit ? [0, 2, 4, 6, 8, 1, 3, 5, 7, 9][value] : value;
|
|
1817
|
-
}
|
|
1818
|
-
return sum % 10 === 0;
|
|
1819
|
-
}
|
|
1820
|
-
function isValidCreditCard(input) {
|
|
1821
|
-
if (!creditCard.test(input))
|
|
1822
|
-
return false;
|
|
1823
|
-
return isLuhnAlgo(input.replace(CC_SANITIZE, ""));
|
|
1824
|
-
}
|
|
1825
|
-
function isIso7064Mod97(iban2) {
|
|
1826
|
-
let remainder = 0;
|
|
1827
|
-
const len = iban2.length;
|
|
1828
|
-
for (let i = 4;i < len; i++) {
|
|
1829
|
-
const code = iban2.charCodeAt(i);
|
|
1830
|
-
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
1831
|
-
}
|
|
1832
|
-
for (let i = 0;i < 4; i++) {
|
|
1833
|
-
const code = iban2.charCodeAt(i);
|
|
1834
|
-
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
1835
|
-
}
|
|
1836
|
-
return remainder === 1;
|
|
1837
|
-
}
|
|
1838
|
-
function isValidIBAN(input) {
|
|
1839
|
-
if (!iban.test(input))
|
|
1840
|
-
return false;
|
|
1841
|
-
return isIso7064Mod97(input);
|
|
1842
|
-
}
|
|
1843
1806
|
function isValidJWT(token, algorithm = null) {
|
|
1844
1807
|
try {
|
|
1845
1808
|
const tokensParts = token.split(".");
|
|
@@ -3152,9 +3115,6 @@ function settle(inst, answer) {
|
|
|
3152
3115
|
recursive.set(inst, answer === PROVEN);
|
|
3153
3116
|
return answer;
|
|
3154
3117
|
}
|
|
3155
|
-
function isRecursiveSchema(inst) {
|
|
3156
|
-
return isRecursive(inst, new Set, true) !== NONE;
|
|
3157
|
-
}
|
|
3158
3118
|
function bucketFor(state, inst) {
|
|
3159
3119
|
let bucket = state.buckets.get(inst);
|
|
3160
3120
|
if (!bucket) {
|
|
@@ -3394,1651 +3354,53 @@ function en_default() {
|
|
|
3394
3354
|
localeError: error()
|
|
3395
3355
|
};
|
|
3396
3356
|
}
|
|
3397
|
-
// node_modules/zod/v4/core/registries.js
|
|
3398
|
-
var _a2;
|
|
3399
|
-
class $ZodRegistry {
|
|
3400
|
-
constructor() {
|
|
3401
|
-
this._map = new WeakMap;
|
|
3402
|
-
this._idmap = new Map;
|
|
3403
|
-
}
|
|
3404
|
-
add(schema, ..._meta) {
|
|
3405
|
-
const meta = _meta[0];
|
|
3406
|
-
this._map.set(schema, meta);
|
|
3407
|
-
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3408
|
-
this._idmap.set(meta.id, schema);
|
|
3409
|
-
}
|
|
3410
|
-
return this;
|
|
3411
|
-
}
|
|
3412
|
-
clear() {
|
|
3413
|
-
this._map = new WeakMap;
|
|
3414
|
-
this._idmap = new Map;
|
|
3415
|
-
return this;
|
|
3416
|
-
}
|
|
3417
|
-
remove(schema) {
|
|
3418
|
-
const meta = this._map.get(schema);
|
|
3419
|
-
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3420
|
-
this._idmap.delete(meta.id);
|
|
3421
|
-
}
|
|
3422
|
-
this._map.delete(schema);
|
|
3423
|
-
return this;
|
|
3424
|
-
}
|
|
3425
|
-
get(schema) {
|
|
3426
|
-
const p = schema._zod.parent;
|
|
3427
|
-
if (p) {
|
|
3428
|
-
const pm = { ...this.get(p) ?? {} };
|
|
3429
|
-
delete pm.id;
|
|
3430
|
-
const f = { ...pm, ...this._map.get(schema) };
|
|
3431
|
-
return Object.keys(f).length ? f : undefined;
|
|
3432
|
-
}
|
|
3433
|
-
return this._map.get(schema);
|
|
3434
|
-
}
|
|
3435
|
-
has(schema) {
|
|
3436
|
-
return this._map.has(schema);
|
|
3437
|
-
}
|
|
3438
|
-
}
|
|
3439
|
-
function registry() {
|
|
3440
|
-
return new $ZodRegistry;
|
|
3441
|
-
}
|
|
3442
|
-
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
|
|
3443
|
-
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
3444
|
-
// node_modules/zod/v4/core/compile.js
|
|
3445
|
-
var INVALID = Symbol.for("zod.compile.invalid");
|
|
3446
|
-
var FALLBACK_FLAG = Symbol.for("zod.compile.fallback");
|
|
3447
|
-
|
|
3448
|
-
class ZodCompileAsyncError extends Error {
|
|
3449
|
-
constructor(message = "z.compile does not support async refinements, transforms, or checks") {
|
|
3450
|
-
super(message);
|
|
3451
|
-
this.name = "ZodCompileAsyncError";
|
|
3452
|
-
}
|
|
3453
|
-
}
|
|
3454
|
-
|
|
3455
|
-
class ZodCompileUnsupportedError extends Error {
|
|
3456
|
-
constructor(feature, islandable = true) {
|
|
3457
|
-
super(`z.compile does not support ${feature}; this schema must use the runtime parser`);
|
|
3458
|
-
this.name = "ZodCompileUnsupportedError";
|
|
3459
|
-
this.islandable = islandable;
|
|
3460
|
-
}
|
|
3461
|
-
}
|
|
3462
|
-
function compileValidator(schema, parser) {
|
|
3463
|
-
try {
|
|
3464
|
-
return compileFn(schema, { assertOnly: true });
|
|
3465
|
-
} catch {
|
|
3466
|
-
return parser;
|
|
3467
|
-
}
|
|
3468
|
-
}
|
|
3469
|
-
function compile(schema, options) {
|
|
3470
|
-
try {
|
|
3471
|
-
const parser = compileFn(schema);
|
|
3472
|
-
const clone = withParser(schema, parser);
|
|
3473
|
-
clone._zod.bag.validator = compileValidator(schema, parser);
|
|
3474
|
-
return clone;
|
|
3475
|
-
} catch (err) {
|
|
3476
|
-
if (options?.strict)
|
|
3477
|
-
throw err;
|
|
3478
|
-
return schema;
|
|
3479
|
-
}
|
|
3480
|
-
}
|
|
3481
|
-
function withParser(schema, parser) {
|
|
3482
|
-
if (isRecursiveSchema(schema)) {
|
|
3483
|
-
throw new ZodCompileUnsupportedError("a schema whose subtree contains a reference cycle");
|
|
3484
|
-
}
|
|
3485
|
-
const clone2 = clone(schema);
|
|
3486
|
-
const liveRun = schema._zod.run;
|
|
3487
|
-
const originalRun = liveRun.__originalRun ?? liveRun;
|
|
3488
|
-
const wrapped = (payload, ctx) => {
|
|
3489
|
-
if (ctx?.async || ctx?.direction === "backward" || ctx?.skipChecks || ctx?.[FALLBACK_FLAG]) {
|
|
3490
|
-
return originalRun(payload, ctx);
|
|
3491
|
-
}
|
|
3492
|
-
if (ctx && isBackEdge(ctx, payload.value)) {
|
|
3493
|
-
return originalRun(payload, ctx);
|
|
3494
|
-
}
|
|
3495
|
-
const out = parser(payload.value);
|
|
3496
|
-
if (out !== INVALID) {
|
|
3497
|
-
payload.value = out;
|
|
3498
|
-
return payload;
|
|
3499
|
-
}
|
|
3500
|
-
if (ctx)
|
|
3501
|
-
ctx[FALLBACK_FLAG] = true;
|
|
3502
|
-
return originalRun(payload, ctx);
|
|
3503
|
-
};
|
|
3504
|
-
wrapped.__originalRun = originalRun;
|
|
3505
|
-
clone2._zod.bag.fallbackRun = originalRun;
|
|
3506
|
-
clone2._zod.bag.validator = parser;
|
|
3507
|
-
clone2._zod.run = wrapped;
|
|
3508
|
-
if (!liveRun.__originalRun)
|
|
3509
|
-
installCompiledUserMethods(clone2, schema, parser);
|
|
3510
|
-
return clone2;
|
|
3511
|
-
}
|
|
3512
|
-
function installCompiledUserMethods(target, source, parser) {
|
|
3513
|
-
const targetAny = target;
|
|
3514
|
-
const sourceAny = source;
|
|
3515
|
-
if (typeof sourceAny.safeParse === "function") {
|
|
3516
|
-
const originalSafeParse = sourceAny.safeParse;
|
|
3517
|
-
targetAny.safeParse = (data, params) => {
|
|
3518
|
-
const out = parser(data);
|
|
3519
|
-
if (out !== INVALID) {
|
|
3520
|
-
return { success: true, data: out };
|
|
3521
|
-
}
|
|
3522
|
-
return originalSafeParse(data, params);
|
|
3523
|
-
};
|
|
3524
|
-
}
|
|
3525
|
-
if (typeof sourceAny.parse === "function") {
|
|
3526
|
-
const originalParse = sourceAny.parse;
|
|
3527
|
-
targetAny.parse = (data, params) => {
|
|
3528
|
-
const out = parser(data);
|
|
3529
|
-
if (out !== INVALID) {
|
|
3530
|
-
return out;
|
|
3531
|
-
}
|
|
3532
|
-
return originalParse(data, params);
|
|
3533
|
-
};
|
|
3534
|
-
}
|
|
3535
|
-
}
|
|
3536
|
-
function compileFn(schema, options) {
|
|
3537
|
-
let recursive = true;
|
|
3538
|
-
try {
|
|
3539
|
-
recursive = isRecursiveSchema(schema);
|
|
3540
|
-
} catch {}
|
|
3541
|
-
if (recursive) {
|
|
3542
|
-
throw new ZodCompileUnsupportedError("a schema whose subtree contains a reference cycle");
|
|
3543
|
-
}
|
|
3544
|
-
const ctx = {
|
|
3545
|
-
constants: new Map,
|
|
3546
|
-
constantCounter: 0,
|
|
3547
|
-
varCounter: 0,
|
|
3548
|
-
definite: true
|
|
3549
|
-
};
|
|
3550
|
-
const doc = new Doc(["input"]);
|
|
3551
|
-
const outputAccessor = generateCheck(doc, ctx, schema, "input", !options?.assertOnly);
|
|
3552
|
-
doc.write(outputAccessor === null ? `return true;` : `return ${outputAccessor};`);
|
|
3553
|
-
const constantNames = ["INVALID", ...ctx.constants.keys()];
|
|
3554
|
-
const constantValues = [INVALID, ...ctx.constants.values()];
|
|
3555
|
-
const code = doc.content.join(`
|
|
3556
|
-
`);
|
|
3557
|
-
const fullCode = options?.debug ? constantNames.length > 0 ? `// Constants: ${constantNames.join(", ")}
|
|
3558
|
-
${code}` : code : "";
|
|
3559
|
-
const F = Function;
|
|
3560
|
-
const factoryCode = `return (input) => {
|
|
3561
|
-
${code}
|
|
3562
|
-
}`;
|
|
3563
|
-
let fn;
|
|
3564
|
-
try {
|
|
3565
|
-
const factory = new F(...constantNames, factoryCode);
|
|
3566
|
-
fn = factory(...constantValues);
|
|
3567
|
-
} catch (err) {
|
|
3568
|
-
throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${err.message})`);
|
|
3569
|
-
}
|
|
3570
|
-
if (options?.debug) {
|
|
3571
|
-
fn.code = fullCode;
|
|
3572
|
-
}
|
|
3573
|
-
fn.definite = ctx.definite;
|
|
3574
|
-
return fn;
|
|
3575
|
-
}
|
|
3576
|
-
function addConstant(ctx, value) {
|
|
3577
|
-
for (const [name, v] of ctx.constants) {
|
|
3578
|
-
if (v === value)
|
|
3579
|
-
return name;
|
|
3580
|
-
}
|
|
3581
|
-
const name = `c${ctx.constantCounter++}`;
|
|
3582
|
-
ctx.constants.set(name, value);
|
|
3583
|
-
return name;
|
|
3584
|
-
}
|
|
3585
|
-
function addUserConstant(ctx, fn) {
|
|
3586
|
-
ctx.definite = false;
|
|
3587
|
-
return addConstant(ctx, fn);
|
|
3588
|
-
}
|
|
3589
|
-
function newVar(ctx) {
|
|
3590
|
-
return `v${ctx.varCounter++}`;
|
|
3591
|
-
}
|
|
3592
|
-
function runtimeRun(schema, value) {
|
|
3593
|
-
const result = schema._zod.run({ value, issues: [] }, {});
|
|
3594
|
-
if (result && typeof result.then === "function")
|
|
3595
|
-
return INVALID;
|
|
3596
|
-
const r = result;
|
|
3597
|
-
return r.issues.length === 0 ? r.value : INVALID;
|
|
3598
|
-
}
|
|
3599
|
-
function compileChild(doc, ctx, schema, accessor, needsValue = true) {
|
|
3600
|
-
const contentLen = doc.content.length;
|
|
3601
|
-
const constantCount = ctx.constants.size;
|
|
3602
|
-
const constantCounter = ctx.constantCounter;
|
|
3603
|
-
const varCounter = ctx.varCounter;
|
|
3604
|
-
try {
|
|
3605
|
-
return generateCheck(doc, ctx, schema, accessor, needsValue);
|
|
3606
|
-
} catch (err) {
|
|
3607
|
-
if (!(err instanceof ZodCompileUnsupportedError) || !err.islandable)
|
|
3608
|
-
throw err;
|
|
3609
|
-
doc.content.length = contentLen;
|
|
3610
|
-
if (ctx.constants.size > constantCount) {
|
|
3611
|
-
const trailing = Array.from(ctx.constants.keys()).slice(constantCount);
|
|
3612
|
-
for (const k of trailing)
|
|
3613
|
-
ctx.constants.delete(k);
|
|
3614
|
-
}
|
|
3615
|
-
ctx.constantCounter = constantCounter;
|
|
3616
|
-
ctx.varCounter = varCounter;
|
|
3617
|
-
return emitRuntimeIsland(doc, ctx, schema, accessor);
|
|
3618
|
-
}
|
|
3619
|
-
}
|
|
3620
|
-
function emitRuntimeIsland(doc, ctx, schema, accessor) {
|
|
3621
|
-
ctx.definite = false;
|
|
3622
|
-
const schemaConst = addConstant(ctx, schema);
|
|
3623
|
-
const runConst = addConstant(ctx, runtimeRun);
|
|
3624
|
-
const outVar = newVar(ctx);
|
|
3625
|
-
doc.write(`const ${outVar} = ${runConst}(${schemaConst}, ${accessor});`);
|
|
3626
|
-
doc.write(`if (${outVar} === INVALID) return INVALID;`);
|
|
3627
|
-
return outVar;
|
|
3628
|
-
}
|
|
3629
|
-
var WHEN_DEFAULTED_CHECKS = new Set([
|
|
3630
|
-
"max_size",
|
|
3631
|
-
"min_size",
|
|
3632
|
-
"size_equals",
|
|
3633
|
-
"max_length",
|
|
3634
|
-
"min_length",
|
|
3635
|
-
"length_equals"
|
|
3636
|
-
]);
|
|
3637
|
-
function generateChecks(doc, ctx, schema, accessor) {
|
|
3638
|
-
const schemaChecks = schema._zod.def.checks;
|
|
3639
|
-
if (!schemaChecks || schemaChecks.length === 0)
|
|
3640
|
-
return accessor;
|
|
3641
|
-
let currentAccessor = accessor;
|
|
3642
|
-
for (const check of schemaChecks) {
|
|
3643
|
-
const def = check._zod.def;
|
|
3644
|
-
if (def.when && !WHEN_DEFAULTED_CHECKS.has(def.check)) {
|
|
3645
|
-
throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
|
|
3646
|
-
}
|
|
3647
|
-
switch (def.check) {
|
|
3648
|
-
case "greater_than":
|
|
3649
|
-
generateGreaterThanCheck(doc, ctx, def, currentAccessor);
|
|
3650
|
-
break;
|
|
3651
|
-
case "less_than":
|
|
3652
|
-
generateLessThanCheck(doc, ctx, def, currentAccessor);
|
|
3653
|
-
break;
|
|
3654
|
-
case "multiple_of":
|
|
3655
|
-
generateMultipleOfCheck(doc, ctx, def, currentAccessor);
|
|
3656
|
-
break;
|
|
3657
|
-
case "number_format":
|
|
3658
|
-
generateNumberFormatCheck(doc, def, currentAccessor);
|
|
3659
|
-
break;
|
|
3660
|
-
case "min_length": {
|
|
3661
|
-
const min = numericOperand(def.minimum, "min_length");
|
|
3662
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${min} && ${currentAccessor}.length < ${def.minimum * 2}`);
|
|
3663
|
-
doc.write(`if (${len} < ${min}) return INVALID;`);
|
|
3664
|
-
break;
|
|
3665
|
-
}
|
|
3666
|
-
case "max_length": {
|
|
3667
|
-
const max = numericOperand(def.maximum, "max_length");
|
|
3668
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length > ${max}`);
|
|
3669
|
-
doc.write(`if (${len} > ${max}) return INVALID;`);
|
|
3670
|
-
break;
|
|
3671
|
-
}
|
|
3672
|
-
case "length_equals": {
|
|
3673
|
-
const exact = numericOperand(def.length, "length_equals");
|
|
3674
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${exact} && ${currentAccessor}.length <= ${def.length * 2}`);
|
|
3675
|
-
doc.write(`if (${len} !== ${exact}) return INVALID;`);
|
|
3676
|
-
break;
|
|
3677
|
-
}
|
|
3678
|
-
case "min_size":
|
|
3679
|
-
doc.write(`if (${currentAccessor}.size < ${numericOperand(def.minimum, "min_size")}) return INVALID;`);
|
|
3680
|
-
break;
|
|
3681
|
-
case "max_size":
|
|
3682
|
-
doc.write(`if (${currentAccessor}.size > ${numericOperand(def.maximum, "max_size")}) return INVALID;`);
|
|
3683
|
-
break;
|
|
3684
|
-
case "size_equals":
|
|
3685
|
-
doc.write(`if (${currentAccessor}.size !== ${numericOperand(def.size, "size_equals")}) return INVALID;`);
|
|
3686
|
-
break;
|
|
3687
|
-
case "string_format":
|
|
3688
|
-
currentAccessor = generateStringFormatCheck(doc, ctx, def, currentAccessor);
|
|
3689
|
-
break;
|
|
3690
|
-
case "custom":
|
|
3691
|
-
currentAccessor = generateCustomRefineCheck(doc, ctx, check, currentAccessor);
|
|
3692
|
-
break;
|
|
3693
|
-
case "bigint_format":
|
|
3694
|
-
generateBigIntFormatCheck(doc, def, currentAccessor);
|
|
3695
|
-
break;
|
|
3696
|
-
case "mime_type":
|
|
3697
|
-
generateMimeTypeCheck(doc, ctx, def, currentAccessor);
|
|
3698
|
-
break;
|
|
3699
|
-
case "property":
|
|
3700
|
-
generatePropertyCheck(doc, ctx, def, currentAccessor);
|
|
3701
|
-
break;
|
|
3702
|
-
case "properties":
|
|
3703
|
-
generatePropertiesChecks(doc, ctx, def, currentAccessor);
|
|
3704
|
-
break;
|
|
3705
|
-
case "overwrite": {
|
|
3706
|
-
const newAccessor = newVar(ctx);
|
|
3707
|
-
generateOverwriteCheck(doc, ctx, check, currentAccessor, newAccessor);
|
|
3708
|
-
currentAccessor = newAccessor;
|
|
3709
|
-
break;
|
|
3710
|
-
}
|
|
3711
|
-
default: {
|
|
3712
|
-
throw new ZodCompileUnsupportedError(`check type ${def.check}`);
|
|
3713
|
-
}
|
|
3714
|
-
}
|
|
3715
|
-
}
|
|
3716
|
-
return currentAccessor;
|
|
3717
|
-
}
|
|
3718
|
-
function codePointLengthVar(doc, ctx, accessor, inDoubt) {
|
|
3719
|
-
const cpLen = addConstant(ctx, codePointLength);
|
|
3720
|
-
const v = newVar(ctx);
|
|
3721
|
-
doc.write(`const ${v} = typeof ${accessor} === "string" && ${inDoubt} ? ${cpLen}(${accessor}) : ${accessor}.length;`);
|
|
3722
|
-
return v;
|
|
3723
|
-
}
|
|
3724
|
-
function numericOperand(value, label) {
|
|
3725
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3726
|
-
throw new ZodCompileUnsupportedError(`${label} bound of type ${typeof value}`);
|
|
3727
|
-
}
|
|
3728
|
-
return `${value}`;
|
|
3729
|
-
}
|
|
3730
|
-
function comparisonOperand(ctx, value) {
|
|
3731
|
-
if (typeof value === "bigint")
|
|
3732
|
-
return `${value}n`;
|
|
3733
|
-
if (typeof value === "number") {
|
|
3734
|
-
if (Number.isNaN(value))
|
|
3735
|
-
throw new ZodCompileUnsupportedError("comparison check with NaN bound");
|
|
3736
|
-
return `${value}`;
|
|
3737
|
-
}
|
|
3738
|
-
if (value instanceof Date) {
|
|
3739
|
-
if (Number.isNaN(value.getTime())) {
|
|
3740
|
-
throw new ZodCompileUnsupportedError("comparison check with Invalid Date bound");
|
|
3741
|
-
}
|
|
3742
|
-
return addConstant(ctx, value);
|
|
3743
|
-
}
|
|
3744
|
-
throw new ZodCompileUnsupportedError(`comparison check bound of type ${typeof value}`);
|
|
3745
|
-
}
|
|
3746
|
-
function generateGreaterThanCheck(doc, ctx, def, accessor) {
|
|
3747
|
-
const op = def.inclusive ? "<" : "<=";
|
|
3748
|
-
doc.write(`if (${accessor} ${op} ${comparisonOperand(ctx, def.value)}) return INVALID;`);
|
|
3749
|
-
}
|
|
3750
|
-
function generateLessThanCheck(doc, ctx, def, accessor) {
|
|
3751
|
-
const op = def.inclusive ? ">" : ">=";
|
|
3752
|
-
doc.write(`if (${accessor} ${op} ${comparisonOperand(ctx, def.value)}) return INVALID;`);
|
|
3753
|
-
}
|
|
3754
|
-
function generateMultipleOfCheck(doc, ctx, def, accessor) {
|
|
3755
|
-
if (typeof def.value === "bigint") {
|
|
3756
|
-
if (def.value === BigInt(0))
|
|
3757
|
-
throw new ZodCompileUnsupportedError("multiple_of check with a zero divisor");
|
|
3758
|
-
doc.write(`if (${accessor} % ${def.value}n !== 0n) return INVALID;`);
|
|
3759
|
-
} else {
|
|
3760
|
-
const remainder = addConstant(ctx, floatSafeRemainder);
|
|
3761
|
-
doc.write(`if (${remainder}(${accessor}, ${numericOperand(def.value, "multiple_of")}) !== 0) return INVALID;`);
|
|
3762
|
-
}
|
|
3763
|
-
}
|
|
3764
|
-
function generateNumberFormatCheck(doc, def, accessor) {
|
|
3765
|
-
const format = def.format;
|
|
3766
|
-
switch (format) {
|
|
3767
|
-
case "safeint":
|
|
3768
|
-
doc.write(`if (!Number.isSafeInteger(${accessor})) return INVALID;`);
|
|
3769
|
-
break;
|
|
3770
|
-
case "int32":
|
|
3771
|
-
doc.write(`if (!Number.isInteger(${accessor}) || ${accessor} < -2147483648 || ${accessor} > 2147483647) return INVALID;`);
|
|
3772
|
-
break;
|
|
3773
|
-
case "uint32":
|
|
3774
|
-
doc.write(`if (!Number.isInteger(${accessor}) || ${accessor} < 0 || ${accessor} > 4294967295) return INVALID;`);
|
|
3775
|
-
break;
|
|
3776
|
-
case "float32":
|
|
3777
|
-
doc.write(`if (!Number.isFinite(${accessor}) || ${accessor} < -3.4028234663852886e38 || ${accessor} > 3.4028234663852886e38) return INVALID;`);
|
|
3778
|
-
break;
|
|
3779
|
-
case "float64":
|
|
3780
|
-
doc.write(`if (!Number.isFinite(${accessor})) return INVALID;`);
|
|
3781
|
-
break;
|
|
3782
|
-
default: {
|
|
3783
|
-
throw new ZodCompileUnsupportedError(`number format ${format}`);
|
|
3784
|
-
}
|
|
3785
|
-
}
|
|
3786
|
-
}
|
|
3787
|
-
function generateBigIntFormatCheck(doc, def, accessor) {
|
|
3788
|
-
const format = def.format;
|
|
3789
|
-
if (!format)
|
|
3790
|
-
return;
|
|
3791
|
-
switch (format) {
|
|
3792
|
-
case "int64":
|
|
3793
|
-
doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);
|
|
3794
|
-
break;
|
|
3795
|
-
case "uint64":
|
|
3796
|
-
doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);
|
|
3797
|
-
break;
|
|
3798
|
-
default: {
|
|
3799
|
-
throw new ZodCompileUnsupportedError(`bigint format ${format}`);
|
|
3800
|
-
}
|
|
3801
|
-
}
|
|
3802
|
-
}
|
|
3803
|
-
function generateMimeTypeCheck(doc, ctx, def, accessor) {
|
|
3804
|
-
const mimeTypes = def.mime;
|
|
3805
|
-
if (mimeTypes && mimeTypes.length > 0) {
|
|
3806
|
-
const mimeSet = addConstant(ctx, new Set(mimeTypes));
|
|
3807
|
-
doc.write(`if (!${mimeSet}.has(${accessor}.type)) return INVALID;`);
|
|
3808
|
-
}
|
|
3809
|
-
}
|
|
3810
|
-
function generatePropertiesChecks(doc, ctx, def, accessor) {
|
|
3811
|
-
if (def.when) {
|
|
3812
|
-
throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
|
|
3813
|
-
}
|
|
3814
|
-
doc.write(`if (${accessor} == null) return INVALID;`);
|
|
3815
|
-
const shape = def.shape;
|
|
3816
|
-
for (const key of Reflect.ownKeys(shape)) {
|
|
3817
|
-
const keyExpr = typeof key === "symbol" ? addConstant(ctx, key) : esc(key);
|
|
3818
|
-
const inputVar = newVar(ctx);
|
|
3819
|
-
doc.write(`const ${inputVar} = ${accessor}[${keyExpr}];`);
|
|
3820
|
-
compileChild(doc, ctx, shape[key], inputVar, false);
|
|
3821
|
-
}
|
|
3822
|
-
}
|
|
3823
|
-
function generatePropertyCheck(doc, ctx, def, accessor) {
|
|
3824
|
-
const propAccessor = `${accessor}[${JSON.stringify(def.property)}]`;
|
|
3825
|
-
generateCheck(doc, ctx, def.schema, propAccessor);
|
|
3826
|
-
}
|
|
3827
|
-
function generateOverwriteCheck(doc, ctx, check, currentAccessor, newAccessor) {
|
|
3828
|
-
const tx = check._zod.def.tx;
|
|
3829
|
-
if (!tx) {
|
|
3830
|
-
throw new ZodCompileUnsupportedError("overwrite check without a transform function");
|
|
3831
|
-
}
|
|
3832
|
-
if (isAsyncFunction(tx)) {
|
|
3833
|
-
throw new ZodCompileAsyncError("z.compile: async overwrite transforms are not supported");
|
|
3834
|
-
}
|
|
3835
|
-
const txConst = addConstant(ctx, tx);
|
|
3836
|
-
doc.write(`const ${newAccessor} = ${txConst}(${currentAccessor});`);
|
|
3837
|
-
}
|
|
3838
|
-
function throwAsync() {
|
|
3839
|
-
throw new $ZodAsyncError;
|
|
3840
|
-
}
|
|
3841
|
-
function pushIssue(issue) {
|
|
3842
|
-
this.issues.push(issue);
|
|
3843
|
-
}
|
|
3844
|
-
function generateCustomRefineCheck(doc, ctx, check, accessor) {
|
|
3845
|
-
const def = check._zod.def;
|
|
3846
|
-
if (def.fn) {
|
|
3847
|
-
if (isAsyncFunction(def.fn)) {
|
|
3848
|
-
throw new ZodCompileAsyncError("z.compile: async .refine() predicates are not supported");
|
|
3849
|
-
}
|
|
3850
|
-
const fnConst = addUserConstant(ctx, def.fn);
|
|
3851
|
-
const throwAsyncConst = addConstant(ctx, throwAsync);
|
|
3852
|
-
const resVar = newVar(ctx);
|
|
3853
|
-
doc.write(`const ${resVar} = ${fnConst}(${accessor});`);
|
|
3854
|
-
doc.write(`if (${resVar} instanceof Promise) ${throwAsyncConst}();`);
|
|
3855
|
-
doc.write(`if (!${resVar}) return INVALID;`);
|
|
3856
|
-
return accessor;
|
|
3857
|
-
}
|
|
3858
|
-
if (check._zod.check) {
|
|
3859
|
-
if (isAsyncFunction(check._zod.check)) {
|
|
3860
|
-
throw new ZodCompileAsyncError("z.compile: async .superRefine() / check functions are not supported");
|
|
3861
|
-
}
|
|
3862
|
-
const checkFn = check._zod.check;
|
|
3863
|
-
const helperFn = (value) => {
|
|
3864
|
-
const fakePayload = { value, issues: [], addIssue: pushIssue };
|
|
3865
|
-
const result = checkFn(fakePayload);
|
|
3866
|
-
if (result instanceof Promise)
|
|
3867
|
-
throwAsync();
|
|
3868
|
-
return fakePayload.issues.length === 0 ? fakePayload.value : INVALID;
|
|
3869
|
-
};
|
|
3870
|
-
const helperConst = addUserConstant(ctx, helperFn);
|
|
3871
|
-
const outVar = newVar(ctx);
|
|
3872
|
-
doc.write(`const ${outVar} = ${helperConst}(${accessor});`);
|
|
3873
|
-
doc.write(`if (${outVar} === INVALID) return INVALID;`);
|
|
3874
|
-
return outVar;
|
|
3875
|
-
}
|
|
3876
|
-
throw new ZodCompileUnsupportedError("custom check without a predicate or check function");
|
|
3877
|
-
}
|
|
3878
|
-
var PATTERN_IS_COMPLETE = new Set([
|
|
3879
|
-
"cidrv4",
|
|
3880
|
-
"cuid",
|
|
3881
|
-
"cuid2",
|
|
3882
|
-
"date",
|
|
3883
|
-
"datetime",
|
|
3884
|
-
"duration",
|
|
3885
|
-
"e164",
|
|
3886
|
-
"email",
|
|
3887
|
-
"emoji",
|
|
3888
|
-
"ends_with",
|
|
3889
|
-
"guid",
|
|
3890
|
-
"includes",
|
|
3891
|
-
"ipv4",
|
|
3892
|
-
"ksuid",
|
|
3893
|
-
"lowercase",
|
|
3894
|
-
"mac",
|
|
3895
|
-
"nanoid",
|
|
3896
|
-
"regex",
|
|
3897
|
-
"starts_with",
|
|
3898
|
-
"time",
|
|
3899
|
-
"ulid",
|
|
3900
|
-
"uppercase",
|
|
3901
|
-
"uuid",
|
|
3902
|
-
"xid"
|
|
3903
|
-
]);
|
|
3904
|
-
function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
3905
|
-
const fmt = def.format;
|
|
3906
|
-
if (fmt === "base64") {
|
|
3907
|
-
const validator = addConstant(ctx, isValidBase64);
|
|
3908
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
3909
|
-
return accessor;
|
|
3910
|
-
}
|
|
3911
|
-
if (fmt === "base64url") {
|
|
3912
|
-
const validator = addConstant(ctx, isValidBase64URL);
|
|
3913
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
3914
|
-
return accessor;
|
|
3915
|
-
}
|
|
3916
|
-
if (fmt === "jwt") {
|
|
3917
|
-
const validator = addConstant(ctx, isValidJWT);
|
|
3918
|
-
const alg = addConstant(ctx, def.alg ?? null);
|
|
3919
|
-
doc.write(`if (!${validator}(${accessor}, ${alg})) return INVALID;`);
|
|
3920
|
-
return accessor;
|
|
3921
|
-
}
|
|
3922
|
-
if (fmt === "ipv6") {
|
|
3923
|
-
const validator = addConstant(ctx, isValidIPv6);
|
|
3924
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
3925
|
-
return accessor;
|
|
3926
|
-
}
|
|
3927
|
-
if (fmt === "cidrv6") {
|
|
3928
|
-
const validator = addConstant(ctx, isValidCIDRv6);
|
|
3929
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
3930
|
-
return accessor;
|
|
3931
|
-
}
|
|
3932
|
-
if (fmt === "credit_card") {
|
|
3933
|
-
const validator = addConstant(ctx, isValidCreditCard);
|
|
3934
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
3935
|
-
return accessor;
|
|
3936
|
-
}
|
|
3937
|
-
if (fmt === "iban") {
|
|
3938
|
-
const validator = addConstant(ctx, isValidIBAN);
|
|
3939
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
3940
|
-
return accessor;
|
|
3941
|
-
}
|
|
3942
|
-
const formatDef = def;
|
|
3943
|
-
if (fmt === "url" || fmt === "httpurl" || formatDef.normalize || formatDef.hostname !== undefined || formatDef.protocol !== undefined) {
|
|
3944
|
-
const parseConst = addConstant(ctx, validateURL);
|
|
3945
|
-
const defConst = addConstant(ctx, def);
|
|
3946
|
-
const trimVar = newVar(ctx);
|
|
3947
|
-
const urlVar = newVar(ctx);
|
|
3948
|
-
doc.write(`const ${trimVar} = ${accessor}.trim();`);
|
|
3949
|
-
doc.write(`const ${urlVar} = ${parseConst}(${trimVar}, ${defConst});`);
|
|
3950
|
-
doc.write(`if (typeof ${urlVar} === "number") return INVALID;`);
|
|
3951
|
-
if (formatDef.hostname !== undefined) {
|
|
3952
|
-
const hostnameConst = addConstant(ctx, urlHostnameOk);
|
|
3953
|
-
doc.write(`if (!${hostnameConst}(${urlVar}, ${defConst}.hostname)) return INVALID;`);
|
|
3954
|
-
}
|
|
3955
|
-
if (formatDef.protocol !== undefined) {
|
|
3956
|
-
const protocolConst = addConstant(ctx, urlProtocolOk);
|
|
3957
|
-
doc.write(`if (!${protocolConst}(${urlVar}, ${defConst}.protocol)) return INVALID;`);
|
|
3958
|
-
}
|
|
3959
|
-
if (!needsValue)
|
|
3960
|
-
return null;
|
|
3961
|
-
const outputVar = newVar(ctx);
|
|
3962
|
-
const outputExpr = formatDef.normalize ? `${urlVar}.href` : `${addConstant(ctx, stripTabAndNewline)}(${trimVar})`;
|
|
3963
|
-
doc.write(`const ${outputVar} = ${outputExpr};`);
|
|
3964
|
-
return outputVar;
|
|
3965
|
-
}
|
|
3966
|
-
const customFn = def.fn;
|
|
3967
|
-
if (customFn) {
|
|
3968
|
-
if (isAsyncFunction(customFn))
|
|
3969
|
-
throw new ZodCompileUnsupportedError(`async string format ${fmt}`);
|
|
3970
|
-
const fnConst = addConstant(ctx, customFn);
|
|
3971
|
-
doc.write(`if (!${fnConst}(${accessor})) return INVALID;`);
|
|
3972
|
-
return accessor;
|
|
3973
|
-
}
|
|
3974
|
-
if (PATTERN_IS_COMPLETE.has(fmt) && def.pattern) {
|
|
3975
|
-
const patternConst = addConstant(ctx, def.pattern);
|
|
3976
|
-
doc.write(`${patternConst}.lastIndex = 0;`);
|
|
3977
|
-
doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);
|
|
3978
|
-
return accessor;
|
|
3979
|
-
}
|
|
3980
|
-
const format = def.format;
|
|
3981
|
-
switch (format) {
|
|
3982
|
-
case "regex":
|
|
3983
|
-
throw new ZodCompileUnsupportedError("regex format without a pattern");
|
|
3984
|
-
case "lowercase":
|
|
3985
|
-
doc.write(`if (${accessor} !== ${accessor}.toLowerCase()) return INVALID;`);
|
|
3986
|
-
break;
|
|
3987
|
-
case "uppercase":
|
|
3988
|
-
doc.write(`if (${accessor} !== ${accessor}.toUpperCase()) return INVALID;`);
|
|
3989
|
-
break;
|
|
3990
|
-
case "includes":
|
|
3991
|
-
doc.write(`if (!${accessor}.includes(${esc(def.includes)})) return INVALID;`);
|
|
3992
|
-
break;
|
|
3993
|
-
case "starts_with": {
|
|
3994
|
-
const prefix = def.prefix;
|
|
3995
|
-
doc.write(`if (${accessor}.slice(0, ${prefix.length}) !== ${esc(prefix)}) return INVALID;`);
|
|
3996
|
-
break;
|
|
3997
|
-
}
|
|
3998
|
-
case "ends_with": {
|
|
3999
|
-
const suffix = def.suffix;
|
|
4000
|
-
doc.write(`if (${accessor}.slice(-${suffix.length}) !== ${esc(suffix)}) return INVALID;`);
|
|
4001
|
-
break;
|
|
4002
|
-
}
|
|
4003
|
-
default: {
|
|
4004
|
-
throw new ZodCompileUnsupportedError(`string format ${format}`);
|
|
4005
|
-
}
|
|
4006
|
-
}
|
|
4007
|
-
return accessor;
|
|
4008
|
-
}
|
|
4009
|
-
function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
4010
|
-
const def = schema._zod.def;
|
|
4011
|
-
const type = def.type;
|
|
4012
|
-
if (def.coerce) {
|
|
4013
|
-
throw new ZodCompileUnsupportedError(`coercion (z.coerce.${type}())`);
|
|
4014
|
-
}
|
|
4015
|
-
const buildsValue = needsValue || !!def.checks?.length;
|
|
4016
|
-
let typeAccessor;
|
|
4017
|
-
switch (type) {
|
|
4018
|
-
case "string":
|
|
4019
|
-
typeAccessor = generateStringCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4020
|
-
break;
|
|
4021
|
-
case "number":
|
|
4022
|
-
typeAccessor = generateNumberCheck(doc, schema, accessor);
|
|
4023
|
-
break;
|
|
4024
|
-
case "boolean":
|
|
4025
|
-
typeAccessor = generateBooleanCheck(doc, accessor);
|
|
4026
|
-
break;
|
|
4027
|
-
case "bigint":
|
|
4028
|
-
typeAccessor = generateBigIntCheck(doc, schema, accessor);
|
|
4029
|
-
break;
|
|
4030
|
-
case "symbol":
|
|
4031
|
-
typeAccessor = generateSymbolCheck(doc, accessor);
|
|
4032
|
-
break;
|
|
4033
|
-
case "undefined":
|
|
4034
|
-
typeAccessor = generateUndefinedCheck(doc, accessor);
|
|
4035
|
-
break;
|
|
4036
|
-
case "null":
|
|
4037
|
-
typeAccessor = generateNullCheck(doc, accessor);
|
|
4038
|
-
break;
|
|
4039
|
-
case "any":
|
|
4040
|
-
case "unknown":
|
|
4041
|
-
typeAccessor = accessor;
|
|
4042
|
-
break;
|
|
4043
|
-
case "never":
|
|
4044
|
-
doc.write("return INVALID;");
|
|
4045
|
-
typeAccessor = accessor;
|
|
4046
|
-
break;
|
|
4047
|
-
case "void":
|
|
4048
|
-
typeAccessor = generateVoidCheck(doc, accessor);
|
|
4049
|
-
break;
|
|
4050
|
-
case "nan":
|
|
4051
|
-
typeAccessor = generateNaNCheck(doc, accessor);
|
|
4052
|
-
break;
|
|
4053
|
-
case "date":
|
|
4054
|
-
typeAccessor = generateDateCheck(doc, accessor);
|
|
4055
|
-
break;
|
|
4056
|
-
case "object":
|
|
4057
|
-
typeAccessor = generateObjectCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4058
|
-
break;
|
|
4059
|
-
case "optional":
|
|
4060
|
-
typeAccessor = generateOptionalCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4061
|
-
break;
|
|
4062
|
-
case "nullable":
|
|
4063
|
-
typeAccessor = generateNullableCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4064
|
-
break;
|
|
4065
|
-
case "array":
|
|
4066
|
-
typeAccessor = generateArrayCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4067
|
-
break;
|
|
4068
|
-
case "literal":
|
|
4069
|
-
typeAccessor = generateLiteralCheck(doc, ctx, schema, accessor);
|
|
4070
|
-
break;
|
|
4071
|
-
case "enum":
|
|
4072
|
-
typeAccessor = generateEnumCheck(doc, ctx, schema, accessor);
|
|
4073
|
-
break;
|
|
4074
|
-
case "readonly": {
|
|
4075
|
-
const innerOut = generateWrapperCheck(doc, ctx, schema, accessor);
|
|
4076
|
-
const frozenVar = newVar(ctx);
|
|
4077
|
-
doc.write(`const ${frozenVar} = Object.freeze(${innerOut});`);
|
|
4078
|
-
typeAccessor = frozenVar;
|
|
4079
|
-
break;
|
|
4080
|
-
}
|
|
4081
|
-
case "success":
|
|
4082
|
-
generateWrapperCheck(doc, ctx, schema, accessor);
|
|
4083
|
-
typeAccessor = "true";
|
|
4084
|
-
break;
|
|
4085
|
-
case "default":
|
|
4086
|
-
case "prefault":
|
|
4087
|
-
typeAccessor = generateDefaultCheck(doc, ctx, schema, accessor);
|
|
4088
|
-
break;
|
|
4089
|
-
case "nonoptional":
|
|
4090
|
-
typeAccessor = generateNonOptionalCheck(doc, ctx, schema, accessor);
|
|
4091
|
-
break;
|
|
4092
|
-
case "tuple":
|
|
4093
|
-
typeAccessor = generateTupleCheck(doc, ctx, schema, accessor);
|
|
4094
|
-
break;
|
|
4095
|
-
case "union":
|
|
4096
|
-
typeAccessor = generateUnionCheck(doc, ctx, schema, accessor);
|
|
4097
|
-
break;
|
|
4098
|
-
case "intersection":
|
|
4099
|
-
typeAccessor = generateIntersectionCheck(doc, ctx, schema, accessor);
|
|
4100
|
-
break;
|
|
4101
|
-
case "record":
|
|
4102
|
-
typeAccessor = generateRecordCheck(doc, ctx, schema, accessor);
|
|
4103
|
-
break;
|
|
4104
|
-
case "map":
|
|
4105
|
-
typeAccessor = generateMapCheck(doc, ctx, schema, accessor);
|
|
4106
|
-
break;
|
|
4107
|
-
case "set":
|
|
4108
|
-
typeAccessor = generateSetCheck(doc, ctx, schema, accessor);
|
|
4109
|
-
break;
|
|
4110
|
-
case "file":
|
|
4111
|
-
typeAccessor = generateFileCheck(doc, accessor);
|
|
4112
|
-
break;
|
|
4113
|
-
case "template_literal":
|
|
4114
|
-
typeAccessor = generateTemplateLiteralCheck(doc, ctx, schema, accessor);
|
|
4115
|
-
break;
|
|
4116
|
-
case "lazy":
|
|
4117
|
-
typeAccessor = generateLazyCheck(doc, ctx, schema, accessor);
|
|
4118
|
-
break;
|
|
4119
|
-
case "pipe":
|
|
4120
|
-
typeAccessor = generatePipeCheck(doc, ctx, schema, accessor);
|
|
4121
|
-
break;
|
|
4122
|
-
case "custom":
|
|
4123
|
-
typeAccessor = generateCustomCheck(doc, ctx, schema, accessor);
|
|
4124
|
-
break;
|
|
4125
|
-
case "transform":
|
|
4126
|
-
typeAccessor = generateTransformCheck(doc, ctx, schema, accessor);
|
|
4127
|
-
break;
|
|
4128
|
-
case "catch":
|
|
4129
|
-
typeAccessor = generateCatchCheck(doc, ctx, schema, accessor);
|
|
4130
|
-
break;
|
|
4131
|
-
default: {
|
|
4132
|
-
throw new ZodCompileUnsupportedError(`schema type ${type}`);
|
|
4133
|
-
}
|
|
4134
|
-
}
|
|
4135
|
-
if (typeAccessor === null)
|
|
4136
|
-
return null;
|
|
4137
|
-
return generateChecks(doc, ctx, schema, typeAccessor);
|
|
4138
|
-
}
|
|
4139
|
-
function generateStringCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
4140
|
-
doc.write(`if (typeof ${accessor} !== "string") return INVALID;`);
|
|
4141
|
-
const def = schema._zod.def;
|
|
4142
|
-
if (def.format === undefined)
|
|
4143
|
-
return accessor;
|
|
4144
|
-
return generateStringFormatCheck(doc, ctx, def, accessor, needsValue);
|
|
4145
|
-
}
|
|
4146
|
-
function generateNumberCheck(doc, schema, accessor) {
|
|
4147
|
-
doc.write(`if (typeof ${accessor} !== "number" || !Number.isFinite(${accessor})) return INVALID;`);
|
|
4148
|
-
const def = schema._zod.def;
|
|
4149
|
-
if (def.check === "number_format" && def.format) {
|
|
4150
|
-
generateNumberFormatCheck(doc, { format: def.format }, accessor);
|
|
4151
|
-
}
|
|
4152
|
-
return accessor;
|
|
4153
|
-
}
|
|
4154
|
-
function generateBooleanCheck(doc, accessor) {
|
|
4155
|
-
doc.write(`if (typeof ${accessor} !== "boolean") return INVALID;`);
|
|
4156
|
-
return accessor;
|
|
4157
|
-
}
|
|
4158
|
-
function generateBigIntCheck(doc, schema, accessor) {
|
|
4159
|
-
doc.write(`if (typeof ${accessor} !== "bigint") return INVALID;`);
|
|
4160
|
-
const def = schema._zod.def;
|
|
4161
|
-
if (def.format) {
|
|
4162
|
-
switch (def.format) {
|
|
4163
|
-
case "int64":
|
|
4164
|
-
doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);
|
|
4165
|
-
break;
|
|
4166
|
-
case "uint64":
|
|
4167
|
-
doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);
|
|
4168
|
-
break;
|
|
4169
|
-
}
|
|
4170
|
-
}
|
|
4171
|
-
return accessor;
|
|
4172
|
-
}
|
|
4173
|
-
function generateSymbolCheck(doc, accessor) {
|
|
4174
|
-
doc.write(`if (typeof ${accessor} !== "symbol") return INVALID;`);
|
|
4175
|
-
return accessor;
|
|
4176
|
-
}
|
|
4177
|
-
function generateUndefinedCheck(doc, accessor) {
|
|
4178
|
-
doc.write(`if (${accessor} !== undefined) return INVALID;`);
|
|
4179
|
-
return accessor;
|
|
4180
|
-
}
|
|
4181
|
-
function generateNullCheck(doc, accessor) {
|
|
4182
|
-
doc.write(`if (${accessor} !== null) return INVALID;`);
|
|
4183
|
-
return accessor;
|
|
4184
|
-
}
|
|
4185
|
-
function generateVoidCheck(doc, accessor) {
|
|
4186
|
-
doc.write(`if (${accessor} !== undefined) return INVALID;`);
|
|
4187
|
-
return accessor;
|
|
4188
|
-
}
|
|
4189
|
-
function generateNaNCheck(doc, accessor) {
|
|
4190
|
-
doc.write(`if (typeof ${accessor} !== "number" || !Number.isNaN(${accessor})) return INVALID;`);
|
|
4191
|
-
return accessor;
|
|
4192
|
-
}
|
|
4193
|
-
function generateDateCheck(doc, accessor) {
|
|
4194
|
-
doc.write(`if (!(${accessor} instanceof Date) || Number.isNaN(${accessor}.getTime())) return INVALID;`);
|
|
4195
|
-
return accessor;
|
|
4196
|
-
}
|
|
4197
|
-
function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4198
|
-
const def = schema._zod.def;
|
|
4199
|
-
doc.write(`if (typeof ${accessor} !== "object" || ${accessor} === null || Array.isArray(${accessor})) return INVALID;`);
|
|
4200
|
-
const shape = def.shape;
|
|
4201
|
-
const keys = Object.keys(shape);
|
|
4202
|
-
const symbolKeys = Object.getOwnPropertySymbols(shape);
|
|
4203
|
-
const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;
|
|
4204
|
-
const keyExpr = (k) => typeof k === "symbol" ? addConstant(ctx, k) : esc(k);
|
|
4205
|
-
const propKey = (k) => typeof k === "symbol" ? `[${keyExpr(k)}]` : esc(k);
|
|
4206
|
-
const propShape = shape;
|
|
4207
|
-
if (keys.includes("__proto__")) {
|
|
4208
|
-
throw new ZodCompileUnsupportedError('object shape key "__proto__"');
|
|
4209
|
-
}
|
|
4210
|
-
const propOutputs = new Map;
|
|
4211
|
-
for (const key of allKeys) {
|
|
4212
|
-
const propSchema = propShape[key];
|
|
4213
|
-
const kx = keyExpr(key);
|
|
4214
|
-
const inputVar = newVar(ctx);
|
|
4215
|
-
doc.write(`const ${inputVar} = ${accessor}[${kx}];`);
|
|
4216
|
-
if (propSchema._zod.optin !== undefined) {
|
|
4217
|
-
const outputVar = newVar(ctx);
|
|
4218
|
-
doc.write(`let ${outputVar} = (() => {`);
|
|
4219
|
-
doc.indented((d) => {
|
|
4220
|
-
const outputAccessor = compileChild(d, ctx, propSchema, inputVar);
|
|
4221
|
-
d.write(`return ${outputAccessor};`);
|
|
4222
|
-
});
|
|
4223
|
-
doc.write(`})();`);
|
|
4224
|
-
if (propSchema._zod.optout === "optional") {
|
|
4225
|
-
doc.write(`if (${outputVar} === INVALID) {`);
|
|
4226
|
-
doc.indented((d) => {
|
|
4227
|
-
d.write(`if (${kx} in ${accessor}) return INVALID;`);
|
|
4228
|
-
d.write(`${outputVar} = undefined;`);
|
|
4229
|
-
});
|
|
4230
|
-
doc.write(`}`);
|
|
4231
|
-
} else {
|
|
4232
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
4233
|
-
}
|
|
4234
|
-
propOutputs.set(key, outputVar);
|
|
4235
|
-
} else {
|
|
4236
|
-
if (requiresPresenceCheck(propSchema)) {
|
|
4237
|
-
doc.write(`if (!(${kx} in ${accessor})) return INVALID;`);
|
|
4238
|
-
}
|
|
4239
|
-
const outputAccessor = compileChild(doc, ctx, propSchema, inputVar, buildsValue);
|
|
4240
|
-
if (outputAccessor !== null)
|
|
4241
|
-
propOutputs.set(key, outputAccessor);
|
|
4242
|
-
}
|
|
4243
|
-
}
|
|
4244
|
-
const catchall = def.catchall;
|
|
4245
|
-
let unknownKeysMode = "none";
|
|
4246
|
-
if (catchall) {
|
|
4247
|
-
const catchallType = catchall._zod.def.type;
|
|
4248
|
-
if (catchallType === "never") {
|
|
4249
|
-
const condition = keys.map((k) => `k !== ${esc(k)}`).join(" && ") || "true";
|
|
4250
|
-
doc.write(`for (const k in ${accessor}) {`);
|
|
4251
|
-
doc.indented((d) => {
|
|
4252
|
-
d.write(`if (${condition}) return INVALID;`);
|
|
4253
|
-
});
|
|
4254
|
-
doc.write(`}`);
|
|
4255
|
-
} else if ((catchallType === "unknown" || catchallType === "any") && !catchall._zod.def.checks?.length) {
|
|
4256
|
-
unknownKeysMode = "passthrough";
|
|
4257
|
-
} else {
|
|
4258
|
-
unknownKeysMode = "schema";
|
|
4259
|
-
}
|
|
4260
|
-
}
|
|
4261
|
-
const outputVar = newVar(ctx);
|
|
4262
|
-
const hasConditionalKeys = allKeys.some((k) => mayOmitUndefined(propShape[k]) || dropsWhenAbsent(propShape[k]));
|
|
4263
|
-
if (!buildsValue) {
|
|
4264
|
-
if (unknownKeysMode === "schema") {
|
|
4265
|
-
const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;
|
|
4266
|
-
doc.write(`for (const k in ${accessor}) {`);
|
|
4267
|
-
doc.indented((d) => {
|
|
4268
|
-
d.write(`if (k === "__proto__") continue;`);
|
|
4269
|
-
if (knownSet)
|
|
4270
|
-
d.write(`if (${knownSet}.has(k)) continue;`);
|
|
4271
|
-
const valVar = newVar(ctx);
|
|
4272
|
-
d.write(`const ${valVar} = ${accessor}[k];`);
|
|
4273
|
-
compileChild(d, ctx, catchall, valVar, false);
|
|
4274
|
-
});
|
|
4275
|
-
doc.write(`}`);
|
|
4276
|
-
}
|
|
4277
|
-
return null;
|
|
4278
|
-
}
|
|
4279
|
-
if (!hasConditionalKeys) {
|
|
4280
|
-
const propLiterals = allKeys.map((k) => `${propKey(k)}: ${propOutputs.get(k)}`).join(", ");
|
|
4281
|
-
doc.write(`const ${outputVar} = { ${propLiterals} };`);
|
|
4282
|
-
} else {
|
|
4283
|
-
doc.write(`const ${outputVar} = {};`);
|
|
4284
|
-
for (const k of allKeys) {
|
|
4285
|
-
const kx = keyExpr(k);
|
|
4286
|
-
const out = propOutputs.get(k);
|
|
4287
|
-
if (dropsWhenAbsent(propShape[k])) {
|
|
4288
|
-
doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
|
|
4289
|
-
} else if (mayOmitUndefined(propShape[k])) {
|
|
4290
|
-
doc.write(`if (${out} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
|
|
4291
|
-
} else {
|
|
4292
|
-
doc.write(`${outputVar}[${kx}] = ${out};`);
|
|
4293
|
-
}
|
|
4294
|
-
}
|
|
4295
|
-
}
|
|
4296
|
-
if (unknownKeysMode !== "none") {
|
|
4297
|
-
const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;
|
|
4298
|
-
doc.write(`for (const k in ${accessor}) {`);
|
|
4299
|
-
doc.indented((d) => {
|
|
4300
|
-
d.write(`if (k === "__proto__") continue;`);
|
|
4301
|
-
if (knownSet)
|
|
4302
|
-
d.write(`if (${knownSet}.has(k)) continue;`);
|
|
4303
|
-
if (unknownKeysMode === "passthrough") {
|
|
4304
|
-
d.write(`${outputVar}[k] = ${accessor}[k];`);
|
|
4305
|
-
} else {
|
|
4306
|
-
const valVar = newVar(ctx);
|
|
4307
|
-
d.write(`const ${valVar} = ${accessor}[k];`);
|
|
4308
|
-
const catchallOut = compileChild(d, ctx, catchall, valVar);
|
|
4309
|
-
d.write(`${outputVar}[k] = ${catchallOut};`);
|
|
4310
|
-
}
|
|
4311
|
-
});
|
|
4312
|
-
doc.write(`}`);
|
|
4313
|
-
}
|
|
4314
|
-
return outputVar;
|
|
4315
|
-
}
|
|
4316
|
-
function generateOptionalCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4317
|
-
const def = schema._zod.def;
|
|
4318
|
-
if (isExactOptional(schema)) {
|
|
4319
|
-
return generateCheck(doc, ctx, def.innerType, accessor, buildsValue);
|
|
4320
|
-
}
|
|
4321
|
-
if (def.innerType._zod.optin === "defaulted") {
|
|
4322
|
-
const outputVar = newVar(ctx);
|
|
4323
|
-
const branchVar = newVar(ctx);
|
|
4324
|
-
doc.write(`let ${outputVar};`);
|
|
4325
|
-
doc.write(`if (${accessor} === undefined) {`);
|
|
4326
|
-
doc.indented((d) => {
|
|
4327
|
-
d.write(`const ${branchVar} = (() => {`);
|
|
4328
|
-
d.indented((d2) => {
|
|
4329
|
-
const innerOutput = generateCheck(d2, ctx, def.innerType, accessor);
|
|
4330
|
-
d2.write(`return ${innerOutput};`);
|
|
4331
|
-
});
|
|
4332
|
-
d.write(`})();`);
|
|
4333
|
-
d.write(`if (${branchVar} !== INVALID) ${outputVar} = ${branchVar};`);
|
|
4334
|
-
});
|
|
4335
|
-
doc.write(`} else {`);
|
|
4336
|
-
doc.indented((d) => {
|
|
4337
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor);
|
|
4338
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4339
|
-
});
|
|
4340
|
-
doc.write(`}`);
|
|
4341
|
-
return outputVar;
|
|
4342
|
-
}
|
|
4343
|
-
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
4344
|
-
if (outputVar)
|
|
4345
|
-
doc.write(`let ${outputVar};`);
|
|
4346
|
-
doc.write(`if (${accessor} !== undefined) {`);
|
|
4347
|
-
doc.indented((d) => {
|
|
4348
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor, buildsValue);
|
|
4349
|
-
if (outputVar && innerOutput !== null)
|
|
4350
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4351
|
-
});
|
|
4352
|
-
doc.write(`}`);
|
|
4353
|
-
return outputVar;
|
|
4354
|
-
}
|
|
4355
|
-
function isExactOptional(schema) {
|
|
4356
|
-
return schema._zod.traits?.has("$ZodExactOptional") === true;
|
|
4357
|
-
}
|
|
4358
|
-
function requiresPresenceCheck(schema) {
|
|
4359
|
-
return schema._zod.optin === undefined && fastPathAcceptsAbsence(schema);
|
|
4360
|
-
}
|
|
4361
|
-
function fastPathAcceptsAbsence(schema) {
|
|
4362
|
-
if (schema._zod.def.coerce)
|
|
4363
|
-
return true;
|
|
4364
|
-
const def = schema._zod.def;
|
|
4365
|
-
switch (def.type) {
|
|
4366
|
-
case "any":
|
|
4367
|
-
case "unknown":
|
|
4368
|
-
case "undefined":
|
|
4369
|
-
case "void":
|
|
4370
|
-
case "default":
|
|
4371
|
-
case "prefault":
|
|
4372
|
-
case "transform":
|
|
4373
|
-
case "custom":
|
|
4374
|
-
case "lazy":
|
|
4375
|
-
return true;
|
|
4376
|
-
case "string":
|
|
4377
|
-
case "number":
|
|
4378
|
-
case "boolean":
|
|
4379
|
-
case "bigint":
|
|
4380
|
-
case "symbol":
|
|
4381
|
-
case "null":
|
|
4382
|
-
case "never":
|
|
4383
|
-
case "nan":
|
|
4384
|
-
case "date":
|
|
4385
|
-
case "object":
|
|
4386
|
-
case "array":
|
|
4387
|
-
case "tuple":
|
|
4388
|
-
case "record":
|
|
4389
|
-
case "map":
|
|
4390
|
-
case "set":
|
|
4391
|
-
case "file":
|
|
4392
|
-
case "template_literal":
|
|
4393
|
-
return false;
|
|
4394
|
-
case "nonoptional":
|
|
4395
|
-
return def.innerType ? fastPathAcceptsAbsence(def.innerType) : false;
|
|
4396
|
-
case "literal":
|
|
4397
|
-
return !!def.values?.includes(undefined);
|
|
4398
|
-
case "enum":
|
|
4399
|
-
return !!schema._zod.values?.has(undefined);
|
|
4400
|
-
case "optional":
|
|
4401
|
-
case "nullable":
|
|
4402
|
-
case "readonly":
|
|
4403
|
-
case "success":
|
|
4404
|
-
return def.innerType ? fastPathAcceptsAbsence(def.innerType) : true;
|
|
4405
|
-
case "catch":
|
|
4406
|
-
return true;
|
|
4407
|
-
case "union":
|
|
4408
|
-
return def.options ? def.options.some(fastPathAcceptsAbsence) : true;
|
|
4409
|
-
case "intersection":
|
|
4410
|
-
if (!def.left || !def.right)
|
|
4411
|
-
return true;
|
|
4412
|
-
return fastPathAcceptsAbsence(def.left) && fastPathAcceptsAbsence(def.right);
|
|
4413
|
-
case "pipe":
|
|
4414
|
-
return def.in ? fastPathAcceptsAbsence(def.in) : true;
|
|
4415
|
-
default:
|
|
4416
|
-
return true;
|
|
4417
|
-
}
|
|
4418
|
-
}
|
|
4419
|
-
function dropsWhenAbsent(schema) {
|
|
4420
|
-
return schema._zod.optin === "optional" && schema._zod.optout === "optional";
|
|
4421
|
-
}
|
|
4422
|
-
function mayOmitUndefined(schema) {
|
|
4423
|
-
return (schema._zod.optin !== "defaulted" || schema._zod.optout === "optional") && mayOutputUndefined(schema);
|
|
4424
|
-
}
|
|
4425
|
-
function mayOutputUndefined(schema) {
|
|
4426
|
-
const def = schema._zod.def;
|
|
4427
|
-
switch (def.type) {
|
|
4428
|
-
case "string":
|
|
4429
|
-
case "number":
|
|
4430
|
-
case "boolean":
|
|
4431
|
-
case "bigint":
|
|
4432
|
-
case "symbol":
|
|
4433
|
-
case "null":
|
|
4434
|
-
case "nan":
|
|
4435
|
-
case "date":
|
|
4436
|
-
case "object":
|
|
4437
|
-
case "array":
|
|
4438
|
-
case "tuple":
|
|
4439
|
-
case "record":
|
|
4440
|
-
case "map":
|
|
4441
|
-
case "set":
|
|
4442
|
-
case "file":
|
|
4443
|
-
case "template_literal":
|
|
4444
|
-
case "never":
|
|
4445
|
-
case "success":
|
|
4446
|
-
return false;
|
|
4447
|
-
case "literal":
|
|
4448
|
-
return !!def.values?.includes(undefined);
|
|
4449
|
-
case "enum":
|
|
4450
|
-
return !!schema._zod.values?.has(undefined);
|
|
4451
|
-
case "optional":
|
|
4452
|
-
return true;
|
|
4453
|
-
case "nullable":
|
|
4454
|
-
case "readonly":
|
|
4455
|
-
case "nonoptional":
|
|
4456
|
-
return def.innerType ? mayOutputUndefined(def.innerType) : true;
|
|
4457
|
-
case "union":
|
|
4458
|
-
return def.options ? def.options.some(mayOutputUndefined) : true;
|
|
4459
|
-
case "intersection":
|
|
4460
|
-
return !def.left || !def.right || mayOutputUndefined(def.left) || mayOutputUndefined(def.right);
|
|
4461
|
-
case "pipe":
|
|
4462
|
-
return def.out ? mayOutputUndefined(def.out) : true;
|
|
4463
|
-
default:
|
|
4464
|
-
return true;
|
|
4465
|
-
}
|
|
4466
|
-
}
|
|
4467
|
-
function generateNullableCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4468
|
-
const def = schema._zod.def;
|
|
4469
|
-
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
4470
|
-
if (outputVar)
|
|
4471
|
-
doc.write(`let ${outputVar} = null;`);
|
|
4472
|
-
doc.write(`if (${accessor} !== null) {`);
|
|
4473
|
-
doc.indented((d) => {
|
|
4474
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor, buildsValue);
|
|
4475
|
-
if (outputVar && innerOutput !== null)
|
|
4476
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4477
|
-
});
|
|
4478
|
-
doc.write(`}`);
|
|
4479
|
-
return outputVar;
|
|
4480
|
-
}
|
|
4481
|
-
function generateArrayCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4482
|
-
const def = schema._zod.def;
|
|
4483
|
-
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
4484
|
-
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
4485
|
-
const iVar = newVar(ctx);
|
|
4486
|
-
const elemVar = newVar(ctx);
|
|
4487
|
-
if (outputVar)
|
|
4488
|
-
doc.write(`const ${outputVar} = new Array(${accessor}.length);`);
|
|
4489
|
-
doc.write(`for (let ${iVar} = 0; ${iVar} < ${accessor}.length; ${iVar}++) {`);
|
|
4490
|
-
doc.indented((d) => {
|
|
4491
|
-
d.write(`const ${elemVar} = ${accessor}[${iVar}];`);
|
|
4492
|
-
const elemOutput = compileChild(d, ctx, def.element, elemVar, buildsValue);
|
|
4493
|
-
if (outputVar && elemOutput !== null)
|
|
4494
|
-
d.write(`${outputVar}[${iVar}] = ${elemOutput};`);
|
|
4495
|
-
});
|
|
4496
|
-
doc.write(`}`);
|
|
4497
|
-
return outputVar;
|
|
4498
|
-
}
|
|
4499
|
-
function generateLiteralCheck(doc, ctx, schema, accessor) {
|
|
4500
|
-
const def = schema._zod.def;
|
|
4501
|
-
const values = def.values;
|
|
4502
|
-
if (values.length !== 1) {
|
|
4503
|
-
const literalSet = addConstant(ctx, new Set(values));
|
|
4504
|
-
doc.write(`if (!${literalSet}.has(${accessor})) return INVALID;`);
|
|
4505
|
-
return accessor;
|
|
4506
|
-
}
|
|
4507
|
-
const value = values[0];
|
|
4508
|
-
if (typeof value === "number" && Number.isNaN(value)) {
|
|
4509
|
-
const literalSet = addConstant(ctx, new Set(values));
|
|
4510
|
-
doc.write(`if (!${literalSet}.has(${accessor})) return INVALID;`);
|
|
4511
|
-
return accessor;
|
|
4512
|
-
}
|
|
4513
|
-
if (typeof value === "string") {
|
|
4514
|
-
doc.write(`if (${accessor} !== ${esc(value)}) return INVALID;`);
|
|
4515
|
-
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
4516
|
-
doc.write(`if (${accessor} !== ${value}) return INVALID;`);
|
|
4517
|
-
} else if (value === null) {
|
|
4518
|
-
doc.write(`if (${accessor} !== null) return INVALID;`);
|
|
4519
|
-
} else if (value === undefined) {
|
|
4520
|
-
doc.write(`if (${accessor} !== undefined) return INVALID;`);
|
|
4521
|
-
} else if (typeof value === "bigint") {
|
|
4522
|
-
doc.write(`if (${accessor} !== ${value}n) return INVALID;`);
|
|
4523
|
-
} else {
|
|
4524
|
-
throw new ZodCompileUnsupportedError(`literal type ${typeof value}`);
|
|
4525
|
-
}
|
|
4526
|
-
return accessor;
|
|
4527
|
-
}
|
|
4528
|
-
function generateEnumCheck(doc, ctx, schema, accessor) {
|
|
4529
|
-
const values = schema._zod.values;
|
|
4530
|
-
if (!values) {
|
|
4531
|
-
throw new ZodCompileUnsupportedError("enum schema without enumerated values");
|
|
4532
|
-
}
|
|
4533
|
-
const enumSet = addConstant(ctx, values);
|
|
4534
|
-
doc.write(`if (!${enumSet}.has(${accessor})) return INVALID;`);
|
|
4535
|
-
return accessor;
|
|
4536
|
-
}
|
|
4537
|
-
function generateWrapperCheck(doc, ctx, schema, accessor) {
|
|
4538
|
-
const def = schema._zod.def;
|
|
4539
|
-
return generateCheck(doc, ctx, def.innerType, accessor);
|
|
4540
|
-
}
|
|
4541
|
-
function generateDefaultCheck(doc, ctx, schema, accessor) {
|
|
4542
|
-
const def = schema._zod.def;
|
|
4543
|
-
const descriptor = Object.getOwnPropertyDescriptor(schema._zod.def, "defaultValue");
|
|
4544
|
-
const defaultGetter = descriptor ? () => schema._zod.def.defaultValue : undefined;
|
|
4545
|
-
if (schema._zod.def.type === "prefault") {
|
|
4546
|
-
if (!defaultGetter) {
|
|
4547
|
-
return generateCheck(doc, ctx, def.innerType, accessor);
|
|
4548
|
-
}
|
|
4549
|
-
const defaultFn = addConstant(ctx, defaultGetter);
|
|
4550
|
-
const inputVar = newVar(ctx);
|
|
4551
|
-
doc.write(`let ${inputVar} = ${accessor};`);
|
|
4552
|
-
doc.write(`if (${accessor} === undefined) ${inputVar} = ${defaultFn}();`);
|
|
4553
|
-
return generateCheck(doc, ctx, def.innerType, inputVar);
|
|
4554
|
-
}
|
|
4555
|
-
const outputVar = newVar(ctx);
|
|
4556
|
-
if (defaultGetter) {
|
|
4557
|
-
const defaultFn = addConstant(ctx, defaultGetter);
|
|
4558
|
-
const cloneFn = addConstant(ctx, shallowClone);
|
|
4559
|
-
doc.write(`let ${outputVar};`);
|
|
4560
|
-
doc.write(`if (${accessor} === undefined) {`);
|
|
4561
|
-
doc.indented((d) => {
|
|
4562
|
-
d.write(`${outputVar} = ${cloneFn}(${defaultFn}());`);
|
|
4563
|
-
});
|
|
4564
|
-
doc.write(`} else {`);
|
|
4565
|
-
doc.indented((d) => {
|
|
4566
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor);
|
|
4567
|
-
d.write(`${outputVar} = ${innerOutput} === undefined ? ${cloneFn}(${defaultFn}()) : ${innerOutput};`);
|
|
4568
|
-
});
|
|
4569
|
-
doc.write(`}`);
|
|
4570
|
-
} else {
|
|
4571
|
-
doc.write(`let ${outputVar};`);
|
|
4572
|
-
doc.write(`if (${accessor} !== undefined) {`);
|
|
4573
|
-
doc.indented((d) => {
|
|
4574
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor);
|
|
4575
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4576
|
-
});
|
|
4577
|
-
doc.write(`}`);
|
|
4578
|
-
}
|
|
4579
|
-
return outputVar;
|
|
4580
|
-
}
|
|
4581
|
-
function generateNonOptionalCheck(doc, ctx, schema, accessor) {
|
|
4582
|
-
const def = schema._zod.def;
|
|
4583
|
-
const innerOutput = generateCheck(doc, ctx, def.innerType, accessor);
|
|
4584
|
-
const outputVar = newVar(ctx);
|
|
4585
|
-
doc.write(`const ${outputVar} = ${innerOutput};`);
|
|
4586
|
-
doc.write(`if (${outputVar} === undefined) return INVALID;`);
|
|
4587
|
-
return outputVar;
|
|
4588
|
-
}
|
|
4589
|
-
function generateTupleCheck(doc, ctx, schema, accessor) {
|
|
4590
|
-
const def = schema._zod.def;
|
|
4591
|
-
const items = def.items;
|
|
4592
|
-
const rest = def.rest;
|
|
4593
|
-
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
4594
|
-
const optinStart = getTupleOptStart(items, "optin");
|
|
4595
|
-
const optoutStart = getTupleOptStart(items, "optout");
|
|
4596
|
-
if (rest) {
|
|
4597
|
-
doc.write(`if (${accessor}.length < ${optinStart}) return INVALID;`);
|
|
4598
|
-
} else {
|
|
4599
|
-
doc.write(`if (${accessor}.length < ${optinStart} || ${accessor}.length > ${items.length}) return INVALID;`);
|
|
4600
|
-
}
|
|
4601
|
-
const outputVar = newVar(ctx);
|
|
4602
|
-
doc.write(`const ${outputVar} = [];`);
|
|
4603
|
-
for (let i = 0;i < items.length; i++) {
|
|
4604
|
-
const itemSchema = items[i];
|
|
4605
|
-
if (i >= optoutStart) {
|
|
4606
|
-
doc.write(`if (${outputVar}.length === ${i}) {`);
|
|
4607
|
-
doc.indented((d) => {
|
|
4608
|
-
d.write(`if (${i} < ${accessor}.length) {`);
|
|
4609
|
-
d.indented((d2) => {
|
|
4610
|
-
const elemVar = newVar(ctx);
|
|
4611
|
-
d2.write(`const ${elemVar} = ${accessor}[${i}];`);
|
|
4612
|
-
const elemOutput = compileChild(d2, ctx, itemSchema, elemVar);
|
|
4613
|
-
d2.write(`${outputVar}[${i}] = ${elemOutput};`);
|
|
4614
|
-
});
|
|
4615
|
-
d.write(`} else {`);
|
|
4616
|
-
d.indented((d2) => {
|
|
4617
|
-
if (dropsWhenAbsent(itemSchema)) {
|
|
4618
|
-
d2.write(`${outputVar}.length = ${i};`);
|
|
4619
|
-
return;
|
|
4620
|
-
}
|
|
4621
|
-
const elemVar = newVar(ctx);
|
|
4622
|
-
const branchVar = newVar(ctx);
|
|
4623
|
-
d2.write(`const ${elemVar} = undefined;`);
|
|
4624
|
-
d2.write(`const ${branchVar} = (() => {`);
|
|
4625
|
-
d2.indented((d3) => {
|
|
4626
|
-
const elemOutput = compileChild(d3, ctx, itemSchema, elemVar);
|
|
4627
|
-
d3.write(`return ${elemOutput};`);
|
|
4628
|
-
});
|
|
4629
|
-
d2.write(`})();`);
|
|
4630
|
-
d2.write(`if (${branchVar} === INVALID || ${branchVar} === undefined) ${outputVar}.length = ${i};`);
|
|
4631
|
-
d2.write(`else ${outputVar}[${i}] = ${branchVar};`);
|
|
4632
|
-
});
|
|
4633
|
-
d.write(`}`);
|
|
4634
|
-
});
|
|
4635
|
-
doc.write(`}`);
|
|
4636
|
-
} else {
|
|
4637
|
-
const elemVar = newVar(ctx);
|
|
4638
|
-
doc.write(`const ${elemVar} = ${accessor}[${i}];`);
|
|
4639
|
-
const elemOutput = compileChild(doc, ctx, itemSchema, elemVar);
|
|
4640
|
-
doc.write(`${outputVar}[${i}] = ${elemOutput};`);
|
|
4641
|
-
}
|
|
4642
|
-
}
|
|
4643
|
-
if (rest) {
|
|
4644
|
-
const iVar = newVar(ctx);
|
|
4645
|
-
const elemVar = newVar(ctx);
|
|
4646
|
-
doc.write(`for (let ${iVar} = ${items.length}; ${iVar} < ${accessor}.length; ${iVar}++) {`);
|
|
4647
|
-
doc.indented((d) => {
|
|
4648
|
-
d.write(`const ${elemVar} = ${accessor}[${iVar}];`);
|
|
4649
|
-
const elemOutput = compileChild(d, ctx, rest, elemVar);
|
|
4650
|
-
d.write(`${outputVar}[${iVar}] = ${elemOutput};`);
|
|
4651
|
-
});
|
|
4652
|
-
doc.write(`}`);
|
|
4653
|
-
}
|
|
4654
|
-
return outputVar;
|
|
4655
|
-
}
|
|
4656
|
-
function getTupleOptStart(items, key) {
|
|
4657
|
-
for (let i = items.length - 1;i >= 0; i--) {
|
|
4658
|
-
const omittable = key === "optin" ? items[i]._zod.optin !== undefined : items[i]._zod.optout === "optional";
|
|
4659
|
-
if (!omittable)
|
|
4660
|
-
return i + 1;
|
|
3357
|
+
// node_modules/zod/v4/core/registries.js
|
|
3358
|
+
var _a2;
|
|
3359
|
+
class $ZodRegistry {
|
|
3360
|
+
constructor() {
|
|
3361
|
+
this._map = new WeakMap;
|
|
3362
|
+
this._idmap = new Map;
|
|
4661
3363
|
}
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
if (def.discriminator) {
|
|
4668
|
-
return generateDiscriminatedUnionCheck(doc, ctx, def, accessor);
|
|
4669
|
-
}
|
|
4670
|
-
if (def.inclusive === false) {
|
|
4671
|
-
throw new ZodCompileUnsupportedError("exclusive unions (z.xor)");
|
|
4672
|
-
}
|
|
4673
|
-
if (options.length === 0) {
|
|
4674
|
-
doc.write("return INVALID;");
|
|
4675
|
-
return accessor;
|
|
4676
|
-
}
|
|
4677
|
-
if (options.length === 1) {
|
|
4678
|
-
return generateCheck(doc, ctx, options[0], accessor);
|
|
4679
|
-
}
|
|
4680
|
-
const allLiterals = options.every((opt) => opt._zod.def.type === "literal" && !opt._zod.def.checks?.length);
|
|
4681
|
-
if (allLiterals) {
|
|
4682
|
-
const values = new Set(options.flatMap((opt) => opt._zod.def.values));
|
|
4683
|
-
const valuesConst = addConstant(ctx, values);
|
|
4684
|
-
doc.write(`if (!${valuesConst}.has(${accessor})) return INVALID;`);
|
|
4685
|
-
return accessor;
|
|
4686
|
-
}
|
|
4687
|
-
const outputVar = newVar(ctx);
|
|
4688
|
-
doc.write(`let ${outputVar};`);
|
|
4689
|
-
for (let i = 0;i < options.length; i++) {
|
|
4690
|
-
const opt = options[i];
|
|
4691
|
-
if (i === 0) {
|
|
4692
|
-
doc.write(`${outputVar} = (() => {`);
|
|
4693
|
-
} else {
|
|
4694
|
-
doc.write(`if (${outputVar} === INVALID) ${outputVar} = (() => {`);
|
|
3364
|
+
add(schema, ..._meta) {
|
|
3365
|
+
const meta = _meta[0];
|
|
3366
|
+
this._map.set(schema, meta);
|
|
3367
|
+
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3368
|
+
this._idmap.set(meta.id, schema);
|
|
4695
3369
|
}
|
|
4696
|
-
|
|
4697
|
-
const branchOutput = generateCheck(d, ctx, opt, accessor);
|
|
4698
|
-
d.write(`return ${branchOutput};`);
|
|
4699
|
-
});
|
|
4700
|
-
doc.write(`})();`);
|
|
4701
|
-
}
|
|
4702
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
4703
|
-
return outputVar;
|
|
4704
|
-
}
|
|
4705
|
-
function generateDiscriminatedUnionCheck(doc, ctx, def, accessor) {
|
|
4706
|
-
if (def.unionFallback) {
|
|
4707
|
-
throw new ZodCompileUnsupportedError("discriminated union with unionFallback");
|
|
3370
|
+
return this;
|
|
4708
3371
|
}
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
3372
|
+
clear() {
|
|
3373
|
+
this._map = new WeakMap;
|
|
3374
|
+
this._idmap = new Map;
|
|
3375
|
+
return this;
|
|
4712
3376
|
}
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
let firstBranch = true;
|
|
4718
|
-
const claimed = new Set;
|
|
4719
|
-
for (const option of def.options) {
|
|
4720
|
-
const values = option._zod.propValues?.[def.discriminator];
|
|
4721
|
-
if (!values || values.size === 0) {
|
|
4722
|
-
throw new ZodCompileUnsupportedError("discriminated union option without static discriminator values");
|
|
3377
|
+
remove(schema) {
|
|
3378
|
+
const meta = this._map.get(schema);
|
|
3379
|
+
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3380
|
+
this._idmap.delete(meta.id);
|
|
4723
3381
|
}
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
throw new ZodCompileUnsupportedError(`duplicate discriminator value ${String(value)}`);
|
|
4727
|
-
}
|
|
4728
|
-
claimed.add(value);
|
|
4729
|
-
}
|
|
4730
|
-
const conditions = Array.from(values, (value) => literalEquality(ctx, discVar, value));
|
|
4731
|
-
const prefix = firstBranch ? "if" : "else if";
|
|
4732
|
-
doc.write(`${prefix} (${conditions.join(" || ")}) {`);
|
|
4733
|
-
doc.indented((d) => {
|
|
4734
|
-
const branchOutput = generateCheck(d, ctx, option, accessor);
|
|
4735
|
-
d.write(`${outputVar} = ${branchOutput};`);
|
|
4736
|
-
});
|
|
4737
|
-
doc.write(`}`);
|
|
4738
|
-
firstBranch = false;
|
|
4739
|
-
}
|
|
4740
|
-
doc.write(`else { return INVALID; }`);
|
|
4741
|
-
return outputVar;
|
|
4742
|
-
}
|
|
4743
|
-
function literalEquality(ctx, accessor, value) {
|
|
4744
|
-
if (typeof value === "string")
|
|
4745
|
-
return `${accessor} === ${esc(value)}`;
|
|
4746
|
-
if (typeof value === "number") {
|
|
4747
|
-
if (Number.isNaN(value))
|
|
4748
|
-
return `Number.isNaN(${accessor})`;
|
|
4749
|
-
return `${accessor} === ${value}`;
|
|
4750
|
-
}
|
|
4751
|
-
if (typeof value === "boolean")
|
|
4752
|
-
return `${accessor} === ${value}`;
|
|
4753
|
-
if (value === null)
|
|
4754
|
-
return `${accessor} === null`;
|
|
4755
|
-
if (value === undefined)
|
|
4756
|
-
return `${accessor} === undefined`;
|
|
4757
|
-
if (typeof value === "bigint")
|
|
4758
|
-
return `${accessor} === ${value}n`;
|
|
4759
|
-
if (typeof value === "symbol") {
|
|
4760
|
-
const symbolConst = addConstant(ctx, value);
|
|
4761
|
-
return `${accessor} === ${symbolConst}`;
|
|
4762
|
-
}
|
|
4763
|
-
throw new ZodCompileUnsupportedError(`literal discriminator value ${String(value)}`);
|
|
4764
|
-
}
|
|
4765
|
-
function generateIntersectionCheck(doc, ctx, schema, accessor) {
|
|
4766
|
-
const def = schema._zod.def;
|
|
4767
|
-
ctx.definite = false;
|
|
4768
|
-
const leftOutput = compileChild(doc, ctx, def.left, accessor);
|
|
4769
|
-
const rightOutput = compileChild(doc, ctx, def.right, accessor);
|
|
4770
|
-
const mergeConst = addConstant(ctx, mergeValues);
|
|
4771
|
-
const mergedVar = newVar(ctx);
|
|
4772
|
-
doc.write(`const ${mergedVar} = ${mergeConst}(${leftOutput}, ${rightOutput});`);
|
|
4773
|
-
doc.write(`if (!${mergedVar}.valid) return INVALID;`);
|
|
4774
|
-
return `${mergedVar}.data`;
|
|
4775
|
-
}
|
|
4776
|
-
function generateRecordCheck(doc, ctx, schema, accessor) {
|
|
4777
|
-
const def = schema._zod.def;
|
|
4778
|
-
const isPlainObjectConst = addConstant(ctx, isPlainObject);
|
|
4779
|
-
doc.write(`if (!${isPlainObjectConst}(${accessor})) return INVALID;`);
|
|
4780
|
-
const outputVar = newVar(ctx);
|
|
4781
|
-
const kVar = newVar(ctx);
|
|
4782
|
-
const valVar = newVar(ctx);
|
|
4783
|
-
doc.write(`const ${outputVar} = {};`);
|
|
4784
|
-
const recordDef = def;
|
|
4785
|
-
const keyValues = recordDef.partial ? undefined : def.keyType._zod.values;
|
|
4786
|
-
if (keyValues) {
|
|
4787
|
-
const inputKeys = [];
|
|
4788
|
-
for (const key of keyValues) {
|
|
4789
|
-
if (!(typeof key === "string" || typeof key === "number" || typeof key === "symbol")) {
|
|
4790
|
-
throw new ZodCompileUnsupportedError(`record key value ${String(key)}`);
|
|
4791
|
-
}
|
|
4792
|
-
const inputKey = typeof key === "number" ? key.toString() : key;
|
|
4793
|
-
if (inputKey === "__proto__") {
|
|
4794
|
-
throw new ZodCompileUnsupportedError('record key "__proto__"');
|
|
4795
|
-
}
|
|
4796
|
-
inputKeys.push(inputKey);
|
|
4797
|
-
const keyConst = addConstant(ctx, key);
|
|
4798
|
-
const outKey = generateCheck(doc, ctx, def.keyType, keyConst);
|
|
4799
|
-
const valueVar = newVar(ctx);
|
|
4800
|
-
doc.write(`const ${valueVar} = ${accessor}[${literalPropertyKey(ctx, inputKey)}];`);
|
|
4801
|
-
const valOutput = compileChild(doc, ctx, def.valueType, valueVar);
|
|
4802
|
-
doc.write(`${outputVar}[${outKey}] = ${valOutput};`);
|
|
4803
|
-
}
|
|
4804
|
-
const knownKeysConst = addConstant(ctx, new Set(inputKeys));
|
|
4805
|
-
doc.write(`for (const ${kVar} in ${accessor}) {`);
|
|
4806
|
-
doc.indented((d) => {
|
|
4807
|
-
d.write(`if (${knownKeysConst}.has(${kVar})) continue;`);
|
|
4808
|
-
if (recordDef.mode === "loose") {
|
|
4809
|
-
d.write(`if (${kVar} !== "__proto__") ${outputVar}[${kVar}] = ${accessor}[${kVar}];`);
|
|
4810
|
-
} else {
|
|
4811
|
-
d.write(`return INVALID;`);
|
|
4812
|
-
}
|
|
4813
|
-
});
|
|
4814
|
-
doc.write(`}`);
|
|
4815
|
-
return outputVar;
|
|
4816
|
-
}
|
|
4817
|
-
const keyDef = def.keyType._zod.def;
|
|
4818
|
-
const keyIsBareString = keyDef.type === "string" && keyDef.format === undefined && !keyDef.coerce && (keyDef.checks?.length ?? 0) === 0;
|
|
4819
|
-
if (!keyIsBareString) {
|
|
4820
|
-
const isLoose = def.mode === "loose";
|
|
4821
|
-
const keyFn = compileFn(def.keyType);
|
|
4822
|
-
if (keyFn.definite === false)
|
|
4823
|
-
ctx.definite = false;
|
|
4824
|
-
const keyFast = addConstant(ctx, keyFn);
|
|
4825
|
-
const numericConst = addConstant(ctx, number);
|
|
4826
|
-
const outKeyVar = newVar(ctx);
|
|
4827
|
-
emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
|
|
4828
|
-
d.write(`let ${outKeyVar} = ${keyFast}(${kVar});`);
|
|
4829
|
-
d.write(`if (${outKeyVar} === INVALID && typeof ${kVar} === "string" && ${numericConst}.test(${kVar})) ${outKeyVar} = ${keyFast}(Number(${kVar}));`);
|
|
4830
|
-
if (isLoose) {
|
|
4831
|
-
d.write(`if (${outKeyVar} === INVALID) { ${outputVar}[${kVar}] = ${accessor}[${kVar}]; continue; }`);
|
|
4832
|
-
} else {
|
|
4833
|
-
d.write(`if (${outKeyVar} === INVALID) return INVALID;`);
|
|
4834
|
-
}
|
|
4835
|
-
d.write(`if (${outKeyVar} === "__proto__") continue;`);
|
|
4836
|
-
const valueVar = newVar(ctx);
|
|
4837
|
-
d.write(`const ${valueVar} = ${accessor}[${kVar}];`);
|
|
4838
|
-
const valOutput = compileChild(d, ctx, def.valueType, valueVar);
|
|
4839
|
-
d.write(`${outputVar}[${outKeyVar}] = ${valOutput};`);
|
|
4840
|
-
});
|
|
4841
|
-
return outputVar;
|
|
4842
|
-
}
|
|
4843
|
-
emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
|
|
4844
|
-
d.write(`const ${valVar} = ${accessor}[${kVar}];`);
|
|
4845
|
-
const valOutput = compileChild(d, ctx, def.valueType, valVar);
|
|
4846
|
-
d.write(`${outputVar}[${kVar}] = ${valOutput};`);
|
|
4847
|
-
}, `return INVALID;`);
|
|
4848
|
-
return outputVar;
|
|
4849
|
-
}
|
|
4850
|
-
function emitOwnKeys(doc, ctx, accessor, kVar, body, onSymbol) {
|
|
4851
|
-
const propIsEnumerableConst = addConstant(ctx, Object.prototype.propertyIsEnumerable);
|
|
4852
|
-
const symsVar = newVar(ctx);
|
|
4853
|
-
const keysVar = newVar(ctx);
|
|
4854
|
-
const iVar = newVar(ctx);
|
|
4855
|
-
doc.write(`const ${symsVar} = Object.getOwnPropertySymbols(${accessor});`);
|
|
4856
|
-
doc.write(`const ${keysVar} = Object.getOwnPropertyNames(${accessor});`);
|
|
4857
|
-
doc.write(`for (let ${iVar} = 0; ${iVar} < ${keysVar}.length; ${iVar}++) {`);
|
|
4858
|
-
doc.indented((d) => {
|
|
4859
|
-
d.write(`const ${kVar} = ${keysVar}[${iVar}];`);
|
|
4860
|
-
d.write(`if (${kVar} === "__proto__" || !${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
|
|
4861
|
-
body(d);
|
|
4862
|
-
});
|
|
4863
|
-
doc.write(`}`);
|
|
4864
|
-
doc.write(`for (let ${iVar} = 0; ${iVar} < ${symsVar}.length; ${iVar}++) {`);
|
|
4865
|
-
doc.indented((d) => {
|
|
4866
|
-
d.write(`const ${kVar} = ${symsVar}[${iVar}];`);
|
|
4867
|
-
d.write(`if (!${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
|
|
4868
|
-
if (onSymbol)
|
|
4869
|
-
d.write(onSymbol);
|
|
4870
|
-
else
|
|
4871
|
-
body(d);
|
|
4872
|
-
});
|
|
4873
|
-
doc.write(`}`);
|
|
4874
|
-
}
|
|
4875
|
-
function literalPropertyKey(ctx, key) {
|
|
4876
|
-
if (typeof key === "string")
|
|
4877
|
-
return esc(key);
|
|
4878
|
-
return addConstant(ctx, key);
|
|
4879
|
-
}
|
|
4880
|
-
function generateMapCheck(doc, ctx, schema, accessor) {
|
|
4881
|
-
const def = schema._zod.def;
|
|
4882
|
-
doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
|
|
4883
|
-
const outputVar = newVar(ctx);
|
|
4884
|
-
const kVar = newVar(ctx);
|
|
4885
|
-
const valVar = newVar(ctx);
|
|
4886
|
-
doc.write(`const ${outputVar} = new Map();`);
|
|
4887
|
-
doc.write(`for (const [${kVar}, ${valVar}] of ${accessor}) {`);
|
|
4888
|
-
doc.indented((d) => {
|
|
4889
|
-
const keyOutput = generateCheck(d, ctx, def.keyType, kVar);
|
|
4890
|
-
const valOutput = generateCheck(d, ctx, def.valueType, valVar);
|
|
4891
|
-
d.write(`${outputVar}.set(${keyOutput}, ${valOutput});`);
|
|
4892
|
-
});
|
|
4893
|
-
doc.write(`}`);
|
|
4894
|
-
return outputVar;
|
|
4895
|
-
}
|
|
4896
|
-
function generateSetCheck(doc, ctx, schema, accessor) {
|
|
4897
|
-
const def = schema._zod.def;
|
|
4898
|
-
doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
|
|
4899
|
-
const outputVar = newVar(ctx);
|
|
4900
|
-
const valVar = newVar(ctx);
|
|
4901
|
-
doc.write(`const ${outputVar} = new Set();`);
|
|
4902
|
-
doc.write(`for (const ${valVar} of ${accessor}) {`);
|
|
4903
|
-
doc.indented((d) => {
|
|
4904
|
-
const valOutput = generateCheck(d, ctx, def.valueType, valVar);
|
|
4905
|
-
d.write(`${outputVar}.add(${valOutput});`);
|
|
4906
|
-
});
|
|
4907
|
-
doc.write(`}`);
|
|
4908
|
-
return outputVar;
|
|
4909
|
-
}
|
|
4910
|
-
function generateFileCheck(doc, accessor) {
|
|
4911
|
-
doc.write(`if (!(${accessor} instanceof File)) return INVALID;`);
|
|
4912
|
-
return accessor;
|
|
4913
|
-
}
|
|
4914
|
-
function generateTemplateLiteralCheck(doc, ctx, schema, accessor) {
|
|
4915
|
-
doc.write(`if (typeof ${accessor} !== "string") return INVALID;`);
|
|
4916
|
-
const pattern = schema._zod.pattern;
|
|
4917
|
-
if (pattern) {
|
|
4918
|
-
const patternConst = addConstant(ctx, pattern);
|
|
4919
|
-
doc.write(`${patternConst}.lastIndex = 0;`);
|
|
4920
|
-
doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);
|
|
3382
|
+
this._map.delete(schema);
|
|
3383
|
+
return this;
|
|
4921
3384
|
}
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
d.write(`${cacheConst}.parser = function(input) {`);
|
|
4932
|
-
d.indented((d2) => {
|
|
4933
|
-
d2.write(`const result = inner._zod.run({ value: input, issues: [] }, {});`);
|
|
4934
|
-
d2.write(`return result.issues.length === 0 ? result.value : INVALID;`);
|
|
4935
|
-
});
|
|
4936
|
-
d.write(`};`);
|
|
4937
|
-
});
|
|
4938
|
-
doc.write(`}`);
|
|
4939
|
-
const outputVar = newVar(ctx);
|
|
4940
|
-
doc.write(`const ${outputVar} = ${cacheConst}.parser(${accessor});`);
|
|
4941
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
4942
|
-
return outputVar;
|
|
4943
|
-
}
|
|
4944
|
-
function generatePipeCheck(doc, ctx, schema, accessor) {
|
|
4945
|
-
const def = schema._zod.def;
|
|
4946
|
-
const inputOutput = generateCheck(doc, ctx, def.in, accessor);
|
|
4947
|
-
if (def.transform) {
|
|
4948
|
-
if (isAsyncFunction(def.transform)) {
|
|
4949
|
-
throw new ZodCompileAsyncError("z.compile: async transforms in pipes are not supported");
|
|
4950
|
-
}
|
|
4951
|
-
const transformFn = def.transform;
|
|
4952
|
-
const helperFn = (value) => {
|
|
4953
|
-
const fakePayload = { value, issues: [], addIssue: pushIssue };
|
|
4954
|
-
const result = transformFn(value, fakePayload);
|
|
4955
|
-
if (result instanceof Promise)
|
|
4956
|
-
return INVALID;
|
|
4957
|
-
return fakePayload.issues.length === 0 ? result : INVALID;
|
|
4958
|
-
};
|
|
4959
|
-
const helperConst = addUserConstant(ctx, helperFn);
|
|
4960
|
-
const transformedVar = newVar(ctx);
|
|
4961
|
-
doc.write(`const ${transformedVar} = ${helperConst}(${inputOutput});`);
|
|
4962
|
-
doc.write(`if (${transformedVar} === INVALID) return INVALID;`);
|
|
4963
|
-
return generateCheck(doc, ctx, def.out, transformedVar);
|
|
4964
|
-
} else {
|
|
4965
|
-
return generateCheck(doc, ctx, def.out, inputOutput);
|
|
3385
|
+
get(schema) {
|
|
3386
|
+
const p = schema._zod.parent;
|
|
3387
|
+
if (p) {
|
|
3388
|
+
const pm = { ...this.get(p) ?? {} };
|
|
3389
|
+
delete pm.id;
|
|
3390
|
+
const f = { ...pm, ...this._map.get(schema) };
|
|
3391
|
+
return Object.keys(f).length ? f : undefined;
|
|
3392
|
+
}
|
|
3393
|
+
return this._map.get(schema);
|
|
4966
3394
|
}
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
return typeof fn === "function" && (fn.constructor.name === "AsyncFunction" || fn[Symbol.toStringTag] === "AsyncFunction");
|
|
4970
|
-
}
|
|
4971
|
-
function generateCustomCheck(doc, ctx, schema, accessor) {
|
|
4972
|
-
const def = schema._zod.def;
|
|
4973
|
-
if (def.fn) {
|
|
4974
|
-
if (isAsyncFunction(def.fn)) {
|
|
4975
|
-
throw new ZodCompileAsyncError("z.compile: async custom predicates are not supported");
|
|
4976
|
-
}
|
|
4977
|
-
const fnConst = addUserConstant(ctx, def.fn);
|
|
4978
|
-
const throwAsyncConst = addConstant(ctx, throwAsync);
|
|
4979
|
-
const resVar = newVar(ctx);
|
|
4980
|
-
doc.write(`const ${resVar} = ${fnConst}(${accessor});`);
|
|
4981
|
-
doc.write(`if (${resVar} instanceof Promise) ${throwAsyncConst}();`);
|
|
4982
|
-
doc.write(`if (!${resVar}) return INVALID;`);
|
|
4983
|
-
} else {
|
|
4984
|
-
throw new ZodCompileUnsupportedError("custom schema without a predicate function");
|
|
3395
|
+
has(schema) {
|
|
3396
|
+
return this._map.has(schema);
|
|
4985
3397
|
}
|
|
4986
|
-
return accessor;
|
|
4987
3398
|
}
|
|
4988
|
-
function
|
|
4989
|
-
|
|
4990
|
-
if (result && typeof result.then === "function")
|
|
4991
|
-
return INVALID;
|
|
4992
|
-
const r = result;
|
|
4993
|
-
if (r.issues.length === 0)
|
|
4994
|
-
return r.value;
|
|
4995
|
-
return catchValue();
|
|
4996
|
-
}
|
|
4997
|
-
function generateCatchCheck(doc, ctx, schema, accessor) {
|
|
4998
|
-
const def = schema._zod.def;
|
|
4999
|
-
if (!def.catchValue[CONSTANT_CATCH]) {
|
|
5000
|
-
throw new ZodCompileUnsupportedError("catch with a callback (only a constant catch value compiles)", false);
|
|
5001
|
-
}
|
|
5002
|
-
const outputVar = newVar(ctx);
|
|
5003
|
-
doc.write(`let ${outputVar} = (() => {`);
|
|
5004
|
-
doc.indented((d) => {
|
|
5005
|
-
const innerOut = compileChild(d, ctx, def.innerType, accessor);
|
|
5006
|
-
d.write(`return ${innerOut};`);
|
|
5007
|
-
});
|
|
5008
|
-
doc.write(`})();`);
|
|
5009
|
-
const innerConst = addConstant(ctx, def.innerType);
|
|
5010
|
-
const catchConst = addUserConstant(ctx, def.catchValue);
|
|
5011
|
-
const catchHelperConst = addConstant(ctx, runtimeCatch);
|
|
5012
|
-
doc.write(`if (${outputVar} === INVALID) {`);
|
|
5013
|
-
doc.indented((d) => {
|
|
5014
|
-
d.write(`${outputVar} = ${catchHelperConst}(${innerConst}, ${catchConst}, ${accessor});`);
|
|
5015
|
-
d.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
5016
|
-
});
|
|
5017
|
-
doc.write(`}`);
|
|
5018
|
-
return outputVar;
|
|
5019
|
-
}
|
|
5020
|
-
function generateTransformCheck(doc, ctx, schema, accessor) {
|
|
5021
|
-
const def = schema._zod.def;
|
|
5022
|
-
if (def.transform) {
|
|
5023
|
-
if (isAsyncFunction(def.transform)) {
|
|
5024
|
-
throw new ZodCompileAsyncError("z.compile: async transforms are not supported");
|
|
5025
|
-
}
|
|
5026
|
-
const transformFn = def.transform;
|
|
5027
|
-
const helperFn = (value) => {
|
|
5028
|
-
const fakePayload = { value, issues: [], addIssue: pushIssue };
|
|
5029
|
-
const result = transformFn(value, fakePayload);
|
|
5030
|
-
if (result instanceof Promise)
|
|
5031
|
-
return INVALID;
|
|
5032
|
-
return fakePayload.issues.length === 0 ? result : INVALID;
|
|
5033
|
-
};
|
|
5034
|
-
const helperConst = addUserConstant(ctx, helperFn);
|
|
5035
|
-
const outputVar = newVar(ctx);
|
|
5036
|
-
doc.write(`const ${outputVar} = ${helperConst}(${accessor});`);
|
|
5037
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
5038
|
-
return outputVar;
|
|
5039
|
-
}
|
|
5040
|
-
return accessor;
|
|
3399
|
+
function registry() {
|
|
3400
|
+
return new $ZodRegistry;
|
|
5041
3401
|
}
|
|
3402
|
+
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
|
|
3403
|
+
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
5042
3404
|
// node_modules/zod/v4/core/api.js
|
|
5043
3405
|
function snapshotChecks(def) {
|
|
5044
3406
|
if (def.checks)
|
|
@@ -7519,15 +5881,6 @@ function superRefine(fn, params) {
|
|
|
7519
5881
|
// packages/workit-core/src/core/task-contract.ts
|
|
7520
5882
|
var SCHEMA_VERSION = 1;
|
|
7521
5883
|
var POLICY_VERSION = "1.0.0";
|
|
7522
|
-
var OPERATION_FAMILIES = [
|
|
7523
|
-
"task",
|
|
7524
|
-
"policy",
|
|
7525
|
-
"evidence",
|
|
7526
|
-
"finding",
|
|
7527
|
-
"decision",
|
|
7528
|
-
"worker",
|
|
7529
|
-
"state"
|
|
7530
|
-
];
|
|
7531
5884
|
var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
7532
5885
|
var digestPattern = /^[0-9a-f]{64}$/;
|
|
7533
5886
|
var invalidUnicode = (value) => {
|
|
@@ -8263,7 +6616,6 @@ var advertisedOperationSchemas = {
|
|
|
8263
6616
|
worker: advertised(workerOperations),
|
|
8264
6617
|
state: advertised(stateOperations)
|
|
8265
6618
|
};
|
|
8266
|
-
var compiledOperationSchemas = Object.fromEntries(OPERATION_FAMILIES.map((family) => [family, compile(operationSchemas[family])]));
|
|
8267
6619
|
var success = (revisionValue, workspaceRevisionValue, data) => ({
|
|
8268
6620
|
ok: true,
|
|
8269
6621
|
schemaVersion: 1,
|
|
@@ -8285,8 +6637,7 @@ function resolveIdRef(kind, ref, ids) {
|
|
|
8285
6637
|
function parseOperation(family, input) {
|
|
8286
6638
|
if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
|
|
8287
6639
|
return failure2("unsupported_version", "unsupported schema version", { operation: family });
|
|
8288
|
-
const
|
|
8289
|
-
const parsed = compiled.success ? operationSchemas[family].safeParse(input) : compiled;
|
|
6640
|
+
const parsed = operationSchemas[family].safeParse(input);
|
|
8290
6641
|
if (parsed.success)
|
|
8291
6642
|
return success(null, null, parsed.data);
|
|
8292
6643
|
const fields = parsed.error.issues.map((issue) => ({
|
|
@@ -19602,6 +17953,24 @@ function workitInvocations(command, dialect = "posix", depth = 0) {
|
|
|
19602
17953
|
}
|
|
19603
17954
|
return found;
|
|
19604
17955
|
}
|
|
17956
|
+
var WORKIT_GLOBAL = /^--(?:cwd|session|token|as)(=|$)/;
|
|
17957
|
+
function skipWorkitGlobals(args) {
|
|
17958
|
+
let cwd = null;
|
|
17959
|
+
let at = 0;
|
|
17960
|
+
for (;at < args.length; at++) {
|
|
17961
|
+
const match = WORKIT_GLOBAL.exec(args[at]);
|
|
17962
|
+
if (match?.[1] === "=") {
|
|
17963
|
+
if (args[at].startsWith("--cwd="))
|
|
17964
|
+
cwd = args[at].slice(6);
|
|
17965
|
+
} else if (match && args[at + 1] !== undefined) {
|
|
17966
|
+
if (args[at] === "--cwd")
|
|
17967
|
+
cwd = args[at + 1];
|
|
17968
|
+
at++;
|
|
17969
|
+
} else if (args[at] !== "--json")
|
|
17970
|
+
break;
|
|
17971
|
+
}
|
|
17972
|
+
return { rest: args.slice(at), cwd };
|
|
17973
|
+
}
|
|
19605
17974
|
var PUSH_VALUE_OPTIONS = new Set(["-o", "--push-option", "--receive-pack", "--exec", "--repo"]);
|
|
19606
17975
|
var CURRENT_BRANCH = /^\$\(\s*git\s+(?:branch\s+--show-current|rev-parse\s+--abbrev-ref\s+HEAD|symbolic-ref\s+--short\s+HEAD)\s*\)$/;
|
|
19607
17976
|
var pushDestination = (destination) => {
|
|
@@ -21423,7 +19792,7 @@ var splitDenial = (plan) => ({
|
|
|
21423
19792
|
unblock: plan.unblock
|
|
21424
19793
|
});
|
|
21425
19794
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
21426
|
-
import { realpathSync as realpathSync5 } from "node:fs";
|
|
19795
|
+
import { existsSync as existsSync7, realpathSync as realpathSync5 } from "node:fs";
|
|
21427
19796
|
import os10 from "node:os";
|
|
21428
19797
|
import path27 from "node:path";
|
|
21429
19798
|
|
|
@@ -21652,7 +20021,7 @@ var exempt = (cwd, root, file, plans) => {
|
|
|
21652
20021
|
const segments = posix.split("/");
|
|
21653
20022
|
return /\.mdx?$/i.test(posix) || segments[0] === "docs" || segments.includes("plans") || [...plans].some((plan) => fold(plan) === posix);
|
|
21654
20023
|
};
|
|
21655
|
-
var PREFIXES2 = new Set(["sudo", "command", "env", "nohup", "time", "exec", "xargs"]);
|
|
20024
|
+
var PREFIXES2 = new Set(["sudo", "command", "env", "nohup", "time", "exec", "xargs", "busybox"]);
|
|
21656
20025
|
var operands = (words) => words.filter((item) => !item.startsWith("-"));
|
|
21657
20026
|
var SCRIPT_SHELLS = new Set(["sh", "bash", "zsh", "dash", "ksh"]);
|
|
21658
20027
|
var wrappedScript = (input) => {
|
|
@@ -21664,9 +20033,9 @@ var wrappedScript = (input) => {
|
|
|
21664
20033
|
return null;
|
|
21665
20034
|
if ("script" in tail)
|
|
21666
20035
|
return tail.script;
|
|
21667
|
-
const
|
|
21668
|
-
if (SCRIPT_SHELLS.has((
|
|
21669
|
-
return script
|
|
20036
|
+
const script = shellScript2(tail.argv);
|
|
20037
|
+
if (SCRIPT_SHELLS.has((tail.argv[0]?.split(/[\\/]/).at(-1) ?? "").toLowerCase()) && script)
|
|
20038
|
+
return script;
|
|
21670
20039
|
return tail.argv.map(quoteWord2).join(" ");
|
|
21671
20040
|
};
|
|
21672
20041
|
var editsOf = (input) => {
|
|
@@ -21745,6 +20114,94 @@ var editsOf = (input) => {
|
|
|
21745
20114
|
return [];
|
|
21746
20115
|
}
|
|
21747
20116
|
};
|
|
20117
|
+
var shellScript2 = (words) => {
|
|
20118
|
+
if (!SCRIPT_SHELLS.has((words[0]?.split(/[\\/]/).at(-1) ?? "").toLowerCase()))
|
|
20119
|
+
return null;
|
|
20120
|
+
for (let index = 1;index < words.length; index++) {
|
|
20121
|
+
const word = words[index];
|
|
20122
|
+
if (/^-[a-z]*c$/.test(word))
|
|
20123
|
+
return words[index + 1] ?? null;
|
|
20124
|
+
if (/^[-+][oO]$/.test(word))
|
|
20125
|
+
index++;
|
|
20126
|
+
else if (!/^[-+]/.test(word))
|
|
20127
|
+
return null;
|
|
20128
|
+
}
|
|
20129
|
+
return null;
|
|
20130
|
+
};
|
|
20131
|
+
var XARGS_VALUE = /^-[IinLPdsEa]$/;
|
|
20132
|
+
var runsWriter = (words) => {
|
|
20133
|
+
const filled = [...words.filter((word) => word !== "{}" && word !== ";" && word !== "+"), "x"];
|
|
20134
|
+
const edits = editsOf(filled);
|
|
20135
|
+
return edits === null || edits.length > 0 || opaqueWrites(filled) !== null;
|
|
20136
|
+
};
|
|
20137
|
+
var opaqueWrites = (input) => {
|
|
20138
|
+
let words = input;
|
|
20139
|
+
while (words.length && (PREFIXES2.has(words[0]) || /^\w+=/.test(words[0]))) {
|
|
20140
|
+
if (words[0] === "xargs") {
|
|
20141
|
+
let at = 1;
|
|
20142
|
+
while (words[at]?.startsWith("-"))
|
|
20143
|
+
at += XARGS_VALUE.test(words[at]) ? 2 : 1;
|
|
20144
|
+
return runsWriter(words.slice(at)) ? ["."] : null;
|
|
20145
|
+
}
|
|
20146
|
+
words = words.slice(1);
|
|
20147
|
+
}
|
|
20148
|
+
const [verb, ...args] = words;
|
|
20149
|
+
const name = (verb?.split(/[\\/]/).at(-1) ?? "").toLowerCase();
|
|
20150
|
+
const files = operands(args);
|
|
20151
|
+
const has = (pattern) => args.some((arg) => pattern.test(arg));
|
|
20152
|
+
const listed = (named) => named.length ? named : ["."];
|
|
20153
|
+
if (name === "unlink" || name === "shred")
|
|
20154
|
+
return listed(files);
|
|
20155
|
+
if (/^(?:chmod|chown|chgrp|chattr)$/.test(name))
|
|
20156
|
+
return listed(has(/^--reference/) ? files : files.slice(1));
|
|
20157
|
+
if (name === "rsync") {
|
|
20158
|
+
const dest = files.at(-1);
|
|
20159
|
+
const remote = /^[\w.@-]*:/.test(dest ?? "") && !/^[A-Za-z]:[\\/]/.test(dest ?? "");
|
|
20160
|
+
return dest === undefined ? ["."] : remote ? [] : [dest];
|
|
20161
|
+
}
|
|
20162
|
+
if (name === "find") {
|
|
20163
|
+
const exec = args.findIndex((arg) => /^-(?:exec|execdir|ok|okdir)$/.test(arg));
|
|
20164
|
+
const writes = has(/^-(?:delete|fprint\w*|fls)$/) || exec >= 0 && runsWriter(args.slice(exec + 1));
|
|
20165
|
+
const end = args.findIndex((arg) => /^[-(!]/.test(arg));
|
|
20166
|
+
return writes ? listed(end < 0 ? args : args.slice(0, end)) : null;
|
|
20167
|
+
}
|
|
20168
|
+
if (/^g?awk$/.test(name)) {
|
|
20169
|
+
if (!has(/^-i|^--include/))
|
|
20170
|
+
return null;
|
|
20171
|
+
const named = [];
|
|
20172
|
+
let program = !has(/^-f$|^--file/);
|
|
20173
|
+
for (let index = 0;index < args.length; index++)
|
|
20174
|
+
if (/^(?:-[ifvF]|--(?:include|file|assign|field-separator))$/.test(args[index]))
|
|
20175
|
+
index++;
|
|
20176
|
+
else if (args[index].startsWith("-"))
|
|
20177
|
+
continue;
|
|
20178
|
+
else if (program)
|
|
20179
|
+
program = false;
|
|
20180
|
+
else
|
|
20181
|
+
named.push(args[index]);
|
|
20182
|
+
return listed(named);
|
|
20183
|
+
}
|
|
20184
|
+
if (name === "perl")
|
|
20185
|
+
return has(/^-[a-zA-Z]*[eE]/) ? ["."] : null;
|
|
20186
|
+
if (/^(?:python[\d.]*|node|bun|deno|ruby|php)$/.test(name))
|
|
20187
|
+
return has(/^-[a-zA-Z]*[ce]$|^--eval$|^-p$/) ? ["."] : null;
|
|
20188
|
+
return shellScript2(words) === null ? null : ["."];
|
|
20189
|
+
};
|
|
20190
|
+
var linkSources = (args, at) => {
|
|
20191
|
+
const names = operands([...args]);
|
|
20192
|
+
const into = args.indexOf("-t");
|
|
20193
|
+
const dest = into >= 0 ? args[into + 1] : names.length > 1 ? names.at(-1) : ".";
|
|
20194
|
+
const sources = names.filter((name, index) => into >= 0 ? name !== dest : index < names.length - 1 || names.length === 1);
|
|
20195
|
+
const target = dest === undefined ? null : at(dest);
|
|
20196
|
+
const symbolic = args.some((arg) => /^-[a-zA-Z]*s|^--symbolic$/.test(arg));
|
|
20197
|
+
const base = target === null ? null : into >= 0 || sources.length > 1 || existsSync7(target) || /[\\/]$/.test(dest ?? "") ? target : path27.dirname(target);
|
|
20198
|
+
return sources.flatMap((source) => {
|
|
20199
|
+
if (symbolic && base !== null && !path27.isAbsolute(homeExpanded(source)))
|
|
20200
|
+
return [path27.resolve(base, source)];
|
|
20201
|
+
const resolved = at(source);
|
|
20202
|
+
return resolved ? [resolved] : [];
|
|
20203
|
+
});
|
|
20204
|
+
};
|
|
21748
20205
|
var shellWrites = (command, depth = 0) => {
|
|
21749
20206
|
const targets = [];
|
|
21750
20207
|
let unknown = false;
|
|
@@ -21854,11 +20311,15 @@ var gitMutationDirs = (cwd, command, dialect) => {
|
|
|
21854
20311
|
var CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
21855
20312
|
var PUSHD2 = new Set(["pushd", "push-location"]);
|
|
21856
20313
|
var POPD2 = new Set(["popd", "pop-location"]);
|
|
21857
|
-
var
|
|
20314
|
+
var UNKNOWN_DIR = path27.resolve(path27.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
20315
|
+
var cdInto = (dir, words, strict = false) => {
|
|
20316
|
+
const lost = strict ? UNKNOWN_DIR : undefined;
|
|
21858
20317
|
const named = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
|
|
21859
20318
|
const target = named === undefined ? undefined : homeExpanded(named);
|
|
21860
|
-
if (
|
|
21861
|
-
return;
|
|
20319
|
+
if (target === "-" || target && /^~|[$`*?]/.test(target))
|
|
20320
|
+
return lost;
|
|
20321
|
+
if (dir === undefined)
|
|
20322
|
+
return lost;
|
|
21862
20323
|
return target === undefined ? os10.homedir() : path27.resolve(dir, target);
|
|
21863
20324
|
};
|
|
21864
20325
|
var quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`;
|
|
@@ -21866,7 +20327,7 @@ var homeExpanded = (file) => {
|
|
|
21866
20327
|
const match = /^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(file);
|
|
21867
20328
|
return match ? (process.env.HOME || os10.homedir()) + file.slice(match[0].length) : file;
|
|
21868
20329
|
};
|
|
21869
|
-
var segmentTargets = (cwd, command, dialect, depth = 0) => {
|
|
20330
|
+
var segmentTargets = (cwd, command, dialect, depth = 0, strict = false) => {
|
|
21870
20331
|
const targets = [];
|
|
21871
20332
|
let dir = cwd;
|
|
21872
20333
|
let stack = [];
|
|
@@ -21890,21 +20351,35 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
|
|
|
21890
20351
|
const words = lead < 0 ? [] : segment.words.slice(lead);
|
|
21891
20352
|
const name = (words[0]?.split(/[\\/]/).at(-1) ?? "").toLowerCase();
|
|
21892
20353
|
if (CD2.has(name)) {
|
|
21893
|
-
dir = cdInto(dir, words);
|
|
20354
|
+
dir = cdInto(dir, words, strict);
|
|
21894
20355
|
continue;
|
|
21895
20356
|
}
|
|
21896
20357
|
if (PUSHD2.has(name)) {
|
|
21897
20358
|
stack.push(dir);
|
|
21898
|
-
dir = cdInto(dir, words);
|
|
20359
|
+
dir = cdInto(dir, words, strict);
|
|
21899
20360
|
continue;
|
|
21900
20361
|
}
|
|
21901
20362
|
if (POPD2.has(name)) {
|
|
21902
|
-
dir = stack.length ? stack.pop() : undefined;
|
|
20363
|
+
dir = stack.length ? stack.pop() : strict ? UNKNOWN_DIR : undefined;
|
|
21903
20364
|
continue;
|
|
21904
20365
|
}
|
|
21905
|
-
const inner = depth < 4 ? wrappedScript(words) : null;
|
|
20366
|
+
const inner = depth < 4 ? wrappedScript(words) ?? (strict ? shellScript2(words) : null) : null;
|
|
21906
20367
|
if (inner !== null && dir !== undefined)
|
|
21907
|
-
targets.push(...segmentTargets(dir, inner, "posix", depth + 1));
|
|
20368
|
+
targets.push(...segmentTargets(dir, inner, "posix", depth + 1, strict));
|
|
20369
|
+
if (strict && dir !== undefined) {
|
|
20370
|
+
const runIn = dir;
|
|
20371
|
+
for (const sub of depth < 4 ? segment.subs ?? [] : [])
|
|
20372
|
+
targets.push(...segmentTargets(runIn, sub, dialect, depth + 1, true));
|
|
20373
|
+
const opaque = segment.unanalyzable ? ["."] : inner === null ? opaqueWrites(words) : null;
|
|
20374
|
+
for (const file of opaque ?? []) {
|
|
20375
|
+
const resolved = at(file);
|
|
20376
|
+
if (resolved)
|
|
20377
|
+
targets.push(file === "." ? path27.join(resolved, DIR_TARGET) : resolved);
|
|
20378
|
+
}
|
|
20379
|
+
const ln = words.findIndex((word) => /^ln$/i.test(word.split(/[\\/]/).at(-1) ?? ""));
|
|
20380
|
+
if (ln >= 0 && words.slice(0, ln).every((word) => PREFIXES2.has(word)))
|
|
20381
|
+
targets.push(...linkSources(words.slice(ln + 1), at));
|
|
20382
|
+
}
|
|
21908
20383
|
for (const file of segment.redirects)
|
|
21909
20384
|
if (!/^\/dev\/(?:null|stdout|stderr|tty)$/.test(file)) {
|
|
21910
20385
|
const resolved = at(file);
|
|
@@ -21921,11 +20396,29 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
|
|
|
21921
20396
|
if (resolved)
|
|
21922
20397
|
targets.push(resolved);
|
|
21923
20398
|
}
|
|
21924
|
-
if (dir !== undefined
|
|
21925
|
-
|
|
20399
|
+
if (dir !== undefined)
|
|
20400
|
+
for (const invocation of workitInvocations(segment.words.map(quoteWord2).join(" "), "posix")) {
|
|
20401
|
+
const { at: runsIn, args } = workitCwd(dir, invocation);
|
|
20402
|
+
if (args[0] === "git" && MUTATING_WORKIT_GIT.has(args[1] ?? "") && !inert(args.slice(2), ""))
|
|
20403
|
+
targets.push(path27.join(runsIn, DIR_TARGET));
|
|
20404
|
+
}
|
|
21926
20405
|
}
|
|
21927
20406
|
return targets;
|
|
21928
20407
|
};
|
|
20408
|
+
var workitCwd = (dir, args) => {
|
|
20409
|
+
const { rest, cwd } = skipWorkitGlobals(args);
|
|
20410
|
+
return { at: cwd === null ? dir : path27.resolve(dir, homeExpanded(cwd)), args: rest };
|
|
20411
|
+
};
|
|
20412
|
+
var shellMutationTargets = (cwd, command, dialect = "posix", strict = false) => {
|
|
20413
|
+
try {
|
|
20414
|
+
return [
|
|
20415
|
+
...segmentTargets(cwd, command, dialect, 0, strict),
|
|
20416
|
+
...gitMutationDirs(cwd, command, dialect).map((dir) => path27.join(dir, DIR_TARGET))
|
|
20417
|
+
];
|
|
20418
|
+
} catch {
|
|
20419
|
+
return [];
|
|
20420
|
+
}
|
|
20421
|
+
};
|
|
21929
20422
|
var overridden = (command, dialect) => {
|
|
21930
20423
|
const segments = segmentsOf(command, dialect);
|
|
21931
20424
|
if (segments.length !== 1 || segments[0].group || segments[0].subs?.length)
|
|
@@ -22031,16 +20524,8 @@ function shellGate(cwd, command, owner, dialect = "posix", deps) {
|
|
|
22031
20524
|
} catch {}
|
|
22032
20525
|
const writes = shellWrites(command);
|
|
22033
20526
|
let targets = [];
|
|
22034
|
-
if (owner)
|
|
22035
|
-
|
|
22036
|
-
targets = [
|
|
22037
|
-
...segmentTargets(cwd, command, dialect),
|
|
22038
|
-
...gitMutationDirs(cwd, command, dialect).map((dir) => path27.join(dir, DIR_TARGET))
|
|
22039
|
-
];
|
|
22040
|
-
} catch {
|
|
22041
|
-
targets = [];
|
|
22042
|
-
}
|
|
22043
|
-
}
|
|
20527
|
+
if (owner)
|
|
20528
|
+
targets = shellMutationTargets(cwd, command, dialect);
|
|
22044
20529
|
if (owner && targets.length) {
|
|
22045
20530
|
const live = liveGate(owner, targets, deps);
|
|
22046
20531
|
if (live.kind !== "none") {
|
|
@@ -22507,13 +20992,13 @@ ${line}` };
|
|
|
22507
20992
|
return decision;
|
|
22508
20993
|
};
|
|
22509
20994
|
// packages/workit-core/src/hooks/hosts/fields.ts
|
|
22510
|
-
import { existsSync as
|
|
20995
|
+
import { existsSync as existsSync8, realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
|
|
22511
20996
|
import path28 from "node:path";
|
|
22512
20997
|
var isRecord6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
22513
20998
|
var nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "";
|
|
22514
20999
|
var optionalText = (value) => typeof value === "string" ? value : null;
|
|
22515
21000
|
var existingDirectory = (value) => {
|
|
22516
|
-
if (!nonEmpty2(value) || !path28.isAbsolute(value) || !
|
|
21001
|
+
if (!nonEmpty2(value) || !path28.isAbsolute(value) || !existsSync8(value))
|
|
22517
21002
|
return null;
|
|
22518
21003
|
try {
|
|
22519
21004
|
return statSync2(value).isDirectory() ? realpathSync6(value) : null;
|
|
@@ -22716,9 +21201,266 @@ var cwdRewrite = (command) => {
|
|
|
22716
21201
|
return `workit --cwd ${dir} ${rest.slice("workit".length).trimStart()}`.trimEnd();
|
|
22717
21202
|
};
|
|
22718
21203
|
|
|
21204
|
+
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
21205
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
21206
|
+
import fs23 from "node:fs";
|
|
21207
|
+
import path30 from "node:path";
|
|
21208
|
+
var FANOUT_TOKEN_FILE = "workit-fanout-token";
|
|
21209
|
+
var NONE5 = { kind: "none" };
|
|
21210
|
+
var CASE_INSENSITIVE2 = process.platform === "darwin" || process.platform === "win32";
|
|
21211
|
+
var canonical3 = (file) => {
|
|
21212
|
+
let rest = "";
|
|
21213
|
+
for (let dir = path30.resolve(file);; dir = path30.dirname(dir)) {
|
|
21214
|
+
try {
|
|
21215
|
+
return path30.join(fs23.realpathSync.native(dir), rest);
|
|
21216
|
+
} catch {
|
|
21217
|
+
if (path30.dirname(dir) === dir)
|
|
21218
|
+
return path30.resolve(file);
|
|
21219
|
+
rest = rest ? path30.join(path30.basename(dir), rest) : path30.basename(dir);
|
|
21220
|
+
}
|
|
21221
|
+
}
|
|
21222
|
+
};
|
|
21223
|
+
var within = (child, parent) => {
|
|
21224
|
+
const fold = (value) => CASE_INSENSITIVE2 ? value.toLowerCase() : value;
|
|
21225
|
+
const relative = path30.relative(fold(parent), fold(child));
|
|
21226
|
+
return relative === "" || !relative.startsWith("..") && !path30.isAbsolute(relative);
|
|
21227
|
+
};
|
|
21228
|
+
var checkoutOf2 = (file) => {
|
|
21229
|
+
for (let dir = canonical3(file);; dir = path30.dirname(dir)) {
|
|
21230
|
+
const dotGit = path30.join(dir, ".git");
|
|
21231
|
+
if (fs23.existsSync(dotGit)) {
|
|
21232
|
+
if (!fs23.statSync(dotGit).isFile())
|
|
21233
|
+
return { root: dir, workit: false };
|
|
21234
|
+
const admin = /^gitdir:\s*(.+)$/mu.exec(fs23.readFileSync(dotGit, "utf8"))?.[1]?.trim();
|
|
21235
|
+
return {
|
|
21236
|
+
root: dir,
|
|
21237
|
+
workit: Boolean(admin) && fs23.existsSync(path30.join(path30.resolve(dir, admin), FANOUT_TOKEN_FILE))
|
|
21238
|
+
};
|
|
21239
|
+
}
|
|
21240
|
+
if (path30.dirname(dir) === dir)
|
|
21241
|
+
return null;
|
|
21242
|
+
}
|
|
21243
|
+
};
|
|
21244
|
+
var workitWorktreeOf = (file) => {
|
|
21245
|
+
try {
|
|
21246
|
+
const checkout = checkoutOf2(file);
|
|
21247
|
+
return checkout?.workit ? checkout.root : null;
|
|
21248
|
+
} catch {
|
|
21249
|
+
return null;
|
|
21250
|
+
}
|
|
21251
|
+
};
|
|
21252
|
+
var bindingDir = () => path30.join(resolveStateDir(), "worktree-bind");
|
|
21253
|
+
var bindingFile = (session, agentId) => path30.join(bindingDir(), `${createHash17("sha256").update(`${session}\x00${agentId}`).digest("hex").slice(0, 32)}.json`);
|
|
21254
|
+
var readBinding = (file) => {
|
|
21255
|
+
try {
|
|
21256
|
+
const value = JSON.parse(fs23.readFileSync(file, "utf8"));
|
|
21257
|
+
return typeof value.worktree === "string" ? value : null;
|
|
21258
|
+
} catch {
|
|
21259
|
+
return null;
|
|
21260
|
+
}
|
|
21261
|
+
};
|
|
21262
|
+
var boundWorktree = (input) => {
|
|
21263
|
+
const agentId = input.session.agentId;
|
|
21264
|
+
if (!agentId)
|
|
21265
|
+
return null;
|
|
21266
|
+
const binding = readBinding(bindingFile(input.session.id, agentId));
|
|
21267
|
+
return binding && workitWorktreeOf(binding.worktree) === binding.worktree ? binding.worktree : null;
|
|
21268
|
+
};
|
|
21269
|
+
var bind = (input, worktree) => {
|
|
21270
|
+
const agentId = input.session.agentId;
|
|
21271
|
+
const file = bindingFile(input.session.id, agentId);
|
|
21272
|
+
const binding = {
|
|
21273
|
+
worktree,
|
|
21274
|
+
session: input.session.id,
|
|
21275
|
+
agentId,
|
|
21276
|
+
at: new Date().toISOString()
|
|
21277
|
+
};
|
|
21278
|
+
fs23.mkdirSync(path30.dirname(file), { recursive: true });
|
|
21279
|
+
fs23.writeFileSync(file, JSON.stringify(binding));
|
|
21280
|
+
try {
|
|
21281
|
+
if (inWorkitWorkspace(input.cwd))
|
|
21282
|
+
appendHookObserved(input.cwd, {
|
|
21283
|
+
type: "worktree.bound",
|
|
21284
|
+
actor: { host: input.host, session: input.session.id, agentId },
|
|
21285
|
+
agentType: input.session.agentType,
|
|
21286
|
+
worktree
|
|
21287
|
+
});
|
|
21288
|
+
} catch {}
|
|
21289
|
+
};
|
|
21290
|
+
var hostIsolated = (cwd, agentId) => {
|
|
21291
|
+
try {
|
|
21292
|
+
if (agentId === null)
|
|
21293
|
+
return false;
|
|
21294
|
+
const checkout = checkoutOf2(cwd);
|
|
21295
|
+
if (!checkout)
|
|
21296
|
+
return false;
|
|
21297
|
+
const dotGit = path30.join(checkout.root, ".git");
|
|
21298
|
+
if (!fs23.statSync(dotGit).isFile())
|
|
21299
|
+
return false;
|
|
21300
|
+
const admin = /^gitdir:\s*(.+)$/mu.exec(fs23.readFileSync(dotGit, "utf8"))?.[1]?.trim();
|
|
21301
|
+
if (!admin)
|
|
21302
|
+
return false;
|
|
21303
|
+
const adminDir = path30.resolve(checkout.root, admin);
|
|
21304
|
+
const back = fs23.readFileSync(path30.join(adminDir, "gitdir"), "utf8").trim();
|
|
21305
|
+
if (path30.relative(canonical3(path30.resolve(adminDir, back)), canonical3(dotGit)) !== "")
|
|
21306
|
+
return false;
|
|
21307
|
+
const common = path30.join(adminDir, "commondir");
|
|
21308
|
+
const gitDir = fs23.existsSync(common) ? path30.resolve(adminDir, fs23.readFileSync(common, "utf8").trim()) : adminDir;
|
|
21309
|
+
const expected = path30.join(path30.dirname(canonical3(gitDir)), ".claude", "worktrees", `agent-${agentId}`);
|
|
21310
|
+
return path30.relative(canonical3(expected), checkout.root) === "";
|
|
21311
|
+
} catch {
|
|
21312
|
+
return false;
|
|
21313
|
+
}
|
|
21314
|
+
};
|
|
21315
|
+
var shown = (target) => path30.basename(target) === ".workit-live-target" ? path30.dirname(target) : target;
|
|
21316
|
+
var unboundDeny = (input, target) => {
|
|
21317
|
+
const unblock = "Work only in the worktree your brief names, which the lead made with `workit fanout worktree create <slice>`: edit files under it and run one verb per call against it (`workit --cwd <worktree> git commit -m … -- <paths>`, `workit --cwd <worktree> check <name>`). If your brief names no worktree, stop and report that to the lead.";
|
|
21318
|
+
return {
|
|
21319
|
+
kind: "deny",
|
|
21320
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} is not working in a Workit worktree yet, and ${shown(target)} is outside every worktree \`workit fanout worktree create\` made, so it would change the lead's checkout. ${unblock}`,
|
|
21321
|
+
unblock
|
|
21322
|
+
};
|
|
21323
|
+
};
|
|
21324
|
+
var outsideDeny = (input, worktree, target) => {
|
|
21325
|
+
const unblock = `Edit only under ${worktree} and run git there, one verb per call: \`workit --cwd ${worktree} git commit -m … -- <paths>\`, \`workit --cwd ${worktree} check <name>\` (or \`git -C ${worktree} …\`); a command whose writes Workit cannot see is judged by the directory it runs in. Anything outside it is a follow-up for your report.`;
|
|
21326
|
+
return {
|
|
21327
|
+
kind: "deny",
|
|
21328
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} is bound to the worktree ${worktree}, and ${shown(target)} is outside it. ${unblock}`,
|
|
21329
|
+
unblock
|
|
21330
|
+
};
|
|
21331
|
+
};
|
|
21332
|
+
var unknownDirDeny = (input, worktree) => {
|
|
21333
|
+
const wt = worktree ?? "<worktree>";
|
|
21334
|
+
const unblock = `Workit cannot resolve \`cd -\`, \`cd "$X"\` or \`popd\`: write by absolute path, \`git -C ${wt}\` or \`workit --cwd ${wt}\`.`;
|
|
21335
|
+
return {
|
|
21336
|
+
kind: "deny",
|
|
21337
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} writes after an unknown directory change. ${unblock}`,
|
|
21338
|
+
unblock
|
|
21339
|
+
};
|
|
21340
|
+
};
|
|
21341
|
+
function confineImplementer(input, targets) {
|
|
21342
|
+
try {
|
|
21343
|
+
if (!input.session.agentId || hostIsolated(input.cwd, input.session.agentId))
|
|
21344
|
+
return NONE5;
|
|
21345
|
+
if (targets.some((target) => within(path30.resolve(target), UNKNOWN_DIR)))
|
|
21346
|
+
return unknownDirDeny(input, boundWorktree(input));
|
|
21347
|
+
const bindings = canonical3(bindingDir());
|
|
21348
|
+
const judged = targets.map((named) => ({ named, real: canonical3(named) })).filter(({ real }) => within(real, bindings) || checkoutOf2(real) !== null);
|
|
21349
|
+
if (judged.length === 0)
|
|
21350
|
+
return NONE5;
|
|
21351
|
+
let worktree = boundWorktree(input);
|
|
21352
|
+
if (!worktree) {
|
|
21353
|
+
for (const { real } of judged) {
|
|
21354
|
+
worktree = within(real, bindings) ? null : workitWorktreeOf(real);
|
|
21355
|
+
if (worktree)
|
|
21356
|
+
break;
|
|
21357
|
+
}
|
|
21358
|
+
if (!worktree)
|
|
21359
|
+
return unboundDeny(input, judged[0].named);
|
|
21360
|
+
bind(input, worktree);
|
|
21361
|
+
}
|
|
21362
|
+
const root = canonical3(worktree);
|
|
21363
|
+
const outside = judged.find(({ real }) => !within(real, root) || within(real, bindings));
|
|
21364
|
+
return outside ? outsideDeny(input, worktree, outside.named) : NONE5;
|
|
21365
|
+
} catch {
|
|
21366
|
+
return NONE5;
|
|
21367
|
+
}
|
|
21368
|
+
}
|
|
21369
|
+
var MUTATING_REMOTE = new Set([
|
|
21370
|
+
"add",
|
|
21371
|
+
"remove",
|
|
21372
|
+
"rm",
|
|
21373
|
+
"rename",
|
|
21374
|
+
"set-url",
|
|
21375
|
+
"set-head",
|
|
21376
|
+
"set-branches",
|
|
21377
|
+
"prune"
|
|
21378
|
+
]);
|
|
21379
|
+
var CONFIG_READ = /^(?:--get(?:-all|-regexp|-urlmatch)?|--list|-l|get|list)$/;
|
|
21380
|
+
var CONFIG_WRITE = /^(?:--(?:unset(?:-all)?|add|replace-all|rename-section|remove-section|edit)|-e|set|unset|rename-section|remove-section|edit)$/;
|
|
21381
|
+
var CONFIG_VALUE = /^(?:--file|-f|--blob|--type|--default|--comment)$/;
|
|
21382
|
+
var leadOwnedGit = (args) => {
|
|
21383
|
+
const [sub = "", ...rest] = args;
|
|
21384
|
+
if (rest.some((arg) => arg === "--help" || arg === "-h"))
|
|
21385
|
+
return false;
|
|
21386
|
+
const names = rest.filter((arg) => !arg.startsWith("-"));
|
|
21387
|
+
const flag = (pattern) => rest.some((arg) => pattern.test(arg));
|
|
21388
|
+
switch (sub) {
|
|
21389
|
+
case "worktree":
|
|
21390
|
+
return names[0] !== undefined && names[0] !== "list";
|
|
21391
|
+
case "update-ref":
|
|
21392
|
+
return true;
|
|
21393
|
+
case "symbolic-ref":
|
|
21394
|
+
return names.length > 1 || flag(/^(?:-d|--delete)$/);
|
|
21395
|
+
case "branch":
|
|
21396
|
+
return flag(/^-[a-zA-Z]*[dDfmMcC]|^--(?:delete|force|move|copy)$/);
|
|
21397
|
+
case "tag":
|
|
21398
|
+
return flag(/^-[a-zA-Z]*[df]|^--(?:delete|force)$/);
|
|
21399
|
+
case "push": {
|
|
21400
|
+
if (flag(/^(?:-d|--delete|--mirror|--prune)$/))
|
|
21401
|
+
return true;
|
|
21402
|
+
const refspecs = names.slice(1);
|
|
21403
|
+
return refspecs.some((name) => name.includes(":") || name.startsWith("+")) || refspecs.length > 0 && flag(/^-[a-zA-Z]*f|^--force/);
|
|
21404
|
+
}
|
|
21405
|
+
case "replace":
|
|
21406
|
+
case "filter-branch":
|
|
21407
|
+
case "gc":
|
|
21408
|
+
case "prune":
|
|
21409
|
+
case "repack":
|
|
21410
|
+
case "sparse-checkout":
|
|
21411
|
+
return true;
|
|
21412
|
+
case "notes":
|
|
21413
|
+
case "reflog":
|
|
21414
|
+
case "submodule":
|
|
21415
|
+
return !/^(?:list|show|status|exists)$/.test(names[0] ?? "list");
|
|
21416
|
+
case "stash":
|
|
21417
|
+
return names[0] === "drop" || names[0] === "clear";
|
|
21418
|
+
case "remote":
|
|
21419
|
+
return MUTATING_REMOTE.has(names[0] ?? "");
|
|
21420
|
+
case "config": {
|
|
21421
|
+
if (rest.some((arg) => CONFIG_READ.test(arg)))
|
|
21422
|
+
return false;
|
|
21423
|
+
if (rest.some((arg) => CONFIG_WRITE.test(arg)))
|
|
21424
|
+
return true;
|
|
21425
|
+
let operands = 0;
|
|
21426
|
+
for (let index = 0;index < rest.length; index++)
|
|
21427
|
+
if (CONFIG_VALUE.test(rest[index]))
|
|
21428
|
+
index++;
|
|
21429
|
+
else if (!rest[index].startsWith("-"))
|
|
21430
|
+
operands++;
|
|
21431
|
+
return operands > 1;
|
|
21432
|
+
}
|
|
21433
|
+
default:
|
|
21434
|
+
return false;
|
|
21435
|
+
}
|
|
21436
|
+
};
|
|
21437
|
+
var leadOwnedWorkit = (args) => !args.includes("--help") && args.some((_, start) => {
|
|
21438
|
+
if (start > 0 && !/(?:^|[\\/])workit(?:\.exe|\.cmd)?$/.test(args[start - 1]))
|
|
21439
|
+
return false;
|
|
21440
|
+
const [verb, sub] = skipWorkitGlobals(args.slice(start)).rest;
|
|
21441
|
+
return verb === "fanout" && /^(?:plan|worktree)$/.test(sub ?? "");
|
|
21442
|
+
});
|
|
21443
|
+
var leadOwnedDeny = (input, command) => {
|
|
21444
|
+
const unblock = "Worktrees, branches other than your own, refs, tags, remotes, git config, the shared stash and the fan-out plan belong to the lead: report what you need changed as a follow-up instead.";
|
|
21445
|
+
return {
|
|
21446
|
+
kind: "deny",
|
|
21447
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} may not run \`${command.slice(0, 160)}\`. ${unblock}`,
|
|
21448
|
+
unblock
|
|
21449
|
+
};
|
|
21450
|
+
};
|
|
21451
|
+
function confineImplementerShell(input, command, dialect = "posix") {
|
|
21452
|
+
try {
|
|
21453
|
+
if (!input.session.agentId || hostIsolated(input.cwd, input.session.agentId))
|
|
21454
|
+
return NONE5;
|
|
21455
|
+
if (rawInvocations(command, dialect).some((invocation) => invocation.tool === "git" && leadOwnedGit(invocation.args)) || workitInvocations(command, dialect).some(leadOwnedWorkit))
|
|
21456
|
+
return leadOwnedDeny(input, command);
|
|
21457
|
+
} catch {}
|
|
21458
|
+
return confineImplementer(input, shellMutationTargets(input.cwd, command, dialect, true));
|
|
21459
|
+
}
|
|
21460
|
+
|
|
22719
21461
|
// packages/workit-core/src/hooks/handle.ts
|
|
22720
21462
|
var usable2 = (value) => value === "native" || value === "partial";
|
|
22721
|
-
var
|
|
21463
|
+
var NONE6 = { kind: "none" };
|
|
22722
21464
|
var resendsOnChange = (descriptor) => descriptor.context.turnResend === "on-change" && usable2(descriptor.context.perTurn);
|
|
22723
21465
|
var offered = new Set;
|
|
22724
21466
|
var ROLES = {
|
|
@@ -22731,6 +21473,7 @@ var workitRole = (descriptor, agentType) => {
|
|
|
22731
21473
|
const name = agentType.startsWith(prefix) ? agentType.slice(prefix.length) : "";
|
|
22732
21474
|
return Object.hasOwn(ROLES, name) ? ROLES[name] : null;
|
|
22733
21475
|
};
|
|
21476
|
+
var implementerAgent = (input, descriptor) => Boolean(input.session.agentId) && input.session.agentType !== null && workitRole(descriptor, input.session.agentType) === "implementer";
|
|
22734
21477
|
var subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128);
|
|
22735
21478
|
var CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
|
|
22736
21479
|
var isolatedGit = (cwd) => `Run git as plain, separate commands inside your worktree (\`git switch -c <branch> <base>\`, ${workspaceTrailers(cwd).enabled ? '`git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a prepare-commit-msg hook that adds the trailer' : "`git commit` (this workspace sets trailers: false: add no Workit-Session trailer), `git push`"}; add Co-Authored-By with \`git commit --trailer\` in the same commit, never by amending), never \`workit git …\`: Claude Code's worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (\`workit check\`, \`workit ledger\`, \`workit pr\`).`;
|
|
@@ -22738,7 +21481,7 @@ var subagentStartText = (input, descriptor, event) => {
|
|
|
22738
21481
|
const session = input.session.id ?? null;
|
|
22739
21482
|
const role = workitRole(descriptor, event.agentType);
|
|
22740
21483
|
const who = `${descriptor.label} subagent ${event.agentId} (${event.agentType})`;
|
|
22741
|
-
const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer"
|
|
21484
|
+
const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" ? hostIsolated(input.cwd, event.agentId) : CLAUDE_WORKTREE.test(input.cwd));
|
|
22742
21485
|
const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
|
|
22743
21486
|
if (role === "implementer" && isolated)
|
|
22744
21487
|
return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${isolatedGit(input.cwd)} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
|
|
@@ -22746,7 +21489,7 @@ var subagentStartText = (input, descriptor, event) => {
|
|
|
22746
21489
|
return `${isolatedGit(input.cwd)}
|
|
22747
21490
|
${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
|
|
22748
21491
|
if (role === "implementer")
|
|
22749
|
-
return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree (the lead makes
|
|
21492
|
+
return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree, the one its brief names (the lead makes it with \`workit fanout worktree create <slice>\` before spawning), never in the lead's checkout, within its brief's scope. Workit binds it to the first Workit worktree it changes: from then on an edit or a mutating git command outside that worktree is denied, and before then so is one outside every Workit worktree. Run Workit against the worktree one verb per call, never \`cd … &&\` chains or \`$VAR\` paths: \`workit --cwd <worktree> git commit -m "<message>" -- <paths>\`, \`workit --cwd <worktree> check <name>\`. The worktree is on the brief's branch once the lead made it; otherwise switch with \`workit --cwd <worktree> git branch <branch> --base <base>\` (or \`--kind <kind> --slug <slug>\`, which picks the base); branch policy hooks still deny protected or non-compliant branches, raw git included.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
|
|
22750
21493
|
const readOnly = `Workit observed ${who} as read-only/agent-guided.`;
|
|
22751
21494
|
if (role !== "judge" || !event.agentId)
|
|
22752
21495
|
return readOnly;
|
|
@@ -22777,7 +21520,7 @@ function decide(input, deps) {
|
|
|
22777
21520
|
switch (event.kind) {
|
|
22778
21521
|
case "session.start": {
|
|
22779
21522
|
if (!usable2(descriptor.context.sessionStart))
|
|
22780
|
-
return
|
|
21523
|
+
return NONE6;
|
|
22781
21524
|
const key = input.session.id ? `${input.host}\x00${input.session.id}` : null;
|
|
22782
21525
|
const offer = event.source === "startup" && (key === null || !offered.has(key));
|
|
22783
21526
|
if (offer && key !== null)
|
|
@@ -22792,26 +21535,31 @@ function decide(input, deps) {
|
|
|
22792
21535
|
}
|
|
22793
21536
|
case "context.turn": {
|
|
22794
21537
|
if (!usable2(descriptor.context.perTurn))
|
|
22795
|
-
return
|
|
21538
|
+
return NONE6;
|
|
22796
21539
|
const current = turnContextText(input, descriptor);
|
|
22797
21540
|
const text = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
|
|
22798
|
-
return withContextLine(text ? { kind: "context", text } :
|
|
21541
|
+
return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
|
|
22799
21542
|
}
|
|
22800
21543
|
case "shell.pre": {
|
|
22801
21544
|
const skillRead = skillReadIn(event.command, event.dialect);
|
|
22802
21545
|
if (skillRead)
|
|
22803
21546
|
recordSkillLoad(input, skillRead, "read");
|
|
22804
21547
|
const canDeny = usable2(descriptor.shellPolicy.deny);
|
|
22805
|
-
const policy = canDeny ? shellPolicy(input.cwd, event.command, event.dialect) :
|
|
21548
|
+
const policy = canDeny ? shellPolicy(input.cwd, event.command, event.dialect) : NONE6;
|
|
22806
21549
|
if (policy.kind !== "none")
|
|
22807
21550
|
return policy;
|
|
22808
21551
|
const postTool = usable2(descriptor.events["shell.post"].support);
|
|
22809
21552
|
if (!postTool)
|
|
22810
21553
|
settlePendingCommit(input);
|
|
22811
|
-
const raw = canDeny ? rawGitPre(input, event.command, { nudge: false }) :
|
|
21554
|
+
const raw = canDeny ? rawGitPre(input, event.command, { nudge: false }) : NONE6;
|
|
22812
21555
|
if (raw.kind === "deny")
|
|
22813
21556
|
return raw;
|
|
22814
|
-
|
|
21557
|
+
if (canDeny && implementerAgent(input, descriptor)) {
|
|
21558
|
+
const confined = confineImplementerShell(input, event.command, event.dialect);
|
|
21559
|
+
if (confined.kind === "deny")
|
|
21560
|
+
return confined;
|
|
21561
|
+
}
|
|
21562
|
+
const gate = usable2(descriptor.events["write.pre"].support) ? shellGate(input.cwd, event.command, liveOwner(input, descriptor.transport), event.dialect) : NONE6;
|
|
22815
21563
|
if (gate.kind === "deny")
|
|
22816
21564
|
return gate;
|
|
22817
21565
|
const plan = heavyGate(input.cwd, event.command, {
|
|
@@ -22834,10 +21582,10 @@ function decide(input, deps) {
|
|
|
22834
21582
|
command: rewrittenTo,
|
|
22835
21583
|
input: event.toolInput ? { ...event.toolInput, command: rewrittenTo } : null,
|
|
22836
21584
|
text
|
|
22837
|
-
} :
|
|
21585
|
+
} : NONE6;
|
|
22838
21586
|
if (descriptor.transport !== "hook-process")
|
|
22839
21587
|
return rewritten(null);
|
|
22840
|
-
const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) :
|
|
21588
|
+
const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) : NONE6, aside), shipNudge(input, event.command));
|
|
22841
21589
|
if (!lease)
|
|
22842
21590
|
return cwdCommand && nudged.kind !== "deny" ? rewritten(nudged.kind === "context" ? nudged.text : null) : nudged;
|
|
22843
21591
|
return rewritten([rewriteNote(lease), nudged.kind === "context" ? nudged.text : null].filter(Boolean).join(`
|
|
@@ -22846,9 +21594,17 @@ function decide(input, deps) {
|
|
|
22846
21594
|
case "shell.post":
|
|
22847
21595
|
if (usable2(descriptor.events["shell.post"].support))
|
|
22848
21596
|
rawGitPost(input, event.command, callKey(event.toolUseId, event.command));
|
|
22849
|
-
return
|
|
22850
|
-
case "write.pre":
|
|
22851
|
-
|
|
21597
|
+
return NONE6;
|
|
21598
|
+
case "write.pre": {
|
|
21599
|
+
if (!usable2(descriptor.events["write.pre"].support))
|
|
21600
|
+
return NONE6;
|
|
21601
|
+
if (implementerAgent(input, descriptor)) {
|
|
21602
|
+
const confined = confineImplementer(input, liveTargets(input.cwd, event.paths));
|
|
21603
|
+
if (confined.kind === "deny")
|
|
21604
|
+
return confined;
|
|
21605
|
+
}
|
|
21606
|
+
return writeGate(input.cwd, event.paths, liveOwner(input, descriptor.transport));
|
|
21607
|
+
}
|
|
22852
21608
|
case "subagent.start":
|
|
22853
21609
|
if (workitRole(descriptor, event.agentType) === "judge")
|
|
22854
21610
|
trackJudge(input, event.agentId, true);
|
|
@@ -22865,22 +21621,22 @@ function decide(input, deps) {
|
|
|
22865
21621
|
case "tool.pre":
|
|
22866
21622
|
if (event.skill)
|
|
22867
21623
|
recordSkillLoad(input, event.skill, "tool");
|
|
22868
|
-
return
|
|
21624
|
+
return NONE6;
|
|
22869
21625
|
case "stop":
|
|
22870
|
-
return usable2(descriptor.events.stop.support) ? stopDecision(input, descriptor) :
|
|
21626
|
+
return usable2(descriptor.events.stop.support) ? stopDecision(input, descriptor) : NONE6;
|
|
22871
21627
|
case "subagent.stop":
|
|
22872
21628
|
trackJudge(input, event.agentId, false);
|
|
22873
|
-
return
|
|
21629
|
+
return NONE6;
|
|
22874
21630
|
case "prompt.submit":
|
|
22875
|
-
return
|
|
21631
|
+
return NONE6;
|
|
22876
21632
|
}
|
|
22877
21633
|
}
|
|
22878
21634
|
var failureDecision = (descriptor, event, error) => {
|
|
22879
21635
|
if (event === "shell.pre" || event === "tool.pre" || event === "write.pre")
|
|
22880
|
-
return descriptor.shellPolicy.failClosed ? { kind: "deny", reason: error, unblock: null } :
|
|
21636
|
+
return descriptor.shellPolicy.failClosed ? { kind: "deny", reason: error, unblock: null } : NONE6;
|
|
22881
21637
|
if (event === "session.start" || event === "subagent.start")
|
|
22882
21638
|
return { kind: "context", text: `[workit diagnostic: ${error}]` };
|
|
22883
|
-
return
|
|
21639
|
+
return NONE6;
|
|
22884
21640
|
};
|
|
22885
21641
|
var dispatchHook = (adapter, raw, env = process.env) => {
|
|
22886
21642
|
const parsed = adapter.parse(raw, env);
|
|
@@ -22906,7 +21662,7 @@ var dispatchHook = (adapter, raw, env = process.env) => {
|
|
|
22906
21662
|
};
|
|
22907
21663
|
// packages/workit-core/src/hooks/deadline.ts
|
|
22908
21664
|
import { appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
|
|
22909
|
-
import
|
|
21665
|
+
import path31 from "node:path";
|
|
22910
21666
|
var HOOK_SKIP_TEXT = "workit context skipped: host under load";
|
|
22911
21667
|
var HOOK_DEADLINE_MS = 8000;
|
|
22912
21668
|
var HOST_DEADLINES = {
|
|
@@ -22924,7 +21680,7 @@ var hookDeadlineMs = (env, host = "", native) => {
|
|
|
22924
21680
|
const row = HOST_DEADLINES[host];
|
|
22925
21681
|
return override(env) ?? (row ? native === undefined ? Math.min(...Object.values(row)) : row[native] ?? row[""] : HOOK_DEADLINE_MS);
|
|
22926
21682
|
};
|
|
22927
|
-
var skipsFile = (stateDir) =>
|
|
21683
|
+
var skipsFile = (stateDir) => path31.join(stateDir, HOOK_SKIPS_FILE);
|
|
22928
21684
|
var recordHookSkip = (skip, stateDir = resolveStateDir()) => {
|
|
22929
21685
|
try {
|
|
22930
21686
|
mkdirSync3(stateDir, { recursive: true });
|
|
@@ -22942,7 +21698,7 @@ var QUIET = new Set([
|
|
|
22942
21698
|
]);
|
|
22943
21699
|
var skipDecision = (event) => QUIET.has(event) ? { kind: "none" } : { kind: "context", text: HOOK_SKIP_TEXT };
|
|
22944
21700
|
var TIMED_OUT = Symbol("timed out");
|
|
22945
|
-
var
|
|
21701
|
+
var within2 = async (work, ms) => {
|
|
22946
21702
|
let timer;
|
|
22947
21703
|
const expired = new Promise((resolve) => {
|
|
22948
21704
|
timer = setTimeout(() => resolve(TIMED_OUT), Math.max(0, ms));
|
|
@@ -22973,7 +21729,7 @@ var readWithin = async (stdin, budget) => {
|
|
|
22973
21729
|
text += String(chunk);
|
|
22974
21730
|
return text;
|
|
22975
21731
|
})();
|
|
22976
|
-
const text = await
|
|
21732
|
+
const text = await within2(read, budget.startedAt + budget.deadlineMs - budget.now());
|
|
22977
21733
|
return isTimedOut(text) ? null : text;
|
|
22978
21734
|
};
|
|
22979
21735
|
var note = (adapter, raw, env, budget, outcome, stage) => {
|
|
@@ -23002,7 +21758,7 @@ var dispatchWithin = async (adapter, raw, env, budget, dispatch = dispatchHook)
|
|
|
23002
21758
|
if (budget.host !== null && typeof native === "string")
|
|
23003
21759
|
budget.deadlineMs = hookDeadlineMs(env, budget.host, native);
|
|
23004
21760
|
const remaining = () => budget.startedAt + budget.deadlineMs - budget.now();
|
|
23005
|
-
const result = remaining() > 0 ? await
|
|
21761
|
+
const result = remaining() > 0 ? await within2(Promise.resolve().then(() => dispatch(adapter, raw, env)), remaining()) : TIMED_OUT;
|
|
23006
21762
|
if (isTimedOut(result))
|
|
23007
21763
|
return skippedHook(adapter, raw, env, budget, "dispatch");
|
|
23008
21764
|
if (remaining() < 0)
|
|
@@ -23568,8 +22324,8 @@ var codexAdapter = {
|
|
|
23568
22324
|
};
|
|
23569
22325
|
|
|
23570
22326
|
// packages/workit-core/src/hooks/hosts/cursor.ts
|
|
23571
|
-
import
|
|
23572
|
-
import
|
|
22327
|
+
import fs24 from "node:fs";
|
|
22328
|
+
import path32 from "node:path";
|
|
23573
22329
|
var undocumented = { support: "undocumented", native: null };
|
|
23574
22330
|
var none = { support: "none", native: null };
|
|
23575
22331
|
var CURSOR_DESCRIPTOR = {
|
|
@@ -23766,17 +22522,17 @@ var protocolEvent2 = (input) => {
|
|
|
23766
22522
|
};
|
|
23767
22523
|
var TRANSCRIPT_TAIL_BYTES = 256 * 1024;
|
|
23768
22524
|
var lastAssistantText = (file) => {
|
|
23769
|
-
if (!file || !
|
|
22525
|
+
if (!file || !path32.isAbsolute(file))
|
|
23770
22526
|
return null;
|
|
23771
22527
|
try {
|
|
23772
|
-
const size =
|
|
22528
|
+
const size = fs24.statSync(file).size;
|
|
23773
22529
|
const start = Math.max(0, size - TRANSCRIPT_TAIL_BYTES);
|
|
23774
22530
|
const buffer = Buffer.alloc(size - start);
|
|
23775
|
-
const fd =
|
|
22531
|
+
const fd = fs24.openSync(file, "r");
|
|
23776
22532
|
try {
|
|
23777
|
-
|
|
22533
|
+
fs24.readSync(fd, buffer, 0, buffer.length, start);
|
|
23778
22534
|
} finally {
|
|
23779
|
-
|
|
22535
|
+
fs24.closeSync(fd);
|
|
23780
22536
|
}
|
|
23781
22537
|
const lines = buffer.toString("utf8").split(`
|
|
23782
22538
|
`);
|
|
@@ -23803,7 +22559,7 @@ var lastAssistantText = (file) => {
|
|
|
23803
22559
|
return null;
|
|
23804
22560
|
}
|
|
23805
22561
|
};
|
|
23806
|
-
var
|
|
22562
|
+
var within3 = (root, dir) => dir === root || dir.startsWith(root.endsWith(path32.sep) ? root : `${root}${path32.sep}`);
|
|
23807
22563
|
var hookCwd = (input) => {
|
|
23808
22564
|
const cwd = existingDirectory(input.cwd);
|
|
23809
22565
|
if (cwd && input.hook_event_name === "beforeShellExecution")
|
|
@@ -23812,7 +22568,7 @@ var hookCwd = (input) => {
|
|
|
23812
22568
|
};
|
|
23813
22569
|
var cursorWorkspaceRoot = (input) => {
|
|
23814
22570
|
const cwd = existingDirectory(input.cwd);
|
|
23815
|
-
return cwd && input.workspace_roots.find((root) =>
|
|
22571
|
+
return cwd && input.workspace_roots.find((root) => within3(root, cwd)) || input.workspace_roots[0];
|
|
23816
22572
|
};
|
|
23817
22573
|
var cursorDeny = (reason) => ({
|
|
23818
22574
|
permission: "deny",
|