@zapier/kitcore 0.10.1 → 0.12.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/CHANGELOG.md +27 -0
- package/README.md +63 -5
- package/dist/index.cjs +486 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +252 -26
- package/dist/index.d.ts +252 -26
- package/dist/index.mjs +484 -98
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -197,12 +197,19 @@ function composeVoid(existing, added) {
|
|
|
197
197
|
isolated.add(composed);
|
|
198
198
|
return composed;
|
|
199
199
|
}
|
|
200
|
+
function composeAnnotators(existing, added) {
|
|
201
|
+
if (!existing) return added;
|
|
202
|
+
if (!added) return existing;
|
|
203
|
+
return (ctx) => ({ ...existing(ctx), ...added(ctx) });
|
|
204
|
+
}
|
|
200
205
|
function buildHooks(existing, added) {
|
|
201
206
|
const result = {};
|
|
202
207
|
const start2 = composeVoid(existing.onMethodStart, added.onMethodStart);
|
|
203
208
|
if (start2) result.onMethodStart = start2;
|
|
204
209
|
const end = composeVoid(existing.onMethodEnd, added.onMethodEnd);
|
|
205
210
|
if (end) result.onMethodEnd = end;
|
|
211
|
+
const annotator = composeAnnotators(existing.annotator, added.annotator);
|
|
212
|
+
if (annotator) result.annotator = annotator;
|
|
206
213
|
return result;
|
|
207
214
|
}
|
|
208
215
|
|
|
@@ -677,11 +684,14 @@ function generateCallId() {
|
|
|
677
684
|
}
|
|
678
685
|
return null;
|
|
679
686
|
}
|
|
680
|
-
function rootCallContext(
|
|
687
|
+
function rootCallContext({
|
|
688
|
+
callOrigin = "surface"
|
|
689
|
+
} = {}) {
|
|
681
690
|
return {
|
|
682
691
|
callId: generateCallId(),
|
|
683
692
|
depth: 0,
|
|
684
693
|
annotations: {},
|
|
694
|
+
callOrigin,
|
|
685
695
|
[CALL_CONTEXT_BRAND]: true
|
|
686
696
|
};
|
|
687
697
|
}
|
|
@@ -690,6 +700,7 @@ function childCallContext(parent) {
|
|
|
690
700
|
callId: parent.callId,
|
|
691
701
|
depth: parent.depth + 1,
|
|
692
702
|
annotations: {},
|
|
703
|
+
callOrigin: parent.callOrigin,
|
|
693
704
|
[CALL_CONTEXT_BRAND]: true
|
|
694
705
|
};
|
|
695
706
|
}
|
|
@@ -715,6 +726,28 @@ var INTERNAL_CALL = Symbol("kitcore.internalCall");
|
|
|
715
726
|
function resolveCallContext(secondArg) {
|
|
716
727
|
return isCallContext(secondArg) ? secondArg : rootCallContext();
|
|
717
728
|
}
|
|
729
|
+
var hookAnnotatorReentrancy = 0;
|
|
730
|
+
function applyAnnotations({
|
|
731
|
+
context,
|
|
732
|
+
methodName,
|
|
733
|
+
input,
|
|
734
|
+
hookAnnotator,
|
|
735
|
+
methodAnnotator
|
|
736
|
+
}) {
|
|
737
|
+
if (hookAnnotator && !isInsideObserver() && context.depth === 0 && context.callOrigin !== "internal" && hookAnnotatorReentrancy === 0) {
|
|
738
|
+
hookAnnotatorReentrancy++;
|
|
739
|
+
try {
|
|
740
|
+
Object.assign(context.annotations, hookAnnotator({ methodName, input }));
|
|
741
|
+
} catch {
|
|
742
|
+
} finally {
|
|
743
|
+
hookAnnotatorReentrancy--;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
try {
|
|
747
|
+
Object.assign(context.annotations, methodAnnotator?.(input));
|
|
748
|
+
} catch {
|
|
749
|
+
}
|
|
750
|
+
}
|
|
718
751
|
function signalDeprecation(context, methodName, getDeprecation) {
|
|
719
752
|
if (isInsideObserver()) return;
|
|
720
753
|
const deprecation = getDeprecation?.();
|
|
@@ -740,7 +773,7 @@ function normalizeError(error, adaptError) {
|
|
|
740
773
|
);
|
|
741
774
|
}
|
|
742
775
|
function createFunction(coreFn, options) {
|
|
743
|
-
const { sdk, schema, name, getDeprecation } = options;
|
|
776
|
+
const { sdk, schema, name, annotator, getDeprecation } = options;
|
|
744
777
|
const functionName = name || coreFn.name;
|
|
745
778
|
const namedFunctions = {
|
|
746
779
|
[functionName]: async function(callOptions) {
|
|
@@ -754,14 +787,26 @@ function createFunction(coreFn, options) {
|
|
|
754
787
|
const normalizedOptions = callOptions ?? {};
|
|
755
788
|
const args = [normalizedOptions];
|
|
756
789
|
const depth = Math.max(context.depth, getCurrentDepth());
|
|
757
|
-
const
|
|
790
|
+
const insideObserver = isInsideObserver();
|
|
791
|
+
const hooks = insideObserver ? void 0 : sdk.context.hooks;
|
|
758
792
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
759
|
-
|
|
793
|
+
applyAnnotations({
|
|
794
|
+
context,
|
|
795
|
+
methodName: functionName,
|
|
796
|
+
input: normalizedOptions,
|
|
797
|
+
hookAnnotator: hooks?.annotator,
|
|
798
|
+
methodAnnotator: annotator
|
|
799
|
+
});
|
|
800
|
+
const hookBase = {
|
|
760
801
|
methodName: functionName,
|
|
761
802
|
args,
|
|
762
803
|
isPaginated: false,
|
|
763
|
-
depth
|
|
764
|
-
|
|
804
|
+
depth,
|
|
805
|
+
callId: context.callId,
|
|
806
|
+
callOrigin: context.callOrigin,
|
|
807
|
+
annotations: context.annotations
|
|
808
|
+
};
|
|
809
|
+
hooks?.onMethodStart?.({ ...hookBase });
|
|
765
810
|
try {
|
|
766
811
|
let result;
|
|
767
812
|
if (schema) {
|
|
@@ -783,20 +828,14 @@ function createFunction(coreFn, options) {
|
|
|
783
828
|
result = await coreFn(normalizedOptions, context);
|
|
784
829
|
}
|
|
785
830
|
hooks?.onMethodEnd?.({
|
|
786
|
-
|
|
787
|
-
args,
|
|
788
|
-
isPaginated: false,
|
|
789
|
-
depth,
|
|
831
|
+
...hookBase,
|
|
790
832
|
durationMs: Date.now() - startTime
|
|
791
833
|
});
|
|
792
834
|
return result;
|
|
793
835
|
} catch (error) {
|
|
794
836
|
const normalizedError = normalizeError(error, adaptError);
|
|
795
837
|
hooks?.onMethodEnd?.({
|
|
796
|
-
|
|
797
|
-
args,
|
|
798
|
-
isPaginated: false,
|
|
799
|
-
depth,
|
|
838
|
+
...hookBase,
|
|
800
839
|
durationMs: Date.now() - startTime,
|
|
801
840
|
error: normalizedError
|
|
802
841
|
});
|
|
@@ -808,7 +847,7 @@ function createFunction(coreFn, options) {
|
|
|
808
847
|
return namedFunctions[functionName];
|
|
809
848
|
}
|
|
810
849
|
function createRawFunction(coreFn, options) {
|
|
811
|
-
const { sdk, name, schema, positional, getDeprecation } = options;
|
|
850
|
+
const { sdk, name, schema, positional, annotator, getDeprecation } = options;
|
|
812
851
|
return function(rawInput) {
|
|
813
852
|
const internal = arguments[1];
|
|
814
853
|
const context = resolveCallContext(internal);
|
|
@@ -818,23 +857,32 @@ function createRawFunction(coreFn, options) {
|
|
|
818
857
|
return runInMethodScope(() => {
|
|
819
858
|
const startTime = Date.now();
|
|
820
859
|
const depth = Math.max(context.depth, getCurrentDepth());
|
|
821
|
-
const
|
|
860
|
+
const insideObserver = isInsideObserver();
|
|
861
|
+
const hooks = insideObserver ? void 0 : sdk.context.hooks;
|
|
822
862
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
823
863
|
const input = schema ? rawInput ?? {} : rawInput;
|
|
864
|
+
applyAnnotations({
|
|
865
|
+
context,
|
|
866
|
+
methodName: name,
|
|
867
|
+
input,
|
|
868
|
+
hookAnnotator: hooks?.annotator,
|
|
869
|
+
methodAnnotator: annotator
|
|
870
|
+
});
|
|
824
871
|
const record = input;
|
|
825
872
|
const args = positional ? positional.filter((key) => record?.[key] !== void 0).map((key) => record?.[key]) : [input];
|
|
826
|
-
|
|
873
|
+
const hookBase = {
|
|
827
874
|
methodName: name,
|
|
828
875
|
args,
|
|
829
876
|
isPaginated: false,
|
|
830
|
-
depth
|
|
831
|
-
|
|
877
|
+
depth,
|
|
878
|
+
callId: context.callId,
|
|
879
|
+
callOrigin: context.callOrigin,
|
|
880
|
+
annotations: context.annotations
|
|
881
|
+
};
|
|
882
|
+
hooks?.onMethodStart?.({ ...hookBase });
|
|
832
883
|
const fireEnd = (error) => {
|
|
833
884
|
hooks?.onMethodEnd?.({
|
|
834
|
-
|
|
835
|
-
args,
|
|
836
|
-
isPaginated: false,
|
|
837
|
-
depth,
|
|
885
|
+
...hookBase,
|
|
838
886
|
durationMs: Date.now() - startTime,
|
|
839
887
|
...error ? { error } : {}
|
|
840
888
|
});
|
|
@@ -876,7 +924,8 @@ function isSdkPage(value) {
|
|
|
876
924
|
}
|
|
877
925
|
function createPageFunction(coreFn, {
|
|
878
926
|
sdk,
|
|
879
|
-
adaptPage
|
|
927
|
+
adaptPage,
|
|
928
|
+
finalizePage
|
|
880
929
|
}) {
|
|
881
930
|
const functionName = coreFn.name + "Page";
|
|
882
931
|
const namedFunctions = {
|
|
@@ -889,7 +938,7 @@ function createPageFunction(coreFn, {
|
|
|
889
938
|
`${functionName}: paginated result must be exactly { data: TItem[], nextCursor? } (produced by the handler or its \`adaptPage\`); got keys [${page && typeof page === "object" ? Object.keys(page).join(", ") : typeof page}]. If the handler returns a raw shape, set \`adaptPage\` to translate it; if \`adaptPage\` already runs, it must return only \`data\`/\`nextCursor\`.`
|
|
890
939
|
);
|
|
891
940
|
}
|
|
892
|
-
return page;
|
|
941
|
+
return finalizePage ? finalizePage(page) : page;
|
|
893
942
|
} catch (error) {
|
|
894
943
|
throw normalizeError(
|
|
895
944
|
error,
|
|
@@ -901,8 +950,21 @@ function createPageFunction(coreFn, {
|
|
|
901
950
|
return namedFunctions[functionName];
|
|
902
951
|
}
|
|
903
952
|
function createPaginatedFunction(coreFn, options) {
|
|
904
|
-
const {
|
|
905
|
-
|
|
953
|
+
const {
|
|
954
|
+
sdk,
|
|
955
|
+
schema,
|
|
956
|
+
name,
|
|
957
|
+
defaultPageSize,
|
|
958
|
+
adaptPage,
|
|
959
|
+
annotator,
|
|
960
|
+
finalizePage,
|
|
961
|
+
getDeprecation
|
|
962
|
+
} = options;
|
|
963
|
+
const pageFunction = createPageFunction(coreFn, {
|
|
964
|
+
sdk,
|
|
965
|
+
adaptPage,
|
|
966
|
+
finalizePage
|
|
967
|
+
});
|
|
906
968
|
const functionName = name || coreFn.name;
|
|
907
969
|
const namedFunctions = {
|
|
908
970
|
[functionName]: function(callOptions) {
|
|
@@ -916,14 +978,26 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
916
978
|
const normalizedOptions = callOptions ?? {};
|
|
917
979
|
const args = [normalizedOptions];
|
|
918
980
|
const depth = Math.max(context.depth, getCurrentDepth());
|
|
919
|
-
const
|
|
981
|
+
const insideObserver = isInsideObserver();
|
|
982
|
+
const hooks = insideObserver ? void 0 : sdk.context.hooks;
|
|
920
983
|
const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
|
|
921
|
-
|
|
984
|
+
applyAnnotations({
|
|
985
|
+
context,
|
|
986
|
+
methodName: functionName,
|
|
987
|
+
input: normalizedOptions,
|
|
988
|
+
hookAnnotator: hooks?.annotator,
|
|
989
|
+
methodAnnotator: annotator
|
|
990
|
+
});
|
|
991
|
+
const hookBase = {
|
|
922
992
|
methodName: functionName,
|
|
923
993
|
args,
|
|
924
994
|
isPaginated: true,
|
|
925
|
-
depth
|
|
926
|
-
|
|
995
|
+
depth,
|
|
996
|
+
callId: context.callId,
|
|
997
|
+
callOrigin: context.callOrigin,
|
|
998
|
+
annotations: context.annotations
|
|
999
|
+
};
|
|
1000
|
+
hooks?.onMethodStart?.({ ...hookBase });
|
|
927
1001
|
try {
|
|
928
1002
|
const validatedOptions = {
|
|
929
1003
|
...normalizedOptions,
|
|
@@ -949,19 +1023,13 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
949
1023
|
firstPagePromise.then(
|
|
950
1024
|
() => {
|
|
951
1025
|
hooks.onMethodEnd({
|
|
952
|
-
|
|
953
|
-
args,
|
|
954
|
-
isPaginated: true,
|
|
955
|
-
depth,
|
|
1026
|
+
...hookBase,
|
|
956
1027
|
durationMs: Date.now() - startTime
|
|
957
1028
|
});
|
|
958
1029
|
},
|
|
959
1030
|
(error) => {
|
|
960
1031
|
hooks.onMethodEnd({
|
|
961
|
-
|
|
962
|
-
args,
|
|
963
|
-
isPaginated: true,
|
|
964
|
-
depth,
|
|
1032
|
+
...hookBase,
|
|
965
1033
|
durationMs: Date.now() - startTime,
|
|
966
1034
|
error: error instanceof Error ? error : new Error(String(error))
|
|
967
1035
|
});
|
|
@@ -1000,10 +1068,7 @@ function createPaginatedFunction(coreFn, options) {
|
|
|
1000
1068
|
} catch (error) {
|
|
1001
1069
|
const normalizedError = normalizeError(error, adaptError);
|
|
1002
1070
|
hooks?.onMethodEnd?.({
|
|
1003
|
-
|
|
1004
|
-
args,
|
|
1005
|
-
isPaginated: true,
|
|
1006
|
-
depth,
|
|
1071
|
+
...hookBase,
|
|
1007
1072
|
durationMs: Date.now() - startTime,
|
|
1008
1073
|
error: normalizedError
|
|
1009
1074
|
});
|
|
@@ -1425,9 +1490,11 @@ function defineMethod(config) {
|
|
|
1425
1490
|
importBindings: deps.bindings,
|
|
1426
1491
|
inputSchema: config.inputSchema,
|
|
1427
1492
|
skipInputValidation: config.skipInputValidation,
|
|
1493
|
+
skipOutputValidation: config.skipOutputValidation,
|
|
1428
1494
|
meta: collectLeafMeta(config),
|
|
1429
1495
|
resolvers: config.resolvers,
|
|
1430
1496
|
formatter: config.formatter,
|
|
1497
|
+
annotator: config.annotator,
|
|
1431
1498
|
output: config.output,
|
|
1432
1499
|
positional: config.positional,
|
|
1433
1500
|
setup: config.setup,
|
|
@@ -1530,6 +1597,29 @@ function declareMethod(config) {
|
|
|
1530
1597
|
}
|
|
1531
1598
|
};
|
|
1532
1599
|
}
|
|
1600
|
+
function declareOptionalMethod(config) {
|
|
1601
|
+
const { name, namespace } = parseId(config.id);
|
|
1602
|
+
const id = makeId(name, namespace);
|
|
1603
|
+
return {
|
|
1604
|
+
pluginType: "method",
|
|
1605
|
+
name,
|
|
1606
|
+
namespace,
|
|
1607
|
+
id,
|
|
1608
|
+
standIn: true,
|
|
1609
|
+
optional: true,
|
|
1610
|
+
imports: [],
|
|
1611
|
+
importBindings: [],
|
|
1612
|
+
run: () => {
|
|
1613
|
+
throw new Error(
|
|
1614
|
+
`Plugin "${id}" is an optional stand-in (declareOptionalMethod) with no implementation. Its binding is \`undefined\` unless a real plugin is registered under this id.`
|
|
1615
|
+
);
|
|
1616
|
+
}
|
|
1617
|
+
// Requires nothing (phantom carrier `<never, never>`): a consumer that
|
|
1618
|
+
// imports it still passes `createSdk`'s completeness check unprovided. The
|
|
1619
|
+
// `optional: true` literal drives `PluginSurface` to type the binding
|
|
1620
|
+
// `| undefined`.
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1533
1623
|
function defineProperty(config) {
|
|
1534
1624
|
const deps = normalizeImports(config.imports);
|
|
1535
1625
|
return {
|
|
@@ -1575,6 +1665,11 @@ function declareOptionalProperty(config) {
|
|
|
1575
1665
|
// import binding is still typed `TValue | undefined` from the descriptor.
|
|
1576
1666
|
};
|
|
1577
1667
|
}
|
|
1668
|
+
function declareDefault({
|
|
1669
|
+
plugin
|
|
1670
|
+
}) {
|
|
1671
|
+
return { ...plugin, defaultSource: plugin };
|
|
1672
|
+
}
|
|
1578
1673
|
function defineHook(config) {
|
|
1579
1674
|
const deps = normalizeImports(config.imports);
|
|
1580
1675
|
return {
|
|
@@ -1587,7 +1682,8 @@ function defineHook(config) {
|
|
|
1587
1682
|
setup: config.setup,
|
|
1588
1683
|
dispose: config.dispose,
|
|
1589
1684
|
wrap: config.wrap,
|
|
1590
|
-
observe: config.observe
|
|
1685
|
+
observe: config.observe,
|
|
1686
|
+
annotator: config.annotator
|
|
1591
1687
|
};
|
|
1592
1688
|
}
|
|
1593
1689
|
function declarePlugin(config) {
|
|
@@ -1875,6 +1971,97 @@ var getRegistryPlugin = defineMethod({
|
|
|
1875
1971
|
run: ({ imports, input }) => buildSurfaceRegistry(imports.context, input?.package)
|
|
1876
1972
|
});
|
|
1877
1973
|
|
|
1974
|
+
// src/utils/output-policy.ts
|
|
1975
|
+
function isRecord(value) {
|
|
1976
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1977
|
+
}
|
|
1978
|
+
function diffDroppedPaths(raw, parsed, prefix = "") {
|
|
1979
|
+
const paths = [];
|
|
1980
|
+
walkDroppedPaths(raw, parsed, prefix, paths);
|
|
1981
|
+
return paths;
|
|
1982
|
+
}
|
|
1983
|
+
function walkDroppedPaths(raw, parsed, prefix, out) {
|
|
1984
|
+
if (Array.isArray(raw) && Array.isArray(parsed)) {
|
|
1985
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1986
|
+
const length = Math.min(raw.length, parsed.length);
|
|
1987
|
+
for (let index = 0; index < length; index++) {
|
|
1988
|
+
const elementPaths = [];
|
|
1989
|
+
walkDroppedPaths(raw[index], parsed[index], `${prefix}[]`, elementPaths);
|
|
1990
|
+
for (const path of elementPaths) {
|
|
1991
|
+
if (seen.has(path)) continue;
|
|
1992
|
+
seen.add(path);
|
|
1993
|
+
out.push(path);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
return;
|
|
1997
|
+
}
|
|
1998
|
+
if (isRecord(raw) && isRecord(parsed)) {
|
|
1999
|
+
for (const key of Object.keys(raw)) {
|
|
2000
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
2001
|
+
if (!(key in parsed)) {
|
|
2002
|
+
out.push(path);
|
|
2003
|
+
continue;
|
|
2004
|
+
}
|
|
2005
|
+
walkDroppedPaths(raw[key], parsed[key], path, out);
|
|
2006
|
+
}
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
function parseOutput(schema, value, policy, locator) {
|
|
2011
|
+
const result = schema.safeParse(value);
|
|
2012
|
+
if (result.success) return result.data;
|
|
2013
|
+
const issues = result.error.issues.map((issue) => {
|
|
2014
|
+
const path = issue.path.length > 0 ? issue.path.join(".") : "data";
|
|
2015
|
+
return `${path}: ${issue.message}`;
|
|
2016
|
+
});
|
|
2017
|
+
const subject = policy.methodName ? ` for "${policy.methodName}"` : "";
|
|
2018
|
+
const at = locator ? ` at ${locator}` : "";
|
|
2019
|
+
throw createCoreError(
|
|
2020
|
+
{
|
|
2021
|
+
code: CoreErrorCode.Validation,
|
|
2022
|
+
message: `Output validation failed${subject}${at}:
|
|
2023
|
+
${issues.join("\n ")}
|
|
2024
|
+
|
|
2025
|
+
The response does not match the method's \`outputSchema\`. Correct the schema, or set \`skipOutputValidation: true\` on the method to pass the response through unvalidated.`,
|
|
2026
|
+
details: { zodErrors: result.error.issues, output: value }
|
|
2027
|
+
},
|
|
2028
|
+
policy.adaptError
|
|
2029
|
+
);
|
|
2030
|
+
}
|
|
2031
|
+
function applyItemOutputPolicy(result, policy) {
|
|
2032
|
+
const schema = policy.outputSchema;
|
|
2033
|
+
if (!schema || policy.skipOutputValidation) return result;
|
|
2034
|
+
if (!isRecord(result) || !("data" in result)) return result;
|
|
2035
|
+
const data = parseOutput(schema, result.data, policy);
|
|
2036
|
+
const next = { ...result, data };
|
|
2037
|
+
if (policy.includeOutputValidationDroppedPaths) {
|
|
2038
|
+
const droppedPaths = diffDroppedPaths(result.data, data);
|
|
2039
|
+
if (droppedPaths.length > 0) {
|
|
2040
|
+
next.meta = withOutputValidation(result.meta, droppedPaths);
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
return next;
|
|
2044
|
+
}
|
|
2045
|
+
function withOutputValidation(existing, droppedPaths) {
|
|
2046
|
+
const base = isRecord(existing) ? existing : {};
|
|
2047
|
+
return { ...base, outputValidation: { droppedPaths } };
|
|
2048
|
+
}
|
|
2049
|
+
function applyListOutputPolicy(page, policy) {
|
|
2050
|
+
const schema = policy.outputSchema;
|
|
2051
|
+
if (!schema || policy.skipOutputValidation) return page;
|
|
2052
|
+
const data = page.data.map(
|
|
2053
|
+
(item, index) => parseOutput(schema, item, policy, `data[${index}]`)
|
|
2054
|
+
);
|
|
2055
|
+
const next = { ...page, data };
|
|
2056
|
+
if (policy.includeOutputValidationDroppedPaths) {
|
|
2057
|
+
const droppedPaths = diffDroppedPaths(page.data, data);
|
|
2058
|
+
if (droppedPaths.length > 0) {
|
|
2059
|
+
next.meta = { ...page.meta, outputValidation: { droppedPaths } };
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
return next;
|
|
2063
|
+
}
|
|
2064
|
+
|
|
1878
2065
|
// src/model/materialize.ts
|
|
1879
2066
|
var FRAMEWORK_CONFIGURATION_IDS = /* @__PURE__ */ new Set([
|
|
1880
2067
|
CORE_OPTIONS_ID
|
|
@@ -1938,6 +2125,9 @@ function edgesOf(plugin) {
|
|
|
1938
2125
|
function isStandIn(plugin) {
|
|
1939
2126
|
return (plugin.pluginType === "method" || plugin.pluginType === "property" || plugin.pluginType === "aggregate") && plugin.standIn === true;
|
|
1940
2127
|
}
|
|
2128
|
+
function isDefault(plugin) {
|
|
2129
|
+
return (plugin.pluginType === "method" || plugin.pluginType === "property") && plugin.defaultSource !== void 0;
|
|
2130
|
+
}
|
|
1941
2131
|
function topoOrder(descriptors) {
|
|
1942
2132
|
const order = [];
|
|
1943
2133
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -1952,28 +2142,89 @@ function topoOrder(descriptors) {
|
|
|
1952
2142
|
return order;
|
|
1953
2143
|
}
|
|
1954
2144
|
function collectPlugins(root, materialized = /* @__PURE__ */ new Set(), configuration) {
|
|
2145
|
+
const rank = (plugin) => isStandIn(plugin) ? 0 : isDefault(plugin) ? 1 : 2;
|
|
2146
|
+
const allNodes = [];
|
|
2147
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2148
|
+
const collect = (plugin) => {
|
|
2149
|
+
if (materialized.has(plugin.id) || seen.has(plugin)) return;
|
|
2150
|
+
seen.add(plugin);
|
|
2151
|
+
allNodes.push(plugin);
|
|
2152
|
+
for (const edge of edgesOf(plugin)) collect(edge);
|
|
2153
|
+
};
|
|
2154
|
+
collect(root);
|
|
2155
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
2156
|
+
const candidatesById = /* @__PURE__ */ new Map();
|
|
2157
|
+
for (const node of allNodes) {
|
|
2158
|
+
childrenOf.set(
|
|
2159
|
+
node,
|
|
2160
|
+
edgesOf(node).filter((edge) => seen.has(edge))
|
|
2161
|
+
);
|
|
2162
|
+
const candidates = candidatesById.get(node.id);
|
|
2163
|
+
if (candidates) candidates.push(node);
|
|
2164
|
+
else candidatesById.set(node.id, [node]);
|
|
2165
|
+
}
|
|
2166
|
+
const live = new Set(allNodes);
|
|
2167
|
+
for (; ; ) {
|
|
2168
|
+
const reachable = /* @__PURE__ */ new Set();
|
|
2169
|
+
if (live.has(root)) reachable.add(root);
|
|
2170
|
+
const queue = reachable.has(root) ? [root] : [];
|
|
2171
|
+
while (queue.length) {
|
|
2172
|
+
const node = queue.pop();
|
|
2173
|
+
for (const child of childrenOf.get(node) ?? []) {
|
|
2174
|
+
if (reachable.has(child)) continue;
|
|
2175
|
+
reachable.add(child);
|
|
2176
|
+
if (live.has(child)) queue.push(child);
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
let changed = false;
|
|
2180
|
+
for (const node of live) {
|
|
2181
|
+
if (!reachable.has(node)) {
|
|
2182
|
+
live.delete(node);
|
|
2183
|
+
changed = true;
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
for (const candidates of candidatesById.values()) {
|
|
2187
|
+
let maxRank = -1;
|
|
2188
|
+
for (const candidate of candidates) {
|
|
2189
|
+
if (live.has(candidate)) maxRank = Math.max(maxRank, rank(candidate));
|
|
2190
|
+
}
|
|
2191
|
+
if (maxRank < 0) continue;
|
|
2192
|
+
for (const candidate of candidates) {
|
|
2193
|
+
if (live.has(candidate) && rank(candidate) < maxRank) {
|
|
2194
|
+
live.delete(candidate);
|
|
2195
|
+
changed = true;
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
if (!changed) break;
|
|
2200
|
+
}
|
|
1955
2201
|
const byId = /* @__PURE__ */ new Map();
|
|
1956
|
-
const
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2202
|
+
const conflictedDefaults = /* @__PURE__ */ new Set();
|
|
2203
|
+
const isOptional = (plugin) => "optional" in plugin && plugin.optional === true;
|
|
2204
|
+
for (const [id, candidates] of candidatesById) {
|
|
2205
|
+
const liveCandidates = candidates.filter(
|
|
2206
|
+
(candidate) => live.has(candidate)
|
|
2207
|
+
);
|
|
2208
|
+
const winner = liveCandidates.find((candidate) => !isOptional(candidate)) ?? liveCandidates[0];
|
|
2209
|
+
if (!winner) continue;
|
|
2210
|
+
if (liveCandidates.length > 1) {
|
|
2211
|
+
const winnerRank = rank(winner);
|
|
2212
|
+
if (winnerRank === 2) {
|
|
1963
2213
|
throw new Error(
|
|
1964
|
-
`createSdk: duplicate plugin id "${
|
|
2214
|
+
`createSdk: duplicate plugin id "${id}". Two different plugins registered under the same id.`
|
|
1965
2215
|
);
|
|
1966
2216
|
}
|
|
1967
|
-
if (
|
|
1968
|
-
|
|
1969
|
-
|
|
2217
|
+
if (winnerRank === 1) {
|
|
2218
|
+
const sources = new Set(
|
|
2219
|
+
liveCandidates.map(
|
|
2220
|
+
(candidate) => candidate.defaultSource
|
|
2221
|
+
)
|
|
2222
|
+
);
|
|
2223
|
+
if (sources.size > 1) conflictedDefaults.add(id);
|
|
1970
2224
|
}
|
|
1971
|
-
return;
|
|
1972
2225
|
}
|
|
1973
|
-
byId.set(
|
|
1974
|
-
|
|
1975
|
-
};
|
|
1976
|
-
visit(root);
|
|
2226
|
+
byId.set(id, winner);
|
|
2227
|
+
}
|
|
1977
2228
|
if (configuration) {
|
|
1978
2229
|
for (const [id, value] of Object.entries(configuration)) {
|
|
1979
2230
|
const existing = byId.get(id);
|
|
@@ -2024,9 +2275,24 @@ function collectPlugins(root, materialized = /* @__PURE__ */ new Set(), configur
|
|
|
2024
2275
|
);
|
|
2025
2276
|
}
|
|
2026
2277
|
}
|
|
2278
|
+
for (const id of conflictedDefaults) {
|
|
2279
|
+
const winner = byId.get(id);
|
|
2280
|
+
if (winner && isDefault(winner)) {
|
|
2281
|
+
throw new Error(
|
|
2282
|
+
`createSdk: conflicting defaults for "${id}". Two different plugins were declared as defaults for the same id and nothing else provides it. Register an explicit (non-default) plugin for this id to choose the winner, or give the implementations distinct ids if they are meant to coexist.`
|
|
2283
|
+
);
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2027
2286
|
return byId;
|
|
2028
2287
|
}
|
|
2029
|
-
function bindValue(
|
|
2288
|
+
function bindValue({
|
|
2289
|
+
target,
|
|
2290
|
+
key,
|
|
2291
|
+
entry,
|
|
2292
|
+
bindMode = "surface",
|
|
2293
|
+
ctx,
|
|
2294
|
+
frameworkOrigin = false
|
|
2295
|
+
}) {
|
|
2030
2296
|
if (entry.pluginType === "property" && entry.getValue) {
|
|
2031
2297
|
Object.defineProperty(target, key, {
|
|
2032
2298
|
get: entry.getValue,
|
|
@@ -2034,7 +2300,7 @@ function bindValue(target, key, entry, callType = "surface", ctx) {
|
|
|
2034
2300
|
configurable: true
|
|
2035
2301
|
});
|
|
2036
2302
|
} else {
|
|
2037
|
-
const value =
|
|
2303
|
+
const value = bindMode === "internal" && entry.pluginType === "method" ? entry.bindInternal?.({ ctx, frameworkOrigin }) ?? entry.internalValue ?? entry.value : entry.value;
|
|
2038
2304
|
Object.defineProperty(target, key, {
|
|
2039
2305
|
value,
|
|
2040
2306
|
writable: true,
|
|
@@ -2052,7 +2318,12 @@ function buildSurface(context, ...maps) {
|
|
|
2052
2318
|
sdk[CONTEXT] = context;
|
|
2053
2319
|
return sdk;
|
|
2054
2320
|
}
|
|
2055
|
-
function buildImports(
|
|
2321
|
+
function buildImports({
|
|
2322
|
+
plugins,
|
|
2323
|
+
importBindings,
|
|
2324
|
+
ctx,
|
|
2325
|
+
frameworkOrigin = false
|
|
2326
|
+
}) {
|
|
2056
2327
|
const imports = {};
|
|
2057
2328
|
for (const { binding, id, optional } of importBindings) {
|
|
2058
2329
|
const entry = plugins[id];
|
|
@@ -2065,10 +2336,31 @@ function buildImports(plugins, importBindings, ctx) {
|
|
|
2065
2336
|
});
|
|
2066
2337
|
continue;
|
|
2067
2338
|
}
|
|
2068
|
-
bindValue(
|
|
2339
|
+
bindValue({
|
|
2340
|
+
target: imports,
|
|
2341
|
+
key: binding,
|
|
2342
|
+
entry,
|
|
2343
|
+
bindMode: "internal",
|
|
2344
|
+
ctx,
|
|
2345
|
+
frameworkOrigin
|
|
2346
|
+
});
|
|
2069
2347
|
}
|
|
2070
2348
|
return imports;
|
|
2071
2349
|
}
|
|
2350
|
+
function bindInternalTwin({
|
|
2351
|
+
ctx,
|
|
2352
|
+
frameworkOrigin,
|
|
2353
|
+
withContext,
|
|
2354
|
+
internalValue
|
|
2355
|
+
}) {
|
|
2356
|
+
if (ctx) {
|
|
2357
|
+
return (...args) => withContext(childCallContext(ctx))(...args);
|
|
2358
|
+
}
|
|
2359
|
+
if (frameworkOrigin) {
|
|
2360
|
+
return (...args) => withContext(rootCallContext({ callOrigin: "internal" }))(...args);
|
|
2361
|
+
}
|
|
2362
|
+
return internalValue;
|
|
2363
|
+
}
|
|
2072
2364
|
function mirrorLegacyRootKeys(context, rootKeys, meta) {
|
|
2073
2365
|
const exports = {};
|
|
2074
2366
|
for (const [name, value] of Object.entries(rootKeys)) {
|
|
@@ -2132,7 +2424,11 @@ function bindResolver(resolver, plugins) {
|
|
|
2132
2424
|
case "info":
|
|
2133
2425
|
return { type: "info", text: resolver.text };
|
|
2134
2426
|
case "object": {
|
|
2135
|
-
const imports = buildImports(
|
|
2427
|
+
const imports = buildImports({
|
|
2428
|
+
plugins,
|
|
2429
|
+
importBindings: resolver.importBindings,
|
|
2430
|
+
frameworkOrigin: true
|
|
2431
|
+
});
|
|
2136
2432
|
const bound = {
|
|
2137
2433
|
type: "object",
|
|
2138
2434
|
requireParameters: resolver.requireParameters
|
|
@@ -2173,7 +2469,11 @@ function bindResolver(resolver, plugins) {
|
|
|
2173
2469
|
return bound;
|
|
2174
2470
|
}
|
|
2175
2471
|
case "dynamic": {
|
|
2176
|
-
const imports = buildImports(
|
|
2472
|
+
const imports = buildImports({
|
|
2473
|
+
plugins,
|
|
2474
|
+
importBindings: resolver.importBindings,
|
|
2475
|
+
frameworkOrigin: true
|
|
2476
|
+
});
|
|
2177
2477
|
const {
|
|
2178
2478
|
getContext: getContext2,
|
|
2179
2479
|
listItems,
|
|
@@ -2228,7 +2528,11 @@ function bindDefinitions(definitions, plugins) {
|
|
|
2228
2528
|
return out;
|
|
2229
2529
|
}
|
|
2230
2530
|
function bindFormatter(formatter, plugins) {
|
|
2231
|
-
const imports = buildImports(
|
|
2531
|
+
const imports = buildImports({
|
|
2532
|
+
plugins,
|
|
2533
|
+
importBindings: formatter.importBindings,
|
|
2534
|
+
frameworkOrigin: true
|
|
2535
|
+
});
|
|
2232
2536
|
const bound = { format: formatter.format };
|
|
2233
2537
|
const { getContext: getContext2 } = formatter;
|
|
2234
2538
|
if (getContext2)
|
|
@@ -2302,6 +2606,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2302
2606
|
const plugins = context.plugins;
|
|
2303
2607
|
for (const [id, descriptor] of descriptors) {
|
|
2304
2608
|
if (descriptor.pluginType !== "method") continue;
|
|
2609
|
+
if (isStandIn(descriptor)) continue;
|
|
2305
2610
|
const out = normalizeOutput(descriptor.output);
|
|
2306
2611
|
const entry = {
|
|
2307
2612
|
pluginType: "method",
|
|
@@ -2316,17 +2621,32 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2316
2621
|
// Replaced below; never called.
|
|
2317
2622
|
value: () => void 0
|
|
2318
2623
|
};
|
|
2319
|
-
const callRun = (input, ctx) =>
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2624
|
+
const callRun = (input, ctx) => {
|
|
2625
|
+
const callContext = ctx ?? rootCallContext();
|
|
2626
|
+
return descriptor.run({
|
|
2627
|
+
imports: buildImports({
|
|
2628
|
+
plugins,
|
|
2629
|
+
importBindings: descriptor.importBindings,
|
|
2630
|
+
ctx: callContext
|
|
2631
|
+
}),
|
|
2632
|
+
state: states.get(id),
|
|
2633
|
+
input,
|
|
2634
|
+
callContext,
|
|
2635
|
+
annotate: (metadata) => {
|
|
2636
|
+
Object.assign(callContext.annotations, metadata);
|
|
2637
|
+
}
|
|
2638
|
+
});
|
|
2639
|
+
};
|
|
2324
2640
|
const fold = (coreFn) => (input, ctx) => {
|
|
2325
2641
|
let next = (i) => coreFn(i, ctx);
|
|
2326
2642
|
for (const wrap of entry.chain) {
|
|
2327
2643
|
const inner = next;
|
|
2328
2644
|
next = (i) => wrap.run({
|
|
2329
|
-
imports: buildImports(
|
|
2645
|
+
imports: buildImports({
|
|
2646
|
+
plugins,
|
|
2647
|
+
importBindings: wrap.owner.importBindings,
|
|
2648
|
+
ctx
|
|
2649
|
+
}),
|
|
2330
2650
|
next: inner,
|
|
2331
2651
|
input: i,
|
|
2332
2652
|
// Overwritten by the chain item's own closure with the owning
|
|
@@ -2337,6 +2657,18 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2337
2657
|
return next(input);
|
|
2338
2658
|
};
|
|
2339
2659
|
const sdk = { context };
|
|
2660
|
+
const methodAnnotator = descriptor.annotator;
|
|
2661
|
+
const boundAnnotator = methodAnnotator ? (input) => methodAnnotator({ input }) : void 0;
|
|
2662
|
+
const outputPolicy = () => {
|
|
2663
|
+
const core = resolveCoreOptions(context);
|
|
2664
|
+
return {
|
|
2665
|
+
outputSchema: descriptor.meta?.outputSchema,
|
|
2666
|
+
skipOutputValidation: descriptor.skipOutputValidation,
|
|
2667
|
+
includeOutputValidationDroppedPaths: core?.includeOutputValidationDroppedPaths,
|
|
2668
|
+
methodName: descriptor.name,
|
|
2669
|
+
adaptError: core?.adaptError
|
|
2670
|
+
};
|
|
2671
|
+
};
|
|
2340
2672
|
if (out.type === "list") {
|
|
2341
2673
|
entry.value = createPaginatedFunction(
|
|
2342
2674
|
fold(callRun),
|
|
@@ -2346,17 +2678,23 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2346
2678
|
name: descriptor.name,
|
|
2347
2679
|
defaultPageSize: out.defaultPageSize,
|
|
2348
2680
|
adaptPage: out.adaptPage,
|
|
2681
|
+
annotator: boundAnnotator,
|
|
2682
|
+
// Validate + strip each item against the item `outputSchema`
|
|
2683
|
+
// (item mode's sibling); dropped paths surface as `[].x` in the page's
|
|
2684
|
+
// `meta`, unioned across items.
|
|
2685
|
+
finalizePage: (page) => applyListOutputPolicy(page, outputPolicy()),
|
|
2349
2686
|
getDeprecation: () => entry.meta?.deprecation
|
|
2350
2687
|
}
|
|
2351
2688
|
);
|
|
2352
2689
|
} else if (out.type === "item") {
|
|
2353
|
-
const itemCore = async (input, ctx) => callRun(input, ctx);
|
|
2690
|
+
const itemCore = async (input, ctx) => applyItemOutputPolicy(await callRun(input, ctx), outputPolicy());
|
|
2354
2691
|
entry.value = createFunction(
|
|
2355
2692
|
fold(itemCore),
|
|
2356
2693
|
{
|
|
2357
2694
|
sdk,
|
|
2358
2695
|
schema: descriptor.inputSchema,
|
|
2359
2696
|
name: descriptor.name,
|
|
2697
|
+
annotator: boundAnnotator,
|
|
2360
2698
|
getDeprecation: () => entry.meta?.deprecation
|
|
2361
2699
|
}
|
|
2362
2700
|
);
|
|
@@ -2368,6 +2706,7 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2368
2706
|
name: descriptor.name,
|
|
2369
2707
|
schema: descriptor.skipInputValidation ? void 0 : descriptor.inputSchema,
|
|
2370
2708
|
positional: descriptor.positional,
|
|
2709
|
+
annotator: boundAnnotator,
|
|
2371
2710
|
// The boundary reads the deprecation LIVE off the entry, so a
|
|
2372
2711
|
// deprecation merged after build (defineMethodOverride, addPlugin)
|
|
2373
2712
|
// fires too.
|
|
@@ -2388,12 +2727,22 @@ function buildMethodEntries(descriptors, context, states) {
|
|
|
2388
2727
|
const internalValue = (...args) => canonicalValue(pack(args), INTERNAL_CALL);
|
|
2389
2728
|
entry.value = (...args) => canonicalValue(pack(args));
|
|
2390
2729
|
entry.internalValue = internalValue;
|
|
2391
|
-
entry.bindInternal = (
|
|
2730
|
+
entry.bindInternal = (opts) => bindInternalTwin({
|
|
2731
|
+
...opts,
|
|
2732
|
+
withContext: (context2) => {
|
|
2733
|
+
return (...args) => canonicalValue(pack(args), context2);
|
|
2734
|
+
},
|
|
2735
|
+
internalValue
|
|
2736
|
+
});
|
|
2392
2737
|
entry.positional = names;
|
|
2393
2738
|
} else {
|
|
2394
2739
|
const internalValue = (input) => canonicalValue(input, INTERNAL_CALL);
|
|
2395
2740
|
entry.internalValue = internalValue;
|
|
2396
|
-
entry.bindInternal = (
|
|
2741
|
+
entry.bindInternal = (opts) => bindInternalTwin({
|
|
2742
|
+
...opts,
|
|
2743
|
+
withContext: (context2) => (input) => canonicalValue(input, context2),
|
|
2744
|
+
internalValue
|
|
2745
|
+
});
|
|
2397
2746
|
}
|
|
2398
2747
|
plugins[id] = entry;
|
|
2399
2748
|
}
|
|
@@ -2419,8 +2768,14 @@ function buildEagerArtifacts(descriptors, context, states) {
|
|
|
2419
2768
|
if (!dispose) return;
|
|
2420
2769
|
context.disposers?.push({
|
|
2421
2770
|
id,
|
|
2771
|
+
// Teardown is framework-internal: an SDK method a `dispose` calls runs
|
|
2772
|
+
// on an internal-origin root (dropped from telemetry).
|
|
2422
2773
|
dispose: (input) => dispose({
|
|
2423
|
-
imports: buildImports(
|
|
2774
|
+
imports: buildImports({
|
|
2775
|
+
plugins,
|
|
2776
|
+
importBindings: descriptor.importBindings,
|
|
2777
|
+
frameworkOrigin: true
|
|
2778
|
+
}),
|
|
2424
2779
|
state: states.get(id),
|
|
2425
2780
|
input
|
|
2426
2781
|
})
|
|
@@ -2430,7 +2785,10 @@ function buildEagerArtifacts(descriptors, context, states) {
|
|
|
2430
2785
|
states.set(
|
|
2431
2786
|
id,
|
|
2432
2787
|
descriptor.setup ? descriptor.setup({
|
|
2433
|
-
imports: buildImports(
|
|
2788
|
+
imports: buildImports({
|
|
2789
|
+
plugins,
|
|
2790
|
+
importBindings: descriptor.importBindings
|
|
2791
|
+
})
|
|
2434
2792
|
}) : void 0
|
|
2435
2793
|
);
|
|
2436
2794
|
recordDisposer();
|
|
@@ -2442,14 +2800,20 @@ function buildEagerArtifacts(descriptors, context, states) {
|
|
|
2442
2800
|
states.set(
|
|
2443
2801
|
id,
|
|
2444
2802
|
descriptor.setup ? descriptor.setup({
|
|
2445
|
-
imports: buildImports(
|
|
2803
|
+
imports: buildImports({
|
|
2804
|
+
plugins,
|
|
2805
|
+
importBindings: descriptor.importBindings
|
|
2806
|
+
})
|
|
2446
2807
|
}) : void 0
|
|
2447
2808
|
);
|
|
2448
2809
|
} else {
|
|
2449
2810
|
states.set(
|
|
2450
2811
|
id,
|
|
2451
2812
|
descriptor.setup ? descriptor.setup({
|
|
2452
|
-
imports: buildImports(
|
|
2813
|
+
imports: buildImports({
|
|
2814
|
+
plugins,
|
|
2815
|
+
importBindings: descriptor.importBindings
|
|
2816
|
+
})
|
|
2453
2817
|
}) : void 0
|
|
2454
2818
|
);
|
|
2455
2819
|
if (descriptor.privileged) {
|
|
@@ -2467,7 +2831,7 @@ function buildEagerArtifacts(descriptors, context, states) {
|
|
|
2467
2831
|
pluginType: "property",
|
|
2468
2832
|
name: descriptor.name,
|
|
2469
2833
|
getValue: () => get({
|
|
2470
|
-
imports: buildImports(plugins, importBindings),
|
|
2834
|
+
imports: buildImports({ plugins, importBindings }),
|
|
2471
2835
|
state: states.get(id)
|
|
2472
2836
|
}),
|
|
2473
2837
|
meta: descriptor.meta,
|
|
@@ -2503,7 +2867,7 @@ function resolvePlugin(sdk, ref) {
|
|
|
2503
2867
|
return entry.getValue();
|
|
2504
2868
|
}
|
|
2505
2869
|
if (entry.pluginType === "method" && entry.internalValue) {
|
|
2506
|
-
return entry.internalValue;
|
|
2870
|
+
return entry.bindInternal?.({ frameworkOrigin: true }) ?? entry.internalValue;
|
|
2507
2871
|
}
|
|
2508
2872
|
return entry.value;
|
|
2509
2873
|
}
|
|
@@ -2538,7 +2902,7 @@ function resolveAggregates(descriptors, context) {
|
|
|
2538
2902
|
if (descriptor.pluginType !== "aggregate") continue;
|
|
2539
2903
|
const exports = {};
|
|
2540
2904
|
for (const [binding, child] of Object.entries(descriptor.exports)) {
|
|
2541
|
-
bindValue(exports, binding, plugins[child.id]);
|
|
2905
|
+
bindValue({ target: exports, key: binding, entry: plugins[child.id] });
|
|
2542
2906
|
}
|
|
2543
2907
|
plugins[id] = { pluginType: "aggregate", name: descriptor.name, exports };
|
|
2544
2908
|
}
|
|
@@ -2581,23 +2945,39 @@ function assembleHooks(descriptors, context, states) {
|
|
|
2581
2945
|
const plugins = context.plugins;
|
|
2582
2946
|
for (const id of topoOrder(descriptors)) {
|
|
2583
2947
|
const descriptor = descriptors.get(id);
|
|
2584
|
-
if (!descriptor || descriptor.pluginType !== "hook" || !descriptor.observe) {
|
|
2948
|
+
if (!descriptor || descriptor.pluginType !== "hook" || !descriptor.observe && !descriptor.annotator) {
|
|
2585
2949
|
continue;
|
|
2586
2950
|
}
|
|
2587
|
-
const { observe } = descriptor;
|
|
2588
|
-
const imports = buildImports(plugins, descriptor.importBindings);
|
|
2951
|
+
const { observe, annotator } = descriptor;
|
|
2589
2952
|
const state = states.get(id);
|
|
2590
2953
|
const contributed = {};
|
|
2591
|
-
if (observe
|
|
2592
|
-
const
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2954
|
+
if (observe?.onMethodStart || observe?.onMethodEnd) {
|
|
2955
|
+
const imports = buildImports({
|
|
2956
|
+
plugins,
|
|
2957
|
+
importBindings: descriptor.importBindings,
|
|
2958
|
+
frameworkOrigin: true
|
|
2959
|
+
});
|
|
2960
|
+
if (observe.onMethodStart) {
|
|
2961
|
+
const onStart = observe.onMethodStart;
|
|
2962
|
+
contributed.onMethodStart = (input) => {
|
|
2963
|
+
runIsolatedObserver(() => onStart({ imports, input, state }));
|
|
2964
|
+
};
|
|
2965
|
+
}
|
|
2966
|
+
if (observe.onMethodEnd) {
|
|
2967
|
+
const onEnd = observe.onMethodEnd;
|
|
2968
|
+
contributed.onMethodEnd = (input) => {
|
|
2969
|
+
runIsolatedObserver(() => onEnd({ imports, input, state }));
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2596
2972
|
}
|
|
2597
|
-
if (
|
|
2598
|
-
const
|
|
2599
|
-
contributed.
|
|
2600
|
-
|
|
2973
|
+
if (annotator) {
|
|
2974
|
+
const annotatorFn = annotator;
|
|
2975
|
+
contributed.annotator = ({ methodName, input }) => {
|
|
2976
|
+
try {
|
|
2977
|
+
return annotatorFn({ methodName, input, state });
|
|
2978
|
+
} catch {
|
|
2979
|
+
return {};
|
|
2980
|
+
}
|
|
2601
2981
|
};
|
|
2602
2982
|
}
|
|
2603
2983
|
context.hooks = buildHooks(context.hooks, contributed);
|
|
@@ -2631,7 +3011,11 @@ function createSdk(root, options) {
|
|
|
2631
3011
|
pluginSurface = plugins2[plugin.id].exports;
|
|
2632
3012
|
} else {
|
|
2633
3013
|
pluginSurface = {};
|
|
2634
|
-
bindValue(
|
|
3014
|
+
bindValue({
|
|
3015
|
+
target: pluginSurface,
|
|
3016
|
+
key: plugin.name,
|
|
3017
|
+
entry: plugins2[plugin.id]
|
|
3018
|
+
});
|
|
2635
3019
|
}
|
|
2636
3020
|
for (const key of Object.keys(legacyExports)) context.surface[key] = key;
|
|
2637
3021
|
if (plugin.pluginType === "aggregate") {
|
|
@@ -2648,7 +3032,7 @@ function createSdk(root, options) {
|
|
|
2648
3032
|
if (root.pluginType === "method" || root.pluginType === "property") {
|
|
2649
3033
|
context.surface[root.name] = root.id;
|
|
2650
3034
|
const sdk = buildSurface(context);
|
|
2651
|
-
bindValue(sdk, root.name, plugins[root.id]);
|
|
3035
|
+
bindValue({ target: sdk, key: root.name, entry: plugins[root.id] });
|
|
2652
3036
|
return sdk;
|
|
2653
3037
|
}
|
|
2654
3038
|
if (root.pluginType === "aggregate")
|
|
@@ -2680,7 +3064,7 @@ function addModelPlugin(sdk, plugin, options = {}) {
|
|
|
2680
3064
|
context.surface[binding] = child.id;
|
|
2681
3065
|
}
|
|
2682
3066
|
} else {
|
|
2683
|
-
bindValue(sdk, plugin.name, entry);
|
|
3067
|
+
bindValue({ target: sdk, key: plugin.name, entry });
|
|
2684
3068
|
context.surface[plugin.name] = plugin.id;
|
|
2685
3069
|
}
|
|
2686
3070
|
}
|
|
@@ -4019,7 +4403,9 @@ export {
|
|
|
4019
4403
|
createSdk,
|
|
4020
4404
|
createValidator,
|
|
4021
4405
|
dangerousContextPlugin,
|
|
4406
|
+
declareDefault,
|
|
4022
4407
|
declareMethod,
|
|
4408
|
+
declareOptionalMethod,
|
|
4023
4409
|
declareOptionalProperty,
|
|
4024
4410
|
declarePlugin,
|
|
4025
4411
|
declareProperty,
|