beplus-mcp 0.26.0 → 0.28.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/README.md +23 -4
- package/dist/index.js +1837 -644
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -916,10 +916,10 @@ var require_codegen = __commonJS({
|
|
|
916
916
|
return this._leafNode(new Throw(error2));
|
|
917
917
|
}
|
|
918
918
|
// start self-balancing block
|
|
919
|
-
block(
|
|
919
|
+
block(body2, nodeCount) {
|
|
920
920
|
this._blockStarts.push(this._nodes.length);
|
|
921
|
-
if (
|
|
922
|
-
this.code(
|
|
921
|
+
if (body2)
|
|
922
|
+
this.code(body2).endBlock(nodeCount);
|
|
923
923
|
return this;
|
|
924
924
|
}
|
|
925
925
|
// end the current self-balancing block
|
|
@@ -2344,15 +2344,15 @@ var require_validate = __commonJS({
|
|
|
2344
2344
|
validateFunction(it, () => (0, boolSchema_1.topBoolOrEmptySchema)(it));
|
|
2345
2345
|
}
|
|
2346
2346
|
exports.validateFunctionCode = validateFunctionCode;
|
|
2347
|
-
function validateFunction({ gen, validateName, schema, schemaEnv, opts },
|
|
2347
|
+
function validateFunction({ gen, validateName, schema, schemaEnv, opts }, body2) {
|
|
2348
2348
|
if (opts.code.es5) {
|
|
2349
2349
|
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${names_1.default.valCxt}`, schemaEnv.$async, () => {
|
|
2350
2350
|
gen.code((0, codegen_1._)`"use strict"; ${funcSourceUrl(schema, opts)}`);
|
|
2351
2351
|
destructureValCxtES5(gen, opts);
|
|
2352
|
-
gen.code(
|
|
2352
|
+
gen.code(body2);
|
|
2353
2353
|
});
|
|
2354
2354
|
} else {
|
|
2355
|
-
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => gen.code(funcSourceUrl(schema, opts)).code(
|
|
2355
|
+
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => gen.code(funcSourceUrl(schema, opts)).code(body2));
|
|
2356
2356
|
}
|
|
2357
2357
|
}
|
|
2358
2358
|
function destructureValCxt(opts) {
|
|
@@ -7678,15 +7678,15 @@ var $ZodCheckLessThan = /* @__PURE__ */ $constructor("$ZodCheckLessThan", (inst,
|
|
|
7678
7678
|
bag.exclusiveMaximum = def.value;
|
|
7679
7679
|
}
|
|
7680
7680
|
});
|
|
7681
|
-
inst._zod.check = (
|
|
7682
|
-
if (def.inclusive ?
|
|
7681
|
+
inst._zod.check = (payload2) => {
|
|
7682
|
+
if (def.inclusive ? payload2.value <= def.value : payload2.value < def.value) {
|
|
7683
7683
|
return;
|
|
7684
7684
|
}
|
|
7685
|
-
|
|
7685
|
+
payload2.issues.push({
|
|
7686
7686
|
origin,
|
|
7687
7687
|
code: "too_big",
|
|
7688
7688
|
maximum: def.value,
|
|
7689
|
-
input:
|
|
7689
|
+
input: payload2.value,
|
|
7690
7690
|
inclusive: def.inclusive,
|
|
7691
7691
|
inst,
|
|
7692
7692
|
continue: !def.abort
|
|
@@ -7706,15 +7706,15 @@ var $ZodCheckGreaterThan = /* @__PURE__ */ $constructor("$ZodCheckGreaterThan",
|
|
|
7706
7706
|
bag.exclusiveMinimum = def.value;
|
|
7707
7707
|
}
|
|
7708
7708
|
});
|
|
7709
|
-
inst._zod.check = (
|
|
7710
|
-
if (def.inclusive ?
|
|
7709
|
+
inst._zod.check = (payload2) => {
|
|
7710
|
+
if (def.inclusive ? payload2.value >= def.value : payload2.value > def.value) {
|
|
7711
7711
|
return;
|
|
7712
7712
|
}
|
|
7713
|
-
|
|
7713
|
+
payload2.issues.push({
|
|
7714
7714
|
origin,
|
|
7715
7715
|
code: "too_small",
|
|
7716
7716
|
minimum: def.value,
|
|
7717
|
-
input:
|
|
7717
|
+
input: payload2.value,
|
|
7718
7718
|
inclusive: def.inclusive,
|
|
7719
7719
|
inst,
|
|
7720
7720
|
continue: !def.abort
|
|
@@ -7727,17 +7727,17 @@ var $ZodCheckMultipleOf = /* @__PURE__ */ $constructor("$ZodCheckMultipleOf", (i
|
|
|
7727
7727
|
var _a;
|
|
7728
7728
|
(_a = inst2._zod.bag).multipleOf ?? (_a.multipleOf = def.value);
|
|
7729
7729
|
});
|
|
7730
|
-
inst._zod.check = (
|
|
7731
|
-
if (typeof
|
|
7730
|
+
inst._zod.check = (payload2) => {
|
|
7731
|
+
if (typeof payload2.value !== typeof def.value)
|
|
7732
7732
|
throw new Error("Cannot mix number and bigint in multiple_of check.");
|
|
7733
|
-
const isMultiple = typeof
|
|
7733
|
+
const isMultiple = typeof payload2.value === "bigint" ? payload2.value % def.value === BigInt(0) : floatSafeRemainder(payload2.value, def.value) === 0;
|
|
7734
7734
|
if (isMultiple)
|
|
7735
7735
|
return;
|
|
7736
|
-
|
|
7737
|
-
origin: typeof
|
|
7736
|
+
payload2.issues.push({
|
|
7737
|
+
origin: typeof payload2.value,
|
|
7738
7738
|
code: "not_multiple_of",
|
|
7739
7739
|
divisor: def.value,
|
|
7740
|
-
input:
|
|
7740
|
+
input: payload2.value,
|
|
7741
7741
|
inst,
|
|
7742
7742
|
continue: !def.abort
|
|
7743
7743
|
});
|
|
@@ -7757,11 +7757,11 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
7757
7757
|
if (isInt)
|
|
7758
7758
|
bag.pattern = integer;
|
|
7759
7759
|
});
|
|
7760
|
-
inst._zod.check = (
|
|
7761
|
-
const input =
|
|
7760
|
+
inst._zod.check = (payload2) => {
|
|
7761
|
+
const input = payload2.value;
|
|
7762
7762
|
if (isInt) {
|
|
7763
7763
|
if (!Number.isInteger(input)) {
|
|
7764
|
-
|
|
7764
|
+
payload2.issues.push({
|
|
7765
7765
|
expected: origin,
|
|
7766
7766
|
format: def.format,
|
|
7767
7767
|
code: "invalid_type",
|
|
@@ -7772,7 +7772,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
7772
7772
|
}
|
|
7773
7773
|
if (!Number.isSafeInteger(input)) {
|
|
7774
7774
|
if (input > 0) {
|
|
7775
|
-
|
|
7775
|
+
payload2.issues.push({
|
|
7776
7776
|
input,
|
|
7777
7777
|
code: "too_big",
|
|
7778
7778
|
maximum: Number.MAX_SAFE_INTEGER,
|
|
@@ -7782,7 +7782,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
7782
7782
|
continue: !def.abort
|
|
7783
7783
|
});
|
|
7784
7784
|
} else {
|
|
7785
|
-
|
|
7785
|
+
payload2.issues.push({
|
|
7786
7786
|
input,
|
|
7787
7787
|
code: "too_small",
|
|
7788
7788
|
minimum: Number.MIN_SAFE_INTEGER,
|
|
@@ -7796,7 +7796,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
7796
7796
|
}
|
|
7797
7797
|
}
|
|
7798
7798
|
if (input < minimum) {
|
|
7799
|
-
|
|
7799
|
+
payload2.issues.push({
|
|
7800
7800
|
origin: "number",
|
|
7801
7801
|
input,
|
|
7802
7802
|
code: "too_small",
|
|
@@ -7807,7 +7807,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
7807
7807
|
});
|
|
7808
7808
|
}
|
|
7809
7809
|
if (input > maximum) {
|
|
7810
|
-
|
|
7810
|
+
payload2.issues.push({
|
|
7811
7811
|
origin: "number",
|
|
7812
7812
|
input,
|
|
7813
7813
|
code: "too_big",
|
|
@@ -7820,8 +7820,8 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
7820
7820
|
var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (inst, def) => {
|
|
7821
7821
|
var _a;
|
|
7822
7822
|
$ZodCheck.init(inst, def);
|
|
7823
|
-
(_a = inst._zod.def).when ?? (_a.when = (
|
|
7824
|
-
const val =
|
|
7823
|
+
(_a = inst._zod.def).when ?? (_a.when = (payload2) => {
|
|
7824
|
+
const val = payload2.value;
|
|
7825
7825
|
return !nullish(val) && val.length !== void 0;
|
|
7826
7826
|
});
|
|
7827
7827
|
inst._zod.onattach.push((inst2) => {
|
|
@@ -7829,13 +7829,13 @@ var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (ins
|
|
|
7829
7829
|
if (def.maximum < curr)
|
|
7830
7830
|
inst2._zod.bag.maximum = def.maximum;
|
|
7831
7831
|
});
|
|
7832
|
-
inst._zod.check = (
|
|
7833
|
-
const input =
|
|
7832
|
+
inst._zod.check = (payload2) => {
|
|
7833
|
+
const input = payload2.value;
|
|
7834
7834
|
const length = input.length;
|
|
7835
7835
|
if (length <= def.maximum)
|
|
7836
7836
|
return;
|
|
7837
7837
|
const origin = getLengthableOrigin(input);
|
|
7838
|
-
|
|
7838
|
+
payload2.issues.push({
|
|
7839
7839
|
origin,
|
|
7840
7840
|
code: "too_big",
|
|
7841
7841
|
maximum: def.maximum,
|
|
@@ -7849,8 +7849,8 @@ var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (ins
|
|
|
7849
7849
|
var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (inst, def) => {
|
|
7850
7850
|
var _a;
|
|
7851
7851
|
$ZodCheck.init(inst, def);
|
|
7852
|
-
(_a = inst._zod.def).when ?? (_a.when = (
|
|
7853
|
-
const val =
|
|
7852
|
+
(_a = inst._zod.def).when ?? (_a.when = (payload2) => {
|
|
7853
|
+
const val = payload2.value;
|
|
7854
7854
|
return !nullish(val) && val.length !== void 0;
|
|
7855
7855
|
});
|
|
7856
7856
|
inst._zod.onattach.push((inst2) => {
|
|
@@ -7858,13 +7858,13 @@ var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (ins
|
|
|
7858
7858
|
if (def.minimum > curr)
|
|
7859
7859
|
inst2._zod.bag.minimum = def.minimum;
|
|
7860
7860
|
});
|
|
7861
|
-
inst._zod.check = (
|
|
7862
|
-
const input =
|
|
7861
|
+
inst._zod.check = (payload2) => {
|
|
7862
|
+
const input = payload2.value;
|
|
7863
7863
|
const length = input.length;
|
|
7864
7864
|
if (length >= def.minimum)
|
|
7865
7865
|
return;
|
|
7866
7866
|
const origin = getLengthableOrigin(input);
|
|
7867
|
-
|
|
7867
|
+
payload2.issues.push({
|
|
7868
7868
|
origin,
|
|
7869
7869
|
code: "too_small",
|
|
7870
7870
|
minimum: def.minimum,
|
|
@@ -7878,8 +7878,8 @@ var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (ins
|
|
|
7878
7878
|
var $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEquals", (inst, def) => {
|
|
7879
7879
|
var _a;
|
|
7880
7880
|
$ZodCheck.init(inst, def);
|
|
7881
|
-
(_a = inst._zod.def).when ?? (_a.when = (
|
|
7882
|
-
const val =
|
|
7881
|
+
(_a = inst._zod.def).when ?? (_a.when = (payload2) => {
|
|
7882
|
+
const val = payload2.value;
|
|
7883
7883
|
return !nullish(val) && val.length !== void 0;
|
|
7884
7884
|
});
|
|
7885
7885
|
inst._zod.onattach.push((inst2) => {
|
|
@@ -7888,19 +7888,19 @@ var $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEquals"
|
|
|
7888
7888
|
bag.maximum = def.length;
|
|
7889
7889
|
bag.length = def.length;
|
|
7890
7890
|
});
|
|
7891
|
-
inst._zod.check = (
|
|
7892
|
-
const input =
|
|
7891
|
+
inst._zod.check = (payload2) => {
|
|
7892
|
+
const input = payload2.value;
|
|
7893
7893
|
const length = input.length;
|
|
7894
7894
|
if (length === def.length)
|
|
7895
7895
|
return;
|
|
7896
7896
|
const origin = getLengthableOrigin(input);
|
|
7897
7897
|
const tooBig = length > def.length;
|
|
7898
|
-
|
|
7898
|
+
payload2.issues.push({
|
|
7899
7899
|
origin,
|
|
7900
7900
|
...tooBig ? { code: "too_big", maximum: def.length } : { code: "too_small", minimum: def.length },
|
|
7901
7901
|
inclusive: true,
|
|
7902
7902
|
exact: true,
|
|
7903
|
-
input:
|
|
7903
|
+
input: payload2.value,
|
|
7904
7904
|
inst,
|
|
7905
7905
|
continue: !def.abort
|
|
7906
7906
|
});
|
|
@@ -7918,15 +7918,15 @@ var $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringFormat"
|
|
|
7918
7918
|
}
|
|
7919
7919
|
});
|
|
7920
7920
|
if (def.pattern)
|
|
7921
|
-
(_a = inst._zod).check ?? (_a.check = (
|
|
7921
|
+
(_a = inst._zod).check ?? (_a.check = (payload2) => {
|
|
7922
7922
|
def.pattern.lastIndex = 0;
|
|
7923
|
-
if (def.pattern.test(
|
|
7923
|
+
if (def.pattern.test(payload2.value))
|
|
7924
7924
|
return;
|
|
7925
|
-
|
|
7925
|
+
payload2.issues.push({
|
|
7926
7926
|
origin: "string",
|
|
7927
7927
|
code: "invalid_format",
|
|
7928
7928
|
format: def.format,
|
|
7929
|
-
input:
|
|
7929
|
+
input: payload2.value,
|
|
7930
7930
|
...def.pattern ? { pattern: def.pattern.toString() } : {},
|
|
7931
7931
|
inst,
|
|
7932
7932
|
continue: !def.abort
|
|
@@ -7938,15 +7938,15 @@ var $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringFormat"
|
|
|
7938
7938
|
});
|
|
7939
7939
|
var $ZodCheckRegex = /* @__PURE__ */ $constructor("$ZodCheckRegex", (inst, def) => {
|
|
7940
7940
|
$ZodCheckStringFormat.init(inst, def);
|
|
7941
|
-
inst._zod.check = (
|
|
7941
|
+
inst._zod.check = (payload2) => {
|
|
7942
7942
|
def.pattern.lastIndex = 0;
|
|
7943
|
-
if (def.pattern.test(
|
|
7943
|
+
if (def.pattern.test(payload2.value))
|
|
7944
7944
|
return;
|
|
7945
|
-
|
|
7945
|
+
payload2.issues.push({
|
|
7946
7946
|
origin: "string",
|
|
7947
7947
|
code: "invalid_format",
|
|
7948
7948
|
format: "regex",
|
|
7949
|
-
input:
|
|
7949
|
+
input: payload2.value,
|
|
7950
7950
|
pattern: def.pattern.toString(),
|
|
7951
7951
|
inst,
|
|
7952
7952
|
continue: !def.abort
|
|
@@ -7971,15 +7971,15 @@ var $ZodCheckIncludes = /* @__PURE__ */ $constructor("$ZodCheckIncludes", (inst,
|
|
|
7971
7971
|
bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
|
|
7972
7972
|
bag.patterns.add(pattern);
|
|
7973
7973
|
});
|
|
7974
|
-
inst._zod.check = (
|
|
7975
|
-
if (
|
|
7974
|
+
inst._zod.check = (payload2) => {
|
|
7975
|
+
if (payload2.value.includes(def.includes, def.position))
|
|
7976
7976
|
return;
|
|
7977
|
-
|
|
7977
|
+
payload2.issues.push({
|
|
7978
7978
|
origin: "string",
|
|
7979
7979
|
code: "invalid_format",
|
|
7980
7980
|
format: "includes",
|
|
7981
7981
|
includes: def.includes,
|
|
7982
|
-
input:
|
|
7982
|
+
input: payload2.value,
|
|
7983
7983
|
inst,
|
|
7984
7984
|
continue: !def.abort
|
|
7985
7985
|
});
|
|
@@ -7994,15 +7994,15 @@ var $ZodCheckStartsWith = /* @__PURE__ */ $constructor("$ZodCheckStartsWith", (i
|
|
|
7994
7994
|
bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
|
|
7995
7995
|
bag.patterns.add(pattern);
|
|
7996
7996
|
});
|
|
7997
|
-
inst._zod.check = (
|
|
7998
|
-
if (
|
|
7997
|
+
inst._zod.check = (payload2) => {
|
|
7998
|
+
if (payload2.value.startsWith(def.prefix))
|
|
7999
7999
|
return;
|
|
8000
|
-
|
|
8000
|
+
payload2.issues.push({
|
|
8001
8001
|
origin: "string",
|
|
8002
8002
|
code: "invalid_format",
|
|
8003
8003
|
format: "starts_with",
|
|
8004
8004
|
prefix: def.prefix,
|
|
8005
|
-
input:
|
|
8005
|
+
input: payload2.value,
|
|
8006
8006
|
inst,
|
|
8007
8007
|
continue: !def.abort
|
|
8008
8008
|
});
|
|
@@ -8017,15 +8017,15 @@ var $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst,
|
|
|
8017
8017
|
bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
|
|
8018
8018
|
bag.patterns.add(pattern);
|
|
8019
8019
|
});
|
|
8020
|
-
inst._zod.check = (
|
|
8021
|
-
if (
|
|
8020
|
+
inst._zod.check = (payload2) => {
|
|
8021
|
+
if (payload2.value.endsWith(def.suffix))
|
|
8022
8022
|
return;
|
|
8023
|
-
|
|
8023
|
+
payload2.issues.push({
|
|
8024
8024
|
origin: "string",
|
|
8025
8025
|
code: "invalid_format",
|
|
8026
8026
|
format: "ends_with",
|
|
8027
8027
|
suffix: def.suffix,
|
|
8028
|
-
input:
|
|
8028
|
+
input: payload2.value,
|
|
8029
8029
|
inst,
|
|
8030
8030
|
continue: !def.abort
|
|
8031
8031
|
});
|
|
@@ -8033,8 +8033,8 @@ var $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst,
|
|
|
8033
8033
|
});
|
|
8034
8034
|
var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (inst, def) => {
|
|
8035
8035
|
$ZodCheck.init(inst, def);
|
|
8036
|
-
inst._zod.check = (
|
|
8037
|
-
|
|
8036
|
+
inst._zod.check = (payload2) => {
|
|
8037
|
+
payload2.value = def.tx(payload2.value);
|
|
8038
8038
|
};
|
|
8039
8039
|
});
|
|
8040
8040
|
|
|
@@ -8103,48 +8103,48 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
|
8103
8103
|
inst._zod.run = inst._zod.parse;
|
|
8104
8104
|
});
|
|
8105
8105
|
} else {
|
|
8106
|
-
const runChecks = (
|
|
8107
|
-
let isAborted2 = aborted(
|
|
8106
|
+
const runChecks = (payload2, checks2, ctx) => {
|
|
8107
|
+
let isAborted2 = aborted(payload2);
|
|
8108
8108
|
let asyncResult;
|
|
8109
8109
|
for (const ch of checks2) {
|
|
8110
8110
|
if (ch._zod.def.when) {
|
|
8111
|
-
const shouldRun = ch._zod.def.when(
|
|
8111
|
+
const shouldRun = ch._zod.def.when(payload2);
|
|
8112
8112
|
if (!shouldRun)
|
|
8113
8113
|
continue;
|
|
8114
8114
|
} else if (isAborted2) {
|
|
8115
8115
|
continue;
|
|
8116
8116
|
}
|
|
8117
|
-
const currLen =
|
|
8118
|
-
const _ = ch._zod.check(
|
|
8117
|
+
const currLen = payload2.issues.length;
|
|
8118
|
+
const _ = ch._zod.check(payload2);
|
|
8119
8119
|
if (_ instanceof Promise && ctx?.async === false) {
|
|
8120
8120
|
throw new $ZodAsyncError();
|
|
8121
8121
|
}
|
|
8122
8122
|
if (asyncResult || _ instanceof Promise) {
|
|
8123
8123
|
asyncResult = (asyncResult ?? Promise.resolve()).then(async () => {
|
|
8124
8124
|
await _;
|
|
8125
|
-
const nextLen =
|
|
8125
|
+
const nextLen = payload2.issues.length;
|
|
8126
8126
|
if (nextLen === currLen)
|
|
8127
8127
|
return;
|
|
8128
8128
|
if (!isAborted2)
|
|
8129
|
-
isAborted2 = aborted(
|
|
8129
|
+
isAborted2 = aborted(payload2, currLen);
|
|
8130
8130
|
});
|
|
8131
8131
|
} else {
|
|
8132
|
-
const nextLen =
|
|
8132
|
+
const nextLen = payload2.issues.length;
|
|
8133
8133
|
if (nextLen === currLen)
|
|
8134
8134
|
continue;
|
|
8135
8135
|
if (!isAborted2)
|
|
8136
|
-
isAborted2 = aborted(
|
|
8136
|
+
isAborted2 = aborted(payload2, currLen);
|
|
8137
8137
|
}
|
|
8138
8138
|
}
|
|
8139
8139
|
if (asyncResult) {
|
|
8140
8140
|
return asyncResult.then(() => {
|
|
8141
|
-
return
|
|
8141
|
+
return payload2;
|
|
8142
8142
|
});
|
|
8143
8143
|
}
|
|
8144
|
-
return
|
|
8144
|
+
return payload2;
|
|
8145
8145
|
};
|
|
8146
|
-
inst._zod.run = (
|
|
8147
|
-
const result = inst._zod.parse(
|
|
8146
|
+
inst._zod.run = (payload2, ctx) => {
|
|
8147
|
+
const result = inst._zod.parse(payload2, ctx);
|
|
8148
8148
|
if (result instanceof Promise) {
|
|
8149
8149
|
if (ctx.async === false)
|
|
8150
8150
|
throw new $ZodAsyncError();
|
|
@@ -8169,21 +8169,21 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
|
8169
8169
|
var $ZodString = /* @__PURE__ */ $constructor("$ZodString", (inst, def) => {
|
|
8170
8170
|
$ZodType.init(inst, def);
|
|
8171
8171
|
inst._zod.pattern = [...inst?._zod.bag?.patterns ?? []].pop() ?? string(inst._zod.bag);
|
|
8172
|
-
inst._zod.parse = (
|
|
8172
|
+
inst._zod.parse = (payload2, _) => {
|
|
8173
8173
|
if (def.coerce)
|
|
8174
8174
|
try {
|
|
8175
|
-
|
|
8175
|
+
payload2.value = String(payload2.value);
|
|
8176
8176
|
} catch (_2) {
|
|
8177
8177
|
}
|
|
8178
|
-
if (typeof
|
|
8179
|
-
return
|
|
8180
|
-
|
|
8178
|
+
if (typeof payload2.value === "string")
|
|
8179
|
+
return payload2;
|
|
8180
|
+
payload2.issues.push({
|
|
8181
8181
|
expected: "string",
|
|
8182
8182
|
code: "invalid_type",
|
|
8183
|
-
input:
|
|
8183
|
+
input: payload2.value,
|
|
8184
8184
|
inst
|
|
8185
8185
|
});
|
|
8186
|
-
return
|
|
8186
|
+
return payload2;
|
|
8187
8187
|
};
|
|
8188
8188
|
});
|
|
8189
8189
|
var $ZodStringFormat = /* @__PURE__ */ $constructor("$ZodStringFormat", (inst, def) => {
|
|
@@ -8220,20 +8220,20 @@ var $ZodEmail = /* @__PURE__ */ $constructor("$ZodEmail", (inst, def) => {
|
|
|
8220
8220
|
});
|
|
8221
8221
|
var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
8222
8222
|
$ZodStringFormat.init(inst, def);
|
|
8223
|
-
inst._zod.check = (
|
|
8223
|
+
inst._zod.check = (payload2) => {
|
|
8224
8224
|
try {
|
|
8225
|
-
const orig =
|
|
8225
|
+
const orig = payload2.value;
|
|
8226
8226
|
const url = new URL(orig);
|
|
8227
8227
|
const href = url.href;
|
|
8228
8228
|
if (def.hostname) {
|
|
8229
8229
|
def.hostname.lastIndex = 0;
|
|
8230
8230
|
if (!def.hostname.test(url.hostname)) {
|
|
8231
|
-
|
|
8231
|
+
payload2.issues.push({
|
|
8232
8232
|
code: "invalid_format",
|
|
8233
8233
|
format: "url",
|
|
8234
8234
|
note: "Invalid hostname",
|
|
8235
8235
|
pattern: hostname.source,
|
|
8236
|
-
input:
|
|
8236
|
+
input: payload2.value,
|
|
8237
8237
|
inst,
|
|
8238
8238
|
continue: !def.abort
|
|
8239
8239
|
});
|
|
@@ -8242,28 +8242,28 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
8242
8242
|
if (def.protocol) {
|
|
8243
8243
|
def.protocol.lastIndex = 0;
|
|
8244
8244
|
if (!def.protocol.test(url.protocol.endsWith(":") ? url.protocol.slice(0, -1) : url.protocol)) {
|
|
8245
|
-
|
|
8245
|
+
payload2.issues.push({
|
|
8246
8246
|
code: "invalid_format",
|
|
8247
8247
|
format: "url",
|
|
8248
8248
|
note: "Invalid protocol",
|
|
8249
8249
|
pattern: def.protocol.source,
|
|
8250
|
-
input:
|
|
8250
|
+
input: payload2.value,
|
|
8251
8251
|
inst,
|
|
8252
8252
|
continue: !def.abort
|
|
8253
8253
|
});
|
|
8254
8254
|
}
|
|
8255
8255
|
}
|
|
8256
8256
|
if (!orig.endsWith("/") && href.endsWith("/")) {
|
|
8257
|
-
|
|
8257
|
+
payload2.value = href.slice(0, -1);
|
|
8258
8258
|
} else {
|
|
8259
|
-
|
|
8259
|
+
payload2.value = href;
|
|
8260
8260
|
}
|
|
8261
8261
|
return;
|
|
8262
8262
|
} catch (_) {
|
|
8263
|
-
|
|
8263
|
+
payload2.issues.push({
|
|
8264
8264
|
code: "invalid_format",
|
|
8265
8265
|
format: "url",
|
|
8266
|
-
input:
|
|
8266
|
+
input: payload2.value,
|
|
8267
8267
|
inst,
|
|
8268
8268
|
continue: !def.abort
|
|
8269
8269
|
});
|
|
@@ -8329,14 +8329,14 @@ var $ZodIPv6 = /* @__PURE__ */ $constructor("$ZodIPv6", (inst, def) => {
|
|
|
8329
8329
|
const bag = inst2._zod.bag;
|
|
8330
8330
|
bag.format = `ipv6`;
|
|
8331
8331
|
});
|
|
8332
|
-
inst._zod.check = (
|
|
8332
|
+
inst._zod.check = (payload2) => {
|
|
8333
8333
|
try {
|
|
8334
|
-
new URL(`http://[${
|
|
8334
|
+
new URL(`http://[${payload2.value}]`);
|
|
8335
8335
|
} catch {
|
|
8336
|
-
|
|
8336
|
+
payload2.issues.push({
|
|
8337
8337
|
code: "invalid_format",
|
|
8338
8338
|
format: "ipv6",
|
|
8339
|
-
input:
|
|
8339
|
+
input: payload2.value,
|
|
8340
8340
|
inst,
|
|
8341
8341
|
continue: !def.abort
|
|
8342
8342
|
});
|
|
@@ -8350,8 +8350,8 @@ var $ZodCIDRv4 = /* @__PURE__ */ $constructor("$ZodCIDRv4", (inst, def) => {
|
|
|
8350
8350
|
var $ZodCIDRv6 = /* @__PURE__ */ $constructor("$ZodCIDRv6", (inst, def) => {
|
|
8351
8351
|
def.pattern ?? (def.pattern = cidrv6);
|
|
8352
8352
|
$ZodStringFormat.init(inst, def);
|
|
8353
|
-
inst._zod.check = (
|
|
8354
|
-
const [address, prefix] =
|
|
8353
|
+
inst._zod.check = (payload2) => {
|
|
8354
|
+
const [address, prefix] = payload2.value.split("/");
|
|
8355
8355
|
try {
|
|
8356
8356
|
if (!prefix)
|
|
8357
8357
|
throw new Error();
|
|
@@ -8362,10 +8362,10 @@ var $ZodCIDRv6 = /* @__PURE__ */ $constructor("$ZodCIDRv6", (inst, def) => {
|
|
|
8362
8362
|
throw new Error();
|
|
8363
8363
|
new URL(`http://[${address}]`);
|
|
8364
8364
|
} catch {
|
|
8365
|
-
|
|
8365
|
+
payload2.issues.push({
|
|
8366
8366
|
code: "invalid_format",
|
|
8367
8367
|
format: "cidrv6",
|
|
8368
|
-
input:
|
|
8368
|
+
input: payload2.value,
|
|
8369
8369
|
inst,
|
|
8370
8370
|
continue: !def.abort
|
|
8371
8371
|
});
|
|
@@ -8390,13 +8390,13 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
|
|
|
8390
8390
|
inst._zod.onattach.push((inst2) => {
|
|
8391
8391
|
inst2._zod.bag.contentEncoding = "base64";
|
|
8392
8392
|
});
|
|
8393
|
-
inst._zod.check = (
|
|
8394
|
-
if (isValidBase64(
|
|
8393
|
+
inst._zod.check = (payload2) => {
|
|
8394
|
+
if (isValidBase64(payload2.value))
|
|
8395
8395
|
return;
|
|
8396
|
-
|
|
8396
|
+
payload2.issues.push({
|
|
8397
8397
|
code: "invalid_format",
|
|
8398
8398
|
format: "base64",
|
|
8399
|
-
input:
|
|
8399
|
+
input: payload2.value,
|
|
8400
8400
|
inst,
|
|
8401
8401
|
continue: !def.abort
|
|
8402
8402
|
});
|
|
@@ -8415,13 +8415,13 @@ var $ZodBase64URL = /* @__PURE__ */ $constructor("$ZodBase64URL", (inst, def) =>
|
|
|
8415
8415
|
inst._zod.onattach.push((inst2) => {
|
|
8416
8416
|
inst2._zod.bag.contentEncoding = "base64url";
|
|
8417
8417
|
});
|
|
8418
|
-
inst._zod.check = (
|
|
8419
|
-
if (isValidBase64URL(
|
|
8418
|
+
inst._zod.check = (payload2) => {
|
|
8419
|
+
if (isValidBase64URL(payload2.value))
|
|
8420
8420
|
return;
|
|
8421
|
-
|
|
8421
|
+
payload2.issues.push({
|
|
8422
8422
|
code: "invalid_format",
|
|
8423
8423
|
format: "base64url",
|
|
8424
|
-
input:
|
|
8424
|
+
input: payload2.value,
|
|
8425
8425
|
inst,
|
|
8426
8426
|
continue: !def.abort
|
|
8427
8427
|
});
|
|
@@ -8453,13 +8453,13 @@ function isValidJWT(token, algorithm = null) {
|
|
|
8453
8453
|
}
|
|
8454
8454
|
var $ZodJWT = /* @__PURE__ */ $constructor("$ZodJWT", (inst, def) => {
|
|
8455
8455
|
$ZodStringFormat.init(inst, def);
|
|
8456
|
-
inst._zod.check = (
|
|
8457
|
-
if (isValidJWT(
|
|
8456
|
+
inst._zod.check = (payload2) => {
|
|
8457
|
+
if (isValidJWT(payload2.value, def.alg))
|
|
8458
8458
|
return;
|
|
8459
|
-
|
|
8459
|
+
payload2.issues.push({
|
|
8460
8460
|
code: "invalid_format",
|
|
8461
8461
|
format: "jwt",
|
|
8462
|
-
input:
|
|
8462
|
+
input: payload2.value,
|
|
8463
8463
|
inst,
|
|
8464
8464
|
continue: !def.abort
|
|
8465
8465
|
});
|
|
@@ -8468,25 +8468,25 @@ var $ZodJWT = /* @__PURE__ */ $constructor("$ZodJWT", (inst, def) => {
|
|
|
8468
8468
|
var $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
|
|
8469
8469
|
$ZodType.init(inst, def);
|
|
8470
8470
|
inst._zod.pattern = inst._zod.bag.pattern ?? number;
|
|
8471
|
-
inst._zod.parse = (
|
|
8471
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
8472
8472
|
if (def.coerce)
|
|
8473
8473
|
try {
|
|
8474
|
-
|
|
8474
|
+
payload2.value = Number(payload2.value);
|
|
8475
8475
|
} catch (_) {
|
|
8476
8476
|
}
|
|
8477
|
-
const input =
|
|
8477
|
+
const input = payload2.value;
|
|
8478
8478
|
if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) {
|
|
8479
|
-
return
|
|
8479
|
+
return payload2;
|
|
8480
8480
|
}
|
|
8481
8481
|
const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0;
|
|
8482
|
-
|
|
8482
|
+
payload2.issues.push({
|
|
8483
8483
|
expected: "number",
|
|
8484
8484
|
code: "invalid_type",
|
|
8485
8485
|
input,
|
|
8486
8486
|
inst,
|
|
8487
8487
|
...received ? { received } : {}
|
|
8488
8488
|
});
|
|
8489
|
-
return
|
|
8489
|
+
return payload2;
|
|
8490
8490
|
};
|
|
8491
8491
|
});
|
|
8492
8492
|
var $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
|
|
@@ -8496,55 +8496,55 @@ var $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) =>
|
|
|
8496
8496
|
var $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
|
|
8497
8497
|
$ZodType.init(inst, def);
|
|
8498
8498
|
inst._zod.pattern = boolean;
|
|
8499
|
-
inst._zod.parse = (
|
|
8499
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
8500
8500
|
if (def.coerce)
|
|
8501
8501
|
try {
|
|
8502
|
-
|
|
8502
|
+
payload2.value = Boolean(payload2.value);
|
|
8503
8503
|
} catch (_) {
|
|
8504
8504
|
}
|
|
8505
|
-
const input =
|
|
8505
|
+
const input = payload2.value;
|
|
8506
8506
|
if (typeof input === "boolean")
|
|
8507
|
-
return
|
|
8508
|
-
|
|
8507
|
+
return payload2;
|
|
8508
|
+
payload2.issues.push({
|
|
8509
8509
|
expected: "boolean",
|
|
8510
8510
|
code: "invalid_type",
|
|
8511
8511
|
input,
|
|
8512
8512
|
inst
|
|
8513
8513
|
});
|
|
8514
|
-
return
|
|
8514
|
+
return payload2;
|
|
8515
8515
|
};
|
|
8516
8516
|
});
|
|
8517
8517
|
var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
|
|
8518
8518
|
$ZodType.init(inst, def);
|
|
8519
8519
|
inst._zod.pattern = _null;
|
|
8520
8520
|
inst._zod.values = /* @__PURE__ */ new Set([null]);
|
|
8521
|
-
inst._zod.parse = (
|
|
8522
|
-
const input =
|
|
8521
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
8522
|
+
const input = payload2.value;
|
|
8523
8523
|
if (input === null)
|
|
8524
|
-
return
|
|
8525
|
-
|
|
8524
|
+
return payload2;
|
|
8525
|
+
payload2.issues.push({
|
|
8526
8526
|
expected: "null",
|
|
8527
8527
|
code: "invalid_type",
|
|
8528
8528
|
input,
|
|
8529
8529
|
inst
|
|
8530
8530
|
});
|
|
8531
|
-
return
|
|
8531
|
+
return payload2;
|
|
8532
8532
|
};
|
|
8533
8533
|
});
|
|
8534
8534
|
var $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
|
|
8535
8535
|
$ZodType.init(inst, def);
|
|
8536
|
-
inst._zod.parse = (
|
|
8536
|
+
inst._zod.parse = (payload2) => payload2;
|
|
8537
8537
|
});
|
|
8538
8538
|
var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
|
|
8539
8539
|
$ZodType.init(inst, def);
|
|
8540
|
-
inst._zod.parse = (
|
|
8541
|
-
|
|
8540
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
8541
|
+
payload2.issues.push({
|
|
8542
8542
|
expected: "never",
|
|
8543
8543
|
code: "invalid_type",
|
|
8544
|
-
input:
|
|
8544
|
+
input: payload2.value,
|
|
8545
8545
|
inst
|
|
8546
8546
|
});
|
|
8547
|
-
return
|
|
8547
|
+
return payload2;
|
|
8548
8548
|
};
|
|
8549
8549
|
});
|
|
8550
8550
|
function handleArrayResult(result, final, index) {
|
|
@@ -8555,18 +8555,18 @@ function handleArrayResult(result, final, index) {
|
|
|
8555
8555
|
}
|
|
8556
8556
|
var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
8557
8557
|
$ZodType.init(inst, def);
|
|
8558
|
-
inst._zod.parse = (
|
|
8559
|
-
const input =
|
|
8558
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
8559
|
+
const input = payload2.value;
|
|
8560
8560
|
if (!Array.isArray(input)) {
|
|
8561
|
-
|
|
8561
|
+
payload2.issues.push({
|
|
8562
8562
|
expected: "array",
|
|
8563
8563
|
code: "invalid_type",
|
|
8564
8564
|
input,
|
|
8565
8565
|
inst
|
|
8566
8566
|
});
|
|
8567
|
-
return
|
|
8567
|
+
return payload2;
|
|
8568
8568
|
}
|
|
8569
|
-
|
|
8569
|
+
payload2.value = Array(input.length);
|
|
8570
8570
|
const proms = [];
|
|
8571
8571
|
for (let i = 0; i < input.length; i++) {
|
|
8572
8572
|
const item = input[i];
|
|
@@ -8575,15 +8575,15 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
|
8575
8575
|
issues: []
|
|
8576
8576
|
}, ctx);
|
|
8577
8577
|
if (result instanceof Promise) {
|
|
8578
|
-
proms.push(result.then((result2) => handleArrayResult(result2,
|
|
8578
|
+
proms.push(result.then((result2) => handleArrayResult(result2, payload2, i)));
|
|
8579
8579
|
} else {
|
|
8580
|
-
handleArrayResult(result,
|
|
8580
|
+
handleArrayResult(result, payload2, i);
|
|
8581
8581
|
}
|
|
8582
8582
|
}
|
|
8583
8583
|
if (proms.length) {
|
|
8584
|
-
return Promise.all(proms).then(() =>
|
|
8584
|
+
return Promise.all(proms).then(() => payload2);
|
|
8585
8585
|
}
|
|
8586
|
-
return
|
|
8586
|
+
return payload2;
|
|
8587
8587
|
};
|
|
8588
8588
|
});
|
|
8589
8589
|
function handleObjectResult(result, final, key) {
|
|
@@ -8694,7 +8694,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
8694
8694
|
doc.write(`payload.value = newResult;`);
|
|
8695
8695
|
doc.write(`return payload;`);
|
|
8696
8696
|
const fn = doc.compile();
|
|
8697
|
-
return (
|
|
8697
|
+
return (payload2, ctx) => fn(shape, payload2, ctx);
|
|
8698
8698
|
};
|
|
8699
8699
|
let fastpass;
|
|
8700
8700
|
const isObject2 = isObject;
|
|
@@ -8703,41 +8703,41 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
8703
8703
|
const fastEnabled = jit && allowsEval2.value;
|
|
8704
8704
|
const catchall = def.catchall;
|
|
8705
8705
|
let value;
|
|
8706
|
-
inst._zod.parse = (
|
|
8706
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
8707
8707
|
value ?? (value = _normalized.value);
|
|
8708
|
-
const input =
|
|
8708
|
+
const input = payload2.value;
|
|
8709
8709
|
if (!isObject2(input)) {
|
|
8710
|
-
|
|
8710
|
+
payload2.issues.push({
|
|
8711
8711
|
expected: "object",
|
|
8712
8712
|
code: "invalid_type",
|
|
8713
8713
|
input,
|
|
8714
8714
|
inst
|
|
8715
8715
|
});
|
|
8716
|
-
return
|
|
8716
|
+
return payload2;
|
|
8717
8717
|
}
|
|
8718
8718
|
const proms = [];
|
|
8719
8719
|
if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {
|
|
8720
8720
|
if (!fastpass)
|
|
8721
8721
|
fastpass = generateFastpass(def.shape);
|
|
8722
|
-
|
|
8722
|
+
payload2 = fastpass(payload2, ctx);
|
|
8723
8723
|
} else {
|
|
8724
|
-
|
|
8724
|
+
payload2.value = {};
|
|
8725
8725
|
const shape = value.shape;
|
|
8726
8726
|
for (const key of value.keys) {
|
|
8727
8727
|
const el = shape[key];
|
|
8728
8728
|
const r = el._zod.run({ value: input[key], issues: [] }, ctx);
|
|
8729
8729
|
const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
|
|
8730
8730
|
if (r instanceof Promise) {
|
|
8731
|
-
proms.push(r.then((r2) => isOptional ? handleOptionalObjectResult(r2,
|
|
8731
|
+
proms.push(r.then((r2) => isOptional ? handleOptionalObjectResult(r2, payload2, key, input) : handleObjectResult(r2, payload2, key)));
|
|
8732
8732
|
} else if (isOptional) {
|
|
8733
|
-
handleOptionalObjectResult(r,
|
|
8733
|
+
handleOptionalObjectResult(r, payload2, key, input);
|
|
8734
8734
|
} else {
|
|
8735
|
-
handleObjectResult(r,
|
|
8735
|
+
handleObjectResult(r, payload2, key);
|
|
8736
8736
|
}
|
|
8737
8737
|
}
|
|
8738
8738
|
}
|
|
8739
8739
|
if (!catchall) {
|
|
8740
|
-
return proms.length ? Promise.all(proms).then(() =>
|
|
8740
|
+
return proms.length ? Promise.all(proms).then(() => payload2) : payload2;
|
|
8741
8741
|
}
|
|
8742
8742
|
const unrecognized = [];
|
|
8743
8743
|
const keySet = value.keySet;
|
|
@@ -8752,13 +8752,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
8752
8752
|
}
|
|
8753
8753
|
const r = _catchall.run({ value: input[key], issues: [] }, ctx);
|
|
8754
8754
|
if (r instanceof Promise) {
|
|
8755
|
-
proms.push(r.then((r2) => handleObjectResult(r2,
|
|
8755
|
+
proms.push(r.then((r2) => handleObjectResult(r2, payload2, key)));
|
|
8756
8756
|
} else {
|
|
8757
|
-
handleObjectResult(r,
|
|
8757
|
+
handleObjectResult(r, payload2, key);
|
|
8758
8758
|
}
|
|
8759
8759
|
}
|
|
8760
8760
|
if (unrecognized.length) {
|
|
8761
|
-
|
|
8761
|
+
payload2.issues.push({
|
|
8762
8762
|
code: "unrecognized_keys",
|
|
8763
8763
|
keys: unrecognized,
|
|
8764
8764
|
input,
|
|
@@ -8766,9 +8766,9 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
8766
8766
|
});
|
|
8767
8767
|
}
|
|
8768
8768
|
if (!proms.length)
|
|
8769
|
-
return
|
|
8769
|
+
return payload2;
|
|
8770
8770
|
return Promise.all(proms).then(() => {
|
|
8771
|
-
return
|
|
8771
|
+
return payload2;
|
|
8772
8772
|
});
|
|
8773
8773
|
};
|
|
8774
8774
|
});
|
|
@@ -8804,12 +8804,12 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
|
|
|
8804
8804
|
}
|
|
8805
8805
|
return void 0;
|
|
8806
8806
|
});
|
|
8807
|
-
inst._zod.parse = (
|
|
8807
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
8808
8808
|
let async = false;
|
|
8809
8809
|
const results = [];
|
|
8810
8810
|
for (const option of def.options) {
|
|
8811
8811
|
const result = option._zod.run({
|
|
8812
|
-
value:
|
|
8812
|
+
value: payload2.value,
|
|
8813
8813
|
issues: []
|
|
8814
8814
|
}, ctx);
|
|
8815
8815
|
if (result instanceof Promise) {
|
|
@@ -8822,9 +8822,9 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
|
|
|
8822
8822
|
}
|
|
8823
8823
|
}
|
|
8824
8824
|
if (!async)
|
|
8825
|
-
return handleUnionResults(results,
|
|
8825
|
+
return handleUnionResults(results, payload2, inst, ctx);
|
|
8826
8826
|
return Promise.all(results).then((results2) => {
|
|
8827
|
-
return handleUnionResults(results2,
|
|
8827
|
+
return handleUnionResults(results2, payload2, inst, ctx);
|
|
8828
8828
|
});
|
|
8829
8829
|
};
|
|
8830
8830
|
});
|
|
@@ -8863,25 +8863,25 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
8863
8863
|
}
|
|
8864
8864
|
return map;
|
|
8865
8865
|
});
|
|
8866
|
-
inst._zod.parse = (
|
|
8867
|
-
const input =
|
|
8866
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
8867
|
+
const input = payload2.value;
|
|
8868
8868
|
if (!isObject(input)) {
|
|
8869
|
-
|
|
8869
|
+
payload2.issues.push({
|
|
8870
8870
|
code: "invalid_type",
|
|
8871
8871
|
expected: "object",
|
|
8872
8872
|
input,
|
|
8873
8873
|
inst
|
|
8874
8874
|
});
|
|
8875
|
-
return
|
|
8875
|
+
return payload2;
|
|
8876
8876
|
}
|
|
8877
8877
|
const opt = disc.value.get(input?.[def.discriminator]);
|
|
8878
8878
|
if (opt) {
|
|
8879
|
-
return opt._zod.run(
|
|
8879
|
+
return opt._zod.run(payload2, ctx);
|
|
8880
8880
|
}
|
|
8881
8881
|
if (def.unionFallback) {
|
|
8882
|
-
return _super(
|
|
8882
|
+
return _super(payload2, ctx);
|
|
8883
8883
|
}
|
|
8884
|
-
|
|
8884
|
+
payload2.issues.push({
|
|
8885
8885
|
code: "invalid_union",
|
|
8886
8886
|
errors: [],
|
|
8887
8887
|
note: "No matching discriminator",
|
|
@@ -8889,22 +8889,22 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
8889
8889
|
path: [def.discriminator],
|
|
8890
8890
|
inst
|
|
8891
8891
|
});
|
|
8892
|
-
return
|
|
8892
|
+
return payload2;
|
|
8893
8893
|
};
|
|
8894
8894
|
});
|
|
8895
8895
|
var $ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
|
|
8896
8896
|
$ZodType.init(inst, def);
|
|
8897
|
-
inst._zod.parse = (
|
|
8898
|
-
const input =
|
|
8897
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
8898
|
+
const input = payload2.value;
|
|
8899
8899
|
const left = def.left._zod.run({ value: input, issues: [] }, ctx);
|
|
8900
8900
|
const right = def.right._zod.run({ value: input, issues: [] }, ctx);
|
|
8901
8901
|
const async = left instanceof Promise || right instanceof Promise;
|
|
8902
8902
|
if (async) {
|
|
8903
8903
|
return Promise.all([left, right]).then(([left2, right2]) => {
|
|
8904
|
-
return handleIntersectionResults(
|
|
8904
|
+
return handleIntersectionResults(payload2, left2, right2);
|
|
8905
8905
|
});
|
|
8906
8906
|
}
|
|
8907
|
-
return handleIntersectionResults(
|
|
8907
|
+
return handleIntersectionResults(payload2, left, right);
|
|
8908
8908
|
};
|
|
8909
8909
|
});
|
|
8910
8910
|
function mergeValues(a, b) {
|
|
@@ -8969,36 +8969,36 @@ function handleIntersectionResults(result, left, right) {
|
|
|
8969
8969
|
}
|
|
8970
8970
|
var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
8971
8971
|
$ZodType.init(inst, def);
|
|
8972
|
-
inst._zod.parse = (
|
|
8973
|
-
const input =
|
|
8972
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
8973
|
+
const input = payload2.value;
|
|
8974
8974
|
if (!isPlainObject(input)) {
|
|
8975
|
-
|
|
8975
|
+
payload2.issues.push({
|
|
8976
8976
|
expected: "record",
|
|
8977
8977
|
code: "invalid_type",
|
|
8978
8978
|
input,
|
|
8979
8979
|
inst
|
|
8980
8980
|
});
|
|
8981
|
-
return
|
|
8981
|
+
return payload2;
|
|
8982
8982
|
}
|
|
8983
8983
|
const proms = [];
|
|
8984
8984
|
if (def.keyType._zod.values) {
|
|
8985
8985
|
const values = def.keyType._zod.values;
|
|
8986
|
-
|
|
8986
|
+
payload2.value = {};
|
|
8987
8987
|
for (const key of values) {
|
|
8988
8988
|
if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
|
|
8989
8989
|
const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
|
|
8990
8990
|
if (result instanceof Promise) {
|
|
8991
8991
|
proms.push(result.then((result2) => {
|
|
8992
8992
|
if (result2.issues.length) {
|
|
8993
|
-
|
|
8993
|
+
payload2.issues.push(...prefixIssues(key, result2.issues));
|
|
8994
8994
|
}
|
|
8995
|
-
|
|
8995
|
+
payload2.value[key] = result2.value;
|
|
8996
8996
|
}));
|
|
8997
8997
|
} else {
|
|
8998
8998
|
if (result.issues.length) {
|
|
8999
|
-
|
|
8999
|
+
payload2.issues.push(...prefixIssues(key, result.issues));
|
|
9000
9000
|
}
|
|
9001
|
-
|
|
9001
|
+
payload2.value[key] = result.value;
|
|
9002
9002
|
}
|
|
9003
9003
|
}
|
|
9004
9004
|
}
|
|
@@ -9010,7 +9010,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
9010
9010
|
}
|
|
9011
9011
|
}
|
|
9012
9012
|
if (unrecognized && unrecognized.length > 0) {
|
|
9013
|
-
|
|
9013
|
+
payload2.issues.push({
|
|
9014
9014
|
code: "unrecognized_keys",
|
|
9015
9015
|
input,
|
|
9016
9016
|
inst,
|
|
@@ -9018,7 +9018,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
9018
9018
|
});
|
|
9019
9019
|
}
|
|
9020
9020
|
} else {
|
|
9021
|
-
|
|
9021
|
+
payload2.value = {};
|
|
9022
9022
|
for (const key of Reflect.ownKeys(input)) {
|
|
9023
9023
|
if (key === "__proto__")
|
|
9024
9024
|
continue;
|
|
@@ -9027,7 +9027,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
9027
9027
|
throw new Error("Async schemas not supported in object keys currently");
|
|
9028
9028
|
}
|
|
9029
9029
|
if (keyResult.issues.length) {
|
|
9030
|
-
|
|
9030
|
+
payload2.issues.push({
|
|
9031
9031
|
origin: "record",
|
|
9032
9032
|
code: "invalid_key",
|
|
9033
9033
|
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
@@ -9035,29 +9035,29 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
9035
9035
|
path: [key],
|
|
9036
9036
|
inst
|
|
9037
9037
|
});
|
|
9038
|
-
|
|
9038
|
+
payload2.value[keyResult.value] = keyResult.value;
|
|
9039
9039
|
continue;
|
|
9040
9040
|
}
|
|
9041
9041
|
const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
|
|
9042
9042
|
if (result instanceof Promise) {
|
|
9043
9043
|
proms.push(result.then((result2) => {
|
|
9044
9044
|
if (result2.issues.length) {
|
|
9045
|
-
|
|
9045
|
+
payload2.issues.push(...prefixIssues(key, result2.issues));
|
|
9046
9046
|
}
|
|
9047
|
-
|
|
9047
|
+
payload2.value[keyResult.value] = result2.value;
|
|
9048
9048
|
}));
|
|
9049
9049
|
} else {
|
|
9050
9050
|
if (result.issues.length) {
|
|
9051
|
-
|
|
9051
|
+
payload2.issues.push(...prefixIssues(key, result.issues));
|
|
9052
9052
|
}
|
|
9053
|
-
|
|
9053
|
+
payload2.value[keyResult.value] = result.value;
|
|
9054
9054
|
}
|
|
9055
9055
|
}
|
|
9056
9056
|
}
|
|
9057
9057
|
if (proms.length) {
|
|
9058
|
-
return Promise.all(proms).then(() =>
|
|
9058
|
+
return Promise.all(proms).then(() => payload2);
|
|
9059
9059
|
}
|
|
9060
|
-
return
|
|
9060
|
+
return payload2;
|
|
9061
9061
|
};
|
|
9062
9062
|
});
|
|
9063
9063
|
var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
|
|
@@ -9065,54 +9065,54 @@ var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
|
|
|
9065
9065
|
const values = getEnumValues(def.entries);
|
|
9066
9066
|
inst._zod.values = new Set(values);
|
|
9067
9067
|
inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
|
|
9068
|
-
inst._zod.parse = (
|
|
9069
|
-
const input =
|
|
9068
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
9069
|
+
const input = payload2.value;
|
|
9070
9070
|
if (inst._zod.values.has(input)) {
|
|
9071
|
-
return
|
|
9071
|
+
return payload2;
|
|
9072
9072
|
}
|
|
9073
|
-
|
|
9073
|
+
payload2.issues.push({
|
|
9074
9074
|
code: "invalid_value",
|
|
9075
9075
|
values,
|
|
9076
9076
|
input,
|
|
9077
9077
|
inst
|
|
9078
9078
|
});
|
|
9079
|
-
return
|
|
9079
|
+
return payload2;
|
|
9080
9080
|
};
|
|
9081
9081
|
});
|
|
9082
9082
|
var $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
|
|
9083
9083
|
$ZodType.init(inst, def);
|
|
9084
9084
|
inst._zod.values = new Set(def.values);
|
|
9085
9085
|
inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? o.toString() : String(o)).join("|")})$`);
|
|
9086
|
-
inst._zod.parse = (
|
|
9087
|
-
const input =
|
|
9086
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
9087
|
+
const input = payload2.value;
|
|
9088
9088
|
if (inst._zod.values.has(input)) {
|
|
9089
|
-
return
|
|
9089
|
+
return payload2;
|
|
9090
9090
|
}
|
|
9091
|
-
|
|
9091
|
+
payload2.issues.push({
|
|
9092
9092
|
code: "invalid_value",
|
|
9093
9093
|
values: def.values,
|
|
9094
9094
|
input,
|
|
9095
9095
|
inst
|
|
9096
9096
|
});
|
|
9097
|
-
return
|
|
9097
|
+
return payload2;
|
|
9098
9098
|
};
|
|
9099
9099
|
});
|
|
9100
9100
|
var $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) => {
|
|
9101
9101
|
$ZodType.init(inst, def);
|
|
9102
|
-
inst._zod.parse = (
|
|
9103
|
-
const _out = def.transform(
|
|
9102
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
9103
|
+
const _out = def.transform(payload2.value, payload2);
|
|
9104
9104
|
if (_ctx.async) {
|
|
9105
9105
|
const output = _out instanceof Promise ? _out : Promise.resolve(_out);
|
|
9106
9106
|
return output.then((output2) => {
|
|
9107
|
-
|
|
9108
|
-
return
|
|
9107
|
+
payload2.value = output2;
|
|
9108
|
+
return payload2;
|
|
9109
9109
|
});
|
|
9110
9110
|
}
|
|
9111
9111
|
if (_out instanceof Promise) {
|
|
9112
9112
|
throw new $ZodAsyncError();
|
|
9113
9113
|
}
|
|
9114
|
-
|
|
9115
|
-
return
|
|
9114
|
+
payload2.value = _out;
|
|
9115
|
+
return payload2;
|
|
9116
9116
|
};
|
|
9117
9117
|
});
|
|
9118
9118
|
var $ZodOptional = /* @__PURE__ */ $constructor("$ZodOptional", (inst, def) => {
|
|
@@ -9126,14 +9126,14 @@ var $ZodOptional = /* @__PURE__ */ $constructor("$ZodOptional", (inst, def) => {
|
|
|
9126
9126
|
const pattern = def.innerType._zod.pattern;
|
|
9127
9127
|
return pattern ? new RegExp(`^(${cleanRegex(pattern.source)})?$`) : void 0;
|
|
9128
9128
|
});
|
|
9129
|
-
inst._zod.parse = (
|
|
9129
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9130
9130
|
if (def.innerType._zod.optin === "optional") {
|
|
9131
|
-
return def.innerType._zod.run(
|
|
9131
|
+
return def.innerType._zod.run(payload2, ctx);
|
|
9132
9132
|
}
|
|
9133
|
-
if (
|
|
9134
|
-
return
|
|
9133
|
+
if (payload2.value === void 0) {
|
|
9134
|
+
return payload2;
|
|
9135
9135
|
}
|
|
9136
|
-
return def.innerType._zod.run(
|
|
9136
|
+
return def.innerType._zod.run(payload2, ctx);
|
|
9137
9137
|
};
|
|
9138
9138
|
});
|
|
9139
9139
|
var $ZodNullable = /* @__PURE__ */ $constructor("$ZodNullable", (inst, def) => {
|
|
@@ -9147,43 +9147,43 @@ var $ZodNullable = /* @__PURE__ */ $constructor("$ZodNullable", (inst, def) => {
|
|
|
9147
9147
|
defineLazy(inst._zod, "values", () => {
|
|
9148
9148
|
return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, null]) : void 0;
|
|
9149
9149
|
});
|
|
9150
|
-
inst._zod.parse = (
|
|
9151
|
-
if (
|
|
9152
|
-
return
|
|
9153
|
-
return def.innerType._zod.run(
|
|
9150
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9151
|
+
if (payload2.value === null)
|
|
9152
|
+
return payload2;
|
|
9153
|
+
return def.innerType._zod.run(payload2, ctx);
|
|
9154
9154
|
};
|
|
9155
9155
|
});
|
|
9156
9156
|
var $ZodDefault = /* @__PURE__ */ $constructor("$ZodDefault", (inst, def) => {
|
|
9157
9157
|
$ZodType.init(inst, def);
|
|
9158
9158
|
inst._zod.optin = "optional";
|
|
9159
9159
|
defineLazy(inst._zod, "values", () => def.innerType._zod.values);
|
|
9160
|
-
inst._zod.parse = (
|
|
9161
|
-
if (
|
|
9162
|
-
|
|
9163
|
-
return
|
|
9160
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9161
|
+
if (payload2.value === void 0) {
|
|
9162
|
+
payload2.value = def.defaultValue;
|
|
9163
|
+
return payload2;
|
|
9164
9164
|
}
|
|
9165
|
-
const result = def.innerType._zod.run(
|
|
9165
|
+
const result = def.innerType._zod.run(payload2, ctx);
|
|
9166
9166
|
if (result instanceof Promise) {
|
|
9167
9167
|
return result.then((result2) => handleDefaultResult(result2, def));
|
|
9168
9168
|
}
|
|
9169
9169
|
return handleDefaultResult(result, def);
|
|
9170
9170
|
};
|
|
9171
9171
|
});
|
|
9172
|
-
function handleDefaultResult(
|
|
9173
|
-
if (
|
|
9174
|
-
|
|
9172
|
+
function handleDefaultResult(payload2, def) {
|
|
9173
|
+
if (payload2.value === void 0) {
|
|
9174
|
+
payload2.value = def.defaultValue;
|
|
9175
9175
|
}
|
|
9176
|
-
return
|
|
9176
|
+
return payload2;
|
|
9177
9177
|
}
|
|
9178
9178
|
var $ZodPrefault = /* @__PURE__ */ $constructor("$ZodPrefault", (inst, def) => {
|
|
9179
9179
|
$ZodType.init(inst, def);
|
|
9180
9180
|
inst._zod.optin = "optional";
|
|
9181
9181
|
defineLazy(inst._zod, "values", () => def.innerType._zod.values);
|
|
9182
|
-
inst._zod.parse = (
|
|
9183
|
-
if (
|
|
9184
|
-
|
|
9182
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9183
|
+
if (payload2.value === void 0) {
|
|
9184
|
+
payload2.value = def.defaultValue;
|
|
9185
9185
|
}
|
|
9186
|
-
return def.innerType._zod.run(
|
|
9186
|
+
return def.innerType._zod.run(payload2, ctx);
|
|
9187
9187
|
};
|
|
9188
9188
|
});
|
|
9189
9189
|
var $ZodNonOptional = /* @__PURE__ */ $constructor("$ZodNonOptional", (inst, def) => {
|
|
@@ -9192,60 +9192,60 @@ var $ZodNonOptional = /* @__PURE__ */ $constructor("$ZodNonOptional", (inst, def
|
|
|
9192
9192
|
const v = def.innerType._zod.values;
|
|
9193
9193
|
return v ? new Set([...v].filter((x) => x !== void 0)) : void 0;
|
|
9194
9194
|
});
|
|
9195
|
-
inst._zod.parse = (
|
|
9196
|
-
const result = def.innerType._zod.run(
|
|
9195
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9196
|
+
const result = def.innerType._zod.run(payload2, ctx);
|
|
9197
9197
|
if (result instanceof Promise) {
|
|
9198
9198
|
return result.then((result2) => handleNonOptionalResult(result2, inst));
|
|
9199
9199
|
}
|
|
9200
9200
|
return handleNonOptionalResult(result, inst);
|
|
9201
9201
|
};
|
|
9202
9202
|
});
|
|
9203
|
-
function handleNonOptionalResult(
|
|
9204
|
-
if (!
|
|
9205
|
-
|
|
9203
|
+
function handleNonOptionalResult(payload2, inst) {
|
|
9204
|
+
if (!payload2.issues.length && payload2.value === void 0) {
|
|
9205
|
+
payload2.issues.push({
|
|
9206
9206
|
code: "invalid_type",
|
|
9207
9207
|
expected: "nonoptional",
|
|
9208
|
-
input:
|
|
9208
|
+
input: payload2.value,
|
|
9209
9209
|
inst
|
|
9210
9210
|
});
|
|
9211
9211
|
}
|
|
9212
|
-
return
|
|
9212
|
+
return payload2;
|
|
9213
9213
|
}
|
|
9214
9214
|
var $ZodCatch = /* @__PURE__ */ $constructor("$ZodCatch", (inst, def) => {
|
|
9215
9215
|
$ZodType.init(inst, def);
|
|
9216
9216
|
inst._zod.optin = "optional";
|
|
9217
9217
|
defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
|
|
9218
9218
|
defineLazy(inst._zod, "values", () => def.innerType._zod.values);
|
|
9219
|
-
inst._zod.parse = (
|
|
9220
|
-
const result = def.innerType._zod.run(
|
|
9219
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9220
|
+
const result = def.innerType._zod.run(payload2, ctx);
|
|
9221
9221
|
if (result instanceof Promise) {
|
|
9222
9222
|
return result.then((result2) => {
|
|
9223
|
-
|
|
9223
|
+
payload2.value = result2.value;
|
|
9224
9224
|
if (result2.issues.length) {
|
|
9225
|
-
|
|
9226
|
-
...
|
|
9225
|
+
payload2.value = def.catchValue({
|
|
9226
|
+
...payload2,
|
|
9227
9227
|
error: {
|
|
9228
9228
|
issues: result2.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
9229
9229
|
},
|
|
9230
|
-
input:
|
|
9230
|
+
input: payload2.value
|
|
9231
9231
|
});
|
|
9232
|
-
|
|
9232
|
+
payload2.issues = [];
|
|
9233
9233
|
}
|
|
9234
|
-
return
|
|
9234
|
+
return payload2;
|
|
9235
9235
|
});
|
|
9236
9236
|
}
|
|
9237
|
-
|
|
9237
|
+
payload2.value = result.value;
|
|
9238
9238
|
if (result.issues.length) {
|
|
9239
|
-
|
|
9240
|
-
...
|
|
9239
|
+
payload2.value = def.catchValue({
|
|
9240
|
+
...payload2,
|
|
9241
9241
|
error: {
|
|
9242
9242
|
issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
9243
9243
|
},
|
|
9244
|
-
input:
|
|
9244
|
+
input: payload2.value
|
|
9245
9245
|
});
|
|
9246
|
-
|
|
9246
|
+
payload2.issues = [];
|
|
9247
9247
|
}
|
|
9248
|
-
return
|
|
9248
|
+
return payload2;
|
|
9249
9249
|
};
|
|
9250
9250
|
});
|
|
9251
9251
|
var $ZodPipe = /* @__PURE__ */ $constructor("$ZodPipe", (inst, def) => {
|
|
@@ -9253,8 +9253,8 @@ var $ZodPipe = /* @__PURE__ */ $constructor("$ZodPipe", (inst, def) => {
|
|
|
9253
9253
|
defineLazy(inst._zod, "values", () => def.in._zod.values);
|
|
9254
9254
|
defineLazy(inst._zod, "optin", () => def.in._zod.optin);
|
|
9255
9255
|
defineLazy(inst._zod, "optout", () => def.out._zod.optout);
|
|
9256
|
-
inst._zod.parse = (
|
|
9257
|
-
const left = def.in._zod.run(
|
|
9256
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9257
|
+
const left = def.in._zod.run(payload2, ctx);
|
|
9258
9258
|
if (left instanceof Promise) {
|
|
9259
9259
|
return left.then((left2) => handlePipeResult(left2, def, ctx));
|
|
9260
9260
|
}
|
|
@@ -9273,35 +9273,35 @@ var $ZodReadonly = /* @__PURE__ */ $constructor("$ZodReadonly", (inst, def) => {
|
|
|
9273
9273
|
defineLazy(inst._zod, "values", () => def.innerType._zod.values);
|
|
9274
9274
|
defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
|
|
9275
9275
|
defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
|
|
9276
|
-
inst._zod.parse = (
|
|
9277
|
-
const result = def.innerType._zod.run(
|
|
9276
|
+
inst._zod.parse = (payload2, ctx) => {
|
|
9277
|
+
const result = def.innerType._zod.run(payload2, ctx);
|
|
9278
9278
|
if (result instanceof Promise) {
|
|
9279
9279
|
return result.then(handleReadonlyResult);
|
|
9280
9280
|
}
|
|
9281
9281
|
return handleReadonlyResult(result);
|
|
9282
9282
|
};
|
|
9283
9283
|
});
|
|
9284
|
-
function handleReadonlyResult(
|
|
9285
|
-
|
|
9286
|
-
return
|
|
9284
|
+
function handleReadonlyResult(payload2) {
|
|
9285
|
+
payload2.value = Object.freeze(payload2.value);
|
|
9286
|
+
return payload2;
|
|
9287
9287
|
}
|
|
9288
9288
|
var $ZodCustom = /* @__PURE__ */ $constructor("$ZodCustom", (inst, def) => {
|
|
9289
9289
|
$ZodCheck.init(inst, def);
|
|
9290
9290
|
$ZodType.init(inst, def);
|
|
9291
|
-
inst._zod.parse = (
|
|
9292
|
-
return
|
|
9291
|
+
inst._zod.parse = (payload2, _) => {
|
|
9292
|
+
return payload2;
|
|
9293
9293
|
};
|
|
9294
|
-
inst._zod.check = (
|
|
9295
|
-
const input =
|
|
9294
|
+
inst._zod.check = (payload2) => {
|
|
9295
|
+
const input = payload2.value;
|
|
9296
9296
|
const r = def.fn(input);
|
|
9297
9297
|
if (r instanceof Promise) {
|
|
9298
|
-
return r.then((r2) => handleRefineResult(r2,
|
|
9298
|
+
return r.then((r2) => handleRefineResult(r2, payload2, input, inst));
|
|
9299
9299
|
}
|
|
9300
|
-
handleRefineResult(r,
|
|
9300
|
+
handleRefineResult(r, payload2, input, inst);
|
|
9301
9301
|
return;
|
|
9302
9302
|
};
|
|
9303
9303
|
});
|
|
9304
|
-
function handleRefineResult(result,
|
|
9304
|
+
function handleRefineResult(result, payload2, input, inst) {
|
|
9305
9305
|
if (!result) {
|
|
9306
9306
|
const _iss = {
|
|
9307
9307
|
code: "custom",
|
|
@@ -9315,7 +9315,7 @@ function handleRefineResult(result, payload, input, inst) {
|
|
|
9315
9315
|
};
|
|
9316
9316
|
if (inst._zod.def.params)
|
|
9317
9317
|
_iss.params = inst._zod.def.params;
|
|
9318
|
-
|
|
9318
|
+
payload2.issues.push(issue(_iss));
|
|
9319
9319
|
}
|
|
9320
9320
|
}
|
|
9321
9321
|
|
|
@@ -11209,30 +11209,30 @@ function literal(value, params) {
|
|
|
11209
11209
|
var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
|
|
11210
11210
|
$ZodTransform.init(inst, def);
|
|
11211
11211
|
ZodType.init(inst, def);
|
|
11212
|
-
inst._zod.parse = (
|
|
11213
|
-
|
|
11212
|
+
inst._zod.parse = (payload2, _ctx) => {
|
|
11213
|
+
payload2.addIssue = (issue2) => {
|
|
11214
11214
|
if (typeof issue2 === "string") {
|
|
11215
|
-
|
|
11215
|
+
payload2.issues.push(util_exports.issue(issue2, payload2.value, def));
|
|
11216
11216
|
} else {
|
|
11217
11217
|
const _issue = issue2;
|
|
11218
11218
|
if (_issue.fatal)
|
|
11219
11219
|
_issue.continue = false;
|
|
11220
11220
|
_issue.code ?? (_issue.code = "custom");
|
|
11221
|
-
_issue.input ?? (_issue.input =
|
|
11221
|
+
_issue.input ?? (_issue.input = payload2.value);
|
|
11222
11222
|
_issue.inst ?? (_issue.inst = inst);
|
|
11223
11223
|
_issue.continue ?? (_issue.continue = true);
|
|
11224
|
-
|
|
11224
|
+
payload2.issues.push(util_exports.issue(_issue));
|
|
11225
11225
|
}
|
|
11226
11226
|
};
|
|
11227
|
-
const output = def.transform(
|
|
11227
|
+
const output = def.transform(payload2.value, payload2);
|
|
11228
11228
|
if (output instanceof Promise) {
|
|
11229
11229
|
return output.then((output2) => {
|
|
11230
|
-
|
|
11231
|
-
return
|
|
11230
|
+
payload2.value = output2;
|
|
11231
|
+
return payload2;
|
|
11232
11232
|
});
|
|
11233
11233
|
}
|
|
11234
|
-
|
|
11235
|
-
return
|
|
11234
|
+
payload2.value = output;
|
|
11235
|
+
return payload2;
|
|
11236
11236
|
};
|
|
11237
11237
|
});
|
|
11238
11238
|
function transform(fn) {
|
|
@@ -11360,22 +11360,22 @@ function refine(fn, _params = {}) {
|
|
|
11360
11360
|
return _refine(ZodCustom, fn, _params);
|
|
11361
11361
|
}
|
|
11362
11362
|
function superRefine(fn) {
|
|
11363
|
-
const ch = check((
|
|
11364
|
-
|
|
11363
|
+
const ch = check((payload2) => {
|
|
11364
|
+
payload2.addIssue = (issue2) => {
|
|
11365
11365
|
if (typeof issue2 === "string") {
|
|
11366
|
-
|
|
11366
|
+
payload2.issues.push(util_exports.issue(issue2, payload2.value, ch._zod.def));
|
|
11367
11367
|
} else {
|
|
11368
11368
|
const _issue = issue2;
|
|
11369
11369
|
if (_issue.fatal)
|
|
11370
11370
|
_issue.continue = false;
|
|
11371
11371
|
_issue.code ?? (_issue.code = "custom");
|
|
11372
|
-
_issue.input ?? (_issue.input =
|
|
11372
|
+
_issue.input ?? (_issue.input = payload2.value);
|
|
11373
11373
|
_issue.inst ?? (_issue.inst = ch);
|
|
11374
11374
|
_issue.continue ?? (_issue.continue = !ch._zod.def.abort);
|
|
11375
|
-
|
|
11375
|
+
payload2.issues.push(util_exports.issue(_issue));
|
|
11376
11376
|
}
|
|
11377
11377
|
};
|
|
11378
|
-
return fn(
|
|
11378
|
+
return fn(payload2.value, payload2);
|
|
11379
11379
|
});
|
|
11380
11380
|
return ch;
|
|
11381
11381
|
}
|
|
@@ -21156,14 +21156,24 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
21156
21156
|
var ApiError = class extends Error {
|
|
21157
21157
|
httpStatus;
|
|
21158
21158
|
body;
|
|
21159
|
-
constructor(httpStatus, message,
|
|
21159
|
+
constructor(httpStatus, message, body2) {
|
|
21160
21160
|
super(message);
|
|
21161
21161
|
this.name = "ApiError";
|
|
21162
21162
|
this.httpStatus = httpStatus;
|
|
21163
|
-
this.body =
|
|
21163
|
+
this.body = body2;
|
|
21164
|
+
}
|
|
21165
|
+
};
|
|
21166
|
+
var LoginExpiredError = class extends ApiError {
|
|
21167
|
+
constructor() {
|
|
21168
|
+
super(
|
|
21169
|
+
401,
|
|
21170
|
+
"O acesso pelo navegador expirou e n\xE3o deu para renovar sozinho. Rode `beplus-mcp login` de novo e autorize; n\xE3o precisa reiniciar o agente, a pr\xF3xima chamada j\xE1 usa o login novo."
|
|
21171
|
+
);
|
|
21172
|
+
this.name = "LoginExpiredError";
|
|
21164
21173
|
}
|
|
21165
21174
|
};
|
|
21166
21175
|
function apiErrorToUserMessage(err) {
|
|
21176
|
+
if (err instanceof LoginExpiredError) return err.message;
|
|
21167
21177
|
if (err instanceof ApiError) {
|
|
21168
21178
|
const detail = err.message || "";
|
|
21169
21179
|
switch (err.httpStatus) {
|
|
@@ -21195,6 +21205,333 @@ function apiErrorToUserMessage(err) {
|
|
|
21195
21205
|
return String(err);
|
|
21196
21206
|
}
|
|
21197
21207
|
|
|
21208
|
+
// src/credentials.ts
|
|
21209
|
+
import { chmod, mkdir, open, readFile, rename, stat, unlink, writeFile } from "fs/promises";
|
|
21210
|
+
import { homedir } from "os";
|
|
21211
|
+
import { dirname, join } from "path";
|
|
21212
|
+
function credentialsPath() {
|
|
21213
|
+
const base = process.env.XDG_CONFIG_HOME?.trim() || join(homedir(), ".config");
|
|
21214
|
+
return join(base, "beplus-mcp", "credentials.json");
|
|
21215
|
+
}
|
|
21216
|
+
async function readCredentials() {
|
|
21217
|
+
try {
|
|
21218
|
+
const raw = await readFile(credentialsPath(), "utf8");
|
|
21219
|
+
const parsed = JSON.parse(raw);
|
|
21220
|
+
if (!parsed.accessToken || !parsed.apiUrl) return null;
|
|
21221
|
+
return parsed;
|
|
21222
|
+
} catch {
|
|
21223
|
+
return null;
|
|
21224
|
+
}
|
|
21225
|
+
}
|
|
21226
|
+
async function writeCredentials(creds) {
|
|
21227
|
+
const path = credentialsPath();
|
|
21228
|
+
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
21229
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
21230
|
+
await writeFile(tmp, `${JSON.stringify(creds, null, 2)}
|
|
21231
|
+
`, { mode: 384 });
|
|
21232
|
+
await chmod(tmp, 384);
|
|
21233
|
+
await rename(tmp, path);
|
|
21234
|
+
return path;
|
|
21235
|
+
}
|
|
21236
|
+
async function clearCredentials() {
|
|
21237
|
+
try {
|
|
21238
|
+
await unlink(credentialsPath());
|
|
21239
|
+
return true;
|
|
21240
|
+
} catch {
|
|
21241
|
+
return false;
|
|
21242
|
+
}
|
|
21243
|
+
}
|
|
21244
|
+
var RENEW_MARGIN_MS = 6e4;
|
|
21245
|
+
function isExpired(creds) {
|
|
21246
|
+
return typeof creds.expiresAt === "number" && creds.expiresAt - RENEW_MARGIN_MS <= Date.now();
|
|
21247
|
+
}
|
|
21248
|
+
var credentialsLock = {
|
|
21249
|
+
staleMs: 3e4,
|
|
21250
|
+
waitMs: 35e3,
|
|
21251
|
+
pollMs: 100
|
|
21252
|
+
};
|
|
21253
|
+
async function withCredentialsLock(fn) {
|
|
21254
|
+
const path = credentialsPath();
|
|
21255
|
+
const lock = `${path}.lock`;
|
|
21256
|
+
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
21257
|
+
const started = Date.now();
|
|
21258
|
+
for (; ; ) {
|
|
21259
|
+
try {
|
|
21260
|
+
const fh = await open(lock, "wx", 384);
|
|
21261
|
+
await fh.writeFile(String(process.pid));
|
|
21262
|
+
await fh.close();
|
|
21263
|
+
break;
|
|
21264
|
+
} catch (e) {
|
|
21265
|
+
if (e.code !== "EEXIST") throw e;
|
|
21266
|
+
try {
|
|
21267
|
+
const age = Date.now() - (await stat(lock)).mtimeMs;
|
|
21268
|
+
if (age > credentialsLock.staleMs) {
|
|
21269
|
+
await unlink(lock).catch(() => {
|
|
21270
|
+
});
|
|
21271
|
+
continue;
|
|
21272
|
+
}
|
|
21273
|
+
} catch {
|
|
21274
|
+
continue;
|
|
21275
|
+
}
|
|
21276
|
+
if (Date.now() - started > credentialsLock.waitMs) {
|
|
21277
|
+
throw new Error("Outro processo do beplus-mcp est\xE1 renovando o login h\xE1 tempo demais. Tente de novo em instantes.");
|
|
21278
|
+
}
|
|
21279
|
+
await new Promise((r) => setTimeout(r, credentialsLock.pollMs));
|
|
21280
|
+
}
|
|
21281
|
+
}
|
|
21282
|
+
try {
|
|
21283
|
+
return await fn();
|
|
21284
|
+
} finally {
|
|
21285
|
+
await unlink(lock).catch(() => {
|
|
21286
|
+
});
|
|
21287
|
+
}
|
|
21288
|
+
}
|
|
21289
|
+
|
|
21290
|
+
// src/oauth.ts
|
|
21291
|
+
import crypto from "crypto";
|
|
21292
|
+
import { createServer } from "http";
|
|
21293
|
+
import { spawn } from "child_process";
|
|
21294
|
+
var CALLBACK_TIMEOUT_MS = 5 * 6e4;
|
|
21295
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
21296
|
+
async function json(url, init) {
|
|
21297
|
+
let res;
|
|
21298
|
+
try {
|
|
21299
|
+
res = await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
|
|
21300
|
+
} catch {
|
|
21301
|
+
throw new Error(`Nao consegui falar com ${new URL(url).origin}. Confira a rede e o BEPLUS_API_URL.`);
|
|
21302
|
+
}
|
|
21303
|
+
const text = await res.text();
|
|
21304
|
+
let body2;
|
|
21305
|
+
try {
|
|
21306
|
+
body2 = text ? JSON.parse(text) : void 0;
|
|
21307
|
+
} catch {
|
|
21308
|
+
}
|
|
21309
|
+
if (!res.ok) {
|
|
21310
|
+
const msg = body2?.message ?? body2?.error_description ?? body2?.error ?? `HTTP ${res.status}`;
|
|
21311
|
+
throw new Error(`${msg} (${url})`);
|
|
21312
|
+
}
|
|
21313
|
+
return body2;
|
|
21314
|
+
}
|
|
21315
|
+
async function discover(apiUrl2) {
|
|
21316
|
+
const meta = await json(`${apiUrl2}/.well-known/oauth-authorization-server`);
|
|
21317
|
+
if (!meta.authorization_endpoint || !meta.token_endpoint || !meta.registration_endpoint) {
|
|
21318
|
+
throw new Error("O servidor respondeu a descoberta sem os endpoints obrigatorios.");
|
|
21319
|
+
}
|
|
21320
|
+
return meta;
|
|
21321
|
+
}
|
|
21322
|
+
function pkce() {
|
|
21323
|
+
const verifier = crypto.randomBytes(32).toString("base64url");
|
|
21324
|
+
return { verifier, challenge: crypto.createHash("sha256").update(verifier).digest("base64url") };
|
|
21325
|
+
}
|
|
21326
|
+
function openBrowser(url) {
|
|
21327
|
+
try {
|
|
21328
|
+
if (process.platform === "win32") {
|
|
21329
|
+
spawn("cmd.exe", ["/c", "start", '""', "/b", url.replace(/&/g, "^&")], {
|
|
21330
|
+
stdio: "ignore",
|
|
21331
|
+
detached: true,
|
|
21332
|
+
windowsVerbatimArguments: true
|
|
21333
|
+
}).unref();
|
|
21334
|
+
return;
|
|
21335
|
+
}
|
|
21336
|
+
const cmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
21337
|
+
spawn(cmd, [url], { stdio: "ignore", detached: true }).unref();
|
|
21338
|
+
} catch {
|
|
21339
|
+
}
|
|
21340
|
+
}
|
|
21341
|
+
var PAGINA_OK = `<!doctype html><meta charset="utf-8"><title>Pronto</title>
|
|
21342
|
+
<body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
|
|
21343
|
+
<div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Tudo certo</h1>
|
|
21344
|
+
<p style="margin:0;opacity:.7">Pode fechar esta aba e voltar para o seu agente.</p></div>`;
|
|
21345
|
+
var PAGINA_ERRO = `<!doctype html><meta charset="utf-8"><title>Nao deu</title>
|
|
21346
|
+
<body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
|
|
21347
|
+
<div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Nao foi dessa vez</h1>
|
|
21348
|
+
<p style="margin:0;opacity:.7">Volte ao terminal para ver o motivo.</p></div>`;
|
|
21349
|
+
function listenForCallback(expectedState) {
|
|
21350
|
+
return new Promise((resolvePort, rejectPort) => {
|
|
21351
|
+
let settle;
|
|
21352
|
+
let fail;
|
|
21353
|
+
const code = new Promise((res, rej) => {
|
|
21354
|
+
settle = res;
|
|
21355
|
+
fail = rej;
|
|
21356
|
+
});
|
|
21357
|
+
const server = createServer((req, res) => {
|
|
21358
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
21359
|
+
if (url.pathname !== "/callback") {
|
|
21360
|
+
res.writeHead(404).end();
|
|
21361
|
+
return;
|
|
21362
|
+
}
|
|
21363
|
+
const erro = url.searchParams.get("error");
|
|
21364
|
+
const recebido = url.searchParams.get("code");
|
|
21365
|
+
const state = url.searchParams.get("state") ?? "";
|
|
21366
|
+
const ok = !erro && recebido && state === expectedState;
|
|
21367
|
+
res.writeHead(ok ? 200 : 400, { "content-type": "text/html; charset=utf-8" });
|
|
21368
|
+
res.end(ok ? PAGINA_OK : PAGINA_ERRO);
|
|
21369
|
+
server.close();
|
|
21370
|
+
if (erro) return fail(new Error(url.searchParams.get("error_description") || erro));
|
|
21371
|
+
if (!recebido || state !== expectedState) return fail(new Error("Resposta de autorizacao invalida."));
|
|
21372
|
+
settle({ code: recebido, state });
|
|
21373
|
+
});
|
|
21374
|
+
server.on("error", rejectPort);
|
|
21375
|
+
server.listen(0, "127.0.0.1", () => {
|
|
21376
|
+
const addr = server.address();
|
|
21377
|
+
if (!addr || typeof addr === "string") return rejectPort(new Error("Nao consegui abrir a porta local."));
|
|
21378
|
+
const timer = setTimeout(() => {
|
|
21379
|
+
server.close();
|
|
21380
|
+
fail(new Error("Tempo esgotado esperando a autorizacao no navegador."));
|
|
21381
|
+
}, CALLBACK_TIMEOUT_MS);
|
|
21382
|
+
void code.finally(() => clearTimeout(timer));
|
|
21383
|
+
resolvePort({ port: addr.port, code });
|
|
21384
|
+
});
|
|
21385
|
+
});
|
|
21386
|
+
}
|
|
21387
|
+
function toStored(t, apiUrl2, clientId) {
|
|
21388
|
+
return {
|
|
21389
|
+
accessToken: t.access_token,
|
|
21390
|
+
refreshToken: t.refresh_token,
|
|
21391
|
+
expiresAt: t.expires_in ? Date.now() + t.expires_in * 1e3 : void 0,
|
|
21392
|
+
apiUrl: apiUrl2,
|
|
21393
|
+
clientId
|
|
21394
|
+
};
|
|
21395
|
+
}
|
|
21396
|
+
async function login(apiUrl2, onUrl) {
|
|
21397
|
+
const meta = await discover(apiUrl2);
|
|
21398
|
+
const state = crypto.randomBytes(24).toString("base64url");
|
|
21399
|
+
const { verifier, challenge } = pkce();
|
|
21400
|
+
const { port, code } = await listenForCallback(state);
|
|
21401
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
21402
|
+
const client = await json(meta.registration_endpoint, {
|
|
21403
|
+
method: "POST",
|
|
21404
|
+
headers: { "content-type": "application/json" },
|
|
21405
|
+
body: JSON.stringify({
|
|
21406
|
+
client_name: "beplus-mcp (CLI)",
|
|
21407
|
+
redirect_uris: [redirectUri],
|
|
21408
|
+
token_endpoint_auth_method: "none",
|
|
21409
|
+
grant_types: ["authorization_code", "refresh_token"]
|
|
21410
|
+
})
|
|
21411
|
+
});
|
|
21412
|
+
const authorizeUrl = new URL(meta.authorization_endpoint);
|
|
21413
|
+
authorizeUrl.searchParams.set("response_type", "code");
|
|
21414
|
+
authorizeUrl.searchParams.set("client_id", client.client_id);
|
|
21415
|
+
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
|
|
21416
|
+
authorizeUrl.searchParams.set("code_challenge", challenge);
|
|
21417
|
+
authorizeUrl.searchParams.set("code_challenge_method", "S256");
|
|
21418
|
+
authorizeUrl.searchParams.set("state", state);
|
|
21419
|
+
onUrl(authorizeUrl.toString());
|
|
21420
|
+
openBrowser(authorizeUrl.toString());
|
|
21421
|
+
const { code: authCode } = await code;
|
|
21422
|
+
const token = await json(meta.token_endpoint, {
|
|
21423
|
+
method: "POST",
|
|
21424
|
+
headers: { "content-type": "application/json" },
|
|
21425
|
+
body: JSON.stringify({
|
|
21426
|
+
grant_type: "authorization_code",
|
|
21427
|
+
code: authCode,
|
|
21428
|
+
code_verifier: verifier,
|
|
21429
|
+
client_id: client.client_id,
|
|
21430
|
+
redirect_uri: redirectUri
|
|
21431
|
+
})
|
|
21432
|
+
});
|
|
21433
|
+
const path = await writeCredentials(toStored(token, apiUrl2, client.client_id));
|
|
21434
|
+
return { path, authorizeUrl: authorizeUrl.toString() };
|
|
21435
|
+
}
|
|
21436
|
+
var sameApi = (a, b) => a.replace(/\/+$/, "") === b.replace(/\/+$/, "");
|
|
21437
|
+
async function refreshGrant(apiUrl2, creds) {
|
|
21438
|
+
const meta = await discover(apiUrl2);
|
|
21439
|
+
const token = await json(meta.token_endpoint, {
|
|
21440
|
+
method: "POST",
|
|
21441
|
+
headers: { "content-type": "application/json" },
|
|
21442
|
+
body: JSON.stringify({
|
|
21443
|
+
grant_type: "refresh_token",
|
|
21444
|
+
refresh_token: creds.refreshToken,
|
|
21445
|
+
client_id: creds.clientId
|
|
21446
|
+
})
|
|
21447
|
+
});
|
|
21448
|
+
return toStored(token, apiUrl2, creds.clientId);
|
|
21449
|
+
}
|
|
21450
|
+
async function renewFromDisk(apiUrl2, rejected) {
|
|
21451
|
+
try {
|
|
21452
|
+
return await withCredentialsLock(async () => {
|
|
21453
|
+
const creds = await readCredentials();
|
|
21454
|
+
if (!creds || !sameApi(creds.apiUrl, apiUrl2)) return null;
|
|
21455
|
+
if (creds.accessToken !== rejected && !isExpired(creds)) return creds.accessToken;
|
|
21456
|
+
if (!creds.refreshToken) return null;
|
|
21457
|
+
const fresh = await refreshGrant(apiUrl2, creds);
|
|
21458
|
+
await writeCredentials(fresh);
|
|
21459
|
+
return fresh.accessToken;
|
|
21460
|
+
});
|
|
21461
|
+
} catch {
|
|
21462
|
+
return null;
|
|
21463
|
+
}
|
|
21464
|
+
}
|
|
21465
|
+
async function tokenFromDisk(apiUrl2) {
|
|
21466
|
+
const creds = await readCredentials();
|
|
21467
|
+
if (!creds || !sameApi(creds.apiUrl, apiUrl2)) return null;
|
|
21468
|
+
if (!isExpired(creds)) return creds.accessToken;
|
|
21469
|
+
if (!creds.refreshToken) return null;
|
|
21470
|
+
return renewFromDisk(apiUrl2, creds.accessToken);
|
|
21471
|
+
}
|
|
21472
|
+
|
|
21473
|
+
// src/auth.ts
|
|
21474
|
+
function staticToken(token) {
|
|
21475
|
+
return { renewable: false, current: async () => token, refresh: async () => null };
|
|
21476
|
+
}
|
|
21477
|
+
var LoginToken = class {
|
|
21478
|
+
constructor(apiUrl2, last) {
|
|
21479
|
+
this.apiUrl = apiUrl2;
|
|
21480
|
+
this.last = last;
|
|
21481
|
+
}
|
|
21482
|
+
apiUrl;
|
|
21483
|
+
last;
|
|
21484
|
+
renewable = true;
|
|
21485
|
+
/** Token cuja renovação antecipada acabou de falhar: o 401 dele não tenta de novo. */
|
|
21486
|
+
failedFor = null;
|
|
21487
|
+
async current() {
|
|
21488
|
+
const creds = await readCredentials();
|
|
21489
|
+
if (!creds || creds.apiUrl.replace(/\/+$/, "") !== this.apiUrl.replace(/\/+$/, "")) return this.last;
|
|
21490
|
+
if (isExpired(creds) && creds.refreshToken) {
|
|
21491
|
+
const fresh = await renewFromDisk(this.apiUrl, creds.accessToken);
|
|
21492
|
+
if (fresh) return this.last = fresh;
|
|
21493
|
+
this.failedFor = creds.accessToken;
|
|
21494
|
+
}
|
|
21495
|
+
return this.last = creds.accessToken;
|
|
21496
|
+
}
|
|
21497
|
+
async refresh(rejected) {
|
|
21498
|
+
if (rejected === this.failedFor) return null;
|
|
21499
|
+
const fresh = await renewFromDisk(this.apiUrl, rejected);
|
|
21500
|
+
if (fresh) this.last = fresh;
|
|
21501
|
+
return fresh;
|
|
21502
|
+
}
|
|
21503
|
+
};
|
|
21504
|
+
function tokenProvider(cfg) {
|
|
21505
|
+
return cfg.auth ?? staticToken(cfg.token);
|
|
21506
|
+
}
|
|
21507
|
+
async function fetchWithAuth(cfg, url, init, what) {
|
|
21508
|
+
const auth = tokenProvider(cfg);
|
|
21509
|
+
const send = async (token2) => {
|
|
21510
|
+
const { timeoutMs, headers, ...rest } = init;
|
|
21511
|
+
try {
|
|
21512
|
+
return await fetch(url, {
|
|
21513
|
+
...rest,
|
|
21514
|
+
headers: { ...headers, Authorization: `Bearer ${token2}` },
|
|
21515
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
21516
|
+
});
|
|
21517
|
+
} catch (e) {
|
|
21518
|
+
const name = e?.name;
|
|
21519
|
+
if (name === "TimeoutError" || name === "AbortError") {
|
|
21520
|
+
throw new ApiError(408, `Tempo esgotado ao falar com a API BePlus (${what}).`);
|
|
21521
|
+
}
|
|
21522
|
+
throw new ApiError(0, `Falha de rede ao falar com a API BePlus (${what}). Confira BEPLUS_API_URL.`);
|
|
21523
|
+
}
|
|
21524
|
+
};
|
|
21525
|
+
const token = await auth.current();
|
|
21526
|
+
const res = await send(token);
|
|
21527
|
+
if (res.status !== 401 || !auth.renewable) return res;
|
|
21528
|
+
await res.body?.cancel().catch(() => {
|
|
21529
|
+
});
|
|
21530
|
+
const fresh = await auth.refresh(token);
|
|
21531
|
+
if (!fresh) throw new LoginExpiredError();
|
|
21532
|
+
return send(fresh);
|
|
21533
|
+
}
|
|
21534
|
+
|
|
21198
21535
|
// src/api/client.ts
|
|
21199
21536
|
var BeplusClient = class {
|
|
21200
21537
|
constructor(cfg) {
|
|
@@ -21209,28 +21546,23 @@ var BeplusClient = class {
|
|
|
21209
21546
|
if (v !== void 0 && v !== null && v !== "") url.searchParams.set(k, String(v));
|
|
21210
21547
|
}
|
|
21211
21548
|
}
|
|
21212
|
-
const
|
|
21213
|
-
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
res = await fetch(url, {
|
|
21549
|
+
const res = await fetchWithAuth(
|
|
21550
|
+
this.cfg,
|
|
21551
|
+
url,
|
|
21552
|
+
{
|
|
21217
21553
|
method,
|
|
21218
|
-
headers: {
|
|
21219
|
-
Authorization: `Bearer ${this.cfg.token}`,
|
|
21220
|
-
...opts.body ? { "Content-Type": "application/json" } : {}
|
|
21221
|
-
},
|
|
21554
|
+
headers: opts.body ? { "Content-Type": "application/json" } : {},
|
|
21222
21555
|
body: opts.body ? JSON.stringify(opts.body) : void 0,
|
|
21223
|
-
|
|
21224
|
-
}
|
|
21225
|
-
|
|
21226
|
-
|
|
21227
|
-
|
|
21228
|
-
|
|
21229
|
-
|
|
21230
|
-
}
|
|
21231
|
-
|
|
21556
|
+
timeoutMs: opts.timeoutMs ?? 3e4
|
|
21557
|
+
},
|
|
21558
|
+
path
|
|
21559
|
+
);
|
|
21560
|
+
let text;
|
|
21561
|
+
try {
|
|
21562
|
+
text = await res.text();
|
|
21563
|
+
} catch {
|
|
21564
|
+
throw new ApiError(408, `Tempo esgotado ao falar com a API BePlus (${path}).`);
|
|
21232
21565
|
}
|
|
21233
|
-
const text = await res.text();
|
|
21234
21566
|
let json2;
|
|
21235
21567
|
if (text) {
|
|
21236
21568
|
try {
|
|
@@ -21244,14 +21576,14 @@ var BeplusClient = class {
|
|
|
21244
21576
|
}
|
|
21245
21577
|
return json2 && typeof json2 === "object" && "result" in json2 ? json2.result : json2;
|
|
21246
21578
|
}
|
|
21247
|
-
startGeneration(
|
|
21248
|
-
return this.request("POST", "/generations", { body });
|
|
21579
|
+
startGeneration(body2) {
|
|
21580
|
+
return this.request("POST", "/generations", { body: body2 });
|
|
21249
21581
|
}
|
|
21250
21582
|
listProjects() {
|
|
21251
21583
|
return this.request("GET", "/projects");
|
|
21252
21584
|
}
|
|
21253
|
-
createProject(
|
|
21254
|
-
return this.request("POST", "/projects", { body });
|
|
21585
|
+
createProject(body2) {
|
|
21586
|
+
return this.request("POST", "/projects", { body: body2 });
|
|
21255
21587
|
}
|
|
21256
21588
|
getActiveProject() {
|
|
21257
21589
|
return this.request("GET", "/projects/active");
|
|
@@ -21263,8 +21595,8 @@ var BeplusClient = class {
|
|
|
21263
21595
|
listClients() {
|
|
21264
21596
|
return this.request("GET", "/clients");
|
|
21265
21597
|
}
|
|
21266
|
-
createClient(
|
|
21267
|
-
return this.request("POST", "/clients", { body });
|
|
21598
|
+
createClient(body2) {
|
|
21599
|
+
return this.request("POST", "/clients", { body: body2 });
|
|
21268
21600
|
}
|
|
21269
21601
|
setActiveClient(client) {
|
|
21270
21602
|
return this.request("PUT", "/clients/active", { body: { client } });
|
|
@@ -21286,8 +21618,8 @@ var BeplusClient = class {
|
|
|
21286
21618
|
}
|
|
21287
21619
|
});
|
|
21288
21620
|
}
|
|
21289
|
-
tts(
|
|
21290
|
-
return this.request("POST", "/tts", { body, timeoutMs: 9e4 });
|
|
21621
|
+
tts(body2) {
|
|
21622
|
+
return this.request("POST", "/tts", { body: body2, timeoutMs: 9e4 });
|
|
21291
21623
|
}
|
|
21292
21624
|
models() {
|
|
21293
21625
|
return this.request("GET", "/models");
|
|
@@ -21302,11 +21634,11 @@ var BeplusClient = class {
|
|
|
21302
21634
|
me(billing) {
|
|
21303
21635
|
return this.request("GET", "/me", { query: { billing } });
|
|
21304
21636
|
}
|
|
21305
|
-
readProvenance(
|
|
21306
|
-
return this.request("POST", "/read-provenance", { body, timeoutMs: 3e4 });
|
|
21637
|
+
readProvenance(body2) {
|
|
21638
|
+
return this.request("POST", "/read-provenance", { body: body2, timeoutMs: 3e4 });
|
|
21307
21639
|
}
|
|
21308
|
-
analyzeMedia(
|
|
21309
|
-
return this.request("POST", "/analyze-media", { body, timeoutMs: 3e5 });
|
|
21640
|
+
analyzeMedia(body2) {
|
|
21641
|
+
return this.request("POST", "/analyze-media", { body: body2, timeoutMs: 3e5 });
|
|
21310
21642
|
}
|
|
21311
21643
|
searchCalls(query) {
|
|
21312
21644
|
return this.request("GET", "/calls", {
|
|
@@ -21386,9 +21718,9 @@ async function pollUntilDone(client, generationId, budgetMs, jitterSeed = 0) {
|
|
|
21386
21718
|
}
|
|
21387
21719
|
|
|
21388
21720
|
// src/media.ts
|
|
21389
|
-
import { readFile } from "fs/promises";
|
|
21721
|
+
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
21390
21722
|
import { basename, extname, isAbsolute, resolve } from "path";
|
|
21391
|
-
import { homedir } from "os";
|
|
21723
|
+
import { homedir as homedir2 } from "os";
|
|
21392
21724
|
import { fileURLToPath } from "url";
|
|
21393
21725
|
var MIME_BY_EXT = {
|
|
21394
21726
|
".png": "image/png",
|
|
@@ -21396,82 +21728,207 @@ var MIME_BY_EXT = {
|
|
|
21396
21728
|
".jpeg": "image/jpeg",
|
|
21397
21729
|
".webp": "image/webp",
|
|
21398
21730
|
".gif": "image/gif",
|
|
21731
|
+
".avif": "image/avif",
|
|
21732
|
+
".heic": "image/heic",
|
|
21733
|
+
".heif": "image/heif",
|
|
21399
21734
|
".bmp": "image/bmp",
|
|
21735
|
+
".tif": "image/tiff",
|
|
21736
|
+
".tiff": "image/tiff",
|
|
21400
21737
|
".svg": "image/svg+xml",
|
|
21401
21738
|
".mp4": "video/mp4",
|
|
21402
21739
|
".mov": "video/quicktime",
|
|
21403
21740
|
".webm": "video/webm",
|
|
21404
21741
|
".m4v": "video/x-m4v",
|
|
21742
|
+
".mkv": "video/x-matroska",
|
|
21743
|
+
".mpeg": "video/mpeg",
|
|
21744
|
+
".mpg": "video/mpeg",
|
|
21745
|
+
".avi": "video/x-msvideo",
|
|
21746
|
+
".3gp": "video/3gpp",
|
|
21405
21747
|
".mp3": "audio/mpeg",
|
|
21406
21748
|
".wav": "audio/wav",
|
|
21407
21749
|
".m4a": "audio/mp4",
|
|
21408
21750
|
".aac": "audio/aac",
|
|
21409
21751
|
".ogg": "audio/ogg",
|
|
21752
|
+
".oga": "audio/ogg",
|
|
21753
|
+
".opus": "audio/opus",
|
|
21410
21754
|
".flac": "audio/flac",
|
|
21411
|
-
".
|
|
21755
|
+
".aiff": "audio/aiff",
|
|
21756
|
+
".aif": "audio/aiff",
|
|
21757
|
+
".pdf": "application/pdf",
|
|
21758
|
+
".md": "text/markdown",
|
|
21759
|
+
".txt": "text/plain"
|
|
21412
21760
|
};
|
|
21413
|
-
var
|
|
21761
|
+
var UPLOAD_EXTENSIONS = [
|
|
21762
|
+
"jpg",
|
|
21763
|
+
"jpeg",
|
|
21764
|
+
"png",
|
|
21765
|
+
"gif",
|
|
21766
|
+
"webp",
|
|
21767
|
+
"avif",
|
|
21768
|
+
"heic",
|
|
21769
|
+
"heif",
|
|
21770
|
+
"bmp",
|
|
21771
|
+
"tif",
|
|
21772
|
+
"tiff",
|
|
21773
|
+
"mp4",
|
|
21774
|
+
"webm",
|
|
21775
|
+
"mov",
|
|
21776
|
+
"m4v",
|
|
21777
|
+
"mkv",
|
|
21778
|
+
"mpeg",
|
|
21779
|
+
"mpg",
|
|
21780
|
+
"avi",
|
|
21781
|
+
"flv",
|
|
21782
|
+
"wmv",
|
|
21783
|
+
"3gp",
|
|
21784
|
+
"3gpp",
|
|
21785
|
+
"mp3",
|
|
21786
|
+
"wav",
|
|
21787
|
+
"ogg",
|
|
21788
|
+
"oga",
|
|
21789
|
+
"aac",
|
|
21790
|
+
"flac",
|
|
21791
|
+
"m4a",
|
|
21792
|
+
"opus",
|
|
21793
|
+
"wma",
|
|
21794
|
+
"aiff",
|
|
21795
|
+
"aif",
|
|
21796
|
+
"pdf",
|
|
21797
|
+
"md",
|
|
21798
|
+
"txt",
|
|
21799
|
+
"markdown"
|
|
21800
|
+
];
|
|
21801
|
+
var MAX_UPLOAD_BYTES = 95 * 1024 * 1024;
|
|
21414
21802
|
var UPLOAD_TIMEOUT_MS = 12e4;
|
|
21803
|
+
var DOWNLOAD_TIMEOUT_MS = 12e4;
|
|
21804
|
+
var BEPLUS_STORAGE_HOST = "storage.beplus.academy";
|
|
21415
21805
|
function isRemoteRef(ref) {
|
|
21416
21806
|
return /^https?:\/\//i.test(ref);
|
|
21417
21807
|
}
|
|
21418
21808
|
function toLocalPath(ref) {
|
|
21419
21809
|
if (ref.startsWith("file://")) return fileURLToPath(ref);
|
|
21420
|
-
if (ref === "~") return
|
|
21421
|
-
if (ref.startsWith("~/")) return resolve(
|
|
21810
|
+
if (ref === "~") return homedir2();
|
|
21811
|
+
if (ref.startsWith("~/")) return resolve(homedir2(), ref.slice(2));
|
|
21422
21812
|
return isAbsolute(ref) ? ref : resolve(process.cwd(), ref);
|
|
21423
21813
|
}
|
|
21424
|
-
function
|
|
21425
|
-
return MIME_BY_EXT[extname(
|
|
21814
|
+
function mimeForName(name) {
|
|
21815
|
+
return MIME_BY_EXT[extname(name).toLowerCase()] ?? "application/octet-stream";
|
|
21426
21816
|
}
|
|
21427
|
-
|
|
21817
|
+
var extOf = (name) => extname(name).slice(1).toLowerCase();
|
|
21818
|
+
function mb(bytes) {
|
|
21819
|
+
return (bytes / 1024 / 1024).toFixed(1).replace(".", ",");
|
|
21820
|
+
}
|
|
21821
|
+
function tooLarge(name, bytes) {
|
|
21822
|
+
const size = bytes === null ? "passa" : `tem ${mb(bytes)} MB,`;
|
|
21823
|
+
return new ApiError(
|
|
21824
|
+
413,
|
|
21825
|
+
`"${name}" ${size} acima do teto de 95 MB para subir pela API (o proxy da Cloudflare corta corpo acima de 100 MB antes de chegar no servidor). Comprima ou corte o arquivo (ex.: ffmpeg -i entrada.mp4 -crf 26 saida.mp4) e tente de novo.`
|
|
21826
|
+
);
|
|
21827
|
+
}
|
|
21828
|
+
async function loadLocal(ref) {
|
|
21428
21829
|
const abs = toLocalPath(ref);
|
|
21429
|
-
|
|
21830
|
+
const name = basename(abs);
|
|
21831
|
+
let size;
|
|
21430
21832
|
try {
|
|
21431
|
-
|
|
21833
|
+
size = (await stat2(abs)).size;
|
|
21432
21834
|
} catch {
|
|
21433
21835
|
throw new ApiError(
|
|
21434
21836
|
0,
|
|
21435
21837
|
`Arquivo local n\xE3o encontrado: "${ref}". Passe um caminho v\xE1lido ou uma URL p\xFAblica (http/https).`
|
|
21436
21838
|
);
|
|
21437
21839
|
}
|
|
21438
|
-
|
|
21439
|
-
|
|
21440
|
-
|
|
21441
|
-
|
|
21442
|
-
|
|
21443
|
-
|
|
21444
|
-
}
|
|
21445
|
-
const form = new FormData();
|
|
21446
|
-
form.append("file", new Blob([buf], { type: mimeForPath(abs) }), name);
|
|
21447
|
-
const controller = new AbortController();
|
|
21448
|
-
const timer = setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS);
|
|
21840
|
+
if (size > MAX_UPLOAD_BYTES) throw tooLarge(name, size);
|
|
21841
|
+
return { buf: await readFile2(abs), name, mime: mimeForName(abs), localPath: abs };
|
|
21842
|
+
}
|
|
21843
|
+
async function loadRemote(url) {
|
|
21844
|
+
const u = new URL(url);
|
|
21845
|
+
let name = decodeURIComponent(basename(u.pathname)) || "arquivo";
|
|
21449
21846
|
let res;
|
|
21450
21847
|
try {
|
|
21451
|
-
res = await fetch(
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
|
|
21455
|
-
|
|
21848
|
+
res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
|
|
21849
|
+
} catch {
|
|
21850
|
+
throw new ApiError(0, `N\xE3o consegui baixar ${url} (rede ou tempo esgotado).`);
|
|
21851
|
+
}
|
|
21852
|
+
if (!res.ok) {
|
|
21853
|
+
await res.body?.cancel().catch(() => {
|
|
21854
|
+
});
|
|
21855
|
+
throw new ApiError(res.status, `N\xE3o consegui baixar ${url}: a origem respondeu HTTP ${res.status}.`);
|
|
21856
|
+
}
|
|
21857
|
+
const declared = Number(res.headers.get("content-length") ?? NaN);
|
|
21858
|
+
if (Number.isFinite(declared) && declared > MAX_UPLOAD_BYTES) {
|
|
21859
|
+
await res.body?.cancel().catch(() => {
|
|
21456
21860
|
});
|
|
21861
|
+
throw tooLarge(name, declared);
|
|
21862
|
+
}
|
|
21863
|
+
const chunks = [];
|
|
21864
|
+
let total = 0;
|
|
21865
|
+
try {
|
|
21866
|
+
const reader = res.body?.getReader();
|
|
21867
|
+
if (reader) {
|
|
21868
|
+
for (; ; ) {
|
|
21869
|
+
const { done, value } = await reader.read();
|
|
21870
|
+
if (done) break;
|
|
21871
|
+
total += value.byteLength;
|
|
21872
|
+
if (total > MAX_UPLOAD_BYTES) {
|
|
21873
|
+
await reader.cancel().catch(() => {
|
|
21874
|
+
});
|
|
21875
|
+
throw tooLarge(name, null);
|
|
21876
|
+
}
|
|
21877
|
+
chunks.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength));
|
|
21878
|
+
}
|
|
21879
|
+
}
|
|
21457
21880
|
} catch (e) {
|
|
21458
|
-
if (e
|
|
21459
|
-
|
|
21881
|
+
if (e instanceof ApiError) throw e;
|
|
21882
|
+
throw new ApiError(0, `O download de ${url} caiu no meio (rede ou tempo esgotado).`);
|
|
21883
|
+
}
|
|
21884
|
+
const buf = Buffer.concat(chunks);
|
|
21885
|
+
const typed = (res.headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase();
|
|
21886
|
+
let mime = mimeForName(name);
|
|
21887
|
+
if (mime === "application/octet-stream" && typed) {
|
|
21888
|
+
const ext = Object.entries(MIME_BY_EXT).find(([, m]) => m === typed)?.[0];
|
|
21889
|
+
if (ext) {
|
|
21890
|
+
name = `${name.replace(/\.$/, "")}${ext}`;
|
|
21891
|
+
mime = typed;
|
|
21460
21892
|
}
|
|
21461
|
-
throw new ApiError(0, `Falha de rede ao subir "${name}" para o R2. Confira BEPLUS_API_URL.`);
|
|
21462
|
-
} finally {
|
|
21463
|
-
clearTimeout(timer);
|
|
21464
21893
|
}
|
|
21465
|
-
|
|
21894
|
+
return { buf, name, mime };
|
|
21895
|
+
}
|
|
21896
|
+
async function uploadBytes(cfg, file) {
|
|
21897
|
+
const { buf, name, mime } = file;
|
|
21898
|
+
if (!UPLOAD_EXTENSIONS.includes(extOf(name))) {
|
|
21899
|
+
throw new ApiError(
|
|
21900
|
+
422,
|
|
21901
|
+
`"${name}" n\xE3o sobe pela rota de arquivos da BePlus: a extens\xE3o n\xE3o est\xE1 na lista aceita (${UPLOAD_EXTENSIONS.join(", ")}). Converta para um desses formatos.`
|
|
21902
|
+
);
|
|
21903
|
+
}
|
|
21904
|
+
if (buf.byteLength > MAX_UPLOAD_BYTES) throw tooLarge(name, buf.byteLength);
|
|
21905
|
+
const form = new FormData();
|
|
21906
|
+
form.append("file", new Blob([buf], { type: mime }), name);
|
|
21907
|
+
const res = await fetchWithAuth(
|
|
21908
|
+
cfg,
|
|
21909
|
+
`${cfg.baseUrl}/api/v1/files/upload`,
|
|
21910
|
+
{ method: "POST", body: form, timeoutMs: UPLOAD_TIMEOUT_MS },
|
|
21911
|
+
`upload de "${name}"`
|
|
21912
|
+
);
|
|
21466
21913
|
let json2;
|
|
21467
|
-
|
|
21468
|
-
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
}
|
|
21914
|
+
try {
|
|
21915
|
+
const text = await res.text();
|
|
21916
|
+
json2 = text ? JSON.parse(text) : void 0;
|
|
21917
|
+
} catch {
|
|
21472
21918
|
}
|
|
21473
21919
|
if (!res.ok) {
|
|
21474
21920
|
const message = json2?.message || res.statusText || `HTTP ${res.status}`;
|
|
21921
|
+
if (res.status === 413) throw tooLarge(name, buf.byteLength);
|
|
21922
|
+
if (res.status === 403) {
|
|
21923
|
+
throw new ApiError(
|
|
21924
|
+
403,
|
|
21925
|
+
`Sem permiss\xE3o para subir "${name}" (${message}). No login pelo navegador, subir arquivo exige a permiss\xE3o ialab:spend: rode \`beplus-mcp login\` e autorize.`,
|
|
21926
|
+
json2
|
|
21927
|
+
);
|
|
21928
|
+
}
|
|
21929
|
+
if (res.status === 422) {
|
|
21930
|
+
throw new ApiError(422, `O servidor n\xE3o aceitou "${name}" (${message}). Confira o formato do arquivo.`, json2);
|
|
21931
|
+
}
|
|
21475
21932
|
throw new ApiError(res.status, `Upload de "${name}" falhou: ${message}`, json2);
|
|
21476
21933
|
}
|
|
21477
21934
|
const fileUrl = json2?.result?.file_url ?? json2?.file_url;
|
|
@@ -21480,6 +21937,9 @@ async function uploadFile(cfg, ref) {
|
|
|
21480
21937
|
}
|
|
21481
21938
|
return fileUrl;
|
|
21482
21939
|
}
|
|
21940
|
+
async function uploadFile(cfg, ref) {
|
|
21941
|
+
return uploadBytes(cfg, await loadLocal(ref));
|
|
21942
|
+
}
|
|
21483
21943
|
async function resolveRef(cfg, ref) {
|
|
21484
21944
|
if (!ref) return ref;
|
|
21485
21945
|
return isRemoteRef(ref) ? ref : uploadFile(cfg, ref);
|
|
@@ -22395,9 +22855,9 @@ ${list}${flagsLine(status)}${draftHint}` }, ...blocks] };
|
|
|
22395
22855
|
}
|
|
22396
22856
|
|
|
22397
22857
|
// src/probe.ts
|
|
22398
|
-
import { open, stat } from "fs/promises";
|
|
22858
|
+
import { open as open2, stat as stat3 } from "fs/promises";
|
|
22399
22859
|
import { extname as extname2, isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
|
|
22400
|
-
import { homedir as
|
|
22860
|
+
import { homedir as homedir3 } from "os";
|
|
22401
22861
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
22402
22862
|
var IMAGE_EXT = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
22403
22863
|
var VIDEO_EXT = /* @__PURE__ */ new Set([".mp4", ".mov", ".m4v"]);
|
|
@@ -22409,8 +22869,8 @@ function isRemote(ref) {
|
|
|
22409
22869
|
}
|
|
22410
22870
|
function toLocalPath2(ref) {
|
|
22411
22871
|
if (ref.startsWith("file://")) return fileURLToPath2(ref);
|
|
22412
|
-
if (ref === "~") return
|
|
22413
|
-
if (ref.startsWith("~/")) return resolve2(
|
|
22872
|
+
if (ref === "~") return homedir3();
|
|
22873
|
+
if (ref.startsWith("~/")) return resolve2(homedir3(), ref.slice(2));
|
|
22414
22874
|
return isAbsolute2(ref) ? ref : resolve2(process.cwd(), ref);
|
|
22415
22875
|
}
|
|
22416
22876
|
function kindFromExt(ref) {
|
|
@@ -22421,7 +22881,7 @@ function kindFromExt(ref) {
|
|
|
22421
22881
|
}
|
|
22422
22882
|
async function readAt(ref, offset, len) {
|
|
22423
22883
|
if (!isRemote(ref)) {
|
|
22424
|
-
const fh = await
|
|
22884
|
+
const fh = await open2(toLocalPath2(ref), "r");
|
|
22425
22885
|
try {
|
|
22426
22886
|
const buf = Buffer.alloc(len);
|
|
22427
22887
|
const { bytesRead } = await fh.read(buf, 0, len, offset);
|
|
@@ -22464,7 +22924,7 @@ async function findMoov(ref, fileSize) {
|
|
|
22464
22924
|
}
|
|
22465
22925
|
async function readHead(ref, bytes) {
|
|
22466
22926
|
if (!isRemote(ref)) {
|
|
22467
|
-
const fh = await
|
|
22927
|
+
const fh = await open2(toLocalPath2(ref), "r");
|
|
22468
22928
|
try {
|
|
22469
22929
|
const buf = Buffer.alloc(bytes);
|
|
22470
22930
|
const { bytesRead } = await fh.read(buf, 0, bytes, 0);
|
|
@@ -22542,7 +23002,7 @@ function probeWebp(b) {
|
|
|
22542
23002
|
}
|
|
22543
23003
|
return null;
|
|
22544
23004
|
}
|
|
22545
|
-
function
|
|
23005
|
+
function mp4Info(b) {
|
|
22546
23006
|
let duration3;
|
|
22547
23007
|
let width = 0;
|
|
22548
23008
|
let height = 0;
|
|
@@ -22610,13 +23070,16 @@ function probeMp4(b) {
|
|
|
22610
23070
|
}
|
|
22611
23071
|
};
|
|
22612
23072
|
walk(0, b.length, 0);
|
|
22613
|
-
if (!width || !height) return null;
|
|
22614
23073
|
const dur = duration3 ?? mediaDuration;
|
|
22615
|
-
const fps = dur && frames ? Math.round(frames / dur * 100) / 100 : void 0;
|
|
23074
|
+
const fps = width && height && dur && frames ? Math.round(frames / dur * 100) / 100 : void 0;
|
|
22616
23075
|
return { width, height, duration: dur, fps };
|
|
22617
23076
|
}
|
|
23077
|
+
function probeMp4(b) {
|
|
23078
|
+
const info = mp4Info(b);
|
|
23079
|
+
return info.width && info.height ? info : null;
|
|
23080
|
+
}
|
|
22618
23081
|
async function fileSizeOf(ref) {
|
|
22619
|
-
if (!isRemote(ref)) return (await
|
|
23082
|
+
if (!isRemote(ref)) return (await stat3(toLocalPath2(ref))).size;
|
|
22620
23083
|
const res = await fetch(ref, { method: "HEAD" });
|
|
22621
23084
|
return Number(res.headers.get("content-length") ?? 0);
|
|
22622
23085
|
}
|
|
@@ -22659,6 +23122,124 @@ async function probeMedia(ref) {
|
|
|
22659
23122
|
}
|
|
22660
23123
|
return { kind, width: info.width, height: info.height, duration: info.duration, fps: info.fps };
|
|
22661
23124
|
}
|
|
23125
|
+
function probeGif(b) {
|
|
23126
|
+
if (b.length < 10 || b.toString("ascii", 0, 4) !== "GIF8") return null;
|
|
23127
|
+
return { width: b.readUInt16LE(6), height: b.readUInt16LE(8) };
|
|
23128
|
+
}
|
|
23129
|
+
function probeWav(b) {
|
|
23130
|
+
if (b.length < 12 || b.toString("ascii", 0, 4) !== "RIFF" || b.toString("ascii", 8, 12) !== "WAVE") return null;
|
|
23131
|
+
let byteRate = 0;
|
|
23132
|
+
for (let i = 12; i + 8 <= b.length; ) {
|
|
23133
|
+
const id = b.toString("ascii", i, i + 4);
|
|
23134
|
+
const size = b.readUInt32LE(i + 4);
|
|
23135
|
+
if (id === "fmt " && i + 16 <= b.length) byteRate = b.readUInt32LE(i + 16);
|
|
23136
|
+
if (id === "data") {
|
|
23137
|
+
const bytes = size === 0 || size === 4294967295 || i + 8 + size > b.length ? b.length - i - 8 : size;
|
|
23138
|
+
return byteRate ? bytes / byteRate : null;
|
|
23139
|
+
}
|
|
23140
|
+
i += 8 + size + size % 2;
|
|
23141
|
+
}
|
|
23142
|
+
return null;
|
|
23143
|
+
}
|
|
23144
|
+
function probeFlac(b) {
|
|
23145
|
+
if (b.length < 42 || b.toString("ascii", 0, 4) !== "fLaC" || (b[4] & 127) !== 0) return null;
|
|
23146
|
+
const d = 8;
|
|
23147
|
+
const rate = b[d + 10] << 12 | b[d + 11] << 4 | b[d + 12] >> 4;
|
|
23148
|
+
const total = (b[d + 13] & 15) * 2 ** 32 + b.readUInt32BE(d + 14);
|
|
23149
|
+
return rate && total ? total / rate : null;
|
|
23150
|
+
}
|
|
23151
|
+
var MP3_KBPS = {
|
|
23152
|
+
v1: [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
|
|
23153
|
+
v2: [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160]
|
|
23154
|
+
};
|
|
23155
|
+
var MP3_RATES = { 3: [44100, 48e3, 32e3], 2: [22050, 24e3, 16e3], 0: [11025, 12e3, 8e3] };
|
|
23156
|
+
function probeMp3(b) {
|
|
23157
|
+
let i = 0;
|
|
23158
|
+
if (b.length > 10 && b.toString("ascii", 0, 3) === "ID3") {
|
|
23159
|
+
const size = (b[6] & 127) << 21 | (b[7] & 127) << 14 | (b[8] & 127) << 7 | b[9] & 127;
|
|
23160
|
+
i = 10 + size + (b[5] & 16 ? 10 : 0);
|
|
23161
|
+
}
|
|
23162
|
+
for (const end = Math.min(b.length - 4, i + 64 * 1024); i < end; i++) {
|
|
23163
|
+
if (b[i] !== 255 || (b[i + 1] & 224) !== 224) continue;
|
|
23164
|
+
const version2 = b[i + 1] >> 3 & 3;
|
|
23165
|
+
const layer = b[i + 1] >> 1 & 3;
|
|
23166
|
+
const kbps = MP3_KBPS[version2 === 3 ? "v1" : "v2"][b[i + 2] >> 4 & 15];
|
|
23167
|
+
const rate = MP3_RATES[version2]?.[b[i + 2] >> 2 & 3];
|
|
23168
|
+
if (version2 === 1 || layer !== 1 || !kbps || !rate) continue;
|
|
23169
|
+
const mono = (b[i + 3] >> 6 & 3) === 3;
|
|
23170
|
+
const spf = version2 === 3 ? 1152 : 576;
|
|
23171
|
+
const side = version2 === 3 ? mono ? 17 : 32 : mono ? 9 : 17;
|
|
23172
|
+
const xing = i + 4 + side;
|
|
23173
|
+
const tag = b.toString("ascii", xing, xing + 4);
|
|
23174
|
+
if ((tag === "Xing" || tag === "Info") && b[xing + 7] & 1) {
|
|
23175
|
+
const flags = b[xing + 7];
|
|
23176
|
+
const lame = xing + 12 + (flags & 2 ? 4 : 0) + (flags & 4 ? 100 : 0) + (flags & 8 ? 4 : 0);
|
|
23177
|
+
const gap = lame + 24 <= b.length && /^(LAME|Lavc|Lavf)/.test(b.toString("ascii", lame, lame + 4)) ? (b[lame + 21] << 4) + (b[lame + 22] >> 4) + ((b[lame + 22] & 15) << 8 | b[lame + 23]) : 0;
|
|
23178
|
+
return (b.readUInt32BE(xing + 8) * spf - gap) / rate;
|
|
23179
|
+
}
|
|
23180
|
+
if (b.toString("ascii", i + 36, i + 40) === "VBRI") return b.readUInt32BE(i + 36 + 14) * spf / rate;
|
|
23181
|
+
const tail = b.length >= 128 && b.toString("ascii", b.length - 128, b.length - 125) === "TAG" ? 128 : 0;
|
|
23182
|
+
return (b.length - i - tail) * 8 / (kbps * 1e3);
|
|
23183
|
+
}
|
|
23184
|
+
return null;
|
|
23185
|
+
}
|
|
23186
|
+
function probeBuffer(b, mime) {
|
|
23187
|
+
const round = (n) => Math.round(n * 1e3) / 1e3;
|
|
23188
|
+
if (mime.startsWith("image/")) {
|
|
23189
|
+
const dim = probePng(b) ?? probeJpeg(b) ?? probeWebp(b) ?? probeGif(b);
|
|
23190
|
+
return dim ? { width: dim.width, height: dim.height } : null;
|
|
23191
|
+
}
|
|
23192
|
+
if (/^(video|audio)\/(mp4|quicktime|x-m4v|x-m4a|aac)$/.test(mime) || probeMp4Head(b)) {
|
|
23193
|
+
const info = mp4Info(b);
|
|
23194
|
+
if (!info.duration && !info.width) return null;
|
|
23195
|
+
const meta = {};
|
|
23196
|
+
if (info.width && info.height && mime.startsWith("video/")) {
|
|
23197
|
+
meta.width = info.width;
|
|
23198
|
+
meta.height = info.height;
|
|
23199
|
+
if (info.fps) meta.fps = info.fps;
|
|
23200
|
+
}
|
|
23201
|
+
if (info.duration) meta.duration = round(info.duration);
|
|
23202
|
+
return meta;
|
|
23203
|
+
}
|
|
23204
|
+
if (mime.startsWith("audio/")) {
|
|
23205
|
+
const seconds = probeWav(b) ?? probeFlac(b) ?? (mime === "audio/mpeg" ? probeMp3(b) : null);
|
|
23206
|
+
return seconds ? { duration: round(seconds) } : null;
|
|
23207
|
+
}
|
|
23208
|
+
return null;
|
|
23209
|
+
}
|
|
23210
|
+
function probeMp4Head(b) {
|
|
23211
|
+
return b.length > 12 && b.toString("ascii", 4, 8) === "ftyp";
|
|
23212
|
+
}
|
|
23213
|
+
async function ffprobeFile(path, timeoutMs = 2e4) {
|
|
23214
|
+
const bin = process.env.BEPLUS_FFPROBE?.trim() || "ffprobe";
|
|
23215
|
+
if (bin === "0") return null;
|
|
23216
|
+
const { execFile } = await import("child_process");
|
|
23217
|
+
const out = await new Promise((done) => {
|
|
23218
|
+
execFile(
|
|
23219
|
+
bin,
|
|
23220
|
+
["-v", "error", "-print_format", "json", "-show_entries", "format=duration:stream=codec_type,width,height,avg_frame_rate", path],
|
|
23221
|
+
{ timeout: timeoutMs, maxBuffer: 1024 * 1024 },
|
|
23222
|
+
(err, stdout) => done(err ? null : stdout)
|
|
23223
|
+
);
|
|
23224
|
+
});
|
|
23225
|
+
if (!out) return null;
|
|
23226
|
+
try {
|
|
23227
|
+
const j = JSON.parse(out);
|
|
23228
|
+
const meta = {};
|
|
23229
|
+
const video = j.streams?.find((s) => s.codec_type === "video" && s.width && s.height);
|
|
23230
|
+
if (video) {
|
|
23231
|
+
meta.width = video.width;
|
|
23232
|
+
meta.height = video.height;
|
|
23233
|
+
const [n, d] = String(video.avg_frame_rate ?? "").split("/").map(Number);
|
|
23234
|
+
if (n && d) meta.fps = Math.round(n / d * 100) / 100;
|
|
23235
|
+
}
|
|
23236
|
+
const duration3 = Number(j.format?.duration);
|
|
23237
|
+
if (Number.isFinite(duration3) && duration3 > 0) meta.duration = Math.round(duration3 * 1e3) / 1e3;
|
|
23238
|
+
return Object.keys(meta).length ? meta : null;
|
|
23239
|
+
} catch {
|
|
23240
|
+
return null;
|
|
23241
|
+
}
|
|
23242
|
+
}
|
|
22662
23243
|
|
|
22663
23244
|
// src/tools/upscale.ts
|
|
22664
23245
|
var IMAGE_MODEL = "topaz/upscale/image/generative";
|
|
@@ -22874,7 +23455,7 @@ function registerAudioTools(server, client, cfg) {
|
|
|
22874
23455
|
},
|
|
22875
23456
|
async (args) => {
|
|
22876
23457
|
try {
|
|
22877
|
-
const
|
|
23458
|
+
const body2 = compact({
|
|
22878
23459
|
text: args.text,
|
|
22879
23460
|
voice: args.voice,
|
|
22880
23461
|
model: args.model,
|
|
@@ -22882,7 +23463,7 @@ function registerAudioTools(server, client, cfg) {
|
|
|
22882
23463
|
multiSpeaker: args.multi_speaker,
|
|
22883
23464
|
project: args.project ?? cfg.activeProject ?? void 0
|
|
22884
23465
|
});
|
|
22885
|
-
const res = await client.tts(
|
|
23466
|
+
const res = await client.tts(body2);
|
|
22886
23467
|
const parts = [`Custo: ${res.diamond_cost} \u{1F48E}`];
|
|
22887
23468
|
if (res.diamonds_refunded) parts.push(`Estorno: ${res.diamonds_refunded} \u{1F48E}`);
|
|
22888
23469
|
const projLine = res.project_code ? `
|
|
@@ -23378,11 +23959,11 @@ function fmtDate(iso) {
|
|
|
23378
23959
|
function callLine(c) {
|
|
23379
23960
|
const company = c.company_name ? ` \xB7 ${c.company_name}` : "";
|
|
23380
23961
|
const proj = c.project_name ? ` \xB7 ${c.client_name ? c.client_name + " / " : ""}${c.project_name}` : "";
|
|
23381
|
-
const
|
|
23962
|
+
const who2 = c.speakers.length ? ` \xB7 ${c.speakers.join(", ")}` : c.participant_count ? ` \xB7 ${c.participant_count} falantes` : "";
|
|
23382
23963
|
const vis = VIS_LABEL[c.visibility] ?? c.visibility;
|
|
23383
23964
|
const flag = c.status !== "ready" ? ` [${c.status}]` : "";
|
|
23384
23965
|
return `\u2022 ${c.title ?? "(sem t\xEDtulo)"}${flag}
|
|
23385
|
-
${fmtDate(c.date)} \xB7 ${fmtDuration(c.duration_sec)} \xB7 ${vis}${company}${proj}${
|
|
23966
|
+
${fmtDate(c.date)} \xB7 ${fmtDuration(c.duration_sec)} \xB7 ${vis}${company}${proj}${who2}
|
|
23386
23967
|
id: ${c.id}`;
|
|
23387
23968
|
}
|
|
23388
23969
|
function renderCall(c) {
|
|
@@ -23468,6 +24049,9 @@ ${calls.map(callLine).join("\n\n")}`);
|
|
|
23468
24049
|
);
|
|
23469
24050
|
}
|
|
23470
24051
|
|
|
24052
|
+
// src/tools/canvas.ts
|
|
24053
|
+
import { createHash } from "crypto";
|
|
24054
|
+
|
|
23471
24055
|
// src/canvas/api.ts
|
|
23472
24056
|
var PINNED_CORE_VERSION = "ca7b3b406184c7f679f555c3a008013197182b23";
|
|
23473
24057
|
function errorRaw(err) {
|
|
@@ -23475,6 +24059,12 @@ function errorRaw(err) {
|
|
|
23475
24059
|
const raw = err.body?.error?.raw;
|
|
23476
24060
|
return raw && typeof raw === "object" ? raw : void 0;
|
|
23477
24061
|
}
|
|
24062
|
+
var commentPacing = {
|
|
24063
|
+
perMinute: 50,
|
|
24064
|
+
retryWaitsMs: [5e3, 15e3, 45e3],
|
|
24065
|
+
now: () => Date.now(),
|
|
24066
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, Math.max(0, ms)))
|
|
24067
|
+
};
|
|
23478
24068
|
var CanvasApi = class {
|
|
23479
24069
|
constructor(client, cfg) {
|
|
23480
24070
|
this.client = client;
|
|
@@ -23484,6 +24074,8 @@ var CanvasApi = class {
|
|
|
23484
24074
|
cfg;
|
|
23485
24075
|
coreVersion = PINNED_CORE_VERSION;
|
|
23486
24076
|
userId = null;
|
|
24077
|
+
/** Instantes das escritas de comentário no último minuto. */
|
|
24078
|
+
writes = [];
|
|
23487
24079
|
req(method, path, opts = {}) {
|
|
23488
24080
|
return this.client.request(method, path, { ...opts, base: this.cfg.canvasBase });
|
|
23489
24081
|
}
|
|
@@ -23499,16 +24091,16 @@ var CanvasApi = class {
|
|
|
23499
24091
|
listBoards(kind = "board") {
|
|
23500
24092
|
return this.req("GET", "/boards", { query: { kind } });
|
|
23501
24093
|
}
|
|
23502
|
-
createBoard(
|
|
23503
|
-
return this.req("POST", "/boards", { body });
|
|
24094
|
+
createBoard(body2) {
|
|
24095
|
+
return this.req("POST", "/boards", { body: body2 });
|
|
23504
24096
|
}
|
|
23505
|
-
snapshot(
|
|
23506
|
-
return this.req("GET", `/boards/${
|
|
24097
|
+
snapshot(boardId3) {
|
|
24098
|
+
return this.req("GET", `/boards/${boardId3}`);
|
|
23507
24099
|
}
|
|
23508
24100
|
/** Replay depois de `after`. `null` quando o servidor manda reler a foto (410). */
|
|
23509
|
-
async opsAfter(
|
|
24101
|
+
async opsAfter(boardId3, after) {
|
|
23510
24102
|
try {
|
|
23511
|
-
const { envelopes } = await this.req("GET", `/boards/${
|
|
24103
|
+
const { envelopes } = await this.req("GET", `/boards/${boardId3}/ops`, {
|
|
23512
24104
|
query: { after }
|
|
23513
24105
|
});
|
|
23514
24106
|
return envelopes;
|
|
@@ -23517,8 +24109,8 @@ var CanvasApi = class {
|
|
|
23517
24109
|
throw e;
|
|
23518
24110
|
}
|
|
23519
24111
|
}
|
|
23520
|
-
async commit(
|
|
23521
|
-
const send = () => this.req("POST", `/boards/${
|
|
24112
|
+
async commit(boardId3, ops) {
|
|
24113
|
+
const send = () => this.req("POST", `/boards/${boardId3}/ops`, {
|
|
23522
24114
|
body: { coreVersion: this.coreVersion, ops }
|
|
23523
24115
|
});
|
|
23524
24116
|
try {
|
|
@@ -23539,14 +24131,51 @@ var CanvasApi = class {
|
|
|
23539
24131
|
}
|
|
23540
24132
|
}
|
|
23541
24133
|
}
|
|
23542
|
-
members(
|
|
23543
|
-
return this.req("GET", `/boards/${
|
|
24134
|
+
members(boardId3) {
|
|
24135
|
+
return this.req("GET", `/boards/${boardId3}/members`);
|
|
23544
24136
|
}
|
|
23545
|
-
putMember(
|
|
23546
|
-
return this.req("PUT", `/boards/${
|
|
24137
|
+
putMember(boardId3, userId, role) {
|
|
24138
|
+
return this.req("PUT", `/boards/${boardId3}/members/${userId}`, { body: { role } });
|
|
23547
24139
|
}
|
|
23548
|
-
removeMember(
|
|
23549
|
-
return this.req("DELETE", `/boards/${
|
|
24140
|
+
removeMember(boardId3, userId) {
|
|
24141
|
+
return this.req("DELETE", `/boards/${boardId3}/members/${userId}`);
|
|
24142
|
+
}
|
|
24143
|
+
// ── comentários (academy-backend #313) ────────────────────────────────────
|
|
24144
|
+
listComments(boardId3, status = "open") {
|
|
24145
|
+
return this.req("GET", `/boards/${boardId3}/comments`, { query: { status } });
|
|
24146
|
+
}
|
|
24147
|
+
/**
|
|
24148
|
+
* Escrita de comentário passa por aqui: o back limita a 60 por minuto por pessoa
|
|
24149
|
+
* (balde fixo, sem Retry-After). O MCP se espaça abaixo do teto e, se ainda
|
|
24150
|
+
* assim vier 429 (a pessoa também comentando no Canvas), espera e tenta de novo.
|
|
24151
|
+
*/
|
|
24152
|
+
async write(method, path, body2) {
|
|
24153
|
+
const p = commentPacing;
|
|
24154
|
+
const now = p.now();
|
|
24155
|
+
this.writes = this.writes.filter((t) => now - t < 6e4);
|
|
24156
|
+
if (this.writes.length >= p.perMinute) {
|
|
24157
|
+
await p.sleep(this.writes[0] + 6e4 - now);
|
|
24158
|
+
this.writes.shift();
|
|
24159
|
+
}
|
|
24160
|
+
for (let attempt = 0; ; attempt++) {
|
|
24161
|
+
this.writes.push(p.now());
|
|
24162
|
+
try {
|
|
24163
|
+
return await this.req(method, path, body2 === void 0 ? {} : { body: body2 });
|
|
24164
|
+
} catch (e) {
|
|
24165
|
+
if (!(e instanceof ApiError) || e.httpStatus !== 429 || attempt >= p.retryWaitsMs.length) throw e;
|
|
24166
|
+
await p.sleep(p.retryWaitsMs[attempt]);
|
|
24167
|
+
}
|
|
24168
|
+
}
|
|
24169
|
+
}
|
|
24170
|
+
/** Raiz ou resposta. O back devolve sempre a THREAD DA RAIZ (resposta nova = última de `replies`). */
|
|
24171
|
+
createComment(boardId3, body2) {
|
|
24172
|
+
return this.write("POST", `/boards/${boardId3}/comments`, body2);
|
|
24173
|
+
}
|
|
24174
|
+
resolveComment(boardId3, commentId2) {
|
|
24175
|
+
return this.write("POST", `/boards/${boardId3}/comments/${commentId2}/resolve`);
|
|
24176
|
+
}
|
|
24177
|
+
reopenComment(boardId3, commentId2) {
|
|
24178
|
+
return this.write("POST", `/boards/${boardId3}/comments/${commentId2}/reopen`);
|
|
23550
24179
|
}
|
|
23551
24180
|
/** Só para os testes conferirem o aprendizado. */
|
|
23552
24181
|
get currentCoreVersion() {
|
|
@@ -23563,6 +24192,8 @@ var CoreMismatchError = class extends Error {
|
|
|
23563
24192
|
}
|
|
23564
24193
|
serverVersion;
|
|
23565
24194
|
};
|
|
24195
|
+
var CanvasToolError = class extends Error {
|
|
24196
|
+
};
|
|
23566
24197
|
|
|
23567
24198
|
// src/canvas/catalog.ts
|
|
23568
24199
|
var WORKFLOW_NODE_TYPE = "workflow";
|
|
@@ -23737,6 +24368,7 @@ function knownPort(kind, side, port) {
|
|
|
23737
24368
|
// src/canvas/core.ts
|
|
23738
24369
|
import { randomBytes, randomUUID } from "crypto";
|
|
23739
24370
|
var SCHEMA_VERSION = 1;
|
|
24371
|
+
var MAX_ENVELOPES_PER_COMMIT = 200;
|
|
23740
24372
|
var MAX_OP_BYTES = 64 * 1024;
|
|
23741
24373
|
var MAX_DATA_URL_BYTES = 8 * 1024;
|
|
23742
24374
|
var CLIENT_ID = `mcp-${randomBytes(6).toString("hex")}`;
|
|
@@ -23816,8 +24448,8 @@ function checkOp(op) {
|
|
|
23816
24448
|
return null;
|
|
23817
24449
|
}
|
|
23818
24450
|
}
|
|
23819
|
-
function envelope(
|
|
23820
|
-
return { id: randomUUID(), boardId:
|
|
24451
|
+
function envelope(boardId3, op, actorId) {
|
|
24452
|
+
return { id: randomUUID(), boardId: boardId3, clientId: CLIENT_ID, actorId, seq: null, ts: Date.now(), op };
|
|
23821
24453
|
}
|
|
23822
24454
|
function checkEnvelope(env) {
|
|
23823
24455
|
const bad = checkOp(env.op);
|
|
@@ -23884,6 +24516,38 @@ function removeNodeOps(doc, nodeId) {
|
|
|
23884
24516
|
function batchOf(ops) {
|
|
23885
24517
|
return ops.length === 1 ? ops[0] : { type: "batch", ops };
|
|
23886
24518
|
}
|
|
24519
|
+
var OpTooLargeError = class extends Error {
|
|
24520
|
+
constructor(op, bytes) {
|
|
24521
|
+
super(`opera\xE7\xE3o de ${bytes} bytes`);
|
|
24522
|
+
this.op = op;
|
|
24523
|
+
this.bytes = bytes;
|
|
24524
|
+
this.name = "OpTooLargeError";
|
|
24525
|
+
}
|
|
24526
|
+
op;
|
|
24527
|
+
bytes;
|
|
24528
|
+
};
|
|
24529
|
+
function packEnvelopes(boardId3, ops, actorId, limit = MAX_OP_BYTES - 1024) {
|
|
24530
|
+
const bytes = (v) => Buffer.byteLength(JSON.stringify(v));
|
|
24531
|
+
const overhead = bytes(envelope(boardId3, { type: "batch", ops: [] }, actorId));
|
|
24532
|
+
const out = [];
|
|
24533
|
+
let cur = [];
|
|
24534
|
+
let size = overhead;
|
|
24535
|
+
const flush = () => {
|
|
24536
|
+
if (cur.length) out.push(envelope(boardId3, batchOf(cur), actorId));
|
|
24537
|
+
cur = [];
|
|
24538
|
+
size = overhead;
|
|
24539
|
+
};
|
|
24540
|
+
for (const op of ops) {
|
|
24541
|
+
const b = bytes(op);
|
|
24542
|
+
if (overhead + b > limit) throw new OpTooLargeError(op, b);
|
|
24543
|
+
const next = size + b + (cur.length ? 1 : 0);
|
|
24544
|
+
if (next > limit) flush();
|
|
24545
|
+
size += b + (cur.length ? 1 : 0);
|
|
24546
|
+
cur.push(op);
|
|
24547
|
+
}
|
|
24548
|
+
flush();
|
|
24549
|
+
return out;
|
|
24550
|
+
}
|
|
23887
24551
|
|
|
23888
24552
|
// src/canvas/summary.ts
|
|
23889
24553
|
var MAX_TEXT = 160;
|
|
@@ -23894,6 +24558,7 @@ var HEAVY_KEYS = /* @__PURE__ */ new Set([
|
|
|
23894
24558
|
"main",
|
|
23895
24559
|
"lastFrame",
|
|
23896
24560
|
"sequence",
|
|
24561
|
+
"timeline",
|
|
23897
24562
|
"points",
|
|
23898
24563
|
"extra",
|
|
23899
24564
|
"mentions",
|
|
@@ -23980,6 +24645,10 @@ function nodeLines(node, run) {
|
|
|
23980
24645
|
facts.push(`${d.rows.length} linha(s)`);
|
|
23981
24646
|
extra.push(...rowsLines(d.rows));
|
|
23982
24647
|
}
|
|
24648
|
+
if (kind === "montage") {
|
|
24649
|
+
const fact = timelineFact(d);
|
|
24650
|
+
if (fact) facts.push(fact);
|
|
24651
|
+
}
|
|
23983
24652
|
const main2 = spec?.main;
|
|
23984
24653
|
if (main2 && typeof d[main2] === "string" && d[main2]) facts.push(`${main2}: "${oneLine(d[main2])}"`);
|
|
23985
24654
|
for (const [key, value] of Object.entries(d)) {
|
|
@@ -23994,6 +24663,18 @@ function nodeLines(node, run) {
|
|
|
23994
24663
|
if (run?.claimedBy) facts.push("rodando agora");
|
|
23995
24664
|
return [facts.length ? `${head} \xB7 ${facts.join(" \xB7 ")}` : head, ...extra];
|
|
23996
24665
|
}
|
|
24666
|
+
function timelineFact(d) {
|
|
24667
|
+
const volume = "musicGainDb/duckingDb n\xE3o valem para ela: o volume fica nos clipes e faixas";
|
|
24668
|
+
if (d.timeline !== void 0) {
|
|
24669
|
+
const legacy = d.sequence !== void 0 ? "; data.sequence \xE9 o legado congelado" : "";
|
|
24670
|
+
return `timeline (v3): ${JSON.stringify(d.timeline).length} caracteres (inteira em canvas_read_node sem path${legacy}; ${volume})`;
|
|
24671
|
+
}
|
|
24672
|
+
const seq = d.sequence;
|
|
24673
|
+
if (!seq || typeof seq !== "object" || Array.isArray(seq)) return null;
|
|
24674
|
+
const plans = Array.isArray(seq.plans) ? seq.plans.length : 0;
|
|
24675
|
+
const clips = seq.audioClips && typeof seq.audioClips === "object" && !Array.isArray(seq.audioClips) ? Object.values(seq.audioClips).reduce((t, list) => t + (Array.isArray(list) ? list.length : 0), 0) : 0;
|
|
24676
|
+
return `sequ\xEAncia (legado, sem data.timeline): ${plans} plano(s), ${clips} clipe(s) de \xE1udio, ${JSON.stringify(seq).length} caracteres (inteira em canvas_read_node sem path; ${volume})`;
|
|
24677
|
+
}
|
|
23997
24678
|
function boardSummary(snap) {
|
|
23998
24679
|
const doc = snap.doc;
|
|
23999
24680
|
const nodes = Object.values(doc.nodes).sort((a, b) => a.position.x - b.position.x || a.position.y - b.position.y);
|
|
@@ -24018,28 +24699,46 @@ function boardSummary(snap) {
|
|
|
24018
24699
|
return lines.join("\n");
|
|
24019
24700
|
}
|
|
24020
24701
|
function nodeDetail(node) {
|
|
24021
|
-
|
|
24702
|
+
let cuts = 0;
|
|
24703
|
+
const strip = (v, depth, path) => {
|
|
24022
24704
|
if (typeof v === "string") {
|
|
24023
24705
|
if (v.startsWith("data:")) return `[data-url ${v.length}b]`;
|
|
24024
|
-
|
|
24706
|
+
if (v.length <= 2e3) return v;
|
|
24707
|
+
cuts++;
|
|
24708
|
+
return `${v.slice(0, 2e3)}\u2026 [+${v.length - 2e3} caracteres: path=${path}]`;
|
|
24025
24709
|
}
|
|
24026
24710
|
if (Array.isArray(v)) {
|
|
24027
|
-
if (depth > 4)
|
|
24028
|
-
|
|
24029
|
-
|
|
24711
|
+
if (depth > 4) {
|
|
24712
|
+
cuts++;
|
|
24713
|
+
return `[${v.length} itens, ${JSON.stringify(v).length} caracteres: path=${path}]`;
|
|
24714
|
+
}
|
|
24715
|
+
const head = v.slice(0, 60).map((x, i) => strip(x, depth + 1, `${path}.${i}`));
|
|
24716
|
+
if (v.length <= 60) return head;
|
|
24717
|
+
cuts++;
|
|
24718
|
+
return [...head, `\u2026 +${v.length - 60} itens: path=${path}`];
|
|
24030
24719
|
}
|
|
24031
24720
|
if (v && typeof v === "object") {
|
|
24032
|
-
if (depth > 4)
|
|
24721
|
+
if (depth > 4) {
|
|
24722
|
+
cuts++;
|
|
24723
|
+
return `{${JSON.stringify(v).length} caracteres: path=${path}}`;
|
|
24724
|
+
}
|
|
24033
24725
|
const out = {};
|
|
24034
24726
|
for (const [k, x] of Object.entries(v)) {
|
|
24035
|
-
|
|
24727
|
+
const at = path ? `${path}.${k}` : k;
|
|
24728
|
+
if (depth === 0 && (k === "points" || k === "sequence" || k === "timeline")) {
|
|
24729
|
+
cuts++;
|
|
24730
|
+
out[k] = `[omitido: ${JSON.stringify(x).length} caracteres: path=${k}]`;
|
|
24731
|
+
} else out[k] = strip(x, depth + 1, at);
|
|
24036
24732
|
}
|
|
24037
24733
|
return out;
|
|
24038
24734
|
}
|
|
24039
24735
|
return v;
|
|
24040
24736
|
};
|
|
24737
|
+
const json2 = JSON.stringify(strip(node.data, 0, ""));
|
|
24738
|
+
const note = cuts ? `
|
|
24739
|
+
(${cuts} corte(s) marcado(s) com path=\u2026: leia inteiro com canvas_read_node e esse path)` : "";
|
|
24041
24740
|
return `${node.id} \xB7 ${nodeKind(node) ?? node.type} \xB7 "${nodeName(node)}"
|
|
24042
|
-
${
|
|
24741
|
+
${json2}${note}`;
|
|
24043
24742
|
}
|
|
24044
24743
|
function changesSince(envelopes, doc) {
|
|
24045
24744
|
const count = /* @__PURE__ */ new Map();
|
|
@@ -24067,6 +24766,497 @@ function touchedNodes(envelopes) {
|
|
|
24067
24766
|
return out;
|
|
24068
24767
|
}
|
|
24069
24768
|
|
|
24769
|
+
// src/canvas/comments.ts
|
|
24770
|
+
function mmss(t) {
|
|
24771
|
+
const total = Math.max(0, Math.floor(t));
|
|
24772
|
+
const h = Math.floor(total / 3600);
|
|
24773
|
+
const m = Math.floor(total % 3600 / 60);
|
|
24774
|
+
const s = total % 60;
|
|
24775
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
24776
|
+
return h ? `${h}:${pad(m)}:${pad(s)}` : `${pad(m)}:${pad(s)}`;
|
|
24777
|
+
}
|
|
24778
|
+
function nodeRef(doc, nodeId) {
|
|
24779
|
+
const node = doc.nodes[nodeId];
|
|
24780
|
+
const kind = nodeKind(node) ?? node.type;
|
|
24781
|
+
return `"${oneLine(nodeName(node), 60)}" (${kind}, ${node.id})`;
|
|
24782
|
+
}
|
|
24783
|
+
function hashString(text) {
|
|
24784
|
+
let h1 = 3735928559;
|
|
24785
|
+
let h2 = 1103547991;
|
|
24786
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
24787
|
+
const ch = text.charCodeAt(i);
|
|
24788
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
24789
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
24790
|
+
}
|
|
24791
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
24792
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
24793
|
+
const hex = (n) => (n >>> 0).toString(16).padStart(8, "0");
|
|
24794
|
+
return hex(h2) + hex(h1);
|
|
24795
|
+
}
|
|
24796
|
+
function outputKeyOf(entry) {
|
|
24797
|
+
for (const field of [entry.resultId, entry.id, entry.generationId]) {
|
|
24798
|
+
if (typeof field === "string" && field !== "" && field.length <= 128) return field;
|
|
24799
|
+
}
|
|
24800
|
+
if (typeof entry.url === "string" && entry.url !== "") return `url-${hashString(entry.url)}`;
|
|
24801
|
+
return null;
|
|
24802
|
+
}
|
|
24803
|
+
function versionOf(doc, nodeId, outputKey) {
|
|
24804
|
+
const ids = doc.nodeHistory?.[nodeId];
|
|
24805
|
+
if (Array.isArray(ids)) {
|
|
24806
|
+
const i = ids.indexOf(outputKey);
|
|
24807
|
+
if (i >= 0) return i + 1;
|
|
24808
|
+
}
|
|
24809
|
+
const history = doc.nodes[nodeId]?.data.history;
|
|
24810
|
+
if (Array.isArray(history)) {
|
|
24811
|
+
const i = history.findIndex(
|
|
24812
|
+
(h) => typeof h === "object" && h !== null && !Array.isArray(h) && outputKeyOf(h) === outputKey
|
|
24813
|
+
);
|
|
24814
|
+
if (i >= 0) return history.length - i;
|
|
24815
|
+
}
|
|
24816
|
+
return null;
|
|
24817
|
+
}
|
|
24818
|
+
function describeAnchor(anchor, doc) {
|
|
24819
|
+
if (!anchor || anchor.kind === "point") return { text: "no board" };
|
|
24820
|
+
const exists = !!doc.nodes[anchor.nodeId];
|
|
24821
|
+
if (!exists) {
|
|
24822
|
+
return { text: `no n\xF3 ${anchor.nodeId}`, gone: "o n\xF3 foi apagado" };
|
|
24823
|
+
}
|
|
24824
|
+
const ref = nodeRef(doc, anchor.nodeId);
|
|
24825
|
+
switch (anchor.kind) {
|
|
24826
|
+
case "node":
|
|
24827
|
+
return { text: `no n\xF3 ${ref}`, nodeId: anchor.nodeId };
|
|
24828
|
+
case "output": {
|
|
24829
|
+
const v = versionOf(doc, anchor.nodeId, anchor.outputKey);
|
|
24830
|
+
return v === null ? { text: `numa vers\xE3o de ${ref} (${anchor.outputKey})`, nodeId: anchor.nodeId, gone: "essa vers\xE3o n\xE3o est\xE1 mais no hist\xF3rico do n\xF3" } : { text: `na vers\xE3o ${v} de ${ref}`, nodeId: anchor.nodeId };
|
|
24831
|
+
}
|
|
24832
|
+
case "timecode": {
|
|
24833
|
+
const node = doc.nodes[anchor.nodeId];
|
|
24834
|
+
const kind = nodeKind(node);
|
|
24835
|
+
const t = mmss(Number(anchor.t) || 0);
|
|
24836
|
+
if (kind === "montage") {
|
|
24837
|
+
const name = nodeName(node);
|
|
24838
|
+
const title = name === KINDS.montage.title ? "" : ` "${oneLine(name, 60)}"`;
|
|
24839
|
+
return { text: `em ${t} da Montagem${title} (${node.id})`, nodeId: anchor.nodeId };
|
|
24840
|
+
}
|
|
24841
|
+
return { text: `em ${t} de ${ref}`, nodeId: anchor.nodeId };
|
|
24842
|
+
}
|
|
24843
|
+
default:
|
|
24844
|
+
return { text: "no board" };
|
|
24845
|
+
}
|
|
24846
|
+
}
|
|
24847
|
+
function who(c) {
|
|
24848
|
+
return c.author?.name?.trim() || "algu\xE9m";
|
|
24849
|
+
}
|
|
24850
|
+
function reactionsText(r) {
|
|
24851
|
+
if (Array.isArray(r)) {
|
|
24852
|
+
const parts = r.map((x) => {
|
|
24853
|
+
const rec = x ?? {};
|
|
24854
|
+
const emoji2 = typeof rec.emoji === "string" ? rec.emoji : null;
|
|
24855
|
+
const n = typeof rec.count === "number" ? rec.count : Array.isArray(rec.userIds) ? rec.userIds.length : Array.isArray(rec.users) ? rec.users.length : 1;
|
|
24856
|
+
return emoji2 ? `${emoji2}${n > 1 ? `\xD7${n}` : ""}` : null;
|
|
24857
|
+
}).filter(Boolean);
|
|
24858
|
+
return parts.join(" ");
|
|
24859
|
+
}
|
|
24860
|
+
if (r && typeof r === "object") {
|
|
24861
|
+
return Object.entries(r).map(([emoji2, v]) => {
|
|
24862
|
+
const n = Array.isArray(v) ? v.length : typeof v === "number" ? v : 1;
|
|
24863
|
+
return `${emoji2}${n > 1 ? `\xD7${n}` : ""}`;
|
|
24864
|
+
}).join(" ");
|
|
24865
|
+
}
|
|
24866
|
+
return "";
|
|
24867
|
+
}
|
|
24868
|
+
var MAX_REPLIES = 5;
|
|
24869
|
+
function threadLines(t, doc) {
|
|
24870
|
+
const where = describeAnchor(t.anchor, doc);
|
|
24871
|
+
const state = t.resolvedAt ? " \xB7 RESOLVIDO" : "";
|
|
24872
|
+
const reacts = reactionsText(t.reactions);
|
|
24873
|
+
const lines = t.deleted ? [`- ${t.id} \xB7 ${where.text}${state}`, " (coment\xE1rio raiz apagado: n\xE3o d\xE1 para responder nem resolver)"] : [`- ${t.id} \xB7 ${where.text} \xB7 ${who(t)}${state}${reacts ? ` \xB7 ${reacts}` : ""}`, ` pedido: ${oneLine(t.body ?? "", 400)}`];
|
|
24874
|
+
if (where.gone && !t.deleted) lines.push(` \u26A0 ALVO SUMIU: ${where.gone}. Responda com pergunta, n\xE3o resolva.`);
|
|
24875
|
+
const replies = Array.isArray(t.replies) ? t.replies : [];
|
|
24876
|
+
for (const r of replies.slice(-MAX_REPLIES)) {
|
|
24877
|
+
lines.push(r.deleted ? " \u21B3 (resposta apagada)" : ` \u21B3 ${who(r)}: ${oneLine(r.body ?? "", 140)}`);
|
|
24878
|
+
}
|
|
24879
|
+
if (replies.length > MAX_REPLIES) lines.splice(lines.length - MAX_REPLIES, 0, ` \u21B3 \u2026 ${replies.length - MAX_REPLIES} resposta(s) antes`);
|
|
24880
|
+
return lines;
|
|
24881
|
+
}
|
|
24882
|
+
function commentsSummary(threads, doc, status) {
|
|
24883
|
+
const label = status === "resolved" ? "resolvido(s)" : status === "all" ? "no total" : "aberto(s)";
|
|
24884
|
+
if (!threads.length) return `Nenhum coment\xE1rio ${label === "no total" ? "no board" : label}.`;
|
|
24885
|
+
const out = [`${threads.length} coment\xE1rio(s) ${label}:`];
|
|
24886
|
+
for (const t of threads) out.push(...threadLines(t, doc));
|
|
24887
|
+
return out.join("\n");
|
|
24888
|
+
}
|
|
24889
|
+
|
|
24890
|
+
// src/tools/canvas-comments.ts
|
|
24891
|
+
var boardId = external_exports.string().uuid().describe("Id (uuid) do board.");
|
|
24892
|
+
var commentId = external_exports.string().min(1).max(128).describe("Id do coment\xE1rio raiz, como sai em canvas_list_comments.");
|
|
24893
|
+
var body = external_exports.string().trim().min(1).max(4e3);
|
|
24894
|
+
var mentions = external_exports.array(external_exports.string().uuid()).max(50).optional().describe("userIds a marcar (opcional; quem n\xE3o \xE9 membro \xE9 ignorado).");
|
|
24895
|
+
function registerCanvasCommentTools(server, api, run) {
|
|
24896
|
+
async function onComment(fn) {
|
|
24897
|
+
try {
|
|
24898
|
+
return await fn();
|
|
24899
|
+
} catch (e) {
|
|
24900
|
+
if (!(e instanceof ApiError)) throw e;
|
|
24901
|
+
if (e.httpStatus === 404) {
|
|
24902
|
+
throw new CanvasToolError("Coment\xE1rio (ou board) n\xE3o encontrado ou apagado. Liste de novo com canvas_list_comments.");
|
|
24903
|
+
}
|
|
24904
|
+
if (e.httpStatus === 400) throw new CanvasToolError(`O servidor recusou o coment\xE1rio: ${e.message}.`);
|
|
24905
|
+
if (e.httpStatus === 403 && (!api.usesPat || /ialab:/.test(e.message))) {
|
|
24906
|
+
throw new CanvasToolError(
|
|
24907
|
+
"O login pelo navegador deste MCP n\xE3o tem a permiss\xE3o ialab:spend, que toda escrita de coment\xE1rio exige. Rode `beplus-mcp login` de novo e autorize a permiss\xE3o de gastar/editar."
|
|
24908
|
+
);
|
|
24909
|
+
}
|
|
24910
|
+
if (e.httpStatus === 403) throw new CanvasToolError(`Sem permiss\xE3o: ${e.message}.`);
|
|
24911
|
+
if (e.httpStatus === 429) {
|
|
24912
|
+
throw new CanvasToolError(
|
|
24913
|
+
"Limite de escrita em coment\xE1rios (60 por minuto por pessoa) mesmo depois de esperar. Pare o lote, diga \xE0 pessoa quais j\xE1 foram fechados e siga daqui a 1 minuto a partir do pr\xF3ximo."
|
|
24914
|
+
);
|
|
24915
|
+
}
|
|
24916
|
+
throw e;
|
|
24917
|
+
}
|
|
24918
|
+
}
|
|
24919
|
+
const newReplyId = (thread) => {
|
|
24920
|
+
const last = thread?.replies?.at(-1);
|
|
24921
|
+
return last?.id ?? "?";
|
|
24922
|
+
};
|
|
24923
|
+
server.registerTool(
|
|
24924
|
+
"canvas_list_comments",
|
|
24925
|
+
{
|
|
24926
|
+
title: "Canvas: listar coment\xE1rios",
|
|
24927
|
+
description: "Lista os coment\xE1rios de um board (padr\xE3o: abertos): id, onde est\xE1 (n\xF3, vers\xE3o, minutagem da Montagem ou board), autor, pedido e respostas. Avisa quando o alvo sumiu. S\xF3 leitura.",
|
|
24928
|
+
inputSchema: {
|
|
24929
|
+
board_id: boardId,
|
|
24930
|
+
status: external_exports.enum(["open", "resolved", "all"]).optional().describe("open (padr\xE3o), resolved ou all.")
|
|
24931
|
+
},
|
|
24932
|
+
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
24933
|
+
},
|
|
24934
|
+
async ({ board_id, status }) => run(async () => {
|
|
24935
|
+
const st = status ?? "open";
|
|
24936
|
+
const [snap, threads] = await Promise.all([api.snapshot(board_id), api.listComments(board_id, st)]);
|
|
24937
|
+
const text = commentsSummary(threads, snap.doc, st);
|
|
24938
|
+
const open3 = threads.some((t) => !t.resolvedAt);
|
|
24939
|
+
return open3 ? `${text}
|
|
24940
|
+
|
|
24941
|
+
Para aplicar: leia o n\xF3 com canvas_read_board (node_ids), edite pelas canvas_* e feche com canvas_resolve_comment dizendo o que fez.` : text;
|
|
24942
|
+
})
|
|
24943
|
+
);
|
|
24944
|
+
server.registerTool(
|
|
24945
|
+
"canvas_reply_comment",
|
|
24946
|
+
{
|
|
24947
|
+
title: "Canvas: responder coment\xE1rio",
|
|
24948
|
+
description: "Responde numa thread de coment\xE1rio sem resolver. Use para perguntar quando o pedido \xE9 amb\xEDguo ou o alvo sumiu.",
|
|
24949
|
+
inputSchema: { board_id: boardId, comment_id: commentId, body, mentions },
|
|
24950
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24951
|
+
},
|
|
24952
|
+
async ({ board_id, comment_id, body: text, mentions: m }) => run(async () => {
|
|
24953
|
+
const thread = await onComment(
|
|
24954
|
+
() => api.createComment(board_id, { body: text, parentId: comment_id, ...m?.length ? { mentions: m } : {} })
|
|
24955
|
+
);
|
|
24956
|
+
const open3 = thread?.resolvedAt ? "A thread est\xE1 resolvida; reabra com canvas_reopen_comment se precisar." : "A thread segue aberta.";
|
|
24957
|
+
return `\u2705 Resposta ${newReplyId(thread)} em ${comment_id}: "${oneLine(text, 120)}". ${open3}`;
|
|
24958
|
+
})
|
|
24959
|
+
);
|
|
24960
|
+
server.registerTool(
|
|
24961
|
+
"canvas_resolve_comment",
|
|
24962
|
+
{
|
|
24963
|
+
title: "Canvas: resolver coment\xE1rio",
|
|
24964
|
+
description: "Fecha um coment\xE1rio depois de aplicar o ajuste. done \xE9 obrigat\xF3rio: uma frase curta dizendo o que foi feito (vira resposta na thread antes de resolver). N\xE3o resolva pedido amb\xEDguo nem com alvo sumido: responda com pergunta.",
|
|
24965
|
+
inputSchema: {
|
|
24966
|
+
board_id: boardId,
|
|
24967
|
+
comment_id: commentId,
|
|
24968
|
+
done: external_exports.string().trim().min(3).max(500).describe('O que foi feito, ex.: "troquei a fala do b2 e encurtei o b3".')
|
|
24969
|
+
},
|
|
24970
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24971
|
+
},
|
|
24972
|
+
async ({ board_id, comment_id, done }) => run(async () => {
|
|
24973
|
+
const thread = await onComment(() => api.createComment(board_id, { body: done, parentId: comment_id }));
|
|
24974
|
+
const replyId = newReplyId(thread);
|
|
24975
|
+
try {
|
|
24976
|
+
await onComment(() => api.resolveComment(board_id, comment_id));
|
|
24977
|
+
} catch (e) {
|
|
24978
|
+
const why = e instanceof Error ? e.message : String(e);
|
|
24979
|
+
throw new CanvasToolError(
|
|
24980
|
+
`A resposta "${oneLine(done, 80)}" (${replyId}) foi postada em ${comment_id}, mas resolver falhou: ${why} N\xE3o repita canvas_resolve_comment (postaria a resposta de novo): avise a pessoa para resolver no Canvas.`
|
|
24981
|
+
);
|
|
24982
|
+
}
|
|
24983
|
+
return `\u2705 Resolvido ${comment_id}: "${oneLine(done, 120)}" (resposta ${replyId}).`;
|
|
24984
|
+
})
|
|
24985
|
+
);
|
|
24986
|
+
server.registerTool(
|
|
24987
|
+
"canvas_reopen_comment",
|
|
24988
|
+
{
|
|
24989
|
+
title: "Canvas: reabrir coment\xE1rio",
|
|
24990
|
+
description: "Reabre um coment\xE1rio resolvido. why (opcional) vira resposta na thread explicando o motivo.",
|
|
24991
|
+
inputSchema: { board_id: boardId, comment_id: commentId, why: external_exports.string().trim().min(1).max(1e3).optional() },
|
|
24992
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24993
|
+
},
|
|
24994
|
+
async ({ board_id, comment_id, why }) => run(async () => {
|
|
24995
|
+
await onComment(() => api.reopenComment(board_id, comment_id));
|
|
24996
|
+
if (why) await onComment(() => api.createComment(board_id, { body: why, parentId: comment_id }));
|
|
24997
|
+
return `\u2705 Reaberto ${comment_id}${why ? ` com a resposta "${oneLine(why, 120)}"` : ""}.`;
|
|
24998
|
+
})
|
|
24999
|
+
);
|
|
25000
|
+
server.registerTool(
|
|
25001
|
+
"canvas_comment",
|
|
25002
|
+
{
|
|
25003
|
+
title: "Canvas: comentar",
|
|
25004
|
+
description: "Cria um coment\xE1rio novo (raiz), ancorado para aparecer no lugar certo do Canvas. Use para deixar uma pergunta ou observa\xE7\xE3o para a pessoa. \xC2ncora: node_id (no n\xF3); node_id + output_key (numa vers\xE3o gerada); node_id + t em segundos (minutagem da Montagem ou do v\xEDdeo); x,y (ponto do board); nada = acima do conte\xFAdo do board.",
|
|
25005
|
+
inputSchema: {
|
|
25006
|
+
board_id: boardId,
|
|
25007
|
+
body,
|
|
25008
|
+
node_id: external_exports.string().min(1).max(64).optional(),
|
|
25009
|
+
output_key: external_exports.string().min(1).max(128).optional().describe("Id da vers\xE3o (resultado) do n\xF3."),
|
|
25010
|
+
t: external_exports.number().finite().min(0).optional().describe("Segundos desde o in\xEDcio."),
|
|
25011
|
+
x: external_exports.number().finite().optional(),
|
|
25012
|
+
y: external_exports.number().finite().optional(),
|
|
25013
|
+
mentions
|
|
25014
|
+
},
|
|
25015
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
25016
|
+
},
|
|
25017
|
+
async (args) => run(async () => {
|
|
25018
|
+
if (!args.node_id && (args.output_key !== void 0 || args.t !== void 0)) {
|
|
25019
|
+
throw new CanvasToolError("output_key e t precisam de node_id.");
|
|
25020
|
+
}
|
|
25021
|
+
if (args.output_key !== void 0 && args.t !== void 0) throw new CanvasToolError("Use output_key ou t, n\xE3o os dois.");
|
|
25022
|
+
if (args.x === void 0 !== (args.y === void 0)) throw new CanvasToolError("Informe x e y juntos.");
|
|
25023
|
+
const snap = await api.snapshot(args.board_id);
|
|
25024
|
+
let anchor;
|
|
25025
|
+
if (args.node_id) {
|
|
25026
|
+
if (!snap.doc.nodes[args.node_id]) {
|
|
25027
|
+
throw new CanvasToolError(`N\xF3 ${args.node_id} n\xE3o existe no board. Releia com canvas_read_board.`);
|
|
25028
|
+
}
|
|
25029
|
+
if (args.output_key !== void 0) anchor = { kind: "output", nodeId: args.node_id, outputKey: args.output_key };
|
|
25030
|
+
else if (args.t !== void 0) anchor = { kind: "timecode", nodeId: args.node_id, t: args.t };
|
|
25031
|
+
else anchor = { kind: "node", nodeId: args.node_id, dx: 0, dy: 0 };
|
|
25032
|
+
} else if (args.x !== void 0 && args.y !== void 0) {
|
|
25033
|
+
anchor = { kind: "point", x: args.x, y: args.y };
|
|
25034
|
+
} else {
|
|
25035
|
+
const nodes = Object.values(snap.doc.nodes);
|
|
25036
|
+
anchor = nodes.length ? { kind: "point", x: Math.min(...nodes.map((n) => n.position.x)), y: Math.min(...nodes.map((n) => n.position.y)) - 80 } : { kind: "point", x: 0, y: 0 };
|
|
25037
|
+
}
|
|
25038
|
+
const created = await onComment(
|
|
25039
|
+
() => api.createComment(args.board_id, {
|
|
25040
|
+
body: args.body,
|
|
25041
|
+
anchor,
|
|
25042
|
+
...args.mentions?.length ? { mentions: args.mentions } : {}
|
|
25043
|
+
})
|
|
25044
|
+
);
|
|
25045
|
+
const where = describeAnchor(anchor, snap.doc).text;
|
|
25046
|
+
const at = anchor.kind === "point" && args.x !== void 0 ? ` em (${args.x}, ${args.y})` : "";
|
|
25047
|
+
return `\u2705 Coment\xE1rio ${created?.id ?? ""} criado ${where}${at}.`.replace(" ", " ");
|
|
25048
|
+
})
|
|
25049
|
+
);
|
|
25050
|
+
}
|
|
25051
|
+
|
|
25052
|
+
// src/canvas/upload.ts
|
|
25053
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
25054
|
+
import { basename as basename2, extname as extname3 } from "path";
|
|
25055
|
+
function kindOfMime(mime) {
|
|
25056
|
+
if (mime.startsWith("image/")) return "image";
|
|
25057
|
+
if (mime.startsWith("video/")) return "video";
|
|
25058
|
+
if (mime.startsWith("audio/")) return "audio";
|
|
25059
|
+
return "file";
|
|
25060
|
+
}
|
|
25061
|
+
function withExtension(name, file) {
|
|
25062
|
+
if (!name?.trim()) return file.name;
|
|
25063
|
+
const ext = extname3(file.name);
|
|
25064
|
+
const clean = basename2(name.trim());
|
|
25065
|
+
return ext && extname3(clean).toLowerCase() !== ext.toLowerCase() ? `${clean}${ext}` : clean;
|
|
25066
|
+
}
|
|
25067
|
+
async function uploadMedia(cfg, source, name) {
|
|
25068
|
+
const remote = isRemoteRef(source);
|
|
25069
|
+
const loaded = remote ? await loadRemote(source) : await loadLocal(source);
|
|
25070
|
+
const file = { ...loaded, name: withExtension(name, loaded) };
|
|
25071
|
+
const reused = remote && new URL(source).host === BEPLUS_STORAGE_HOST;
|
|
25072
|
+
const url = reused ? source : await uploadBytes(cfg, file);
|
|
25073
|
+
const kind = kindOfMime(file.mime);
|
|
25074
|
+
let meta = null;
|
|
25075
|
+
let measuredBy = "n\xE3o medido";
|
|
25076
|
+
if (kind !== "file") {
|
|
25077
|
+
meta = probeBuffer(file.buf, file.mime);
|
|
25078
|
+
if (meta) measuredBy = "cabe\xE7alho";
|
|
25079
|
+
else {
|
|
25080
|
+
meta = await ffprobeFile(file.localPath ?? url);
|
|
25081
|
+
if (meta) measuredBy = "ffprobe";
|
|
25082
|
+
}
|
|
25083
|
+
}
|
|
25084
|
+
return {
|
|
25085
|
+
url,
|
|
25086
|
+
name: file.name,
|
|
25087
|
+
mime: file.mime,
|
|
25088
|
+
bytes: file.buf.byteLength,
|
|
25089
|
+
kind,
|
|
25090
|
+
meta: meta ?? {},
|
|
25091
|
+
measuredBy,
|
|
25092
|
+
reused,
|
|
25093
|
+
assetId: `asset_${randomUUID2()}`
|
|
25094
|
+
};
|
|
25095
|
+
}
|
|
25096
|
+
function mediaItem(u) {
|
|
25097
|
+
const item = { assetId: u.assetId, name: u.name, mime: u.mime, size: u.bytes };
|
|
25098
|
+
if (u.meta.width !== void 0) item.width = u.meta.width;
|
|
25099
|
+
if (u.meta.height !== void 0) item.height = u.meta.height;
|
|
25100
|
+
if (u.meta.duration !== void 0) item.duration = u.meta.duration;
|
|
25101
|
+
item.remoteUrl = u.url;
|
|
25102
|
+
return item;
|
|
25103
|
+
}
|
|
25104
|
+
function sequenceAsset(u) {
|
|
25105
|
+
return { assetId: u.assetId, name: u.name, mime: u.mime, size: u.bytes, origin: "imported" };
|
|
25106
|
+
}
|
|
25107
|
+
function libraryItemId(u, mediaNodeId) {
|
|
25108
|
+
return `${mediaNodeId ?? "<id do n\xF3 M\xEDdia>"}|${u.kind}::${u.url}`;
|
|
25109
|
+
}
|
|
25110
|
+
function describeUpload(u) {
|
|
25111
|
+
const parts = [u.mime, `${mb(u.bytes)} MB`];
|
|
25112
|
+
if (u.meta.width && u.meta.height) parts.push(`${u.meta.width}\xD7${u.meta.height}`);
|
|
25113
|
+
if (u.meta.duration !== void 0) parts.push(`${String(u.meta.duration).replace(".", ",")} s`);
|
|
25114
|
+
if (u.meta.fps) parts.push(`${String(u.meta.fps).replace(".", ",")} fps`);
|
|
25115
|
+
const measured = u.kind === "file" ? "" : u.measuredBy === "n\xE3o medido" ? " (dura\xE7\xE3o e dimens\xF5es n\xE3o medidas: formato sem leitor de cabe\xE7alho e sem ffprobe no PATH)" : ` (medido pelo ${u.measuredBy})`;
|
|
25116
|
+
return `"${u.name}" \xB7 ${parts.join(" \xB7 ")}${measured}`;
|
|
25117
|
+
}
|
|
25118
|
+
|
|
25119
|
+
// src/tools/canvas-media.ts
|
|
25120
|
+
var MAX_MEDIA_ITEMS = 60;
|
|
25121
|
+
var itemsOf = (node) => Array.isArray(node.data.items) ? node.data.items : [];
|
|
25122
|
+
function holdsOne(doc, node) {
|
|
25123
|
+
if (node.data.holds === "one") return true;
|
|
25124
|
+
if (node.data.holds === "many") return false;
|
|
25125
|
+
return itemsOf(node).length === 1 && Object.values(doc.edges).some((e) => e.source === node.id);
|
|
25126
|
+
}
|
|
25127
|
+
function needMediaNode(doc, nodeId) {
|
|
25128
|
+
const node = doc.nodes[nodeId];
|
|
25129
|
+
if (!node) throw new CanvasToolError(`N\xF3 ${nodeId} n\xE3o existe no board. Releia com canvas_read_board.`);
|
|
25130
|
+
if (nodeKind(node) !== "media") {
|
|
25131
|
+
throw new CanvasToolError(
|
|
25132
|
+
`O n\xF3 ${nodeId} ("${oneLine(nodeName(node), 40)}") \xE9 ${nodeKind(node) ?? node.type}, n\xE3o M\xEDdia. Passe o id de um n\xF3 media, ou omita node_id para criar um n\xF3 M\xEDdia novo.`
|
|
25133
|
+
);
|
|
25134
|
+
}
|
|
25135
|
+
return node;
|
|
25136
|
+
}
|
|
25137
|
+
function payload(u, nodeId) {
|
|
25138
|
+
const out = { url: u.url, mime: u.mime, bytes: u.bytes };
|
|
25139
|
+
if (u.meta.duration !== void 0) out.duration = u.meta.duration;
|
|
25140
|
+
if (u.meta.width !== void 0) out.width = u.meta.width;
|
|
25141
|
+
if (u.meta.height !== void 0) out.height = u.meta.height;
|
|
25142
|
+
if (u.meta.fps !== void 0) out.fps = u.meta.fps;
|
|
25143
|
+
out.media_item = mediaItem(u);
|
|
25144
|
+
if (u.kind !== "file") {
|
|
25145
|
+
out.sequence_asset = sequenceAsset(u);
|
|
25146
|
+
out.libraryItemId = libraryItemId(u, nodeId);
|
|
25147
|
+
}
|
|
25148
|
+
return JSON.stringify(out);
|
|
25149
|
+
}
|
|
25150
|
+
function sequenceHint(u, nodeId) {
|
|
25151
|
+
if (u.kind === "file") return "Documento: entra no n\xF3 M\xEDdia, n\xE3o na timeline da Montagem.";
|
|
25152
|
+
const lines = [
|
|
25153
|
+
"Num clipe da timeline da Montagem (data.timeline; data.sequence s\xF3 em n\xF3 que ainda n\xE3o migrou): use sequence_asset como `asset` e libraryItemId como est\xE1" + (nodeId ? "." : ", trocando <id do n\xF3 M\xEDdia> pelo id do n\xF3 onde o item ficou.")
|
|
25154
|
+
];
|
|
25155
|
+
if (u.meta.duration !== void 0) {
|
|
25156
|
+
const at30 = Math.floor(u.meta.duration * 30 + 1e-9);
|
|
25157
|
+
lines.push(`Quadros = dura\xE7\xE3o \xD7 fps da timeline, para baixo (ex.: ${at30} a 30 fps).`);
|
|
25158
|
+
}
|
|
25159
|
+
return lines.join(" ");
|
|
25160
|
+
}
|
|
25161
|
+
function registerCanvasMediaTools(server, deps) {
|
|
25162
|
+
const { api, cfg, run, edit, seen, placeFor } = deps;
|
|
25163
|
+
server.registerTool(
|
|
25164
|
+
"canvas_upload_media",
|
|
25165
|
+
{
|
|
25166
|
+
title: "Canvas: subir arquivo",
|
|
25167
|
+
description: "Sobe um arquivo (caminho local ou URL) pela rota de arquivos da BePlus e devolve o item pronto: url, mime, bytes, dura\xE7\xE3o/largura/altura quando \xE9 m\xEDdia, media_item (data.items do n\xF3 M\xEDdia), sequence_asset e libraryItemId (clipe da timeline da Montagem). Com board_id grava no n\xF3 M\xEDdia node_id, ou cria um n\xF3 M\xEDdia novo sem node_id; a\xED exige canvas_read_board nesta sess\xE3o. Teto de 95 MB. N\xE3o gera m\xEDdia nem gasta diamantes.",
|
|
25168
|
+
inputSchema: {
|
|
25169
|
+
source: external_exports.string().trim().min(1).max(2e3).describe("Caminho local (/\u2026, ~/\u2026, file://) ou URL http(s)."),
|
|
25170
|
+
name: external_exports.string().trim().min(1).max(120).optional().describe("Nome do arquivo no Canvas (a extens\xE3o \xE9 mantida)."),
|
|
25171
|
+
board_id: external_exports.string().uuid().optional().describe("Board onde gravar o item (opcional)."),
|
|
25172
|
+
node_id: external_exports.string().min(1).max(128).optional().describe("N\xF3 M\xEDdia que recebe o item. Sem ele, cria um n\xF3 M\xEDdia novo."),
|
|
25173
|
+
label: external_exports.string().trim().min(1).max(120).optional().describe("Nome do n\xF3 M\xEDdia novo (padr\xE3o: nome do arquivo)."),
|
|
25174
|
+
replace: external_exports.boolean().optional().describe("true troca a lista do n\xF3 por este arquivo; false acrescenta. Padr\xE3o: a regra do Canvas (n\xF3 de um arquivo s\xF3, ligado, troca).")
|
|
25175
|
+
},
|
|
25176
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true }
|
|
25177
|
+
},
|
|
25178
|
+
async (args) => run(async () => {
|
|
25179
|
+
if (!args.board_id && (args.node_id || args.label || args.replace !== void 0)) {
|
|
25180
|
+
throw new CanvasToolError("node_id, label e replace s\xF3 valem com board_id.");
|
|
25181
|
+
}
|
|
25182
|
+
if (args.board_id) {
|
|
25183
|
+
if (!seen.has(args.board_id)) {
|
|
25184
|
+
throw new CanvasToolError("Leia o board com canvas_read_board antes de gravar nele (a leitura vale para a sess\xE3o).");
|
|
25185
|
+
}
|
|
25186
|
+
const snap = await api.snapshot(args.board_id);
|
|
25187
|
+
if (snap.role === "viewer") throw new CanvasToolError("Voc\xEA \xE9 s\xF3 leitor neste board: pe\xE7a ao dono para te dar papel de editor.");
|
|
25188
|
+
if (args.node_id) {
|
|
25189
|
+
const node = needMediaNode(snap.doc, args.node_id);
|
|
25190
|
+
const replacing = args.replace ?? holdsOne(snap.doc, node);
|
|
25191
|
+
if (!replacing && itemsOf(node).length >= MAX_MEDIA_ITEMS) {
|
|
25192
|
+
throw new CanvasToolError(
|
|
25193
|
+
`O n\xF3 "${oneLine(nodeName(node), 40)}" j\xE1 tem ${MAX_MEDIA_ITEMS} arquivos (teto do Canvas). Omita node_id para criar outro n\xF3 M\xEDdia.`
|
|
25194
|
+
);
|
|
25195
|
+
}
|
|
25196
|
+
}
|
|
25197
|
+
}
|
|
25198
|
+
let u;
|
|
25199
|
+
try {
|
|
25200
|
+
u = await uploadMedia(cfg, args.source, args.name);
|
|
25201
|
+
} catch (e) {
|
|
25202
|
+
if (e instanceof ApiError && e.httpStatus !== 401) throw new CanvasToolError(e.message);
|
|
25203
|
+
throw e;
|
|
25204
|
+
}
|
|
25205
|
+
const head = `\u2705 ${u.reused ? "J\xE1 estava no armazenamento da BePlus (n\xE3o subiu de novo)" : "Subiu"}: ${describeUpload(u)}
|
|
25206
|
+
URL: ${u.url}`;
|
|
25207
|
+
if (!args.board_id) {
|
|
25208
|
+
return [head, "", payload(u), "", sequenceHint(u)].join("\n");
|
|
25209
|
+
}
|
|
25210
|
+
const boardId3 = args.board_id;
|
|
25211
|
+
let nodeId = args.node_id;
|
|
25212
|
+
let done;
|
|
25213
|
+
try {
|
|
25214
|
+
done = await edit(boardId3, async (doc) => {
|
|
25215
|
+
const item = mediaItem(u);
|
|
25216
|
+
if (nodeId) {
|
|
25217
|
+
const node = needMediaNode(doc, nodeId);
|
|
25218
|
+
const replacing = args.replace ?? holdsOne(doc, node);
|
|
25219
|
+
const items = replacing ? [item] : [...itemsOf(node), item];
|
|
25220
|
+
if (items.length > MAX_MEDIA_ITEMS) {
|
|
25221
|
+
throw new CanvasToolError(`O n\xF3 j\xE1 tem ${MAX_MEDIA_ITEMS} arquivos (teto do Canvas).`);
|
|
25222
|
+
}
|
|
25223
|
+
const before = itemsOf(node).length;
|
|
25224
|
+
return {
|
|
25225
|
+
ops: [{ type: "node.set", nodeId: node.id, path: "data.items", value: setValue(items) }],
|
|
25226
|
+
targets: [node.id],
|
|
25227
|
+
done: `N\xF3 M\xEDdia "${oneLine(nodeName(node), 40)}" (${node.id}): ` + (replacing ? `arquivo trocado (${before} \u2192 1)` : `arquivo acrescentado, agora com ${items.length}`)
|
|
25228
|
+
};
|
|
25229
|
+
}
|
|
25230
|
+
const spec = KINDS.media;
|
|
25231
|
+
const created = makeNode({
|
|
25232
|
+
type: WORKFLOW_NODE_TYPE,
|
|
25233
|
+
data: { ...spec.data, [KIND_FIELD]: "media", label: args.label ?? u.name, items: [item] },
|
|
25234
|
+
position: placeFor(doc, spec.size),
|
|
25235
|
+
size: spec.size,
|
|
25236
|
+
zIndex: Object.values(doc.nodes).reduce((t, n) => Math.max(t, n.zIndex), 0) + 1,
|
|
25237
|
+
createdBy: await api.me()
|
|
25238
|
+
});
|
|
25239
|
+
nodeId = created.id;
|
|
25240
|
+
return {
|
|
25241
|
+
ops: [{ type: "node.add", nodeId: created.id, node: created }],
|
|
25242
|
+
targets: [],
|
|
25243
|
+
done: `N\xF3 M\xEDdia "${oneLine(nodeName(created), 40)}" criado: ${created.id}`
|
|
25244
|
+
};
|
|
25245
|
+
});
|
|
25246
|
+
} catch (e) {
|
|
25247
|
+
const why = e instanceof CanvasToolError ? e.message : apiErrorToUserMessage(e);
|
|
25248
|
+
throw new CanvasToolError(
|
|
25249
|
+
`${head}
|
|
25250
|
+
Mas o item N\xC3O entrou no board: ${why}
|
|
25251
|
+
N\xE3o suba de novo: releia com canvas_read_board e grave media_item em data.items do n\xF3 M\xEDdia (canvas_update_node com a lista inteira) ou em um n\xF3 novo.
|
|
25252
|
+
${payload(u)}`
|
|
25253
|
+
);
|
|
25254
|
+
}
|
|
25255
|
+
return [head, done, "", payload(u, nodeId), "", sequenceHint(u, nodeId)].join("\n");
|
|
25256
|
+
})
|
|
25257
|
+
);
|
|
25258
|
+
}
|
|
25259
|
+
|
|
24070
25260
|
// src/tools/canvas.ts
|
|
24071
25261
|
var REJECT_TEXT = {
|
|
24072
25262
|
"node-missing": "o n\xF3 n\xE3o existe mais (algu\xE9m apagou)",
|
|
@@ -24074,11 +25264,25 @@ var REJECT_TEXT = {
|
|
|
24074
25264
|
"invalid-op": "opera\xE7\xE3o inv\xE1lida ou repetida",
|
|
24075
25265
|
"too-large": "opera\xE7\xE3o grande demais (64 KB) ou com m\xEDdia embutida"
|
|
24076
25266
|
};
|
|
25267
|
+
var READ = "Exige canvas_read_board nesta sess\xE3o (e de novo depois de uma recusa). ";
|
|
25268
|
+
var MONTAGE_NOTE = "Montagem: musicGainDb, duckingDb e fadeMs valem s\xF3 para a montagem autom\xE1tica (clipes ligados) e n\xE3o mexem na timeline do editor (data.timeline; data.sequence \xE9 o legado); o volume dela fica nos clipes (gainDb, gainKeyframes, fades) e nas faixas (gainDb de cada faixa, master).";
|
|
25269
|
+
function dataSegments(path) {
|
|
25270
|
+
const p = path?.trim() ?? "";
|
|
25271
|
+
if (!p || p === "data") return [];
|
|
25272
|
+
const segs = (p.startsWith("data.") ? p.slice(5) : p).split(".");
|
|
25273
|
+
if (segs.some((seg) => !seg)) throw new CanvasToolError(`Caminho "${p}" tem segmento vazio (dois pontos seguidos ou ponto na ponta).`);
|
|
25274
|
+
return segs;
|
|
25275
|
+
}
|
|
25276
|
+
function legacySequenceGuard(node, key) {
|
|
25277
|
+
if (key === "sequence" && nodeKind(node) === "montage" && node.data.timeline !== void 0) {
|
|
25278
|
+
throw new CanvasToolError(
|
|
25279
|
+
"Este n\xF3 Montagem j\xE1 grava em data.timeline; data.sequence \xE9 o legado congelado e n\xE3o se escreve mais. Leia a timeline com canvas_read_node e grave por caminho em data.timeline com canvas_patch_node."
|
|
25280
|
+
);
|
|
25281
|
+
}
|
|
25282
|
+
}
|
|
24077
25283
|
var SECTION_Z = -1e3;
|
|
24078
25284
|
var GAP = 80;
|
|
24079
|
-
var
|
|
24080
|
-
};
|
|
24081
|
-
var boardId = external_exports.string().uuid().describe("Id (uuid) do board, como sai em canvas_list_boards.");
|
|
25285
|
+
var boardId2 = external_exports.string().uuid().describe("Id (uuid) do board, como sai em canvas_list_boards.");
|
|
24082
25286
|
var nodeIdArg = external_exports.string().min(1).max(128);
|
|
24083
25287
|
var point = external_exports.object({ x: external_exports.number().finite(), y: external_exports.number().finite() });
|
|
24084
25288
|
function registerCanvasTools(server, client, cfg) {
|
|
@@ -24086,10 +25290,9 @@ function registerCanvasTools(server, client, cfg) {
|
|
|
24086
25290
|
const seen = /* @__PURE__ */ new Map();
|
|
24087
25291
|
function fail(e) {
|
|
24088
25292
|
if (e instanceof CanvasToolError || e instanceof CoreMismatchError) return errorResult(e.message);
|
|
25293
|
+
if (e instanceof LoginExpiredError) return errorResult(e.message);
|
|
24089
25294
|
if (e instanceof ApiError && e.httpStatus === 401 && !api.usesPat) {
|
|
24090
|
-
return errorResult(
|
|
24091
|
-
"O acesso pelo navegador expirou ou foi revogado. Rode `beplus-mcp login` de novo e autorize."
|
|
24092
|
-
);
|
|
25295
|
+
return errorResult(`O servidor recusou o acesso pelo navegador (${e.message}). Rode \`beplus-mcp login\` de novo e autorize.`);
|
|
24093
25296
|
}
|
|
24094
25297
|
if (e instanceof ApiError && e.httpStatus === 404) {
|
|
24095
25298
|
return errorResult("Board n\xE3o encontrado, ou voc\xEA n\xE3o \xE9 membro dele. Confira o id em canvas_list_boards.");
|
|
@@ -24103,7 +25306,7 @@ function registerCanvasTools(server, client, cfg) {
|
|
|
24103
25306
|
return fail(e);
|
|
24104
25307
|
}
|
|
24105
25308
|
}
|
|
24106
|
-
async function edit(id, build) {
|
|
25309
|
+
async function edit(id, build, opts = {}) {
|
|
24107
25310
|
const last = seen.get(id);
|
|
24108
25311
|
if (last === void 0) {
|
|
24109
25312
|
throw new CanvasToolError("Leia o board com canvas_read_board antes de editar (a leitura vale para a sess\xE3o).");
|
|
@@ -24134,6 +25337,7 @@ function registerCanvasTools(server, client, cfg) {
|
|
|
24134
25337
|
if (theirs.length) note = `
|
|
24135
25338
|
Aviso: ${changesSince(theirs, doc)}.`;
|
|
24136
25339
|
}
|
|
25340
|
+
if (opts.split) return commitSplit(id, ops, done, note);
|
|
24137
25341
|
const env = envelope(id, batchOf(ops), await api.me());
|
|
24138
25342
|
const bad = checkEnvelope(env);
|
|
24139
25343
|
if (bad) throw new CanvasToolError(`Edi\xE7\xE3o recusada antes de enviar: ${bad}.`);
|
|
@@ -24147,6 +25351,50 @@ Aviso: ${changesSince(theirs, doc)}.`;
|
|
|
24147
25351
|
seen.set(id, res.seq);
|
|
24148
25352
|
return `\u2705 ${done} (seq ${res.seq}).${note}`;
|
|
24149
25353
|
}
|
|
25354
|
+
async function commitSplit(id, ops, done, note) {
|
|
25355
|
+
let envs;
|
|
25356
|
+
try {
|
|
25357
|
+
envs = packEnvelopes(id, ops, await api.me());
|
|
25358
|
+
} catch (e) {
|
|
25359
|
+
if (!(e instanceof OpTooLargeError)) throw e;
|
|
25360
|
+
const path = e.op.type === "node.set" ? e.op.path.replace(/^data\./, "") : e.op.type;
|
|
25361
|
+
throw new CanvasToolError(
|
|
25362
|
+
`O valor de ${path} tem ${Math.round(e.bytes / 1024)} KB e n\xE3o cabe num envelope (64 KB). Nada foi enviado: grave por partes menores (um caminho por item, ex.: <cole\xE7\xE3o>.<id>).`
|
|
25363
|
+
);
|
|
25364
|
+
}
|
|
25365
|
+
for (const env of envs) {
|
|
25366
|
+
const bad = checkEnvelope(env);
|
|
25367
|
+
if (bad) throw new CanvasToolError(`Edi\xE7\xE3o recusada antes de enviar: ${bad}. Nada foi enviado.`);
|
|
25368
|
+
}
|
|
25369
|
+
const outcomes = /* @__PURE__ */ new Map();
|
|
25370
|
+
let last = null;
|
|
25371
|
+
for (let i = 0; i < envs.length; i += MAX_ENVELOPES_PER_COMMIT) {
|
|
25372
|
+
const res = await api.commit(id, envs.slice(i, i + MAX_ENVELOPES_PER_COMMIT));
|
|
25373
|
+
for (const o of res.outcomes) outcomes.set(o.opId, o);
|
|
25374
|
+
last = res.seq;
|
|
25375
|
+
}
|
|
25376
|
+
const pathsOf = (op) => op.type === "batch" ? op.ops.flatMap(pathsOf) : op.type === "node.set" ? [op.path.replace(/^data\./, "")] : [op.type];
|
|
25377
|
+
let failed = 0;
|
|
25378
|
+
const lines = envs.map((env, i) => {
|
|
25379
|
+
const paths = pathsOf(env.op);
|
|
25380
|
+
const span = paths.length > 1 ? `${paths[0]} \u2026 ${paths[paths.length - 1]}` : paths[0];
|
|
25381
|
+
const kb = (Buffer.byteLength(JSON.stringify(env)) / 1024).toFixed(1).replace(".", ",");
|
|
25382
|
+
const o = outcomes.get(env.id);
|
|
25383
|
+
const result = o && "seq" in o ? `seq ${o.seq}` : (failed++, `RECUSADO (${o && "rejected" in o ? REJECT_TEXT[o.rejected] ?? o.rejected : "sem resposta do servidor"}): nada deste envelope entrou`);
|
|
25384
|
+
return `- envelope ${i + 1}/${envs.length}: ${paths.length} caminho(s) (${span}), ${kb} KB \u2192 ${result}`;
|
|
25385
|
+
});
|
|
25386
|
+
if (failed) {
|
|
25387
|
+
seen.delete(id);
|
|
25388
|
+
throw new CanvasToolError(
|
|
25389
|
+
`${done}: ${envs.length - failed} de ${envs.length} envelope(s) entraram, ${failed} recusado(s).
|
|
25390
|
+
${lines.join("\n")}
|
|
25391
|
+
Os aceitos ficam. Releia com canvas_read_board e canvas_read_node e reenvie s\xF3 os caminhos dos envelopes recusados.` + note
|
|
25392
|
+
);
|
|
25393
|
+
}
|
|
25394
|
+
if (last !== null) seen.set(id, last);
|
|
25395
|
+
return `\u2705 ${done} em ${envs.length} envelope(s) (seq at\xE9 ${last}).
|
|
25396
|
+
${lines.join("\n")}${note}`;
|
|
25397
|
+
}
|
|
24150
25398
|
function needNode(doc, nodeId) {
|
|
24151
25399
|
const node = doc.nodes[nodeId];
|
|
24152
25400
|
if (!node) throw new CanvasToolError(`N\xF3 ${nodeId} n\xE3o existe no board. Releia com canvas_read_board.`);
|
|
@@ -24220,10 +25468,10 @@ Aviso: ${changesSince(theirs, doc)}.`;
|
|
|
24220
25468
|
"canvas_read_board",
|
|
24221
25469
|
{
|
|
24222
25470
|
title: "Canvas: ler board",
|
|
24223
|
-
description: "L\xEA um board: n\xF3s (id, tipo, nome, campos principais), liga\xE7\xF5es e v\xEDnculo com o IA Lab, sem m\xEDdia. Obrigat\xF3rio antes de editar (vale para a sess\xE3o). node_ids devolve o data
|
|
25471
|
+
description: "L\xEA um board: n\xF3s (id, tipo, nome, campos principais), liga\xE7\xF5es e v\xEDnculo com o IA Lab, sem m\xEDdia. Obrigat\xF3rio antes de editar (vale para a sess\xE3o). node_ids devolve o data desses n\xF3s, com cada corte marcado (path=\u2026); o valor inteiro (ex.: data.sequence da Montagem) sai no canvas_read_node.",
|
|
24224
25472
|
inputSchema: {
|
|
24225
|
-
board_id:
|
|
24226
|
-
node_ids: external_exports.array(nodeIdArg).max(20).optional().describe("N\xF3s para ver o data
|
|
25473
|
+
board_id: boardId2,
|
|
25474
|
+
node_ids: external_exports.array(nodeIdArg).max(20).optional().describe("N\xF3s para ver o data (sem blobs, cortes marcados).")
|
|
24227
25475
|
},
|
|
24228
25476
|
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
24229
25477
|
},
|
|
@@ -24238,6 +25486,61 @@ Aviso: ${changesSince(theirs, doc)}.`;
|
|
|
24238
25486
|
return parts.join("\n");
|
|
24239
25487
|
})
|
|
24240
25488
|
);
|
|
25489
|
+
server.registerTool(
|
|
25490
|
+
"canvas_read_node",
|
|
25491
|
+
{
|
|
25492
|
+
title: "Canvas: ler n\xF3 inteiro",
|
|
25493
|
+
description: 'Devolve o data de UM n\xF3 sem corte nenhum, em JSON compacto, para conferir e fazer diff. Na Montagem, sem path, vem a timeline do editor: data.timeline, ou data.sequence (legado) quando o n\xF3 ainda n\xE3o tem timeline, e o cabe\xE7alho diz qual veio. path escolhe um peda\xE7o ("items" da M\xEDdia, "timeline.meta"); "data" traz o data todo. Diz o tamanho total e o sha256; acima de max_chars vem em partes expl\xEDcitas (offset). N\xE3o substitui o canvas_read_board, que continua obrigat\xF3rio antes de editar. ' + MONTAGE_NOTE,
|
|
25494
|
+
inputSchema: {
|
|
25495
|
+
board_id: boardId2,
|
|
25496
|
+
node_id: nodeIdArg,
|
|
25497
|
+
path: external_exports.string().trim().max(200).optional().describe('Caminho dentro do data, com pontos (ex.: "timeline.meta", "items.0"). "data" = o data todo.'),
|
|
25498
|
+
offset: external_exports.number().int().min(0).optional().describe("In\xEDcio da parte, em caracteres (padr\xE3o 0)."),
|
|
25499
|
+
max_chars: external_exports.number().int().min(1e3).max(6e4).optional().describe("Tamanho da parte (padr\xE3o 40000).")
|
|
25500
|
+
},
|
|
25501
|
+
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
25502
|
+
},
|
|
25503
|
+
async ({ board_id, node_id, path, offset, max_chars }) => run(async () => {
|
|
25504
|
+
const snap = await api.snapshot(board_id);
|
|
25505
|
+
const node = snap.doc.nodes[node_id];
|
|
25506
|
+
if (!node) throw new CanvasToolError(`N\xF3 ${node_id} n\xE3o existe no board. Releia com canvas_read_board.`);
|
|
25507
|
+
let value = node.data;
|
|
25508
|
+
let segments = dataSegments(path);
|
|
25509
|
+
let which = "";
|
|
25510
|
+
if (!path?.trim() && nodeKind(node) === "montage") {
|
|
25511
|
+
if (node.data.timeline !== void 0) {
|
|
25512
|
+
segments = ["timeline"];
|
|
25513
|
+
which = " (a timeline do editor, formato v3)";
|
|
25514
|
+
} else if (node.data.sequence !== void 0) {
|
|
25515
|
+
segments = ["sequence"];
|
|
25516
|
+
which = " (legado: este n\xF3 ainda n\xE3o tem data.timeline)";
|
|
25517
|
+
} else which = " (sem timeline nem sequence: o data todo)";
|
|
25518
|
+
} else if (segments[0] === "sequence" && nodeKind(node) === "montage" && node.data.timeline !== void 0) {
|
|
25519
|
+
which = " (LEGADO congelado: o editor l\xEA data.timeline)";
|
|
25520
|
+
}
|
|
25521
|
+
for (const [i, seg] of segments.entries()) {
|
|
25522
|
+
const here = value;
|
|
25523
|
+
value = Array.isArray(here) ? here[Number(seg)] : here && typeof here === "object" ? here[seg] : void 0;
|
|
25524
|
+
if (value === void 0) {
|
|
25525
|
+
const at = segments.slice(0, i).join(".");
|
|
25526
|
+
const keys = Array.isArray(here) ? `\xEDndices 0 a ${here.length - 1}` : here && typeof here === "object" ? Object.keys(here).join(", ") : "\u2014";
|
|
25527
|
+
throw new CanvasToolError(`"${seg}" n\xE3o existe em data${at ? `.${at}` : ""}. Existe: ${keys || "\u2014"}.`);
|
|
25528
|
+
}
|
|
25529
|
+
}
|
|
25530
|
+
const json2 = JSON.stringify(value);
|
|
25531
|
+
const total = json2.length;
|
|
25532
|
+
const from = Math.min(offset ?? 0, total);
|
|
25533
|
+
const size = max_chars ?? 4e4;
|
|
25534
|
+
const to = Math.min(from + size, total);
|
|
25535
|
+
const hash = createHash("sha256").update(json2).digest("hex").slice(0, 12);
|
|
25536
|
+
const where = `data${segments.length ? `.${segments.join(".")}` : ""}`;
|
|
25537
|
+
const head = `${node.id} \xB7 ${nodeKind(node) ?? node.type} \xB7 "${oneLine(nodeName(node), 60)}" \xB7 board seq ${snap.seq} \xB7 ${where}${which}: ${total} caracteres (JSON compacto) \xB7 sha256 ${hash}`;
|
|
25538
|
+
const part = from === 0 && to === total ? "Inteiro, abaixo." : `Parte: caracteres ${from} a ${to} de ${total}. ${to < total ? `Falta o resto: chame de novo com offset=${to}.` : "Esta \xE9 a \xFAltima parte."}`;
|
|
25539
|
+
return `${head}
|
|
25540
|
+
${part}
|
|
25541
|
+
${json2.slice(from, to)}`;
|
|
25542
|
+
})
|
|
25543
|
+
);
|
|
24241
25544
|
server.registerTool(
|
|
24242
25545
|
"canvas_create_board",
|
|
24243
25546
|
{
|
|
@@ -24292,9 +25595,9 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24292
25595
|
"canvas_add_node",
|
|
24293
25596
|
{
|
|
24294
25597
|
title: "Canvas: adicionar n\xF3",
|
|
24295
|
-
description: `Adiciona um n\xF3 (n\xE3o executa). kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board. inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo
|
|
25598
|
+
description: `Adiciona um n\xF3 (n\xE3o executa). ${READ}kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board. inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo. ` + MONTAGE_NOTE,
|
|
24296
25599
|
inputSchema: {
|
|
24297
|
-
board_id:
|
|
25600
|
+
board_id: boardId2,
|
|
24298
25601
|
kind: external_exports.string().min(1).max(40),
|
|
24299
25602
|
label: external_exports.string().trim().min(1).max(120).optional().describe("Nome do cart\xE3o (data.label)."),
|
|
24300
25603
|
data: external_exports.record(external_exports.unknown()).optional().describe("Campos do data. Ex.: narration {blocks:[{id,text}]}, text {text}, prompt {template}."),
|
|
@@ -24340,9 +25643,9 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24340
25643
|
"canvas_update_node",
|
|
24341
25644
|
{
|
|
24342
25645
|
title: "Canvas: editar n\xF3",
|
|
24343
|
-
description:
|
|
25646
|
+
description: `Muda campos do data de um n\xF3, chave a chave (null apaga a chave), sem executar. ${READ}label renomeia. N\xE3o troca o tipo. Cada chave \xE9 gravada inteira: leia antes com canvas_read_node e mande o valor completo j\xE1 revisado, para n\xE3o apagar o que outra pessoa escreveu. Para mudar partes de uma estrutura grande (clipes da timeline), use canvas_patch_node, por caminho. ` + MONTAGE_NOTE,
|
|
24344
25647
|
inputSchema: {
|
|
24345
|
-
board_id:
|
|
25648
|
+
board_id: boardId2,
|
|
24346
25649
|
node_id: nodeIdArg,
|
|
24347
25650
|
data: external_exports.record(external_exports.unknown()).optional().describe("Chaves de data a gravar. Valor null apaga a chave."),
|
|
24348
25651
|
label: external_exports.string().trim().min(1).max(120).optional(),
|
|
@@ -24355,6 +25658,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24355
25658
|
const node = needNode(doc, args.node_id);
|
|
24356
25659
|
const ops = [];
|
|
24357
25660
|
const patch = parseData(args.data);
|
|
25661
|
+
for (const key of Object.keys(patch)) legacySequenceGuard(node, key);
|
|
24358
25662
|
if (args.label) patch.label = args.label;
|
|
24359
25663
|
for (const [k, v] of Object.entries(patch)) {
|
|
24360
25664
|
const path = `data.${k}`;
|
|
@@ -24373,13 +25677,104 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24373
25677
|
})
|
|
24374
25678
|
)
|
|
24375
25679
|
);
|
|
25680
|
+
server.registerTool(
|
|
25681
|
+
"canvas_patch_node",
|
|
25682
|
+
{
|
|
25683
|
+
title: "Canvas: gravar por caminho",
|
|
25684
|
+
description: `Grava v\xE1rios caminhos dentro do data de um n\xF3, sem executar: {path, value} grava, {path, unset: true} apaga. ${READ}O caminho atravessa objetos (o n\xEDvel que falta \xE9 criado) e n\xE3o entra em lista: para mudar um item de lista, grave a lista inteira. Quebra sozinho em envelopes de at\xE9 64 KB, em ordem, e devolve o resultado de cada um; entre envelopes n\xE3o h\xE1 atomicidade (o que entrou fica). Serve para mexer em partes de uma estrutura grande, como clipes da timeline da Montagem, sem reenviar tudo. Leia antes com canvas_read_node. ` + MONTAGE_NOTE,
|
|
25685
|
+
inputSchema: {
|
|
25686
|
+
board_id: boardId2,
|
|
25687
|
+
node_id: nodeIdArg,
|
|
25688
|
+
sets: external_exports.array(
|
|
25689
|
+
external_exports.object({
|
|
25690
|
+
path: external_exports.string().trim().min(1).max(500).describe('Caminho dentro do data (ex.: "timeline.meta.fps"); aceita o prefixo "data.".'),
|
|
25691
|
+
value: external_exports.unknown().optional().describe("Valor JSON a gravar (null grava null)."),
|
|
25692
|
+
unset: external_exports.literal(true).optional().describe("true apaga a chave.")
|
|
25693
|
+
})
|
|
25694
|
+
).min(1).max(5e3)
|
|
25695
|
+
},
|
|
25696
|
+
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
|
|
25697
|
+
},
|
|
25698
|
+
async (args) => run(
|
|
25699
|
+
() => edit(
|
|
25700
|
+
args.board_id,
|
|
25701
|
+
async (doc) => {
|
|
25702
|
+
const node = needNode(doc, args.node_id);
|
|
25703
|
+
const work = structuredClone(node.data);
|
|
25704
|
+
const ops = [];
|
|
25705
|
+
let same = 0;
|
|
25706
|
+
let absent = 0;
|
|
25707
|
+
for (const [i, item] of args.sets.entries()) {
|
|
25708
|
+
const at = `sets[${i}] (${item.path})`;
|
|
25709
|
+
const segs = dataSegments(item.path);
|
|
25710
|
+
if (!segs.length) throw new CanvasToolError(`${at}: informe um caminho dentro do data, n\xE3o o data inteiro.`);
|
|
25711
|
+
if (segs[0] === KIND_FIELD) throw new CanvasToolError(`${at}: data.kind n\xE3o muda (apague o n\xF3 e crie outro do tipo certo).`);
|
|
25712
|
+
legacySequenceGuard(node, segs[0]);
|
|
25713
|
+
const path = `data.${segs.join(".")}`;
|
|
25714
|
+
const badPath = checkNodePath(path);
|
|
25715
|
+
if (badPath) throw new CanvasToolError(`${at}: ${badPath}.`);
|
|
25716
|
+
const unset = item.unset === true;
|
|
25717
|
+
const hasValue = item.value !== void 0;
|
|
25718
|
+
if (unset === hasValue) throw new CanvasToolError(`${at}: mande value OU unset: true.`);
|
|
25719
|
+
if (hasValue && !isJson(item.value)) throw new CanvasToolError(`${at}: value n\xE3o \xE9 JSON v\xE1lido.`);
|
|
25720
|
+
let cur = work;
|
|
25721
|
+
for (const [j, seg] of segs.slice(0, -1).entries()) {
|
|
25722
|
+
const next = Object.hasOwn(cur, seg) ? cur[seg] : void 0;
|
|
25723
|
+
const isObject2 = !!next && typeof next === "object" && !Array.isArray(next);
|
|
25724
|
+
if (isObject2) {
|
|
25725
|
+
cur = next;
|
|
25726
|
+
continue;
|
|
25727
|
+
}
|
|
25728
|
+
if (unset) {
|
|
25729
|
+
cur = null;
|
|
25730
|
+
break;
|
|
25731
|
+
}
|
|
25732
|
+
if (next === void 0) {
|
|
25733
|
+
const created = {};
|
|
25734
|
+
cur[seg] = created;
|
|
25735
|
+
cur = created;
|
|
25736
|
+
continue;
|
|
25737
|
+
}
|
|
25738
|
+
throw new CanvasToolError(
|
|
25739
|
+
`${at}: data.${segs.slice(0, j + 1).join(".")} \xE9 ${Array.isArray(next) ? "uma lista" : "um valor simples"}, e o caminho n\xE3o entra nele. Grave o n\xEDvel de cima inteiro.`
|
|
25740
|
+
);
|
|
25741
|
+
}
|
|
25742
|
+
const leaf = segs[segs.length - 1];
|
|
25743
|
+
if (unset) {
|
|
25744
|
+
if (!cur || !Object.hasOwn(cur, leaf)) {
|
|
25745
|
+
absent++;
|
|
25746
|
+
continue;
|
|
25747
|
+
}
|
|
25748
|
+
delete cur[leaf];
|
|
25749
|
+
ops.push({ type: "node.set", nodeId: node.id, path, value: unsetValue() });
|
|
25750
|
+
continue;
|
|
25751
|
+
}
|
|
25752
|
+
const value = item.value;
|
|
25753
|
+
if (cur && Object.hasOwn(cur, leaf) && JSON.stringify(cur[leaf]) === JSON.stringify(value)) {
|
|
25754
|
+
same++;
|
|
25755
|
+
continue;
|
|
25756
|
+
}
|
|
25757
|
+
if (cur) cur[leaf] = value;
|
|
25758
|
+
ops.push({ type: "node.set", nodeId: node.id, path, value: setValue(value) });
|
|
25759
|
+
}
|
|
25760
|
+
const skipped = [same ? `${same} igual(is) ao que j\xE1 estava` : "", absent ? `${absent} unset de caminho que n\xE3o existe` : ""].filter(Boolean).join(", ");
|
|
25761
|
+
return {
|
|
25762
|
+
ops,
|
|
25763
|
+
targets: [node.id],
|
|
25764
|
+
done: `N\xF3 "${oneLine(nodeName(node), 40)}" (${node.id}): ${ops.length} caminho(s) gravado(s)` + (skipped ? ` (ignorados: ${skipped})` : "")
|
|
25765
|
+
};
|
|
25766
|
+
},
|
|
25767
|
+
{ split: true }
|
|
25768
|
+
)
|
|
25769
|
+
)
|
|
25770
|
+
);
|
|
24376
25771
|
server.registerTool(
|
|
24377
25772
|
"canvas_connect",
|
|
24378
25773
|
{
|
|
24379
25774
|
title: "Canvas: ligar portas",
|
|
24380
|
-
description:
|
|
25775
|
+
description: `Liga a sa\xEDda de um n\xF3 \xE0 entrada de outro (ids e portas de canvas_read_board). ${READ}Liga\xE7\xE3o repetida \xE9 ignorada.`,
|
|
24381
25776
|
inputSchema: {
|
|
24382
|
-
board_id:
|
|
25777
|
+
board_id: boardId2,
|
|
24383
25778
|
source: nodeIdArg,
|
|
24384
25779
|
source_port: external_exports.string().min(1).max(80),
|
|
24385
25780
|
target: nodeIdArg,
|
|
@@ -24404,9 +25799,9 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24404
25799
|
"canvas_delete",
|
|
24405
25800
|
{
|
|
24406
25801
|
title: "Canvas: apagar n\xF3s/liga\xE7\xF5es",
|
|
24407
|
-
description:
|
|
25802
|
+
description: `Apaga n\xF3s (com as liga\xE7\xF5es e varia\xE7\xF5es deles) e/ou liga\xE7\xF5es, num passo s\xF3. Irrevers\xEDvel pelo MCP: confirme com o usu\xE1rio antes. ${READ}N\xE3o apaga o board.`,
|
|
24408
25803
|
inputSchema: {
|
|
24409
|
-
board_id:
|
|
25804
|
+
board_id: boardId2,
|
|
24410
25805
|
node_ids: external_exports.array(nodeIdArg).max(200).optional(),
|
|
24411
25806
|
edge_ids: external_exports.array(nodeIdArg).max(200).optional()
|
|
24412
25807
|
},
|
|
@@ -24449,8 +25844,8 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24449
25844
|
"canvas_rename_board",
|
|
24450
25845
|
{
|
|
24451
25846
|
title: "Canvas: renomear board",
|
|
24452
|
-
description:
|
|
24453
|
-
inputSchema: { board_id:
|
|
25847
|
+
description: `Troca o t\xEDtulo do board (board.set). ${READ}Precisa de papel de editor ou dono.`,
|
|
25848
|
+
inputSchema: { board_id: boardId2, title: external_exports.string().trim().min(1).max(200) },
|
|
24454
25849
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
24455
25850
|
},
|
|
24456
25851
|
async ({ board_id, title }) => run(
|
|
@@ -24466,7 +25861,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24466
25861
|
{
|
|
24467
25862
|
title: "Canvas: membros do board",
|
|
24468
25863
|
description: "Lista quem tem acesso ao board (userId, nome, papel). S\xF3 leitura.",
|
|
24469
|
-
inputSchema: { board_id:
|
|
25864
|
+
inputSchema: { board_id: boardId2 },
|
|
24470
25865
|
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
24471
25866
|
},
|
|
24472
25867
|
async ({ board_id }) => run(async () => {
|
|
@@ -24483,7 +25878,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24483
25878
|
title: "Canvas: adicionar membro",
|
|
24484
25879
|
description: "D\xE1 acesso ao board (ou troca o papel) para um usu\xE1rio pelo userId (uuid). S\xF3 o dono pode. Ainda n\xE3o h\xE1 busca por e-mail: pe\xE7a o userId ou copie de canvas_list_members de outro board.",
|
|
24485
25880
|
inputSchema: {
|
|
24486
|
-
board_id:
|
|
25881
|
+
board_id: boardId2,
|
|
24487
25882
|
user_id: external_exports.string().uuid(),
|
|
24488
25883
|
role: external_exports.enum(["editor", "viewer"]).describe("editor edita; viewer s\xF3 v\xEA.")
|
|
24489
25884
|
},
|
|
@@ -24499,7 +25894,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24499
25894
|
{
|
|
24500
25895
|
title: "Canvas: remover membro",
|
|
24501
25896
|
description: "Tira o acesso de algu\xE9m ao board (o dono tira qualquer um; quem n\xE3o \xE9 dono s\xF3 sai sozinho). O dono n\xE3o sai.",
|
|
24502
|
-
inputSchema: { board_id:
|
|
25897
|
+
inputSchema: { board_id: boardId2, user_id: external_exports.string().uuid() },
|
|
24503
25898
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
|
|
24504
25899
|
},
|
|
24505
25900
|
async ({ board_id, user_id }) => run(async () => {
|
|
@@ -24507,13 +25902,15 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
24507
25902
|
return `\u2705 ${user_id} n\xE3o tem mais acesso ao board.`;
|
|
24508
25903
|
})
|
|
24509
25904
|
);
|
|
25905
|
+
registerCanvasCommentTools(server, api, run);
|
|
25906
|
+
registerCanvasMediaTools(server, { api, cfg, run, edit, seen, placeFor });
|
|
24510
25907
|
}
|
|
24511
25908
|
|
|
24512
25909
|
// src/version.ts
|
|
24513
25910
|
import { createRequire } from "module";
|
|
24514
25911
|
var require2 = createRequire(import.meta.url);
|
|
24515
25912
|
function readVersion() {
|
|
24516
|
-
if ("0.
|
|
25913
|
+
if ("0.28.0") return "0.28.0";
|
|
24517
25914
|
try {
|
|
24518
25915
|
const pkg = require2("../package.json");
|
|
24519
25916
|
return pkg.version ?? "0.0.0-unknown";
|
|
@@ -24528,7 +25925,8 @@ var SERVER_INSTRUCTIONS = [
|
|
|
24528
25925
|
"BePlus: tudo roda pela conta do usu\xE1rio (diamantes, limites e hist\xF3rico na plataforma).",
|
|
24529
25926
|
'M\xEDdia: generate_* gasta diamantes; confira com estimate_cost antes de lotes grandes. Sem project, a gera\xE7\xE3o cai no projeto ativo; billing:"personal" cobra do usu\xE1rio.',
|
|
24530
25927
|
"Calls: search_calls acha, get_call traz a transcri\xE7\xE3o.",
|
|
24531
|
-
"Canvas online (canvas_*): leia com canvas_read_board antes de editar e siga o estado lido. Cada edi\xE7\xE3o vai num passo s\xF3; se outra pessoa mexeu nos mesmos n\xF3s, a ferramenta recusa e pede releitura. As ferramentas canvas_* n\xE3o geram m\xEDdia nem gastam diamantes: quem roda os n\xF3s \xE9 o usu\xE1rio no Canvas. D\xEA nome (label) aos n\xF3s, n\xE3o invente tipos nem portas, e confirme antes de canvas_delete."
|
|
25928
|
+
"Canvas online (canvas_*): leia com canvas_read_board antes de editar e siga o estado lido. Cada edi\xE7\xE3o vai num passo s\xF3; se outra pessoa mexeu nos mesmos n\xF3s, a ferramenta recusa e pede releitura. As ferramentas canvas_* n\xE3o geram m\xEDdia nem gastam diamantes: quem roda os n\xF3s \xE9 o usu\xE1rio no Canvas. D\xEA nome (label) aos n\xF3s, n\xE3o invente tipos nem portas, e confirme antes de canvas_delete.",
|
|
25929
|
+
'"Aplica os coment\xE1rios" do board: canvas_list_comments (abertos) \u2192 para cada um, leia o n\xF3 ancorado com canvas_read_board (node_ids), aplique a edi\xE7\xE3o pelas canvas_* e feche com canvas_resolve_comment dizendo em uma frase o que fez. Coment\xE1rio amb\xEDguo ou com alvo sumido: responda com pergunta (canvas_reply_comment) e n\xE3o resolva. D\xFAvida sua sobre um n\xF3: canvas_comment ancorado nele. As escritas j\xE1 saem espa\xE7adas (60/min); se ainda vier limite, pare e diga de onde seguir.'
|
|
24532
25930
|
].join("\n");
|
|
24533
25931
|
function buildServer(cfg) {
|
|
24534
25932
|
const server = new McpServer({ name: "beplus", version: VERSION }, { instructions: SERVER_INSTRUCTIONS });
|
|
@@ -24569,8 +25967,8 @@ function assertSupportedNode() {
|
|
|
24569
25967
|
|
|
24570
25968
|
// src/doctor.ts
|
|
24571
25969
|
import { readFileSync } from "fs";
|
|
24572
|
-
import { homedir as
|
|
24573
|
-
import { join } from "path";
|
|
25970
|
+
import { homedir as homedir4 } from "os";
|
|
25971
|
+
import { join as join2 } from "path";
|
|
24574
25972
|
var LABEL = { ok: "[ok] ", aviso: "[aviso]", erro: "[erro] " };
|
|
24575
25973
|
var Report = class {
|
|
24576
25974
|
failed = false;
|
|
@@ -24590,27 +25988,27 @@ function maskToken(token) {
|
|
|
24590
25988
|
return `${token.slice(0, 4)}...${token.slice(-4)}`;
|
|
24591
25989
|
}
|
|
24592
25990
|
function configCandidates() {
|
|
24593
|
-
const home =
|
|
25991
|
+
const home = homedir4();
|
|
24594
25992
|
const cwd = process.cwd();
|
|
24595
25993
|
const list = [
|
|
24596
|
-
{ path:
|
|
24597
|
-
{ path:
|
|
24598
|
-
{ path:
|
|
24599
|
-
{ path:
|
|
25994
|
+
{ path: join2(home, ".claude.json"), client: "Claude Code (global)" },
|
|
25995
|
+
{ path: join2(cwd, ".mcp.json"), client: "Claude Code (projeto)" },
|
|
25996
|
+
{ path: join2(home, ".cursor", "mcp.json"), client: "Cursor (global)" },
|
|
25997
|
+
{ path: join2(cwd, ".cursor", "mcp.json"), client: "Cursor (projeto)" }
|
|
24600
25998
|
];
|
|
24601
25999
|
if (process.platform === "darwin") {
|
|
24602
26000
|
list.push({
|
|
24603
|
-
path:
|
|
26001
|
+
path: join2(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
24604
26002
|
client: "Claude Desktop"
|
|
24605
26003
|
});
|
|
24606
26004
|
} else if (process.platform === "win32") {
|
|
24607
26005
|
const appData = process.env.APPDATA;
|
|
24608
26006
|
if (appData) {
|
|
24609
|
-
list.push({ path:
|
|
26007
|
+
list.push({ path: join2(appData, "Claude", "claude_desktop_config.json"), client: "Claude Desktop" });
|
|
24610
26008
|
}
|
|
24611
26009
|
} else {
|
|
24612
26010
|
list.push({
|
|
24613
|
-
path:
|
|
26011
|
+
path: join2(home, ".config", "Claude", "claude_desktop_config.json"),
|
|
24614
26012
|
client: "Claude Desktop"
|
|
24615
26013
|
});
|
|
24616
26014
|
}
|
|
@@ -24728,216 +26126,6 @@ async function runDoctor() {
|
|
|
24728
26126
|
return code;
|
|
24729
26127
|
}
|
|
24730
26128
|
|
|
24731
|
-
// src/oauth.ts
|
|
24732
|
-
import crypto from "crypto";
|
|
24733
|
-
import { createServer } from "http";
|
|
24734
|
-
import { spawn } from "child_process";
|
|
24735
|
-
|
|
24736
|
-
// src/credentials.ts
|
|
24737
|
-
import { chmod, mkdir, readFile as readFile2, writeFile, unlink } from "fs/promises";
|
|
24738
|
-
import { homedir as homedir4 } from "os";
|
|
24739
|
-
import { dirname, join as join2 } from "path";
|
|
24740
|
-
function credentialsPath() {
|
|
24741
|
-
const base = process.env.XDG_CONFIG_HOME?.trim() || join2(homedir4(), ".config");
|
|
24742
|
-
return join2(base, "beplus-mcp", "credentials.json");
|
|
24743
|
-
}
|
|
24744
|
-
async function readCredentials() {
|
|
24745
|
-
try {
|
|
24746
|
-
const raw = await readFile2(credentialsPath(), "utf8");
|
|
24747
|
-
const parsed = JSON.parse(raw);
|
|
24748
|
-
if (!parsed.accessToken || !parsed.apiUrl) return null;
|
|
24749
|
-
return parsed;
|
|
24750
|
-
} catch {
|
|
24751
|
-
return null;
|
|
24752
|
-
}
|
|
24753
|
-
}
|
|
24754
|
-
async function writeCredentials(creds) {
|
|
24755
|
-
const path = credentialsPath();
|
|
24756
|
-
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
24757
|
-
await writeFile(path, `${JSON.stringify(creds, null, 2)}
|
|
24758
|
-
`, { mode: 384 });
|
|
24759
|
-
await chmod(path, 384);
|
|
24760
|
-
return path;
|
|
24761
|
-
}
|
|
24762
|
-
async function clearCredentials() {
|
|
24763
|
-
try {
|
|
24764
|
-
await unlink(credentialsPath());
|
|
24765
|
-
return true;
|
|
24766
|
-
} catch {
|
|
24767
|
-
return false;
|
|
24768
|
-
}
|
|
24769
|
-
}
|
|
24770
|
-
var RENEW_MARGIN_MS = 6e4;
|
|
24771
|
-
function isExpired(creds) {
|
|
24772
|
-
return typeof creds.expiresAt === "number" && creds.expiresAt - RENEW_MARGIN_MS <= Date.now();
|
|
24773
|
-
}
|
|
24774
|
-
|
|
24775
|
-
// src/oauth.ts
|
|
24776
|
-
var CALLBACK_TIMEOUT_MS = 5 * 6e4;
|
|
24777
|
-
async function json(url, init) {
|
|
24778
|
-
let res;
|
|
24779
|
-
try {
|
|
24780
|
-
res = await fetch(url, init);
|
|
24781
|
-
} catch {
|
|
24782
|
-
throw new Error(`Nao consegui falar com ${new URL(url).origin}. Confira a rede e o BEPLUS_API_URL.`);
|
|
24783
|
-
}
|
|
24784
|
-
const text = await res.text();
|
|
24785
|
-
let body;
|
|
24786
|
-
try {
|
|
24787
|
-
body = text ? JSON.parse(text) : void 0;
|
|
24788
|
-
} catch {
|
|
24789
|
-
}
|
|
24790
|
-
if (!res.ok) {
|
|
24791
|
-
const msg = body?.message ?? body?.error_description ?? body?.error ?? `HTTP ${res.status}`;
|
|
24792
|
-
throw new Error(`${msg} (${url})`);
|
|
24793
|
-
}
|
|
24794
|
-
return body;
|
|
24795
|
-
}
|
|
24796
|
-
async function discover(apiUrl2) {
|
|
24797
|
-
const meta = await json(`${apiUrl2}/.well-known/oauth-authorization-server`);
|
|
24798
|
-
if (!meta.authorization_endpoint || !meta.token_endpoint || !meta.registration_endpoint) {
|
|
24799
|
-
throw new Error("O servidor respondeu a descoberta sem os endpoints obrigatorios.");
|
|
24800
|
-
}
|
|
24801
|
-
return meta;
|
|
24802
|
-
}
|
|
24803
|
-
function pkce() {
|
|
24804
|
-
const verifier = crypto.randomBytes(32).toString("base64url");
|
|
24805
|
-
return { verifier, challenge: crypto.createHash("sha256").update(verifier).digest("base64url") };
|
|
24806
|
-
}
|
|
24807
|
-
function openBrowser(url) {
|
|
24808
|
-
try {
|
|
24809
|
-
if (process.platform === "win32") {
|
|
24810
|
-
spawn("cmd.exe", ["/c", "start", '""', "/b", url.replace(/&/g, "^&")], {
|
|
24811
|
-
stdio: "ignore",
|
|
24812
|
-
detached: true,
|
|
24813
|
-
windowsVerbatimArguments: true
|
|
24814
|
-
}).unref();
|
|
24815
|
-
return;
|
|
24816
|
-
}
|
|
24817
|
-
const cmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
24818
|
-
spawn(cmd, [url], { stdio: "ignore", detached: true }).unref();
|
|
24819
|
-
} catch {
|
|
24820
|
-
}
|
|
24821
|
-
}
|
|
24822
|
-
var PAGINA_OK = `<!doctype html><meta charset="utf-8"><title>Pronto</title>
|
|
24823
|
-
<body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
|
|
24824
|
-
<div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Tudo certo</h1>
|
|
24825
|
-
<p style="margin:0;opacity:.7">Pode fechar esta aba e voltar para o seu agente.</p></div>`;
|
|
24826
|
-
var PAGINA_ERRO = `<!doctype html><meta charset="utf-8"><title>Nao deu</title>
|
|
24827
|
-
<body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
|
|
24828
|
-
<div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Nao foi dessa vez</h1>
|
|
24829
|
-
<p style="margin:0;opacity:.7">Volte ao terminal para ver o motivo.</p></div>`;
|
|
24830
|
-
function listenForCallback(expectedState) {
|
|
24831
|
-
return new Promise((resolvePort, rejectPort) => {
|
|
24832
|
-
let settle;
|
|
24833
|
-
let fail;
|
|
24834
|
-
const code = new Promise((res, rej) => {
|
|
24835
|
-
settle = res;
|
|
24836
|
-
fail = rej;
|
|
24837
|
-
});
|
|
24838
|
-
const server = createServer((req, res) => {
|
|
24839
|
-
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
24840
|
-
if (url.pathname !== "/callback") {
|
|
24841
|
-
res.writeHead(404).end();
|
|
24842
|
-
return;
|
|
24843
|
-
}
|
|
24844
|
-
const erro = url.searchParams.get("error");
|
|
24845
|
-
const recebido = url.searchParams.get("code");
|
|
24846
|
-
const state = url.searchParams.get("state") ?? "";
|
|
24847
|
-
const ok = !erro && recebido && state === expectedState;
|
|
24848
|
-
res.writeHead(ok ? 200 : 400, { "content-type": "text/html; charset=utf-8" });
|
|
24849
|
-
res.end(ok ? PAGINA_OK : PAGINA_ERRO);
|
|
24850
|
-
server.close();
|
|
24851
|
-
if (erro) return fail(new Error(url.searchParams.get("error_description") || erro));
|
|
24852
|
-
if (!recebido || state !== expectedState) return fail(new Error("Resposta de autorizacao invalida."));
|
|
24853
|
-
settle({ code: recebido, state });
|
|
24854
|
-
});
|
|
24855
|
-
server.on("error", rejectPort);
|
|
24856
|
-
server.listen(0, "127.0.0.1", () => {
|
|
24857
|
-
const addr = server.address();
|
|
24858
|
-
if (!addr || typeof addr === "string") return rejectPort(new Error("Nao consegui abrir a porta local."));
|
|
24859
|
-
const timer = setTimeout(() => {
|
|
24860
|
-
server.close();
|
|
24861
|
-
fail(new Error("Tempo esgotado esperando a autorizacao no navegador."));
|
|
24862
|
-
}, CALLBACK_TIMEOUT_MS);
|
|
24863
|
-
void code.finally(() => clearTimeout(timer));
|
|
24864
|
-
resolvePort({ port: addr.port, code });
|
|
24865
|
-
});
|
|
24866
|
-
});
|
|
24867
|
-
}
|
|
24868
|
-
function toStored(t, apiUrl2, clientId) {
|
|
24869
|
-
return {
|
|
24870
|
-
accessToken: t.access_token,
|
|
24871
|
-
refreshToken: t.refresh_token,
|
|
24872
|
-
expiresAt: t.expires_in ? Date.now() + t.expires_in * 1e3 : void 0,
|
|
24873
|
-
apiUrl: apiUrl2,
|
|
24874
|
-
clientId
|
|
24875
|
-
};
|
|
24876
|
-
}
|
|
24877
|
-
async function login(apiUrl2, onUrl) {
|
|
24878
|
-
const meta = await discover(apiUrl2);
|
|
24879
|
-
const state = crypto.randomBytes(24).toString("base64url");
|
|
24880
|
-
const { verifier, challenge } = pkce();
|
|
24881
|
-
const { port, code } = await listenForCallback(state);
|
|
24882
|
-
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
24883
|
-
const client = await json(meta.registration_endpoint, {
|
|
24884
|
-
method: "POST",
|
|
24885
|
-
headers: { "content-type": "application/json" },
|
|
24886
|
-
body: JSON.stringify({
|
|
24887
|
-
client_name: "beplus-mcp (CLI)",
|
|
24888
|
-
redirect_uris: [redirectUri],
|
|
24889
|
-
token_endpoint_auth_method: "none",
|
|
24890
|
-
grant_types: ["authorization_code", "refresh_token"]
|
|
24891
|
-
})
|
|
24892
|
-
});
|
|
24893
|
-
const authorizeUrl = new URL(meta.authorization_endpoint);
|
|
24894
|
-
authorizeUrl.searchParams.set("response_type", "code");
|
|
24895
|
-
authorizeUrl.searchParams.set("client_id", client.client_id);
|
|
24896
|
-
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
|
|
24897
|
-
authorizeUrl.searchParams.set("code_challenge", challenge);
|
|
24898
|
-
authorizeUrl.searchParams.set("code_challenge_method", "S256");
|
|
24899
|
-
authorizeUrl.searchParams.set("state", state);
|
|
24900
|
-
onUrl(authorizeUrl.toString());
|
|
24901
|
-
openBrowser(authorizeUrl.toString());
|
|
24902
|
-
const { code: authCode } = await code;
|
|
24903
|
-
const token = await json(meta.token_endpoint, {
|
|
24904
|
-
method: "POST",
|
|
24905
|
-
headers: { "content-type": "application/json" },
|
|
24906
|
-
body: JSON.stringify({
|
|
24907
|
-
grant_type: "authorization_code",
|
|
24908
|
-
code: authCode,
|
|
24909
|
-
code_verifier: verifier,
|
|
24910
|
-
client_id: client.client_id,
|
|
24911
|
-
redirect_uri: redirectUri
|
|
24912
|
-
})
|
|
24913
|
-
});
|
|
24914
|
-
const path = await writeCredentials(toStored(token, apiUrl2, client.client_id));
|
|
24915
|
-
return { path, authorizeUrl: authorizeUrl.toString() };
|
|
24916
|
-
}
|
|
24917
|
-
async function tokenFromDisk(apiUrl2) {
|
|
24918
|
-
const creds = await readCredentials();
|
|
24919
|
-
if (!creds) return null;
|
|
24920
|
-
if (creds.apiUrl.replace(/\/$/, "") !== apiUrl2.replace(/\/$/, "")) return null;
|
|
24921
|
-
if (!isExpired(creds)) return creds.accessToken;
|
|
24922
|
-
if (!creds.refreshToken) return null;
|
|
24923
|
-
try {
|
|
24924
|
-
const meta = await discover(apiUrl2);
|
|
24925
|
-
const token = await json(meta.token_endpoint, {
|
|
24926
|
-
method: "POST",
|
|
24927
|
-
headers: { "content-type": "application/json" },
|
|
24928
|
-
body: JSON.stringify({
|
|
24929
|
-
grant_type: "refresh_token",
|
|
24930
|
-
refresh_token: creds.refreshToken,
|
|
24931
|
-
client_id: creds.clientId
|
|
24932
|
-
})
|
|
24933
|
-
});
|
|
24934
|
-
await writeCredentials(toStored(token, apiUrl2, creds.clientId));
|
|
24935
|
-
return token.access_token;
|
|
24936
|
-
} catch {
|
|
24937
|
-
return null;
|
|
24938
|
-
}
|
|
24939
|
-
}
|
|
24940
|
-
|
|
24941
26129
|
// src/index.ts
|
|
24942
26130
|
if (process.argv.length <= 2) assertSupportedNode();
|
|
24943
26131
|
var HELP = `beplus-mcp ${VERSION}
|
|
@@ -25002,7 +26190,7 @@ Se ele nao abrir, acesse:
|
|
|
25002
26190
|
});
|
|
25003
26191
|
process.stdout.write(`Pronto. Credencial guardada em ${path}
|
|
25004
26192
|
`);
|
|
25005
|
-
process.stdout.write("
|
|
26193
|
+
process.stdout.write("Se as ferramentas beplus ainda nao aparecem no agente, reinicie o agente.\n");
|
|
25006
26194
|
return 0;
|
|
25007
26195
|
} catch (e) {
|
|
25008
26196
|
logError(e.message);
|
|
@@ -25014,9 +26202,13 @@ async function main() {
|
|
|
25014
26202
|
if (handled !== null) {
|
|
25015
26203
|
process.exit(handled);
|
|
25016
26204
|
}
|
|
26205
|
+
let doLogin = false;
|
|
25017
26206
|
if (!process.env.BEPLUS_API_TOKEN?.trim()) {
|
|
25018
26207
|
const doDisco = await tokenFromDisk(apiUrl());
|
|
25019
|
-
if (doDisco)
|
|
26208
|
+
if (doDisco) {
|
|
26209
|
+
process.env.BEPLUS_API_TOKEN = doDisco;
|
|
26210
|
+
doLogin = true;
|
|
26211
|
+
}
|
|
25020
26212
|
}
|
|
25021
26213
|
let cfg;
|
|
25022
26214
|
try {
|
|
@@ -25025,6 +26217,7 @@ async function main() {
|
|
|
25025
26217
|
logError(e.message);
|
|
25026
26218
|
process.exit(1);
|
|
25027
26219
|
}
|
|
26220
|
+
if (doLogin) cfg.auth = new LoginToken(cfg.baseUrl, cfg.token);
|
|
25028
26221
|
const { server, client } = buildServer(cfg);
|
|
25029
26222
|
if (cfg.verifyOnStart) {
|
|
25030
26223
|
try {
|
|
@@ -25033,7 +26226,7 @@ async function main() {
|
|
|
25033
26226
|
} catch (e) {
|
|
25034
26227
|
if (e instanceof ApiError && e.httpStatus === 401) {
|
|
25035
26228
|
logError(
|
|
25036
|
-
'Token invalido ou revogado. Gere um novo Personal Access Token no painel BePlus e atualize BEPLUS_API_TOKEN no config do MCP. Rode "beplus-mcp doctor" para conferir.'
|
|
26229
|
+
doLogin ? 'O login pelo navegador expirou e nao deu para renovar. Rode "beplus-mcp login" de novo.' : 'Token invalido ou revogado. Gere um novo Personal Access Token no painel BePlus e atualize BEPLUS_API_TOKEN no config do MCP. Rode "beplus-mcp doctor" para conferir.'
|
|
25037
26230
|
);
|
|
25038
26231
|
process.exit(1);
|
|
25039
26232
|
}
|