@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/experimental.mjs
CHANGED
|
@@ -32,6 +32,36 @@ 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
|
+
}
|
|
62
|
+
function openEnum(values, description) {
|
|
63
|
+
return z.union([z.enum(values), z.string()]).describe(description);
|
|
64
|
+
}
|
|
35
65
|
function resolveCategoryDefinition(ref) {
|
|
36
66
|
const def = typeof ref === "string" ? { key: ref } : ref;
|
|
37
67
|
const title = def.title ?? toTitleCase(def.key);
|
|
@@ -41,30 +71,25 @@ function resolveCategoryDefinition(ref) {
|
|
|
41
71
|
titlePlural: def.titlePlural ?? pluralizeLastWord(title)
|
|
42
72
|
};
|
|
43
73
|
}
|
|
44
|
-
function canonicalInputSchema(schema) {
|
|
45
|
-
if (schema instanceof z.ZodUnion) {
|
|
46
|
-
return schema.options[0];
|
|
47
|
-
}
|
|
48
|
-
return schema;
|
|
49
|
-
}
|
|
50
74
|
function buildRegistry({
|
|
51
75
|
sdk,
|
|
52
76
|
meta,
|
|
53
77
|
formatters,
|
|
54
|
-
|
|
78
|
+
resolvers,
|
|
55
79
|
positional,
|
|
80
|
+
skipInputValidation,
|
|
56
81
|
packageFilter
|
|
57
82
|
}) {
|
|
58
83
|
const definitionsByKey = /* @__PURE__ */ new Map();
|
|
59
84
|
const objectDeclaredKeys = /* @__PURE__ */ new Set();
|
|
60
85
|
for (const m of Object.values(meta)) {
|
|
61
86
|
for (const ref of m.categories ?? []) {
|
|
62
|
-
const
|
|
87
|
+
const key = typeof ref === "string" ? ref : ref.key;
|
|
63
88
|
if (typeof ref === "object") {
|
|
64
|
-
objectDeclaredKeys.add(
|
|
65
|
-
definitionsByKey.set(
|
|
66
|
-
} else if (!objectDeclaredKeys.has(
|
|
67
|
-
definitionsByKey.set(
|
|
89
|
+
objectDeclaredKeys.add(key);
|
|
90
|
+
definitionsByKey.set(key, resolveCategoryDefinition(ref));
|
|
91
|
+
} else if (!objectDeclaredKeys.has(key)) {
|
|
92
|
+
definitionsByKey.set(key, resolveCategoryDefinition(ref));
|
|
68
93
|
}
|
|
69
94
|
}
|
|
70
95
|
}
|
|
@@ -72,30 +97,29 @@ function buildRegistry({
|
|
|
72
97
|
definitionsByKey.set("other", resolveCategoryDefinition("other"));
|
|
73
98
|
}
|
|
74
99
|
const knownCategories = Array.from(definitionsByKey.keys());
|
|
75
|
-
const functions = Object.keys(meta).filter((
|
|
76
|
-
const property = sdk[
|
|
100
|
+
const functions = Object.keys(meta).filter((key) => {
|
|
101
|
+
const property = sdk[key];
|
|
77
102
|
if (typeof property === "function") return true;
|
|
78
|
-
const [rootKey] =
|
|
103
|
+
const [rootKey] = key.split(".");
|
|
79
104
|
const rootProperty = sdk[rootKey];
|
|
80
105
|
return typeof rootProperty === "object" && rootProperty !== null;
|
|
81
|
-
}).map((
|
|
82
|
-
const m = meta[
|
|
106
|
+
}).map((key) => {
|
|
107
|
+
const m = meta[key];
|
|
83
108
|
return {
|
|
84
|
-
name:
|
|
109
|
+
name: key,
|
|
85
110
|
description: m.description,
|
|
86
111
|
type: m.type,
|
|
87
112
|
itemType: m.itemType,
|
|
88
113
|
returnType: m.returnType,
|
|
89
114
|
inputSchema: canonicalInputSchema(m.inputSchema),
|
|
90
|
-
inputParameters: m.inputParameters,
|
|
91
115
|
outputSchema: m.outputSchema,
|
|
92
|
-
positional: positional?.[
|
|
116
|
+
positional: positional?.[key],
|
|
117
|
+
skipInputValidation: skipInputValidation?.[key],
|
|
93
118
|
categories: (m.categories ?? []).map(
|
|
94
119
|
(c) => typeof c === "string" ? c : c.key
|
|
95
120
|
),
|
|
96
|
-
resolvers:
|
|
97
|
-
|
|
98
|
-
formatter: formatters?.[key2],
|
|
121
|
+
resolvers: resolvers?.[key],
|
|
122
|
+
formatter: formatters?.[key],
|
|
99
123
|
experimental: m.experimental,
|
|
100
124
|
packages: m.packages,
|
|
101
125
|
confirm: m.confirm ?? (m.type === "delete" ? "delete" : void 0),
|
|
@@ -408,51 +432,36 @@ function decodeConcatCursor(incoming) {
|
|
|
408
432
|
}
|
|
409
433
|
return { index: 0, cursor: incoming };
|
|
410
434
|
}
|
|
411
|
-
function
|
|
435
|
+
async function concatLists({
|
|
412
436
|
sources,
|
|
413
437
|
pageSize = 100,
|
|
414
438
|
cursor
|
|
415
439
|
}) {
|
|
416
440
|
if (sources.length === 0) {
|
|
417
|
-
|
|
418
|
-
return Object.assign(Promise.resolve(empty), {
|
|
419
|
-
[Symbol.asyncIterator]: async function* () {
|
|
420
|
-
yield empty;
|
|
421
|
-
}
|
|
422
|
-
});
|
|
441
|
+
return { data: [] };
|
|
423
442
|
}
|
|
424
443
|
const pageFunction = async (options) => {
|
|
425
|
-
let { index, cursor:
|
|
444
|
+
let { index, cursor: listCursor } = decodeConcatCursor(options.cursor);
|
|
426
445
|
while (index < sources.length) {
|
|
427
|
-
const page = await sources[index]({ cursor:
|
|
428
|
-
const
|
|
429
|
-
if (page.data.length === 0 && !
|
|
446
|
+
const page = await sources[index]({ cursor: listCursor });
|
|
447
|
+
const hasMoreInList = page.nextCursor != null;
|
|
448
|
+
if (page.data.length === 0 && !hasMoreInList) {
|
|
430
449
|
index++;
|
|
431
|
-
|
|
450
|
+
listCursor = void 0;
|
|
432
451
|
continue;
|
|
433
452
|
}
|
|
434
453
|
return {
|
|
435
454
|
data: page.data,
|
|
436
|
-
nextCursor:
|
|
455
|
+
nextCursor: hasMoreInList ? encodeConcatCursor(index, page.nextCursor) : index < sources.length - 1 ? encodeConcatCursor(index + 1, void 0) : void 0
|
|
437
456
|
};
|
|
438
457
|
}
|
|
439
458
|
return { data: [] };
|
|
440
459
|
};
|
|
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
|
-
});
|
|
460
|
+
const result = await paginateBuffered(pageFunction, {
|
|
461
|
+
pageSize,
|
|
462
|
+
cursor
|
|
463
|
+
}).next();
|
|
464
|
+
return result.done ? { data: [] } : result.value;
|
|
456
465
|
}
|
|
457
466
|
var parseOrThrow = (schema, input, { adaptError } = {}) => {
|
|
458
467
|
const result = schema.safeParse(input);
|
|
@@ -525,6 +534,50 @@ function runInMethodScope(fn) {
|
|
|
525
534
|
return scope.run({ depth: currentDepth + 1 }, fn);
|
|
526
535
|
}
|
|
527
536
|
var runWithTelemetryContext = runInMethodScope;
|
|
537
|
+
var CALL_CONTEXT_BRAND = Symbol("kitcore.callContext");
|
|
538
|
+
function isCallContext(value) {
|
|
539
|
+
return typeof value === "object" && value !== null && value[CALL_CONTEXT_BRAND] === true;
|
|
540
|
+
}
|
|
541
|
+
function generateCallId() {
|
|
542
|
+
try {
|
|
543
|
+
const webCrypto = globalThis.crypto;
|
|
544
|
+
if (webCrypto?.randomUUID) {
|
|
545
|
+
return webCrypto.randomUUID();
|
|
546
|
+
}
|
|
547
|
+
if (webCrypto?.getRandomValues) {
|
|
548
|
+
const bytes = webCrypto.getRandomValues(new Uint8Array(16));
|
|
549
|
+
const hex = Array.from(bytes, (byte, i) => {
|
|
550
|
+
const value = i === 6 ? byte & 15 | 64 : i === 8 ? byte & 63 | 128 : byte;
|
|
551
|
+
return value.toString(16).padStart(2, "0");
|
|
552
|
+
});
|
|
553
|
+
return [
|
|
554
|
+
hex.slice(0, 4).join(""),
|
|
555
|
+
hex.slice(4, 6).join(""),
|
|
556
|
+
hex.slice(6, 8).join(""),
|
|
557
|
+
hex.slice(8, 10).join(""),
|
|
558
|
+
hex.slice(10, 16).join("")
|
|
559
|
+
].join("-");
|
|
560
|
+
}
|
|
561
|
+
} catch {
|
|
562
|
+
}
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
565
|
+
function rootCallContext() {
|
|
566
|
+
return {
|
|
567
|
+
callId: generateCallId(),
|
|
568
|
+
depth: 0,
|
|
569
|
+
annotations: {},
|
|
570
|
+
[CALL_CONTEXT_BRAND]: true
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function childCallContext(parent) {
|
|
574
|
+
return {
|
|
575
|
+
callId: parent.callId,
|
|
576
|
+
depth: parent.depth + 1,
|
|
577
|
+
annotations: {},
|
|
578
|
+
[CALL_CONTEXT_BRAND]: true
|
|
579
|
+
};
|
|
580
|
+
}
|
|
528
581
|
function defaultLogDeprecation({
|
|
529
582
|
methodName,
|
|
530
583
|
deprecation
|
|
@@ -540,6 +593,9 @@ function resolveCoreOptions(context) {
|
|
|
540
593
|
return context.core;
|
|
541
594
|
}
|
|
542
595
|
var INTERNAL_CALL = Symbol("kitcore.internalCall");
|
|
596
|
+
function resolveCallContext(secondArg) {
|
|
597
|
+
return isCallContext(secondArg) ? secondArg : rootCallContext();
|
|
598
|
+
}
|
|
543
599
|
function signalDeprecation(context, methodName, getDeprecation) {
|
|
544
600
|
if (isInsideObserver()) return;
|
|
545
601
|
const deprecation = getDeprecation?.();
|
|
@@ -569,14 +625,16 @@ function createFunction(coreFn, options) {
|
|
|
569
625
|
const functionName = name || coreFn.name;
|
|
570
626
|
const namedFunctions = {
|
|
571
627
|
[functionName]: async function(callOptions) {
|
|
572
|
-
|
|
628
|
+
const internal = arguments[1];
|
|
629
|
+
const context = resolveCallContext(internal);
|
|
630
|
+
if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
|
|
573
631
|
signalDeprecation(sdk.context, functionName, getDeprecation);
|
|
574
632
|
}
|
|
575
633
|
return runInMethodScope(async () => {
|
|
576
634
|
const startTime = Date.now();
|
|
577
635
|
const normalizedOptions = callOptions ?? {};
|
|
578
636
|
const args = [normalizedOptions];
|
|
579
|
-
const depth = getCurrentDepth();
|
|
637
|
+
const depth = Math.max(context.depth, getCurrentDepth());
|
|
580
638
|
const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
|
|
581
639
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
582
640
|
hooks?.onMethodStart?.({
|
|
@@ -595,12 +653,15 @@ function createFunction(coreFn, options) {
|
|
|
595
653
|
adaptError
|
|
596
654
|
}
|
|
597
655
|
);
|
|
598
|
-
result = await coreFn(
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
656
|
+
result = await coreFn(
|
|
657
|
+
{
|
|
658
|
+
...normalizedOptions,
|
|
659
|
+
...validatedOptions
|
|
660
|
+
},
|
|
661
|
+
context
|
|
662
|
+
);
|
|
602
663
|
} else {
|
|
603
|
-
result = await coreFn(normalizedOptions);
|
|
664
|
+
result = await coreFn(normalizedOptions, context);
|
|
604
665
|
}
|
|
605
666
|
hooks?.onMethodEnd?.({
|
|
606
667
|
methodName: functionName,
|
|
@@ -630,17 +691,19 @@ function createFunction(coreFn, options) {
|
|
|
630
691
|
function createRawFunction(coreFn, options) {
|
|
631
692
|
const { sdk, name, schema, positional, getDeprecation } = options;
|
|
632
693
|
return function(rawInput) {
|
|
633
|
-
|
|
694
|
+
const internal = arguments[1];
|
|
695
|
+
const context = resolveCallContext(internal);
|
|
696
|
+
if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
|
|
634
697
|
signalDeprecation(sdk.context, name, getDeprecation);
|
|
635
698
|
}
|
|
636
699
|
return runInMethodScope(() => {
|
|
637
700
|
const startTime = Date.now();
|
|
638
|
-
const depth = getCurrentDepth();
|
|
701
|
+
const depth = Math.max(context.depth, getCurrentDepth());
|
|
639
702
|
const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
|
|
640
703
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
641
704
|
const input = schema ? rawInput ?? {} : rawInput;
|
|
642
705
|
const record = input;
|
|
643
|
-
const args = positional ? positional.filter((
|
|
706
|
+
const args = positional ? positional.filter((key) => record?.[key] !== void 0).map((key) => record?.[key]) : [input];
|
|
644
707
|
hooks?.onMethodStart?.({
|
|
645
708
|
methodName: name,
|
|
646
709
|
args,
|
|
@@ -659,7 +722,7 @@ function createRawFunction(coreFn, options) {
|
|
|
659
722
|
};
|
|
660
723
|
try {
|
|
661
724
|
const parsed = schema ? validateOptions(schema, input, { adaptError }) : input;
|
|
662
|
-
const result = coreFn(parsed);
|
|
725
|
+
const result = coreFn(parsed, context);
|
|
663
726
|
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
664
727
|
return result.then(
|
|
665
728
|
(value) => {
|
|
@@ -698,9 +761,9 @@ function createPageFunction(coreFn, {
|
|
|
698
761
|
}) {
|
|
699
762
|
const functionName = coreFn.name + "Page";
|
|
700
763
|
const namedFunctions = {
|
|
701
|
-
[functionName]: async function(options) {
|
|
764
|
+
[functionName]: async function(options, callContext) {
|
|
702
765
|
try {
|
|
703
|
-
const response = await coreFn(options);
|
|
766
|
+
const response = await coreFn(options, callContext);
|
|
704
767
|
const page = adaptPage ? adaptPage(response) : response;
|
|
705
768
|
if (!isSdkPage(page)) {
|
|
706
769
|
throw new Error(
|
|
@@ -724,14 +787,16 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
724
787
|
const functionName = name || coreFn.name;
|
|
725
788
|
const namedFunctions = {
|
|
726
789
|
[functionName]: function(callOptions) {
|
|
727
|
-
|
|
790
|
+
const internal = arguments[1];
|
|
791
|
+
const context = resolveCallContext(internal);
|
|
792
|
+
if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
|
|
728
793
|
signalDeprecation(sdk.context, functionName, getDeprecation);
|
|
729
794
|
}
|
|
730
795
|
return runInMethodScope(() => {
|
|
731
796
|
const startTime = Date.now();
|
|
732
797
|
const normalizedOptions = callOptions ?? {};
|
|
733
798
|
const args = [normalizedOptions];
|
|
734
|
-
const depth = getCurrentDepth();
|
|
799
|
+
const depth = Math.max(context.depth, getCurrentDepth());
|
|
735
800
|
const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
|
|
736
801
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
737
802
|
hooks?.onMethodStart?.({
|
|
@@ -750,7 +815,11 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
750
815
|
...validatedOptions,
|
|
751
816
|
pageSize
|
|
752
817
|
};
|
|
753
|
-
const iterator = paginate(
|
|
818
|
+
const iterator = paginate(
|
|
819
|
+
(pageOptions) => pageFunction(pageOptions, context),
|
|
820
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
821
|
+
optimizedOptions
|
|
822
|
+
);
|
|
754
823
|
const firstPagePromise = iterator.next().then((result) => {
|
|
755
824
|
if (result.done) {
|
|
756
825
|
throw new Error("Paginate should always iterate at least once");
|
|
@@ -787,6 +856,13 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
787
856
|
[Symbol.asyncIterator]() {
|
|
788
857
|
return pageStream;
|
|
789
858
|
},
|
|
859
|
+
pages: function() {
|
|
860
|
+
return {
|
|
861
|
+
[Symbol.asyncIterator]() {
|
|
862
|
+
return pageStream;
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
},
|
|
790
866
|
items: function() {
|
|
791
867
|
return {
|
|
792
868
|
[Symbol.asyncIterator]: async function* () {
|
|
@@ -892,11 +968,11 @@ var RESERVED_ROOT_KEYS = /* @__PURE__ */ new Set([
|
|
|
892
968
|
"context",
|
|
893
969
|
"getRegistry"
|
|
894
970
|
]);
|
|
895
|
-
function hasOwn(obj,
|
|
896
|
-
return Object.prototype.hasOwnProperty.call(obj,
|
|
971
|
+
function hasOwn(obj, key) {
|
|
972
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
897
973
|
}
|
|
898
|
-
function setOwn(target,
|
|
899
|
-
Object.defineProperty(target,
|
|
974
|
+
function setOwn(target, key, value) {
|
|
975
|
+
Object.defineProperty(target, key, {
|
|
900
976
|
value,
|
|
901
977
|
enumerable: true,
|
|
902
978
|
configurable: true,
|
|
@@ -908,31 +984,31 @@ function checkCollisions(target, source, kind, callerLabel, override) {
|
|
|
908
984
|
checkRootKeyCollisions(target, Object.keys(source), override, callerLabel);
|
|
909
985
|
return;
|
|
910
986
|
}
|
|
911
|
-
for (const
|
|
912
|
-
if (!override && hasOwn(target,
|
|
987
|
+
for (const key of Object.keys(source)) {
|
|
988
|
+
if (!override && hasOwn(target, key)) {
|
|
913
989
|
throw new Error(
|
|
914
|
-
`${callerLabel}: duplicate ${kind} "${
|
|
990
|
+
`${callerLabel}: duplicate ${kind} "${key}". If the override is intentional, pass { override: true } in the options.`
|
|
915
991
|
);
|
|
916
992
|
}
|
|
917
993
|
}
|
|
918
994
|
}
|
|
919
995
|
function checkRootKeyCollisions(target, keys, override, callerLabel) {
|
|
920
|
-
for (const
|
|
921
|
-
if (RESERVED_ROOT_KEYS.has(
|
|
996
|
+
for (const key of keys) {
|
|
997
|
+
if (RESERVED_ROOT_KEYS.has(key)) {
|
|
922
998
|
throw new Error(
|
|
923
|
-
`${callerLabel}: plugin attempted to register reserved root key "${
|
|
999
|
+
`${callerLabel}: plugin attempted to register reserved root key "${key}". The SDK uses this key for its own accessor; rename the plugin's method.`
|
|
924
1000
|
);
|
|
925
1001
|
}
|
|
926
|
-
if (!override && hasOwn(target,
|
|
1002
|
+
if (!override && hasOwn(target, key)) {
|
|
927
1003
|
throw new Error(
|
|
928
|
-
`${callerLabel}: duplicate root key "${
|
|
1004
|
+
`${callerLabel}: duplicate root key "${key}". If the override is intentional, pass { override: true } in the options.`
|
|
929
1005
|
);
|
|
930
1006
|
}
|
|
931
1007
|
}
|
|
932
1008
|
}
|
|
933
1009
|
function applyOwnProperties(target, source) {
|
|
934
|
-
for (const
|
|
935
|
-
setOwn(target,
|
|
1010
|
+
for (const key of Object.keys(source)) {
|
|
1011
|
+
setOwn(target, key, source[key]);
|
|
936
1012
|
}
|
|
937
1013
|
}
|
|
938
1014
|
function createPluginAccumulator(initialProperties = {}, initialContext = {}) {
|
|
@@ -1146,7 +1222,6 @@ var LEAF_META_KEYS = [
|
|
|
1146
1222
|
"itemType",
|
|
1147
1223
|
"returnType",
|
|
1148
1224
|
"outputSchema",
|
|
1149
|
-
"inputParameters",
|
|
1150
1225
|
"packages",
|
|
1151
1226
|
"experimental",
|
|
1152
1227
|
"confirm",
|
|
@@ -1183,8 +1258,8 @@ function normalizeImports(deps) {
|
|
|
1183
1258
|
}
|
|
1184
1259
|
function collectLeafMeta(config) {
|
|
1185
1260
|
let meta;
|
|
1186
|
-
for (const
|
|
1187
|
-
if (config[
|
|
1261
|
+
for (const key of LEAF_META_KEYS) {
|
|
1262
|
+
if (config[key] !== void 0) (meta ?? (meta = {}))[key] = config[key];
|
|
1188
1263
|
}
|
|
1189
1264
|
return meta;
|
|
1190
1265
|
}
|
|
@@ -1267,7 +1342,8 @@ function defineResolver(config) {
|
|
|
1267
1342
|
type: "object",
|
|
1268
1343
|
properties: config.properties,
|
|
1269
1344
|
definitions: config.definitions,
|
|
1270
|
-
getProperties: config.getProperties
|
|
1345
|
+
getProperties: config.getProperties,
|
|
1346
|
+
additionalKeys: config.additionalKeys
|
|
1271
1347
|
};
|
|
1272
1348
|
case "array":
|
|
1273
1349
|
return {
|
|
@@ -1570,7 +1646,7 @@ function normalizeFormatter(entry, sdk) {
|
|
|
1570
1646
|
const legacy = entry.meta?.formatter;
|
|
1571
1647
|
return legacy ? adaptLegacyFormatter(legacy, sdk) : void 0;
|
|
1572
1648
|
}
|
|
1573
|
-
function
|
|
1649
|
+
function normalizeResolvers(entry) {
|
|
1574
1650
|
if (entry.pluginType !== "method") return void 0;
|
|
1575
1651
|
return entry.resolvers;
|
|
1576
1652
|
}
|
|
@@ -1611,17 +1687,20 @@ function collectSurfaceProjection(context, formatterSdk) {
|
|
|
1611
1687
|
foldDynamicMembers(entry, surfaceBindings, meta);
|
|
1612
1688
|
}
|
|
1613
1689
|
const formatters = {};
|
|
1614
|
-
const
|
|
1690
|
+
const resolvers = {};
|
|
1615
1691
|
const positional = {};
|
|
1692
|
+
const skipInputValidation = {};
|
|
1616
1693
|
for (const [binding, entry] of Object.entries(entries)) {
|
|
1617
1694
|
const f = normalizeFormatter(entry, formatterSdk);
|
|
1618
1695
|
if (f) formatters[binding] = f;
|
|
1619
|
-
const r =
|
|
1620
|
-
if (r)
|
|
1696
|
+
const r = normalizeResolvers(entry);
|
|
1697
|
+
if (r) resolvers[binding] = r;
|
|
1621
1698
|
const p = methodPositional(entry);
|
|
1622
1699
|
if (p) positional[binding] = p;
|
|
1700
|
+
if (entry.pluginType === "method" && entry.skipInputValidation)
|
|
1701
|
+
skipInputValidation[binding] = true;
|
|
1623
1702
|
}
|
|
1624
|
-
return { meta, formatters,
|
|
1703
|
+
return { meta, formatters, resolvers, positional, skipInputValidation };
|
|
1625
1704
|
}
|
|
1626
1705
|
function buildSurfaceRegistry(context, packageFilter) {
|
|
1627
1706
|
const surface = {};
|
|
@@ -1674,6 +1753,11 @@ function nestedResolvers(resolver) {
|
|
|
1674
1753
|
for (const field of Object.values(resolver.properties ?? {})) {
|
|
1675
1754
|
if (!isResolverRef(field.resolver)) out.push(field.resolver);
|
|
1676
1755
|
}
|
|
1756
|
+
const ak = resolver.additionalKeys;
|
|
1757
|
+
if (ak) {
|
|
1758
|
+
if (!isResolverRef(ak.values)) out.push(ak.values);
|
|
1759
|
+
if (ak.keys && !isResolverRef(ak.keys)) out.push(ak.keys);
|
|
1760
|
+
}
|
|
1677
1761
|
out.push(...Object.values(resolver.definitions ?? {}));
|
|
1678
1762
|
} else if (resolver.type === "array") {
|
|
1679
1763
|
if (!isResolverRef(resolver.items)) out.push(resolver.items);
|
|
@@ -1798,16 +1882,16 @@ function collectPlugins(root, materialized = /* @__PURE__ */ new Set(), configur
|
|
|
1798
1882
|
}
|
|
1799
1883
|
return byId;
|
|
1800
1884
|
}
|
|
1801
|
-
function bindValue(target,
|
|
1885
|
+
function bindValue(target, key, entry, callType = "surface", ctx) {
|
|
1802
1886
|
if (entry.pluginType === "property" && entry.getValue) {
|
|
1803
|
-
Object.defineProperty(target,
|
|
1887
|
+
Object.defineProperty(target, key, {
|
|
1804
1888
|
get: entry.getValue,
|
|
1805
1889
|
enumerable: true,
|
|
1806
1890
|
configurable: true
|
|
1807
1891
|
});
|
|
1808
1892
|
} else {
|
|
1809
|
-
const value = callType === "internal" && entry.pluginType === "method" ? entry.internalValue ?? entry.value : entry.value;
|
|
1810
|
-
Object.defineProperty(target,
|
|
1893
|
+
const value = callType === "internal" && entry.pluginType === "method" ? entry.bindInternal?.(ctx) ?? entry.internalValue ?? entry.value : entry.value;
|
|
1894
|
+
Object.defineProperty(target, key, {
|
|
1811
1895
|
value,
|
|
1812
1896
|
writable: true,
|
|
1813
1897
|
enumerable: true,
|
|
@@ -1824,7 +1908,7 @@ function buildSurface(context, ...maps) {
|
|
|
1824
1908
|
sdk[CONTEXT] = context;
|
|
1825
1909
|
return sdk;
|
|
1826
1910
|
}
|
|
1827
|
-
function buildImports(plugins, importBindings) {
|
|
1911
|
+
function buildImports(plugins, importBindings, ctx) {
|
|
1828
1912
|
const imports = {};
|
|
1829
1913
|
for (const { binding, id, optional } of importBindings) {
|
|
1830
1914
|
const entry = plugins[id];
|
|
@@ -1837,7 +1921,7 @@ function buildImports(plugins, importBindings) {
|
|
|
1837
1921
|
});
|
|
1838
1922
|
continue;
|
|
1839
1923
|
}
|
|
1840
|
-
bindValue(imports, binding, entry, "internal");
|
|
1924
|
+
bindValue(imports, binding, entry, "internal", ctx);
|
|
1841
1925
|
}
|
|
1842
1926
|
return imports;
|
|
1843
1927
|
}
|
|
@@ -1916,6 +2000,19 @@ function bindResolver(resolver, plugins) {
|
|
|
1916
2000
|
const { getProperties } = resolver;
|
|
1917
2001
|
if (getProperties)
|
|
1918
2002
|
bound.getProperties = ({ input }) => getProperties({ imports, input });
|
|
2003
|
+
if (resolver.additionalKeys) {
|
|
2004
|
+
const ak = resolver.additionalKeys;
|
|
2005
|
+
const boundAk = {
|
|
2006
|
+
values: isResolverRef(ak.values) ? ak.values : bindResolver(ak.values, plugins),
|
|
2007
|
+
minEntries: ak.minEntries,
|
|
2008
|
+
maxEntries: ak.maxEntries,
|
|
2009
|
+
keyValueType: ak.keyValueType,
|
|
2010
|
+
valueValueType: ak.valueValueType
|
|
2011
|
+
};
|
|
2012
|
+
if (ak.keys)
|
|
2013
|
+
boundAk.keys = isResolverRef(ak.keys) ? ak.keys : bindResolver(ak.keys, plugins);
|
|
2014
|
+
bound.additionalKeys = boundAk;
|
|
2015
|
+
}
|
|
1919
2016
|
return bound;
|
|
1920
2017
|
}
|
|
1921
2018
|
case "array": {
|
|
@@ -1971,8 +2068,8 @@ function bindResolver(resolver, plugins) {
|
|
|
1971
2068
|
}
|
|
1972
2069
|
function bindFields(fields, plugins) {
|
|
1973
2070
|
const out = {};
|
|
1974
|
-
for (const [
|
|
1975
|
-
out[
|
|
2071
|
+
for (const [key, field] of Object.entries(fields)) {
|
|
2072
|
+
out[key] = {
|
|
1976
2073
|
...field,
|
|
1977
2074
|
resolver: isResolverRef(field.resolver) ? field.resolver : bindResolver(field.resolver, plugins)
|
|
1978
2075
|
};
|
|
@@ -1981,8 +2078,8 @@ function bindFields(fields, plugins) {
|
|
|
1981
2078
|
}
|
|
1982
2079
|
function bindDefinitions(definitions, plugins) {
|
|
1983
2080
|
const out = {};
|
|
1984
|
-
for (const [
|
|
1985
|
-
out[
|
|
2081
|
+
for (const [key, def] of Object.entries(definitions)) {
|
|
2082
|
+
out[key] = bindResolver(def, plugins);
|
|
1986
2083
|
}
|
|
1987
2084
|
return out;
|
|
1988
2085
|
}
|
|
@@ -2066,6 +2163,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2066
2163
|
name: descriptor.name,
|
|
2067
2164
|
chain: [],
|
|
2068
2165
|
inputSchema: descriptor.inputSchema,
|
|
2166
|
+
skipInputValidation: descriptor.skipInputValidation,
|
|
2069
2167
|
// Derive the presentation type from the output mode when the author did
|
|
2070
2168
|
// not set one; an explicit meta.type (e.g. "create") still wins.
|
|
2071
2169
|
meta: out.type === "raw" || descriptor.meta?.type ? descriptor.meta : { ...descriptor.meta, type: out.type },
|
|
@@ -2073,17 +2171,17 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2073
2171
|
// Replaced below; never called.
|
|
2074
2172
|
value: () => void 0
|
|
2075
2173
|
};
|
|
2076
|
-
const callRun = (input) => descriptor.run({
|
|
2077
|
-
imports: buildImports(plugins, descriptor.importBindings),
|
|
2174
|
+
const callRun = (input, ctx) => descriptor.run({
|
|
2175
|
+
imports: buildImports(plugins, descriptor.importBindings, ctx),
|
|
2078
2176
|
state: states.get(id),
|
|
2079
2177
|
input
|
|
2080
2178
|
});
|
|
2081
|
-
const fold = (coreFn) => (input) => {
|
|
2082
|
-
let next = coreFn;
|
|
2179
|
+
const fold = (coreFn) => (input, ctx) => {
|
|
2180
|
+
let next = (i) => coreFn(i, ctx);
|
|
2083
2181
|
for (const wrap of entry.chain) {
|
|
2084
2182
|
const inner = next;
|
|
2085
2183
|
next = (i) => wrap.run({
|
|
2086
|
-
imports: buildImports(plugins, wrap.owner.importBindings),
|
|
2184
|
+
imports: buildImports(plugins, wrap.owner.importBindings, ctx),
|
|
2087
2185
|
next: inner,
|
|
2088
2186
|
input: i,
|
|
2089
2187
|
// Overwritten by the chain item's own closure with the owning
|
|
@@ -2107,7 +2205,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2107
2205
|
}
|
|
2108
2206
|
);
|
|
2109
2207
|
} else if (out.type === "item") {
|
|
2110
|
-
const itemCore = async (input) => callRun(input);
|
|
2208
|
+
const itemCore = async (input, ctx) => callRun(input, ctx);
|
|
2111
2209
|
entry.value = createFunction(
|
|
2112
2210
|
fold(itemCore),
|
|
2113
2211
|
{
|
|
@@ -2119,7 +2217,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2119
2217
|
);
|
|
2120
2218
|
} else {
|
|
2121
2219
|
entry.value = createRawFunction(
|
|
2122
|
-
(input) => fold(callRun)(input),
|
|
2220
|
+
(input, ctx) => fold(callRun)(input, ctx),
|
|
2123
2221
|
{
|
|
2124
2222
|
sdk,
|
|
2125
2223
|
name: descriptor.name,
|
|
@@ -2142,11 +2240,15 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2142
2240
|
});
|
|
2143
2241
|
return packed;
|
|
2144
2242
|
};
|
|
2243
|
+
const internalValue = (...args) => canonicalValue(pack(args), INTERNAL_CALL);
|
|
2145
2244
|
entry.value = (...args) => canonicalValue(pack(args));
|
|
2146
|
-
entry.internalValue =
|
|
2245
|
+
entry.internalValue = internalValue;
|
|
2246
|
+
entry.bindInternal = (ctx) => ctx ? (...args) => canonicalValue(pack(args), childCallContext(ctx)) : internalValue;
|
|
2147
2247
|
entry.positional = names;
|
|
2148
2248
|
} else {
|
|
2149
|
-
|
|
2249
|
+
const internalValue = (input) => canonicalValue(input, INTERNAL_CALL);
|
|
2250
|
+
entry.internalValue = internalValue;
|
|
2251
|
+
entry.bindInternal = (ctx) => ctx ? (input) => canonicalValue(input, childCallContext(ctx)) : internalValue;
|
|
2150
2252
|
}
|
|
2151
2253
|
plugins[id] = entry;
|
|
2152
2254
|
}
|
|
@@ -2386,7 +2488,7 @@ function createSdk(root, options) {
|
|
|
2386
2488
|
pluginSurface = {};
|
|
2387
2489
|
bindValue(pluginSurface, plugin.name, plugins2[plugin.id]);
|
|
2388
2490
|
}
|
|
2389
|
-
for (const
|
|
2491
|
+
for (const key of Object.keys(legacyExports)) context.surface[key] = key;
|
|
2390
2492
|
if (plugin.pluginType === "aggregate") {
|
|
2391
2493
|
recordExportSurface(context, plugin.exports);
|
|
2392
2494
|
} else {
|
|
@@ -2517,6 +2619,7 @@ function valueTypeOf(inner) {
|
|
|
2517
2619
|
if (inner instanceof z.ZodEnum) return "string";
|
|
2518
2620
|
if (inner instanceof z.ZodArray) return "array";
|
|
2519
2621
|
if (inner instanceof z.ZodObject) return "object";
|
|
2622
|
+
if (inner instanceof z.ZodRecord) return "object";
|
|
2520
2623
|
return void 0;
|
|
2521
2624
|
}
|
|
2522
2625
|
function staticChoicesOf(inner) {
|
|
@@ -2527,7 +2630,8 @@ function staticChoicesOf(inner) {
|
|
|
2527
2630
|
return void 0;
|
|
2528
2631
|
}
|
|
2529
2632
|
function objectShape(schema) {
|
|
2530
|
-
const
|
|
2633
|
+
const canonical = canonicalInputSchema(schema);
|
|
2634
|
+
const { inner } = canonical ? unwrap(canonical) : { inner: void 0 };
|
|
2531
2635
|
if (inner instanceof z.ZodObject) {
|
|
2532
2636
|
return inner.shape;
|
|
2533
2637
|
}
|
|
@@ -2549,7 +2653,7 @@ function topoOrder2(specs) {
|
|
|
2549
2653
|
}
|
|
2550
2654
|
function planParameters(entry) {
|
|
2551
2655
|
const shape = objectShape(entry.inputSchema);
|
|
2552
|
-
const resolvers = entry.
|
|
2656
|
+
const resolvers = entry.resolvers ?? {};
|
|
2553
2657
|
const names = shape ? [
|
|
2554
2658
|
...Object.keys(shape),
|
|
2555
2659
|
...Object.keys(resolvers).filter(
|
|
@@ -2585,24 +2689,48 @@ function getAtPath(root, path) {
|
|
|
2585
2689
|
}
|
|
2586
2690
|
return node;
|
|
2587
2691
|
}
|
|
2692
|
+
function defineOwn(node, key, value) {
|
|
2693
|
+
Object.defineProperty(node, key, {
|
|
2694
|
+
value,
|
|
2695
|
+
writable: true,
|
|
2696
|
+
enumerable: true,
|
|
2697
|
+
configurable: true
|
|
2698
|
+
});
|
|
2699
|
+
}
|
|
2588
2700
|
function setAtPath(root, path, value) {
|
|
2589
2701
|
let node = root;
|
|
2590
2702
|
for (let i = 0; i < path.length - 1; i++) {
|
|
2591
2703
|
const seg = path[i];
|
|
2592
|
-
|
|
2593
|
-
|
|
2704
|
+
const existing = Object.prototype.hasOwnProperty.call(node, seg) ? node[seg] : void 0;
|
|
2705
|
+
if (existing != null && typeof existing === "object") {
|
|
2706
|
+
node = existing;
|
|
2707
|
+
} else {
|
|
2708
|
+
const child = {};
|
|
2709
|
+
defineOwn(node, seg, child);
|
|
2710
|
+
node = child;
|
|
2711
|
+
}
|
|
2594
2712
|
}
|
|
2595
|
-
node
|
|
2713
|
+
defineOwn(node, path[path.length - 1], value);
|
|
2596
2714
|
}
|
|
2597
|
-
var
|
|
2715
|
+
var SAFE_SEGMENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
2716
|
+
var pathToKey = (path) => {
|
|
2717
|
+
let out = "";
|
|
2718
|
+
for (const segment of path) {
|
|
2719
|
+
if (typeof segment === "number") out += `[${segment}]`;
|
|
2720
|
+
else if (SAFE_SEGMENT.test(segment))
|
|
2721
|
+
out += out === "" ? segment : `.${segment}`;
|
|
2722
|
+
else out += `[${JSON.stringify(segment)}]`;
|
|
2723
|
+
}
|
|
2724
|
+
return out;
|
|
2725
|
+
};
|
|
2598
2726
|
function isSettled(state, path) {
|
|
2599
|
-
return state.settled.includes(
|
|
2727
|
+
return state.settled.includes(pathToKey(path));
|
|
2600
2728
|
}
|
|
2601
2729
|
function remember(state, k) {
|
|
2602
2730
|
if (!state.settled.includes(k)) state.settled.push(k);
|
|
2603
2731
|
}
|
|
2604
2732
|
function settle(state, path) {
|
|
2605
|
-
remember(state,
|
|
2733
|
+
remember(state, pathToKey(path));
|
|
2606
2734
|
}
|
|
2607
2735
|
function clone(state) {
|
|
2608
2736
|
return JSON.parse(JSON.stringify(state));
|
|
@@ -2617,6 +2745,28 @@ function coerce(leaf, raw) {
|
|
|
2617
2745
|
if (raw === "true") return true;
|
|
2618
2746
|
if (raw === "false") return false;
|
|
2619
2747
|
}
|
|
2748
|
+
if (leaf.valueType === "object") {
|
|
2749
|
+
const trimmed = raw.trim();
|
|
2750
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
2751
|
+
try {
|
|
2752
|
+
return JSON.parse(trimmed);
|
|
2753
|
+
} catch {
|
|
2754
|
+
return raw;
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
return raw;
|
|
2758
|
+
}
|
|
2759
|
+
if (leaf.valueType === "array") {
|
|
2760
|
+
const trimmed = raw.trim();
|
|
2761
|
+
if (trimmed.startsWith("[")) {
|
|
2762
|
+
try {
|
|
2763
|
+
return JSON.parse(trimmed);
|
|
2764
|
+
} catch {
|
|
2765
|
+
return raw;
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
return raw;
|
|
2769
|
+
}
|
|
2620
2770
|
return raw;
|
|
2621
2771
|
}
|
|
2622
2772
|
async function validationError(leaf, value, state) {
|
|
@@ -2674,27 +2824,6 @@ async function objectChildren(resolver, input) {
|
|
|
2674
2824
|
return toLeaf(name, field, resolver.definitions);
|
|
2675
2825
|
});
|
|
2676
2826
|
}
|
|
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
2827
|
function autoSettles(resolver) {
|
|
2699
2828
|
return resolver.type === "constant" || resolver.type === "info";
|
|
2700
2829
|
}
|
|
@@ -2714,10 +2843,28 @@ async function leafAt(ctx, path, resolved) {
|
|
|
2714
2843
|
const seg = path[i];
|
|
2715
2844
|
if (typeof seg === "number") {
|
|
2716
2845
|
if (leaf?.resolver?.type !== "array") return void 0;
|
|
2717
|
-
leaf =
|
|
2846
|
+
leaf = boundLeaf(
|
|
2847
|
+
"",
|
|
2848
|
+
leaf.resolver.items,
|
|
2849
|
+
leaf.resolver.definitions,
|
|
2850
|
+
leaf.resolver.itemValueType
|
|
2851
|
+
);
|
|
2718
2852
|
} else {
|
|
2719
|
-
|
|
2720
|
-
|
|
2853
|
+
const parent = leaf;
|
|
2854
|
+
const found = children.find((c) => c.name === seg);
|
|
2855
|
+
if (found) {
|
|
2856
|
+
leaf = found;
|
|
2857
|
+
} else if (parent?.resolver?.type === "object" && parent.resolver.additionalKeys) {
|
|
2858
|
+
const ak = parent.resolver.additionalKeys;
|
|
2859
|
+
leaf = boundLeaf(
|
|
2860
|
+
String(seg),
|
|
2861
|
+
ak.values,
|
|
2862
|
+
parent.resolver.definitions,
|
|
2863
|
+
ak.valueValueType
|
|
2864
|
+
);
|
|
2865
|
+
} else {
|
|
2866
|
+
return void 0;
|
|
2867
|
+
}
|
|
2721
2868
|
}
|
|
2722
2869
|
if (i < path.length - 1 && typeof path[i + 1] === "string") {
|
|
2723
2870
|
if (leaf?.resolver?.type !== "object") return void 0;
|
|
@@ -2729,16 +2876,81 @@ async function leafAt(ctx, path, resolved) {
|
|
|
2729
2876
|
}
|
|
2730
2877
|
return leaf;
|
|
2731
2878
|
}
|
|
2879
|
+
function boundLeaf(name, resolverOrRef, definitions, valueType) {
|
|
2880
|
+
if (isRef(resolverOrRef)) {
|
|
2881
|
+
return {
|
|
2882
|
+
name,
|
|
2883
|
+
required: true,
|
|
2884
|
+
resolver: definitions?.[resolverOrRef.ref],
|
|
2885
|
+
extraInput: resolverOrRef.input,
|
|
2886
|
+
valueType,
|
|
2887
|
+
requires: []
|
|
2888
|
+
};
|
|
2889
|
+
}
|
|
2890
|
+
return {
|
|
2891
|
+
name,
|
|
2892
|
+
required: true,
|
|
2893
|
+
resolver: resolverOrRef,
|
|
2894
|
+
valueType,
|
|
2895
|
+
requires: []
|
|
2896
|
+
};
|
|
2897
|
+
}
|
|
2898
|
+
async function recordInfoAt(ctx, path, resolved) {
|
|
2899
|
+
const leaf = await leafAt(ctx, path, resolved);
|
|
2900
|
+
const resolver = leaf?.resolver;
|
|
2901
|
+
if (resolver?.type !== "object" || !resolver.additionalKeys) {
|
|
2902
|
+
throw new Error(
|
|
2903
|
+
`expected an object resolver with additionalKeys at "${pathToKey(path)}"`
|
|
2904
|
+
);
|
|
2905
|
+
}
|
|
2906
|
+
if (resolver.getProperties) {
|
|
2907
|
+
throw new Error(
|
|
2908
|
+
`object resolver at "${pathToKey(path)}" cannot combine getProperties with additionalKeys`
|
|
2909
|
+
);
|
|
2910
|
+
}
|
|
2911
|
+
const ak = resolver.additionalKeys;
|
|
2912
|
+
const defs = resolver.definitions;
|
|
2913
|
+
const keyLeaf = ak.keys ? boundLeaf("key", ak.keys, defs, ak.keyValueType ?? "string") : {
|
|
2914
|
+
name: "key",
|
|
2915
|
+
required: true,
|
|
2916
|
+
resolver: { type: "static", inputType: "text" },
|
|
2917
|
+
valueType: "string",
|
|
2918
|
+
requires: []
|
|
2919
|
+
};
|
|
2920
|
+
const valueLeaf = boundLeaf("value", ak.values, defs, ak.valueValueType);
|
|
2921
|
+
if (keyLeaf.resolver && keyLeaf.resolver.type !== "static") {
|
|
2922
|
+
throw new Error(
|
|
2923
|
+
`record key resolver at "${pathToKey(path)}" must be a static free-text prompt, not "${keyLeaf.resolver.type}"`
|
|
2924
|
+
);
|
|
2925
|
+
}
|
|
2926
|
+
if (valueLeaf.resolver?.type === "object" || valueLeaf.resolver?.type === "array") {
|
|
2927
|
+
throw new Error(
|
|
2928
|
+
`record value resolver at "${pathToKey(path)}" must be a single value, not "${valueLeaf.resolver.type}"`
|
|
2929
|
+
);
|
|
2930
|
+
}
|
|
2931
|
+
return {
|
|
2932
|
+
min: ak.minEntries ?? 0,
|
|
2933
|
+
max: ak.maxEntries ?? Infinity,
|
|
2934
|
+
keyLeaf,
|
|
2935
|
+
valueLeaf,
|
|
2936
|
+
fixedKeys: Object.keys(resolver.properties ?? {})
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2732
2939
|
async function arrayInfoAt(ctx, path, resolved) {
|
|
2733
2940
|
const leaf = await leafAt(ctx, path, resolved);
|
|
2734
2941
|
const resolver = leaf?.resolver;
|
|
2735
2942
|
if (resolver?.type !== "array") {
|
|
2736
|
-
throw new Error(`expected an array resolver at "${
|
|
2943
|
+
throw new Error(`expected an array resolver at "${pathToKey(path)}"`);
|
|
2737
2944
|
}
|
|
2738
2945
|
return {
|
|
2739
2946
|
min: resolver.minItems ?? 0,
|
|
2740
2947
|
max: resolver.maxItems ?? Infinity,
|
|
2741
|
-
item:
|
|
2948
|
+
item: boundLeaf(
|
|
2949
|
+
String(path[path.length - 1]),
|
|
2950
|
+
resolver.items,
|
|
2951
|
+
resolver.definitions,
|
|
2952
|
+
resolver.itemValueType
|
|
2953
|
+
)
|
|
2742
2954
|
};
|
|
2743
2955
|
}
|
|
2744
2956
|
async function firstPage(result) {
|
|
@@ -2817,6 +3029,9 @@ var AFFORDANCE = {
|
|
|
2817
3029
|
retry: { action: "retry", description: "Retry loading the options" },
|
|
2818
3030
|
cancel: { action: "cancel", description: "Cancel resolution" }
|
|
2819
3031
|
};
|
|
3032
|
+
function affordance(base, description) {
|
|
3033
|
+
return { ...base, description };
|
|
3034
|
+
}
|
|
2820
3035
|
function selectActions(leaf, page, multiple) {
|
|
2821
3036
|
const searchMode = leaf.resolver?.type === "dynamic" && leaf.resolver.inputType === "search";
|
|
2822
3037
|
if (searchMode && page.position.search === void 0 && page.items.length === 0) {
|
|
@@ -2931,7 +3146,7 @@ async function buildQuestion(leaf, path, input) {
|
|
|
2931
3146
|
}
|
|
2932
3147
|
};
|
|
2933
3148
|
}
|
|
2934
|
-
function
|
|
3149
|
+
function arrayItemsQuestion(t) {
|
|
2935
3150
|
const actions = [AFFORDANCE.add];
|
|
2936
3151
|
if (t.count >= t.min) actions.push(AFFORDANCE.done);
|
|
2937
3152
|
return {
|
|
@@ -2947,22 +3162,37 @@ function collectionQuestion(t) {
|
|
|
2947
3162
|
actions
|
|
2948
3163
|
};
|
|
2949
3164
|
}
|
|
2950
|
-
function
|
|
3165
|
+
function recordEntriesQuestion(t) {
|
|
3166
|
+
const actions = [
|
|
3167
|
+
affordance(AFFORDANCE.add, "Add another entry")
|
|
3168
|
+
];
|
|
3169
|
+
if (t.count >= t.min) {
|
|
3170
|
+
actions.push(affordance(AFFORDANCE.done, "Finish the entries"));
|
|
3171
|
+
}
|
|
3172
|
+
return {
|
|
3173
|
+
type: "collection",
|
|
3174
|
+
path: t.path,
|
|
3175
|
+
message: `Add another ${t.path[t.path.length - 1]} entry? (${t.count} so far)`,
|
|
3176
|
+
container: "record",
|
|
3177
|
+
count: t.count,
|
|
3178
|
+
min: t.min,
|
|
3179
|
+
...Number.isFinite(t.max) ? { max: t.max } : {},
|
|
3180
|
+
actions
|
|
3181
|
+
};
|
|
3182
|
+
}
|
|
3183
|
+
function objectOptionalQuestion(path) {
|
|
2951
3184
|
return {
|
|
2952
3185
|
type: "collection",
|
|
2953
3186
|
path,
|
|
2954
3187
|
message: `Add ${path[path.length - 1]}?`,
|
|
2955
3188
|
container: "object",
|
|
2956
3189
|
actions: [
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
description: "Provide values for these fields"
|
|
2960
|
-
},
|
|
2961
|
-
{ action: "done", description: "Skip these fields" }
|
|
3190
|
+
affordance(AFFORDANCE.add, "Provide values for these fields"),
|
|
3191
|
+
affordance(AFFORDANCE.done, "Skip these fields")
|
|
2962
3192
|
]
|
|
2963
3193
|
};
|
|
2964
3194
|
}
|
|
2965
|
-
function
|
|
3195
|
+
function objectOptionalPropertiesQuestion(path, pending) {
|
|
2966
3196
|
return {
|
|
2967
3197
|
type: "collection",
|
|
2968
3198
|
path,
|
|
@@ -2979,8 +3209,8 @@ function optionalsGateQuestion(path, pending) {
|
|
|
2979
3209
|
...leaf.valueType ? { valueType: leaf.valueType } : {}
|
|
2980
3210
|
})),
|
|
2981
3211
|
actions: [
|
|
2982
|
-
|
|
2983
|
-
|
|
3212
|
+
affordance(AFFORDANCE.add, "Configure the optional fields"),
|
|
3213
|
+
affordance(AFFORDANCE.done, "Skip the optional fields")
|
|
2984
3214
|
]
|
|
2985
3215
|
};
|
|
2986
3216
|
}
|
|
@@ -2996,7 +3226,8 @@ function finalize(ctx, resolved) {
|
|
|
2996
3226
|
}));
|
|
2997
3227
|
return { status: "invalid", issues };
|
|
2998
3228
|
}
|
|
2999
|
-
var optionalsMarker = (path) => `${
|
|
3229
|
+
var optionalsMarker = (path) => `${pathToKey(path)}?optionals`;
|
|
3230
|
+
var UNSAFE_RECORD_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
3000
3231
|
async function findInArray(ctx, state, path) {
|
|
3001
3232
|
if (isSettled(state, path)) return null;
|
|
3002
3233
|
if (getAtPath(state.resolved, path) == null)
|
|
@@ -3017,7 +3248,28 @@ async function findInArray(ctx, state, path) {
|
|
|
3017
3248
|
}
|
|
3018
3249
|
}
|
|
3019
3250
|
if (len < min) return descendItem(ctx, state, path, len, item);
|
|
3020
|
-
if (len < max) return {
|
|
3251
|
+
if (len < max) return { type: "array_items", path, count: len, min, max };
|
|
3252
|
+
settle(state, path);
|
|
3253
|
+
return null;
|
|
3254
|
+
}
|
|
3255
|
+
async function findInRecord(ctx, state, path) {
|
|
3256
|
+
if (isSettled(state, path)) return null;
|
|
3257
|
+
if (getAtPath(state.resolved, path) == null)
|
|
3258
|
+
setAtPath(state.resolved, path, {});
|
|
3259
|
+
if (!state.interactive) {
|
|
3260
|
+
settle(state, path);
|
|
3261
|
+
return null;
|
|
3262
|
+
}
|
|
3263
|
+
const { min, max, keyLeaf, fixedKeys } = await recordInfoAt(
|
|
3264
|
+
ctx,
|
|
3265
|
+
path,
|
|
3266
|
+
state.resolved
|
|
3267
|
+
);
|
|
3268
|
+
const container = getAtPath(state.resolved, path);
|
|
3269
|
+
const fixed = new Set(fixedKeys);
|
|
3270
|
+
const count = Object.keys(container).filter((k) => !fixed.has(k)).length;
|
|
3271
|
+
if (count < min) return { type: "record_key", path, leaf: keyLeaf };
|
|
3272
|
+
if (count < max) return { type: "record_entries", path, count, min, max };
|
|
3021
3273
|
settle(state, path);
|
|
3022
3274
|
return null;
|
|
3023
3275
|
}
|
|
@@ -3035,10 +3287,10 @@ function seedItemSlot(state, itemPath, item) {
|
|
|
3035
3287
|
}
|
|
3036
3288
|
async function descendItem(ctx, state, arrayPath, index, item) {
|
|
3037
3289
|
const itemPath = [...arrayPath, index];
|
|
3038
|
-
const
|
|
3039
|
-
if (
|
|
3040
|
-
if (
|
|
3041
|
-
return {
|
|
3290
|
+
const slotType = seedItemSlot(state, itemPath, item);
|
|
3291
|
+
if (slotType === "object") return findNext(ctx, state, itemPath);
|
|
3292
|
+
if (slotType === "array") return findInArray(ctx, state, itemPath);
|
|
3293
|
+
return { type: "leaf", path: itemPath, leaf: item };
|
|
3042
3294
|
}
|
|
3043
3295
|
async function findNext(ctx, state, path = []) {
|
|
3044
3296
|
const container = getAtPath(state.resolved, path) ?? {};
|
|
@@ -3063,7 +3315,7 @@ async function findNext(ctx, state, path = []) {
|
|
|
3063
3315
|
const pending = ordered.filter(
|
|
3064
3316
|
(c) => !c.required && asksUser(c) && isPendingChild(c)
|
|
3065
3317
|
);
|
|
3066
|
-
return {
|
|
3318
|
+
return { type: "object_optional_properties", path, pending };
|
|
3067
3319
|
}
|
|
3068
3320
|
if (leaf.resolver?.type === "object") {
|
|
3069
3321
|
if (isSettled(state, childPath)) continue;
|
|
@@ -3073,7 +3325,7 @@ async function findNext(ctx, state, path = []) {
|
|
|
3073
3325
|
settle(state, childPath);
|
|
3074
3326
|
continue;
|
|
3075
3327
|
}
|
|
3076
|
-
return {
|
|
3328
|
+
return { type: "object_optional", path: childPath, leaf };
|
|
3077
3329
|
}
|
|
3078
3330
|
setAtPath(state.resolved, childPath, {});
|
|
3079
3331
|
}
|
|
@@ -3105,13 +3357,21 @@ async function findNext(ctx, state, path = []) {
|
|
|
3105
3357
|
}
|
|
3106
3358
|
if (container[leaf.name] !== void 0 || isSettled(state, childPath))
|
|
3107
3359
|
continue;
|
|
3108
|
-
return {
|
|
3360
|
+
return { type: "leaf", path: childPath, leaf };
|
|
3361
|
+
}
|
|
3362
|
+
if (inObject && !isSettled(state, path)) {
|
|
3363
|
+
const self = await leafAt(ctx, path, state.resolved);
|
|
3364
|
+
if (self?.resolver?.type === "object" && self.resolver.additionalKeys) {
|
|
3365
|
+
const rec = await findInRecord(ctx, state, path);
|
|
3366
|
+
if (rec) return rec;
|
|
3367
|
+
}
|
|
3109
3368
|
}
|
|
3110
3369
|
return null;
|
|
3111
3370
|
}
|
|
3112
3371
|
async function askLeaf(state, path, leaf, opts = {}) {
|
|
3113
3372
|
state.current = path;
|
|
3114
|
-
|
|
3373
|
+
if (opts.gate) state.gate = opts.gate;
|
|
3374
|
+
else delete state.gate;
|
|
3115
3375
|
try {
|
|
3116
3376
|
const { question, pagination } = await buildQuestion(
|
|
3117
3377
|
leaf,
|
|
@@ -3132,6 +3392,28 @@ async function askLeaf(state, path, leaf, opts = {}) {
|
|
|
3132
3392
|
return failedResult(state, leaf.name, error);
|
|
3133
3393
|
}
|
|
3134
3394
|
}
|
|
3395
|
+
async function askRecordKey(state, path, keyLeaf, opts = {}) {
|
|
3396
|
+
return askLeaf(state, path, keyLeaf, { gate: "record_key", ...opts });
|
|
3397
|
+
}
|
|
3398
|
+
async function autoResolveLeaf(state, path, leaf) {
|
|
3399
|
+
const resolver = leaf.resolver;
|
|
3400
|
+
if (resolver && autoSettles(resolver)) {
|
|
3401
|
+
if (resolver.type === "constant")
|
|
3402
|
+
setAtPath(state.resolved, path, resolver.value);
|
|
3403
|
+
settle(state, path);
|
|
3404
|
+
return true;
|
|
3405
|
+
}
|
|
3406
|
+
const auto = resolver?.type === "dynamic" ? await resolver.tryResolveWithoutPrompt?.({
|
|
3407
|
+
input: mergeInput(state.resolved, leaf.extraInput)
|
|
3408
|
+
}) : void 0;
|
|
3409
|
+
if (auto) {
|
|
3410
|
+
if (auto.resolvedValue !== void 0)
|
|
3411
|
+
setAtPath(state.resolved, path, auto.resolvedValue);
|
|
3412
|
+
settle(state, path);
|
|
3413
|
+
return true;
|
|
3414
|
+
}
|
|
3415
|
+
return false;
|
|
3416
|
+
}
|
|
3135
3417
|
async function advance(ctx, state) {
|
|
3136
3418
|
for (; ; ) {
|
|
3137
3419
|
const target = await findNext(ctx, state);
|
|
@@ -3141,54 +3423,56 @@ async function advance(ctx, state) {
|
|
|
3141
3423
|
delete state.pagination;
|
|
3142
3424
|
return { state, result: finalize(ctx, state.resolved) };
|
|
3143
3425
|
}
|
|
3144
|
-
if (target.
|
|
3426
|
+
if (target.type === "array_items") {
|
|
3145
3427
|
state.current = target.path;
|
|
3146
|
-
state.gate = "
|
|
3428
|
+
state.gate = "array_items";
|
|
3147
3429
|
delete state.pagination;
|
|
3148
3430
|
return {
|
|
3149
3431
|
state,
|
|
3150
|
-
result: { status: "ask", question:
|
|
3432
|
+
result: { status: "ask", question: arrayItemsQuestion(target) }
|
|
3151
3433
|
};
|
|
3152
3434
|
}
|
|
3153
|
-
if (target.
|
|
3435
|
+
if (target.type === "object_optional") {
|
|
3154
3436
|
state.current = target.path;
|
|
3155
|
-
state.gate = "
|
|
3437
|
+
state.gate = "object_optional";
|
|
3156
3438
|
delete state.pagination;
|
|
3157
3439
|
return {
|
|
3158
3440
|
state,
|
|
3159
|
-
result: {
|
|
3441
|
+
result: {
|
|
3442
|
+
status: "ask",
|
|
3443
|
+
question: objectOptionalQuestion(target.path)
|
|
3444
|
+
}
|
|
3160
3445
|
};
|
|
3161
3446
|
}
|
|
3162
|
-
if (target.
|
|
3447
|
+
if (target.type === "object_optional_properties") {
|
|
3163
3448
|
state.current = target.path;
|
|
3164
|
-
state.gate = "
|
|
3449
|
+
state.gate = "object_optional_properties";
|
|
3165
3450
|
delete state.pagination;
|
|
3166
3451
|
return {
|
|
3167
3452
|
state,
|
|
3168
3453
|
result: {
|
|
3169
3454
|
status: "ask",
|
|
3170
|
-
question:
|
|
3455
|
+
question: objectOptionalPropertiesQuestion(
|
|
3456
|
+
target.path,
|
|
3457
|
+
target.pending
|
|
3458
|
+
)
|
|
3171
3459
|
}
|
|
3172
3460
|
};
|
|
3173
3461
|
}
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3462
|
+
if (target.type === "record_entries") {
|
|
3463
|
+
state.current = target.path;
|
|
3464
|
+
state.gate = "record_entries";
|
|
3465
|
+
delete state.pagination;
|
|
3466
|
+
return {
|
|
3467
|
+
state,
|
|
3468
|
+
result: { status: "ask", question: recordEntriesQuestion(target) }
|
|
3469
|
+
};
|
|
3182
3470
|
}
|
|
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;
|
|
3471
|
+
if (target.type === "record_key") {
|
|
3472
|
+
return askRecordKey(state, target.path, target.leaf);
|
|
3191
3473
|
}
|
|
3474
|
+
const { path, leaf } = target;
|
|
3475
|
+
if (await autoResolveLeaf(state, path, leaf)) continue;
|
|
3192
3476
|
if (!state.interactive) {
|
|
3193
3477
|
if (!leaf.required) {
|
|
3194
3478
|
settle(state, path);
|
|
@@ -3221,10 +3505,18 @@ async function step(ctx, prior, action) {
|
|
|
3221
3505
|
delete state.pagination;
|
|
3222
3506
|
return { state, result: { status: "cancelled" } };
|
|
3223
3507
|
}
|
|
3508
|
+
if (state.gate === "record_key") {
|
|
3509
|
+
return stepRecordKey(ctx, state, action);
|
|
3510
|
+
}
|
|
3224
3511
|
const path = state.current;
|
|
3225
3512
|
if (!path) throw new Error("step called with no outstanding question");
|
|
3226
3513
|
const leaf = await leafAt(ctx, path, state.resolved);
|
|
3227
|
-
if (leaf
|
|
3514
|
+
if (!leaf) {
|
|
3515
|
+
throw new Error(
|
|
3516
|
+
`no resolver for the outstanding question at "${pathToKey(path)}"`
|
|
3517
|
+
);
|
|
3518
|
+
}
|
|
3519
|
+
if (action.type === "search" || action.type === "next_page" || action.type === "previous_page" || action.type === "retry") {
|
|
3228
3520
|
return refine(ctx, state, leaf, path, action);
|
|
3229
3521
|
}
|
|
3230
3522
|
if (action.type === "add" || action.type === "done") {
|
|
@@ -3241,19 +3533,26 @@ async function step(ctx, prior, action) {
|
|
|
3241
3533
|
settle(state, path);
|
|
3242
3534
|
return advance(ctx, state);
|
|
3243
3535
|
}
|
|
3244
|
-
if (gate === "
|
|
3536
|
+
if (gate === "object_optional") {
|
|
3245
3537
|
setAtPath(state.resolved, path, {});
|
|
3246
3538
|
return advance(ctx, state);
|
|
3247
3539
|
}
|
|
3248
|
-
if (gate === "
|
|
3540
|
+
if (gate === "object_optional_properties") {
|
|
3249
3541
|
remember(state, optionalsMarker(path));
|
|
3250
3542
|
return advance(ctx, state);
|
|
3251
3543
|
}
|
|
3544
|
+
if (gate === "record_entries") {
|
|
3545
|
+
const { keyLeaf } = await recordInfoAt(ctx, path, state.resolved);
|
|
3546
|
+
return askRecordKey(state, path, keyLeaf);
|
|
3547
|
+
}
|
|
3252
3548
|
const items = getAtPath(state.resolved, path) ?? [];
|
|
3253
3549
|
const { item } = await arrayInfoAt(ctx, path, state.resolved);
|
|
3254
3550
|
const itemPath = [...path, items.length];
|
|
3255
|
-
if (seedItemSlot(state, itemPath, item) === "leaf")
|
|
3551
|
+
if (seedItemSlot(state, itemPath, item) === "leaf") {
|
|
3552
|
+
if (await autoResolveLeaf(state, itemPath, item))
|
|
3553
|
+
return advance(ctx, state);
|
|
3256
3554
|
return askLeaf(state, itemPath, item);
|
|
3555
|
+
}
|
|
3257
3556
|
return advance(ctx, state);
|
|
3258
3557
|
}
|
|
3259
3558
|
if (state.gate) {
|
|
@@ -3264,81 +3563,37 @@ async function step(ctx, prior, action) {
|
|
|
3264
3563
|
switch (action.type) {
|
|
3265
3564
|
case "choose":
|
|
3266
3565
|
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 });
|
|
3566
|
+
let error;
|
|
3567
|
+
try {
|
|
3568
|
+
error = await validationError(leaf, action.value, state);
|
|
3569
|
+
} catch (thrown) {
|
|
3570
|
+
return failedResult(state, leaf.name, thrown);
|
|
3571
|
+
}
|
|
3572
|
+
if (error) {
|
|
3573
|
+
if (state.pagination && leaf.resolver?.type === "dynamic") {
|
|
3574
|
+
return renderPageAt(state, leaf, path, state.pagination.position, {
|
|
3575
|
+
error
|
|
3576
|
+
});
|
|
3308
3577
|
}
|
|
3578
|
+
return askLeaf(state, path, leaf, { error });
|
|
3309
3579
|
}
|
|
3310
|
-
setAtPath(
|
|
3311
|
-
state.resolved,
|
|
3312
|
-
path,
|
|
3313
|
-
leaf ? coerce(leaf, action.value) : action.value
|
|
3314
|
-
);
|
|
3580
|
+
setAtPath(state.resolved, path, coerce(leaf, action.value));
|
|
3315
3581
|
break;
|
|
3316
3582
|
}
|
|
3317
3583
|
case "skip":
|
|
3318
3584
|
settle(state, path);
|
|
3319
3585
|
break;
|
|
3320
3586
|
default:
|
|
3321
|
-
throw new Error(
|
|
3587
|
+
throw new Error(
|
|
3588
|
+
`action "${action.type}" is not supported here`
|
|
3589
|
+
);
|
|
3322
3590
|
}
|
|
3323
3591
|
delete state.current;
|
|
3324
3592
|
delete state.pagination;
|
|
3325
3593
|
return advance(ctx, state);
|
|
3326
3594
|
}
|
|
3327
|
-
async function
|
|
3328
|
-
const position = positionAfter(state.pagination, action);
|
|
3595
|
+
async function renderPageAt(state, leaf, path, position, opts = {}) {
|
|
3329
3596
|
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
3597
|
const context = await resolveContext(leaf, state.resolved);
|
|
3343
3598
|
const page = await fetchListing(leaf, state.resolved, position, context);
|
|
3344
3599
|
state.pagination = toPagination(page);
|
|
@@ -3346,7 +3601,8 @@ async function refine(ctx, state, leaf, path, action) {
|
|
|
3346
3601
|
state,
|
|
3347
3602
|
result: {
|
|
3348
3603
|
status: "ask",
|
|
3349
|
-
question: selectQuestion(leaf, path, state.resolved, page, context)
|
|
3604
|
+
question: selectQuestion(leaf, path, state.resolved, page, context),
|
|
3605
|
+
...opts.error ? { error: opts.error } : {}
|
|
3350
3606
|
}
|
|
3351
3607
|
};
|
|
3352
3608
|
} catch (error) {
|
|
@@ -3354,6 +3610,65 @@ async function refine(ctx, state, leaf, path, action) {
|
|
|
3354
3610
|
return failedResult(state, leaf.name, error);
|
|
3355
3611
|
}
|
|
3356
3612
|
}
|
|
3613
|
+
async function refine(ctx, state, leaf, path, action) {
|
|
3614
|
+
const position = positionAfter(state.pagination, action);
|
|
3615
|
+
if (action.type === "search") {
|
|
3616
|
+
try {
|
|
3617
|
+
const exact = leaf.resolver?.type === "dynamic" ? await leaf.resolver.tryResolveFromSearch?.({
|
|
3618
|
+
input: mergeInput(state.resolved, leaf.extraInput),
|
|
3619
|
+
search: action.term
|
|
3620
|
+
}) : void 0;
|
|
3621
|
+
if (exact) {
|
|
3622
|
+
setAtPath(state.resolved, path, coerce(leaf, exact.resolvedValue));
|
|
3623
|
+
delete state.current;
|
|
3624
|
+
delete state.pagination;
|
|
3625
|
+
return advance(ctx, state);
|
|
3626
|
+
}
|
|
3627
|
+
} catch (error) {
|
|
3628
|
+
state.pagination = failedPagination(state.pagination, position);
|
|
3629
|
+
return failedResult(state, leaf.name, error);
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
return renderPageAt(state, leaf, path, position);
|
|
3633
|
+
}
|
|
3634
|
+
async function stepRecordKey(ctx, state, action) {
|
|
3635
|
+
const path = state.current;
|
|
3636
|
+
if (!path)
|
|
3637
|
+
throw new Error("record key step called with no outstanding question");
|
|
3638
|
+
const { keyLeaf, valueLeaf } = await recordInfoAt(ctx, path, state.resolved);
|
|
3639
|
+
if (action.type === "skip") {
|
|
3640
|
+
delete state.gate;
|
|
3641
|
+
delete state.current;
|
|
3642
|
+
delete state.pagination;
|
|
3643
|
+
return advance(ctx, state);
|
|
3644
|
+
}
|
|
3645
|
+
if (action.type !== "custom" && action.type !== "choose") {
|
|
3646
|
+
throw new Error(
|
|
3647
|
+
`action "${action.type}" is not supported while entering a record key`
|
|
3648
|
+
);
|
|
3649
|
+
}
|
|
3650
|
+
const raw = Array.isArray(action.value) ? action.value[0] : action.value;
|
|
3651
|
+
const entryKey = String(coerce(keyLeaf, raw));
|
|
3652
|
+
if (entryKey.trim() === "") {
|
|
3653
|
+
return askRecordKey(state, path, keyLeaf, { error: "A key is required." });
|
|
3654
|
+
}
|
|
3655
|
+
if (UNSAFE_RECORD_KEYS.has(entryKey)) {
|
|
3656
|
+
return askRecordKey(state, path, keyLeaf, {
|
|
3657
|
+
error: `"${entryKey}" is not an allowed key.`
|
|
3658
|
+
});
|
|
3659
|
+
}
|
|
3660
|
+
const container = getAtPath(state.resolved, path);
|
|
3661
|
+
if (Object.prototype.hasOwnProperty.call(container, entryKey)) {
|
|
3662
|
+
return askRecordKey(state, path, keyLeaf, {
|
|
3663
|
+
error: `"${entryKey}" is already set.`
|
|
3664
|
+
});
|
|
3665
|
+
}
|
|
3666
|
+
const valuePath = [...path, entryKey];
|
|
3667
|
+
if (await autoResolveLeaf(state, valuePath, valueLeaf)) {
|
|
3668
|
+
return advance(ctx, state);
|
|
3669
|
+
}
|
|
3670
|
+
return askLeaf(state, valuePath, valueLeaf);
|
|
3671
|
+
}
|
|
3357
3672
|
function failedPagination(pagination, retryPosition) {
|
|
3358
3673
|
return {
|
|
3359
3674
|
position: pagination?.position ?? firstPagePosition(),
|
|
@@ -3407,7 +3722,7 @@ function projectSummary(entry) {
|
|
|
3407
3722
|
};
|
|
3408
3723
|
}
|
|
3409
3724
|
function projectMethod(entry) {
|
|
3410
|
-
const inputProperties = toJsonSchema(entry.inputSchema)?.properties;
|
|
3725
|
+
const inputProperties = toJsonSchema(canonicalInputSchema(entry.inputSchema))?.properties;
|
|
3411
3726
|
const parameters = {};
|
|
3412
3727
|
for (const spec of planParameters(entry).parameters) {
|
|
3413
3728
|
const dynamic = spec.resolver?.type === "dynamic" ? spec.resolver : void 0;
|
|
@@ -3440,7 +3755,12 @@ function createController(sdk) {
|
|
|
3440
3755
|
const entry = entryFor(method);
|
|
3441
3756
|
return {
|
|
3442
3757
|
method,
|
|
3443
|
-
|
|
3758
|
+
// A method that owns its input validation (`skipInputValidation`, e.g.
|
|
3759
|
+
// fetch) must not be re-validated by the controller's final `safeParse`;
|
|
3760
|
+
// drop the schema so `finalize` returns the resolved input untouched.
|
|
3761
|
+
// Planning still reads `entry.inputSchema` directly, so parameters are
|
|
3762
|
+
// unaffected.
|
|
3763
|
+
schema: entry.skipInputValidation ? void 0 : entry.inputSchema,
|
|
3444
3764
|
parameters: planParameters(entry).parameters
|
|
3445
3765
|
};
|
|
3446
3766
|
}
|
|
@@ -3503,30 +3823,6 @@ function createCorePlugin(options) {
|
|
|
3503
3823
|
}
|
|
3504
3824
|
});
|
|
3505
3825
|
}
|
|
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
|
-
function openEnum(values, description) {
|
|
3528
|
-
return z.union([z.enum(values), z.string()]).describe(description);
|
|
3529
|
-
}
|
|
3530
3826
|
|
|
3531
3827
|
// src/utils/logging.ts
|
|
3532
3828
|
var { logDeprecation: logDeprecation2, resetDeprecationWarnings: resetDeprecationWarnings2 } = createDeprecationLogger("zapier-sdk");
|
|
@@ -3935,8 +4231,8 @@ function censorHeaders(headers) {
|
|
|
3935
4231
|
if (!headers) return headers;
|
|
3936
4232
|
const headersObj = new Headers(headers);
|
|
3937
4233
|
const authKeys = ["authorization", "x-api-key"];
|
|
3938
|
-
for (const [
|
|
3939
|
-
if (authKeys.some((authKey) =>
|
|
4234
|
+
for (const [key, value] of headersObj.entries()) {
|
|
4235
|
+
if (authKeys.some((authKey) => key.toLowerCase() === authKey)) {
|
|
3940
4236
|
const spaceIndex = value.indexOf(" ");
|
|
3941
4237
|
if (spaceIndex > 0 && spaceIndex < value.length - 1) {
|
|
3942
4238
|
const prefix = value.substring(0, spaceIndex + 1);
|
|
@@ -3944,19 +4240,19 @@ function censorHeaders(headers) {
|
|
|
3944
4240
|
if (token.length > 12) {
|
|
3945
4241
|
const start2 = token.substring(0, 4);
|
|
3946
4242
|
const end = token.substring(token.length - 4);
|
|
3947
|
-
headersObj.set(
|
|
4243
|
+
headersObj.set(key, `${prefix}${start2}...${end}`);
|
|
3948
4244
|
} else {
|
|
3949
4245
|
const firstChar = token.charAt(0);
|
|
3950
|
-
headersObj.set(
|
|
4246
|
+
headersObj.set(key, `${prefix}${firstChar}...`);
|
|
3951
4247
|
}
|
|
3952
4248
|
} else {
|
|
3953
4249
|
if (value.length > 12) {
|
|
3954
4250
|
const start2 = value.substring(0, 4);
|
|
3955
4251
|
const end = value.substring(value.length - 4);
|
|
3956
|
-
headersObj.set(
|
|
4252
|
+
headersObj.set(key, `${start2}...${end}`);
|
|
3957
4253
|
} else {
|
|
3958
4254
|
const firstChar = value.charAt(0);
|
|
3959
|
-
headersObj.set(
|
|
4255
|
+
headersObj.set(key, `${firstChar}...`);
|
|
3960
4256
|
}
|
|
3961
4257
|
}
|
|
3962
4258
|
}
|
|
@@ -4604,21 +4900,21 @@ function getClientIdFromCredentials(credentials) {
|
|
|
4604
4900
|
function createMemoryCache() {
|
|
4605
4901
|
const store = /* @__PURE__ */ new Map();
|
|
4606
4902
|
return {
|
|
4607
|
-
async get(
|
|
4608
|
-
const entry = store.get(
|
|
4903
|
+
async get(key) {
|
|
4904
|
+
const entry = store.get(key);
|
|
4609
4905
|
if (!entry) return void 0;
|
|
4610
4906
|
if (entry.expiresAt !== void 0 && entry.expiresAt <= Date.now()) {
|
|
4611
|
-
store.delete(
|
|
4907
|
+
store.delete(key);
|
|
4612
4908
|
return void 0;
|
|
4613
4909
|
}
|
|
4614
4910
|
return { value: entry.value, expiresAt: entry.expiresAt };
|
|
4615
4911
|
},
|
|
4616
|
-
async set(
|
|
4912
|
+
async set(key, value, options) {
|
|
4617
4913
|
const expiresAt = options?.ttl ? Date.now() + options.ttl * 1e3 : void 0;
|
|
4618
|
-
store.set(
|
|
4914
|
+
store.set(key, { value, expiresAt });
|
|
4619
4915
|
},
|
|
4620
|
-
async delete(
|
|
4621
|
-
store.delete(
|
|
4916
|
+
async delete(key) {
|
|
4917
|
+
store.delete(key);
|
|
4622
4918
|
}
|
|
4623
4919
|
};
|
|
4624
4920
|
}
|
|
@@ -5281,7 +5577,7 @@ function parseDeprecationDate(value) {
|
|
|
5281
5577
|
}
|
|
5282
5578
|
|
|
5283
5579
|
// src/sdk-version.ts
|
|
5284
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.
|
|
5580
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.86.0" : void 0) || "unknown";
|
|
5285
5581
|
|
|
5286
5582
|
// src/utils/open-url.ts
|
|
5287
5583
|
var nodePrefix = "node:";
|
|
@@ -5539,11 +5835,11 @@ var ZapierApiClient = class {
|
|
|
5539
5835
|
);
|
|
5540
5836
|
const inputHeaders = new Headers(init?.headers ?? {});
|
|
5541
5837
|
const mergedHeaders = new Headers();
|
|
5542
|
-
builtHeaders.forEach((value,
|
|
5543
|
-
mergedHeaders.set(
|
|
5838
|
+
builtHeaders.forEach((value, key) => {
|
|
5839
|
+
mergedHeaders.set(key, value);
|
|
5544
5840
|
});
|
|
5545
|
-
inputHeaders.forEach((value,
|
|
5546
|
-
mergedHeaders.set(
|
|
5841
|
+
inputHeaders.forEach((value, key) => {
|
|
5842
|
+
mergedHeaders.set(key, value);
|
|
5547
5843
|
});
|
|
5548
5844
|
this.applyTelemetryHeaders(mergedHeaders);
|
|
5549
5845
|
let retries = 0;
|
|
@@ -6068,8 +6364,8 @@ var ZapierApiClient = class {
|
|
|
6068
6364
|
canSendDeprecationMessaging
|
|
6069
6365
|
} = this.applyPathConfiguration(path);
|
|
6070
6366
|
if (searchParams) {
|
|
6071
|
-
Object.entries(searchParams).forEach(([
|
|
6072
|
-
url.searchParams.set(
|
|
6367
|
+
Object.entries(searchParams).forEach(([key, value]) => {
|
|
6368
|
+
url.searchParams.set(key, value);
|
|
6073
6369
|
});
|
|
6074
6370
|
}
|
|
6075
6371
|
return {
|
|
@@ -7126,13 +7422,13 @@ function parseManifestSection({
|
|
|
7126
7422
|
return void 0;
|
|
7127
7423
|
}
|
|
7128
7424
|
const kept = {};
|
|
7129
|
-
for (const [
|
|
7425
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
7130
7426
|
const result = schema.safeParse(value);
|
|
7131
7427
|
if (result.success) {
|
|
7132
|
-
kept[
|
|
7428
|
+
kept[key] = result.data;
|
|
7133
7429
|
} else {
|
|
7134
7430
|
console.warn(
|
|
7135
|
-
`\u26A0\uFE0F Dropping invalid "${section}" entry "${
|
|
7431
|
+
`\u26A0\uFE0F Dropping invalid "${section}" entry "${key}" in ${source}: ${result.error}`
|
|
7136
7432
|
);
|
|
7137
7433
|
}
|
|
7138
7434
|
}
|
|
@@ -7281,9 +7577,9 @@ function findManifestEntry({
|
|
|
7281
7577
|
return [slug, manifest.apps[slug]];
|
|
7282
7578
|
}
|
|
7283
7579
|
}
|
|
7284
|
-
for (const [
|
|
7580
|
+
for (const [key, entry] of Object.entries(manifest.apps)) {
|
|
7285
7581
|
if (entry.implementationName === appKeyWithoutVersion) {
|
|
7286
|
-
return [
|
|
7582
|
+
return [key, entry];
|
|
7287
7583
|
}
|
|
7288
7584
|
}
|
|
7289
7585
|
return null;
|
|
@@ -7537,8 +7833,8 @@ function normalizeHeaders(optionsHeaders) {
|
|
|
7537
7833
|
return headers;
|
|
7538
7834
|
}
|
|
7539
7835
|
const headerEntries = optionsHeaders instanceof Headers ? Array.from(optionsHeaders.entries()) : Array.isArray(optionsHeaders) ? optionsHeaders : Object.entries(optionsHeaders);
|
|
7540
|
-
for (const [
|
|
7541
|
-
headers[
|
|
7836
|
+
for (const [key, value] of headerEntries) {
|
|
7837
|
+
headers[key] = value;
|
|
7542
7838
|
}
|
|
7543
7839
|
return headers;
|
|
7544
7840
|
}
|
|
@@ -7609,14 +7905,9 @@ var fetchPlugin = defineMethod({
|
|
|
7609
7905
|
// of order.
|
|
7610
7906
|
categories: [{ key: "http", title: "HTTP Request" }],
|
|
7611
7907
|
returnType: "Response",
|
|
7612
|
-
// The controller
|
|
7613
|
-
// `positional
|
|
7614
|
-
// individual flags (--method, --connection, ...)
|
|
7615
|
-
// the only surface that reads this. Both describe the same (url, init) shape.
|
|
7616
|
-
inputParameters: [
|
|
7617
|
-
{ name: "url", schema: FetchUrlSchema },
|
|
7618
|
-
{ name: "init", schema: FetchInitSchema }
|
|
7619
|
-
],
|
|
7908
|
+
// The CLI, controller, and MCP all derive fetch's `(url, init)` shape from
|
|
7909
|
+
// `inputSchema` + `positional`; the CLI flattens `init`'s fields into
|
|
7910
|
+
// individual flags (--method, --connection, ...) off that same schema.
|
|
7620
7911
|
// Build the validator once, binding it to the head's `adaptError` so failures
|
|
7621
7912
|
// surface as `ZapierValidationError` rather than the neutral kitcore fallback.
|
|
7622
7913
|
setup: ({ imports }) => {
|
|
@@ -7755,9 +8046,9 @@ var RunActionInputSchema = z.union([RunActionSchema, RunActionSchemaDeprecated])
|
|
|
7755
8046
|
var ActionResultItemSchema = z.unknown().describe("Action execution result");
|
|
7756
8047
|
|
|
7757
8048
|
// src/formatters/actionResult.ts
|
|
7758
|
-
function getStringProperty(obj,
|
|
7759
|
-
if (typeof obj === "object" && obj !== null &&
|
|
7760
|
-
const value = obj[
|
|
8049
|
+
function getStringProperty(obj, key) {
|
|
8050
|
+
if (typeof obj === "object" && obj !== null && key in obj) {
|
|
8051
|
+
const value = obj[key];
|
|
7761
8052
|
return typeof value === "string" ? value : void 0;
|
|
7762
8053
|
}
|
|
7763
8054
|
return void 0;
|
|
@@ -8243,21 +8534,21 @@ var actionKeyResolver = defineResolver({
|
|
|
8243
8534
|
});
|
|
8244
8535
|
|
|
8245
8536
|
// src/plugins/capabilities/index.ts
|
|
8246
|
-
function toDescription(
|
|
8247
|
-
const words =
|
|
8537
|
+
function toDescription(key) {
|
|
8538
|
+
const words = key.replace(/^can/, "").replace(/([A-Z])/g, " $1").trim().toLowerCase();
|
|
8248
8539
|
return `To ${words}`;
|
|
8249
8540
|
}
|
|
8250
|
-
function toEnvVar(
|
|
8251
|
-
return "ZAPIER_" +
|
|
8541
|
+
function toEnvVar(key) {
|
|
8542
|
+
return "ZAPIER_" + key.replace(/([A-Z])/g, "_$1").toUpperCase();
|
|
8252
8543
|
}
|
|
8253
|
-
function toCliFlag(
|
|
8254
|
-
return "--" +
|
|
8544
|
+
function toCliFlag(key) {
|
|
8545
|
+
return "--" + key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
8255
8546
|
}
|
|
8256
|
-
function buildCapabilityMessage(
|
|
8547
|
+
function buildCapabilityMessage(key) {
|
|
8257
8548
|
return [
|
|
8258
|
-
`${toDescription(
|
|
8259
|
-
`set ${
|
|
8260
|
-
`or set ${toEnvVar(
|
|
8549
|
+
`${toDescription(key)}, use ${toCliFlag(key)} in the CLI,`,
|
|
8550
|
+
`set ${key}: true in SDK options or .zapierrc,`,
|
|
8551
|
+
`or set ${toEnvVar(key)}=true.`
|
|
8261
8552
|
].join(" ");
|
|
8262
8553
|
}
|
|
8263
8554
|
var GATED_FLAGS = [
|
|
@@ -8265,8 +8556,8 @@ var GATED_FLAGS = [
|
|
|
8265
8556
|
"canIncludeSharedTables",
|
|
8266
8557
|
"canDeleteTables"
|
|
8267
8558
|
];
|
|
8268
|
-
function isEnabledByEnv(
|
|
8269
|
-
const value = globalThis.process?.env?.[toEnvVar(
|
|
8559
|
+
function isEnabledByEnv(key) {
|
|
8560
|
+
const value = globalThis.process?.env?.[toEnvVar(key)];
|
|
8270
8561
|
if (value === void 0) return void 0;
|
|
8271
8562
|
if (value === "true" || value === "1") return true;
|
|
8272
8563
|
if (value === "false" || value === "0") return false;
|
|
@@ -8293,17 +8584,17 @@ var capabilitiesPlugin = defineProperty({
|
|
|
8293
8584
|
return cached;
|
|
8294
8585
|
}
|
|
8295
8586
|
return {
|
|
8296
|
-
checkCapability: async (
|
|
8587
|
+
checkCapability: async (key) => {
|
|
8297
8588
|
const flags = await resolveFlags();
|
|
8298
|
-
if (flags[
|
|
8589
|
+
if (flags[key]) return;
|
|
8299
8590
|
throw new ZapierConfigurationError(
|
|
8300
|
-
buildCapabilityMessage(
|
|
8301
|
-
{ configType:
|
|
8591
|
+
buildCapabilityMessage(key) + " (If you are an AI agent, you MUST NOT retry. Ask the user if they want to enable this.)",
|
|
8592
|
+
{ configType: key }
|
|
8302
8593
|
);
|
|
8303
8594
|
},
|
|
8304
|
-
hasCapability: async (
|
|
8595
|
+
hasCapability: async (key) => {
|
|
8305
8596
|
const flags = await resolveFlags();
|
|
8306
|
-
return flags[
|
|
8597
|
+
return flags[key];
|
|
8307
8598
|
}
|
|
8308
8599
|
};
|
|
8309
8600
|
},
|
|
@@ -8588,13 +8879,13 @@ var tableIdResolver = defineResolver({
|
|
|
8588
8879
|
listItems: ({ imports, context, cursor }) => {
|
|
8589
8880
|
const includeShared = context?.includeShared;
|
|
8590
8881
|
if (includeShared) {
|
|
8591
|
-
return
|
|
8882
|
+
return concatLists({
|
|
8592
8883
|
sources: [
|
|
8593
|
-
({ cursor:
|
|
8594
|
-
({ cursor:
|
|
8884
|
+
({ cursor: listCursor }) => imports.listTablesInternal({ cursor: listCursor }),
|
|
8885
|
+
({ cursor: listCursor }) => imports.listTablesInternal({
|
|
8595
8886
|
includeShared: true,
|
|
8596
8887
|
includePersonal: false,
|
|
8597
|
-
cursor:
|
|
8888
|
+
cursor: listCursor
|
|
8598
8889
|
})
|
|
8599
8890
|
],
|
|
8600
8891
|
cursor
|
|
@@ -8800,7 +9091,7 @@ function formatRecordError(fieldId, err) {
|
|
|
8800
9091
|
function formatResponseError(err) {
|
|
8801
9092
|
const message = err.human_title || err.title || "Unknown error";
|
|
8802
9093
|
if (err.meta && Object.keys(err.meta).length > 0) {
|
|
8803
|
-
const metaParts = Object.entries(err.meta).map(([
|
|
9094
|
+
const metaParts = Object.entries(err.meta).map(([key, val]) => `${key}: ${JSON.stringify(val)}`).join(", ");
|
|
8804
9095
|
return `${message} (${metaParts})`;
|
|
8805
9096
|
}
|
|
8806
9097
|
return message;
|
|
@@ -8835,8 +9126,8 @@ var TrashSchema = z.enum(["exclude", "include", "only"]).optional().describe(
|
|
|
8835
9126
|
'Control soft-deleted item visibility. "exclude" (default) returns active items only, "include" returns both active and soft-deleted, "only" returns soft-deleted items only.'
|
|
8836
9127
|
);
|
|
8837
9128
|
var FIELD_ID_PATTERN = /^f\d+$/;
|
|
8838
|
-
function isFieldId(
|
|
8839
|
-
return FIELD_ID_PATTERN.test(
|
|
9129
|
+
function isFieldId(key) {
|
|
9130
|
+
return FIELD_ID_PATTERN.test(key);
|
|
8840
9131
|
}
|
|
8841
9132
|
var NESTED_COMPONENTS = {
|
|
8842
9133
|
labeled_string: /* @__PURE__ */ new Set(["value"]),
|
|
@@ -8874,7 +9165,7 @@ async function resolveFieldKeys({
|
|
|
8874
9165
|
fieldKeys
|
|
8875
9166
|
}) {
|
|
8876
9167
|
const allAreIds = fieldKeys.every(
|
|
8877
|
-
(
|
|
9168
|
+
(key) => typeof key === "number" || /^(f?\d+)$/.test(key)
|
|
8878
9169
|
);
|
|
8879
9170
|
if (allAreIds) {
|
|
8880
9171
|
return fieldKeys.map(toNumericFieldId);
|
|
@@ -8883,13 +9174,13 @@ async function resolveFieldKeys({
|
|
|
8883
9174
|
if (!mapping) {
|
|
8884
9175
|
return fieldKeys.map(toNumericFieldId);
|
|
8885
9176
|
}
|
|
8886
|
-
return fieldKeys.map((
|
|
8887
|
-
if (typeof
|
|
8888
|
-
if (FIELD_ID_PATTERN.test(
|
|
8889
|
-
const id = mapping.nameToId.get(
|
|
9177
|
+
return fieldKeys.map((key) => {
|
|
9178
|
+
if (typeof key === "number") return key;
|
|
9179
|
+
if (FIELD_ID_PATTERN.test(key)) return toNumericFieldId(key);
|
|
9180
|
+
const id = mapping.nameToId.get(key);
|
|
8890
9181
|
if (!id) {
|
|
8891
9182
|
throw new ZapierValidationError(
|
|
8892
|
-
`Unknown field name: "${
|
|
9183
|
+
`Unknown field name: "${key}". Use a valid field name or ID.`
|
|
8893
9184
|
);
|
|
8894
9185
|
}
|
|
8895
9186
|
return toNumericFieldId(id);
|
|
@@ -8905,13 +9196,13 @@ async function createFieldKeyTranslator({
|
|
|
8905
9196
|
translateInput(data) {
|
|
8906
9197
|
if (!mapping) return data;
|
|
8907
9198
|
const result = {};
|
|
8908
|
-
for (const [
|
|
8909
|
-
if (FIELD_ID_PATTERN.test(
|
|
8910
|
-
result[
|
|
8911
|
-
} else if (mapping.nameToId.has(
|
|
8912
|
-
result[mapping.nameToId.get(
|
|
9199
|
+
for (const [key, value] of Object.entries(data)) {
|
|
9200
|
+
if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
|
|
9201
|
+
result[key] = value;
|
|
9202
|
+
} else if (mapping.nameToId.has(key)) {
|
|
9203
|
+
result[mapping.nameToId.get(key)] = value;
|
|
8913
9204
|
} else {
|
|
8914
|
-
result[
|
|
9205
|
+
result[key] = value;
|
|
8915
9206
|
}
|
|
8916
9207
|
}
|
|
8917
9208
|
return result;
|
|
@@ -8919,29 +9210,29 @@ async function createFieldKeyTranslator({
|
|
|
8919
9210
|
translateOutput(data) {
|
|
8920
9211
|
if (!mapping) return data;
|
|
8921
9212
|
const result = {};
|
|
8922
|
-
for (const [
|
|
8923
|
-
if (mapping.idToName.has(
|
|
8924
|
-
result[mapping.idToName.get(
|
|
9213
|
+
for (const [key, value] of Object.entries(data)) {
|
|
9214
|
+
if (mapping.idToName.has(key)) {
|
|
9215
|
+
result[mapping.idToName.get(key)] = value;
|
|
8925
9216
|
} else {
|
|
8926
|
-
result[
|
|
9217
|
+
result[key] = value;
|
|
8927
9218
|
}
|
|
8928
9219
|
}
|
|
8929
9220
|
return result;
|
|
8930
9221
|
},
|
|
8931
|
-
translateFieldKey(
|
|
8932
|
-
if (!mapping) return
|
|
8933
|
-
if (FIELD_ID_PATTERN.test(
|
|
8934
|
-
const fieldType = mapping.idToType.get(
|
|
9222
|
+
translateFieldKey(key) {
|
|
9223
|
+
if (!mapping) return key;
|
|
9224
|
+
if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
|
|
9225
|
+
const fieldType = mapping.idToType.get(key);
|
|
8935
9226
|
if (fieldType) {
|
|
8936
9227
|
const components = NESTED_COMPONENTS[fieldType];
|
|
8937
9228
|
if (components?.size === 1) {
|
|
8938
|
-
return `${
|
|
9229
|
+
return `${key}__${[...components][0]}`;
|
|
8939
9230
|
}
|
|
8940
9231
|
}
|
|
8941
|
-
return
|
|
9232
|
+
return key;
|
|
8942
9233
|
}
|
|
8943
|
-
if (mapping.nameToId.has(
|
|
8944
|
-
const fieldId = mapping.nameToId.get(
|
|
9234
|
+
if (mapping.nameToId.has(key)) {
|
|
9235
|
+
const fieldId = mapping.nameToId.get(key);
|
|
8945
9236
|
const fieldType = mapping.idToType.get(fieldId);
|
|
8946
9237
|
if (fieldType) {
|
|
8947
9238
|
const components = NESTED_COMPONENTS[fieldType];
|
|
@@ -8951,10 +9242,10 @@ async function createFieldKeyTranslator({
|
|
|
8951
9242
|
}
|
|
8952
9243
|
return fieldId;
|
|
8953
9244
|
}
|
|
8954
|
-
const sepIndex =
|
|
9245
|
+
const sepIndex = key.lastIndexOf("__");
|
|
8955
9246
|
if (sepIndex > 0) {
|
|
8956
|
-
const prefix =
|
|
8957
|
-
const component =
|
|
9247
|
+
const prefix = key.slice(0, sepIndex);
|
|
9248
|
+
const component = key.slice(sepIndex + 2);
|
|
8958
9249
|
let fieldId;
|
|
8959
9250
|
if (FIELD_ID_PATTERN.test(prefix) && mapping.idToName.has(prefix)) {
|
|
8960
9251
|
fieldId = prefix;
|
|
@@ -8968,7 +9259,7 @@ async function createFieldKeyTranslator({
|
|
|
8968
9259
|
}
|
|
8969
9260
|
}
|
|
8970
9261
|
}
|
|
8971
|
-
return
|
|
9262
|
+
return key;
|
|
8972
9263
|
}
|
|
8973
9264
|
};
|
|
8974
9265
|
}
|
|
@@ -9564,13 +9855,13 @@ var runActionPlugin = defineMethod({
|
|
|
9564
9855
|
let oldestKey;
|
|
9565
9856
|
let oldestExpiry = Infinity;
|
|
9566
9857
|
let evictedAny = false;
|
|
9567
|
-
for (const [
|
|
9858
|
+
for (const [key, entry] of cache) {
|
|
9568
9859
|
if (now >= entry.expiresAt) {
|
|
9569
|
-
cache.delete(
|
|
9860
|
+
cache.delete(key);
|
|
9570
9861
|
evictedAny = true;
|
|
9571
9862
|
} else if (entry.expiresAt < oldestExpiry) {
|
|
9572
9863
|
oldestExpiry = entry.expiresAt;
|
|
9573
|
-
oldestKey =
|
|
9864
|
+
oldestKey = key;
|
|
9574
9865
|
}
|
|
9575
9866
|
}
|
|
9576
9867
|
if (!evictedAny && oldestKey) cache.delete(oldestKey);
|
|
@@ -9928,7 +10219,7 @@ var listAppsPlugin = defineMethod({
|
|
|
9928
10219
|
locator
|
|
9929
10220
|
];
|
|
9930
10221
|
}
|
|
9931
|
-
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((
|
|
10222
|
+
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
|
|
9932
10223
|
if (duplicatedLookupAppKeys.length > 0) {
|
|
9933
10224
|
throw new Error(
|
|
9934
10225
|
`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
|
|
@@ -10880,8 +11171,8 @@ function formatRootField(item) {
|
|
|
10880
11171
|
}
|
|
10881
11172
|
var rootFieldItemFormatter = defineFormatter({
|
|
10882
11173
|
format: ({ item }) => {
|
|
10883
|
-
const { key
|
|
10884
|
-
return { ...rest, hint:
|
|
11174
|
+
const { key, ...rest } = formatRootField(item);
|
|
11175
|
+
return { ...rest, hint: key };
|
|
10885
11176
|
}
|
|
10886
11177
|
});
|
|
10887
11178
|
|
|
@@ -11622,7 +11913,7 @@ var createTriggerInboxPlugin = defineMethod({
|
|
|
11622
11913
|
inputs = {},
|
|
11623
11914
|
notificationUrl
|
|
11624
11915
|
} = input;
|
|
11625
|
-
const
|
|
11916
|
+
const key = input.key ?? input.name;
|
|
11626
11917
|
const resolvedConnectionId = await resolveConnectionId({
|
|
11627
11918
|
connection,
|
|
11628
11919
|
resolveConnection
|
|
@@ -11642,8 +11933,8 @@ var createTriggerInboxPlugin = defineMethod({
|
|
|
11642
11933
|
connection_id: resolvedConnectionId ?? null
|
|
11643
11934
|
}
|
|
11644
11935
|
};
|
|
11645
|
-
if (
|
|
11646
|
-
requestBody.key =
|
|
11936
|
+
if (key !== void 0) {
|
|
11937
|
+
requestBody.key = key;
|
|
11647
11938
|
}
|
|
11648
11939
|
if (notificationUrl !== void 0) {
|
|
11649
11940
|
requestBody.notification_url = notificationUrl;
|
|
@@ -11657,7 +11948,7 @@ var createTriggerInboxPlugin = defineMethod({
|
|
|
11657
11948
|
if (status === 409) {
|
|
11658
11949
|
const detail = extractErrorDetail(data);
|
|
11659
11950
|
return new ZapierConflictError(
|
|
11660
|
-
detail ?? `An inbox with key "${
|
|
11951
|
+
detail ?? `An inbox with key "${key}" already exists with a different subscription.`,
|
|
11661
11952
|
{ statusCode: status, resourceType: "trigger_inbox" }
|
|
11662
11953
|
);
|
|
11663
11954
|
}
|
|
@@ -11725,7 +12016,7 @@ var ensureTriggerInboxPlugin = defineMethod({
|
|
|
11725
12016
|
inputs = {},
|
|
11726
12017
|
notificationUrl
|
|
11727
12018
|
} = input;
|
|
11728
|
-
const
|
|
12019
|
+
const key = "key" in input ? input.key : input.name;
|
|
11729
12020
|
const resolvedConnectionId = await resolveConnectionId({
|
|
11730
12021
|
connection,
|
|
11731
12022
|
resolveConnection
|
|
@@ -11738,7 +12029,7 @@ var ensureTriggerInboxPlugin = defineMethod({
|
|
|
11738
12029
|
);
|
|
11739
12030
|
}
|
|
11740
12031
|
const requestBody = {
|
|
11741
|
-
key
|
|
12032
|
+
key,
|
|
11742
12033
|
subscription: {
|
|
11743
12034
|
app_key: selectedApi,
|
|
11744
12035
|
action_key: actionKey,
|
|
@@ -11758,7 +12049,7 @@ var ensureTriggerInboxPlugin = defineMethod({
|
|
|
11758
12049
|
if (status === 409) {
|
|
11759
12050
|
const detail = extractErrorDetail(data);
|
|
11760
12051
|
return new ZapierConflictError(
|
|
11761
|
-
detail ?? `An inbox with key "${
|
|
12052
|
+
detail ?? `An inbox with key "${key}" already exists with a different subscription.`,
|
|
11762
12053
|
{ statusCode: status, resourceType: "trigger_inbox" }
|
|
11763
12054
|
);
|
|
11764
12055
|
}
|
|
@@ -12405,9 +12696,9 @@ function createWaiter() {
|
|
|
12405
12696
|
}
|
|
12406
12697
|
};
|
|
12407
12698
|
}
|
|
12408
|
-
function addToMap(m,
|
|
12409
|
-
const existing = m.get(
|
|
12410
|
-
m.set(
|
|
12699
|
+
function addToMap(m, key, value) {
|
|
12700
|
+
const existing = m.get(key) ?? [];
|
|
12701
|
+
m.set(key, [...existing, value]);
|
|
12411
12702
|
}
|
|
12412
12703
|
async function runBatchedDrainPipeline(options) {
|
|
12413
12704
|
const {
|
|
@@ -14166,8 +14457,8 @@ function getOsInfo() {
|
|
|
14166
14457
|
function getPlatformVersions() {
|
|
14167
14458
|
const versions = {};
|
|
14168
14459
|
if (typeof globalThis.process?.versions === "object") {
|
|
14169
|
-
for (const [
|
|
14170
|
-
versions[
|
|
14460
|
+
for (const [key, value] of Object.entries(globalThis.process.versions)) {
|
|
14461
|
+
versions[key] = value || null;
|
|
14171
14462
|
}
|
|
14172
14463
|
}
|
|
14173
14464
|
return versions;
|
|
@@ -14421,9 +14712,9 @@ async function emitWithTimeout(transport, subject, event) {
|
|
|
14421
14712
|
}
|
|
14422
14713
|
function mergeUserContext(event, userContext) {
|
|
14423
14714
|
const merged = { ...event };
|
|
14424
|
-
for (const [
|
|
14425
|
-
if (merged[
|
|
14426
|
-
merged[
|
|
14715
|
+
for (const [key, value] of Object.entries(userContext)) {
|
|
14716
|
+
if (merged[key] == null) {
|
|
14717
|
+
merged[key] = value;
|
|
14427
14718
|
}
|
|
14428
14719
|
}
|
|
14429
14720
|
return merged;
|
|
@@ -14902,14 +15193,14 @@ function toWireConnections(connections) {
|
|
|
14902
15193
|
}
|
|
14903
15194
|
function toWireAppVersions(appVersions) {
|
|
14904
15195
|
const wire = {};
|
|
14905
|
-
for (const [
|
|
15196
|
+
for (const [key, entry] of Object.entries(appVersions)) {
|
|
14906
15197
|
const implementationName = entry.implementationName ?? entry.implementation_name;
|
|
14907
15198
|
if (implementationName === void 0) {
|
|
14908
15199
|
throw new ZapierValidationError(
|
|
14909
|
-
`appVersions["${
|
|
15200
|
+
`appVersions["${key}"] is missing implementationName`
|
|
14910
15201
|
);
|
|
14911
15202
|
}
|
|
14912
|
-
wire[
|
|
15203
|
+
wire[key] = {
|
|
14913
15204
|
implementation_name: implementationName,
|
|
14914
15205
|
...entry.version !== void 0 ? { version: entry.version } : {}
|
|
14915
15206
|
};
|
|
@@ -15582,6 +15873,26 @@ var RunDurableResponseSchema = z.object({
|
|
|
15582
15873
|
created_at: z.string().describe("When the run was created (ISO-8601)")
|
|
15583
15874
|
});
|
|
15584
15875
|
|
|
15876
|
+
// src/resolvers/sourceFiles.ts
|
|
15877
|
+
var sourceFilesResolver = defineResolver({
|
|
15878
|
+
type: "object",
|
|
15879
|
+
additionalKeys: {
|
|
15880
|
+
minEntries: 1,
|
|
15881
|
+
keys: defineResolver({
|
|
15882
|
+
type: "static",
|
|
15883
|
+
inputType: "text",
|
|
15884
|
+
placeholder: "filename (e.g. index.ts)"
|
|
15885
|
+
}),
|
|
15886
|
+
values: defineResolver({
|
|
15887
|
+
type: "static",
|
|
15888
|
+
inputType: "text",
|
|
15889
|
+
placeholder: "file contents"
|
|
15890
|
+
}),
|
|
15891
|
+
keyValueType: "string",
|
|
15892
|
+
valueValueType: "string"
|
|
15893
|
+
}
|
|
15894
|
+
});
|
|
15895
|
+
|
|
15585
15896
|
// src/plugins/codeSubstrate/runDurable/index.ts
|
|
15586
15897
|
var runDurablePlugin = defineMethod({
|
|
15587
15898
|
...codeSubstrateDefaults,
|
|
@@ -15592,6 +15903,7 @@ var runDurablePlugin = defineMethod({
|
|
|
15592
15903
|
inputSchema: RunDurableOptionsSchema,
|
|
15593
15904
|
outputSchema: RunDurableResponseSchema,
|
|
15594
15905
|
output: "item",
|
|
15906
|
+
resolvers: { sourceFiles: sourceFilesResolver },
|
|
15595
15907
|
run: async ({ imports, input }) => {
|
|
15596
15908
|
const api = imports.api;
|
|
15597
15909
|
const sourceFiles = "sourceFiles" in input ? input.sourceFiles : input.source_files;
|
|
@@ -15762,7 +16074,7 @@ var publishWorkflowVersionPlugin = defineMethod({
|
|
|
15762
16074
|
inputSchema: PublishWorkflowVersionOptionsSchema,
|
|
15763
16075
|
outputSchema: PublishWorkflowVersionResponseSchema,
|
|
15764
16076
|
output: "item",
|
|
15765
|
-
resolvers: { workflow: workflowIdResolver },
|
|
16077
|
+
resolvers: { workflow: workflowIdResolver, sourceFiles: sourceFilesResolver },
|
|
15766
16078
|
run: async ({ imports, input }) => {
|
|
15767
16079
|
const api = imports.api;
|
|
15768
16080
|
const sourceFiles = "sourceFiles" in input ? input.sourceFiles : input.source_files;
|