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