@brainervirus/workit-codex 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/.codex-plugin/plugin.json +1 -1
- package/agents/workit-implementer.toml +27 -19
- package/dist/launch-mcp.js +33 -1656
- package/dist/{workit-hook-aq4zdwdp.js → workit-hook-hegafjtc.js} +505 -1749
- package/dist/workit-hook.js +3 -1
- 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
|
@@ -1393,8 +1393,6 @@ var base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/
|
|
|
1393
1393
|
var base64url = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/;
|
|
1394
1394
|
var httpProtocol = /^https?$/;
|
|
1395
1395
|
var e164 = /^\+[1-9]\d{6,14}$/;
|
|
1396
|
-
var creditCard = /^\d(?:[ -]?\d){11,18}$/;
|
|
1397
|
-
var iban = /^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/;
|
|
1398
1396
|
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])))`;
|
|
1399
1397
|
function anchor(source) {
|
|
1400
1398
|
return new RegExp(`^${source}$`);
|
|
@@ -2240,41 +2238,6 @@ var $ZodE164 = /* @__PURE__ */ $constructor("$ZodE164", (inst, def) => {
|
|
|
2240
2238
|
def.pattern ?? (def.pattern = e164);
|
|
2241
2239
|
$ZodStringFormat.init(inst, def);
|
|
2242
2240
|
});
|
|
2243
|
-
var CC_SANITIZE = /[- ]/g;
|
|
2244
|
-
function isLuhnAlgo(digits) {
|
|
2245
|
-
let length = digits.length;
|
|
2246
|
-
let bit = 1;
|
|
2247
|
-
let sum = 0;
|
|
2248
|
-
while (length) {
|
|
2249
|
-
const value = digits.charCodeAt(--length) - 48;
|
|
2250
|
-
bit ^= 1;
|
|
2251
|
-
sum += bit ? [0, 2, 4, 6, 8, 1, 3, 5, 7, 9][value] : value;
|
|
2252
|
-
}
|
|
2253
|
-
return sum % 10 === 0;
|
|
2254
|
-
}
|
|
2255
|
-
function isValidCreditCard(input) {
|
|
2256
|
-
if (!creditCard.test(input))
|
|
2257
|
-
return false;
|
|
2258
|
-
return isLuhnAlgo(input.replace(CC_SANITIZE, ""));
|
|
2259
|
-
}
|
|
2260
|
-
function isIso7064Mod97(iban2) {
|
|
2261
|
-
let remainder = 0;
|
|
2262
|
-
const len = iban2.length;
|
|
2263
|
-
for (let i = 4;i < len; i++) {
|
|
2264
|
-
const code = iban2.charCodeAt(i);
|
|
2265
|
-
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
2266
|
-
}
|
|
2267
|
-
for (let i = 0;i < 4; i++) {
|
|
2268
|
-
const code = iban2.charCodeAt(i);
|
|
2269
|
-
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
2270
|
-
}
|
|
2271
|
-
return remainder === 1;
|
|
2272
|
-
}
|
|
2273
|
-
function isValidIBAN(input) {
|
|
2274
|
-
if (!iban.test(input))
|
|
2275
|
-
return false;
|
|
2276
|
-
return isIso7064Mod97(input);
|
|
2277
|
-
}
|
|
2278
2241
|
function isValidJWT(token, algorithm = null) {
|
|
2279
2242
|
try {
|
|
2280
2243
|
const tokensParts = token.split(".");
|
|
@@ -3587,9 +3550,6 @@ function settle(inst, answer) {
|
|
|
3587
3550
|
recursive.set(inst, answer === PROVEN);
|
|
3588
3551
|
return answer;
|
|
3589
3552
|
}
|
|
3590
|
-
function isRecursiveSchema(inst) {
|
|
3591
|
-
return isRecursive(inst, new Set, true) !== NONE;
|
|
3592
|
-
}
|
|
3593
3553
|
function bucketFor(state, inst) {
|
|
3594
3554
|
let bucket = state.buckets.get(inst);
|
|
3595
3555
|
if (!bucket) {
|
|
@@ -3829,1651 +3789,53 @@ function en_default() {
|
|
|
3829
3789
|
localeError: error()
|
|
3830
3790
|
};
|
|
3831
3791
|
}
|
|
3832
|
-
// node_modules/zod/v4/core/registries.js
|
|
3833
|
-
var _a2;
|
|
3834
|
-
class $ZodRegistry {
|
|
3835
|
-
constructor() {
|
|
3836
|
-
this._map = new WeakMap;
|
|
3837
|
-
this._idmap = new Map;
|
|
3838
|
-
}
|
|
3839
|
-
add(schema, ..._meta) {
|
|
3840
|
-
const meta = _meta[0];
|
|
3841
|
-
this._map.set(schema, meta);
|
|
3842
|
-
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3843
|
-
this._idmap.set(meta.id, schema);
|
|
3844
|
-
}
|
|
3845
|
-
return this;
|
|
3846
|
-
}
|
|
3847
|
-
clear() {
|
|
3848
|
-
this._map = new WeakMap;
|
|
3849
|
-
this._idmap = new Map;
|
|
3850
|
-
return this;
|
|
3851
|
-
}
|
|
3852
|
-
remove(schema) {
|
|
3853
|
-
const meta = this._map.get(schema);
|
|
3854
|
-
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3855
|
-
this._idmap.delete(meta.id);
|
|
3856
|
-
}
|
|
3857
|
-
this._map.delete(schema);
|
|
3858
|
-
return this;
|
|
3859
|
-
}
|
|
3860
|
-
get(schema) {
|
|
3861
|
-
const p = schema._zod.parent;
|
|
3862
|
-
if (p) {
|
|
3863
|
-
const pm = { ...this.get(p) ?? {} };
|
|
3864
|
-
delete pm.id;
|
|
3865
|
-
const f = { ...pm, ...this._map.get(schema) };
|
|
3866
|
-
return Object.keys(f).length ? f : undefined;
|
|
3867
|
-
}
|
|
3868
|
-
return this._map.get(schema);
|
|
3869
|
-
}
|
|
3870
|
-
has(schema) {
|
|
3871
|
-
return this._map.has(schema);
|
|
3872
|
-
}
|
|
3873
|
-
}
|
|
3874
|
-
function registry() {
|
|
3875
|
-
return new $ZodRegistry;
|
|
3876
|
-
}
|
|
3877
|
-
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
|
|
3878
|
-
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
3879
|
-
// node_modules/zod/v4/core/compile.js
|
|
3880
|
-
var INVALID = Symbol.for("zod.compile.invalid");
|
|
3881
|
-
var FALLBACK_FLAG = Symbol.for("zod.compile.fallback");
|
|
3882
|
-
|
|
3883
|
-
class ZodCompileAsyncError extends Error {
|
|
3884
|
-
constructor(message = "z.compile does not support async refinements, transforms, or checks") {
|
|
3885
|
-
super(message);
|
|
3886
|
-
this.name = "ZodCompileAsyncError";
|
|
3887
|
-
}
|
|
3888
|
-
}
|
|
3889
|
-
|
|
3890
|
-
class ZodCompileUnsupportedError extends Error {
|
|
3891
|
-
constructor(feature, islandable = true) {
|
|
3892
|
-
super(`z.compile does not support ${feature}; this schema must use the runtime parser`);
|
|
3893
|
-
this.name = "ZodCompileUnsupportedError";
|
|
3894
|
-
this.islandable = islandable;
|
|
3895
|
-
}
|
|
3896
|
-
}
|
|
3897
|
-
function compileValidator(schema, parser) {
|
|
3898
|
-
try {
|
|
3899
|
-
return compileFn(schema, { assertOnly: true });
|
|
3900
|
-
} catch {
|
|
3901
|
-
return parser;
|
|
3902
|
-
}
|
|
3903
|
-
}
|
|
3904
|
-
function compile(schema, options) {
|
|
3905
|
-
try {
|
|
3906
|
-
const parser = compileFn(schema);
|
|
3907
|
-
const clone = withParser(schema, parser);
|
|
3908
|
-
clone._zod.bag.validator = compileValidator(schema, parser);
|
|
3909
|
-
return clone;
|
|
3910
|
-
} catch (err) {
|
|
3911
|
-
if (options?.strict)
|
|
3912
|
-
throw err;
|
|
3913
|
-
return schema;
|
|
3914
|
-
}
|
|
3915
|
-
}
|
|
3916
|
-
function withParser(schema, parser) {
|
|
3917
|
-
if (isRecursiveSchema(schema)) {
|
|
3918
|
-
throw new ZodCompileUnsupportedError("a schema whose subtree contains a reference cycle");
|
|
3919
|
-
}
|
|
3920
|
-
const clone2 = clone(schema);
|
|
3921
|
-
const liveRun = schema._zod.run;
|
|
3922
|
-
const originalRun = liveRun.__originalRun ?? liveRun;
|
|
3923
|
-
const wrapped = (payload, ctx) => {
|
|
3924
|
-
if (ctx?.async || ctx?.direction === "backward" || ctx?.skipChecks || ctx?.[FALLBACK_FLAG]) {
|
|
3925
|
-
return originalRun(payload, ctx);
|
|
3926
|
-
}
|
|
3927
|
-
if (ctx && isBackEdge(ctx, payload.value)) {
|
|
3928
|
-
return originalRun(payload, ctx);
|
|
3929
|
-
}
|
|
3930
|
-
const out = parser(payload.value);
|
|
3931
|
-
if (out !== INVALID) {
|
|
3932
|
-
payload.value = out;
|
|
3933
|
-
return payload;
|
|
3934
|
-
}
|
|
3935
|
-
if (ctx)
|
|
3936
|
-
ctx[FALLBACK_FLAG] = true;
|
|
3937
|
-
return originalRun(payload, ctx);
|
|
3938
|
-
};
|
|
3939
|
-
wrapped.__originalRun = originalRun;
|
|
3940
|
-
clone2._zod.bag.fallbackRun = originalRun;
|
|
3941
|
-
clone2._zod.bag.validator = parser;
|
|
3942
|
-
clone2._zod.run = wrapped;
|
|
3943
|
-
if (!liveRun.__originalRun)
|
|
3944
|
-
installCompiledUserMethods(clone2, schema, parser);
|
|
3945
|
-
return clone2;
|
|
3946
|
-
}
|
|
3947
|
-
function installCompiledUserMethods(target, source, parser) {
|
|
3948
|
-
const targetAny = target;
|
|
3949
|
-
const sourceAny = source;
|
|
3950
|
-
if (typeof sourceAny.safeParse === "function") {
|
|
3951
|
-
const originalSafeParse = sourceAny.safeParse;
|
|
3952
|
-
targetAny.safeParse = (data, params) => {
|
|
3953
|
-
const out = parser(data);
|
|
3954
|
-
if (out !== INVALID) {
|
|
3955
|
-
return { success: true, data: out };
|
|
3956
|
-
}
|
|
3957
|
-
return originalSafeParse(data, params);
|
|
3958
|
-
};
|
|
3959
|
-
}
|
|
3960
|
-
if (typeof sourceAny.parse === "function") {
|
|
3961
|
-
const originalParse = sourceAny.parse;
|
|
3962
|
-
targetAny.parse = (data, params) => {
|
|
3963
|
-
const out = parser(data);
|
|
3964
|
-
if (out !== INVALID) {
|
|
3965
|
-
return out;
|
|
3966
|
-
}
|
|
3967
|
-
return originalParse(data, params);
|
|
3968
|
-
};
|
|
3969
|
-
}
|
|
3970
|
-
}
|
|
3971
|
-
function compileFn(schema, options) {
|
|
3972
|
-
let recursive = true;
|
|
3973
|
-
try {
|
|
3974
|
-
recursive = isRecursiveSchema(schema);
|
|
3975
|
-
} catch {}
|
|
3976
|
-
if (recursive) {
|
|
3977
|
-
throw new ZodCompileUnsupportedError("a schema whose subtree contains a reference cycle");
|
|
3978
|
-
}
|
|
3979
|
-
const ctx = {
|
|
3980
|
-
constants: new Map,
|
|
3981
|
-
constantCounter: 0,
|
|
3982
|
-
varCounter: 0,
|
|
3983
|
-
definite: true
|
|
3984
|
-
};
|
|
3985
|
-
const doc = new Doc(["input"]);
|
|
3986
|
-
const outputAccessor = generateCheck(doc, ctx, schema, "input", !options?.assertOnly);
|
|
3987
|
-
doc.write(outputAccessor === null ? `return true;` : `return ${outputAccessor};`);
|
|
3988
|
-
const constantNames = ["INVALID", ...ctx.constants.keys()];
|
|
3989
|
-
const constantValues = [INVALID, ...ctx.constants.values()];
|
|
3990
|
-
const code = doc.content.join(`
|
|
3991
|
-
`);
|
|
3992
|
-
const fullCode = options?.debug ? constantNames.length > 0 ? `// Constants: ${constantNames.join(", ")}
|
|
3993
|
-
${code}` : code : "";
|
|
3994
|
-
const F = Function;
|
|
3995
|
-
const factoryCode = `return (input) => {
|
|
3996
|
-
${code}
|
|
3997
|
-
}`;
|
|
3998
|
-
let fn;
|
|
3999
|
-
try {
|
|
4000
|
-
const factory = new F(...constantNames, factoryCode);
|
|
4001
|
-
fn = factory(...constantValues);
|
|
4002
|
-
} catch (err) {
|
|
4003
|
-
throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${err.message})`);
|
|
4004
|
-
}
|
|
4005
|
-
if (options?.debug) {
|
|
4006
|
-
fn.code = fullCode;
|
|
4007
|
-
}
|
|
4008
|
-
fn.definite = ctx.definite;
|
|
4009
|
-
return fn;
|
|
4010
|
-
}
|
|
4011
|
-
function addConstant(ctx, value) {
|
|
4012
|
-
for (const [name, v] of ctx.constants) {
|
|
4013
|
-
if (v === value)
|
|
4014
|
-
return name;
|
|
4015
|
-
}
|
|
4016
|
-
const name = `c${ctx.constantCounter++}`;
|
|
4017
|
-
ctx.constants.set(name, value);
|
|
4018
|
-
return name;
|
|
4019
|
-
}
|
|
4020
|
-
function addUserConstant(ctx, fn) {
|
|
4021
|
-
ctx.definite = false;
|
|
4022
|
-
return addConstant(ctx, fn);
|
|
4023
|
-
}
|
|
4024
|
-
function newVar(ctx) {
|
|
4025
|
-
return `v${ctx.varCounter++}`;
|
|
4026
|
-
}
|
|
4027
|
-
function runtimeRun(schema, value) {
|
|
4028
|
-
const result = schema._zod.run({ value, issues: [] }, {});
|
|
4029
|
-
if (result && typeof result.then === "function")
|
|
4030
|
-
return INVALID;
|
|
4031
|
-
const r = result;
|
|
4032
|
-
return r.issues.length === 0 ? r.value : INVALID;
|
|
4033
|
-
}
|
|
4034
|
-
function compileChild(doc, ctx, schema, accessor, needsValue = true) {
|
|
4035
|
-
const contentLen = doc.content.length;
|
|
4036
|
-
const constantCount = ctx.constants.size;
|
|
4037
|
-
const constantCounter = ctx.constantCounter;
|
|
4038
|
-
const varCounter = ctx.varCounter;
|
|
4039
|
-
try {
|
|
4040
|
-
return generateCheck(doc, ctx, schema, accessor, needsValue);
|
|
4041
|
-
} catch (err) {
|
|
4042
|
-
if (!(err instanceof ZodCompileUnsupportedError) || !err.islandable)
|
|
4043
|
-
throw err;
|
|
4044
|
-
doc.content.length = contentLen;
|
|
4045
|
-
if (ctx.constants.size > constantCount) {
|
|
4046
|
-
const trailing = Array.from(ctx.constants.keys()).slice(constantCount);
|
|
4047
|
-
for (const k of trailing)
|
|
4048
|
-
ctx.constants.delete(k);
|
|
4049
|
-
}
|
|
4050
|
-
ctx.constantCounter = constantCounter;
|
|
4051
|
-
ctx.varCounter = varCounter;
|
|
4052
|
-
return emitRuntimeIsland(doc, ctx, schema, accessor);
|
|
4053
|
-
}
|
|
4054
|
-
}
|
|
4055
|
-
function emitRuntimeIsland(doc, ctx, schema, accessor) {
|
|
4056
|
-
ctx.definite = false;
|
|
4057
|
-
const schemaConst = addConstant(ctx, schema);
|
|
4058
|
-
const runConst = addConstant(ctx, runtimeRun);
|
|
4059
|
-
const outVar = newVar(ctx);
|
|
4060
|
-
doc.write(`const ${outVar} = ${runConst}(${schemaConst}, ${accessor});`);
|
|
4061
|
-
doc.write(`if (${outVar} === INVALID) return INVALID;`);
|
|
4062
|
-
return outVar;
|
|
4063
|
-
}
|
|
4064
|
-
var WHEN_DEFAULTED_CHECKS = new Set([
|
|
4065
|
-
"max_size",
|
|
4066
|
-
"min_size",
|
|
4067
|
-
"size_equals",
|
|
4068
|
-
"max_length",
|
|
4069
|
-
"min_length",
|
|
4070
|
-
"length_equals"
|
|
4071
|
-
]);
|
|
4072
|
-
function generateChecks(doc, ctx, schema, accessor) {
|
|
4073
|
-
const schemaChecks = schema._zod.def.checks;
|
|
4074
|
-
if (!schemaChecks || schemaChecks.length === 0)
|
|
4075
|
-
return accessor;
|
|
4076
|
-
let currentAccessor = accessor;
|
|
4077
|
-
for (const check of schemaChecks) {
|
|
4078
|
-
const def = check._zod.def;
|
|
4079
|
-
if (def.when && !WHEN_DEFAULTED_CHECKS.has(def.check)) {
|
|
4080
|
-
throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
|
|
4081
|
-
}
|
|
4082
|
-
switch (def.check) {
|
|
4083
|
-
case "greater_than":
|
|
4084
|
-
generateGreaterThanCheck(doc, ctx, def, currentAccessor);
|
|
4085
|
-
break;
|
|
4086
|
-
case "less_than":
|
|
4087
|
-
generateLessThanCheck(doc, ctx, def, currentAccessor);
|
|
4088
|
-
break;
|
|
4089
|
-
case "multiple_of":
|
|
4090
|
-
generateMultipleOfCheck(doc, ctx, def, currentAccessor);
|
|
4091
|
-
break;
|
|
4092
|
-
case "number_format":
|
|
4093
|
-
generateNumberFormatCheck(doc, def, currentAccessor);
|
|
4094
|
-
break;
|
|
4095
|
-
case "min_length": {
|
|
4096
|
-
const min = numericOperand(def.minimum, "min_length");
|
|
4097
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${min} && ${currentAccessor}.length < ${def.minimum * 2}`);
|
|
4098
|
-
doc.write(`if (${len} < ${min}) return INVALID;`);
|
|
4099
|
-
break;
|
|
4100
|
-
}
|
|
4101
|
-
case "max_length": {
|
|
4102
|
-
const max = numericOperand(def.maximum, "max_length");
|
|
4103
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length > ${max}`);
|
|
4104
|
-
doc.write(`if (${len} > ${max}) return INVALID;`);
|
|
4105
|
-
break;
|
|
4106
|
-
}
|
|
4107
|
-
case "length_equals": {
|
|
4108
|
-
const exact = numericOperand(def.length, "length_equals");
|
|
4109
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${exact} && ${currentAccessor}.length <= ${def.length * 2}`);
|
|
4110
|
-
doc.write(`if (${len} !== ${exact}) return INVALID;`);
|
|
4111
|
-
break;
|
|
4112
|
-
}
|
|
4113
|
-
case "min_size":
|
|
4114
|
-
doc.write(`if (${currentAccessor}.size < ${numericOperand(def.minimum, "min_size")}) return INVALID;`);
|
|
4115
|
-
break;
|
|
4116
|
-
case "max_size":
|
|
4117
|
-
doc.write(`if (${currentAccessor}.size > ${numericOperand(def.maximum, "max_size")}) return INVALID;`);
|
|
4118
|
-
break;
|
|
4119
|
-
case "size_equals":
|
|
4120
|
-
doc.write(`if (${currentAccessor}.size !== ${numericOperand(def.size, "size_equals")}) return INVALID;`);
|
|
4121
|
-
break;
|
|
4122
|
-
case "string_format":
|
|
4123
|
-
currentAccessor = generateStringFormatCheck(doc, ctx, def, currentAccessor);
|
|
4124
|
-
break;
|
|
4125
|
-
case "custom":
|
|
4126
|
-
currentAccessor = generateCustomRefineCheck(doc, ctx, check, currentAccessor);
|
|
4127
|
-
break;
|
|
4128
|
-
case "bigint_format":
|
|
4129
|
-
generateBigIntFormatCheck(doc, def, currentAccessor);
|
|
4130
|
-
break;
|
|
4131
|
-
case "mime_type":
|
|
4132
|
-
generateMimeTypeCheck(doc, ctx, def, currentAccessor);
|
|
4133
|
-
break;
|
|
4134
|
-
case "property":
|
|
4135
|
-
generatePropertyCheck(doc, ctx, def, currentAccessor);
|
|
4136
|
-
break;
|
|
4137
|
-
case "properties":
|
|
4138
|
-
generatePropertiesChecks(doc, ctx, def, currentAccessor);
|
|
4139
|
-
break;
|
|
4140
|
-
case "overwrite": {
|
|
4141
|
-
const newAccessor = newVar(ctx);
|
|
4142
|
-
generateOverwriteCheck(doc, ctx, check, currentAccessor, newAccessor);
|
|
4143
|
-
currentAccessor = newAccessor;
|
|
4144
|
-
break;
|
|
4145
|
-
}
|
|
4146
|
-
default: {
|
|
4147
|
-
throw new ZodCompileUnsupportedError(`check type ${def.check}`);
|
|
4148
|
-
}
|
|
4149
|
-
}
|
|
4150
|
-
}
|
|
4151
|
-
return currentAccessor;
|
|
4152
|
-
}
|
|
4153
|
-
function codePointLengthVar(doc, ctx, accessor, inDoubt) {
|
|
4154
|
-
const cpLen = addConstant(ctx, codePointLength);
|
|
4155
|
-
const v = newVar(ctx);
|
|
4156
|
-
doc.write(`const ${v} = typeof ${accessor} === "string" && ${inDoubt} ? ${cpLen}(${accessor}) : ${accessor}.length;`);
|
|
4157
|
-
return v;
|
|
4158
|
-
}
|
|
4159
|
-
function numericOperand(value, label) {
|
|
4160
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
4161
|
-
throw new ZodCompileUnsupportedError(`${label} bound of type ${typeof value}`);
|
|
4162
|
-
}
|
|
4163
|
-
return `${value}`;
|
|
4164
|
-
}
|
|
4165
|
-
function comparisonOperand(ctx, value) {
|
|
4166
|
-
if (typeof value === "bigint")
|
|
4167
|
-
return `${value}n`;
|
|
4168
|
-
if (typeof value === "number") {
|
|
4169
|
-
if (Number.isNaN(value))
|
|
4170
|
-
throw new ZodCompileUnsupportedError("comparison check with NaN bound");
|
|
4171
|
-
return `${value}`;
|
|
4172
|
-
}
|
|
4173
|
-
if (value instanceof Date) {
|
|
4174
|
-
if (Number.isNaN(value.getTime())) {
|
|
4175
|
-
throw new ZodCompileUnsupportedError("comparison check with Invalid Date bound");
|
|
4176
|
-
}
|
|
4177
|
-
return addConstant(ctx, value);
|
|
4178
|
-
}
|
|
4179
|
-
throw new ZodCompileUnsupportedError(`comparison check bound of type ${typeof value}`);
|
|
4180
|
-
}
|
|
4181
|
-
function generateGreaterThanCheck(doc, ctx, def, accessor) {
|
|
4182
|
-
const op = def.inclusive ? "<" : "<=";
|
|
4183
|
-
doc.write(`if (${accessor} ${op} ${comparisonOperand(ctx, def.value)}) return INVALID;`);
|
|
4184
|
-
}
|
|
4185
|
-
function generateLessThanCheck(doc, ctx, def, accessor) {
|
|
4186
|
-
const op = def.inclusive ? ">" : ">=";
|
|
4187
|
-
doc.write(`if (${accessor} ${op} ${comparisonOperand(ctx, def.value)}) return INVALID;`);
|
|
4188
|
-
}
|
|
4189
|
-
function generateMultipleOfCheck(doc, ctx, def, accessor) {
|
|
4190
|
-
if (typeof def.value === "bigint") {
|
|
4191
|
-
if (def.value === BigInt(0))
|
|
4192
|
-
throw new ZodCompileUnsupportedError("multiple_of check with a zero divisor");
|
|
4193
|
-
doc.write(`if (${accessor} % ${def.value}n !== 0n) return INVALID;`);
|
|
4194
|
-
} else {
|
|
4195
|
-
const remainder = addConstant(ctx, floatSafeRemainder);
|
|
4196
|
-
doc.write(`if (${remainder}(${accessor}, ${numericOperand(def.value, "multiple_of")}) !== 0) return INVALID;`);
|
|
4197
|
-
}
|
|
4198
|
-
}
|
|
4199
|
-
function generateNumberFormatCheck(doc, def, accessor) {
|
|
4200
|
-
const format = def.format;
|
|
4201
|
-
switch (format) {
|
|
4202
|
-
case "safeint":
|
|
4203
|
-
doc.write(`if (!Number.isSafeInteger(${accessor})) return INVALID;`);
|
|
4204
|
-
break;
|
|
4205
|
-
case "int32":
|
|
4206
|
-
doc.write(`if (!Number.isInteger(${accessor}) || ${accessor} < -2147483648 || ${accessor} > 2147483647) return INVALID;`);
|
|
4207
|
-
break;
|
|
4208
|
-
case "uint32":
|
|
4209
|
-
doc.write(`if (!Number.isInteger(${accessor}) || ${accessor} < 0 || ${accessor} > 4294967295) return INVALID;`);
|
|
4210
|
-
break;
|
|
4211
|
-
case "float32":
|
|
4212
|
-
doc.write(`if (!Number.isFinite(${accessor}) || ${accessor} < -3.4028234663852886e38 || ${accessor} > 3.4028234663852886e38) return INVALID;`);
|
|
4213
|
-
break;
|
|
4214
|
-
case "float64":
|
|
4215
|
-
doc.write(`if (!Number.isFinite(${accessor})) return INVALID;`);
|
|
4216
|
-
break;
|
|
4217
|
-
default: {
|
|
4218
|
-
throw new ZodCompileUnsupportedError(`number format ${format}`);
|
|
4219
|
-
}
|
|
4220
|
-
}
|
|
4221
|
-
}
|
|
4222
|
-
function generateBigIntFormatCheck(doc, def, accessor) {
|
|
4223
|
-
const format = def.format;
|
|
4224
|
-
if (!format)
|
|
4225
|
-
return;
|
|
4226
|
-
switch (format) {
|
|
4227
|
-
case "int64":
|
|
4228
|
-
doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);
|
|
4229
|
-
break;
|
|
4230
|
-
case "uint64":
|
|
4231
|
-
doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);
|
|
4232
|
-
break;
|
|
4233
|
-
default: {
|
|
4234
|
-
throw new ZodCompileUnsupportedError(`bigint format ${format}`);
|
|
4235
|
-
}
|
|
4236
|
-
}
|
|
4237
|
-
}
|
|
4238
|
-
function generateMimeTypeCheck(doc, ctx, def, accessor) {
|
|
4239
|
-
const mimeTypes = def.mime;
|
|
4240
|
-
if (mimeTypes && mimeTypes.length > 0) {
|
|
4241
|
-
const mimeSet = addConstant(ctx, new Set(mimeTypes));
|
|
4242
|
-
doc.write(`if (!${mimeSet}.has(${accessor}.type)) return INVALID;`);
|
|
4243
|
-
}
|
|
4244
|
-
}
|
|
4245
|
-
function generatePropertiesChecks(doc, ctx, def, accessor) {
|
|
4246
|
-
if (def.when) {
|
|
4247
|
-
throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
|
|
4248
|
-
}
|
|
4249
|
-
doc.write(`if (${accessor} == null) return INVALID;`);
|
|
4250
|
-
const shape = def.shape;
|
|
4251
|
-
for (const key of Reflect.ownKeys(shape)) {
|
|
4252
|
-
const keyExpr = typeof key === "symbol" ? addConstant(ctx, key) : esc(key);
|
|
4253
|
-
const inputVar = newVar(ctx);
|
|
4254
|
-
doc.write(`const ${inputVar} = ${accessor}[${keyExpr}];`);
|
|
4255
|
-
compileChild(doc, ctx, shape[key], inputVar, false);
|
|
4256
|
-
}
|
|
4257
|
-
}
|
|
4258
|
-
function generatePropertyCheck(doc, ctx, def, accessor) {
|
|
4259
|
-
const propAccessor = `${accessor}[${JSON.stringify(def.property)}]`;
|
|
4260
|
-
generateCheck(doc, ctx, def.schema, propAccessor);
|
|
4261
|
-
}
|
|
4262
|
-
function generateOverwriteCheck(doc, ctx, check, currentAccessor, newAccessor) {
|
|
4263
|
-
const tx = check._zod.def.tx;
|
|
4264
|
-
if (!tx) {
|
|
4265
|
-
throw new ZodCompileUnsupportedError("overwrite check without a transform function");
|
|
4266
|
-
}
|
|
4267
|
-
if (isAsyncFunction(tx)) {
|
|
4268
|
-
throw new ZodCompileAsyncError("z.compile: async overwrite transforms are not supported");
|
|
4269
|
-
}
|
|
4270
|
-
const txConst = addConstant(ctx, tx);
|
|
4271
|
-
doc.write(`const ${newAccessor} = ${txConst}(${currentAccessor});`);
|
|
4272
|
-
}
|
|
4273
|
-
function throwAsync() {
|
|
4274
|
-
throw new $ZodAsyncError;
|
|
4275
|
-
}
|
|
4276
|
-
function pushIssue(issue) {
|
|
4277
|
-
this.issues.push(issue);
|
|
4278
|
-
}
|
|
4279
|
-
function generateCustomRefineCheck(doc, ctx, check, accessor) {
|
|
4280
|
-
const def = check._zod.def;
|
|
4281
|
-
if (def.fn) {
|
|
4282
|
-
if (isAsyncFunction(def.fn)) {
|
|
4283
|
-
throw new ZodCompileAsyncError("z.compile: async .refine() predicates are not supported");
|
|
4284
|
-
}
|
|
4285
|
-
const fnConst = addUserConstant(ctx, def.fn);
|
|
4286
|
-
const throwAsyncConst = addConstant(ctx, throwAsync);
|
|
4287
|
-
const resVar = newVar(ctx);
|
|
4288
|
-
doc.write(`const ${resVar} = ${fnConst}(${accessor});`);
|
|
4289
|
-
doc.write(`if (${resVar} instanceof Promise) ${throwAsyncConst}();`);
|
|
4290
|
-
doc.write(`if (!${resVar}) return INVALID;`);
|
|
4291
|
-
return accessor;
|
|
4292
|
-
}
|
|
4293
|
-
if (check._zod.check) {
|
|
4294
|
-
if (isAsyncFunction(check._zod.check)) {
|
|
4295
|
-
throw new ZodCompileAsyncError("z.compile: async .superRefine() / check functions are not supported");
|
|
4296
|
-
}
|
|
4297
|
-
const checkFn = check._zod.check;
|
|
4298
|
-
const helperFn = (value) => {
|
|
4299
|
-
const fakePayload = { value, issues: [], addIssue: pushIssue };
|
|
4300
|
-
const result = checkFn(fakePayload);
|
|
4301
|
-
if (result instanceof Promise)
|
|
4302
|
-
throwAsync();
|
|
4303
|
-
return fakePayload.issues.length === 0 ? fakePayload.value : INVALID;
|
|
4304
|
-
};
|
|
4305
|
-
const helperConst = addUserConstant(ctx, helperFn);
|
|
4306
|
-
const outVar = newVar(ctx);
|
|
4307
|
-
doc.write(`const ${outVar} = ${helperConst}(${accessor});`);
|
|
4308
|
-
doc.write(`if (${outVar} === INVALID) return INVALID;`);
|
|
4309
|
-
return outVar;
|
|
4310
|
-
}
|
|
4311
|
-
throw new ZodCompileUnsupportedError("custom check without a predicate or check function");
|
|
4312
|
-
}
|
|
4313
|
-
var PATTERN_IS_COMPLETE = new Set([
|
|
4314
|
-
"cidrv4",
|
|
4315
|
-
"cuid",
|
|
4316
|
-
"cuid2",
|
|
4317
|
-
"date",
|
|
4318
|
-
"datetime",
|
|
4319
|
-
"duration",
|
|
4320
|
-
"e164",
|
|
4321
|
-
"email",
|
|
4322
|
-
"emoji",
|
|
4323
|
-
"ends_with",
|
|
4324
|
-
"guid",
|
|
4325
|
-
"includes",
|
|
4326
|
-
"ipv4",
|
|
4327
|
-
"ksuid",
|
|
4328
|
-
"lowercase",
|
|
4329
|
-
"mac",
|
|
4330
|
-
"nanoid",
|
|
4331
|
-
"regex",
|
|
4332
|
-
"starts_with",
|
|
4333
|
-
"time",
|
|
4334
|
-
"ulid",
|
|
4335
|
-
"uppercase",
|
|
4336
|
-
"uuid",
|
|
4337
|
-
"xid"
|
|
4338
|
-
]);
|
|
4339
|
-
function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
4340
|
-
const fmt = def.format;
|
|
4341
|
-
if (fmt === "base64") {
|
|
4342
|
-
const validator = addConstant(ctx, isValidBase64);
|
|
4343
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
4344
|
-
return accessor;
|
|
4345
|
-
}
|
|
4346
|
-
if (fmt === "base64url") {
|
|
4347
|
-
const validator = addConstant(ctx, isValidBase64URL);
|
|
4348
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
4349
|
-
return accessor;
|
|
4350
|
-
}
|
|
4351
|
-
if (fmt === "jwt") {
|
|
4352
|
-
const validator = addConstant(ctx, isValidJWT);
|
|
4353
|
-
const alg = addConstant(ctx, def.alg ?? null);
|
|
4354
|
-
doc.write(`if (!${validator}(${accessor}, ${alg})) return INVALID;`);
|
|
4355
|
-
return accessor;
|
|
4356
|
-
}
|
|
4357
|
-
if (fmt === "ipv6") {
|
|
4358
|
-
const validator = addConstant(ctx, isValidIPv6);
|
|
4359
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
4360
|
-
return accessor;
|
|
4361
|
-
}
|
|
4362
|
-
if (fmt === "cidrv6") {
|
|
4363
|
-
const validator = addConstant(ctx, isValidCIDRv6);
|
|
4364
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
4365
|
-
return accessor;
|
|
4366
|
-
}
|
|
4367
|
-
if (fmt === "credit_card") {
|
|
4368
|
-
const validator = addConstant(ctx, isValidCreditCard);
|
|
4369
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
4370
|
-
return accessor;
|
|
4371
|
-
}
|
|
4372
|
-
if (fmt === "iban") {
|
|
4373
|
-
const validator = addConstant(ctx, isValidIBAN);
|
|
4374
|
-
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
4375
|
-
return accessor;
|
|
4376
|
-
}
|
|
4377
|
-
const formatDef = def;
|
|
4378
|
-
if (fmt === "url" || fmt === "httpurl" || formatDef.normalize || formatDef.hostname !== undefined || formatDef.protocol !== undefined) {
|
|
4379
|
-
const parseConst = addConstant(ctx, validateURL);
|
|
4380
|
-
const defConst = addConstant(ctx, def);
|
|
4381
|
-
const trimVar = newVar(ctx);
|
|
4382
|
-
const urlVar = newVar(ctx);
|
|
4383
|
-
doc.write(`const ${trimVar} = ${accessor}.trim();`);
|
|
4384
|
-
doc.write(`const ${urlVar} = ${parseConst}(${trimVar}, ${defConst});`);
|
|
4385
|
-
doc.write(`if (typeof ${urlVar} === "number") return INVALID;`);
|
|
4386
|
-
if (formatDef.hostname !== undefined) {
|
|
4387
|
-
const hostnameConst = addConstant(ctx, urlHostnameOk);
|
|
4388
|
-
doc.write(`if (!${hostnameConst}(${urlVar}, ${defConst}.hostname)) return INVALID;`);
|
|
4389
|
-
}
|
|
4390
|
-
if (formatDef.protocol !== undefined) {
|
|
4391
|
-
const protocolConst = addConstant(ctx, urlProtocolOk);
|
|
4392
|
-
doc.write(`if (!${protocolConst}(${urlVar}, ${defConst}.protocol)) return INVALID;`);
|
|
4393
|
-
}
|
|
4394
|
-
if (!needsValue)
|
|
4395
|
-
return null;
|
|
4396
|
-
const outputVar = newVar(ctx);
|
|
4397
|
-
const outputExpr = formatDef.normalize ? `${urlVar}.href` : `${addConstant(ctx, stripTabAndNewline)}(${trimVar})`;
|
|
4398
|
-
doc.write(`const ${outputVar} = ${outputExpr};`);
|
|
4399
|
-
return outputVar;
|
|
4400
|
-
}
|
|
4401
|
-
const customFn = def.fn;
|
|
4402
|
-
if (customFn) {
|
|
4403
|
-
if (isAsyncFunction(customFn))
|
|
4404
|
-
throw new ZodCompileUnsupportedError(`async string format ${fmt}`);
|
|
4405
|
-
const fnConst = addConstant(ctx, customFn);
|
|
4406
|
-
doc.write(`if (!${fnConst}(${accessor})) return INVALID;`);
|
|
4407
|
-
return accessor;
|
|
4408
|
-
}
|
|
4409
|
-
if (PATTERN_IS_COMPLETE.has(fmt) && def.pattern) {
|
|
4410
|
-
const patternConst = addConstant(ctx, def.pattern);
|
|
4411
|
-
doc.write(`${patternConst}.lastIndex = 0;`);
|
|
4412
|
-
doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);
|
|
4413
|
-
return accessor;
|
|
4414
|
-
}
|
|
4415
|
-
const format = def.format;
|
|
4416
|
-
switch (format) {
|
|
4417
|
-
case "regex":
|
|
4418
|
-
throw new ZodCompileUnsupportedError("regex format without a pattern");
|
|
4419
|
-
case "lowercase":
|
|
4420
|
-
doc.write(`if (${accessor} !== ${accessor}.toLowerCase()) return INVALID;`);
|
|
4421
|
-
break;
|
|
4422
|
-
case "uppercase":
|
|
4423
|
-
doc.write(`if (${accessor} !== ${accessor}.toUpperCase()) return INVALID;`);
|
|
4424
|
-
break;
|
|
4425
|
-
case "includes":
|
|
4426
|
-
doc.write(`if (!${accessor}.includes(${esc(def.includes)})) return INVALID;`);
|
|
4427
|
-
break;
|
|
4428
|
-
case "starts_with": {
|
|
4429
|
-
const prefix = def.prefix;
|
|
4430
|
-
doc.write(`if (${accessor}.slice(0, ${prefix.length}) !== ${esc(prefix)}) return INVALID;`);
|
|
4431
|
-
break;
|
|
4432
|
-
}
|
|
4433
|
-
case "ends_with": {
|
|
4434
|
-
const suffix = def.suffix;
|
|
4435
|
-
doc.write(`if (${accessor}.slice(-${suffix.length}) !== ${esc(suffix)}) return INVALID;`);
|
|
4436
|
-
break;
|
|
4437
|
-
}
|
|
4438
|
-
default: {
|
|
4439
|
-
throw new ZodCompileUnsupportedError(`string format ${format}`);
|
|
4440
|
-
}
|
|
4441
|
-
}
|
|
4442
|
-
return accessor;
|
|
4443
|
-
}
|
|
4444
|
-
function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
4445
|
-
const def = schema._zod.def;
|
|
4446
|
-
const type = def.type;
|
|
4447
|
-
if (def.coerce) {
|
|
4448
|
-
throw new ZodCompileUnsupportedError(`coercion (z.coerce.${type}())`);
|
|
4449
|
-
}
|
|
4450
|
-
const buildsValue = needsValue || !!def.checks?.length;
|
|
4451
|
-
let typeAccessor;
|
|
4452
|
-
switch (type) {
|
|
4453
|
-
case "string":
|
|
4454
|
-
typeAccessor = generateStringCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4455
|
-
break;
|
|
4456
|
-
case "number":
|
|
4457
|
-
typeAccessor = generateNumberCheck(doc, schema, accessor);
|
|
4458
|
-
break;
|
|
4459
|
-
case "boolean":
|
|
4460
|
-
typeAccessor = generateBooleanCheck(doc, accessor);
|
|
4461
|
-
break;
|
|
4462
|
-
case "bigint":
|
|
4463
|
-
typeAccessor = generateBigIntCheck(doc, schema, accessor);
|
|
4464
|
-
break;
|
|
4465
|
-
case "symbol":
|
|
4466
|
-
typeAccessor = generateSymbolCheck(doc, accessor);
|
|
4467
|
-
break;
|
|
4468
|
-
case "undefined":
|
|
4469
|
-
typeAccessor = generateUndefinedCheck(doc, accessor);
|
|
4470
|
-
break;
|
|
4471
|
-
case "null":
|
|
4472
|
-
typeAccessor = generateNullCheck(doc, accessor);
|
|
4473
|
-
break;
|
|
4474
|
-
case "any":
|
|
4475
|
-
case "unknown":
|
|
4476
|
-
typeAccessor = accessor;
|
|
4477
|
-
break;
|
|
4478
|
-
case "never":
|
|
4479
|
-
doc.write("return INVALID;");
|
|
4480
|
-
typeAccessor = accessor;
|
|
4481
|
-
break;
|
|
4482
|
-
case "void":
|
|
4483
|
-
typeAccessor = generateVoidCheck(doc, accessor);
|
|
4484
|
-
break;
|
|
4485
|
-
case "nan":
|
|
4486
|
-
typeAccessor = generateNaNCheck(doc, accessor);
|
|
4487
|
-
break;
|
|
4488
|
-
case "date":
|
|
4489
|
-
typeAccessor = generateDateCheck(doc, accessor);
|
|
4490
|
-
break;
|
|
4491
|
-
case "object":
|
|
4492
|
-
typeAccessor = generateObjectCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4493
|
-
break;
|
|
4494
|
-
case "optional":
|
|
4495
|
-
typeAccessor = generateOptionalCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4496
|
-
break;
|
|
4497
|
-
case "nullable":
|
|
4498
|
-
typeAccessor = generateNullableCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4499
|
-
break;
|
|
4500
|
-
case "array":
|
|
4501
|
-
typeAccessor = generateArrayCheck(doc, ctx, schema, accessor, buildsValue);
|
|
4502
|
-
break;
|
|
4503
|
-
case "literal":
|
|
4504
|
-
typeAccessor = generateLiteralCheck(doc, ctx, schema, accessor);
|
|
4505
|
-
break;
|
|
4506
|
-
case "enum":
|
|
4507
|
-
typeAccessor = generateEnumCheck(doc, ctx, schema, accessor);
|
|
4508
|
-
break;
|
|
4509
|
-
case "readonly": {
|
|
4510
|
-
const innerOut = generateWrapperCheck(doc, ctx, schema, accessor);
|
|
4511
|
-
const frozenVar = newVar(ctx);
|
|
4512
|
-
doc.write(`const ${frozenVar} = Object.freeze(${innerOut});`);
|
|
4513
|
-
typeAccessor = frozenVar;
|
|
4514
|
-
break;
|
|
4515
|
-
}
|
|
4516
|
-
case "success":
|
|
4517
|
-
generateWrapperCheck(doc, ctx, schema, accessor);
|
|
4518
|
-
typeAccessor = "true";
|
|
4519
|
-
break;
|
|
4520
|
-
case "default":
|
|
4521
|
-
case "prefault":
|
|
4522
|
-
typeAccessor = generateDefaultCheck(doc, ctx, schema, accessor);
|
|
4523
|
-
break;
|
|
4524
|
-
case "nonoptional":
|
|
4525
|
-
typeAccessor = generateNonOptionalCheck(doc, ctx, schema, accessor);
|
|
4526
|
-
break;
|
|
4527
|
-
case "tuple":
|
|
4528
|
-
typeAccessor = generateTupleCheck(doc, ctx, schema, accessor);
|
|
4529
|
-
break;
|
|
4530
|
-
case "union":
|
|
4531
|
-
typeAccessor = generateUnionCheck(doc, ctx, schema, accessor);
|
|
4532
|
-
break;
|
|
4533
|
-
case "intersection":
|
|
4534
|
-
typeAccessor = generateIntersectionCheck(doc, ctx, schema, accessor);
|
|
4535
|
-
break;
|
|
4536
|
-
case "record":
|
|
4537
|
-
typeAccessor = generateRecordCheck(doc, ctx, schema, accessor);
|
|
4538
|
-
break;
|
|
4539
|
-
case "map":
|
|
4540
|
-
typeAccessor = generateMapCheck(doc, ctx, schema, accessor);
|
|
4541
|
-
break;
|
|
4542
|
-
case "set":
|
|
4543
|
-
typeAccessor = generateSetCheck(doc, ctx, schema, accessor);
|
|
4544
|
-
break;
|
|
4545
|
-
case "file":
|
|
4546
|
-
typeAccessor = generateFileCheck(doc, accessor);
|
|
4547
|
-
break;
|
|
4548
|
-
case "template_literal":
|
|
4549
|
-
typeAccessor = generateTemplateLiteralCheck(doc, ctx, schema, accessor);
|
|
4550
|
-
break;
|
|
4551
|
-
case "lazy":
|
|
4552
|
-
typeAccessor = generateLazyCheck(doc, ctx, schema, accessor);
|
|
4553
|
-
break;
|
|
4554
|
-
case "pipe":
|
|
4555
|
-
typeAccessor = generatePipeCheck(doc, ctx, schema, accessor);
|
|
4556
|
-
break;
|
|
4557
|
-
case "custom":
|
|
4558
|
-
typeAccessor = generateCustomCheck(doc, ctx, schema, accessor);
|
|
4559
|
-
break;
|
|
4560
|
-
case "transform":
|
|
4561
|
-
typeAccessor = generateTransformCheck(doc, ctx, schema, accessor);
|
|
4562
|
-
break;
|
|
4563
|
-
case "catch":
|
|
4564
|
-
typeAccessor = generateCatchCheck(doc, ctx, schema, accessor);
|
|
4565
|
-
break;
|
|
4566
|
-
default: {
|
|
4567
|
-
throw new ZodCompileUnsupportedError(`schema type ${type}`);
|
|
4568
|
-
}
|
|
4569
|
-
}
|
|
4570
|
-
if (typeAccessor === null)
|
|
4571
|
-
return null;
|
|
4572
|
-
return generateChecks(doc, ctx, schema, typeAccessor);
|
|
4573
|
-
}
|
|
4574
|
-
function generateStringCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
4575
|
-
doc.write(`if (typeof ${accessor} !== "string") return INVALID;`);
|
|
4576
|
-
const def = schema._zod.def;
|
|
4577
|
-
if (def.format === undefined)
|
|
4578
|
-
return accessor;
|
|
4579
|
-
return generateStringFormatCheck(doc, ctx, def, accessor, needsValue);
|
|
4580
|
-
}
|
|
4581
|
-
function generateNumberCheck(doc, schema, accessor) {
|
|
4582
|
-
doc.write(`if (typeof ${accessor} !== "number" || !Number.isFinite(${accessor})) return INVALID;`);
|
|
4583
|
-
const def = schema._zod.def;
|
|
4584
|
-
if (def.check === "number_format" && def.format) {
|
|
4585
|
-
generateNumberFormatCheck(doc, { format: def.format }, accessor);
|
|
4586
|
-
}
|
|
4587
|
-
return accessor;
|
|
4588
|
-
}
|
|
4589
|
-
function generateBooleanCheck(doc, accessor) {
|
|
4590
|
-
doc.write(`if (typeof ${accessor} !== "boolean") return INVALID;`);
|
|
4591
|
-
return accessor;
|
|
4592
|
-
}
|
|
4593
|
-
function generateBigIntCheck(doc, schema, accessor) {
|
|
4594
|
-
doc.write(`if (typeof ${accessor} !== "bigint") return INVALID;`);
|
|
4595
|
-
const def = schema._zod.def;
|
|
4596
|
-
if (def.format) {
|
|
4597
|
-
switch (def.format) {
|
|
4598
|
-
case "int64":
|
|
4599
|
-
doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);
|
|
4600
|
-
break;
|
|
4601
|
-
case "uint64":
|
|
4602
|
-
doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);
|
|
4603
|
-
break;
|
|
4604
|
-
}
|
|
4605
|
-
}
|
|
4606
|
-
return accessor;
|
|
4607
|
-
}
|
|
4608
|
-
function generateSymbolCheck(doc, accessor) {
|
|
4609
|
-
doc.write(`if (typeof ${accessor} !== "symbol") return INVALID;`);
|
|
4610
|
-
return accessor;
|
|
4611
|
-
}
|
|
4612
|
-
function generateUndefinedCheck(doc, accessor) {
|
|
4613
|
-
doc.write(`if (${accessor} !== undefined) return INVALID;`);
|
|
4614
|
-
return accessor;
|
|
4615
|
-
}
|
|
4616
|
-
function generateNullCheck(doc, accessor) {
|
|
4617
|
-
doc.write(`if (${accessor} !== null) return INVALID;`);
|
|
4618
|
-
return accessor;
|
|
4619
|
-
}
|
|
4620
|
-
function generateVoidCheck(doc, accessor) {
|
|
4621
|
-
doc.write(`if (${accessor} !== undefined) return INVALID;`);
|
|
4622
|
-
return accessor;
|
|
4623
|
-
}
|
|
4624
|
-
function generateNaNCheck(doc, accessor) {
|
|
4625
|
-
doc.write(`if (typeof ${accessor} !== "number" || !Number.isNaN(${accessor})) return INVALID;`);
|
|
4626
|
-
return accessor;
|
|
4627
|
-
}
|
|
4628
|
-
function generateDateCheck(doc, accessor) {
|
|
4629
|
-
doc.write(`if (!(${accessor} instanceof Date) || Number.isNaN(${accessor}.getTime())) return INVALID;`);
|
|
4630
|
-
return accessor;
|
|
4631
|
-
}
|
|
4632
|
-
function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4633
|
-
const def = schema._zod.def;
|
|
4634
|
-
doc.write(`if (typeof ${accessor} !== "object" || ${accessor} === null || Array.isArray(${accessor})) return INVALID;`);
|
|
4635
|
-
const shape = def.shape;
|
|
4636
|
-
const keys = Object.keys(shape);
|
|
4637
|
-
const symbolKeys = Object.getOwnPropertySymbols(shape);
|
|
4638
|
-
const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;
|
|
4639
|
-
const keyExpr = (k) => typeof k === "symbol" ? addConstant(ctx, k) : esc(k);
|
|
4640
|
-
const propKey = (k) => typeof k === "symbol" ? `[${keyExpr(k)}]` : esc(k);
|
|
4641
|
-
const propShape = shape;
|
|
4642
|
-
if (keys.includes("__proto__")) {
|
|
4643
|
-
throw new ZodCompileUnsupportedError('object shape key "__proto__"');
|
|
4644
|
-
}
|
|
4645
|
-
const propOutputs = new Map;
|
|
4646
|
-
for (const key of allKeys) {
|
|
4647
|
-
const propSchema = propShape[key];
|
|
4648
|
-
const kx = keyExpr(key);
|
|
4649
|
-
const inputVar = newVar(ctx);
|
|
4650
|
-
doc.write(`const ${inputVar} = ${accessor}[${kx}];`);
|
|
4651
|
-
if (propSchema._zod.optin !== undefined) {
|
|
4652
|
-
const outputVar = newVar(ctx);
|
|
4653
|
-
doc.write(`let ${outputVar} = (() => {`);
|
|
4654
|
-
doc.indented((d) => {
|
|
4655
|
-
const outputAccessor = compileChild(d, ctx, propSchema, inputVar);
|
|
4656
|
-
d.write(`return ${outputAccessor};`);
|
|
4657
|
-
});
|
|
4658
|
-
doc.write(`})();`);
|
|
4659
|
-
if (propSchema._zod.optout === "optional") {
|
|
4660
|
-
doc.write(`if (${outputVar} === INVALID) {`);
|
|
4661
|
-
doc.indented((d) => {
|
|
4662
|
-
d.write(`if (${kx} in ${accessor}) return INVALID;`);
|
|
4663
|
-
d.write(`${outputVar} = undefined;`);
|
|
4664
|
-
});
|
|
4665
|
-
doc.write(`}`);
|
|
4666
|
-
} else {
|
|
4667
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
4668
|
-
}
|
|
4669
|
-
propOutputs.set(key, outputVar);
|
|
4670
|
-
} else {
|
|
4671
|
-
if (requiresPresenceCheck(propSchema)) {
|
|
4672
|
-
doc.write(`if (!(${kx} in ${accessor})) return INVALID;`);
|
|
4673
|
-
}
|
|
4674
|
-
const outputAccessor = compileChild(doc, ctx, propSchema, inputVar, buildsValue);
|
|
4675
|
-
if (outputAccessor !== null)
|
|
4676
|
-
propOutputs.set(key, outputAccessor);
|
|
4677
|
-
}
|
|
4678
|
-
}
|
|
4679
|
-
const catchall = def.catchall;
|
|
4680
|
-
let unknownKeysMode = "none";
|
|
4681
|
-
if (catchall) {
|
|
4682
|
-
const catchallType = catchall._zod.def.type;
|
|
4683
|
-
if (catchallType === "never") {
|
|
4684
|
-
const condition = keys.map((k) => `k !== ${esc(k)}`).join(" && ") || "true";
|
|
4685
|
-
doc.write(`for (const k in ${accessor}) {`);
|
|
4686
|
-
doc.indented((d) => {
|
|
4687
|
-
d.write(`if (${condition}) return INVALID;`);
|
|
4688
|
-
});
|
|
4689
|
-
doc.write(`}`);
|
|
4690
|
-
} else if ((catchallType === "unknown" || catchallType === "any") && !catchall._zod.def.checks?.length) {
|
|
4691
|
-
unknownKeysMode = "passthrough";
|
|
4692
|
-
} else {
|
|
4693
|
-
unknownKeysMode = "schema";
|
|
4694
|
-
}
|
|
4695
|
-
}
|
|
4696
|
-
const outputVar = newVar(ctx);
|
|
4697
|
-
const hasConditionalKeys = allKeys.some((k) => mayOmitUndefined(propShape[k]) || dropsWhenAbsent(propShape[k]));
|
|
4698
|
-
if (!buildsValue) {
|
|
4699
|
-
if (unknownKeysMode === "schema") {
|
|
4700
|
-
const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;
|
|
4701
|
-
doc.write(`for (const k in ${accessor}) {`);
|
|
4702
|
-
doc.indented((d) => {
|
|
4703
|
-
d.write(`if (k === "__proto__") continue;`);
|
|
4704
|
-
if (knownSet)
|
|
4705
|
-
d.write(`if (${knownSet}.has(k)) continue;`);
|
|
4706
|
-
const valVar = newVar(ctx);
|
|
4707
|
-
d.write(`const ${valVar} = ${accessor}[k];`);
|
|
4708
|
-
compileChild(d, ctx, catchall, valVar, false);
|
|
4709
|
-
});
|
|
4710
|
-
doc.write(`}`);
|
|
4711
|
-
}
|
|
4712
|
-
return null;
|
|
4713
|
-
}
|
|
4714
|
-
if (!hasConditionalKeys) {
|
|
4715
|
-
const propLiterals = allKeys.map((k) => `${propKey(k)}: ${propOutputs.get(k)}`).join(", ");
|
|
4716
|
-
doc.write(`const ${outputVar} = { ${propLiterals} };`);
|
|
4717
|
-
} else {
|
|
4718
|
-
doc.write(`const ${outputVar} = {};`);
|
|
4719
|
-
for (const k of allKeys) {
|
|
4720
|
-
const kx = keyExpr(k);
|
|
4721
|
-
const out = propOutputs.get(k);
|
|
4722
|
-
if (dropsWhenAbsent(propShape[k])) {
|
|
4723
|
-
doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
|
|
4724
|
-
} else if (mayOmitUndefined(propShape[k])) {
|
|
4725
|
-
doc.write(`if (${out} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
|
|
4726
|
-
} else {
|
|
4727
|
-
doc.write(`${outputVar}[${kx}] = ${out};`);
|
|
4728
|
-
}
|
|
4729
|
-
}
|
|
4730
|
-
}
|
|
4731
|
-
if (unknownKeysMode !== "none") {
|
|
4732
|
-
const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;
|
|
4733
|
-
doc.write(`for (const k in ${accessor}) {`);
|
|
4734
|
-
doc.indented((d) => {
|
|
4735
|
-
d.write(`if (k === "__proto__") continue;`);
|
|
4736
|
-
if (knownSet)
|
|
4737
|
-
d.write(`if (${knownSet}.has(k)) continue;`);
|
|
4738
|
-
if (unknownKeysMode === "passthrough") {
|
|
4739
|
-
d.write(`${outputVar}[k] = ${accessor}[k];`);
|
|
4740
|
-
} else {
|
|
4741
|
-
const valVar = newVar(ctx);
|
|
4742
|
-
d.write(`const ${valVar} = ${accessor}[k];`);
|
|
4743
|
-
const catchallOut = compileChild(d, ctx, catchall, valVar);
|
|
4744
|
-
d.write(`${outputVar}[k] = ${catchallOut};`);
|
|
4745
|
-
}
|
|
4746
|
-
});
|
|
4747
|
-
doc.write(`}`);
|
|
4748
|
-
}
|
|
4749
|
-
return outputVar;
|
|
4750
|
-
}
|
|
4751
|
-
function generateOptionalCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4752
|
-
const def = schema._zod.def;
|
|
4753
|
-
if (isExactOptional(schema)) {
|
|
4754
|
-
return generateCheck(doc, ctx, def.innerType, accessor, buildsValue);
|
|
4755
|
-
}
|
|
4756
|
-
if (def.innerType._zod.optin === "defaulted") {
|
|
4757
|
-
const outputVar = newVar(ctx);
|
|
4758
|
-
const branchVar = newVar(ctx);
|
|
4759
|
-
doc.write(`let ${outputVar};`);
|
|
4760
|
-
doc.write(`if (${accessor} === undefined) {`);
|
|
4761
|
-
doc.indented((d) => {
|
|
4762
|
-
d.write(`const ${branchVar} = (() => {`);
|
|
4763
|
-
d.indented((d2) => {
|
|
4764
|
-
const innerOutput = generateCheck(d2, ctx, def.innerType, accessor);
|
|
4765
|
-
d2.write(`return ${innerOutput};`);
|
|
4766
|
-
});
|
|
4767
|
-
d.write(`})();`);
|
|
4768
|
-
d.write(`if (${branchVar} !== INVALID) ${outputVar} = ${branchVar};`);
|
|
4769
|
-
});
|
|
4770
|
-
doc.write(`} else {`);
|
|
4771
|
-
doc.indented((d) => {
|
|
4772
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor);
|
|
4773
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4774
|
-
});
|
|
4775
|
-
doc.write(`}`);
|
|
4776
|
-
return outputVar;
|
|
4777
|
-
}
|
|
4778
|
-
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
4779
|
-
if (outputVar)
|
|
4780
|
-
doc.write(`let ${outputVar};`);
|
|
4781
|
-
doc.write(`if (${accessor} !== undefined) {`);
|
|
4782
|
-
doc.indented((d) => {
|
|
4783
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor, buildsValue);
|
|
4784
|
-
if (outputVar && innerOutput !== null)
|
|
4785
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4786
|
-
});
|
|
4787
|
-
doc.write(`}`);
|
|
4788
|
-
return outputVar;
|
|
4789
|
-
}
|
|
4790
|
-
function isExactOptional(schema) {
|
|
4791
|
-
return schema._zod.traits?.has("$ZodExactOptional") === true;
|
|
4792
|
-
}
|
|
4793
|
-
function requiresPresenceCheck(schema) {
|
|
4794
|
-
return schema._zod.optin === undefined && fastPathAcceptsAbsence(schema);
|
|
4795
|
-
}
|
|
4796
|
-
function fastPathAcceptsAbsence(schema) {
|
|
4797
|
-
if (schema._zod.def.coerce)
|
|
4798
|
-
return true;
|
|
4799
|
-
const def = schema._zod.def;
|
|
4800
|
-
switch (def.type) {
|
|
4801
|
-
case "any":
|
|
4802
|
-
case "unknown":
|
|
4803
|
-
case "undefined":
|
|
4804
|
-
case "void":
|
|
4805
|
-
case "default":
|
|
4806
|
-
case "prefault":
|
|
4807
|
-
case "transform":
|
|
4808
|
-
case "custom":
|
|
4809
|
-
case "lazy":
|
|
4810
|
-
return true;
|
|
4811
|
-
case "string":
|
|
4812
|
-
case "number":
|
|
4813
|
-
case "boolean":
|
|
4814
|
-
case "bigint":
|
|
4815
|
-
case "symbol":
|
|
4816
|
-
case "null":
|
|
4817
|
-
case "never":
|
|
4818
|
-
case "nan":
|
|
4819
|
-
case "date":
|
|
4820
|
-
case "object":
|
|
4821
|
-
case "array":
|
|
4822
|
-
case "tuple":
|
|
4823
|
-
case "record":
|
|
4824
|
-
case "map":
|
|
4825
|
-
case "set":
|
|
4826
|
-
case "file":
|
|
4827
|
-
case "template_literal":
|
|
4828
|
-
return false;
|
|
4829
|
-
case "nonoptional":
|
|
4830
|
-
return def.innerType ? fastPathAcceptsAbsence(def.innerType) : false;
|
|
4831
|
-
case "literal":
|
|
4832
|
-
return !!def.values?.includes(undefined);
|
|
4833
|
-
case "enum":
|
|
4834
|
-
return !!schema._zod.values?.has(undefined);
|
|
4835
|
-
case "optional":
|
|
4836
|
-
case "nullable":
|
|
4837
|
-
case "readonly":
|
|
4838
|
-
case "success":
|
|
4839
|
-
return def.innerType ? fastPathAcceptsAbsence(def.innerType) : true;
|
|
4840
|
-
case "catch":
|
|
4841
|
-
return true;
|
|
4842
|
-
case "union":
|
|
4843
|
-
return def.options ? def.options.some(fastPathAcceptsAbsence) : true;
|
|
4844
|
-
case "intersection":
|
|
4845
|
-
if (!def.left || !def.right)
|
|
4846
|
-
return true;
|
|
4847
|
-
return fastPathAcceptsAbsence(def.left) && fastPathAcceptsAbsence(def.right);
|
|
4848
|
-
case "pipe":
|
|
4849
|
-
return def.in ? fastPathAcceptsAbsence(def.in) : true;
|
|
4850
|
-
default:
|
|
4851
|
-
return true;
|
|
4852
|
-
}
|
|
4853
|
-
}
|
|
4854
|
-
function dropsWhenAbsent(schema) {
|
|
4855
|
-
return schema._zod.optin === "optional" && schema._zod.optout === "optional";
|
|
4856
|
-
}
|
|
4857
|
-
function mayOmitUndefined(schema) {
|
|
4858
|
-
return (schema._zod.optin !== "defaulted" || schema._zod.optout === "optional") && mayOutputUndefined(schema);
|
|
4859
|
-
}
|
|
4860
|
-
function mayOutputUndefined(schema) {
|
|
4861
|
-
const def = schema._zod.def;
|
|
4862
|
-
switch (def.type) {
|
|
4863
|
-
case "string":
|
|
4864
|
-
case "number":
|
|
4865
|
-
case "boolean":
|
|
4866
|
-
case "bigint":
|
|
4867
|
-
case "symbol":
|
|
4868
|
-
case "null":
|
|
4869
|
-
case "nan":
|
|
4870
|
-
case "date":
|
|
4871
|
-
case "object":
|
|
4872
|
-
case "array":
|
|
4873
|
-
case "tuple":
|
|
4874
|
-
case "record":
|
|
4875
|
-
case "map":
|
|
4876
|
-
case "set":
|
|
4877
|
-
case "file":
|
|
4878
|
-
case "template_literal":
|
|
4879
|
-
case "never":
|
|
4880
|
-
case "success":
|
|
4881
|
-
return false;
|
|
4882
|
-
case "literal":
|
|
4883
|
-
return !!def.values?.includes(undefined);
|
|
4884
|
-
case "enum":
|
|
4885
|
-
return !!schema._zod.values?.has(undefined);
|
|
4886
|
-
case "optional":
|
|
4887
|
-
return true;
|
|
4888
|
-
case "nullable":
|
|
4889
|
-
case "readonly":
|
|
4890
|
-
case "nonoptional":
|
|
4891
|
-
return def.innerType ? mayOutputUndefined(def.innerType) : true;
|
|
4892
|
-
case "union":
|
|
4893
|
-
return def.options ? def.options.some(mayOutputUndefined) : true;
|
|
4894
|
-
case "intersection":
|
|
4895
|
-
return !def.left || !def.right || mayOutputUndefined(def.left) || mayOutputUndefined(def.right);
|
|
4896
|
-
case "pipe":
|
|
4897
|
-
return def.out ? mayOutputUndefined(def.out) : true;
|
|
4898
|
-
default:
|
|
4899
|
-
return true;
|
|
4900
|
-
}
|
|
4901
|
-
}
|
|
4902
|
-
function generateNullableCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4903
|
-
const def = schema._zod.def;
|
|
4904
|
-
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
4905
|
-
if (outputVar)
|
|
4906
|
-
doc.write(`let ${outputVar} = null;`);
|
|
4907
|
-
doc.write(`if (${accessor} !== null) {`);
|
|
4908
|
-
doc.indented((d) => {
|
|
4909
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor, buildsValue);
|
|
4910
|
-
if (outputVar && innerOutput !== null)
|
|
4911
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
4912
|
-
});
|
|
4913
|
-
doc.write(`}`);
|
|
4914
|
-
return outputVar;
|
|
4915
|
-
}
|
|
4916
|
-
function generateArrayCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
4917
|
-
const def = schema._zod.def;
|
|
4918
|
-
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
4919
|
-
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
4920
|
-
const iVar = newVar(ctx);
|
|
4921
|
-
const elemVar = newVar(ctx);
|
|
4922
|
-
if (outputVar)
|
|
4923
|
-
doc.write(`const ${outputVar} = new Array(${accessor}.length);`);
|
|
4924
|
-
doc.write(`for (let ${iVar} = 0; ${iVar} < ${accessor}.length; ${iVar}++) {`);
|
|
4925
|
-
doc.indented((d) => {
|
|
4926
|
-
d.write(`const ${elemVar} = ${accessor}[${iVar}];`);
|
|
4927
|
-
const elemOutput = compileChild(d, ctx, def.element, elemVar, buildsValue);
|
|
4928
|
-
if (outputVar && elemOutput !== null)
|
|
4929
|
-
d.write(`${outputVar}[${iVar}] = ${elemOutput};`);
|
|
4930
|
-
});
|
|
4931
|
-
doc.write(`}`);
|
|
4932
|
-
return outputVar;
|
|
4933
|
-
}
|
|
4934
|
-
function generateLiteralCheck(doc, ctx, schema, accessor) {
|
|
4935
|
-
const def = schema._zod.def;
|
|
4936
|
-
const values = def.values;
|
|
4937
|
-
if (values.length !== 1) {
|
|
4938
|
-
const literalSet = addConstant(ctx, new Set(values));
|
|
4939
|
-
doc.write(`if (!${literalSet}.has(${accessor})) return INVALID;`);
|
|
4940
|
-
return accessor;
|
|
4941
|
-
}
|
|
4942
|
-
const value = values[0];
|
|
4943
|
-
if (typeof value === "number" && Number.isNaN(value)) {
|
|
4944
|
-
const literalSet = addConstant(ctx, new Set(values));
|
|
4945
|
-
doc.write(`if (!${literalSet}.has(${accessor})) return INVALID;`);
|
|
4946
|
-
return accessor;
|
|
4947
|
-
}
|
|
4948
|
-
if (typeof value === "string") {
|
|
4949
|
-
doc.write(`if (${accessor} !== ${esc(value)}) return INVALID;`);
|
|
4950
|
-
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
4951
|
-
doc.write(`if (${accessor} !== ${value}) return INVALID;`);
|
|
4952
|
-
} else if (value === null) {
|
|
4953
|
-
doc.write(`if (${accessor} !== null) return INVALID;`);
|
|
4954
|
-
} else if (value === undefined) {
|
|
4955
|
-
doc.write(`if (${accessor} !== undefined) return INVALID;`);
|
|
4956
|
-
} else if (typeof value === "bigint") {
|
|
4957
|
-
doc.write(`if (${accessor} !== ${value}n) return INVALID;`);
|
|
4958
|
-
} else {
|
|
4959
|
-
throw new ZodCompileUnsupportedError(`literal type ${typeof value}`);
|
|
4960
|
-
}
|
|
4961
|
-
return accessor;
|
|
4962
|
-
}
|
|
4963
|
-
function generateEnumCheck(doc, ctx, schema, accessor) {
|
|
4964
|
-
const values = schema._zod.values;
|
|
4965
|
-
if (!values) {
|
|
4966
|
-
throw new ZodCompileUnsupportedError("enum schema without enumerated values");
|
|
4967
|
-
}
|
|
4968
|
-
const enumSet = addConstant(ctx, values);
|
|
4969
|
-
doc.write(`if (!${enumSet}.has(${accessor})) return INVALID;`);
|
|
4970
|
-
return accessor;
|
|
4971
|
-
}
|
|
4972
|
-
function generateWrapperCheck(doc, ctx, schema, accessor) {
|
|
4973
|
-
const def = schema._zod.def;
|
|
4974
|
-
return generateCheck(doc, ctx, def.innerType, accessor);
|
|
4975
|
-
}
|
|
4976
|
-
function generateDefaultCheck(doc, ctx, schema, accessor) {
|
|
4977
|
-
const def = schema._zod.def;
|
|
4978
|
-
const descriptor = Object.getOwnPropertyDescriptor(schema._zod.def, "defaultValue");
|
|
4979
|
-
const defaultGetter = descriptor ? () => schema._zod.def.defaultValue : undefined;
|
|
4980
|
-
if (schema._zod.def.type === "prefault") {
|
|
4981
|
-
if (!defaultGetter) {
|
|
4982
|
-
return generateCheck(doc, ctx, def.innerType, accessor);
|
|
4983
|
-
}
|
|
4984
|
-
const defaultFn = addConstant(ctx, defaultGetter);
|
|
4985
|
-
const inputVar = newVar(ctx);
|
|
4986
|
-
doc.write(`let ${inputVar} = ${accessor};`);
|
|
4987
|
-
doc.write(`if (${accessor} === undefined) ${inputVar} = ${defaultFn}();`);
|
|
4988
|
-
return generateCheck(doc, ctx, def.innerType, inputVar);
|
|
4989
|
-
}
|
|
4990
|
-
const outputVar = newVar(ctx);
|
|
4991
|
-
if (defaultGetter) {
|
|
4992
|
-
const defaultFn = addConstant(ctx, defaultGetter);
|
|
4993
|
-
const cloneFn = addConstant(ctx, shallowClone);
|
|
4994
|
-
doc.write(`let ${outputVar};`);
|
|
4995
|
-
doc.write(`if (${accessor} === undefined) {`);
|
|
4996
|
-
doc.indented((d) => {
|
|
4997
|
-
d.write(`${outputVar} = ${cloneFn}(${defaultFn}());`);
|
|
4998
|
-
});
|
|
4999
|
-
doc.write(`} else {`);
|
|
5000
|
-
doc.indented((d) => {
|
|
5001
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor);
|
|
5002
|
-
d.write(`${outputVar} = ${innerOutput} === undefined ? ${cloneFn}(${defaultFn}()) : ${innerOutput};`);
|
|
5003
|
-
});
|
|
5004
|
-
doc.write(`}`);
|
|
5005
|
-
} else {
|
|
5006
|
-
doc.write(`let ${outputVar};`);
|
|
5007
|
-
doc.write(`if (${accessor} !== undefined) {`);
|
|
5008
|
-
doc.indented((d) => {
|
|
5009
|
-
const innerOutput = generateCheck(d, ctx, def.innerType, accessor);
|
|
5010
|
-
d.write(`${outputVar} = ${innerOutput};`);
|
|
5011
|
-
});
|
|
5012
|
-
doc.write(`}`);
|
|
5013
|
-
}
|
|
5014
|
-
return outputVar;
|
|
5015
|
-
}
|
|
5016
|
-
function generateNonOptionalCheck(doc, ctx, schema, accessor) {
|
|
5017
|
-
const def = schema._zod.def;
|
|
5018
|
-
const innerOutput = generateCheck(doc, ctx, def.innerType, accessor);
|
|
5019
|
-
const outputVar = newVar(ctx);
|
|
5020
|
-
doc.write(`const ${outputVar} = ${innerOutput};`);
|
|
5021
|
-
doc.write(`if (${outputVar} === undefined) return INVALID;`);
|
|
5022
|
-
return outputVar;
|
|
5023
|
-
}
|
|
5024
|
-
function generateTupleCheck(doc, ctx, schema, accessor) {
|
|
5025
|
-
const def = schema._zod.def;
|
|
5026
|
-
const items = def.items;
|
|
5027
|
-
const rest = def.rest;
|
|
5028
|
-
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
5029
|
-
const optinStart = getTupleOptStart(items, "optin");
|
|
5030
|
-
const optoutStart = getTupleOptStart(items, "optout");
|
|
5031
|
-
if (rest) {
|
|
5032
|
-
doc.write(`if (${accessor}.length < ${optinStart}) return INVALID;`);
|
|
5033
|
-
} else {
|
|
5034
|
-
doc.write(`if (${accessor}.length < ${optinStart} || ${accessor}.length > ${items.length}) return INVALID;`);
|
|
5035
|
-
}
|
|
5036
|
-
const outputVar = newVar(ctx);
|
|
5037
|
-
doc.write(`const ${outputVar} = [];`);
|
|
5038
|
-
for (let i = 0;i < items.length; i++) {
|
|
5039
|
-
const itemSchema = items[i];
|
|
5040
|
-
if (i >= optoutStart) {
|
|
5041
|
-
doc.write(`if (${outputVar}.length === ${i}) {`);
|
|
5042
|
-
doc.indented((d) => {
|
|
5043
|
-
d.write(`if (${i} < ${accessor}.length) {`);
|
|
5044
|
-
d.indented((d2) => {
|
|
5045
|
-
const elemVar = newVar(ctx);
|
|
5046
|
-
d2.write(`const ${elemVar} = ${accessor}[${i}];`);
|
|
5047
|
-
const elemOutput = compileChild(d2, ctx, itemSchema, elemVar);
|
|
5048
|
-
d2.write(`${outputVar}[${i}] = ${elemOutput};`);
|
|
5049
|
-
});
|
|
5050
|
-
d.write(`} else {`);
|
|
5051
|
-
d.indented((d2) => {
|
|
5052
|
-
if (dropsWhenAbsent(itemSchema)) {
|
|
5053
|
-
d2.write(`${outputVar}.length = ${i};`);
|
|
5054
|
-
return;
|
|
5055
|
-
}
|
|
5056
|
-
const elemVar = newVar(ctx);
|
|
5057
|
-
const branchVar = newVar(ctx);
|
|
5058
|
-
d2.write(`const ${elemVar} = undefined;`);
|
|
5059
|
-
d2.write(`const ${branchVar} = (() => {`);
|
|
5060
|
-
d2.indented((d3) => {
|
|
5061
|
-
const elemOutput = compileChild(d3, ctx, itemSchema, elemVar);
|
|
5062
|
-
d3.write(`return ${elemOutput};`);
|
|
5063
|
-
});
|
|
5064
|
-
d2.write(`})();`);
|
|
5065
|
-
d2.write(`if (${branchVar} === INVALID || ${branchVar} === undefined) ${outputVar}.length = ${i};`);
|
|
5066
|
-
d2.write(`else ${outputVar}[${i}] = ${branchVar};`);
|
|
5067
|
-
});
|
|
5068
|
-
d.write(`}`);
|
|
5069
|
-
});
|
|
5070
|
-
doc.write(`}`);
|
|
5071
|
-
} else {
|
|
5072
|
-
const elemVar = newVar(ctx);
|
|
5073
|
-
doc.write(`const ${elemVar} = ${accessor}[${i}];`);
|
|
5074
|
-
const elemOutput = compileChild(doc, ctx, itemSchema, elemVar);
|
|
5075
|
-
doc.write(`${outputVar}[${i}] = ${elemOutput};`);
|
|
5076
|
-
}
|
|
5077
|
-
}
|
|
5078
|
-
if (rest) {
|
|
5079
|
-
const iVar = newVar(ctx);
|
|
5080
|
-
const elemVar = newVar(ctx);
|
|
5081
|
-
doc.write(`for (let ${iVar} = ${items.length}; ${iVar} < ${accessor}.length; ${iVar}++) {`);
|
|
5082
|
-
doc.indented((d) => {
|
|
5083
|
-
d.write(`const ${elemVar} = ${accessor}[${iVar}];`);
|
|
5084
|
-
const elemOutput = compileChild(d, ctx, rest, elemVar);
|
|
5085
|
-
d.write(`${outputVar}[${iVar}] = ${elemOutput};`);
|
|
5086
|
-
});
|
|
5087
|
-
doc.write(`}`);
|
|
5088
|
-
}
|
|
5089
|
-
return outputVar;
|
|
5090
|
-
}
|
|
5091
|
-
function getTupleOptStart(items, key) {
|
|
5092
|
-
for (let i = items.length - 1;i >= 0; i--) {
|
|
5093
|
-
const omittable = key === "optin" ? items[i]._zod.optin !== undefined : items[i]._zod.optout === "optional";
|
|
5094
|
-
if (!omittable)
|
|
5095
|
-
return i + 1;
|
|
3792
|
+
// node_modules/zod/v4/core/registries.js
|
|
3793
|
+
var _a2;
|
|
3794
|
+
class $ZodRegistry {
|
|
3795
|
+
constructor() {
|
|
3796
|
+
this._map = new WeakMap;
|
|
3797
|
+
this._idmap = new Map;
|
|
5096
3798
|
}
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
if (def.discriminator) {
|
|
5103
|
-
return generateDiscriminatedUnionCheck(doc, ctx, def, accessor);
|
|
5104
|
-
}
|
|
5105
|
-
if (def.inclusive === false) {
|
|
5106
|
-
throw new ZodCompileUnsupportedError("exclusive unions (z.xor)");
|
|
5107
|
-
}
|
|
5108
|
-
if (options.length === 0) {
|
|
5109
|
-
doc.write("return INVALID;");
|
|
5110
|
-
return accessor;
|
|
5111
|
-
}
|
|
5112
|
-
if (options.length === 1) {
|
|
5113
|
-
return generateCheck(doc, ctx, options[0], accessor);
|
|
5114
|
-
}
|
|
5115
|
-
const allLiterals = options.every((opt) => opt._zod.def.type === "literal" && !opt._zod.def.checks?.length);
|
|
5116
|
-
if (allLiterals) {
|
|
5117
|
-
const values = new Set(options.flatMap((opt) => opt._zod.def.values));
|
|
5118
|
-
const valuesConst = addConstant(ctx, values);
|
|
5119
|
-
doc.write(`if (!${valuesConst}.has(${accessor})) return INVALID;`);
|
|
5120
|
-
return accessor;
|
|
5121
|
-
}
|
|
5122
|
-
const outputVar = newVar(ctx);
|
|
5123
|
-
doc.write(`let ${outputVar};`);
|
|
5124
|
-
for (let i = 0;i < options.length; i++) {
|
|
5125
|
-
const opt = options[i];
|
|
5126
|
-
if (i === 0) {
|
|
5127
|
-
doc.write(`${outputVar} = (() => {`);
|
|
5128
|
-
} else {
|
|
5129
|
-
doc.write(`if (${outputVar} === INVALID) ${outputVar} = (() => {`);
|
|
3799
|
+
add(schema, ..._meta) {
|
|
3800
|
+
const meta = _meta[0];
|
|
3801
|
+
this._map.set(schema, meta);
|
|
3802
|
+
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3803
|
+
this._idmap.set(meta.id, schema);
|
|
5130
3804
|
}
|
|
5131
|
-
|
|
5132
|
-
const branchOutput = generateCheck(d, ctx, opt, accessor);
|
|
5133
|
-
d.write(`return ${branchOutput};`);
|
|
5134
|
-
});
|
|
5135
|
-
doc.write(`})();`);
|
|
5136
|
-
}
|
|
5137
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
5138
|
-
return outputVar;
|
|
5139
|
-
}
|
|
5140
|
-
function generateDiscriminatedUnionCheck(doc, ctx, def, accessor) {
|
|
5141
|
-
if (def.unionFallback) {
|
|
5142
|
-
throw new ZodCompileUnsupportedError("discriminated union with unionFallback");
|
|
3805
|
+
return this;
|
|
5143
3806
|
}
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
3807
|
+
clear() {
|
|
3808
|
+
this._map = new WeakMap;
|
|
3809
|
+
this._idmap = new Map;
|
|
3810
|
+
return this;
|
|
5147
3811
|
}
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
let firstBranch = true;
|
|
5153
|
-
const claimed = new Set;
|
|
5154
|
-
for (const option of def.options) {
|
|
5155
|
-
const values = option._zod.propValues?.[def.discriminator];
|
|
5156
|
-
if (!values || values.size === 0) {
|
|
5157
|
-
throw new ZodCompileUnsupportedError("discriminated union option without static discriminator values");
|
|
3812
|
+
remove(schema) {
|
|
3813
|
+
const meta = this._map.get(schema);
|
|
3814
|
+
if (meta && typeof meta === "object" && "id" in meta) {
|
|
3815
|
+
this._idmap.delete(meta.id);
|
|
5158
3816
|
}
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
throw new ZodCompileUnsupportedError(`duplicate discriminator value ${String(value)}`);
|
|
5162
|
-
}
|
|
5163
|
-
claimed.add(value);
|
|
5164
|
-
}
|
|
5165
|
-
const conditions = Array.from(values, (value) => literalEquality(ctx, discVar, value));
|
|
5166
|
-
const prefix = firstBranch ? "if" : "else if";
|
|
5167
|
-
doc.write(`${prefix} (${conditions.join(" || ")}) {`);
|
|
5168
|
-
doc.indented((d) => {
|
|
5169
|
-
const branchOutput = generateCheck(d, ctx, option, accessor);
|
|
5170
|
-
d.write(`${outputVar} = ${branchOutput};`);
|
|
5171
|
-
});
|
|
5172
|
-
doc.write(`}`);
|
|
5173
|
-
firstBranch = false;
|
|
5174
|
-
}
|
|
5175
|
-
doc.write(`else { return INVALID; }`);
|
|
5176
|
-
return outputVar;
|
|
5177
|
-
}
|
|
5178
|
-
function literalEquality(ctx, accessor, value) {
|
|
5179
|
-
if (typeof value === "string")
|
|
5180
|
-
return `${accessor} === ${esc(value)}`;
|
|
5181
|
-
if (typeof value === "number") {
|
|
5182
|
-
if (Number.isNaN(value))
|
|
5183
|
-
return `Number.isNaN(${accessor})`;
|
|
5184
|
-
return `${accessor} === ${value}`;
|
|
5185
|
-
}
|
|
5186
|
-
if (typeof value === "boolean")
|
|
5187
|
-
return `${accessor} === ${value}`;
|
|
5188
|
-
if (value === null)
|
|
5189
|
-
return `${accessor} === null`;
|
|
5190
|
-
if (value === undefined)
|
|
5191
|
-
return `${accessor} === undefined`;
|
|
5192
|
-
if (typeof value === "bigint")
|
|
5193
|
-
return `${accessor} === ${value}n`;
|
|
5194
|
-
if (typeof value === "symbol") {
|
|
5195
|
-
const symbolConst = addConstant(ctx, value);
|
|
5196
|
-
return `${accessor} === ${symbolConst}`;
|
|
5197
|
-
}
|
|
5198
|
-
throw new ZodCompileUnsupportedError(`literal discriminator value ${String(value)}`);
|
|
5199
|
-
}
|
|
5200
|
-
function generateIntersectionCheck(doc, ctx, schema, accessor) {
|
|
5201
|
-
const def = schema._zod.def;
|
|
5202
|
-
ctx.definite = false;
|
|
5203
|
-
const leftOutput = compileChild(doc, ctx, def.left, accessor);
|
|
5204
|
-
const rightOutput = compileChild(doc, ctx, def.right, accessor);
|
|
5205
|
-
const mergeConst = addConstant(ctx, mergeValues);
|
|
5206
|
-
const mergedVar = newVar(ctx);
|
|
5207
|
-
doc.write(`const ${mergedVar} = ${mergeConst}(${leftOutput}, ${rightOutput});`);
|
|
5208
|
-
doc.write(`if (!${mergedVar}.valid) return INVALID;`);
|
|
5209
|
-
return `${mergedVar}.data`;
|
|
5210
|
-
}
|
|
5211
|
-
function generateRecordCheck(doc, ctx, schema, accessor) {
|
|
5212
|
-
const def = schema._zod.def;
|
|
5213
|
-
const isPlainObjectConst = addConstant(ctx, isPlainObject);
|
|
5214
|
-
doc.write(`if (!${isPlainObjectConst}(${accessor})) return INVALID;`);
|
|
5215
|
-
const outputVar = newVar(ctx);
|
|
5216
|
-
const kVar = newVar(ctx);
|
|
5217
|
-
const valVar = newVar(ctx);
|
|
5218
|
-
doc.write(`const ${outputVar} = {};`);
|
|
5219
|
-
const recordDef = def;
|
|
5220
|
-
const keyValues = recordDef.partial ? undefined : def.keyType._zod.values;
|
|
5221
|
-
if (keyValues) {
|
|
5222
|
-
const inputKeys = [];
|
|
5223
|
-
for (const key of keyValues) {
|
|
5224
|
-
if (!(typeof key === "string" || typeof key === "number" || typeof key === "symbol")) {
|
|
5225
|
-
throw new ZodCompileUnsupportedError(`record key value ${String(key)}`);
|
|
5226
|
-
}
|
|
5227
|
-
const inputKey = typeof key === "number" ? key.toString() : key;
|
|
5228
|
-
if (inputKey === "__proto__") {
|
|
5229
|
-
throw new ZodCompileUnsupportedError('record key "__proto__"');
|
|
5230
|
-
}
|
|
5231
|
-
inputKeys.push(inputKey);
|
|
5232
|
-
const keyConst = addConstant(ctx, key);
|
|
5233
|
-
const outKey = generateCheck(doc, ctx, def.keyType, keyConst);
|
|
5234
|
-
const valueVar = newVar(ctx);
|
|
5235
|
-
doc.write(`const ${valueVar} = ${accessor}[${literalPropertyKey(ctx, inputKey)}];`);
|
|
5236
|
-
const valOutput = compileChild(doc, ctx, def.valueType, valueVar);
|
|
5237
|
-
doc.write(`${outputVar}[${outKey}] = ${valOutput};`);
|
|
5238
|
-
}
|
|
5239
|
-
const knownKeysConst = addConstant(ctx, new Set(inputKeys));
|
|
5240
|
-
doc.write(`for (const ${kVar} in ${accessor}) {`);
|
|
5241
|
-
doc.indented((d) => {
|
|
5242
|
-
d.write(`if (${knownKeysConst}.has(${kVar})) continue;`);
|
|
5243
|
-
if (recordDef.mode === "loose") {
|
|
5244
|
-
d.write(`if (${kVar} !== "__proto__") ${outputVar}[${kVar}] = ${accessor}[${kVar}];`);
|
|
5245
|
-
} else {
|
|
5246
|
-
d.write(`return INVALID;`);
|
|
5247
|
-
}
|
|
5248
|
-
});
|
|
5249
|
-
doc.write(`}`);
|
|
5250
|
-
return outputVar;
|
|
5251
|
-
}
|
|
5252
|
-
const keyDef = def.keyType._zod.def;
|
|
5253
|
-
const keyIsBareString = keyDef.type === "string" && keyDef.format === undefined && !keyDef.coerce && (keyDef.checks?.length ?? 0) === 0;
|
|
5254
|
-
if (!keyIsBareString) {
|
|
5255
|
-
const isLoose = def.mode === "loose";
|
|
5256
|
-
const keyFn = compileFn(def.keyType);
|
|
5257
|
-
if (keyFn.definite === false)
|
|
5258
|
-
ctx.definite = false;
|
|
5259
|
-
const keyFast = addConstant(ctx, keyFn);
|
|
5260
|
-
const numericConst = addConstant(ctx, number);
|
|
5261
|
-
const outKeyVar = newVar(ctx);
|
|
5262
|
-
emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
|
|
5263
|
-
d.write(`let ${outKeyVar} = ${keyFast}(${kVar});`);
|
|
5264
|
-
d.write(`if (${outKeyVar} === INVALID && typeof ${kVar} === "string" && ${numericConst}.test(${kVar})) ${outKeyVar} = ${keyFast}(Number(${kVar}));`);
|
|
5265
|
-
if (isLoose) {
|
|
5266
|
-
d.write(`if (${outKeyVar} === INVALID) { ${outputVar}[${kVar}] = ${accessor}[${kVar}]; continue; }`);
|
|
5267
|
-
} else {
|
|
5268
|
-
d.write(`if (${outKeyVar} === INVALID) return INVALID;`);
|
|
5269
|
-
}
|
|
5270
|
-
d.write(`if (${outKeyVar} === "__proto__") continue;`);
|
|
5271
|
-
const valueVar = newVar(ctx);
|
|
5272
|
-
d.write(`const ${valueVar} = ${accessor}[${kVar}];`);
|
|
5273
|
-
const valOutput = compileChild(d, ctx, def.valueType, valueVar);
|
|
5274
|
-
d.write(`${outputVar}[${outKeyVar}] = ${valOutput};`);
|
|
5275
|
-
});
|
|
5276
|
-
return outputVar;
|
|
5277
|
-
}
|
|
5278
|
-
emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
|
|
5279
|
-
d.write(`const ${valVar} = ${accessor}[${kVar}];`);
|
|
5280
|
-
const valOutput = compileChild(d, ctx, def.valueType, valVar);
|
|
5281
|
-
d.write(`${outputVar}[${kVar}] = ${valOutput};`);
|
|
5282
|
-
}, `return INVALID;`);
|
|
5283
|
-
return outputVar;
|
|
5284
|
-
}
|
|
5285
|
-
function emitOwnKeys(doc, ctx, accessor, kVar, body, onSymbol) {
|
|
5286
|
-
const propIsEnumerableConst = addConstant(ctx, Object.prototype.propertyIsEnumerable);
|
|
5287
|
-
const symsVar = newVar(ctx);
|
|
5288
|
-
const keysVar = newVar(ctx);
|
|
5289
|
-
const iVar = newVar(ctx);
|
|
5290
|
-
doc.write(`const ${symsVar} = Object.getOwnPropertySymbols(${accessor});`);
|
|
5291
|
-
doc.write(`const ${keysVar} = Object.getOwnPropertyNames(${accessor});`);
|
|
5292
|
-
doc.write(`for (let ${iVar} = 0; ${iVar} < ${keysVar}.length; ${iVar}++) {`);
|
|
5293
|
-
doc.indented((d) => {
|
|
5294
|
-
d.write(`const ${kVar} = ${keysVar}[${iVar}];`);
|
|
5295
|
-
d.write(`if (${kVar} === "__proto__" || !${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
|
|
5296
|
-
body(d);
|
|
5297
|
-
});
|
|
5298
|
-
doc.write(`}`);
|
|
5299
|
-
doc.write(`for (let ${iVar} = 0; ${iVar} < ${symsVar}.length; ${iVar}++) {`);
|
|
5300
|
-
doc.indented((d) => {
|
|
5301
|
-
d.write(`const ${kVar} = ${symsVar}[${iVar}];`);
|
|
5302
|
-
d.write(`if (!${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
|
|
5303
|
-
if (onSymbol)
|
|
5304
|
-
d.write(onSymbol);
|
|
5305
|
-
else
|
|
5306
|
-
body(d);
|
|
5307
|
-
});
|
|
5308
|
-
doc.write(`}`);
|
|
5309
|
-
}
|
|
5310
|
-
function literalPropertyKey(ctx, key) {
|
|
5311
|
-
if (typeof key === "string")
|
|
5312
|
-
return esc(key);
|
|
5313
|
-
return addConstant(ctx, key);
|
|
5314
|
-
}
|
|
5315
|
-
function generateMapCheck(doc, ctx, schema, accessor) {
|
|
5316
|
-
const def = schema._zod.def;
|
|
5317
|
-
doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
|
|
5318
|
-
const outputVar = newVar(ctx);
|
|
5319
|
-
const kVar = newVar(ctx);
|
|
5320
|
-
const valVar = newVar(ctx);
|
|
5321
|
-
doc.write(`const ${outputVar} = new Map();`);
|
|
5322
|
-
doc.write(`for (const [${kVar}, ${valVar}] of ${accessor}) {`);
|
|
5323
|
-
doc.indented((d) => {
|
|
5324
|
-
const keyOutput = generateCheck(d, ctx, def.keyType, kVar);
|
|
5325
|
-
const valOutput = generateCheck(d, ctx, def.valueType, valVar);
|
|
5326
|
-
d.write(`${outputVar}.set(${keyOutput}, ${valOutput});`);
|
|
5327
|
-
});
|
|
5328
|
-
doc.write(`}`);
|
|
5329
|
-
return outputVar;
|
|
5330
|
-
}
|
|
5331
|
-
function generateSetCheck(doc, ctx, schema, accessor) {
|
|
5332
|
-
const def = schema._zod.def;
|
|
5333
|
-
doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
|
|
5334
|
-
const outputVar = newVar(ctx);
|
|
5335
|
-
const valVar = newVar(ctx);
|
|
5336
|
-
doc.write(`const ${outputVar} = new Set();`);
|
|
5337
|
-
doc.write(`for (const ${valVar} of ${accessor}) {`);
|
|
5338
|
-
doc.indented((d) => {
|
|
5339
|
-
const valOutput = generateCheck(d, ctx, def.valueType, valVar);
|
|
5340
|
-
d.write(`${outputVar}.add(${valOutput});`);
|
|
5341
|
-
});
|
|
5342
|
-
doc.write(`}`);
|
|
5343
|
-
return outputVar;
|
|
5344
|
-
}
|
|
5345
|
-
function generateFileCheck(doc, accessor) {
|
|
5346
|
-
doc.write(`if (!(${accessor} instanceof File)) return INVALID;`);
|
|
5347
|
-
return accessor;
|
|
5348
|
-
}
|
|
5349
|
-
function generateTemplateLiteralCheck(doc, ctx, schema, accessor) {
|
|
5350
|
-
doc.write(`if (typeof ${accessor} !== "string") return INVALID;`);
|
|
5351
|
-
const pattern = schema._zod.pattern;
|
|
5352
|
-
if (pattern) {
|
|
5353
|
-
const patternConst = addConstant(ctx, pattern);
|
|
5354
|
-
doc.write(`${patternConst}.lastIndex = 0;`);
|
|
5355
|
-
doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);
|
|
3817
|
+
this._map.delete(schema);
|
|
3818
|
+
return this;
|
|
5356
3819
|
}
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
d.write(`${cacheConst}.parser = function(input) {`);
|
|
5367
|
-
d.indented((d2) => {
|
|
5368
|
-
d2.write(`const result = inner._zod.run({ value: input, issues: [] }, {});`);
|
|
5369
|
-
d2.write(`return result.issues.length === 0 ? result.value : INVALID;`);
|
|
5370
|
-
});
|
|
5371
|
-
d.write(`};`);
|
|
5372
|
-
});
|
|
5373
|
-
doc.write(`}`);
|
|
5374
|
-
const outputVar = newVar(ctx);
|
|
5375
|
-
doc.write(`const ${outputVar} = ${cacheConst}.parser(${accessor});`);
|
|
5376
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
5377
|
-
return outputVar;
|
|
5378
|
-
}
|
|
5379
|
-
function generatePipeCheck(doc, ctx, schema, accessor) {
|
|
5380
|
-
const def = schema._zod.def;
|
|
5381
|
-
const inputOutput = generateCheck(doc, ctx, def.in, accessor);
|
|
5382
|
-
if (def.transform) {
|
|
5383
|
-
if (isAsyncFunction(def.transform)) {
|
|
5384
|
-
throw new ZodCompileAsyncError("z.compile: async transforms in pipes are not supported");
|
|
5385
|
-
}
|
|
5386
|
-
const transformFn = def.transform;
|
|
5387
|
-
const helperFn = (value) => {
|
|
5388
|
-
const fakePayload = { value, issues: [], addIssue: pushIssue };
|
|
5389
|
-
const result = transformFn(value, fakePayload);
|
|
5390
|
-
if (result instanceof Promise)
|
|
5391
|
-
return INVALID;
|
|
5392
|
-
return fakePayload.issues.length === 0 ? result : INVALID;
|
|
5393
|
-
};
|
|
5394
|
-
const helperConst = addUserConstant(ctx, helperFn);
|
|
5395
|
-
const transformedVar = newVar(ctx);
|
|
5396
|
-
doc.write(`const ${transformedVar} = ${helperConst}(${inputOutput});`);
|
|
5397
|
-
doc.write(`if (${transformedVar} === INVALID) return INVALID;`);
|
|
5398
|
-
return generateCheck(doc, ctx, def.out, transformedVar);
|
|
5399
|
-
} else {
|
|
5400
|
-
return generateCheck(doc, ctx, def.out, inputOutput);
|
|
3820
|
+
get(schema) {
|
|
3821
|
+
const p = schema._zod.parent;
|
|
3822
|
+
if (p) {
|
|
3823
|
+
const pm = { ...this.get(p) ?? {} };
|
|
3824
|
+
delete pm.id;
|
|
3825
|
+
const f = { ...pm, ...this._map.get(schema) };
|
|
3826
|
+
return Object.keys(f).length ? f : undefined;
|
|
3827
|
+
}
|
|
3828
|
+
return this._map.get(schema);
|
|
5401
3829
|
}
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
return typeof fn === "function" && (fn.constructor.name === "AsyncFunction" || fn[Symbol.toStringTag] === "AsyncFunction");
|
|
5405
|
-
}
|
|
5406
|
-
function generateCustomCheck(doc, ctx, schema, accessor) {
|
|
5407
|
-
const def = schema._zod.def;
|
|
5408
|
-
if (def.fn) {
|
|
5409
|
-
if (isAsyncFunction(def.fn)) {
|
|
5410
|
-
throw new ZodCompileAsyncError("z.compile: async custom predicates are not supported");
|
|
5411
|
-
}
|
|
5412
|
-
const fnConst = addUserConstant(ctx, def.fn);
|
|
5413
|
-
const throwAsyncConst = addConstant(ctx, throwAsync);
|
|
5414
|
-
const resVar = newVar(ctx);
|
|
5415
|
-
doc.write(`const ${resVar} = ${fnConst}(${accessor});`);
|
|
5416
|
-
doc.write(`if (${resVar} instanceof Promise) ${throwAsyncConst}();`);
|
|
5417
|
-
doc.write(`if (!${resVar}) return INVALID;`);
|
|
5418
|
-
} else {
|
|
5419
|
-
throw new ZodCompileUnsupportedError("custom schema without a predicate function");
|
|
3830
|
+
has(schema) {
|
|
3831
|
+
return this._map.has(schema);
|
|
5420
3832
|
}
|
|
5421
|
-
return accessor;
|
|
5422
3833
|
}
|
|
5423
|
-
function
|
|
5424
|
-
|
|
5425
|
-
if (result && typeof result.then === "function")
|
|
5426
|
-
return INVALID;
|
|
5427
|
-
const r = result;
|
|
5428
|
-
if (r.issues.length === 0)
|
|
5429
|
-
return r.value;
|
|
5430
|
-
return catchValue();
|
|
5431
|
-
}
|
|
5432
|
-
function generateCatchCheck(doc, ctx, schema, accessor) {
|
|
5433
|
-
const def = schema._zod.def;
|
|
5434
|
-
if (!def.catchValue[CONSTANT_CATCH]) {
|
|
5435
|
-
throw new ZodCompileUnsupportedError("catch with a callback (only a constant catch value compiles)", false);
|
|
5436
|
-
}
|
|
5437
|
-
const outputVar = newVar(ctx);
|
|
5438
|
-
doc.write(`let ${outputVar} = (() => {`);
|
|
5439
|
-
doc.indented((d) => {
|
|
5440
|
-
const innerOut = compileChild(d, ctx, def.innerType, accessor);
|
|
5441
|
-
d.write(`return ${innerOut};`);
|
|
5442
|
-
});
|
|
5443
|
-
doc.write(`})();`);
|
|
5444
|
-
const innerConst = addConstant(ctx, def.innerType);
|
|
5445
|
-
const catchConst = addUserConstant(ctx, def.catchValue);
|
|
5446
|
-
const catchHelperConst = addConstant(ctx, runtimeCatch);
|
|
5447
|
-
doc.write(`if (${outputVar} === INVALID) {`);
|
|
5448
|
-
doc.indented((d) => {
|
|
5449
|
-
d.write(`${outputVar} = ${catchHelperConst}(${innerConst}, ${catchConst}, ${accessor});`);
|
|
5450
|
-
d.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
5451
|
-
});
|
|
5452
|
-
doc.write(`}`);
|
|
5453
|
-
return outputVar;
|
|
5454
|
-
}
|
|
5455
|
-
function generateTransformCheck(doc, ctx, schema, accessor) {
|
|
5456
|
-
const def = schema._zod.def;
|
|
5457
|
-
if (def.transform) {
|
|
5458
|
-
if (isAsyncFunction(def.transform)) {
|
|
5459
|
-
throw new ZodCompileAsyncError("z.compile: async transforms are not supported");
|
|
5460
|
-
}
|
|
5461
|
-
const transformFn = def.transform;
|
|
5462
|
-
const helperFn = (value) => {
|
|
5463
|
-
const fakePayload = { value, issues: [], addIssue: pushIssue };
|
|
5464
|
-
const result = transformFn(value, fakePayload);
|
|
5465
|
-
if (result instanceof Promise)
|
|
5466
|
-
return INVALID;
|
|
5467
|
-
return fakePayload.issues.length === 0 ? result : INVALID;
|
|
5468
|
-
};
|
|
5469
|
-
const helperConst = addUserConstant(ctx, helperFn);
|
|
5470
|
-
const outputVar = newVar(ctx);
|
|
5471
|
-
doc.write(`const ${outputVar} = ${helperConst}(${accessor});`);
|
|
5472
|
-
doc.write(`if (${outputVar} === INVALID) return INVALID;`);
|
|
5473
|
-
return outputVar;
|
|
5474
|
-
}
|
|
5475
|
-
return accessor;
|
|
3834
|
+
function registry() {
|
|
3835
|
+
return new $ZodRegistry;
|
|
5476
3836
|
}
|
|
3837
|
+
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
|
|
3838
|
+
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
5477
3839
|
// node_modules/zod/v4/core/api.js
|
|
5478
3840
|
function snapshotChecks(def) {
|
|
5479
3841
|
if (def.checks)
|
|
@@ -7954,15 +6316,6 @@ function superRefine(fn, params) {
|
|
|
7954
6316
|
// packages/workit-core/src/core/task-contract.ts
|
|
7955
6317
|
var SCHEMA_VERSION = 1;
|
|
7956
6318
|
var POLICY_VERSION = "1.0.0";
|
|
7957
|
-
var OPERATION_FAMILIES = [
|
|
7958
|
-
"task",
|
|
7959
|
-
"policy",
|
|
7960
|
-
"evidence",
|
|
7961
|
-
"finding",
|
|
7962
|
-
"decision",
|
|
7963
|
-
"worker",
|
|
7964
|
-
"state"
|
|
7965
|
-
];
|
|
7966
6319
|
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}$/;
|
|
7967
6320
|
var digestPattern = /^[0-9a-f]{64}$/;
|
|
7968
6321
|
var invalidUnicode = (value) => {
|
|
@@ -8698,7 +7051,6 @@ var advertisedOperationSchemas = {
|
|
|
8698
7051
|
worker: advertised(workerOperations),
|
|
8699
7052
|
state: advertised(stateOperations)
|
|
8700
7053
|
};
|
|
8701
|
-
var compiledOperationSchemas = Object.fromEntries(OPERATION_FAMILIES.map((family) => [family, compile(operationSchemas[family])]));
|
|
8702
7054
|
var success = (revisionValue, workspaceRevisionValue, data) => ({
|
|
8703
7055
|
ok: true,
|
|
8704
7056
|
schemaVersion: 1,
|
|
@@ -8720,8 +7072,7 @@ function resolveIdRef(kind, ref, ids) {
|
|
|
8720
7072
|
function parseOperation(family, input) {
|
|
8721
7073
|
if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
|
|
8722
7074
|
return failure2("unsupported_version", "unsupported schema version", { operation: family });
|
|
8723
|
-
const
|
|
8724
|
-
const parsed = compiled.success ? operationSchemas[family].safeParse(input) : compiled;
|
|
7075
|
+
const parsed = operationSchemas[family].safeParse(input);
|
|
8725
7076
|
if (parsed.success)
|
|
8726
7077
|
return success(null, null, parsed.data);
|
|
8727
7078
|
const fields = parsed.error.issues.map((issue) => ({
|
|
@@ -19332,6 +17683,24 @@ function workitInvocations(command, dialect = "posix", depth = 0) {
|
|
|
19332
17683
|
}
|
|
19333
17684
|
return found;
|
|
19334
17685
|
}
|
|
17686
|
+
var WORKIT_GLOBAL = /^--(?:cwd|session|token|as)(=|$)/;
|
|
17687
|
+
function skipWorkitGlobals(args) {
|
|
17688
|
+
let cwd = null;
|
|
17689
|
+
let at = 0;
|
|
17690
|
+
for (;at < args.length; at++) {
|
|
17691
|
+
const match = WORKIT_GLOBAL.exec(args[at]);
|
|
17692
|
+
if (match?.[1] === "=") {
|
|
17693
|
+
if (args[at].startsWith("--cwd="))
|
|
17694
|
+
cwd = args[at].slice(6);
|
|
17695
|
+
} else if (match && args[at + 1] !== undefined) {
|
|
17696
|
+
if (args[at] === "--cwd")
|
|
17697
|
+
cwd = args[at + 1];
|
|
17698
|
+
at++;
|
|
17699
|
+
} else if (args[at] !== "--json")
|
|
17700
|
+
break;
|
|
17701
|
+
}
|
|
17702
|
+
return { rest: args.slice(at), cwd };
|
|
17703
|
+
}
|
|
19335
17704
|
var PUSH_VALUE_OPTIONS = new Set(["-o", "--push-option", "--receive-pack", "--exec", "--repo"]);
|
|
19336
17705
|
var CURRENT_BRANCH = /^\$\(\s*git\s+(?:branch\s+--show-current|rev-parse\s+--abbrev-ref\s+HEAD|symbolic-ref\s+--short\s+HEAD)\s*\)$/;
|
|
19337
17706
|
var pushDestination = (destination) => {
|
|
@@ -21092,7 +19461,7 @@ var splitDenial = (plan) => ({
|
|
|
21092
19461
|
unblock: plan.unblock
|
|
21093
19462
|
});
|
|
21094
19463
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
21095
|
-
import { realpathSync as realpathSync5 } from "node:fs";
|
|
19464
|
+
import { existsSync as existsSync7, realpathSync as realpathSync5 } from "node:fs";
|
|
21096
19465
|
import os9 from "node:os";
|
|
21097
19466
|
import path24 from "node:path";
|
|
21098
19467
|
|
|
@@ -21321,7 +19690,7 @@ var exempt = (cwd, root, file, plans) => {
|
|
|
21321
19690
|
const segments = posix.split("/");
|
|
21322
19691
|
return /\.mdx?$/i.test(posix) || segments[0] === "docs" || segments.includes("plans") || [...plans].some((plan) => fold(plan) === posix);
|
|
21323
19692
|
};
|
|
21324
|
-
var PREFIXES2 = new Set(["sudo", "command", "env", "nohup", "time", "exec", "xargs"]);
|
|
19693
|
+
var PREFIXES2 = new Set(["sudo", "command", "env", "nohup", "time", "exec", "xargs", "busybox"]);
|
|
21325
19694
|
var operands = (words) => words.filter((item) => !item.startsWith("-"));
|
|
21326
19695
|
var SCRIPT_SHELLS = new Set(["sh", "bash", "zsh", "dash", "ksh"]);
|
|
21327
19696
|
var wrappedScript = (input) => {
|
|
@@ -21333,9 +19702,9 @@ var wrappedScript = (input) => {
|
|
|
21333
19702
|
return null;
|
|
21334
19703
|
if ("script" in tail)
|
|
21335
19704
|
return tail.script;
|
|
21336
|
-
const
|
|
21337
|
-
if (SCRIPT_SHELLS.has((
|
|
21338
|
-
return script
|
|
19705
|
+
const script = shellScript2(tail.argv);
|
|
19706
|
+
if (SCRIPT_SHELLS.has((tail.argv[0]?.split(/[\\/]/).at(-1) ?? "").toLowerCase()) && script)
|
|
19707
|
+
return script;
|
|
21339
19708
|
return tail.argv.map(quoteWord2).join(" ");
|
|
21340
19709
|
};
|
|
21341
19710
|
var editsOf = (input) => {
|
|
@@ -21414,6 +19783,94 @@ var editsOf = (input) => {
|
|
|
21414
19783
|
return [];
|
|
21415
19784
|
}
|
|
21416
19785
|
};
|
|
19786
|
+
var shellScript2 = (words) => {
|
|
19787
|
+
if (!SCRIPT_SHELLS.has((words[0]?.split(/[\\/]/).at(-1) ?? "").toLowerCase()))
|
|
19788
|
+
return null;
|
|
19789
|
+
for (let index = 1;index < words.length; index++) {
|
|
19790
|
+
const word = words[index];
|
|
19791
|
+
if (/^-[a-z]*c$/.test(word))
|
|
19792
|
+
return words[index + 1] ?? null;
|
|
19793
|
+
if (/^[-+][oO]$/.test(word))
|
|
19794
|
+
index++;
|
|
19795
|
+
else if (!/^[-+]/.test(word))
|
|
19796
|
+
return null;
|
|
19797
|
+
}
|
|
19798
|
+
return null;
|
|
19799
|
+
};
|
|
19800
|
+
var XARGS_VALUE = /^-[IinLPdsEa]$/;
|
|
19801
|
+
var runsWriter = (words) => {
|
|
19802
|
+
const filled = [...words.filter((word) => word !== "{}" && word !== ";" && word !== "+"), "x"];
|
|
19803
|
+
const edits = editsOf(filled);
|
|
19804
|
+
return edits === null || edits.length > 0 || opaqueWrites(filled) !== null;
|
|
19805
|
+
};
|
|
19806
|
+
var opaqueWrites = (input) => {
|
|
19807
|
+
let words = input;
|
|
19808
|
+
while (words.length && (PREFIXES2.has(words[0]) || /^\w+=/.test(words[0]))) {
|
|
19809
|
+
if (words[0] === "xargs") {
|
|
19810
|
+
let at = 1;
|
|
19811
|
+
while (words[at]?.startsWith("-"))
|
|
19812
|
+
at += XARGS_VALUE.test(words[at]) ? 2 : 1;
|
|
19813
|
+
return runsWriter(words.slice(at)) ? ["."] : null;
|
|
19814
|
+
}
|
|
19815
|
+
words = words.slice(1);
|
|
19816
|
+
}
|
|
19817
|
+
const [verb, ...args] = words;
|
|
19818
|
+
const name = (verb?.split(/[\\/]/).at(-1) ?? "").toLowerCase();
|
|
19819
|
+
const files = operands(args);
|
|
19820
|
+
const has = (pattern) => args.some((arg) => pattern.test(arg));
|
|
19821
|
+
const listed = (named) => named.length ? named : ["."];
|
|
19822
|
+
if (name === "unlink" || name === "shred")
|
|
19823
|
+
return listed(files);
|
|
19824
|
+
if (/^(?:chmod|chown|chgrp|chattr)$/.test(name))
|
|
19825
|
+
return listed(has(/^--reference/) ? files : files.slice(1));
|
|
19826
|
+
if (name === "rsync") {
|
|
19827
|
+
const dest = files.at(-1);
|
|
19828
|
+
const remote = /^[\w.@-]*:/.test(dest ?? "") && !/^[A-Za-z]:[\\/]/.test(dest ?? "");
|
|
19829
|
+
return dest === undefined ? ["."] : remote ? [] : [dest];
|
|
19830
|
+
}
|
|
19831
|
+
if (name === "find") {
|
|
19832
|
+
const exec = args.findIndex((arg) => /^-(?:exec|execdir|ok|okdir)$/.test(arg));
|
|
19833
|
+
const writes = has(/^-(?:delete|fprint\w*|fls)$/) || exec >= 0 && runsWriter(args.slice(exec + 1));
|
|
19834
|
+
const end = args.findIndex((arg) => /^[-(!]/.test(arg));
|
|
19835
|
+
return writes ? listed(end < 0 ? args : args.slice(0, end)) : null;
|
|
19836
|
+
}
|
|
19837
|
+
if (/^g?awk$/.test(name)) {
|
|
19838
|
+
if (!has(/^-i|^--include/))
|
|
19839
|
+
return null;
|
|
19840
|
+
const named = [];
|
|
19841
|
+
let program = !has(/^-f$|^--file/);
|
|
19842
|
+
for (let index = 0;index < args.length; index++)
|
|
19843
|
+
if (/^(?:-[ifvF]|--(?:include|file|assign|field-separator))$/.test(args[index]))
|
|
19844
|
+
index++;
|
|
19845
|
+
else if (args[index].startsWith("-"))
|
|
19846
|
+
continue;
|
|
19847
|
+
else if (program)
|
|
19848
|
+
program = false;
|
|
19849
|
+
else
|
|
19850
|
+
named.push(args[index]);
|
|
19851
|
+
return listed(named);
|
|
19852
|
+
}
|
|
19853
|
+
if (name === "perl")
|
|
19854
|
+
return has(/^-[a-zA-Z]*[eE]/) ? ["."] : null;
|
|
19855
|
+
if (/^(?:python[\d.]*|node|bun|deno|ruby|php)$/.test(name))
|
|
19856
|
+
return has(/^-[a-zA-Z]*[ce]$|^--eval$|^-p$/) ? ["."] : null;
|
|
19857
|
+
return shellScript2(words) === null ? null : ["."];
|
|
19858
|
+
};
|
|
19859
|
+
var linkSources = (args, at) => {
|
|
19860
|
+
const names = operands([...args]);
|
|
19861
|
+
const into = args.indexOf("-t");
|
|
19862
|
+
const dest = into >= 0 ? args[into + 1] : names.length > 1 ? names.at(-1) : ".";
|
|
19863
|
+
const sources = names.filter((name, index) => into >= 0 ? name !== dest : index < names.length - 1 || names.length === 1);
|
|
19864
|
+
const target = dest === undefined ? null : at(dest);
|
|
19865
|
+
const symbolic = args.some((arg) => /^-[a-zA-Z]*s|^--symbolic$/.test(arg));
|
|
19866
|
+
const base = target === null ? null : into >= 0 || sources.length > 1 || existsSync7(target) || /[\\/]$/.test(dest ?? "") ? target : path24.dirname(target);
|
|
19867
|
+
return sources.flatMap((source) => {
|
|
19868
|
+
if (symbolic && base !== null && !path24.isAbsolute(homeExpanded(source)))
|
|
19869
|
+
return [path24.resolve(base, source)];
|
|
19870
|
+
const resolved = at(source);
|
|
19871
|
+
return resolved ? [resolved] : [];
|
|
19872
|
+
});
|
|
19873
|
+
};
|
|
21417
19874
|
var shellWrites = (command, depth = 0) => {
|
|
21418
19875
|
const targets = [];
|
|
21419
19876
|
let unknown = false;
|
|
@@ -21523,11 +19980,15 @@ var gitMutationDirs = (cwd, command, dialect) => {
|
|
|
21523
19980
|
var CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
21524
19981
|
var PUSHD2 = new Set(["pushd", "push-location"]);
|
|
21525
19982
|
var POPD2 = new Set(["popd", "pop-location"]);
|
|
21526
|
-
var
|
|
19983
|
+
var UNKNOWN_DIR = path24.resolve(path24.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
19984
|
+
var cdInto = (dir, words, strict = false) => {
|
|
19985
|
+
const lost = strict ? UNKNOWN_DIR : undefined;
|
|
21527
19986
|
const named = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
|
|
21528
19987
|
const target = named === undefined ? undefined : homeExpanded(named);
|
|
21529
|
-
if (
|
|
21530
|
-
return;
|
|
19988
|
+
if (target === "-" || target && /^~|[$`*?]/.test(target))
|
|
19989
|
+
return lost;
|
|
19990
|
+
if (dir === undefined)
|
|
19991
|
+
return lost;
|
|
21531
19992
|
return target === undefined ? os9.homedir() : path24.resolve(dir, target);
|
|
21532
19993
|
};
|
|
21533
19994
|
var quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`;
|
|
@@ -21535,7 +19996,7 @@ var homeExpanded = (file) => {
|
|
|
21535
19996
|
const match = /^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(file);
|
|
21536
19997
|
return match ? (process.env.HOME || os9.homedir()) + file.slice(match[0].length) : file;
|
|
21537
19998
|
};
|
|
21538
|
-
var segmentTargets = (cwd, command, dialect, depth = 0) => {
|
|
19999
|
+
var segmentTargets = (cwd, command, dialect, depth = 0, strict = false) => {
|
|
21539
20000
|
const targets = [];
|
|
21540
20001
|
let dir = cwd;
|
|
21541
20002
|
let stack = [];
|
|
@@ -21559,21 +20020,35 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
|
|
|
21559
20020
|
const words = lead < 0 ? [] : segment.words.slice(lead);
|
|
21560
20021
|
const name = (words[0]?.split(/[\\/]/).at(-1) ?? "").toLowerCase();
|
|
21561
20022
|
if (CD2.has(name)) {
|
|
21562
|
-
dir = cdInto(dir, words);
|
|
20023
|
+
dir = cdInto(dir, words, strict);
|
|
21563
20024
|
continue;
|
|
21564
20025
|
}
|
|
21565
20026
|
if (PUSHD2.has(name)) {
|
|
21566
20027
|
stack.push(dir);
|
|
21567
|
-
dir = cdInto(dir, words);
|
|
20028
|
+
dir = cdInto(dir, words, strict);
|
|
21568
20029
|
continue;
|
|
21569
20030
|
}
|
|
21570
20031
|
if (POPD2.has(name)) {
|
|
21571
|
-
dir = stack.length ? stack.pop() : undefined;
|
|
20032
|
+
dir = stack.length ? stack.pop() : strict ? UNKNOWN_DIR : undefined;
|
|
21572
20033
|
continue;
|
|
21573
20034
|
}
|
|
21574
|
-
const inner = depth < 4 ? wrappedScript(words) : null;
|
|
20035
|
+
const inner = depth < 4 ? wrappedScript(words) ?? (strict ? shellScript2(words) : null) : null;
|
|
21575
20036
|
if (inner !== null && dir !== undefined)
|
|
21576
|
-
targets.push(...segmentTargets(dir, inner, "posix", depth + 1));
|
|
20037
|
+
targets.push(...segmentTargets(dir, inner, "posix", depth + 1, strict));
|
|
20038
|
+
if (strict && dir !== undefined) {
|
|
20039
|
+
const runIn = dir;
|
|
20040
|
+
for (const sub of depth < 4 ? segment.subs ?? [] : [])
|
|
20041
|
+
targets.push(...segmentTargets(runIn, sub, dialect, depth + 1, true));
|
|
20042
|
+
const opaque = segment.unanalyzable ? ["."] : inner === null ? opaqueWrites(words) : null;
|
|
20043
|
+
for (const file of opaque ?? []) {
|
|
20044
|
+
const resolved = at(file);
|
|
20045
|
+
if (resolved)
|
|
20046
|
+
targets.push(file === "." ? path24.join(resolved, DIR_TARGET) : resolved);
|
|
20047
|
+
}
|
|
20048
|
+
const ln = words.findIndex((word) => /^ln$/i.test(word.split(/[\\/]/).at(-1) ?? ""));
|
|
20049
|
+
if (ln >= 0 && words.slice(0, ln).every((word) => PREFIXES2.has(word)))
|
|
20050
|
+
targets.push(...linkSources(words.slice(ln + 1), at));
|
|
20051
|
+
}
|
|
21577
20052
|
for (const file of segment.redirects)
|
|
21578
20053
|
if (!/^\/dev\/(?:null|stdout|stderr|tty)$/.test(file)) {
|
|
21579
20054
|
const resolved = at(file);
|
|
@@ -21590,11 +20065,29 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
|
|
|
21590
20065
|
if (resolved)
|
|
21591
20066
|
targets.push(resolved);
|
|
21592
20067
|
}
|
|
21593
|
-
if (dir !== undefined
|
|
21594
|
-
|
|
20068
|
+
if (dir !== undefined)
|
|
20069
|
+
for (const invocation of workitInvocations(segment.words.map(quoteWord2).join(" "), "posix")) {
|
|
20070
|
+
const { at: runsIn, args } = workitCwd(dir, invocation);
|
|
20071
|
+
if (args[0] === "git" && MUTATING_WORKIT_GIT.has(args[1] ?? "") && !inert(args.slice(2), ""))
|
|
20072
|
+
targets.push(path24.join(runsIn, DIR_TARGET));
|
|
20073
|
+
}
|
|
21595
20074
|
}
|
|
21596
20075
|
return targets;
|
|
21597
20076
|
};
|
|
20077
|
+
var workitCwd = (dir, args) => {
|
|
20078
|
+
const { rest, cwd } = skipWorkitGlobals(args);
|
|
20079
|
+
return { at: cwd === null ? dir : path24.resolve(dir, homeExpanded(cwd)), args: rest };
|
|
20080
|
+
};
|
|
20081
|
+
var shellMutationTargets = (cwd, command, dialect = "posix", strict = false) => {
|
|
20082
|
+
try {
|
|
20083
|
+
return [
|
|
20084
|
+
...segmentTargets(cwd, command, dialect, 0, strict),
|
|
20085
|
+
...gitMutationDirs(cwd, command, dialect).map((dir) => path24.join(dir, DIR_TARGET))
|
|
20086
|
+
];
|
|
20087
|
+
} catch {
|
|
20088
|
+
return [];
|
|
20089
|
+
}
|
|
20090
|
+
};
|
|
21598
20091
|
var overridden = (command, dialect) => {
|
|
21599
20092
|
const segments = segmentsOf(command, dialect);
|
|
21600
20093
|
if (segments.length !== 1 || segments[0].group || segments[0].subs?.length)
|
|
@@ -21700,16 +20193,8 @@ function shellGate(cwd, command, owner, dialect = "posix", deps) {
|
|
|
21700
20193
|
} catch {}
|
|
21701
20194
|
const writes = shellWrites(command);
|
|
21702
20195
|
let targets = [];
|
|
21703
|
-
if (owner)
|
|
21704
|
-
|
|
21705
|
-
targets = [
|
|
21706
|
-
...segmentTargets(cwd, command, dialect),
|
|
21707
|
-
...gitMutationDirs(cwd, command, dialect).map((dir) => path24.join(dir, DIR_TARGET))
|
|
21708
|
-
];
|
|
21709
|
-
} catch {
|
|
21710
|
-
targets = [];
|
|
21711
|
-
}
|
|
21712
|
-
}
|
|
20196
|
+
if (owner)
|
|
20197
|
+
targets = shellMutationTargets(cwd, command, dialect);
|
|
21713
20198
|
if (owner && targets.length) {
|
|
21714
20199
|
const live = liveGate(owner, targets, deps);
|
|
21715
20200
|
if (live.kind !== "none") {
|
|
@@ -22176,13 +20661,13 @@ ${line}` };
|
|
|
22176
20661
|
return decision;
|
|
22177
20662
|
};
|
|
22178
20663
|
// packages/workit-core/src/hooks/hosts/fields.ts
|
|
22179
|
-
import { existsSync as
|
|
20664
|
+
import { existsSync as existsSync8, realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
|
|
22180
20665
|
import path25 from "node:path";
|
|
22181
20666
|
var isRecord5 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
22182
20667
|
var nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "";
|
|
22183
20668
|
var optionalText = (value) => typeof value === "string" ? value : null;
|
|
22184
20669
|
var existingDirectory = (value) => {
|
|
22185
|
-
if (!nonEmpty2(value) || !path25.isAbsolute(value) || !
|
|
20670
|
+
if (!nonEmpty2(value) || !path25.isAbsolute(value) || !existsSync8(value))
|
|
22186
20671
|
return null;
|
|
22187
20672
|
try {
|
|
22188
20673
|
return statSync2(value).isDirectory() ? realpathSync6(value) : null;
|
|
@@ -22385,9 +20870,266 @@ var cwdRewrite = (command) => {
|
|
|
22385
20870
|
return `workit --cwd ${dir} ${rest.slice("workit".length).trimStart()}`.trimEnd();
|
|
22386
20871
|
};
|
|
22387
20872
|
|
|
20873
|
+
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
20874
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
20875
|
+
import fs20 from "node:fs";
|
|
20876
|
+
import path27 from "node:path";
|
|
20877
|
+
var FANOUT_TOKEN_FILE = "workit-fanout-token";
|
|
20878
|
+
var NONE5 = { kind: "none" };
|
|
20879
|
+
var CASE_INSENSITIVE2 = process.platform === "darwin" || process.platform === "win32";
|
|
20880
|
+
var canonical3 = (file) => {
|
|
20881
|
+
let rest = "";
|
|
20882
|
+
for (let dir = path27.resolve(file);; dir = path27.dirname(dir)) {
|
|
20883
|
+
try {
|
|
20884
|
+
return path27.join(fs20.realpathSync.native(dir), rest);
|
|
20885
|
+
} catch {
|
|
20886
|
+
if (path27.dirname(dir) === dir)
|
|
20887
|
+
return path27.resolve(file);
|
|
20888
|
+
rest = rest ? path27.join(path27.basename(dir), rest) : path27.basename(dir);
|
|
20889
|
+
}
|
|
20890
|
+
}
|
|
20891
|
+
};
|
|
20892
|
+
var within = (child, parent) => {
|
|
20893
|
+
const fold = (value) => CASE_INSENSITIVE2 ? value.toLowerCase() : value;
|
|
20894
|
+
const relative = path27.relative(fold(parent), fold(child));
|
|
20895
|
+
return relative === "" || !relative.startsWith("..") && !path27.isAbsolute(relative);
|
|
20896
|
+
};
|
|
20897
|
+
var checkoutOf2 = (file) => {
|
|
20898
|
+
for (let dir = canonical3(file);; dir = path27.dirname(dir)) {
|
|
20899
|
+
const dotGit = path27.join(dir, ".git");
|
|
20900
|
+
if (fs20.existsSync(dotGit)) {
|
|
20901
|
+
if (!fs20.statSync(dotGit).isFile())
|
|
20902
|
+
return { root: dir, workit: false };
|
|
20903
|
+
const admin = /^gitdir:\s*(.+)$/mu.exec(fs20.readFileSync(dotGit, "utf8"))?.[1]?.trim();
|
|
20904
|
+
return {
|
|
20905
|
+
root: dir,
|
|
20906
|
+
workit: Boolean(admin) && fs20.existsSync(path27.join(path27.resolve(dir, admin), FANOUT_TOKEN_FILE))
|
|
20907
|
+
};
|
|
20908
|
+
}
|
|
20909
|
+
if (path27.dirname(dir) === dir)
|
|
20910
|
+
return null;
|
|
20911
|
+
}
|
|
20912
|
+
};
|
|
20913
|
+
var workitWorktreeOf = (file) => {
|
|
20914
|
+
try {
|
|
20915
|
+
const checkout = checkoutOf2(file);
|
|
20916
|
+
return checkout?.workit ? checkout.root : null;
|
|
20917
|
+
} catch {
|
|
20918
|
+
return null;
|
|
20919
|
+
}
|
|
20920
|
+
};
|
|
20921
|
+
var bindingDir = () => path27.join(resolveStateDir(), "worktree-bind");
|
|
20922
|
+
var bindingFile = (session, agentId) => path27.join(bindingDir(), `${createHash16("sha256").update(`${session}\x00${agentId}`).digest("hex").slice(0, 32)}.json`);
|
|
20923
|
+
var readBinding = (file) => {
|
|
20924
|
+
try {
|
|
20925
|
+
const value = JSON.parse(fs20.readFileSync(file, "utf8"));
|
|
20926
|
+
return typeof value.worktree === "string" ? value : null;
|
|
20927
|
+
} catch {
|
|
20928
|
+
return null;
|
|
20929
|
+
}
|
|
20930
|
+
};
|
|
20931
|
+
var boundWorktree = (input) => {
|
|
20932
|
+
const agentId = input.session.agentId;
|
|
20933
|
+
if (!agentId)
|
|
20934
|
+
return null;
|
|
20935
|
+
const binding = readBinding(bindingFile(input.session.id, agentId));
|
|
20936
|
+
return binding && workitWorktreeOf(binding.worktree) === binding.worktree ? binding.worktree : null;
|
|
20937
|
+
};
|
|
20938
|
+
var bind = (input, worktree) => {
|
|
20939
|
+
const agentId = input.session.agentId;
|
|
20940
|
+
const file = bindingFile(input.session.id, agentId);
|
|
20941
|
+
const binding = {
|
|
20942
|
+
worktree,
|
|
20943
|
+
session: input.session.id,
|
|
20944
|
+
agentId,
|
|
20945
|
+
at: new Date().toISOString()
|
|
20946
|
+
};
|
|
20947
|
+
fs20.mkdirSync(path27.dirname(file), { recursive: true });
|
|
20948
|
+
fs20.writeFileSync(file, JSON.stringify(binding));
|
|
20949
|
+
try {
|
|
20950
|
+
if (inWorkitWorkspace(input.cwd))
|
|
20951
|
+
appendHookObserved(input.cwd, {
|
|
20952
|
+
type: "worktree.bound",
|
|
20953
|
+
actor: { host: input.host, session: input.session.id, agentId },
|
|
20954
|
+
agentType: input.session.agentType,
|
|
20955
|
+
worktree
|
|
20956
|
+
});
|
|
20957
|
+
} catch {}
|
|
20958
|
+
};
|
|
20959
|
+
var hostIsolated = (cwd, agentId) => {
|
|
20960
|
+
try {
|
|
20961
|
+
if (agentId === null)
|
|
20962
|
+
return false;
|
|
20963
|
+
const checkout = checkoutOf2(cwd);
|
|
20964
|
+
if (!checkout)
|
|
20965
|
+
return false;
|
|
20966
|
+
const dotGit = path27.join(checkout.root, ".git");
|
|
20967
|
+
if (!fs20.statSync(dotGit).isFile())
|
|
20968
|
+
return false;
|
|
20969
|
+
const admin = /^gitdir:\s*(.+)$/mu.exec(fs20.readFileSync(dotGit, "utf8"))?.[1]?.trim();
|
|
20970
|
+
if (!admin)
|
|
20971
|
+
return false;
|
|
20972
|
+
const adminDir = path27.resolve(checkout.root, admin);
|
|
20973
|
+
const back = fs20.readFileSync(path27.join(adminDir, "gitdir"), "utf8").trim();
|
|
20974
|
+
if (path27.relative(canonical3(path27.resolve(adminDir, back)), canonical3(dotGit)) !== "")
|
|
20975
|
+
return false;
|
|
20976
|
+
const common = path27.join(adminDir, "commondir");
|
|
20977
|
+
const gitDir = fs20.existsSync(common) ? path27.resolve(adminDir, fs20.readFileSync(common, "utf8").trim()) : adminDir;
|
|
20978
|
+
const expected = path27.join(path27.dirname(canonical3(gitDir)), ".claude", "worktrees", `agent-${agentId}`);
|
|
20979
|
+
return path27.relative(canonical3(expected), checkout.root) === "";
|
|
20980
|
+
} catch {
|
|
20981
|
+
return false;
|
|
20982
|
+
}
|
|
20983
|
+
};
|
|
20984
|
+
var shown = (target) => path27.basename(target) === ".workit-live-target" ? path27.dirname(target) : target;
|
|
20985
|
+
var unboundDeny = (input, target) => {
|
|
20986
|
+
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.";
|
|
20987
|
+
return {
|
|
20988
|
+
kind: "deny",
|
|
20989
|
+
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}`,
|
|
20990
|
+
unblock
|
|
20991
|
+
};
|
|
20992
|
+
};
|
|
20993
|
+
var outsideDeny = (input, worktree, target) => {
|
|
20994
|
+
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.`;
|
|
20995
|
+
return {
|
|
20996
|
+
kind: "deny",
|
|
20997
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} is bound to the worktree ${worktree}, and ${shown(target)} is outside it. ${unblock}`,
|
|
20998
|
+
unblock
|
|
20999
|
+
};
|
|
21000
|
+
};
|
|
21001
|
+
var unknownDirDeny = (input, worktree) => {
|
|
21002
|
+
const wt = worktree ?? "<worktree>";
|
|
21003
|
+
const unblock = `Workit cannot resolve \`cd -\`, \`cd "$X"\` or \`popd\`: write by absolute path, \`git -C ${wt}\` or \`workit --cwd ${wt}\`.`;
|
|
21004
|
+
return {
|
|
21005
|
+
kind: "deny",
|
|
21006
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} writes after an unknown directory change. ${unblock}`,
|
|
21007
|
+
unblock
|
|
21008
|
+
};
|
|
21009
|
+
};
|
|
21010
|
+
function confineImplementer(input, targets) {
|
|
21011
|
+
try {
|
|
21012
|
+
if (!input.session.agentId || hostIsolated(input.cwd, input.session.agentId))
|
|
21013
|
+
return NONE5;
|
|
21014
|
+
if (targets.some((target) => within(path27.resolve(target), UNKNOWN_DIR)))
|
|
21015
|
+
return unknownDirDeny(input, boundWorktree(input));
|
|
21016
|
+
const bindings = canonical3(bindingDir());
|
|
21017
|
+
const judged = targets.map((named) => ({ named, real: canonical3(named) })).filter(({ real }) => within(real, bindings) || checkoutOf2(real) !== null);
|
|
21018
|
+
if (judged.length === 0)
|
|
21019
|
+
return NONE5;
|
|
21020
|
+
let worktree = boundWorktree(input);
|
|
21021
|
+
if (!worktree) {
|
|
21022
|
+
for (const { real } of judged) {
|
|
21023
|
+
worktree = within(real, bindings) ? null : workitWorktreeOf(real);
|
|
21024
|
+
if (worktree)
|
|
21025
|
+
break;
|
|
21026
|
+
}
|
|
21027
|
+
if (!worktree)
|
|
21028
|
+
return unboundDeny(input, judged[0].named);
|
|
21029
|
+
bind(input, worktree);
|
|
21030
|
+
}
|
|
21031
|
+
const root = canonical3(worktree);
|
|
21032
|
+
const outside = judged.find(({ real }) => !within(real, root) || within(real, bindings));
|
|
21033
|
+
return outside ? outsideDeny(input, worktree, outside.named) : NONE5;
|
|
21034
|
+
} catch {
|
|
21035
|
+
return NONE5;
|
|
21036
|
+
}
|
|
21037
|
+
}
|
|
21038
|
+
var MUTATING_REMOTE = new Set([
|
|
21039
|
+
"add",
|
|
21040
|
+
"remove",
|
|
21041
|
+
"rm",
|
|
21042
|
+
"rename",
|
|
21043
|
+
"set-url",
|
|
21044
|
+
"set-head",
|
|
21045
|
+
"set-branches",
|
|
21046
|
+
"prune"
|
|
21047
|
+
]);
|
|
21048
|
+
var CONFIG_READ = /^(?:--get(?:-all|-regexp|-urlmatch)?|--list|-l|get|list)$/;
|
|
21049
|
+
var CONFIG_WRITE = /^(?:--(?:unset(?:-all)?|add|replace-all|rename-section|remove-section|edit)|-e|set|unset|rename-section|remove-section|edit)$/;
|
|
21050
|
+
var CONFIG_VALUE = /^(?:--file|-f|--blob|--type|--default|--comment)$/;
|
|
21051
|
+
var leadOwnedGit = (args) => {
|
|
21052
|
+
const [sub = "", ...rest] = args;
|
|
21053
|
+
if (rest.some((arg) => arg === "--help" || arg === "-h"))
|
|
21054
|
+
return false;
|
|
21055
|
+
const names = rest.filter((arg) => !arg.startsWith("-"));
|
|
21056
|
+
const flag = (pattern) => rest.some((arg) => pattern.test(arg));
|
|
21057
|
+
switch (sub) {
|
|
21058
|
+
case "worktree":
|
|
21059
|
+
return names[0] !== undefined && names[0] !== "list";
|
|
21060
|
+
case "update-ref":
|
|
21061
|
+
return true;
|
|
21062
|
+
case "symbolic-ref":
|
|
21063
|
+
return names.length > 1 || flag(/^(?:-d|--delete)$/);
|
|
21064
|
+
case "branch":
|
|
21065
|
+
return flag(/^-[a-zA-Z]*[dDfmMcC]|^--(?:delete|force|move|copy)$/);
|
|
21066
|
+
case "tag":
|
|
21067
|
+
return flag(/^-[a-zA-Z]*[df]|^--(?:delete|force)$/);
|
|
21068
|
+
case "push": {
|
|
21069
|
+
if (flag(/^(?:-d|--delete|--mirror|--prune)$/))
|
|
21070
|
+
return true;
|
|
21071
|
+
const refspecs = names.slice(1);
|
|
21072
|
+
return refspecs.some((name) => name.includes(":") || name.startsWith("+")) || refspecs.length > 0 && flag(/^-[a-zA-Z]*f|^--force/);
|
|
21073
|
+
}
|
|
21074
|
+
case "replace":
|
|
21075
|
+
case "filter-branch":
|
|
21076
|
+
case "gc":
|
|
21077
|
+
case "prune":
|
|
21078
|
+
case "repack":
|
|
21079
|
+
case "sparse-checkout":
|
|
21080
|
+
return true;
|
|
21081
|
+
case "notes":
|
|
21082
|
+
case "reflog":
|
|
21083
|
+
case "submodule":
|
|
21084
|
+
return !/^(?:list|show|status|exists)$/.test(names[0] ?? "list");
|
|
21085
|
+
case "stash":
|
|
21086
|
+
return names[0] === "drop" || names[0] === "clear";
|
|
21087
|
+
case "remote":
|
|
21088
|
+
return MUTATING_REMOTE.has(names[0] ?? "");
|
|
21089
|
+
case "config": {
|
|
21090
|
+
if (rest.some((arg) => CONFIG_READ.test(arg)))
|
|
21091
|
+
return false;
|
|
21092
|
+
if (rest.some((arg) => CONFIG_WRITE.test(arg)))
|
|
21093
|
+
return true;
|
|
21094
|
+
let operands = 0;
|
|
21095
|
+
for (let index = 0;index < rest.length; index++)
|
|
21096
|
+
if (CONFIG_VALUE.test(rest[index]))
|
|
21097
|
+
index++;
|
|
21098
|
+
else if (!rest[index].startsWith("-"))
|
|
21099
|
+
operands++;
|
|
21100
|
+
return operands > 1;
|
|
21101
|
+
}
|
|
21102
|
+
default:
|
|
21103
|
+
return false;
|
|
21104
|
+
}
|
|
21105
|
+
};
|
|
21106
|
+
var leadOwnedWorkit = (args) => !args.includes("--help") && args.some((_, start) => {
|
|
21107
|
+
if (start > 0 && !/(?:^|[\\/])workit(?:\.exe|\.cmd)?$/.test(args[start - 1]))
|
|
21108
|
+
return false;
|
|
21109
|
+
const [verb, sub] = skipWorkitGlobals(args.slice(start)).rest;
|
|
21110
|
+
return verb === "fanout" && /^(?:plan|worktree)$/.test(sub ?? "");
|
|
21111
|
+
});
|
|
21112
|
+
var leadOwnedDeny = (input, command) => {
|
|
21113
|
+
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.";
|
|
21114
|
+
return {
|
|
21115
|
+
kind: "deny",
|
|
21116
|
+
reason: `workit worktree confinement: implementer ${input.session.agentId} may not run \`${command.slice(0, 160)}\`. ${unblock}`,
|
|
21117
|
+
unblock
|
|
21118
|
+
};
|
|
21119
|
+
};
|
|
21120
|
+
function confineImplementerShell(input, command, dialect = "posix") {
|
|
21121
|
+
try {
|
|
21122
|
+
if (!input.session.agentId || hostIsolated(input.cwd, input.session.agentId))
|
|
21123
|
+
return NONE5;
|
|
21124
|
+
if (rawInvocations(command, dialect).some((invocation) => invocation.tool === "git" && leadOwnedGit(invocation.args)) || workitInvocations(command, dialect).some(leadOwnedWorkit))
|
|
21125
|
+
return leadOwnedDeny(input, command);
|
|
21126
|
+
} catch {}
|
|
21127
|
+
return confineImplementer(input, shellMutationTargets(input.cwd, command, dialect, true));
|
|
21128
|
+
}
|
|
21129
|
+
|
|
22388
21130
|
// packages/workit-core/src/hooks/handle.ts
|
|
22389
21131
|
var usable2 = (value) => value === "native" || value === "partial";
|
|
22390
|
-
var
|
|
21132
|
+
var NONE6 = { kind: "none" };
|
|
22391
21133
|
var resendsOnChange = (descriptor) => descriptor.context.turnResend === "on-change" && usable2(descriptor.context.perTurn);
|
|
22392
21134
|
var offered = new Set;
|
|
22393
21135
|
var ROLES = {
|
|
@@ -22400,6 +21142,7 @@ var workitRole = (descriptor, agentType) => {
|
|
|
22400
21142
|
const name = agentType.startsWith(prefix) ? agentType.slice(prefix.length) : "";
|
|
22401
21143
|
return Object.hasOwn(ROLES, name) ? ROLES[name] : null;
|
|
22402
21144
|
};
|
|
21145
|
+
var implementerAgent = (input, descriptor) => Boolean(input.session.agentId) && input.session.agentType !== null && workitRole(descriptor, input.session.agentType) === "implementer";
|
|
22403
21146
|
var subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128);
|
|
22404
21147
|
var CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
|
|
22405
21148
|
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\`).`;
|
|
@@ -22407,7 +21150,7 @@ var subagentStartText = (input, descriptor, event) => {
|
|
|
22407
21150
|
const session = input.session.id ?? null;
|
|
22408
21151
|
const role = workitRole(descriptor, event.agentType);
|
|
22409
21152
|
const who = `${descriptor.label} subagent ${event.agentId} (${event.agentType})`;
|
|
22410
|
-
const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer"
|
|
21153
|
+
const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" ? hostIsolated(input.cwd, event.agentId) : CLAUDE_WORKTREE.test(input.cwd));
|
|
22411
21154
|
const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
|
|
22412
21155
|
if (role === "implementer" && isolated)
|
|
22413
21156
|
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.`;
|
|
@@ -22415,7 +21158,7 @@ var subagentStartText = (input, descriptor, event) => {
|
|
|
22415
21158
|
return `${isolatedGit(input.cwd)}
|
|
22416
21159
|
${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
|
|
22417
21160
|
if (role === "implementer")
|
|
22418
|
-
return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree (the lead makes
|
|
21161
|
+
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.`;
|
|
22419
21162
|
const readOnly = `Workit observed ${who} as read-only/agent-guided.`;
|
|
22420
21163
|
if (role !== "judge" || !event.agentId)
|
|
22421
21164
|
return readOnly;
|
|
@@ -22446,7 +21189,7 @@ function decide(input, deps) {
|
|
|
22446
21189
|
switch (event.kind) {
|
|
22447
21190
|
case "session.start": {
|
|
22448
21191
|
if (!usable2(descriptor.context.sessionStart))
|
|
22449
|
-
return
|
|
21192
|
+
return NONE6;
|
|
22450
21193
|
const key = input.session.id ? `${input.host}\x00${input.session.id}` : null;
|
|
22451
21194
|
const offer = event.source === "startup" && (key === null || !offered.has(key));
|
|
22452
21195
|
if (offer && key !== null)
|
|
@@ -22461,26 +21204,31 @@ function decide(input, deps) {
|
|
|
22461
21204
|
}
|
|
22462
21205
|
case "context.turn": {
|
|
22463
21206
|
if (!usable2(descriptor.context.perTurn))
|
|
22464
|
-
return
|
|
21207
|
+
return NONE6;
|
|
22465
21208
|
const current = turnContextText(input, descriptor);
|
|
22466
21209
|
const text = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
|
|
22467
|
-
return withContextLine(text ? { kind: "context", text } :
|
|
21210
|
+
return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
|
|
22468
21211
|
}
|
|
22469
21212
|
case "shell.pre": {
|
|
22470
21213
|
const skillRead = skillReadIn(event.command, event.dialect);
|
|
22471
21214
|
if (skillRead)
|
|
22472
21215
|
recordSkillLoad(input, skillRead, "read");
|
|
22473
21216
|
const canDeny = usable2(descriptor.shellPolicy.deny);
|
|
22474
|
-
const policy = canDeny ? shellPolicy(input.cwd, event.command, event.dialect) :
|
|
21217
|
+
const policy = canDeny ? shellPolicy(input.cwd, event.command, event.dialect) : NONE6;
|
|
22475
21218
|
if (policy.kind !== "none")
|
|
22476
21219
|
return policy;
|
|
22477
21220
|
const postTool = usable2(descriptor.events["shell.post"].support);
|
|
22478
21221
|
if (!postTool)
|
|
22479
21222
|
settlePendingCommit(input);
|
|
22480
|
-
const raw = canDeny ? rawGitPre(input, event.command, { nudge: false }) :
|
|
21223
|
+
const raw = canDeny ? rawGitPre(input, event.command, { nudge: false }) : NONE6;
|
|
22481
21224
|
if (raw.kind === "deny")
|
|
22482
21225
|
return raw;
|
|
22483
|
-
|
|
21226
|
+
if (canDeny && implementerAgent(input, descriptor)) {
|
|
21227
|
+
const confined = confineImplementerShell(input, event.command, event.dialect);
|
|
21228
|
+
if (confined.kind === "deny")
|
|
21229
|
+
return confined;
|
|
21230
|
+
}
|
|
21231
|
+
const gate = usable2(descriptor.events["write.pre"].support) ? shellGate(input.cwd, event.command, liveOwner(input, descriptor.transport), event.dialect) : NONE6;
|
|
22484
21232
|
if (gate.kind === "deny")
|
|
22485
21233
|
return gate;
|
|
22486
21234
|
const plan = heavyGate(input.cwd, event.command, {
|
|
@@ -22503,10 +21251,10 @@ function decide(input, deps) {
|
|
|
22503
21251
|
command: rewrittenTo,
|
|
22504
21252
|
input: event.toolInput ? { ...event.toolInput, command: rewrittenTo } : null,
|
|
22505
21253
|
text
|
|
22506
|
-
} :
|
|
21254
|
+
} : NONE6;
|
|
22507
21255
|
if (descriptor.transport !== "hook-process")
|
|
22508
21256
|
return rewritten(null);
|
|
22509
|
-
const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) :
|
|
21257
|
+
const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) : NONE6, aside), shipNudge(input, event.command));
|
|
22510
21258
|
if (!lease)
|
|
22511
21259
|
return cwdCommand && nudged.kind !== "deny" ? rewritten(nudged.kind === "context" ? nudged.text : null) : nudged;
|
|
22512
21260
|
return rewritten([rewriteNote(lease), nudged.kind === "context" ? nudged.text : null].filter(Boolean).join(`
|
|
@@ -22515,9 +21263,17 @@ function decide(input, deps) {
|
|
|
22515
21263
|
case "shell.post":
|
|
22516
21264
|
if (usable2(descriptor.events["shell.post"].support))
|
|
22517
21265
|
rawGitPost(input, event.command, callKey(event.toolUseId, event.command));
|
|
22518
|
-
return
|
|
22519
|
-
case "write.pre":
|
|
22520
|
-
|
|
21266
|
+
return NONE6;
|
|
21267
|
+
case "write.pre": {
|
|
21268
|
+
if (!usable2(descriptor.events["write.pre"].support))
|
|
21269
|
+
return NONE6;
|
|
21270
|
+
if (implementerAgent(input, descriptor)) {
|
|
21271
|
+
const confined = confineImplementer(input, liveTargets(input.cwd, event.paths));
|
|
21272
|
+
if (confined.kind === "deny")
|
|
21273
|
+
return confined;
|
|
21274
|
+
}
|
|
21275
|
+
return writeGate(input.cwd, event.paths, liveOwner(input, descriptor.transport));
|
|
21276
|
+
}
|
|
22521
21277
|
case "subagent.start":
|
|
22522
21278
|
if (workitRole(descriptor, event.agentType) === "judge")
|
|
22523
21279
|
trackJudge(input, event.agentId, true);
|
|
@@ -22534,22 +21290,22 @@ function decide(input, deps) {
|
|
|
22534
21290
|
case "tool.pre":
|
|
22535
21291
|
if (event.skill)
|
|
22536
21292
|
recordSkillLoad(input, event.skill, "tool");
|
|
22537
|
-
return
|
|
21293
|
+
return NONE6;
|
|
22538
21294
|
case "stop":
|
|
22539
|
-
return usable2(descriptor.events.stop.support) ? stopDecision(input, descriptor) :
|
|
21295
|
+
return usable2(descriptor.events.stop.support) ? stopDecision(input, descriptor) : NONE6;
|
|
22540
21296
|
case "subagent.stop":
|
|
22541
21297
|
trackJudge(input, event.agentId, false);
|
|
22542
|
-
return
|
|
21298
|
+
return NONE6;
|
|
22543
21299
|
case "prompt.submit":
|
|
22544
|
-
return
|
|
21300
|
+
return NONE6;
|
|
22545
21301
|
}
|
|
22546
21302
|
}
|
|
22547
21303
|
var failureDecision = (descriptor, event, error) => {
|
|
22548
21304
|
if (event === "shell.pre" || event === "tool.pre" || event === "write.pre")
|
|
22549
|
-
return descriptor.shellPolicy.failClosed ? { kind: "deny", reason: error, unblock: null } :
|
|
21305
|
+
return descriptor.shellPolicy.failClosed ? { kind: "deny", reason: error, unblock: null } : NONE6;
|
|
22550
21306
|
if (event === "session.start" || event === "subagent.start")
|
|
22551
21307
|
return { kind: "context", text: `[workit diagnostic: ${error}]` };
|
|
22552
|
-
return
|
|
21308
|
+
return NONE6;
|
|
22553
21309
|
};
|
|
22554
21310
|
var dispatchHook = (adapter, raw, env = process.env) => {
|
|
22555
21311
|
const parsed = adapter.parse(raw, env);
|
|
@@ -22575,7 +21331,7 @@ var dispatchHook = (adapter, raw, env = process.env) => {
|
|
|
22575
21331
|
};
|
|
22576
21332
|
// packages/workit-core/src/hooks/deadline.ts
|
|
22577
21333
|
import { appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
|
|
22578
|
-
import
|
|
21334
|
+
import path28 from "node:path";
|
|
22579
21335
|
var HOOK_SKIP_TEXT = "workit context skipped: host under load";
|
|
22580
21336
|
var HOOK_DEADLINE_MS = 8000;
|
|
22581
21337
|
var HOST_DEADLINES = {
|
|
@@ -22593,7 +21349,7 @@ var hookDeadlineMs = (env, host = "", native) => {
|
|
|
22593
21349
|
const row = HOST_DEADLINES[host];
|
|
22594
21350
|
return override(env) ?? (row ? native === undefined ? Math.min(...Object.values(row)) : row[native] ?? row[""] : HOOK_DEADLINE_MS);
|
|
22595
21351
|
};
|
|
22596
|
-
var skipsFile = (stateDir) =>
|
|
21352
|
+
var skipsFile = (stateDir) => path28.join(stateDir, HOOK_SKIPS_FILE);
|
|
22597
21353
|
var recordHookSkip = (skip, stateDir = resolveStateDir()) => {
|
|
22598
21354
|
try {
|
|
22599
21355
|
mkdirSync3(stateDir, { recursive: true });
|
|
@@ -22611,7 +21367,7 @@ var QUIET = new Set([
|
|
|
22611
21367
|
]);
|
|
22612
21368
|
var skipDecision = (event) => QUIET.has(event) ? { kind: "none" } : { kind: "context", text: HOOK_SKIP_TEXT };
|
|
22613
21369
|
var TIMED_OUT = Symbol("timed out");
|
|
22614
|
-
var
|
|
21370
|
+
var within2 = async (work, ms) => {
|
|
22615
21371
|
let timer;
|
|
22616
21372
|
const expired = new Promise((resolve) => {
|
|
22617
21373
|
timer = setTimeout(() => resolve(TIMED_OUT), Math.max(0, ms));
|
|
@@ -22642,7 +21398,7 @@ var readWithin = async (stdin, budget) => {
|
|
|
22642
21398
|
text += String(chunk);
|
|
22643
21399
|
return text;
|
|
22644
21400
|
})();
|
|
22645
|
-
const text = await
|
|
21401
|
+
const text = await within2(read, budget.startedAt + budget.deadlineMs - budget.now());
|
|
22646
21402
|
return isTimedOut(text) ? null : text;
|
|
22647
21403
|
};
|
|
22648
21404
|
var note = (adapter, raw, env, budget, outcome, stage) => {
|
|
@@ -22671,7 +21427,7 @@ var dispatchWithin = async (adapter, raw, env, budget, dispatch = dispatchHook)
|
|
|
22671
21427
|
if (budget.host !== null && typeof native === "string")
|
|
22672
21428
|
budget.deadlineMs = hookDeadlineMs(env, budget.host, native);
|
|
22673
21429
|
const remaining = () => budget.startedAt + budget.deadlineMs - budget.now();
|
|
22674
|
-
const result = remaining() > 0 ? await
|
|
21430
|
+
const result = remaining() > 0 ? await within2(Promise.resolve().then(() => dispatch(adapter, raw, env)), remaining()) : TIMED_OUT;
|
|
22675
21431
|
if (isTimedOut(result))
|
|
22676
21432
|
return skippedHook(adapter, raw, env, budget, "dispatch");
|
|
22677
21433
|
if (remaining() < 0)
|
|
@@ -23237,8 +21993,8 @@ var codexAdapter = {
|
|
|
23237
21993
|
};
|
|
23238
21994
|
|
|
23239
21995
|
// packages/workit-core/src/hooks/hosts/cursor.ts
|
|
23240
|
-
import
|
|
23241
|
-
import
|
|
21996
|
+
import fs21 from "node:fs";
|
|
21997
|
+
import path29 from "node:path";
|
|
23242
21998
|
var undocumented = { support: "undocumented", native: null };
|
|
23243
21999
|
var none = { support: "none", native: null };
|
|
23244
22000
|
var CURSOR_DESCRIPTOR = {
|
|
@@ -23435,17 +22191,17 @@ var protocolEvent2 = (input) => {
|
|
|
23435
22191
|
};
|
|
23436
22192
|
var TRANSCRIPT_TAIL_BYTES = 256 * 1024;
|
|
23437
22193
|
var lastAssistantText = (file) => {
|
|
23438
|
-
if (!file || !
|
|
22194
|
+
if (!file || !path29.isAbsolute(file))
|
|
23439
22195
|
return null;
|
|
23440
22196
|
try {
|
|
23441
|
-
const size =
|
|
22197
|
+
const size = fs21.statSync(file).size;
|
|
23442
22198
|
const start = Math.max(0, size - TRANSCRIPT_TAIL_BYTES);
|
|
23443
22199
|
const buffer = Buffer.alloc(size - start);
|
|
23444
|
-
const fd =
|
|
22200
|
+
const fd = fs21.openSync(file, "r");
|
|
23445
22201
|
try {
|
|
23446
|
-
|
|
22202
|
+
fs21.readSync(fd, buffer, 0, buffer.length, start);
|
|
23447
22203
|
} finally {
|
|
23448
|
-
|
|
22204
|
+
fs21.closeSync(fd);
|
|
23449
22205
|
}
|
|
23450
22206
|
const lines = buffer.toString("utf8").split(`
|
|
23451
22207
|
`);
|
|
@@ -23472,7 +22228,7 @@ var lastAssistantText = (file) => {
|
|
|
23472
22228
|
return null;
|
|
23473
22229
|
}
|
|
23474
22230
|
};
|
|
23475
|
-
var
|
|
22231
|
+
var within3 = (root, dir) => dir === root || dir.startsWith(root.endsWith(path29.sep) ? root : `${root}${path29.sep}`);
|
|
23476
22232
|
var hookCwd = (input) => {
|
|
23477
22233
|
const cwd = existingDirectory(input.cwd);
|
|
23478
22234
|
if (cwd && input.hook_event_name === "beforeShellExecution")
|
|
@@ -23481,7 +22237,7 @@ var hookCwd = (input) => {
|
|
|
23481
22237
|
};
|
|
23482
22238
|
var cursorWorkspaceRoot = (input) => {
|
|
23483
22239
|
const cwd = existingDirectory(input.cwd);
|
|
23484
|
-
return cwd && input.workspace_roots.find((root) =>
|
|
22240
|
+
return cwd && input.workspace_roots.find((root) => within3(root, cwd)) || input.workspace_roots[0];
|
|
23485
22241
|
};
|
|
23486
22242
|
var cursorDeny = (reason) => ({
|
|
23487
22243
|
permission: "deny",
|