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