@zapier/zapier-sdk 0.84.4 → 0.86.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/AGENTS.md +3 -1
- package/CHANGELOG.md +12 -0
- package/README.md +80 -56
- package/dist/experimental.cjs +709 -397
- package/dist/experimental.d.mts +4 -4
- package/dist/experimental.d.ts +4 -4
- package/dist/experimental.mjs +709 -397
- package/dist/{index-ChZuXQDn.d.mts → index-Pjitof_V.d.mts} +184 -96
- package/dist/{index-ChZuXQDn.d.ts → index-Pjitof_V.d.ts} +184 -96
- package/dist/index.cjs +681 -390
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +681 -390
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,33 @@ function pluralizeLastWord(title) {
|
|
|
34
34
|
const words = title.split(" ");
|
|
35
35
|
return [...words.slice(0, -1), pluralize(words[words.length - 1])].join(" ");
|
|
36
36
|
}
|
|
37
|
+
function canonicalInputSchema(schema) {
|
|
38
|
+
if (schema instanceof zod.z.ZodUnion) {
|
|
39
|
+
return schema.options[0];
|
|
40
|
+
}
|
|
41
|
+
return schema;
|
|
42
|
+
}
|
|
43
|
+
function withPositional(schema) {
|
|
44
|
+
Object.assign(schema._zod.def, {
|
|
45
|
+
positionalMeta: { positional: true }
|
|
46
|
+
});
|
|
47
|
+
return schema;
|
|
48
|
+
}
|
|
49
|
+
function schemaHasPositionalMeta(schema) {
|
|
50
|
+
return "positionalMeta" in schema._zod.def;
|
|
51
|
+
}
|
|
52
|
+
function isPositional(schema) {
|
|
53
|
+
if (schemaHasPositionalMeta(schema) && schema._zod.def.positionalMeta?.positional) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (schema instanceof zod.z.ZodOptional) {
|
|
57
|
+
return isPositional(schema._zod.def.innerType);
|
|
58
|
+
}
|
|
59
|
+
if (schema instanceof zod.z.ZodDefault) {
|
|
60
|
+
return isPositional(schema._zod.def.innerType);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
37
64
|
function resolveCategoryDefinition(ref) {
|
|
38
65
|
const def = typeof ref === "string" ? { key: ref } : ref;
|
|
39
66
|
const title = def.title ?? toTitleCase(def.key);
|
|
@@ -43,30 +70,25 @@ function resolveCategoryDefinition(ref) {
|
|
|
43
70
|
titlePlural: def.titlePlural ?? pluralizeLastWord(title)
|
|
44
71
|
};
|
|
45
72
|
}
|
|
46
|
-
function canonicalInputSchema(schema) {
|
|
47
|
-
if (schema instanceof zod.z.ZodUnion) {
|
|
48
|
-
return schema.options[0];
|
|
49
|
-
}
|
|
50
|
-
return schema;
|
|
51
|
-
}
|
|
52
73
|
function buildRegistry({
|
|
53
74
|
sdk,
|
|
54
75
|
meta,
|
|
55
76
|
formatters,
|
|
56
|
-
|
|
77
|
+
resolvers,
|
|
57
78
|
positional,
|
|
79
|
+
skipInputValidation,
|
|
58
80
|
packageFilter
|
|
59
81
|
}) {
|
|
60
82
|
const definitionsByKey = /* @__PURE__ */ new Map();
|
|
61
83
|
const objectDeclaredKeys = /* @__PURE__ */ new Set();
|
|
62
84
|
for (const m of Object.values(meta)) {
|
|
63
85
|
for (const ref of m.categories ?? []) {
|
|
64
|
-
const
|
|
86
|
+
const key = typeof ref === "string" ? ref : ref.key;
|
|
65
87
|
if (typeof ref === "object") {
|
|
66
|
-
objectDeclaredKeys.add(
|
|
67
|
-
definitionsByKey.set(
|
|
68
|
-
} else if (!objectDeclaredKeys.has(
|
|
69
|
-
definitionsByKey.set(
|
|
88
|
+
objectDeclaredKeys.add(key);
|
|
89
|
+
definitionsByKey.set(key, resolveCategoryDefinition(ref));
|
|
90
|
+
} else if (!objectDeclaredKeys.has(key)) {
|
|
91
|
+
definitionsByKey.set(key, resolveCategoryDefinition(ref));
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
94
|
}
|
|
@@ -74,30 +96,29 @@ function buildRegistry({
|
|
|
74
96
|
definitionsByKey.set("other", resolveCategoryDefinition("other"));
|
|
75
97
|
}
|
|
76
98
|
const knownCategories = Array.from(definitionsByKey.keys());
|
|
77
|
-
const functions = Object.keys(meta).filter((
|
|
78
|
-
const property = sdk[
|
|
99
|
+
const functions = Object.keys(meta).filter((key) => {
|
|
100
|
+
const property = sdk[key];
|
|
79
101
|
if (typeof property === "function") return true;
|
|
80
|
-
const [rootKey] =
|
|
102
|
+
const [rootKey] = key.split(".");
|
|
81
103
|
const rootProperty = sdk[rootKey];
|
|
82
104
|
return typeof rootProperty === "object" && rootProperty !== null;
|
|
83
|
-
}).map((
|
|
84
|
-
const m = meta[
|
|
105
|
+
}).map((key) => {
|
|
106
|
+
const m = meta[key];
|
|
85
107
|
return {
|
|
86
|
-
name:
|
|
108
|
+
name: key,
|
|
87
109
|
description: m.description,
|
|
88
110
|
type: m.type,
|
|
89
111
|
itemType: m.itemType,
|
|
90
112
|
returnType: m.returnType,
|
|
91
113
|
inputSchema: canonicalInputSchema(m.inputSchema),
|
|
92
|
-
inputParameters: m.inputParameters,
|
|
93
114
|
outputSchema: m.outputSchema,
|
|
94
|
-
positional: positional?.[
|
|
115
|
+
positional: positional?.[key],
|
|
116
|
+
skipInputValidation: skipInputValidation?.[key],
|
|
95
117
|
categories: (m.categories ?? []).map(
|
|
96
118
|
(c) => typeof c === "string" ? c : c.key
|
|
97
119
|
),
|
|
98
|
-
resolvers:
|
|
99
|
-
|
|
100
|
-
formatter: formatters?.[key2],
|
|
120
|
+
resolvers: resolvers?.[key],
|
|
121
|
+
formatter: formatters?.[key],
|
|
101
122
|
experimental: m.experimental,
|
|
102
123
|
packages: m.packages,
|
|
103
124
|
confirm: m.confirm ?? (m.type === "delete" ? "delete" : void 0),
|
|
@@ -410,51 +431,36 @@ function decodeConcatCursor(incoming) {
|
|
|
410
431
|
}
|
|
411
432
|
return { index: 0, cursor: incoming };
|
|
412
433
|
}
|
|
413
|
-
function
|
|
434
|
+
async function concatLists({
|
|
414
435
|
sources,
|
|
415
436
|
pageSize = 100,
|
|
416
437
|
cursor
|
|
417
438
|
}) {
|
|
418
439
|
if (sources.length === 0) {
|
|
419
|
-
|
|
420
|
-
return Object.assign(Promise.resolve(empty), {
|
|
421
|
-
[Symbol.asyncIterator]: async function* () {
|
|
422
|
-
yield empty;
|
|
423
|
-
}
|
|
424
|
-
});
|
|
440
|
+
return { data: [] };
|
|
425
441
|
}
|
|
426
442
|
const pageFunction = async (options) => {
|
|
427
|
-
let { index, cursor:
|
|
443
|
+
let { index, cursor: listCursor } = decodeConcatCursor(options.cursor);
|
|
428
444
|
while (index < sources.length) {
|
|
429
|
-
const page = await sources[index]({ cursor:
|
|
430
|
-
const
|
|
431
|
-
if (page.data.length === 0 && !
|
|
445
|
+
const page = await sources[index]({ cursor: listCursor });
|
|
446
|
+
const hasMoreInList = page.nextCursor != null;
|
|
447
|
+
if (page.data.length === 0 && !hasMoreInList) {
|
|
432
448
|
index++;
|
|
433
|
-
|
|
449
|
+
listCursor = void 0;
|
|
434
450
|
continue;
|
|
435
451
|
}
|
|
436
452
|
return {
|
|
437
453
|
data: page.data,
|
|
438
|
-
nextCursor:
|
|
454
|
+
nextCursor: hasMoreInList ? encodeConcatCursor(index, page.nextCursor) : index < sources.length - 1 ? encodeConcatCursor(index + 1, void 0) : void 0
|
|
439
455
|
};
|
|
440
456
|
}
|
|
441
457
|
return { data: [] };
|
|
442
458
|
};
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return result.value;
|
|
449
|
-
});
|
|
450
|
-
return Object.assign(firstPagePromise, {
|
|
451
|
-
[Symbol.asyncIterator]: async function* () {
|
|
452
|
-
yield await firstPagePromise;
|
|
453
|
-
for await (const page of { [Symbol.asyncIterator]: () => iterator }) {
|
|
454
|
-
yield page;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
});
|
|
459
|
+
const result = await paginateBuffered(pageFunction, {
|
|
460
|
+
pageSize,
|
|
461
|
+
cursor
|
|
462
|
+
}).next();
|
|
463
|
+
return result.done ? { data: [] } : result.value;
|
|
458
464
|
}
|
|
459
465
|
var parseOrThrow = (schema, input, { adaptError } = {}) => {
|
|
460
466
|
const result = schema.safeParse(input);
|
|
@@ -527,6 +533,50 @@ function runInMethodScope(fn) {
|
|
|
527
533
|
return scope.run({ depth: currentDepth + 1 }, fn);
|
|
528
534
|
}
|
|
529
535
|
var runWithTelemetryContext = runInMethodScope;
|
|
536
|
+
var CALL_CONTEXT_BRAND = Symbol("kitcore.callContext");
|
|
537
|
+
function isCallContext(value) {
|
|
538
|
+
return typeof value === "object" && value !== null && value[CALL_CONTEXT_BRAND] === true;
|
|
539
|
+
}
|
|
540
|
+
function generateCallId() {
|
|
541
|
+
try {
|
|
542
|
+
const webCrypto = globalThis.crypto;
|
|
543
|
+
if (webCrypto?.randomUUID) {
|
|
544
|
+
return webCrypto.randomUUID();
|
|
545
|
+
}
|
|
546
|
+
if (webCrypto?.getRandomValues) {
|
|
547
|
+
const bytes = webCrypto.getRandomValues(new Uint8Array(16));
|
|
548
|
+
const hex = Array.from(bytes, (byte, i) => {
|
|
549
|
+
const value = i === 6 ? byte & 15 | 64 : i === 8 ? byte & 63 | 128 : byte;
|
|
550
|
+
return value.toString(16).padStart(2, "0");
|
|
551
|
+
});
|
|
552
|
+
return [
|
|
553
|
+
hex.slice(0, 4).join(""),
|
|
554
|
+
hex.slice(4, 6).join(""),
|
|
555
|
+
hex.slice(6, 8).join(""),
|
|
556
|
+
hex.slice(8, 10).join(""),
|
|
557
|
+
hex.slice(10, 16).join("")
|
|
558
|
+
].join("-");
|
|
559
|
+
}
|
|
560
|
+
} catch {
|
|
561
|
+
}
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
function rootCallContext() {
|
|
565
|
+
return {
|
|
566
|
+
callId: generateCallId(),
|
|
567
|
+
depth: 0,
|
|
568
|
+
annotations: {},
|
|
569
|
+
[CALL_CONTEXT_BRAND]: true
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
function childCallContext(parent) {
|
|
573
|
+
return {
|
|
574
|
+
callId: parent.callId,
|
|
575
|
+
depth: parent.depth + 1,
|
|
576
|
+
annotations: {},
|
|
577
|
+
[CALL_CONTEXT_BRAND]: true
|
|
578
|
+
};
|
|
579
|
+
}
|
|
530
580
|
function defaultLogDeprecation({
|
|
531
581
|
methodName,
|
|
532
582
|
deprecation
|
|
@@ -542,6 +592,9 @@ function resolveCoreOptions(context) {
|
|
|
542
592
|
return context.core;
|
|
543
593
|
}
|
|
544
594
|
var INTERNAL_CALL = Symbol("kitcore.internalCall");
|
|
595
|
+
function resolveCallContext(secondArg) {
|
|
596
|
+
return isCallContext(secondArg) ? secondArg : rootCallContext();
|
|
597
|
+
}
|
|
545
598
|
function signalDeprecation(context, methodName, getDeprecation) {
|
|
546
599
|
if (isInsideObserver()) return;
|
|
547
600
|
const deprecation = getDeprecation?.();
|
|
@@ -571,14 +624,16 @@ function createFunction(coreFn, options) {
|
|
|
571
624
|
const functionName = name || coreFn.name;
|
|
572
625
|
const namedFunctions = {
|
|
573
626
|
[functionName]: async function(callOptions) {
|
|
574
|
-
|
|
627
|
+
const internal = arguments[1];
|
|
628
|
+
const context = resolveCallContext(internal);
|
|
629
|
+
if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
|
|
575
630
|
signalDeprecation(sdk.context, functionName, getDeprecation);
|
|
576
631
|
}
|
|
577
632
|
return runInMethodScope(async () => {
|
|
578
633
|
const startTime = Date.now();
|
|
579
634
|
const normalizedOptions = callOptions ?? {};
|
|
580
635
|
const args = [normalizedOptions];
|
|
581
|
-
const depth = getCurrentDepth();
|
|
636
|
+
const depth = Math.max(context.depth, getCurrentDepth());
|
|
582
637
|
const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
|
|
583
638
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
584
639
|
hooks?.onMethodStart?.({
|
|
@@ -597,12 +652,15 @@ function createFunction(coreFn, options) {
|
|
|
597
652
|
adaptError
|
|
598
653
|
}
|
|
599
654
|
);
|
|
600
|
-
result = await coreFn(
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
655
|
+
result = await coreFn(
|
|
656
|
+
{
|
|
657
|
+
...normalizedOptions,
|
|
658
|
+
...validatedOptions
|
|
659
|
+
},
|
|
660
|
+
context
|
|
661
|
+
);
|
|
604
662
|
} else {
|
|
605
|
-
result = await coreFn(normalizedOptions);
|
|
663
|
+
result = await coreFn(normalizedOptions, context);
|
|
606
664
|
}
|
|
607
665
|
hooks?.onMethodEnd?.({
|
|
608
666
|
methodName: functionName,
|
|
@@ -632,17 +690,19 @@ function createFunction(coreFn, options) {
|
|
|
632
690
|
function createRawFunction(coreFn, options) {
|
|
633
691
|
const { sdk, name, schema, positional, getDeprecation } = options;
|
|
634
692
|
return function(rawInput) {
|
|
635
|
-
|
|
693
|
+
const internal = arguments[1];
|
|
694
|
+
const context = resolveCallContext(internal);
|
|
695
|
+
if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
|
|
636
696
|
signalDeprecation(sdk.context, name, getDeprecation);
|
|
637
697
|
}
|
|
638
698
|
return runInMethodScope(() => {
|
|
639
699
|
const startTime = Date.now();
|
|
640
|
-
const depth = getCurrentDepth();
|
|
700
|
+
const depth = Math.max(context.depth, getCurrentDepth());
|
|
641
701
|
const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
|
|
642
702
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
643
703
|
const input = schema ? rawInput ?? {} : rawInput;
|
|
644
704
|
const record = input;
|
|
645
|
-
const args = positional ? positional.filter((
|
|
705
|
+
const args = positional ? positional.filter((key) => record?.[key] !== void 0).map((key) => record?.[key]) : [input];
|
|
646
706
|
hooks?.onMethodStart?.({
|
|
647
707
|
methodName: name,
|
|
648
708
|
args,
|
|
@@ -661,7 +721,7 @@ function createRawFunction(coreFn, options) {
|
|
|
661
721
|
};
|
|
662
722
|
try {
|
|
663
723
|
const parsed = schema ? validateOptions(schema, input, { adaptError }) : input;
|
|
664
|
-
const result = coreFn(parsed);
|
|
724
|
+
const result = coreFn(parsed, context);
|
|
665
725
|
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
666
726
|
return result.then(
|
|
667
727
|
(value) => {
|
|
@@ -700,9 +760,9 @@ function createPageFunction(coreFn, {
|
|
|
700
760
|
}) {
|
|
701
761
|
const functionName = coreFn.name + "Page";
|
|
702
762
|
const namedFunctions = {
|
|
703
|
-
[functionName]: async function(options) {
|
|
763
|
+
[functionName]: async function(options, callContext) {
|
|
704
764
|
try {
|
|
705
|
-
const response = await coreFn(options);
|
|
765
|
+
const response = await coreFn(options, callContext);
|
|
706
766
|
const page = adaptPage ? adaptPage(response) : response;
|
|
707
767
|
if (!isSdkPage(page)) {
|
|
708
768
|
throw new Error(
|
|
@@ -726,14 +786,16 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
726
786
|
const functionName = name || coreFn.name;
|
|
727
787
|
const namedFunctions = {
|
|
728
788
|
[functionName]: function(callOptions) {
|
|
729
|
-
|
|
789
|
+
const internal = arguments[1];
|
|
790
|
+
const context = resolveCallContext(internal);
|
|
791
|
+
if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
|
|
730
792
|
signalDeprecation(sdk.context, functionName, getDeprecation);
|
|
731
793
|
}
|
|
732
794
|
return runInMethodScope(() => {
|
|
733
795
|
const startTime = Date.now();
|
|
734
796
|
const normalizedOptions = callOptions ?? {};
|
|
735
797
|
const args = [normalizedOptions];
|
|
736
|
-
const depth = getCurrentDepth();
|
|
798
|
+
const depth = Math.max(context.depth, getCurrentDepth());
|
|
737
799
|
const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
|
|
738
800
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
739
801
|
hooks?.onMethodStart?.({
|
|
@@ -752,7 +814,11 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
752
814
|
...validatedOptions,
|
|
753
815
|
pageSize
|
|
754
816
|
};
|
|
755
|
-
const iterator = paginate(
|
|
817
|
+
const iterator = paginate(
|
|
818
|
+
(pageOptions) => pageFunction(pageOptions, context),
|
|
819
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
820
|
+
optimizedOptions
|
|
821
|
+
);
|
|
756
822
|
const firstPagePromise = iterator.next().then((result) => {
|
|
757
823
|
if (result.done) {
|
|
758
824
|
throw new Error("Paginate should always iterate at least once");
|
|
@@ -789,6 +855,13 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
789
855
|
[Symbol.asyncIterator]() {
|
|
790
856
|
return pageStream;
|
|
791
857
|
},
|
|
858
|
+
pages: function() {
|
|
859
|
+
return {
|
|
860
|
+
[Symbol.asyncIterator]() {
|
|
861
|
+
return pageStream;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
},
|
|
792
865
|
items: function() {
|
|
793
866
|
return {
|
|
794
867
|
[Symbol.asyncIterator]: async function* () {
|
|
@@ -894,11 +967,11 @@ var RESERVED_ROOT_KEYS = /* @__PURE__ */ new Set([
|
|
|
894
967
|
"context",
|
|
895
968
|
"getRegistry"
|
|
896
969
|
]);
|
|
897
|
-
function hasOwn(obj,
|
|
898
|
-
return Object.prototype.hasOwnProperty.call(obj,
|
|
970
|
+
function hasOwn(obj, key) {
|
|
971
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
899
972
|
}
|
|
900
|
-
function setOwn(target,
|
|
901
|
-
Object.defineProperty(target,
|
|
973
|
+
function setOwn(target, key, value) {
|
|
974
|
+
Object.defineProperty(target, key, {
|
|
902
975
|
value,
|
|
903
976
|
enumerable: true,
|
|
904
977
|
configurable: true,
|
|
@@ -910,31 +983,31 @@ function checkCollisions(target, source, kind, callerLabel, override) {
|
|
|
910
983
|
checkRootKeyCollisions(target, Object.keys(source), override, callerLabel);
|
|
911
984
|
return;
|
|
912
985
|
}
|
|
913
|
-
for (const
|
|
914
|
-
if (!override && hasOwn(target,
|
|
986
|
+
for (const key of Object.keys(source)) {
|
|
987
|
+
if (!override && hasOwn(target, key)) {
|
|
915
988
|
throw new Error(
|
|
916
|
-
`${callerLabel}: duplicate ${kind} "${
|
|
989
|
+
`${callerLabel}: duplicate ${kind} "${key}". If the override is intentional, pass { override: true } in the options.`
|
|
917
990
|
);
|
|
918
991
|
}
|
|
919
992
|
}
|
|
920
993
|
}
|
|
921
994
|
function checkRootKeyCollisions(target, keys, override, callerLabel) {
|
|
922
|
-
for (const
|
|
923
|
-
if (RESERVED_ROOT_KEYS.has(
|
|
995
|
+
for (const key of keys) {
|
|
996
|
+
if (RESERVED_ROOT_KEYS.has(key)) {
|
|
924
997
|
throw new Error(
|
|
925
|
-
`${callerLabel}: plugin attempted to register reserved root key "${
|
|
998
|
+
`${callerLabel}: plugin attempted to register reserved root key "${key}". The SDK uses this key for its own accessor; rename the plugin's method.`
|
|
926
999
|
);
|
|
927
1000
|
}
|
|
928
|
-
if (!override && hasOwn(target,
|
|
1001
|
+
if (!override && hasOwn(target, key)) {
|
|
929
1002
|
throw new Error(
|
|
930
|
-
`${callerLabel}: duplicate root key "${
|
|
1003
|
+
`${callerLabel}: duplicate root key "${key}". If the override is intentional, pass { override: true } in the options.`
|
|
931
1004
|
);
|
|
932
1005
|
}
|
|
933
1006
|
}
|
|
934
1007
|
}
|
|
935
1008
|
function applyOwnProperties(target, source) {
|
|
936
|
-
for (const
|
|
937
|
-
setOwn(target,
|
|
1009
|
+
for (const key of Object.keys(source)) {
|
|
1010
|
+
setOwn(target, key, source[key]);
|
|
938
1011
|
}
|
|
939
1012
|
}
|
|
940
1013
|
function createPluginAccumulator(initialProperties = {}, initialContext = {}) {
|
|
@@ -1148,7 +1221,6 @@ var LEAF_META_KEYS = [
|
|
|
1148
1221
|
"itemType",
|
|
1149
1222
|
"returnType",
|
|
1150
1223
|
"outputSchema",
|
|
1151
|
-
"inputParameters",
|
|
1152
1224
|
"packages",
|
|
1153
1225
|
"experimental",
|
|
1154
1226
|
"confirm",
|
|
@@ -1185,8 +1257,8 @@ function normalizeImports(deps) {
|
|
|
1185
1257
|
}
|
|
1186
1258
|
function collectLeafMeta(config) {
|
|
1187
1259
|
let meta;
|
|
1188
|
-
for (const
|
|
1189
|
-
if (config[
|
|
1260
|
+
for (const key of LEAF_META_KEYS) {
|
|
1261
|
+
if (config[key] !== void 0) (meta ?? (meta = {}))[key] = config[key];
|
|
1190
1262
|
}
|
|
1191
1263
|
return meta;
|
|
1192
1264
|
}
|
|
@@ -1269,7 +1341,8 @@ function defineResolver(config) {
|
|
|
1269
1341
|
type: "object",
|
|
1270
1342
|
properties: config.properties,
|
|
1271
1343
|
definitions: config.definitions,
|
|
1272
|
-
getProperties: config.getProperties
|
|
1344
|
+
getProperties: config.getProperties,
|
|
1345
|
+
additionalKeys: config.additionalKeys
|
|
1273
1346
|
};
|
|
1274
1347
|
case "array":
|
|
1275
1348
|
return {
|
|
@@ -1572,7 +1645,7 @@ function normalizeFormatter(entry, sdk) {
|
|
|
1572
1645
|
const legacy = entry.meta?.formatter;
|
|
1573
1646
|
return legacy ? adaptLegacyFormatter(legacy, sdk) : void 0;
|
|
1574
1647
|
}
|
|
1575
|
-
function
|
|
1648
|
+
function normalizeResolvers(entry) {
|
|
1576
1649
|
if (entry.pluginType !== "method") return void 0;
|
|
1577
1650
|
return entry.resolvers;
|
|
1578
1651
|
}
|
|
@@ -1613,17 +1686,20 @@ function collectSurfaceProjection(context, formatterSdk) {
|
|
|
1613
1686
|
foldDynamicMembers(entry, surfaceBindings, meta);
|
|
1614
1687
|
}
|
|
1615
1688
|
const formatters = {};
|
|
1616
|
-
const
|
|
1689
|
+
const resolvers = {};
|
|
1617
1690
|
const positional = {};
|
|
1691
|
+
const skipInputValidation = {};
|
|
1618
1692
|
for (const [binding, entry] of Object.entries(entries)) {
|
|
1619
1693
|
const f = normalizeFormatter(entry, formatterSdk);
|
|
1620
1694
|
if (f) formatters[binding] = f;
|
|
1621
|
-
const r =
|
|
1622
|
-
if (r)
|
|
1695
|
+
const r = normalizeResolvers(entry);
|
|
1696
|
+
if (r) resolvers[binding] = r;
|
|
1623
1697
|
const p = methodPositional(entry);
|
|
1624
1698
|
if (p) positional[binding] = p;
|
|
1699
|
+
if (entry.pluginType === "method" && entry.skipInputValidation)
|
|
1700
|
+
skipInputValidation[binding] = true;
|
|
1625
1701
|
}
|
|
1626
|
-
return { meta, formatters,
|
|
1702
|
+
return { meta, formatters, resolvers, positional, skipInputValidation };
|
|
1627
1703
|
}
|
|
1628
1704
|
function buildSurfaceRegistry(context, packageFilter) {
|
|
1629
1705
|
const surface = {};
|
|
@@ -1676,6 +1752,11 @@ function nestedResolvers(resolver) {
|
|
|
1676
1752
|
for (const field of Object.values(resolver.properties ?? {})) {
|
|
1677
1753
|
if (!isResolverRef(field.resolver)) out.push(field.resolver);
|
|
1678
1754
|
}
|
|
1755
|
+
const ak = resolver.additionalKeys;
|
|
1756
|
+
if (ak) {
|
|
1757
|
+
if (!isResolverRef(ak.values)) out.push(ak.values);
|
|
1758
|
+
if (ak.keys && !isResolverRef(ak.keys)) out.push(ak.keys);
|
|
1759
|
+
}
|
|
1679
1760
|
out.push(...Object.values(resolver.definitions ?? {}));
|
|
1680
1761
|
} else if (resolver.type === "array") {
|
|
1681
1762
|
if (!isResolverRef(resolver.items)) out.push(resolver.items);
|
|
@@ -1800,16 +1881,16 @@ function collectPlugins(root, materialized = /* @__PURE__ */ new Set(), configur
|
|
|
1800
1881
|
}
|
|
1801
1882
|
return byId;
|
|
1802
1883
|
}
|
|
1803
|
-
function bindValue(target,
|
|
1884
|
+
function bindValue(target, key, entry, callType = "surface", ctx) {
|
|
1804
1885
|
if (entry.pluginType === "property" && entry.getValue) {
|
|
1805
|
-
Object.defineProperty(target,
|
|
1886
|
+
Object.defineProperty(target, key, {
|
|
1806
1887
|
get: entry.getValue,
|
|
1807
1888
|
enumerable: true,
|
|
1808
1889
|
configurable: true
|
|
1809
1890
|
});
|
|
1810
1891
|
} else {
|
|
1811
|
-
const value = callType === "internal" && entry.pluginType === "method" ? entry.internalValue ?? entry.value : entry.value;
|
|
1812
|
-
Object.defineProperty(target,
|
|
1892
|
+
const value = callType === "internal" && entry.pluginType === "method" ? entry.bindInternal?.(ctx) ?? entry.internalValue ?? entry.value : entry.value;
|
|
1893
|
+
Object.defineProperty(target, key, {
|
|
1813
1894
|
value,
|
|
1814
1895
|
writable: true,
|
|
1815
1896
|
enumerable: true,
|
|
@@ -1826,7 +1907,7 @@ function buildSurface(context, ...maps) {
|
|
|
1826
1907
|
sdk[CONTEXT] = context;
|
|
1827
1908
|
return sdk;
|
|
1828
1909
|
}
|
|
1829
|
-
function buildImports(plugins, importBindings) {
|
|
1910
|
+
function buildImports(plugins, importBindings, ctx) {
|
|
1830
1911
|
const imports = {};
|
|
1831
1912
|
for (const { binding, id, optional } of importBindings) {
|
|
1832
1913
|
const entry = plugins[id];
|
|
@@ -1839,7 +1920,7 @@ function buildImports(plugins, importBindings) {
|
|
|
1839
1920
|
});
|
|
1840
1921
|
continue;
|
|
1841
1922
|
}
|
|
1842
|
-
bindValue(imports, binding, entry, "internal");
|
|
1923
|
+
bindValue(imports, binding, entry, "internal", ctx);
|
|
1843
1924
|
}
|
|
1844
1925
|
return imports;
|
|
1845
1926
|
}
|
|
@@ -1918,6 +1999,19 @@ function bindResolver(resolver, plugins) {
|
|
|
1918
1999
|
const { getProperties } = resolver;
|
|
1919
2000
|
if (getProperties)
|
|
1920
2001
|
bound.getProperties = ({ input }) => getProperties({ imports, input });
|
|
2002
|
+
if (resolver.additionalKeys) {
|
|
2003
|
+
const ak = resolver.additionalKeys;
|
|
2004
|
+
const boundAk = {
|
|
2005
|
+
values: isResolverRef(ak.values) ? ak.values : bindResolver(ak.values, plugins),
|
|
2006
|
+
minEntries: ak.minEntries,
|
|
2007
|
+
maxEntries: ak.maxEntries,
|
|
2008
|
+
keyValueType: ak.keyValueType,
|
|
2009
|
+
valueValueType: ak.valueValueType
|
|
2010
|
+
};
|
|
2011
|
+
if (ak.keys)
|
|
2012
|
+
boundAk.keys = isResolverRef(ak.keys) ? ak.keys : bindResolver(ak.keys, plugins);
|
|
2013
|
+
bound.additionalKeys = boundAk;
|
|
2014
|
+
}
|
|
1921
2015
|
return bound;
|
|
1922
2016
|
}
|
|
1923
2017
|
case "array": {
|
|
@@ -1973,8 +2067,8 @@ function bindResolver(resolver, plugins) {
|
|
|
1973
2067
|
}
|
|
1974
2068
|
function bindFields(fields, plugins) {
|
|
1975
2069
|
const out = {};
|
|
1976
|
-
for (const [
|
|
1977
|
-
out[
|
|
2070
|
+
for (const [key, field] of Object.entries(fields)) {
|
|
2071
|
+
out[key] = {
|
|
1978
2072
|
...field,
|
|
1979
2073
|
resolver: isResolverRef(field.resolver) ? field.resolver : bindResolver(field.resolver, plugins)
|
|
1980
2074
|
};
|
|
@@ -1983,8 +2077,8 @@ function bindFields(fields, plugins) {
|
|
|
1983
2077
|
}
|
|
1984
2078
|
function bindDefinitions(definitions, plugins) {
|
|
1985
2079
|
const out = {};
|
|
1986
|
-
for (const [
|
|
1987
|
-
out[
|
|
2080
|
+
for (const [key, def] of Object.entries(definitions)) {
|
|
2081
|
+
out[key] = bindResolver(def, plugins);
|
|
1988
2082
|
}
|
|
1989
2083
|
return out;
|
|
1990
2084
|
}
|
|
@@ -2068,6 +2162,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2068
2162
|
name: descriptor.name,
|
|
2069
2163
|
chain: [],
|
|
2070
2164
|
inputSchema: descriptor.inputSchema,
|
|
2165
|
+
skipInputValidation: descriptor.skipInputValidation,
|
|
2071
2166
|
// Derive the presentation type from the output mode when the author did
|
|
2072
2167
|
// not set one; an explicit meta.type (e.g. "create") still wins.
|
|
2073
2168
|
meta: out.type === "raw" || descriptor.meta?.type ? descriptor.meta : { ...descriptor.meta, type: out.type },
|
|
@@ -2075,17 +2170,17 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2075
2170
|
// Replaced below; never called.
|
|
2076
2171
|
value: () => void 0
|
|
2077
2172
|
};
|
|
2078
|
-
const callRun = (input) => descriptor.run({
|
|
2079
|
-
imports: buildImports(plugins, descriptor.importBindings),
|
|
2173
|
+
const callRun = (input, ctx) => descriptor.run({
|
|
2174
|
+
imports: buildImports(plugins, descriptor.importBindings, ctx),
|
|
2080
2175
|
state: states.get(id),
|
|
2081
2176
|
input
|
|
2082
2177
|
});
|
|
2083
|
-
const fold = (coreFn) => (input) => {
|
|
2084
|
-
let next = coreFn;
|
|
2178
|
+
const fold = (coreFn) => (input, ctx) => {
|
|
2179
|
+
let next = (i) => coreFn(i, ctx);
|
|
2085
2180
|
for (const wrap of entry.chain) {
|
|
2086
2181
|
const inner = next;
|
|
2087
2182
|
next = (i) => wrap.run({
|
|
2088
|
-
imports: buildImports(plugins, wrap.owner.importBindings),
|
|
2183
|
+
imports: buildImports(plugins, wrap.owner.importBindings, ctx),
|
|
2089
2184
|
next: inner,
|
|
2090
2185
|
input: i,
|
|
2091
2186
|
// Overwritten by the chain item's own closure with the owning
|
|
@@ -2109,7 +2204,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2109
2204
|
}
|
|
2110
2205
|
);
|
|
2111
2206
|
} else if (out.type === "item") {
|
|
2112
|
-
const itemCore = async (input) => callRun(input);
|
|
2207
|
+
const itemCore = async (input, ctx) => callRun(input, ctx);
|
|
2113
2208
|
entry.value = createFunction(
|
|
2114
2209
|
fold(itemCore),
|
|
2115
2210
|
{
|
|
@@ -2121,7 +2216,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2121
2216
|
);
|
|
2122
2217
|
} else {
|
|
2123
2218
|
entry.value = createRawFunction(
|
|
2124
|
-
(input) => fold(callRun)(input),
|
|
2219
|
+
(input, ctx) => fold(callRun)(input, ctx),
|
|
2125
2220
|
{
|
|
2126
2221
|
sdk,
|
|
2127
2222
|
name: descriptor.name,
|
|
@@ -2144,11 +2239,15 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2144
2239
|
});
|
|
2145
2240
|
return packed;
|
|
2146
2241
|
};
|
|
2242
|
+
const internalValue = (...args) => canonicalValue(pack(args), INTERNAL_CALL);
|
|
2147
2243
|
entry.value = (...args) => canonicalValue(pack(args));
|
|
2148
|
-
entry.internalValue =
|
|
2244
|
+
entry.internalValue = internalValue;
|
|
2245
|
+
entry.bindInternal = (ctx) => ctx ? (...args) => canonicalValue(pack(args), childCallContext(ctx)) : internalValue;
|
|
2149
2246
|
entry.positional = names;
|
|
2150
2247
|
} else {
|
|
2151
|
-
|
|
2248
|
+
const internalValue = (input) => canonicalValue(input, INTERNAL_CALL);
|
|
2249
|
+
entry.internalValue = internalValue;
|
|
2250
|
+
entry.bindInternal = (ctx) => ctx ? (input) => canonicalValue(input, childCallContext(ctx)) : internalValue;
|
|
2152
2251
|
}
|
|
2153
2252
|
plugins[id] = entry;
|
|
2154
2253
|
}
|
|
@@ -2388,7 +2487,7 @@ function createSdk(root, options) {
|
|
|
2388
2487
|
pluginSurface = {};
|
|
2389
2488
|
bindValue(pluginSurface, plugin.name, plugins2[plugin.id]);
|
|
2390
2489
|
}
|
|
2391
|
-
for (const
|
|
2490
|
+
for (const key of Object.keys(legacyExports)) context.surface[key] = key;
|
|
2392
2491
|
if (plugin.pluginType === "aggregate") {
|
|
2393
2492
|
recordExportSurface(context, plugin.exports);
|
|
2394
2493
|
} else {
|
|
@@ -2519,6 +2618,7 @@ function valueTypeOf(inner) {
|
|
|
2519
2618
|
if (inner instanceof zod.z.ZodEnum) return "string";
|
|
2520
2619
|
if (inner instanceof zod.z.ZodArray) return "array";
|
|
2521
2620
|
if (inner instanceof zod.z.ZodObject) return "object";
|
|
2621
|
+
if (inner instanceof zod.z.ZodRecord) return "object";
|
|
2522
2622
|
return void 0;
|
|
2523
2623
|
}
|
|
2524
2624
|
function staticChoicesOf(inner) {
|
|
@@ -2529,7 +2629,8 @@ function staticChoicesOf(inner) {
|
|
|
2529
2629
|
return void 0;
|
|
2530
2630
|
}
|
|
2531
2631
|
function objectShape(schema) {
|
|
2532
|
-
const
|
|
2632
|
+
const canonical = canonicalInputSchema(schema);
|
|
2633
|
+
const { inner } = canonical ? unwrap(canonical) : { inner: void 0 };
|
|
2533
2634
|
if (inner instanceof zod.z.ZodObject) {
|
|
2534
2635
|
return inner.shape;
|
|
2535
2636
|
}
|
|
@@ -2551,7 +2652,7 @@ function topoOrder2(specs) {
|
|
|
2551
2652
|
}
|
|
2552
2653
|
function planParameters(entry) {
|
|
2553
2654
|
const shape = objectShape(entry.inputSchema);
|
|
2554
|
-
const resolvers = entry.
|
|
2655
|
+
const resolvers = entry.resolvers ?? {};
|
|
2555
2656
|
const names = shape ? [
|
|
2556
2657
|
...Object.keys(shape),
|
|
2557
2658
|
...Object.keys(resolvers).filter(
|
|
@@ -2587,24 +2688,48 @@ function getAtPath(root, path) {
|
|
|
2587
2688
|
}
|
|
2588
2689
|
return node;
|
|
2589
2690
|
}
|
|
2691
|
+
function defineOwn(node, key, value) {
|
|
2692
|
+
Object.defineProperty(node, key, {
|
|
2693
|
+
value,
|
|
2694
|
+
writable: true,
|
|
2695
|
+
enumerable: true,
|
|
2696
|
+
configurable: true
|
|
2697
|
+
});
|
|
2698
|
+
}
|
|
2590
2699
|
function setAtPath(root, path, value) {
|
|
2591
2700
|
let node = root;
|
|
2592
2701
|
for (let i = 0; i < path.length - 1; i++) {
|
|
2593
2702
|
const seg = path[i];
|
|
2594
|
-
|
|
2595
|
-
|
|
2703
|
+
const existing = Object.prototype.hasOwnProperty.call(node, seg) ? node[seg] : void 0;
|
|
2704
|
+
if (existing != null && typeof existing === "object") {
|
|
2705
|
+
node = existing;
|
|
2706
|
+
} else {
|
|
2707
|
+
const child = {};
|
|
2708
|
+
defineOwn(node, seg, child);
|
|
2709
|
+
node = child;
|
|
2710
|
+
}
|
|
2596
2711
|
}
|
|
2597
|
-
node
|
|
2712
|
+
defineOwn(node, path[path.length - 1], value);
|
|
2598
2713
|
}
|
|
2599
|
-
var
|
|
2714
|
+
var SAFE_SEGMENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
2715
|
+
var pathToKey = (path) => {
|
|
2716
|
+
let out = "";
|
|
2717
|
+
for (const segment of path) {
|
|
2718
|
+
if (typeof segment === "number") out += `[${segment}]`;
|
|
2719
|
+
else if (SAFE_SEGMENT.test(segment))
|
|
2720
|
+
out += out === "" ? segment : `.${segment}`;
|
|
2721
|
+
else out += `[${JSON.stringify(segment)}]`;
|
|
2722
|
+
}
|
|
2723
|
+
return out;
|
|
2724
|
+
};
|
|
2600
2725
|
function isSettled(state, path) {
|
|
2601
|
-
return state.settled.includes(
|
|
2726
|
+
return state.settled.includes(pathToKey(path));
|
|
2602
2727
|
}
|
|
2603
2728
|
function remember(state, k) {
|
|
2604
2729
|
if (!state.settled.includes(k)) state.settled.push(k);
|
|
2605
2730
|
}
|
|
2606
2731
|
function settle(state, path) {
|
|
2607
|
-
remember(state,
|
|
2732
|
+
remember(state, pathToKey(path));
|
|
2608
2733
|
}
|
|
2609
2734
|
function clone(state) {
|
|
2610
2735
|
return JSON.parse(JSON.stringify(state));
|
|
@@ -2619,6 +2744,28 @@ function coerce(leaf, raw) {
|
|
|
2619
2744
|
if (raw === "true") return true;
|
|
2620
2745
|
if (raw === "false") return false;
|
|
2621
2746
|
}
|
|
2747
|
+
if (leaf.valueType === "object") {
|
|
2748
|
+
const trimmed = raw.trim();
|
|
2749
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
2750
|
+
try {
|
|
2751
|
+
return JSON.parse(trimmed);
|
|
2752
|
+
} catch {
|
|
2753
|
+
return raw;
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
return raw;
|
|
2757
|
+
}
|
|
2758
|
+
if (leaf.valueType === "array") {
|
|
2759
|
+
const trimmed = raw.trim();
|
|
2760
|
+
if (trimmed.startsWith("[")) {
|
|
2761
|
+
try {
|
|
2762
|
+
return JSON.parse(trimmed);
|
|
2763
|
+
} catch {
|
|
2764
|
+
return raw;
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
return raw;
|
|
2768
|
+
}
|
|
2622
2769
|
return raw;
|
|
2623
2770
|
}
|
|
2624
2771
|
async function validationError(leaf, value, state) {
|
|
@@ -2676,27 +2823,6 @@ async function objectChildren(resolver, input) {
|
|
|
2676
2823
|
return toLeaf(name, field, resolver.definitions);
|
|
2677
2824
|
});
|
|
2678
2825
|
}
|
|
2679
|
-
function arrayItem(resolver) {
|
|
2680
|
-
const items = resolver.items;
|
|
2681
|
-
const valueType = resolver.itemValueType;
|
|
2682
|
-
if (isRef(items)) {
|
|
2683
|
-
return {
|
|
2684
|
-
name: "",
|
|
2685
|
-
required: true,
|
|
2686
|
-
resolver: resolver.definitions?.[items.ref],
|
|
2687
|
-
extraInput: items.input,
|
|
2688
|
-
valueType,
|
|
2689
|
-
requires: []
|
|
2690
|
-
};
|
|
2691
|
-
}
|
|
2692
|
-
return {
|
|
2693
|
-
name: "",
|
|
2694
|
-
required: true,
|
|
2695
|
-
resolver: items,
|
|
2696
|
-
valueType,
|
|
2697
|
-
requires: []
|
|
2698
|
-
};
|
|
2699
|
-
}
|
|
2700
2826
|
function autoSettles(resolver) {
|
|
2701
2827
|
return resolver.type === "constant" || resolver.type === "info";
|
|
2702
2828
|
}
|
|
@@ -2716,10 +2842,28 @@ async function leafAt(ctx, path, resolved) {
|
|
|
2716
2842
|
const seg = path[i];
|
|
2717
2843
|
if (typeof seg === "number") {
|
|
2718
2844
|
if (leaf?.resolver?.type !== "array") return void 0;
|
|
2719
|
-
leaf =
|
|
2845
|
+
leaf = boundLeaf(
|
|
2846
|
+
"",
|
|
2847
|
+
leaf.resolver.items,
|
|
2848
|
+
leaf.resolver.definitions,
|
|
2849
|
+
leaf.resolver.itemValueType
|
|
2850
|
+
);
|
|
2720
2851
|
} else {
|
|
2721
|
-
|
|
2722
|
-
|
|
2852
|
+
const parent = leaf;
|
|
2853
|
+
const found = children.find((c) => c.name === seg);
|
|
2854
|
+
if (found) {
|
|
2855
|
+
leaf = found;
|
|
2856
|
+
} else if (parent?.resolver?.type === "object" && parent.resolver.additionalKeys) {
|
|
2857
|
+
const ak = parent.resolver.additionalKeys;
|
|
2858
|
+
leaf = boundLeaf(
|
|
2859
|
+
String(seg),
|
|
2860
|
+
ak.values,
|
|
2861
|
+
parent.resolver.definitions,
|
|
2862
|
+
ak.valueValueType
|
|
2863
|
+
);
|
|
2864
|
+
} else {
|
|
2865
|
+
return void 0;
|
|
2866
|
+
}
|
|
2723
2867
|
}
|
|
2724
2868
|
if (i < path.length - 1 && typeof path[i + 1] === "string") {
|
|
2725
2869
|
if (leaf?.resolver?.type !== "object") return void 0;
|
|
@@ -2731,16 +2875,81 @@ async function leafAt(ctx, path, resolved) {
|
|
|
2731
2875
|
}
|
|
2732
2876
|
return leaf;
|
|
2733
2877
|
}
|
|
2878
|
+
function boundLeaf(name, resolverOrRef, definitions, valueType) {
|
|
2879
|
+
if (isRef(resolverOrRef)) {
|
|
2880
|
+
return {
|
|
2881
|
+
name,
|
|
2882
|
+
required: true,
|
|
2883
|
+
resolver: definitions?.[resolverOrRef.ref],
|
|
2884
|
+
extraInput: resolverOrRef.input,
|
|
2885
|
+
valueType,
|
|
2886
|
+
requires: []
|
|
2887
|
+
};
|
|
2888
|
+
}
|
|
2889
|
+
return {
|
|
2890
|
+
name,
|
|
2891
|
+
required: true,
|
|
2892
|
+
resolver: resolverOrRef,
|
|
2893
|
+
valueType,
|
|
2894
|
+
requires: []
|
|
2895
|
+
};
|
|
2896
|
+
}
|
|
2897
|
+
async function recordInfoAt(ctx, path, resolved) {
|
|
2898
|
+
const leaf = await leafAt(ctx, path, resolved);
|
|
2899
|
+
const resolver = leaf?.resolver;
|
|
2900
|
+
if (resolver?.type !== "object" || !resolver.additionalKeys) {
|
|
2901
|
+
throw new Error(
|
|
2902
|
+
`expected an object resolver with additionalKeys at "${pathToKey(path)}"`
|
|
2903
|
+
);
|
|
2904
|
+
}
|
|
2905
|
+
if (resolver.getProperties) {
|
|
2906
|
+
throw new Error(
|
|
2907
|
+
`object resolver at "${pathToKey(path)}" cannot combine getProperties with additionalKeys`
|
|
2908
|
+
);
|
|
2909
|
+
}
|
|
2910
|
+
const ak = resolver.additionalKeys;
|
|
2911
|
+
const defs = resolver.definitions;
|
|
2912
|
+
const keyLeaf = ak.keys ? boundLeaf("key", ak.keys, defs, ak.keyValueType ?? "string") : {
|
|
2913
|
+
name: "key",
|
|
2914
|
+
required: true,
|
|
2915
|
+
resolver: { type: "static", inputType: "text" },
|
|
2916
|
+
valueType: "string",
|
|
2917
|
+
requires: []
|
|
2918
|
+
};
|
|
2919
|
+
const valueLeaf = boundLeaf("value", ak.values, defs, ak.valueValueType);
|
|
2920
|
+
if (keyLeaf.resolver && keyLeaf.resolver.type !== "static") {
|
|
2921
|
+
throw new Error(
|
|
2922
|
+
`record key resolver at "${pathToKey(path)}" must be a static free-text prompt, not "${keyLeaf.resolver.type}"`
|
|
2923
|
+
);
|
|
2924
|
+
}
|
|
2925
|
+
if (valueLeaf.resolver?.type === "object" || valueLeaf.resolver?.type === "array") {
|
|
2926
|
+
throw new Error(
|
|
2927
|
+
`record value resolver at "${pathToKey(path)}" must be a single value, not "${valueLeaf.resolver.type}"`
|
|
2928
|
+
);
|
|
2929
|
+
}
|
|
2930
|
+
return {
|
|
2931
|
+
min: ak.minEntries ?? 0,
|
|
2932
|
+
max: ak.maxEntries ?? Infinity,
|
|
2933
|
+
keyLeaf,
|
|
2934
|
+
valueLeaf,
|
|
2935
|
+
fixedKeys: Object.keys(resolver.properties ?? {})
|
|
2936
|
+
};
|
|
2937
|
+
}
|
|
2734
2938
|
async function arrayInfoAt(ctx, path, resolved) {
|
|
2735
2939
|
const leaf = await leafAt(ctx, path, resolved);
|
|
2736
2940
|
const resolver = leaf?.resolver;
|
|
2737
2941
|
if (resolver?.type !== "array") {
|
|
2738
|
-
throw new Error(`expected an array resolver at "${
|
|
2942
|
+
throw new Error(`expected an array resolver at "${pathToKey(path)}"`);
|
|
2739
2943
|
}
|
|
2740
2944
|
return {
|
|
2741
2945
|
min: resolver.minItems ?? 0,
|
|
2742
2946
|
max: resolver.maxItems ?? Infinity,
|
|
2743
|
-
item:
|
|
2947
|
+
item: boundLeaf(
|
|
2948
|
+
String(path[path.length - 1]),
|
|
2949
|
+
resolver.items,
|
|
2950
|
+
resolver.definitions,
|
|
2951
|
+
resolver.itemValueType
|
|
2952
|
+
)
|
|
2744
2953
|
};
|
|
2745
2954
|
}
|
|
2746
2955
|
async function firstPage(result) {
|
|
@@ -2819,6 +3028,9 @@ var AFFORDANCE = {
|
|
|
2819
3028
|
retry: { action: "retry", description: "Retry loading the options" },
|
|
2820
3029
|
cancel: { action: "cancel", description: "Cancel resolution" }
|
|
2821
3030
|
};
|
|
3031
|
+
function affordance(base, description) {
|
|
3032
|
+
return { ...base, description };
|
|
3033
|
+
}
|
|
2822
3034
|
function selectActions(leaf, page, multiple) {
|
|
2823
3035
|
const searchMode = leaf.resolver?.type === "dynamic" && leaf.resolver.inputType === "search";
|
|
2824
3036
|
if (searchMode && page.position.search === void 0 && page.items.length === 0) {
|
|
@@ -2933,7 +3145,7 @@ async function buildQuestion(leaf, path, input) {
|
|
|
2933
3145
|
}
|
|
2934
3146
|
};
|
|
2935
3147
|
}
|
|
2936
|
-
function
|
|
3148
|
+
function arrayItemsQuestion(t) {
|
|
2937
3149
|
const actions = [AFFORDANCE.add];
|
|
2938
3150
|
if (t.count >= t.min) actions.push(AFFORDANCE.done);
|
|
2939
3151
|
return {
|
|
@@ -2949,22 +3161,37 @@ function collectionQuestion(t) {
|
|
|
2949
3161
|
actions
|
|
2950
3162
|
};
|
|
2951
3163
|
}
|
|
2952
|
-
function
|
|
3164
|
+
function recordEntriesQuestion(t) {
|
|
3165
|
+
const actions = [
|
|
3166
|
+
affordance(AFFORDANCE.add, "Add another entry")
|
|
3167
|
+
];
|
|
3168
|
+
if (t.count >= t.min) {
|
|
3169
|
+
actions.push(affordance(AFFORDANCE.done, "Finish the entries"));
|
|
3170
|
+
}
|
|
3171
|
+
return {
|
|
3172
|
+
type: "collection",
|
|
3173
|
+
path: t.path,
|
|
3174
|
+
message: `Add another ${t.path[t.path.length - 1]} entry? (${t.count} so far)`,
|
|
3175
|
+
container: "record",
|
|
3176
|
+
count: t.count,
|
|
3177
|
+
min: t.min,
|
|
3178
|
+
...Number.isFinite(t.max) ? { max: t.max } : {},
|
|
3179
|
+
actions
|
|
3180
|
+
};
|
|
3181
|
+
}
|
|
3182
|
+
function objectOptionalQuestion(path) {
|
|
2953
3183
|
return {
|
|
2954
3184
|
type: "collection",
|
|
2955
3185
|
path,
|
|
2956
3186
|
message: `Add ${path[path.length - 1]}?`,
|
|
2957
3187
|
container: "object",
|
|
2958
3188
|
actions: [
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
description: "Provide values for these fields"
|
|
2962
|
-
},
|
|
2963
|
-
{ action: "done", description: "Skip these fields" }
|
|
3189
|
+
affordance(AFFORDANCE.add, "Provide values for these fields"),
|
|
3190
|
+
affordance(AFFORDANCE.done, "Skip these fields")
|
|
2964
3191
|
]
|
|
2965
3192
|
};
|
|
2966
3193
|
}
|
|
2967
|
-
function
|
|
3194
|
+
function objectOptionalPropertiesQuestion(path, pending) {
|
|
2968
3195
|
return {
|
|
2969
3196
|
type: "collection",
|
|
2970
3197
|
path,
|
|
@@ -2981,8 +3208,8 @@ function optionalsGateQuestion(path, pending) {
|
|
|
2981
3208
|
...leaf.valueType ? { valueType: leaf.valueType } : {}
|
|
2982
3209
|
})),
|
|
2983
3210
|
actions: [
|
|
2984
|
-
|
|
2985
|
-
|
|
3211
|
+
affordance(AFFORDANCE.add, "Configure the optional fields"),
|
|
3212
|
+
affordance(AFFORDANCE.done, "Skip the optional fields")
|
|
2986
3213
|
]
|
|
2987
3214
|
};
|
|
2988
3215
|
}
|
|
@@ -2998,7 +3225,8 @@ function finalize(ctx, resolved) {
|
|
|
2998
3225
|
}));
|
|
2999
3226
|
return { status: "invalid", issues };
|
|
3000
3227
|
}
|
|
3001
|
-
var optionalsMarker = (path) => `${
|
|
3228
|
+
var optionalsMarker = (path) => `${pathToKey(path)}?optionals`;
|
|
3229
|
+
var UNSAFE_RECORD_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
3002
3230
|
async function findInArray(ctx, state, path) {
|
|
3003
3231
|
if (isSettled(state, path)) return null;
|
|
3004
3232
|
if (getAtPath(state.resolved, path) == null)
|
|
@@ -3019,7 +3247,28 @@ async function findInArray(ctx, state, path) {
|
|
|
3019
3247
|
}
|
|
3020
3248
|
}
|
|
3021
3249
|
if (len < min) return descendItem(ctx, state, path, len, item);
|
|
3022
|
-
if (len < max) return {
|
|
3250
|
+
if (len < max) return { type: "array_items", path, count: len, min, max };
|
|
3251
|
+
settle(state, path);
|
|
3252
|
+
return null;
|
|
3253
|
+
}
|
|
3254
|
+
async function findInRecord(ctx, state, path) {
|
|
3255
|
+
if (isSettled(state, path)) return null;
|
|
3256
|
+
if (getAtPath(state.resolved, path) == null)
|
|
3257
|
+
setAtPath(state.resolved, path, {});
|
|
3258
|
+
if (!state.interactive) {
|
|
3259
|
+
settle(state, path);
|
|
3260
|
+
return null;
|
|
3261
|
+
}
|
|
3262
|
+
const { min, max, keyLeaf, fixedKeys } = await recordInfoAt(
|
|
3263
|
+
ctx,
|
|
3264
|
+
path,
|
|
3265
|
+
state.resolved
|
|
3266
|
+
);
|
|
3267
|
+
const container = getAtPath(state.resolved, path);
|
|
3268
|
+
const fixed = new Set(fixedKeys);
|
|
3269
|
+
const count = Object.keys(container).filter((k) => !fixed.has(k)).length;
|
|
3270
|
+
if (count < min) return { type: "record_key", path, leaf: keyLeaf };
|
|
3271
|
+
if (count < max) return { type: "record_entries", path, count, min, max };
|
|
3023
3272
|
settle(state, path);
|
|
3024
3273
|
return null;
|
|
3025
3274
|
}
|
|
@@ -3037,10 +3286,10 @@ function seedItemSlot(state, itemPath, item) {
|
|
|
3037
3286
|
}
|
|
3038
3287
|
async function descendItem(ctx, state, arrayPath, index, item) {
|
|
3039
3288
|
const itemPath = [...arrayPath, index];
|
|
3040
|
-
const
|
|
3041
|
-
if (
|
|
3042
|
-
if (
|
|
3043
|
-
return {
|
|
3289
|
+
const slotType = seedItemSlot(state, itemPath, item);
|
|
3290
|
+
if (slotType === "object") return findNext(ctx, state, itemPath);
|
|
3291
|
+
if (slotType === "array") return findInArray(ctx, state, itemPath);
|
|
3292
|
+
return { type: "leaf", path: itemPath, leaf: item };
|
|
3044
3293
|
}
|
|
3045
3294
|
async function findNext(ctx, state, path = []) {
|
|
3046
3295
|
const container = getAtPath(state.resolved, path) ?? {};
|
|
@@ -3065,7 +3314,7 @@ async function findNext(ctx, state, path = []) {
|
|
|
3065
3314
|
const pending = ordered.filter(
|
|
3066
3315
|
(c) => !c.required && asksUser(c) && isPendingChild(c)
|
|
3067
3316
|
);
|
|
3068
|
-
return {
|
|
3317
|
+
return { type: "object_optional_properties", path, pending };
|
|
3069
3318
|
}
|
|
3070
3319
|
if (leaf.resolver?.type === "object") {
|
|
3071
3320
|
if (isSettled(state, childPath)) continue;
|
|
@@ -3075,7 +3324,7 @@ async function findNext(ctx, state, path = []) {
|
|
|
3075
3324
|
settle(state, childPath);
|
|
3076
3325
|
continue;
|
|
3077
3326
|
}
|
|
3078
|
-
return {
|
|
3327
|
+
return { type: "object_optional", path: childPath, leaf };
|
|
3079
3328
|
}
|
|
3080
3329
|
setAtPath(state.resolved, childPath, {});
|
|
3081
3330
|
}
|
|
@@ -3107,13 +3356,21 @@ async function findNext(ctx, state, path = []) {
|
|
|
3107
3356
|
}
|
|
3108
3357
|
if (container[leaf.name] !== void 0 || isSettled(state, childPath))
|
|
3109
3358
|
continue;
|
|
3110
|
-
return {
|
|
3359
|
+
return { type: "leaf", path: childPath, leaf };
|
|
3360
|
+
}
|
|
3361
|
+
if (inObject && !isSettled(state, path)) {
|
|
3362
|
+
const self = await leafAt(ctx, path, state.resolved);
|
|
3363
|
+
if (self?.resolver?.type === "object" && self.resolver.additionalKeys) {
|
|
3364
|
+
const rec = await findInRecord(ctx, state, path);
|
|
3365
|
+
if (rec) return rec;
|
|
3366
|
+
}
|
|
3111
3367
|
}
|
|
3112
3368
|
return null;
|
|
3113
3369
|
}
|
|
3114
3370
|
async function askLeaf(state, path, leaf, opts = {}) {
|
|
3115
3371
|
state.current = path;
|
|
3116
|
-
|
|
3372
|
+
if (opts.gate) state.gate = opts.gate;
|
|
3373
|
+
else delete state.gate;
|
|
3117
3374
|
try {
|
|
3118
3375
|
const { question, pagination } = await buildQuestion(
|
|
3119
3376
|
leaf,
|
|
@@ -3134,6 +3391,28 @@ async function askLeaf(state, path, leaf, opts = {}) {
|
|
|
3134
3391
|
return failedResult(state, leaf.name, error);
|
|
3135
3392
|
}
|
|
3136
3393
|
}
|
|
3394
|
+
async function askRecordKey(state, path, keyLeaf, opts = {}) {
|
|
3395
|
+
return askLeaf(state, path, keyLeaf, { gate: "record_key", ...opts });
|
|
3396
|
+
}
|
|
3397
|
+
async function autoResolveLeaf(state, path, leaf) {
|
|
3398
|
+
const resolver = leaf.resolver;
|
|
3399
|
+
if (resolver && autoSettles(resolver)) {
|
|
3400
|
+
if (resolver.type === "constant")
|
|
3401
|
+
setAtPath(state.resolved, path, resolver.value);
|
|
3402
|
+
settle(state, path);
|
|
3403
|
+
return true;
|
|
3404
|
+
}
|
|
3405
|
+
const auto = resolver?.type === "dynamic" ? await resolver.tryResolveWithoutPrompt?.({
|
|
3406
|
+
input: mergeInput(state.resolved, leaf.extraInput)
|
|
3407
|
+
}) : void 0;
|
|
3408
|
+
if (auto) {
|
|
3409
|
+
if (auto.resolvedValue !== void 0)
|
|
3410
|
+
setAtPath(state.resolved, path, auto.resolvedValue);
|
|
3411
|
+
settle(state, path);
|
|
3412
|
+
return true;
|
|
3413
|
+
}
|
|
3414
|
+
return false;
|
|
3415
|
+
}
|
|
3137
3416
|
async function advance(ctx, state) {
|
|
3138
3417
|
for (; ; ) {
|
|
3139
3418
|
const target = await findNext(ctx, state);
|
|
@@ -3143,54 +3422,56 @@ async function advance(ctx, state) {
|
|
|
3143
3422
|
delete state.pagination;
|
|
3144
3423
|
return { state, result: finalize(ctx, state.resolved) };
|
|
3145
3424
|
}
|
|
3146
|
-
if (target.
|
|
3425
|
+
if (target.type === "array_items") {
|
|
3147
3426
|
state.current = target.path;
|
|
3148
|
-
state.gate = "
|
|
3427
|
+
state.gate = "array_items";
|
|
3149
3428
|
delete state.pagination;
|
|
3150
3429
|
return {
|
|
3151
3430
|
state,
|
|
3152
|
-
result: { status: "ask", question:
|
|
3431
|
+
result: { status: "ask", question: arrayItemsQuestion(target) }
|
|
3153
3432
|
};
|
|
3154
3433
|
}
|
|
3155
|
-
if (target.
|
|
3434
|
+
if (target.type === "object_optional") {
|
|
3156
3435
|
state.current = target.path;
|
|
3157
|
-
state.gate = "
|
|
3436
|
+
state.gate = "object_optional";
|
|
3158
3437
|
delete state.pagination;
|
|
3159
3438
|
return {
|
|
3160
3439
|
state,
|
|
3161
|
-
result: {
|
|
3440
|
+
result: {
|
|
3441
|
+
status: "ask",
|
|
3442
|
+
question: objectOptionalQuestion(target.path)
|
|
3443
|
+
}
|
|
3162
3444
|
};
|
|
3163
3445
|
}
|
|
3164
|
-
if (target.
|
|
3446
|
+
if (target.type === "object_optional_properties") {
|
|
3165
3447
|
state.current = target.path;
|
|
3166
|
-
state.gate = "
|
|
3448
|
+
state.gate = "object_optional_properties";
|
|
3167
3449
|
delete state.pagination;
|
|
3168
3450
|
return {
|
|
3169
3451
|
state,
|
|
3170
3452
|
result: {
|
|
3171
3453
|
status: "ask",
|
|
3172
|
-
question:
|
|
3454
|
+
question: objectOptionalPropertiesQuestion(
|
|
3455
|
+
target.path,
|
|
3456
|
+
target.pending
|
|
3457
|
+
)
|
|
3173
3458
|
}
|
|
3174
3459
|
};
|
|
3175
3460
|
}
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3461
|
+
if (target.type === "record_entries") {
|
|
3462
|
+
state.current = target.path;
|
|
3463
|
+
state.gate = "record_entries";
|
|
3464
|
+
delete state.pagination;
|
|
3465
|
+
return {
|
|
3466
|
+
state,
|
|
3467
|
+
result: { status: "ask", question: recordEntriesQuestion(target) }
|
|
3468
|
+
};
|
|
3184
3469
|
}
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
}) : void 0;
|
|
3188
|
-
if (auto) {
|
|
3189
|
-
if (auto.resolvedValue !== void 0)
|
|
3190
|
-
setAtPath(state.resolved, path, auto.resolvedValue);
|
|
3191
|
-
settle(state, path);
|
|
3192
|
-
continue;
|
|
3470
|
+
if (target.type === "record_key") {
|
|
3471
|
+
return askRecordKey(state, target.path, target.leaf);
|
|
3193
3472
|
}
|
|
3473
|
+
const { path, leaf } = target;
|
|
3474
|
+
if (await autoResolveLeaf(state, path, leaf)) continue;
|
|
3194
3475
|
if (!state.interactive) {
|
|
3195
3476
|
if (!leaf.required) {
|
|
3196
3477
|
settle(state, path);
|
|
@@ -3223,10 +3504,18 @@ async function step(ctx, prior, action) {
|
|
|
3223
3504
|
delete state.pagination;
|
|
3224
3505
|
return { state, result: { status: "cancelled" } };
|
|
3225
3506
|
}
|
|
3507
|
+
if (state.gate === "record_key") {
|
|
3508
|
+
return stepRecordKey(ctx, state, action);
|
|
3509
|
+
}
|
|
3226
3510
|
const path = state.current;
|
|
3227
3511
|
if (!path) throw new Error("step called with no outstanding question");
|
|
3228
3512
|
const leaf = await leafAt(ctx, path, state.resolved);
|
|
3229
|
-
if (leaf
|
|
3513
|
+
if (!leaf) {
|
|
3514
|
+
throw new Error(
|
|
3515
|
+
`no resolver for the outstanding question at "${pathToKey(path)}"`
|
|
3516
|
+
);
|
|
3517
|
+
}
|
|
3518
|
+
if (action.type === "search" || action.type === "next_page" || action.type === "previous_page" || action.type === "retry") {
|
|
3230
3519
|
return refine(ctx, state, leaf, path, action);
|
|
3231
3520
|
}
|
|
3232
3521
|
if (action.type === "add" || action.type === "done") {
|
|
@@ -3243,19 +3532,26 @@ async function step(ctx, prior, action) {
|
|
|
3243
3532
|
settle(state, path);
|
|
3244
3533
|
return advance(ctx, state);
|
|
3245
3534
|
}
|
|
3246
|
-
if (gate === "
|
|
3535
|
+
if (gate === "object_optional") {
|
|
3247
3536
|
setAtPath(state.resolved, path, {});
|
|
3248
3537
|
return advance(ctx, state);
|
|
3249
3538
|
}
|
|
3250
|
-
if (gate === "
|
|
3539
|
+
if (gate === "object_optional_properties") {
|
|
3251
3540
|
remember(state, optionalsMarker(path));
|
|
3252
3541
|
return advance(ctx, state);
|
|
3253
3542
|
}
|
|
3543
|
+
if (gate === "record_entries") {
|
|
3544
|
+
const { keyLeaf } = await recordInfoAt(ctx, path, state.resolved);
|
|
3545
|
+
return askRecordKey(state, path, keyLeaf);
|
|
3546
|
+
}
|
|
3254
3547
|
const items = getAtPath(state.resolved, path) ?? [];
|
|
3255
3548
|
const { item } = await arrayInfoAt(ctx, path, state.resolved);
|
|
3256
3549
|
const itemPath = [...path, items.length];
|
|
3257
|
-
if (seedItemSlot(state, itemPath, item) === "leaf")
|
|
3550
|
+
if (seedItemSlot(state, itemPath, item) === "leaf") {
|
|
3551
|
+
if (await autoResolveLeaf(state, itemPath, item))
|
|
3552
|
+
return advance(ctx, state);
|
|
3258
3553
|
return askLeaf(state, itemPath, item);
|
|
3554
|
+
}
|
|
3259
3555
|
return advance(ctx, state);
|
|
3260
3556
|
}
|
|
3261
3557
|
if (state.gate) {
|
|
@@ -3266,81 +3562,37 @@ async function step(ctx, prior, action) {
|
|
|
3266
3562
|
switch (action.type) {
|
|
3267
3563
|
case "choose":
|
|
3268
3564
|
case "custom": {
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
if (
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
const page = await fetchListing(
|
|
3281
|
-
leaf,
|
|
3282
|
-
state.resolved,
|
|
3283
|
-
state.pagination.position,
|
|
3284
|
-
context
|
|
3285
|
-
);
|
|
3286
|
-
state.pagination = toPagination(page);
|
|
3287
|
-
return {
|
|
3288
|
-
state,
|
|
3289
|
-
result: {
|
|
3290
|
-
status: "ask",
|
|
3291
|
-
question: selectQuestion(
|
|
3292
|
-
leaf,
|
|
3293
|
-
path,
|
|
3294
|
-
state.resolved,
|
|
3295
|
-
page,
|
|
3296
|
-
context
|
|
3297
|
-
),
|
|
3298
|
-
error
|
|
3299
|
-
}
|
|
3300
|
-
};
|
|
3301
|
-
} catch (fetchError) {
|
|
3302
|
-
state.pagination = failedPagination(
|
|
3303
|
-
state.pagination,
|
|
3304
|
-
state.pagination.position
|
|
3305
|
-
);
|
|
3306
|
-
return failedResult(state, leaf.name, fetchError);
|
|
3307
|
-
}
|
|
3308
|
-
}
|
|
3309
|
-
return askLeaf(state, path, leaf, { error });
|
|
3565
|
+
let error;
|
|
3566
|
+
try {
|
|
3567
|
+
error = await validationError(leaf, action.value, state);
|
|
3568
|
+
} catch (thrown) {
|
|
3569
|
+
return failedResult(state, leaf.name, thrown);
|
|
3570
|
+
}
|
|
3571
|
+
if (error) {
|
|
3572
|
+
if (state.pagination && leaf.resolver?.type === "dynamic") {
|
|
3573
|
+
return renderPageAt(state, leaf, path, state.pagination.position, {
|
|
3574
|
+
error
|
|
3575
|
+
});
|
|
3310
3576
|
}
|
|
3577
|
+
return askLeaf(state, path, leaf, { error });
|
|
3311
3578
|
}
|
|
3312
|
-
setAtPath(
|
|
3313
|
-
state.resolved,
|
|
3314
|
-
path,
|
|
3315
|
-
leaf ? coerce(leaf, action.value) : action.value
|
|
3316
|
-
);
|
|
3579
|
+
setAtPath(state.resolved, path, coerce(leaf, action.value));
|
|
3317
3580
|
break;
|
|
3318
3581
|
}
|
|
3319
3582
|
case "skip":
|
|
3320
3583
|
settle(state, path);
|
|
3321
3584
|
break;
|
|
3322
3585
|
default:
|
|
3323
|
-
throw new Error(
|
|
3586
|
+
throw new Error(
|
|
3587
|
+
`action "${action.type}" is not supported here`
|
|
3588
|
+
);
|
|
3324
3589
|
}
|
|
3325
3590
|
delete state.current;
|
|
3326
3591
|
delete state.pagination;
|
|
3327
3592
|
return advance(ctx, state);
|
|
3328
3593
|
}
|
|
3329
|
-
async function
|
|
3330
|
-
const position = positionAfter(state.pagination, action);
|
|
3594
|
+
async function renderPageAt(state, leaf, path, position, opts = {}) {
|
|
3331
3595
|
try {
|
|
3332
|
-
if (action.type === "search") {
|
|
3333
|
-
const exact = leaf.resolver?.type === "dynamic" ? await leaf.resolver.tryResolveFromSearch?.({
|
|
3334
|
-
input: mergeInput(state.resolved, leaf.extraInput),
|
|
3335
|
-
search: action.term
|
|
3336
|
-
}) : void 0;
|
|
3337
|
-
if (exact) {
|
|
3338
|
-
setAtPath(state.resolved, path, coerce(leaf, exact.resolvedValue));
|
|
3339
|
-
delete state.current;
|
|
3340
|
-
delete state.pagination;
|
|
3341
|
-
return advance(ctx, state);
|
|
3342
|
-
}
|
|
3343
|
-
}
|
|
3344
3596
|
const context = await resolveContext(leaf, state.resolved);
|
|
3345
3597
|
const page = await fetchListing(leaf, state.resolved, position, context);
|
|
3346
3598
|
state.pagination = toPagination(page);
|
|
@@ -3348,7 +3600,8 @@ async function refine(ctx, state, leaf, path, action) {
|
|
|
3348
3600
|
state,
|
|
3349
3601
|
result: {
|
|
3350
3602
|
status: "ask",
|
|
3351
|
-
question: selectQuestion(leaf, path, state.resolved, page, context)
|
|
3603
|
+
question: selectQuestion(leaf, path, state.resolved, page, context),
|
|
3604
|
+
...opts.error ? { error: opts.error } : {}
|
|
3352
3605
|
}
|
|
3353
3606
|
};
|
|
3354
3607
|
} catch (error) {
|
|
@@ -3356,6 +3609,65 @@ async function refine(ctx, state, leaf, path, action) {
|
|
|
3356
3609
|
return failedResult(state, leaf.name, error);
|
|
3357
3610
|
}
|
|
3358
3611
|
}
|
|
3612
|
+
async function refine(ctx, state, leaf, path, action) {
|
|
3613
|
+
const position = positionAfter(state.pagination, action);
|
|
3614
|
+
if (action.type === "search") {
|
|
3615
|
+
try {
|
|
3616
|
+
const exact = leaf.resolver?.type === "dynamic" ? await leaf.resolver.tryResolveFromSearch?.({
|
|
3617
|
+
input: mergeInput(state.resolved, leaf.extraInput),
|
|
3618
|
+
search: action.term
|
|
3619
|
+
}) : void 0;
|
|
3620
|
+
if (exact) {
|
|
3621
|
+
setAtPath(state.resolved, path, coerce(leaf, exact.resolvedValue));
|
|
3622
|
+
delete state.current;
|
|
3623
|
+
delete state.pagination;
|
|
3624
|
+
return advance(ctx, state);
|
|
3625
|
+
}
|
|
3626
|
+
} catch (error) {
|
|
3627
|
+
state.pagination = failedPagination(state.pagination, position);
|
|
3628
|
+
return failedResult(state, leaf.name, error);
|
|
3629
|
+
}
|
|
3630
|
+
}
|
|
3631
|
+
return renderPageAt(state, leaf, path, position);
|
|
3632
|
+
}
|
|
3633
|
+
async function stepRecordKey(ctx, state, action) {
|
|
3634
|
+
const path = state.current;
|
|
3635
|
+
if (!path)
|
|
3636
|
+
throw new Error("record key step called with no outstanding question");
|
|
3637
|
+
const { keyLeaf, valueLeaf } = await recordInfoAt(ctx, path, state.resolved);
|
|
3638
|
+
if (action.type === "skip") {
|
|
3639
|
+
delete state.gate;
|
|
3640
|
+
delete state.current;
|
|
3641
|
+
delete state.pagination;
|
|
3642
|
+
return advance(ctx, state);
|
|
3643
|
+
}
|
|
3644
|
+
if (action.type !== "custom" && action.type !== "choose") {
|
|
3645
|
+
throw new Error(
|
|
3646
|
+
`action "${action.type}" is not supported while entering a record key`
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3649
|
+
const raw = Array.isArray(action.value) ? action.value[0] : action.value;
|
|
3650
|
+
const entryKey = String(coerce(keyLeaf, raw));
|
|
3651
|
+
if (entryKey.trim() === "") {
|
|
3652
|
+
return askRecordKey(state, path, keyLeaf, { error: "A key is required." });
|
|
3653
|
+
}
|
|
3654
|
+
if (UNSAFE_RECORD_KEYS.has(entryKey)) {
|
|
3655
|
+
return askRecordKey(state, path, keyLeaf, {
|
|
3656
|
+
error: `"${entryKey}" is not an allowed key.`
|
|
3657
|
+
});
|
|
3658
|
+
}
|
|
3659
|
+
const container = getAtPath(state.resolved, path);
|
|
3660
|
+
if (Object.prototype.hasOwnProperty.call(container, entryKey)) {
|
|
3661
|
+
return askRecordKey(state, path, keyLeaf, {
|
|
3662
|
+
error: `"${entryKey}" is already set.`
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3665
|
+
const valuePath = [...path, entryKey];
|
|
3666
|
+
if (await autoResolveLeaf(state, valuePath, valueLeaf)) {
|
|
3667
|
+
return advance(ctx, state);
|
|
3668
|
+
}
|
|
3669
|
+
return askLeaf(state, valuePath, valueLeaf);
|
|
3670
|
+
}
|
|
3359
3671
|
function failedPagination(pagination, retryPosition) {
|
|
3360
3672
|
return {
|
|
3361
3673
|
position: pagination?.position ?? firstPagePosition(),
|
|
@@ -3409,7 +3721,7 @@ function projectSummary(entry) {
|
|
|
3409
3721
|
};
|
|
3410
3722
|
}
|
|
3411
3723
|
function projectMethod(entry) {
|
|
3412
|
-
const inputProperties = toJsonSchema(entry.inputSchema)?.properties;
|
|
3724
|
+
const inputProperties = toJsonSchema(canonicalInputSchema(entry.inputSchema))?.properties;
|
|
3413
3725
|
const parameters = {};
|
|
3414
3726
|
for (const spec of planParameters(entry).parameters) {
|
|
3415
3727
|
const dynamic = spec.resolver?.type === "dynamic" ? spec.resolver : void 0;
|
|
@@ -3442,7 +3754,12 @@ function createController(sdk) {
|
|
|
3442
3754
|
const entry = entryFor(method);
|
|
3443
3755
|
return {
|
|
3444
3756
|
method,
|
|
3445
|
-
|
|
3757
|
+
// A method that owns its input validation (`skipInputValidation`, e.g.
|
|
3758
|
+
// fetch) must not be re-validated by the controller's final `safeParse`;
|
|
3759
|
+
// drop the schema so `finalize` returns the resolved input untouched.
|
|
3760
|
+
// Planning still reads `entry.inputSchema` directly, so parameters are
|
|
3761
|
+
// unaffected.
|
|
3762
|
+
schema: entry.skipInputValidation ? void 0 : entry.inputSchema,
|
|
3446
3763
|
parameters: planParameters(entry).parameters
|
|
3447
3764
|
};
|
|
3448
3765
|
}
|
|
@@ -3505,27 +3822,6 @@ function createCorePlugin(options) {
|
|
|
3505
3822
|
}
|
|
3506
3823
|
});
|
|
3507
3824
|
}
|
|
3508
|
-
function withPositional(schema) {
|
|
3509
|
-
Object.assign(schema._zod.def, {
|
|
3510
|
-
positionalMeta: { positional: true }
|
|
3511
|
-
});
|
|
3512
|
-
return schema;
|
|
3513
|
-
}
|
|
3514
|
-
function schemaHasPositionalMeta(schema) {
|
|
3515
|
-
return "positionalMeta" in schema._zod.def;
|
|
3516
|
-
}
|
|
3517
|
-
function isPositional(schema) {
|
|
3518
|
-
if (schemaHasPositionalMeta(schema) && schema._zod.def.positionalMeta?.positional) {
|
|
3519
|
-
return true;
|
|
3520
|
-
}
|
|
3521
|
-
if (schema instanceof zod.z.ZodOptional) {
|
|
3522
|
-
return isPositional(schema._zod.def.innerType);
|
|
3523
|
-
}
|
|
3524
|
-
if (schema instanceof zod.z.ZodDefault) {
|
|
3525
|
-
return isPositional(schema._zod.def.innerType);
|
|
3526
|
-
}
|
|
3527
|
-
return false;
|
|
3528
|
-
}
|
|
3529
3825
|
|
|
3530
3826
|
// src/constants.ts
|
|
3531
3827
|
var ZAPIER_BASE_URL = globalThis.process?.env?.ZAPIER_BASE_URL || "https://zapier.com";
|
|
@@ -4080,8 +4376,8 @@ function censorHeaders(headers) {
|
|
|
4080
4376
|
if (!headers) return headers;
|
|
4081
4377
|
const headersObj = new Headers(headers);
|
|
4082
4378
|
const authKeys = ["authorization", "x-api-key"];
|
|
4083
|
-
for (const [
|
|
4084
|
-
if (authKeys.some((authKey) =>
|
|
4379
|
+
for (const [key, value] of headersObj.entries()) {
|
|
4380
|
+
if (authKeys.some((authKey) => key.toLowerCase() === authKey)) {
|
|
4085
4381
|
const spaceIndex = value.indexOf(" ");
|
|
4086
4382
|
if (spaceIndex > 0 && spaceIndex < value.length - 1) {
|
|
4087
4383
|
const prefix = value.substring(0, spaceIndex + 1);
|
|
@@ -4089,19 +4385,19 @@ function censorHeaders(headers) {
|
|
|
4089
4385
|
if (token.length > 12) {
|
|
4090
4386
|
const start2 = token.substring(0, 4);
|
|
4091
4387
|
const end = token.substring(token.length - 4);
|
|
4092
|
-
headersObj.set(
|
|
4388
|
+
headersObj.set(key, `${prefix}${start2}...${end}`);
|
|
4093
4389
|
} else {
|
|
4094
4390
|
const firstChar = token.charAt(0);
|
|
4095
|
-
headersObj.set(
|
|
4391
|
+
headersObj.set(key, `${prefix}${firstChar}...`);
|
|
4096
4392
|
}
|
|
4097
4393
|
} else {
|
|
4098
4394
|
if (value.length > 12) {
|
|
4099
4395
|
const start2 = value.substring(0, 4);
|
|
4100
4396
|
const end = value.substring(value.length - 4);
|
|
4101
|
-
headersObj.set(
|
|
4397
|
+
headersObj.set(key, `${start2}...${end}`);
|
|
4102
4398
|
} else {
|
|
4103
4399
|
const firstChar = value.charAt(0);
|
|
4104
|
-
headersObj.set(
|
|
4400
|
+
headersObj.set(key, `${firstChar}...`);
|
|
4105
4401
|
}
|
|
4106
4402
|
}
|
|
4107
4403
|
}
|
|
@@ -4752,21 +5048,21 @@ function getClientIdFromCredentials(credentials) {
|
|
|
4752
5048
|
function createMemoryCache() {
|
|
4753
5049
|
const store = /* @__PURE__ */ new Map();
|
|
4754
5050
|
return {
|
|
4755
|
-
async get(
|
|
4756
|
-
const entry = store.get(
|
|
5051
|
+
async get(key) {
|
|
5052
|
+
const entry = store.get(key);
|
|
4757
5053
|
if (!entry) return void 0;
|
|
4758
5054
|
if (entry.expiresAt !== void 0 && entry.expiresAt <= Date.now()) {
|
|
4759
|
-
store.delete(
|
|
5055
|
+
store.delete(key);
|
|
4760
5056
|
return void 0;
|
|
4761
5057
|
}
|
|
4762
5058
|
return { value: entry.value, expiresAt: entry.expiresAt };
|
|
4763
5059
|
},
|
|
4764
|
-
async set(
|
|
5060
|
+
async set(key, value, options) {
|
|
4765
5061
|
const expiresAt = options?.ttl ? Date.now() + options.ttl * 1e3 : void 0;
|
|
4766
|
-
store.set(
|
|
5062
|
+
store.set(key, { value, expiresAt });
|
|
4767
5063
|
},
|
|
4768
|
-
async delete(
|
|
4769
|
-
store.delete(
|
|
5064
|
+
async delete(key) {
|
|
5065
|
+
store.delete(key);
|
|
4770
5066
|
}
|
|
4771
5067
|
};
|
|
4772
5068
|
}
|
|
@@ -5429,7 +5725,7 @@ function parseDeprecationDate(value) {
|
|
|
5429
5725
|
}
|
|
5430
5726
|
|
|
5431
5727
|
// src/sdk-version.ts
|
|
5432
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.
|
|
5728
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.86.0" : void 0) || "unknown";
|
|
5433
5729
|
|
|
5434
5730
|
// src/utils/open-url.ts
|
|
5435
5731
|
var nodePrefix = "node:";
|
|
@@ -5687,11 +5983,11 @@ var ZapierApiClient = class {
|
|
|
5687
5983
|
);
|
|
5688
5984
|
const inputHeaders = new Headers(init?.headers ?? {});
|
|
5689
5985
|
const mergedHeaders = new Headers();
|
|
5690
|
-
builtHeaders.forEach((value,
|
|
5691
|
-
mergedHeaders.set(
|
|
5986
|
+
builtHeaders.forEach((value, key) => {
|
|
5987
|
+
mergedHeaders.set(key, value);
|
|
5692
5988
|
});
|
|
5693
|
-
inputHeaders.forEach((value,
|
|
5694
|
-
mergedHeaders.set(
|
|
5989
|
+
inputHeaders.forEach((value, key) => {
|
|
5990
|
+
mergedHeaders.set(key, value);
|
|
5695
5991
|
});
|
|
5696
5992
|
this.applyTelemetryHeaders(mergedHeaders);
|
|
5697
5993
|
let retries = 0;
|
|
@@ -6216,8 +6512,8 @@ var ZapierApiClient = class {
|
|
|
6216
6512
|
canSendDeprecationMessaging
|
|
6217
6513
|
} = this.applyPathConfiguration(path);
|
|
6218
6514
|
if (searchParams) {
|
|
6219
|
-
Object.entries(searchParams).forEach(([
|
|
6220
|
-
url.searchParams.set(
|
|
6515
|
+
Object.entries(searchParams).forEach(([key, value]) => {
|
|
6516
|
+
url.searchParams.set(key, value);
|
|
6221
6517
|
});
|
|
6222
6518
|
}
|
|
6223
6519
|
return {
|
|
@@ -7116,13 +7412,13 @@ function parseManifestSection({
|
|
|
7116
7412
|
return void 0;
|
|
7117
7413
|
}
|
|
7118
7414
|
const kept = {};
|
|
7119
|
-
for (const [
|
|
7415
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
7120
7416
|
const result = schema.safeParse(value);
|
|
7121
7417
|
if (result.success) {
|
|
7122
|
-
kept[
|
|
7418
|
+
kept[key] = result.data;
|
|
7123
7419
|
} else {
|
|
7124
7420
|
console.warn(
|
|
7125
|
-
`\u26A0\uFE0F Dropping invalid "${section}" entry "${
|
|
7421
|
+
`\u26A0\uFE0F Dropping invalid "${section}" entry "${key}" in ${source}: ${result.error}`
|
|
7126
7422
|
);
|
|
7127
7423
|
}
|
|
7128
7424
|
}
|
|
@@ -7271,9 +7567,9 @@ function findManifestEntry({
|
|
|
7271
7567
|
return [slug, manifest.apps[slug]];
|
|
7272
7568
|
}
|
|
7273
7569
|
}
|
|
7274
|
-
for (const [
|
|
7570
|
+
for (const [key, entry] of Object.entries(manifest.apps)) {
|
|
7275
7571
|
if (entry.implementationName === appKeyWithoutVersion) {
|
|
7276
|
-
return [
|
|
7572
|
+
return [key, entry];
|
|
7277
7573
|
}
|
|
7278
7574
|
}
|
|
7279
7575
|
return null;
|
|
@@ -7527,8 +7823,8 @@ function normalizeHeaders(optionsHeaders) {
|
|
|
7527
7823
|
return headers;
|
|
7528
7824
|
}
|
|
7529
7825
|
const headerEntries = optionsHeaders instanceof Headers ? Array.from(optionsHeaders.entries()) : Array.isArray(optionsHeaders) ? optionsHeaders : Object.entries(optionsHeaders);
|
|
7530
|
-
for (const [
|
|
7531
|
-
headers[
|
|
7826
|
+
for (const [key, value] of headerEntries) {
|
|
7827
|
+
headers[key] = value;
|
|
7532
7828
|
}
|
|
7533
7829
|
return headers;
|
|
7534
7830
|
}
|
|
@@ -7599,14 +7895,9 @@ var fetchPlugin = defineMethod({
|
|
|
7599
7895
|
// of order.
|
|
7600
7896
|
categories: [{ key: "http", title: "HTTP Request" }],
|
|
7601
7897
|
returnType: "Response",
|
|
7602
|
-
// The controller
|
|
7603
|
-
// `positional
|
|
7604
|
-
// individual flags (--method, --connection, ...)
|
|
7605
|
-
// the only surface that reads this. Both describe the same (url, init) shape.
|
|
7606
|
-
inputParameters: [
|
|
7607
|
-
{ name: "url", schema: FetchUrlSchema },
|
|
7608
|
-
{ name: "init", schema: FetchInitSchema }
|
|
7609
|
-
],
|
|
7898
|
+
// The CLI, controller, and MCP all derive fetch's `(url, init)` shape from
|
|
7899
|
+
// `inputSchema` + `positional`; the CLI flattens `init`'s fields into
|
|
7900
|
+
// individual flags (--method, --connection, ...) off that same schema.
|
|
7610
7901
|
// Build the validator once, binding it to the head's `adaptError` so failures
|
|
7611
7902
|
// surface as `ZapierValidationError` rather than the neutral kitcore fallback.
|
|
7612
7903
|
setup: ({ imports }) => {
|
|
@@ -7745,9 +8036,9 @@ var RunActionInputSchema = zod.z.union([RunActionSchema, RunActionSchemaDeprecat
|
|
|
7745
8036
|
var ActionResultItemSchema = zod.z.unknown().describe("Action execution result");
|
|
7746
8037
|
|
|
7747
8038
|
// src/formatters/actionResult.ts
|
|
7748
|
-
function getStringProperty(obj,
|
|
7749
|
-
if (typeof obj === "object" && obj !== null &&
|
|
7750
|
-
const value = obj[
|
|
8039
|
+
function getStringProperty(obj, key) {
|
|
8040
|
+
if (typeof obj === "object" && obj !== null && key in obj) {
|
|
8041
|
+
const value = obj[key];
|
|
7751
8042
|
return typeof value === "string" ? value : void 0;
|
|
7752
8043
|
}
|
|
7753
8044
|
return void 0;
|
|
@@ -8233,21 +8524,21 @@ var actionKeyResolver = defineResolver({
|
|
|
8233
8524
|
});
|
|
8234
8525
|
|
|
8235
8526
|
// src/plugins/capabilities/index.ts
|
|
8236
|
-
function toDescription(
|
|
8237
|
-
const words =
|
|
8527
|
+
function toDescription(key) {
|
|
8528
|
+
const words = key.replace(/^can/, "").replace(/([A-Z])/g, " $1").trim().toLowerCase();
|
|
8238
8529
|
return `To ${words}`;
|
|
8239
8530
|
}
|
|
8240
|
-
function toEnvVar(
|
|
8241
|
-
return "ZAPIER_" +
|
|
8531
|
+
function toEnvVar(key) {
|
|
8532
|
+
return "ZAPIER_" + key.replace(/([A-Z])/g, "_$1").toUpperCase();
|
|
8242
8533
|
}
|
|
8243
|
-
function toCliFlag(
|
|
8244
|
-
return "--" +
|
|
8534
|
+
function toCliFlag(key) {
|
|
8535
|
+
return "--" + key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
8245
8536
|
}
|
|
8246
|
-
function buildCapabilityMessage(
|
|
8537
|
+
function buildCapabilityMessage(key) {
|
|
8247
8538
|
return [
|
|
8248
|
-
`${toDescription(
|
|
8249
|
-
`set ${
|
|
8250
|
-
`or set ${toEnvVar(
|
|
8539
|
+
`${toDescription(key)}, use ${toCliFlag(key)} in the CLI,`,
|
|
8540
|
+
`set ${key}: true in SDK options or .zapierrc,`,
|
|
8541
|
+
`or set ${toEnvVar(key)}=true.`
|
|
8251
8542
|
].join(" ");
|
|
8252
8543
|
}
|
|
8253
8544
|
var GATED_FLAGS = [
|
|
@@ -8255,8 +8546,8 @@ var GATED_FLAGS = [
|
|
|
8255
8546
|
"canIncludeSharedTables",
|
|
8256
8547
|
"canDeleteTables"
|
|
8257
8548
|
];
|
|
8258
|
-
function isEnabledByEnv(
|
|
8259
|
-
const value = globalThis.process?.env?.[toEnvVar(
|
|
8549
|
+
function isEnabledByEnv(key) {
|
|
8550
|
+
const value = globalThis.process?.env?.[toEnvVar(key)];
|
|
8260
8551
|
if (value === void 0) return void 0;
|
|
8261
8552
|
if (value === "true" || value === "1") return true;
|
|
8262
8553
|
if (value === "false" || value === "0") return false;
|
|
@@ -8283,17 +8574,17 @@ var capabilitiesPlugin = defineProperty({
|
|
|
8283
8574
|
return cached;
|
|
8284
8575
|
}
|
|
8285
8576
|
return {
|
|
8286
|
-
checkCapability: async (
|
|
8577
|
+
checkCapability: async (key) => {
|
|
8287
8578
|
const flags = await resolveFlags();
|
|
8288
|
-
if (flags[
|
|
8579
|
+
if (flags[key]) return;
|
|
8289
8580
|
throw new ZapierConfigurationError(
|
|
8290
|
-
buildCapabilityMessage(
|
|
8291
|
-
{ configType:
|
|
8581
|
+
buildCapabilityMessage(key) + " (If you are an AI agent, you MUST NOT retry. Ask the user if they want to enable this.)",
|
|
8582
|
+
{ configType: key }
|
|
8292
8583
|
);
|
|
8293
8584
|
},
|
|
8294
|
-
hasCapability: async (
|
|
8585
|
+
hasCapability: async (key) => {
|
|
8295
8586
|
const flags = await resolveFlags();
|
|
8296
|
-
return flags[
|
|
8587
|
+
return flags[key];
|
|
8297
8588
|
}
|
|
8298
8589
|
};
|
|
8299
8590
|
},
|
|
@@ -8578,13 +8869,13 @@ var tableIdResolver = defineResolver({
|
|
|
8578
8869
|
listItems: ({ imports, context, cursor }) => {
|
|
8579
8870
|
const includeShared = context?.includeShared;
|
|
8580
8871
|
if (includeShared) {
|
|
8581
|
-
return
|
|
8872
|
+
return concatLists({
|
|
8582
8873
|
sources: [
|
|
8583
|
-
({ cursor:
|
|
8584
|
-
({ cursor:
|
|
8874
|
+
({ cursor: listCursor }) => imports.listTablesInternal({ cursor: listCursor }),
|
|
8875
|
+
({ cursor: listCursor }) => imports.listTablesInternal({
|
|
8585
8876
|
includeShared: true,
|
|
8586
8877
|
includePersonal: false,
|
|
8587
|
-
cursor:
|
|
8878
|
+
cursor: listCursor
|
|
8588
8879
|
})
|
|
8589
8880
|
],
|
|
8590
8881
|
cursor
|
|
@@ -8790,7 +9081,7 @@ function formatRecordError(fieldId, err) {
|
|
|
8790
9081
|
function formatResponseError(err) {
|
|
8791
9082
|
const message = err.human_title || err.title || "Unknown error";
|
|
8792
9083
|
if (err.meta && Object.keys(err.meta).length > 0) {
|
|
8793
|
-
const metaParts = Object.entries(err.meta).map(([
|
|
9084
|
+
const metaParts = Object.entries(err.meta).map(([key, val]) => `${key}: ${JSON.stringify(val)}`).join(", ");
|
|
8794
9085
|
return `${message} (${metaParts})`;
|
|
8795
9086
|
}
|
|
8796
9087
|
return message;
|
|
@@ -8825,8 +9116,8 @@ var TrashSchema = zod.z.enum(["exclude", "include", "only"]).optional().describe
|
|
|
8825
9116
|
'Control soft-deleted item visibility. "exclude" (default) returns active items only, "include" returns both active and soft-deleted, "only" returns soft-deleted items only.'
|
|
8826
9117
|
);
|
|
8827
9118
|
var FIELD_ID_PATTERN = /^f\d+$/;
|
|
8828
|
-
function isFieldId(
|
|
8829
|
-
return FIELD_ID_PATTERN.test(
|
|
9119
|
+
function isFieldId(key) {
|
|
9120
|
+
return FIELD_ID_PATTERN.test(key);
|
|
8830
9121
|
}
|
|
8831
9122
|
var NESTED_COMPONENTS = {
|
|
8832
9123
|
labeled_string: /* @__PURE__ */ new Set(["value"]),
|
|
@@ -8864,7 +9155,7 @@ async function resolveFieldKeys({
|
|
|
8864
9155
|
fieldKeys
|
|
8865
9156
|
}) {
|
|
8866
9157
|
const allAreIds = fieldKeys.every(
|
|
8867
|
-
(
|
|
9158
|
+
(key) => typeof key === "number" || /^(f?\d+)$/.test(key)
|
|
8868
9159
|
);
|
|
8869
9160
|
if (allAreIds) {
|
|
8870
9161
|
return fieldKeys.map(toNumericFieldId);
|
|
@@ -8873,13 +9164,13 @@ async function resolveFieldKeys({
|
|
|
8873
9164
|
if (!mapping) {
|
|
8874
9165
|
return fieldKeys.map(toNumericFieldId);
|
|
8875
9166
|
}
|
|
8876
|
-
return fieldKeys.map((
|
|
8877
|
-
if (typeof
|
|
8878
|
-
if (FIELD_ID_PATTERN.test(
|
|
8879
|
-
const id = mapping.nameToId.get(
|
|
9167
|
+
return fieldKeys.map((key) => {
|
|
9168
|
+
if (typeof key === "number") return key;
|
|
9169
|
+
if (FIELD_ID_PATTERN.test(key)) return toNumericFieldId(key);
|
|
9170
|
+
const id = mapping.nameToId.get(key);
|
|
8880
9171
|
if (!id) {
|
|
8881
9172
|
throw new ZapierValidationError(
|
|
8882
|
-
`Unknown field name: "${
|
|
9173
|
+
`Unknown field name: "${key}". Use a valid field name or ID.`
|
|
8883
9174
|
);
|
|
8884
9175
|
}
|
|
8885
9176
|
return toNumericFieldId(id);
|
|
@@ -8895,13 +9186,13 @@ async function createFieldKeyTranslator({
|
|
|
8895
9186
|
translateInput(data) {
|
|
8896
9187
|
if (!mapping) return data;
|
|
8897
9188
|
const result = {};
|
|
8898
|
-
for (const [
|
|
8899
|
-
if (FIELD_ID_PATTERN.test(
|
|
8900
|
-
result[
|
|
8901
|
-
} else if (mapping.nameToId.has(
|
|
8902
|
-
result[mapping.nameToId.get(
|
|
9189
|
+
for (const [key, value] of Object.entries(data)) {
|
|
9190
|
+
if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
|
|
9191
|
+
result[key] = value;
|
|
9192
|
+
} else if (mapping.nameToId.has(key)) {
|
|
9193
|
+
result[mapping.nameToId.get(key)] = value;
|
|
8903
9194
|
} else {
|
|
8904
|
-
result[
|
|
9195
|
+
result[key] = value;
|
|
8905
9196
|
}
|
|
8906
9197
|
}
|
|
8907
9198
|
return result;
|
|
@@ -8909,29 +9200,29 @@ async function createFieldKeyTranslator({
|
|
|
8909
9200
|
translateOutput(data) {
|
|
8910
9201
|
if (!mapping) return data;
|
|
8911
9202
|
const result = {};
|
|
8912
|
-
for (const [
|
|
8913
|
-
if (mapping.idToName.has(
|
|
8914
|
-
result[mapping.idToName.get(
|
|
9203
|
+
for (const [key, value] of Object.entries(data)) {
|
|
9204
|
+
if (mapping.idToName.has(key)) {
|
|
9205
|
+
result[mapping.idToName.get(key)] = value;
|
|
8915
9206
|
} else {
|
|
8916
|
-
result[
|
|
9207
|
+
result[key] = value;
|
|
8917
9208
|
}
|
|
8918
9209
|
}
|
|
8919
9210
|
return result;
|
|
8920
9211
|
},
|
|
8921
|
-
translateFieldKey(
|
|
8922
|
-
if (!mapping) return
|
|
8923
|
-
if (FIELD_ID_PATTERN.test(
|
|
8924
|
-
const fieldType = mapping.idToType.get(
|
|
9212
|
+
translateFieldKey(key) {
|
|
9213
|
+
if (!mapping) return key;
|
|
9214
|
+
if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
|
|
9215
|
+
const fieldType = mapping.idToType.get(key);
|
|
8925
9216
|
if (fieldType) {
|
|
8926
9217
|
const components = NESTED_COMPONENTS[fieldType];
|
|
8927
9218
|
if (components?.size === 1) {
|
|
8928
|
-
return `${
|
|
9219
|
+
return `${key}__${[...components][0]}`;
|
|
8929
9220
|
}
|
|
8930
9221
|
}
|
|
8931
|
-
return
|
|
9222
|
+
return key;
|
|
8932
9223
|
}
|
|
8933
|
-
if (mapping.nameToId.has(
|
|
8934
|
-
const fieldId = mapping.nameToId.get(
|
|
9224
|
+
if (mapping.nameToId.has(key)) {
|
|
9225
|
+
const fieldId = mapping.nameToId.get(key);
|
|
8935
9226
|
const fieldType = mapping.idToType.get(fieldId);
|
|
8936
9227
|
if (fieldType) {
|
|
8937
9228
|
const components = NESTED_COMPONENTS[fieldType];
|
|
@@ -8941,10 +9232,10 @@ async function createFieldKeyTranslator({
|
|
|
8941
9232
|
}
|
|
8942
9233
|
return fieldId;
|
|
8943
9234
|
}
|
|
8944
|
-
const sepIndex =
|
|
9235
|
+
const sepIndex = key.lastIndexOf("__");
|
|
8945
9236
|
if (sepIndex > 0) {
|
|
8946
|
-
const prefix =
|
|
8947
|
-
const component =
|
|
9237
|
+
const prefix = key.slice(0, sepIndex);
|
|
9238
|
+
const component = key.slice(sepIndex + 2);
|
|
8948
9239
|
let fieldId;
|
|
8949
9240
|
if (FIELD_ID_PATTERN.test(prefix) && mapping.idToName.has(prefix)) {
|
|
8950
9241
|
fieldId = prefix;
|
|
@@ -8958,7 +9249,7 @@ async function createFieldKeyTranslator({
|
|
|
8958
9249
|
}
|
|
8959
9250
|
}
|
|
8960
9251
|
}
|
|
8961
|
-
return
|
|
9252
|
+
return key;
|
|
8962
9253
|
}
|
|
8963
9254
|
};
|
|
8964
9255
|
}
|
|
@@ -9554,13 +9845,13 @@ var runActionPlugin = defineMethod({
|
|
|
9554
9845
|
let oldestKey;
|
|
9555
9846
|
let oldestExpiry = Infinity;
|
|
9556
9847
|
let evictedAny = false;
|
|
9557
|
-
for (const [
|
|
9848
|
+
for (const [key, entry] of cache) {
|
|
9558
9849
|
if (now >= entry.expiresAt) {
|
|
9559
|
-
cache.delete(
|
|
9850
|
+
cache.delete(key);
|
|
9560
9851
|
evictedAny = true;
|
|
9561
9852
|
} else if (entry.expiresAt < oldestExpiry) {
|
|
9562
9853
|
oldestExpiry = entry.expiresAt;
|
|
9563
|
-
oldestKey =
|
|
9854
|
+
oldestKey = key;
|
|
9564
9855
|
}
|
|
9565
9856
|
}
|
|
9566
9857
|
if (!evictedAny && oldestKey) cache.delete(oldestKey);
|
|
@@ -9918,7 +10209,7 @@ var listAppsPlugin = defineMethod({
|
|
|
9918
10209
|
locator
|
|
9919
10210
|
];
|
|
9920
10211
|
}
|
|
9921
|
-
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((
|
|
10212
|
+
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
|
|
9922
10213
|
if (duplicatedLookupAppKeys.length > 0) {
|
|
9923
10214
|
throw new Error(
|
|
9924
10215
|
`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
|
|
@@ -10083,8 +10374,8 @@ function formatRootField(item) {
|
|
|
10083
10374
|
}
|
|
10084
10375
|
var rootFieldItemFormatter = defineFormatter({
|
|
10085
10376
|
format: ({ item }) => {
|
|
10086
|
-
const { key
|
|
10087
|
-
return { ...rest, hint:
|
|
10377
|
+
const { key, ...rest } = formatRootField(item);
|
|
10378
|
+
return { ...rest, hint: key };
|
|
10088
10379
|
}
|
|
10089
10380
|
});
|
|
10090
10381
|
|
|
@@ -11744,7 +12035,7 @@ var createTriggerInboxPlugin = defineMethod({
|
|
|
11744
12035
|
inputs = {},
|
|
11745
12036
|
notificationUrl
|
|
11746
12037
|
} = input;
|
|
11747
|
-
const
|
|
12038
|
+
const key = input.key ?? input.name;
|
|
11748
12039
|
const resolvedConnectionId = await resolveConnectionId({
|
|
11749
12040
|
connection,
|
|
11750
12041
|
resolveConnection
|
|
@@ -11764,8 +12055,8 @@ var createTriggerInboxPlugin = defineMethod({
|
|
|
11764
12055
|
connection_id: resolvedConnectionId ?? null
|
|
11765
12056
|
}
|
|
11766
12057
|
};
|
|
11767
|
-
if (
|
|
11768
|
-
requestBody.key =
|
|
12058
|
+
if (key !== void 0) {
|
|
12059
|
+
requestBody.key = key;
|
|
11769
12060
|
}
|
|
11770
12061
|
if (notificationUrl !== void 0) {
|
|
11771
12062
|
requestBody.notification_url = notificationUrl;
|
|
@@ -11779,7 +12070,7 @@ var createTriggerInboxPlugin = defineMethod({
|
|
|
11779
12070
|
if (status === 409) {
|
|
11780
12071
|
const detail = extractErrorDetail(data);
|
|
11781
12072
|
return new ZapierConflictError(
|
|
11782
|
-
detail ?? `An inbox with key "${
|
|
12073
|
+
detail ?? `An inbox with key "${key}" already exists with a different subscription.`,
|
|
11783
12074
|
{ statusCode: status, resourceType: "trigger_inbox" }
|
|
11784
12075
|
);
|
|
11785
12076
|
}
|
|
@@ -11847,7 +12138,7 @@ var ensureTriggerInboxPlugin = defineMethod({
|
|
|
11847
12138
|
inputs = {},
|
|
11848
12139
|
notificationUrl
|
|
11849
12140
|
} = input;
|
|
11850
|
-
const
|
|
12141
|
+
const key = "key" in input ? input.key : input.name;
|
|
11851
12142
|
const resolvedConnectionId = await resolveConnectionId({
|
|
11852
12143
|
connection,
|
|
11853
12144
|
resolveConnection
|
|
@@ -11860,7 +12151,7 @@ var ensureTriggerInboxPlugin = defineMethod({
|
|
|
11860
12151
|
);
|
|
11861
12152
|
}
|
|
11862
12153
|
const requestBody = {
|
|
11863
|
-
key
|
|
12154
|
+
key,
|
|
11864
12155
|
subscription: {
|
|
11865
12156
|
app_key: selectedApi,
|
|
11866
12157
|
action_key: actionKey,
|
|
@@ -11880,7 +12171,7 @@ var ensureTriggerInboxPlugin = defineMethod({
|
|
|
11880
12171
|
if (status === 409) {
|
|
11881
12172
|
const detail = extractErrorDetail(data);
|
|
11882
12173
|
return new ZapierConflictError(
|
|
11883
|
-
detail ?? `An inbox with key "${
|
|
12174
|
+
detail ?? `An inbox with key "${key}" already exists with a different subscription.`,
|
|
11884
12175
|
{ statusCode: status, resourceType: "trigger_inbox" }
|
|
11885
12176
|
);
|
|
11886
12177
|
}
|
|
@@ -12464,9 +12755,9 @@ function createWaiter() {
|
|
|
12464
12755
|
}
|
|
12465
12756
|
};
|
|
12466
12757
|
}
|
|
12467
|
-
function addToMap(m,
|
|
12468
|
-
const existing = m.get(
|
|
12469
|
-
m.set(
|
|
12758
|
+
function addToMap(m, key, value) {
|
|
12759
|
+
const existing = m.get(key) ?? [];
|
|
12760
|
+
m.set(key, [...existing, value]);
|
|
12470
12761
|
}
|
|
12471
12762
|
async function runBatchedDrainPipeline(options) {
|
|
12472
12763
|
const {
|
|
@@ -14163,8 +14454,8 @@ function getOsInfo() {
|
|
|
14163
14454
|
function getPlatformVersions() {
|
|
14164
14455
|
const versions = {};
|
|
14165
14456
|
if (typeof globalThis.process?.versions === "object") {
|
|
14166
|
-
for (const [
|
|
14167
|
-
versions[
|
|
14457
|
+
for (const [key, value] of Object.entries(globalThis.process.versions)) {
|
|
14458
|
+
versions[key] = value || null;
|
|
14168
14459
|
}
|
|
14169
14460
|
}
|
|
14170
14461
|
return versions;
|
|
@@ -14418,9 +14709,9 @@ async function emitWithTimeout(transport, subject, event) {
|
|
|
14418
14709
|
}
|
|
14419
14710
|
function mergeUserContext(event, userContext) {
|
|
14420
14711
|
const merged = { ...event };
|
|
14421
|
-
for (const [
|
|
14422
|
-
if (merged[
|
|
14423
|
-
merged[
|
|
14712
|
+
for (const [key, value] of Object.entries(userContext)) {
|
|
14713
|
+
if (merged[key] == null) {
|
|
14714
|
+
merged[key] = value;
|
|
14424
14715
|
}
|
|
14425
14716
|
}
|
|
14426
14717
|
return merged;
|