@zapier/zapier-sdk 0.18.3 → 1.0.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 +17 -0
- package/README.md +1 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +11 -24
- package/dist/api/client.test.js +82 -27
- package/dist/api/index.d.ts +3 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -3
- package/dist/api/schemas.d.ts +5 -114
- package/dist/api/schemas.d.ts.map +1 -1
- package/dist/api/schemas.js +0 -67
- package/dist/api/types.d.ts +10 -4
- package/dist/api/types.d.ts.map +1 -1
- package/dist/auth.d.ts +54 -26
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +211 -39
- package/dist/auth.test.js +338 -64
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +14 -0
- package/dist/credentials.d.ts +57 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +174 -0
- package/dist/index.cjs +644 -685
- package/dist/index.d.mts +265 -134
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.mjs +624 -684
- package/dist/plugins/api/index.d.ts +2 -0
- package/dist/plugins/api/index.d.ts.map +1 -1
- package/dist/plugins/api/index.js +8 -4
- package/dist/plugins/eventEmission/index.d.ts.map +1 -1
- package/dist/plugins/eventEmission/index.js +1 -3
- package/dist/plugins/eventEmission/index.test.js +14 -17
- package/dist/plugins/getAction/schemas.d.ts +1 -1
- package/dist/plugins/getInputFieldsSchema/schemas.d.ts +1 -1
- package/dist/plugins/listActions/index.test.js +1 -0
- package/dist/plugins/listActions/schemas.d.ts +1 -1
- package/dist/plugins/listApps/index.d.ts +2 -8
- package/dist/plugins/listApps/index.d.ts.map +1 -1
- package/dist/plugins/listApps/index.js +4 -6
- package/dist/plugins/listApps/index.test.js +62 -82
- package/dist/plugins/listApps/schemas.d.ts +35 -14
- package/dist/plugins/listApps/schemas.d.ts.map +1 -1
- package/dist/plugins/listApps/schemas.js +44 -14
- package/dist/plugins/listAuthentications/index.test.js +16 -0
- package/dist/plugins/listInputFieldChoices/schemas.d.ts +1 -1
- package/dist/plugins/listInputFields/schemas.d.ts +1 -1
- package/dist/plugins/runAction/schemas.d.ts +1 -1
- package/dist/schemas/Action.d.ts +1 -1
- package/dist/schemas/App.d.ts +28 -28
- package/dist/schemas/App.d.ts.map +1 -1
- package/dist/schemas/App.js +3 -8
- package/dist/sdk.d.ts +2 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.test.js +17 -13
- package/dist/types/credentials.d.ts +65 -0
- package/dist/types/credentials.d.ts.map +1 -0
- package/dist/types/credentials.js +42 -0
- package/dist/types/properties.d.ts +1 -1
- package/dist/types/sdk.d.ts +12 -3
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/utils/logging.d.ts +13 -0
- package/dist/utils/logging.d.ts.map +1 -0
- package/dist/utils/logging.js +20 -0
- package/package.json +2 -2
- package/dist/api/client.integration.test.d.ts +0 -5
- package/dist/api/client.integration.test.d.ts.map +0 -1
- package/dist/api/client.integration.test.js +0 -318
- package/dist/api/client.methods.test.d.ts +0 -2
- package/dist/api/client.methods.test.d.ts.map +0 -1
- package/dist/api/client.methods.test.js +0 -158
- package/dist/api/router.d.ts +0 -16
- package/dist/api/router.d.ts.map +0 -1
- package/dist/api/router.js +0 -31
- package/dist/api/router.test.d.ts +0 -2
- package/dist/api/router.test.d.ts.map +0 -1
- package/dist/api/router.test.js +0 -103
- package/dist/temporary-internal-core/handlers/listApps.d.ts +0 -67
- package/dist/temporary-internal-core/handlers/listApps.d.ts.map +0 -1
- package/dist/temporary-internal-core/handlers/listApps.js +0 -134
- package/dist/temporary-internal-core/handlers/listApps.test.d.ts +0 -2
- package/dist/temporary-internal-core/handlers/listApps.test.d.ts.map +0 -1
- package/dist/temporary-internal-core/handlers/listApps.test.js +0 -367
- package/dist/temporary-internal-core/index.d.ts +0 -18
- package/dist/temporary-internal-core/index.d.ts.map +0 -1
- package/dist/temporary-internal-core/index.js +0 -18
- package/dist/temporary-internal-core/schemas/apps/index.d.ts +0 -175
- package/dist/temporary-internal-core/schemas/apps/index.d.ts.map +0 -1
- package/dist/temporary-internal-core/schemas/apps/index.js +0 -97
- package/dist/temporary-internal-core/schemas/errors/index.d.ts +0 -139
- package/dist/temporary-internal-core/schemas/errors/index.d.ts.map +0 -1
- package/dist/temporary-internal-core/schemas/errors/index.js +0 -129
- package/dist/temporary-internal-core/schemas/implementations/index.d.ts +0 -127
- package/dist/temporary-internal-core/schemas/implementations/index.d.ts.map +0 -1
- package/dist/temporary-internal-core/schemas/implementations/index.js +0 -79
- package/dist/temporary-internal-core/types/handler.d.ts +0 -51
- package/dist/temporary-internal-core/types/handler.d.ts.map +0 -1
- package/dist/temporary-internal-core/types/handler.js +0 -8
- package/dist/temporary-internal-core/types/index.d.ts +0 -5
- package/dist/temporary-internal-core/types/index.d.ts.map +0 -1
- package/dist/temporary-internal-core/types/index.js +0 -4
- package/dist/temporary-internal-core/utils/app-locators.d.ts +0 -34
- package/dist/temporary-internal-core/utils/app-locators.d.ts.map +0 -1
- package/dist/temporary-internal-core/utils/app-locators.js +0 -39
- package/dist/temporary-internal-core/utils/string-utils.d.ts +0 -28
- package/dist/temporary-internal-core/utils/string-utils.d.ts.map +0 -1
- package/dist/temporary-internal-core/utils/string-utils.js +0 -52
- package/dist/temporary-internal-core/utils/transformations.d.ts +0 -18
- package/dist/temporary-internal-core/utils/transformations.d.ts.map +0 -1
- package/dist/temporary-internal-core/utils/transformations.js +0 -36
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var zod = require('zod');
|
|
4
|
+
var apps = require('@zapier/zapier-sdk-core/v0/schemas/apps');
|
|
4
5
|
var authentications = require('@zapier/zapier-sdk-core/v0/schemas/authentications');
|
|
5
6
|
var promises = require('timers/promises');
|
|
6
7
|
var os = require('os');
|
|
@@ -57,6 +58,14 @@ function isPositional(schema) {
|
|
|
57
58
|
// src/constants.ts
|
|
58
59
|
var ZAPIER_BASE_URL = process.env.ZAPIER_BASE_URL || "https://zapier.com";
|
|
59
60
|
var MAX_PAGE_LIMIT = 1e4;
|
|
61
|
+
var ZAPIER_CREDENTIALS = process.env.ZAPIER_CREDENTIALS;
|
|
62
|
+
var ZAPIER_CREDENTIALS_CLIENT_ID = process.env.ZAPIER_CREDENTIALS_CLIENT_ID;
|
|
63
|
+
var ZAPIER_CREDENTIALS_CLIENT_SECRET = process.env.ZAPIER_CREDENTIALS_CLIENT_SECRET;
|
|
64
|
+
var ZAPIER_CREDENTIALS_BASE_URL = process.env.ZAPIER_CREDENTIALS_BASE_URL;
|
|
65
|
+
var ZAPIER_CREDENTIALS_SCOPE = process.env.ZAPIER_CREDENTIALS_SCOPE;
|
|
66
|
+
var ZAPIER_TOKEN = process.env.ZAPIER_TOKEN;
|
|
67
|
+
var ZAPIER_AUTH_BASE_URL = process.env.ZAPIER_AUTH_BASE_URL;
|
|
68
|
+
var ZAPIER_AUTH_CLIENT_ID = process.env.ZAPIER_AUTH_CLIENT_ID;
|
|
60
69
|
|
|
61
70
|
// src/types/properties.ts
|
|
62
71
|
var AppKeyPropertySchema = withPositional(
|
|
@@ -817,105 +826,230 @@ function createPaginatedFunction(coreFn, schema, telemetry, explicitFunctionName
|
|
|
817
826
|
};
|
|
818
827
|
return namedFunctions[functionName];
|
|
819
828
|
}
|
|
820
|
-
var
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
age_in_days: zod.z.number().optional(),
|
|
825
|
-
auth_type: zod.z.string().optional(),
|
|
826
|
-
banner: zod.z.string().optional(),
|
|
827
|
-
categories: zod.z.array(
|
|
828
|
-
zod.z.object({
|
|
829
|
-
id: zod.z.number(),
|
|
830
|
-
name: zod.z.string(),
|
|
831
|
-
slug: zod.z.string()
|
|
832
|
-
})
|
|
833
|
-
).optional(),
|
|
834
|
-
images: zod.z.object({
|
|
835
|
-
url_16x16: zod.z.string().optional(),
|
|
836
|
-
url_32x32: zod.z.string().optional(),
|
|
837
|
-
url_64x64: zod.z.string().optional(),
|
|
838
|
-
url_128x128: zod.z.string().optional()
|
|
839
|
-
}).optional(),
|
|
840
|
-
popularity: zod.z.number().optional(),
|
|
841
|
-
has_filters: zod.z.boolean().optional(),
|
|
842
|
-
has_reads: zod.z.boolean().optional(),
|
|
843
|
-
has_searches: zod.z.boolean().optional(),
|
|
844
|
-
has_searches_or_writes: zod.z.boolean().optional(),
|
|
845
|
-
has_upfront_fields: zod.z.boolean().optional(),
|
|
846
|
-
has_writes: zod.z.boolean().optional(),
|
|
847
|
-
is_beta: zod.z.boolean().optional(),
|
|
848
|
-
is_built_in: zod.z.boolean().optional(),
|
|
849
|
-
is_deprecated: zod.z.boolean().optional(),
|
|
850
|
-
is_featured: zod.z.boolean().optional(),
|
|
851
|
-
is_hidden: zod.z.boolean().optional(),
|
|
852
|
-
is_invite: zod.z.boolean().optional(),
|
|
853
|
-
is_premium: zod.z.boolean().optional(),
|
|
854
|
-
is_public: zod.z.boolean().optional(),
|
|
855
|
-
is_upcoming: zod.z.boolean().optional(),
|
|
856
|
-
version: zod.z.string().optional(),
|
|
857
|
-
visibility: zod.z.string().optional(),
|
|
858
|
-
actions: zod.z.object({
|
|
859
|
-
read: zod.z.number().optional(),
|
|
860
|
-
read_bulk: zod.z.number().optional(),
|
|
861
|
-
write: zod.z.number().optional(),
|
|
862
|
-
search: zod.z.number().optional(),
|
|
863
|
-
search_or_write: zod.z.number().optional(),
|
|
864
|
-
search_and_write: zod.z.number().optional(),
|
|
865
|
-
filter: zod.z.number().optional()
|
|
866
|
-
}).optional(),
|
|
867
|
-
description: zod.z.string().optional(),
|
|
868
|
-
primary_color: zod.z.string().optional(),
|
|
869
|
-
secondary_color: zod.z.string().optional(),
|
|
870
|
-
classification: zod.z.string().optional(),
|
|
871
|
-
api_docs_url: zod.z.string().optional(),
|
|
872
|
-
image: zod.z.string().optional()
|
|
873
|
-
});
|
|
874
|
-
zod.z.object({
|
|
875
|
-
count: zod.z.number(),
|
|
876
|
-
next: zod.z.string().nullable().optional(),
|
|
877
|
-
previous: zod.z.string().nullable().optional(),
|
|
878
|
-
results: zod.z.array(ImplementationMetaSchema)
|
|
879
|
-
});
|
|
880
|
-
|
|
881
|
-
// src/temporary-internal-core/schemas/apps/index.ts
|
|
882
|
-
var ListAppsOptionsSchema = zod.z.object({
|
|
829
|
+
var ListAppsSchema = apps.ListAppsQuerySchema.omit({
|
|
830
|
+
offset: true
|
|
831
|
+
}).extend({
|
|
832
|
+
// Override appKeys to be an array instead of comma-separated string
|
|
883
833
|
appKeys: zod.z.array(zod.z.string()).optional().describe(
|
|
884
834
|
"Filter apps by app keys (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
885
835
|
),
|
|
886
|
-
|
|
836
|
+
// Override pageSize to make optional (base has default value)
|
|
887
837
|
pageSize: zod.z.number().min(1).optional().describe("Number of apps per page"),
|
|
838
|
+
// SDK specific property for pagination/iterator helpers
|
|
888
839
|
maxItems: zod.z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
840
|
+
// SDK specific property for pagination/iterator helpers
|
|
889
841
|
cursor: zod.z.string().optional().describe("Cursor to start from")
|
|
890
842
|
}).merge(TelemetryMarkerSchema).describe("List all available apps with optional filtering");
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
843
|
+
|
|
844
|
+
// src/utils/string-utils.ts
|
|
845
|
+
function toTitleCase(input) {
|
|
846
|
+
return input.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-]+/g, " ").replace(/\s+/g, " ").trim().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
847
|
+
}
|
|
848
|
+
function toSnakeCase(input) {
|
|
849
|
+
let result = input.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s\-]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
850
|
+
if (/^[0-9]/.test(result)) {
|
|
851
|
+
result = "_" + result;
|
|
852
|
+
}
|
|
853
|
+
return result;
|
|
854
|
+
}
|
|
855
|
+
function stripPageSuffix(functionName) {
|
|
856
|
+
return functionName.replace(/Page$/, "");
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// src/schemas/App.ts
|
|
860
|
+
var AppItemSchema = withFormatter(apps.AppItemSchema, {
|
|
861
|
+
format: (item) => {
|
|
862
|
+
const additionalKeys = [];
|
|
863
|
+
if (item.slug && item.slug !== item.key) {
|
|
864
|
+
additionalKeys.push(item.slug);
|
|
865
|
+
const snakeCaseSlug = toSnakeCase(item.slug);
|
|
866
|
+
if (snakeCaseSlug !== item.slug && snakeCaseSlug !== item.key) {
|
|
867
|
+
additionalKeys.push(snakeCaseSlug);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return {
|
|
871
|
+
title: item.title,
|
|
872
|
+
key: item.key,
|
|
873
|
+
keys: [item.key, ...additionalKeys],
|
|
874
|
+
description: item.description,
|
|
875
|
+
details: []
|
|
876
|
+
};
|
|
877
|
+
}
|
|
903
878
|
});
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
879
|
+
|
|
880
|
+
// src/utils/telemetry-utils.ts
|
|
881
|
+
function createTelemetryCallback(emitMethodCalled, methodName) {
|
|
882
|
+
return {
|
|
883
|
+
onMethodCalled: (data) => {
|
|
884
|
+
emitMethodCalled({
|
|
885
|
+
method_name: methodName,
|
|
886
|
+
execution_duration_ms: data.durationMs,
|
|
887
|
+
success_flag: data.success,
|
|
888
|
+
error_message: data.error?.message ?? null,
|
|
889
|
+
error_type: data.error?.constructor.name ?? null,
|
|
890
|
+
argument_count: data.argumentCount,
|
|
891
|
+
is_paginated: data.isPaginated
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// src/plugins/listApps/index.ts
|
|
898
|
+
var listAppsPlugin = ({ context }) => {
|
|
899
|
+
async function listAppsPage(options) {
|
|
900
|
+
const { api, resolveAppKeys: resolveAppKeys2 } = context;
|
|
901
|
+
const appKeys = options.appKeys ?? [];
|
|
902
|
+
const appLocators = await resolveAppKeys2({
|
|
903
|
+
appKeys: [...appKeys]
|
|
904
|
+
});
|
|
905
|
+
const implementationNameToLocator = {};
|
|
906
|
+
for (const locator of appLocators) {
|
|
907
|
+
implementationNameToLocator[locator.implementationName] = [
|
|
908
|
+
...implementationNameToLocator[locator.implementationName] ?? [],
|
|
909
|
+
locator
|
|
910
|
+
];
|
|
911
|
+
}
|
|
912
|
+
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
|
|
913
|
+
if (duplicatedLookupAppKeys.length > 0) {
|
|
914
|
+
throw new Error(
|
|
915
|
+
`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
if (appKeys.length > 0 && appLocators.length === 0 && !options.search) {
|
|
919
|
+
return {
|
|
920
|
+
data: [],
|
|
921
|
+
links: { next: null },
|
|
922
|
+
meta: { count: 0, limit: 0, offset: 0 }
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
const implementationIds = appLocators.map((locator) => {
|
|
926
|
+
const version = locator.version || "latest";
|
|
927
|
+
return `${locator.implementationName}@${version}`;
|
|
928
|
+
});
|
|
929
|
+
return await api.get("/api/v0/apps", {
|
|
930
|
+
searchParams: {
|
|
931
|
+
appKeys: implementationIds.join(","),
|
|
932
|
+
...options.search && { search: options.search },
|
|
933
|
+
pageSize: options.pageSize.toString(),
|
|
934
|
+
...options.cursor && { offset: options.cursor }
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
const methodName = stripPageSuffix(listAppsPage.name);
|
|
939
|
+
const listAppsDefinition = createPaginatedFunction(
|
|
940
|
+
listAppsPage,
|
|
941
|
+
ListAppsSchema,
|
|
942
|
+
createTelemetryCallback(context.eventEmission.emitMethodCalled, methodName),
|
|
943
|
+
methodName
|
|
944
|
+
);
|
|
945
|
+
return {
|
|
946
|
+
listApps: listAppsDefinition,
|
|
947
|
+
context: {
|
|
948
|
+
meta: {
|
|
949
|
+
listApps: {
|
|
950
|
+
categories: ["app"],
|
|
951
|
+
type: "list",
|
|
952
|
+
itemType: "App",
|
|
953
|
+
inputSchema: ListAppsSchema,
|
|
954
|
+
outputSchema: AppItemSchema
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
// src/utils/domain-utils.ts
|
|
962
|
+
function splitVersionedKey(versionedKey) {
|
|
963
|
+
const parts = versionedKey.split("@");
|
|
964
|
+
if (parts.length >= 2) {
|
|
965
|
+
const baseKey = parts[0];
|
|
966
|
+
const version = parts.slice(1).join("@");
|
|
967
|
+
return [baseKey, version];
|
|
968
|
+
}
|
|
969
|
+
return [versionedKey, void 0];
|
|
970
|
+
}
|
|
971
|
+
function normalizeImplementationMetaToAppItem(implementationMeta) {
|
|
972
|
+
const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
|
|
973
|
+
const { id, name, ...restOfImplementationMeta } = implementationMeta;
|
|
974
|
+
return {
|
|
975
|
+
...restOfImplementationMeta,
|
|
976
|
+
title: name,
|
|
977
|
+
key: selectedApi,
|
|
978
|
+
implementation_id: id,
|
|
979
|
+
version: appVersion
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function normalizeActionItem(action) {
|
|
983
|
+
const { name, type, selected_api: selectedApi } = action;
|
|
984
|
+
const [appKey, appVersion] = selectedApi ? splitVersionedKey(selectedApi) : ["", void 0];
|
|
985
|
+
return {
|
|
986
|
+
// Only include the fields we want - explicitly list them
|
|
987
|
+
id: action.id,
|
|
988
|
+
key: action.key,
|
|
989
|
+
description: action.description,
|
|
990
|
+
is_important: action.is_important,
|
|
991
|
+
is_hidden: action.is_hidden,
|
|
992
|
+
// Transformed fields
|
|
993
|
+
app_key: appKey,
|
|
994
|
+
app_version: appVersion,
|
|
995
|
+
action_type: type,
|
|
996
|
+
title: name,
|
|
997
|
+
// Map name to title
|
|
998
|
+
type: "action"
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function isSlug(slug) {
|
|
1002
|
+
return !!slug.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
|
|
1003
|
+
}
|
|
1004
|
+
function isSnakeCasedSlug(slug) {
|
|
1005
|
+
if (slug.match(/^_[0-9]/)) {
|
|
1006
|
+
slug = slug.slice(1);
|
|
1007
|
+
}
|
|
1008
|
+
return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
|
|
1009
|
+
}
|
|
1010
|
+
function dashifySnakeCasedSlug(slug) {
|
|
1011
|
+
if (!isSnakeCasedSlug(slug)) {
|
|
1012
|
+
return slug;
|
|
1013
|
+
}
|
|
1014
|
+
if (slug.startsWith("_")) {
|
|
1015
|
+
slug = slug.slice(1);
|
|
1016
|
+
}
|
|
1017
|
+
return slug.replace(/_/g, "-");
|
|
1018
|
+
}
|
|
1019
|
+
function isUuid(appKey) {
|
|
1020
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
|
1021
|
+
appKey
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
function toAppLocator(appKey) {
|
|
1025
|
+
const [appKeyWithoutVersion, version] = splitVersionedKey(appKey);
|
|
1026
|
+
if (isUuid(appKeyWithoutVersion)) {
|
|
1027
|
+
throw new Error(
|
|
1028
|
+
`UUID app keys are not supported. Use app slug or implementation ID instead of: ${appKey}`
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
const slug = isSlug(appKeyWithoutVersion) ? appKeyWithoutVersion : isSnakeCasedSlug(appKeyWithoutVersion) ? dashifySnakeCasedSlug(appKeyWithoutVersion) : void 0;
|
|
1032
|
+
return {
|
|
1033
|
+
lookupAppKey: appKeyWithoutVersion,
|
|
1034
|
+
slug,
|
|
1035
|
+
implementationName: slug ? void 0 : appKeyWithoutVersion,
|
|
1036
|
+
version
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
function isResolvedAppLocator(appLocator) {
|
|
1040
|
+
return !!appLocator.implementationName;
|
|
1041
|
+
}
|
|
1042
|
+
var ListActionsSchema = zod.z.object({
|
|
1043
|
+
appKey: AppKeyPropertySchema.describe(
|
|
1044
|
+
"App key of actions to list (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
1045
|
+
),
|
|
1046
|
+
actionType: ActionTypePropertySchema.optional().describe(
|
|
1047
|
+
"Filter actions by type"
|
|
907
1048
|
),
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
cursor: zod.z.string().optional().describe("
|
|
911
|
-
}).
|
|
912
|
-
// Normalize implementationIds to array
|
|
913
|
-
implementationIds: typeof data.implementationIds === "string" ? data.implementationIds === "" ? [] : data.implementationIds.split(",") : data.implementationIds ?? [],
|
|
914
|
-
search: data.search,
|
|
915
|
-
// Normalize pageSize to number
|
|
916
|
-
pageSize: typeof data.pageSize === "string" ? parseInt(data.pageSize, 10) : data.pageSize,
|
|
917
|
-
cursor: data.cursor
|
|
918
|
-
}));
|
|
1049
|
+
pageSize: zod.z.number().min(1).optional().describe("Number of actions per page"),
|
|
1050
|
+
maxItems: zod.z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
1051
|
+
cursor: zod.z.string().optional().describe("Cursor to start from")
|
|
1052
|
+
}).merge(TelemetryMarkerSchema).describe("List all actions for a specific app");
|
|
919
1053
|
var NeedChoicesSchema = zod.z.object({
|
|
920
1054
|
key: zod.z.string().optional(),
|
|
921
1055
|
label: zod.z.string().optional(),
|
|
@@ -1104,394 +1238,116 @@ zod.z.object({
|
|
|
1104
1238
|
internal_id: zod.z.string(),
|
|
1105
1239
|
invite_url: zod.z.string().nullable().optional(),
|
|
1106
1240
|
is_beta: zod.z.string().optional(),
|
|
1107
|
-
is_built_in: zod.z.string().optional(),
|
|
1108
|
-
is_featured: zod.z.string().optional(),
|
|
1109
|
-
is_premium: zod.z.boolean().optional(),
|
|
1110
|
-
is_public: zod.z.string().optional(),
|
|
1111
|
-
is_upcoming: zod.z.string().optional(),
|
|
1112
|
-
learn_more_url: zod.z.string(),
|
|
1113
|
-
name: zod.z.string(),
|
|
1114
|
-
popularity: zod.z.number(),
|
|
1115
|
-
primary_color: zod.z.string(),
|
|
1116
|
-
request_count: zod.z.string().optional(),
|
|
1117
|
-
slug: zod.z.string(),
|
|
1118
|
-
zap_usage_count: zod.z.number().nullable().optional()
|
|
1119
|
-
});
|
|
1120
|
-
var ServiceSchema = zod.z.object({
|
|
1121
|
-
id: zod.z.number().optional(),
|
|
1122
|
-
canonical_id: zod.z.string().optional(),
|
|
1123
|
-
current_implementation_id: zod.z.string(),
|
|
1124
|
-
name: zod.z.string(),
|
|
1125
|
-
slug: zod.z.string(),
|
|
1126
|
-
app_url: zod.z.string().optional(),
|
|
1127
|
-
learn_more_url: zod.z.string().optional(),
|
|
1128
|
-
description: zod.z.string(),
|
|
1129
|
-
primary_color: zod.z.string(),
|
|
1130
|
-
popularity: zod.z.number(),
|
|
1131
|
-
image: zod.z.string().optional(),
|
|
1132
|
-
images: zod.z.string().optional()
|
|
1133
|
-
});
|
|
1134
|
-
zod.z.object({
|
|
1135
|
-
results: zod.z.array(ServiceSchema),
|
|
1136
|
-
next: zod.z.string().nullable().optional(),
|
|
1137
|
-
previous: zod.z.string().nullable().optional()
|
|
1138
|
-
});
|
|
1139
|
-
zod.z.object({
|
|
1140
|
-
selected_api: zod.z.string(),
|
|
1141
|
-
action: zod.z.string(),
|
|
1142
|
-
type_of: zod.z.string(),
|
|
1143
|
-
authentication_id: zod.z.number().optional(),
|
|
1144
|
-
params: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
1145
|
-
});
|
|
1146
|
-
zod.z.object({
|
|
1147
|
-
success: zod.z.boolean(),
|
|
1148
|
-
needs: zod.z.array(NeedSchema).optional(),
|
|
1149
|
-
errors: zod.z.array(zod.z.string()).optional(),
|
|
1150
|
-
last_fetched_at: zod.z.string().optional(),
|
|
1151
|
-
schema: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
1152
|
-
});
|
|
1153
|
-
var ImplementationSchema = zod.z.object({
|
|
1154
|
-
selected_api: zod.z.string(),
|
|
1155
|
-
app_id: zod.z.number().optional(),
|
|
1156
|
-
auth_type: zod.z.string().optional(),
|
|
1157
|
-
auth_fields: zod.z.string().optional(),
|
|
1158
|
-
actions: zod.z.array(ActionSchema).optional(),
|
|
1159
|
-
is_deprecated: zod.z.boolean().optional(),
|
|
1160
|
-
is_private_only: zod.z.boolean().optional(),
|
|
1161
|
-
is_invite_only: zod.z.boolean().optional(),
|
|
1162
|
-
is_beta: zod.z.boolean().optional().default(false),
|
|
1163
|
-
is_premium: zod.z.boolean().optional().default(false),
|
|
1164
|
-
is_hidden: zod.z.string().optional(),
|
|
1165
|
-
name: zod.z.string().optional(),
|
|
1166
|
-
slug: zod.z.string().optional(),
|
|
1167
|
-
images: zod.z.record(zod.z.string(), zod.z.string().nullable()).optional(),
|
|
1168
|
-
primary_color: zod.z.string().optional(),
|
|
1169
|
-
secondary_color: zod.z.string().optional(),
|
|
1170
|
-
current_implementation: zod.z.string().optional(),
|
|
1171
|
-
other_implementations: zod.z.string().optional()
|
|
1172
|
-
});
|
|
1173
|
-
zod.z.object({
|
|
1174
|
-
count: zod.z.number(),
|
|
1175
|
-
next: zod.z.string().nullable().optional(),
|
|
1176
|
-
previous: zod.z.string().nullable().optional(),
|
|
1177
|
-
results: zod.z.array(ImplementationSchema)
|
|
1178
|
-
});
|
|
1179
|
-
var
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
id: zod.z.number(),
|
|
1190
|
-
name: zod.z.string(),
|
|
1191
|
-
slug: zod.z.string()
|
|
1192
|
-
})
|
|
1193
|
-
).optional(),
|
|
1194
|
-
images: zod.z.object({
|
|
1195
|
-
url_16x16: zod.z.string().optional(),
|
|
1196
|
-
url_32x32: zod.z.string().optional(),
|
|
1197
|
-
url_64x64: zod.z.string().optional(),
|
|
1198
|
-
url_128x128: zod.z.string().optional()
|
|
1199
|
-
}).optional(),
|
|
1200
|
-
popularity: zod.z.number().optional(),
|
|
1201
|
-
has_filters: zod.z.boolean().optional(),
|
|
1202
|
-
has_reads: zod.z.boolean().optional(),
|
|
1203
|
-
has_searches: zod.z.boolean().optional(),
|
|
1204
|
-
has_searches_or_writes: zod.z.boolean().optional(),
|
|
1205
|
-
has_upfront_fields: zod.z.boolean().optional(),
|
|
1206
|
-
has_writes: zod.z.boolean().optional(),
|
|
1207
|
-
is_beta: zod.z.boolean().optional(),
|
|
1208
|
-
is_built_in: zod.z.boolean().optional(),
|
|
1209
|
-
is_deprecated: zod.z.boolean().optional(),
|
|
1210
|
-
is_featured: zod.z.boolean().optional(),
|
|
1211
|
-
is_hidden: zod.z.boolean().optional(),
|
|
1212
|
-
is_invite: zod.z.boolean().optional(),
|
|
1213
|
-
is_premium: zod.z.boolean().optional(),
|
|
1214
|
-
is_public: zod.z.boolean().optional(),
|
|
1215
|
-
is_upcoming: zod.z.boolean().optional(),
|
|
1216
|
-
version: zod.z.string().optional(),
|
|
1217
|
-
visibility: zod.z.string().optional(),
|
|
1218
|
-
actions: zod.z.object({
|
|
1219
|
-
read: zod.z.number().optional(),
|
|
1220
|
-
read_bulk: zod.z.number().optional(),
|
|
1221
|
-
write: zod.z.number().optional(),
|
|
1222
|
-
search: zod.z.number().optional(),
|
|
1223
|
-
search_or_write: zod.z.number().optional(),
|
|
1224
|
-
search_and_write: zod.z.number().optional(),
|
|
1225
|
-
filter: zod.z.number().optional()
|
|
1226
|
-
}).optional(),
|
|
1227
|
-
description: zod.z.string().optional(),
|
|
1228
|
-
primary_color: zod.z.string().optional(),
|
|
1229
|
-
secondary_color: zod.z.string().optional(),
|
|
1230
|
-
classification: zod.z.string().optional(),
|
|
1231
|
-
api_docs_url: zod.z.string().optional(),
|
|
1232
|
-
image: zod.z.string().optional()
|
|
1233
|
-
});
|
|
1234
|
-
zod.z.object({
|
|
1235
|
-
count: zod.z.number(),
|
|
1236
|
-
next: zod.z.string().nullable().optional(),
|
|
1237
|
-
previous: zod.z.string().nullable().optional(),
|
|
1238
|
-
results: zod.z.array(ImplementationMetaSchema2)
|
|
1239
|
-
});
|
|
1240
|
-
var NeedChoicesResponseMetaSchema = zod.z.object({
|
|
1241
|
-
page: zod.z.string().nullable().optional()
|
|
1242
|
-
});
|
|
1243
|
-
var NeedChoicesResponseLinksSchema = zod.z.object({
|
|
1244
|
-
next: zod.z.string().nullable().optional(),
|
|
1245
|
-
prev: zod.z.string().nullable().optional()
|
|
1246
|
-
});
|
|
1247
|
-
zod.z.object({
|
|
1248
|
-
selected_api: zod.z.string().optional().describe(
|
|
1249
|
-
"Something like `SlackAPI` (for Python apps) or `SplitwiseCLIAPI@1.0.0` (for CLI apps). Non-public apps are fine as long as the authed user can access them."
|
|
1250
|
-
),
|
|
1251
|
-
authentication_id: zod.z.coerce.number().optional().describe(
|
|
1252
|
-
"If the app needs auth, provide an `authentication_id` that has the `selected_api` of the app you want to run. Can be any auth visible to the user (including shared)."
|
|
1253
|
-
),
|
|
1254
|
-
params: zod.z.record(zod.z.string(), zod.z.unknown()).optional().describe(
|
|
1255
|
-
"Object that matches the input the node would normally get. Has all the same keys/types as the `needs` of the action."
|
|
1256
|
-
),
|
|
1257
|
-
page: zod.z.number().optional().default(0),
|
|
1258
|
-
prefill: zod.z.string().optional().describe(
|
|
1259
|
-
"The prefill string to indicate what we're fetching choices for. Likely something like `spreadsheet.id.title`. Must be provided alongside `selected_api` if both `action_id` and `input_field_id` are not."
|
|
1260
|
-
),
|
|
1261
|
-
action_id: zod.z.string().optional().describe(
|
|
1262
|
-
"The id that will be used to lookup the Action for prefill lookup. If provided, `input_field_id` is required, else `prefill` must be provided."
|
|
1263
|
-
),
|
|
1264
|
-
input_field_id: zod.z.string().optional().describe(
|
|
1265
|
-
"The id (key) of the input field (Need) that dynamic choices are being retrieved for. If provided, `action_id` is required, else `prefill` must be provided."
|
|
1266
|
-
)
|
|
1267
|
-
});
|
|
1268
|
-
zod.z.object({
|
|
1269
|
-
success: zod.z.boolean(),
|
|
1270
|
-
choices: zod.z.array(NeedChoicesSchema).optional(),
|
|
1271
|
-
next_page: zod.z.number().optional(),
|
|
1272
|
-
errors: zod.z.array(zod.z.string()).optional(),
|
|
1273
|
-
meta: NeedChoicesResponseMetaSchema.optional(),
|
|
1274
|
-
links: NeedChoicesResponseLinksSchema.optional()
|
|
1275
|
-
});
|
|
1276
|
-
|
|
1277
|
-
// src/utils/string-utils.ts
|
|
1278
|
-
function toTitleCase(input) {
|
|
1279
|
-
return input.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-]+/g, " ").replace(/\s+/g, " ").trim().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1280
|
-
}
|
|
1281
|
-
function toSnakeCase(input) {
|
|
1282
|
-
let result = input.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s\-]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
1283
|
-
if (/^[0-9]/.test(result)) {
|
|
1284
|
-
result = "_" + result;
|
|
1285
|
-
}
|
|
1286
|
-
return result;
|
|
1287
|
-
}
|
|
1288
|
-
function stripPageSuffix(functionName) {
|
|
1289
|
-
return functionName.replace(/Page$/, "");
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
// src/schemas/App.ts
|
|
1293
|
-
var AppItemSchema2 = withFormatter(
|
|
1294
|
-
ImplementationMetaSchema2.omit({ name: true, id: true }).extend({
|
|
1295
|
-
title: zod.z.string(),
|
|
1296
|
-
// Mapped from name
|
|
1297
|
-
key: zod.z.string(),
|
|
1298
|
-
// Extracted from id (base part without version)
|
|
1299
|
-
implementation_id: zod.z.string()
|
|
1300
|
-
// Mapped from id (full versioned ID)
|
|
1301
|
-
}),
|
|
1302
|
-
{
|
|
1303
|
-
format: (item) => {
|
|
1304
|
-
const additionalKeys = [];
|
|
1305
|
-
if (item.slug && item.slug !== item.key) {
|
|
1306
|
-
additionalKeys.push(item.slug);
|
|
1307
|
-
const snakeCaseSlug = toSnakeCase(item.slug);
|
|
1308
|
-
if (snakeCaseSlug !== item.slug && snakeCaseSlug !== item.key) {
|
|
1309
|
-
additionalKeys.push(snakeCaseSlug);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
return {
|
|
1313
|
-
title: item.title,
|
|
1314
|
-
key: item.key,
|
|
1315
|
-
keys: [item.key, ...additionalKeys],
|
|
1316
|
-
description: item.description,
|
|
1317
|
-
details: []
|
|
1318
|
-
};
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
);
|
|
1322
|
-
|
|
1323
|
-
// src/utils/telemetry-utils.ts
|
|
1324
|
-
function createTelemetryCallback(emitMethodCalled, methodName) {
|
|
1325
|
-
return {
|
|
1326
|
-
onMethodCalled: (data) => {
|
|
1327
|
-
emitMethodCalled({
|
|
1328
|
-
method_name: methodName,
|
|
1329
|
-
execution_duration_ms: data.durationMs,
|
|
1330
|
-
success_flag: data.success,
|
|
1331
|
-
error_message: data.error?.message ?? null,
|
|
1332
|
-
error_type: data.error?.constructor.name ?? null,
|
|
1333
|
-
argument_count: data.argumentCount,
|
|
1334
|
-
is_paginated: data.isPaginated
|
|
1335
|
-
});
|
|
1336
|
-
}
|
|
1337
|
-
};
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
// src/plugins/listApps/index.ts
|
|
1341
|
-
var listAppsPlugin = ({ context }) => {
|
|
1342
|
-
async function listAppsPage(options) {
|
|
1343
|
-
const { api, resolveAppKeys: resolveAppKeys2 } = context;
|
|
1344
|
-
const appKeys = options.appKeys ?? [];
|
|
1345
|
-
const appLocators = await resolveAppKeys2({
|
|
1346
|
-
appKeys: [...appKeys]
|
|
1347
|
-
});
|
|
1348
|
-
const implementationNameToLocator = {};
|
|
1349
|
-
for (const locator of appLocators) {
|
|
1350
|
-
implementationNameToLocator[locator.implementationName] = [
|
|
1351
|
-
...implementationNameToLocator[locator.implementationName] ?? [],
|
|
1352
|
-
locator
|
|
1353
|
-
];
|
|
1354
|
-
}
|
|
1355
|
-
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
|
|
1356
|
-
if (duplicatedLookupAppKeys.length > 0) {
|
|
1357
|
-
throw new Error(
|
|
1358
|
-
`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
|
|
1359
|
-
);
|
|
1360
|
-
}
|
|
1361
|
-
if (appKeys.length > 0 && appLocators.length === 0 && !options.search) {
|
|
1362
|
-
return {
|
|
1363
|
-
data: [],
|
|
1364
|
-
nextCursor: void 0
|
|
1365
|
-
};
|
|
1366
|
-
}
|
|
1367
|
-
const implementationIds = appLocators.map((locator) => {
|
|
1368
|
-
const version = locator.version || "latest";
|
|
1369
|
-
return `${locator.implementationName}@${version}`;
|
|
1370
|
-
});
|
|
1371
|
-
return await api.get("/api/v0/apps", {
|
|
1372
|
-
searchParams: {
|
|
1373
|
-
implementationIds: implementationIds.join(","),
|
|
1374
|
-
...options.search && { search: options.search },
|
|
1375
|
-
pageSize: options.pageSize.toString(),
|
|
1376
|
-
...options.cursor && { cursor: options.cursor }
|
|
1377
|
-
}
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
const methodName = stripPageSuffix(listAppsPage.name);
|
|
1381
|
-
const listAppsDefinition = createPaginatedFunction(
|
|
1382
|
-
listAppsPage,
|
|
1383
|
-
ListAppsOptionsSchema,
|
|
1384
|
-
createTelemetryCallback(context.eventEmission.emitMethodCalled, methodName),
|
|
1385
|
-
methodName
|
|
1386
|
-
);
|
|
1387
|
-
return {
|
|
1388
|
-
listApps: listAppsDefinition,
|
|
1389
|
-
context: {
|
|
1390
|
-
meta: {
|
|
1391
|
-
listApps: {
|
|
1392
|
-
categories: ["app"],
|
|
1393
|
-
type: "list",
|
|
1394
|
-
itemType: "App",
|
|
1395
|
-
inputSchema: ListAppsOptionsSchema,
|
|
1396
|
-
outputSchema: AppItemSchema2
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
};
|
|
1401
|
-
};
|
|
1402
|
-
|
|
1403
|
-
// src/utils/domain-utils.ts
|
|
1404
|
-
function splitVersionedKey(versionedKey) {
|
|
1405
|
-
const parts = versionedKey.split("@");
|
|
1406
|
-
if (parts.length >= 2) {
|
|
1407
|
-
const baseKey = parts[0];
|
|
1408
|
-
const version = parts.slice(1).join("@");
|
|
1409
|
-
return [baseKey, version];
|
|
1410
|
-
}
|
|
1411
|
-
return [versionedKey, void 0];
|
|
1412
|
-
}
|
|
1413
|
-
function normalizeImplementationMetaToAppItem(implementationMeta) {
|
|
1414
|
-
const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
|
|
1415
|
-
const { id, name, ...restOfImplementationMeta } = implementationMeta;
|
|
1416
|
-
return {
|
|
1417
|
-
...restOfImplementationMeta,
|
|
1418
|
-
title: name,
|
|
1419
|
-
key: selectedApi,
|
|
1420
|
-
implementation_id: id,
|
|
1421
|
-
version: appVersion
|
|
1422
|
-
};
|
|
1423
|
-
}
|
|
1424
|
-
function normalizeActionItem(action) {
|
|
1425
|
-
const { name, type, selected_api: selectedApi } = action;
|
|
1426
|
-
const [appKey, appVersion] = selectedApi ? splitVersionedKey(selectedApi) : ["", void 0];
|
|
1427
|
-
return {
|
|
1428
|
-
// Only include the fields we want - explicitly list them
|
|
1429
|
-
id: action.id,
|
|
1430
|
-
key: action.key,
|
|
1431
|
-
description: action.description,
|
|
1432
|
-
is_important: action.is_important,
|
|
1433
|
-
is_hidden: action.is_hidden,
|
|
1434
|
-
// Transformed fields
|
|
1435
|
-
app_key: appKey,
|
|
1436
|
-
app_version: appVersion,
|
|
1437
|
-
action_type: type,
|
|
1438
|
-
title: name,
|
|
1439
|
-
// Map name to title
|
|
1440
|
-
type: "action"
|
|
1441
|
-
};
|
|
1442
|
-
}
|
|
1443
|
-
function isSlug(slug) {
|
|
1444
|
-
return !!slug.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
|
|
1445
|
-
}
|
|
1446
|
-
function isSnakeCasedSlug(slug) {
|
|
1447
|
-
if (slug.match(/^_[0-9]/)) {
|
|
1448
|
-
slug = slug.slice(1);
|
|
1449
|
-
}
|
|
1450
|
-
return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
|
|
1451
|
-
}
|
|
1452
|
-
function dashifySnakeCasedSlug(slug) {
|
|
1453
|
-
if (!isSnakeCasedSlug(slug)) {
|
|
1454
|
-
return slug;
|
|
1455
|
-
}
|
|
1456
|
-
if (slug.startsWith("_")) {
|
|
1457
|
-
slug = slug.slice(1);
|
|
1458
|
-
}
|
|
1459
|
-
return slug.replace(/_/g, "-");
|
|
1460
|
-
}
|
|
1461
|
-
function isUuid(appKey) {
|
|
1462
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
|
1463
|
-
appKey
|
|
1464
|
-
);
|
|
1465
|
-
}
|
|
1466
|
-
function toAppLocator(appKey) {
|
|
1467
|
-
const [appKeyWithoutVersion, version] = splitVersionedKey(appKey);
|
|
1468
|
-
if (isUuid(appKeyWithoutVersion)) {
|
|
1469
|
-
throw new Error(
|
|
1470
|
-
`UUID app keys are not supported. Use app slug or implementation ID instead of: ${appKey}`
|
|
1471
|
-
);
|
|
1472
|
-
}
|
|
1473
|
-
const slug = isSlug(appKeyWithoutVersion) ? appKeyWithoutVersion : isSnakeCasedSlug(appKeyWithoutVersion) ? dashifySnakeCasedSlug(appKeyWithoutVersion) : void 0;
|
|
1474
|
-
return {
|
|
1475
|
-
lookupAppKey: appKeyWithoutVersion,
|
|
1476
|
-
slug,
|
|
1477
|
-
implementationName: slug ? void 0 : appKeyWithoutVersion,
|
|
1478
|
-
version
|
|
1479
|
-
};
|
|
1480
|
-
}
|
|
1481
|
-
function isResolvedAppLocator(appLocator) {
|
|
1482
|
-
return !!appLocator.implementationName;
|
|
1483
|
-
}
|
|
1484
|
-
var ListActionsSchema = zod.z.object({
|
|
1485
|
-
appKey: AppKeyPropertySchema.describe(
|
|
1486
|
-
"App key of actions to list (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
1241
|
+
is_built_in: zod.z.string().optional(),
|
|
1242
|
+
is_featured: zod.z.string().optional(),
|
|
1243
|
+
is_premium: zod.z.boolean().optional(),
|
|
1244
|
+
is_public: zod.z.string().optional(),
|
|
1245
|
+
is_upcoming: zod.z.string().optional(),
|
|
1246
|
+
learn_more_url: zod.z.string(),
|
|
1247
|
+
name: zod.z.string(),
|
|
1248
|
+
popularity: zod.z.number(),
|
|
1249
|
+
primary_color: zod.z.string(),
|
|
1250
|
+
request_count: zod.z.string().optional(),
|
|
1251
|
+
slug: zod.z.string(),
|
|
1252
|
+
zap_usage_count: zod.z.number().nullable().optional()
|
|
1253
|
+
});
|
|
1254
|
+
var ServiceSchema = zod.z.object({
|
|
1255
|
+
id: zod.z.number().optional(),
|
|
1256
|
+
canonical_id: zod.z.string().optional(),
|
|
1257
|
+
current_implementation_id: zod.z.string(),
|
|
1258
|
+
name: zod.z.string(),
|
|
1259
|
+
slug: zod.z.string(),
|
|
1260
|
+
app_url: zod.z.string().optional(),
|
|
1261
|
+
learn_more_url: zod.z.string().optional(),
|
|
1262
|
+
description: zod.z.string(),
|
|
1263
|
+
primary_color: zod.z.string(),
|
|
1264
|
+
popularity: zod.z.number(),
|
|
1265
|
+
image: zod.z.string().optional(),
|
|
1266
|
+
images: zod.z.string().optional()
|
|
1267
|
+
});
|
|
1268
|
+
zod.z.object({
|
|
1269
|
+
results: zod.z.array(ServiceSchema),
|
|
1270
|
+
next: zod.z.string().nullable().optional(),
|
|
1271
|
+
previous: zod.z.string().nullable().optional()
|
|
1272
|
+
});
|
|
1273
|
+
zod.z.object({
|
|
1274
|
+
selected_api: zod.z.string(),
|
|
1275
|
+
action: zod.z.string(),
|
|
1276
|
+
type_of: zod.z.string(),
|
|
1277
|
+
authentication_id: zod.z.number().optional(),
|
|
1278
|
+
params: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
1279
|
+
});
|
|
1280
|
+
zod.z.object({
|
|
1281
|
+
success: zod.z.boolean(),
|
|
1282
|
+
needs: zod.z.array(NeedSchema).optional(),
|
|
1283
|
+
errors: zod.z.array(zod.z.string()).optional(),
|
|
1284
|
+
last_fetched_at: zod.z.string().optional(),
|
|
1285
|
+
schema: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
1286
|
+
});
|
|
1287
|
+
var ImplementationSchema = zod.z.object({
|
|
1288
|
+
selected_api: zod.z.string(),
|
|
1289
|
+
app_id: zod.z.number().optional(),
|
|
1290
|
+
auth_type: zod.z.string().optional(),
|
|
1291
|
+
auth_fields: zod.z.string().optional(),
|
|
1292
|
+
actions: zod.z.array(ActionSchema).optional(),
|
|
1293
|
+
is_deprecated: zod.z.boolean().optional(),
|
|
1294
|
+
is_private_only: zod.z.boolean().optional(),
|
|
1295
|
+
is_invite_only: zod.z.boolean().optional(),
|
|
1296
|
+
is_beta: zod.z.boolean().optional().default(false),
|
|
1297
|
+
is_premium: zod.z.boolean().optional().default(false),
|
|
1298
|
+
is_hidden: zod.z.string().optional(),
|
|
1299
|
+
name: zod.z.string().optional(),
|
|
1300
|
+
slug: zod.z.string().optional(),
|
|
1301
|
+
images: zod.z.record(zod.z.string(), zod.z.string().nullable()).optional(),
|
|
1302
|
+
primary_color: zod.z.string().optional(),
|
|
1303
|
+
secondary_color: zod.z.string().optional(),
|
|
1304
|
+
current_implementation: zod.z.string().optional(),
|
|
1305
|
+
other_implementations: zod.z.string().optional()
|
|
1306
|
+
});
|
|
1307
|
+
zod.z.object({
|
|
1308
|
+
count: zod.z.number(),
|
|
1309
|
+
next: zod.z.string().nullable().optional(),
|
|
1310
|
+
previous: zod.z.string().nullable().optional(),
|
|
1311
|
+
results: zod.z.array(ImplementationSchema)
|
|
1312
|
+
});
|
|
1313
|
+
var NeedChoicesResponseMetaSchema = zod.z.object({
|
|
1314
|
+
page: zod.z.string().nullable().optional()
|
|
1315
|
+
});
|
|
1316
|
+
var NeedChoicesResponseLinksSchema = zod.z.object({
|
|
1317
|
+
next: zod.z.string().nullable().optional(),
|
|
1318
|
+
prev: zod.z.string().nullable().optional()
|
|
1319
|
+
});
|
|
1320
|
+
zod.z.object({
|
|
1321
|
+
selected_api: zod.z.string().optional().describe(
|
|
1322
|
+
"Something like `SlackAPI` (for Python apps) or `SplitwiseCLIAPI@1.0.0` (for CLI apps). Non-public apps are fine as long as the authed user can access them."
|
|
1487
1323
|
),
|
|
1488
|
-
|
|
1489
|
-
"
|
|
1324
|
+
authentication_id: zod.z.coerce.number().optional().describe(
|
|
1325
|
+
"If the app needs auth, provide an `authentication_id` that has the `selected_api` of the app you want to run. Can be any auth visible to the user (including shared)."
|
|
1490
1326
|
),
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1327
|
+
params: zod.z.record(zod.z.string(), zod.z.unknown()).optional().describe(
|
|
1328
|
+
"Object that matches the input the node would normally get. Has all the same keys/types as the `needs` of the action."
|
|
1329
|
+
),
|
|
1330
|
+
page: zod.z.number().optional().default(0),
|
|
1331
|
+
prefill: zod.z.string().optional().describe(
|
|
1332
|
+
"The prefill string to indicate what we're fetching choices for. Likely something like `spreadsheet.id.title`. Must be provided alongside `selected_api` if both `action_id` and `input_field_id` are not."
|
|
1333
|
+
),
|
|
1334
|
+
action_id: zod.z.string().optional().describe(
|
|
1335
|
+
"The id that will be used to lookup the Action for prefill lookup. If provided, `input_field_id` is required, else `prefill` must be provided."
|
|
1336
|
+
),
|
|
1337
|
+
input_field_id: zod.z.string().optional().describe(
|
|
1338
|
+
"The id (key) of the input field (Need) that dynamic choices are being retrieved for. If provided, `action_id` is required, else `prefill` must be provided."
|
|
1339
|
+
)
|
|
1340
|
+
});
|
|
1341
|
+
zod.z.object({
|
|
1342
|
+
success: zod.z.boolean(),
|
|
1343
|
+
choices: zod.z.array(NeedChoicesSchema).optional(),
|
|
1344
|
+
next_page: zod.z.number().optional(),
|
|
1345
|
+
errors: zod.z.array(zod.z.string()).optional(),
|
|
1346
|
+
meta: NeedChoicesResponseMetaSchema.optional(),
|
|
1347
|
+
links: NeedChoicesResponseLinksSchema.optional()
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
// src/schemas/Action.ts
|
|
1495
1351
|
var ActionItemSchema = withFormatter(
|
|
1496
1352
|
ActionSchema.omit({ type: true, name: true, selected_api: true }).extend({
|
|
1497
1353
|
app_key: zod.z.string(),
|
|
@@ -2352,7 +2208,7 @@ var getAppPlugin = ({ sdk, context }) => {
|
|
|
2352
2208
|
type: "item",
|
|
2353
2209
|
itemType: "App",
|
|
2354
2210
|
inputSchema: GetAppSchema,
|
|
2355
|
-
outputSchema:
|
|
2211
|
+
outputSchema: AppItemSchema,
|
|
2356
2212
|
resolvers: {
|
|
2357
2213
|
appKey: appKeyResolver
|
|
2358
2214
|
}
|
|
@@ -3617,36 +3473,29 @@ async function pollUntilComplete(options) {
|
|
|
3617
3473
|
}
|
|
3618
3474
|
}
|
|
3619
3475
|
|
|
3620
|
-
// src/
|
|
3621
|
-
function
|
|
3622
|
-
return
|
|
3476
|
+
// src/types/credentials.ts
|
|
3477
|
+
function isClientCredentials(credentials) {
|
|
3478
|
+
return typeof credentials === "object" && credentials !== null && "clientId" in credentials && "clientSecret" in credentials;
|
|
3623
3479
|
}
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
const { getToken } = await import('@zapier/zapier-sdk-cli-login');
|
|
3627
|
-
return await getToken(options);
|
|
3628
|
-
} catch {
|
|
3629
|
-
return void 0;
|
|
3630
|
-
}
|
|
3480
|
+
function isPkceCredentials(credentials) {
|
|
3481
|
+
return typeof credentials === "object" && credentials !== null && "clientId" in credentials && !("clientSecret" in credentials);
|
|
3631
3482
|
}
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
if (envToken) {
|
|
3635
|
-
return envToken;
|
|
3636
|
-
}
|
|
3637
|
-
return getTokenFromCliLogin(options);
|
|
3483
|
+
function isCredentialsObject(credentials) {
|
|
3484
|
+
return typeof credentials === "object" && credentials !== null && "clientId" in credentials;
|
|
3638
3485
|
}
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
}
|
|
3649
|
-
|
|
3486
|
+
function isCredentialsFunction(credentials) {
|
|
3487
|
+
return typeof credentials === "function";
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
// src/utils/logging.ts
|
|
3491
|
+
var loggedDeprecations = /* @__PURE__ */ new Set();
|
|
3492
|
+
function logDeprecation(message) {
|
|
3493
|
+
if (loggedDeprecations.has(message)) return;
|
|
3494
|
+
loggedDeprecations.add(message);
|
|
3495
|
+
console.warn(`[zapier-sdk] Deprecation: ${message}`);
|
|
3496
|
+
}
|
|
3497
|
+
function resetDeprecationWarnings() {
|
|
3498
|
+
loggedDeprecations.clear();
|
|
3650
3499
|
}
|
|
3651
3500
|
|
|
3652
3501
|
// src/utils/url-utils.ts
|
|
@@ -3695,174 +3544,276 @@ function getTrackingBaseUrl({
|
|
|
3695
3544
|
return ZAPIER_BASE_URL;
|
|
3696
3545
|
}
|
|
3697
3546
|
|
|
3698
|
-
// src/
|
|
3699
|
-
function
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
const baseKey = parts[0];
|
|
3703
|
-
const version = parts.slice(1).join("@");
|
|
3704
|
-
return [baseKey, version];
|
|
3705
|
-
}
|
|
3706
|
-
return [versionedKey, void 0];
|
|
3547
|
+
// src/credentials.ts
|
|
3548
|
+
function deriveAuthBaseUrl(sdkBaseUrl) {
|
|
3549
|
+
if (!sdkBaseUrl) return void 0;
|
|
3550
|
+
return getZapierBaseUrl(sdkBaseUrl);
|
|
3707
3551
|
}
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3552
|
+
function normalizeCredentialsObject(obj, sdkBaseUrl) {
|
|
3553
|
+
const resolvedBaseUrl = obj.baseUrl || deriveAuthBaseUrl(sdkBaseUrl);
|
|
3554
|
+
if (obj.type === "client_credentials" || "clientSecret" in obj && obj.clientSecret) {
|
|
3555
|
+
return {
|
|
3556
|
+
type: "client_credentials",
|
|
3557
|
+
clientId: obj.clientId,
|
|
3558
|
+
clientSecret: obj.clientSecret,
|
|
3559
|
+
baseUrl: resolvedBaseUrl,
|
|
3560
|
+
scope: obj.scope
|
|
3561
|
+
};
|
|
3562
|
+
}
|
|
3713
3563
|
return {
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
version: appVersion
|
|
3564
|
+
type: "pkce",
|
|
3565
|
+
clientId: obj.clientId,
|
|
3566
|
+
baseUrl: resolvedBaseUrl,
|
|
3567
|
+
scope: obj.scope
|
|
3719
3568
|
};
|
|
3720
3569
|
}
|
|
3721
|
-
function
|
|
3722
|
-
if (
|
|
3723
|
-
return
|
|
3724
|
-
}
|
|
3725
|
-
try {
|
|
3726
|
-
const url = new URL(response.next);
|
|
3727
|
-
const offset = url.searchParams.get("offset");
|
|
3728
|
-
return offset || void 0;
|
|
3729
|
-
} catch {
|
|
3730
|
-
return void 0;
|
|
3570
|
+
function resolveCredentialsFromEnv(sdkBaseUrl) {
|
|
3571
|
+
if (ZAPIER_CREDENTIALS) {
|
|
3572
|
+
return ZAPIER_CREDENTIALS;
|
|
3731
3573
|
}
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
const [implementationName] = splitVersionedKey2(result.id);
|
|
3750
|
-
const isPublic = result.visibility === "public";
|
|
3751
|
-
const existing = byImplementationName.get(implementationName);
|
|
3752
|
-
if (!existing || isPublic && !existing.isPublic) {
|
|
3753
|
-
byImplementationName.set(implementationName, { result, isPublic });
|
|
3574
|
+
if (ZAPIER_CREDENTIALS_CLIENT_ID) {
|
|
3575
|
+
const resolvedBaseUrl = ZAPIER_CREDENTIALS_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
|
|
3576
|
+
if (ZAPIER_CREDENTIALS_CLIENT_SECRET) {
|
|
3577
|
+
return {
|
|
3578
|
+
type: "client_credentials",
|
|
3579
|
+
clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
|
|
3580
|
+
clientSecret: ZAPIER_CREDENTIALS_CLIENT_SECRET,
|
|
3581
|
+
baseUrl: resolvedBaseUrl,
|
|
3582
|
+
scope: ZAPIER_CREDENTIALS_SCOPE
|
|
3583
|
+
};
|
|
3584
|
+
} else {
|
|
3585
|
+
return {
|
|
3586
|
+
type: "pkce",
|
|
3587
|
+
clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
|
|
3588
|
+
baseUrl: resolvedBaseUrl,
|
|
3589
|
+
scope: ZAPIER_CREDENTIALS_SCOPE
|
|
3590
|
+
};
|
|
3754
3591
|
}
|
|
3755
3592
|
}
|
|
3756
|
-
|
|
3757
|
-
(
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
additionalIds.push(result.implementation_id);
|
|
3593
|
+
if (ZAPIER_TOKEN) {
|
|
3594
|
+
logDeprecation(
|
|
3595
|
+
"ZAPIER_TOKEN is deprecated. Use ZAPIER_CREDENTIALS instead."
|
|
3596
|
+
);
|
|
3597
|
+
return ZAPIER_TOKEN;
|
|
3598
|
+
}
|
|
3599
|
+
if (ZAPIER_AUTH_CLIENT_ID) {
|
|
3600
|
+
logDeprecation(
|
|
3601
|
+
"ZAPIER_AUTH_CLIENT_ID is deprecated. Use ZAPIER_CREDENTIALS_CLIENT_ID instead."
|
|
3602
|
+
);
|
|
3603
|
+
if (ZAPIER_AUTH_BASE_URL) {
|
|
3604
|
+
logDeprecation(
|
|
3605
|
+
"ZAPIER_AUTH_BASE_URL is deprecated. Use ZAPIER_CREDENTIALS_BASE_URL instead."
|
|
3606
|
+
);
|
|
3771
3607
|
}
|
|
3608
|
+
const resolvedBaseUrl = ZAPIER_AUTH_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
|
|
3609
|
+
return {
|
|
3610
|
+
type: "pkce",
|
|
3611
|
+
clientId: ZAPIER_AUTH_CLIENT_ID,
|
|
3612
|
+
baseUrl: resolvedBaseUrl
|
|
3613
|
+
};
|
|
3772
3614
|
}
|
|
3773
|
-
return
|
|
3615
|
+
return void 0;
|
|
3774
3616
|
}
|
|
3775
|
-
|
|
3776
|
-
const
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
return {
|
|
3790
|
-
data: [],
|
|
3791
|
-
nextCursor: void 0
|
|
3792
|
-
};
|
|
3617
|
+
async function resolveCredentials(options = {}) {
|
|
3618
|
+
const { baseUrl } = options;
|
|
3619
|
+
if (options.credentials !== void 0) {
|
|
3620
|
+
if (isCredentialsFunction(options.credentials)) {
|
|
3621
|
+
const resolved = await options.credentials();
|
|
3622
|
+
if (typeof resolved === "function") {
|
|
3623
|
+
throw new Error(
|
|
3624
|
+
"Credentials function returned another function. Credentials functions must return a string or credentials object."
|
|
3625
|
+
);
|
|
3626
|
+
}
|
|
3627
|
+
if (isCredentialsObject(resolved)) {
|
|
3628
|
+
return normalizeCredentialsObject(resolved, baseUrl);
|
|
3629
|
+
}
|
|
3630
|
+
return resolved;
|
|
3793
3631
|
}
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
selected_apis: "",
|
|
3797
|
-
limit: pageSize.toString()
|
|
3798
|
-
};
|
|
3799
|
-
if (validatedRequest.cursor) {
|
|
3800
|
-
searchParams2.offset = validatedRequest.cursor;
|
|
3632
|
+
if (isCredentialsObject(options.credentials)) {
|
|
3633
|
+
return normalizeCredentialsObject(options.credentials, baseUrl);
|
|
3801
3634
|
}
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3635
|
+
return options.credentials;
|
|
3636
|
+
}
|
|
3637
|
+
if (options.token !== void 0) {
|
|
3638
|
+
logDeprecation(
|
|
3639
|
+
"The `token` option is deprecated. Use `credentials` instead."
|
|
3807
3640
|
);
|
|
3808
|
-
return
|
|
3809
|
-
data: implementationsResponse2.results.map(
|
|
3810
|
-
transformImplementationMetaToAppItem
|
|
3811
|
-
),
|
|
3812
|
-
nextCursor: extractPaginationCursor(implementationsResponse2)
|
|
3813
|
-
};
|
|
3641
|
+
return options.token;
|
|
3814
3642
|
}
|
|
3815
|
-
const
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
};
|
|
3819
|
-
if (validatedRequest.cursor) {
|
|
3820
|
-
searchParams.offset = validatedRequest.cursor;
|
|
3643
|
+
const envCredentials = resolveCredentialsFromEnv(baseUrl);
|
|
3644
|
+
if (envCredentials !== void 0) {
|
|
3645
|
+
return envCredentials;
|
|
3821
3646
|
}
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
return
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
}
|
|
3834
|
-
|
|
3647
|
+
return void 0;
|
|
3648
|
+
}
|
|
3649
|
+
function getBaseUrlFromCredentials(credentials) {
|
|
3650
|
+
if (credentials && isCredentialsObject(credentials)) {
|
|
3651
|
+
return credentials.baseUrl;
|
|
3652
|
+
}
|
|
3653
|
+
return void 0;
|
|
3654
|
+
}
|
|
3655
|
+
function getClientIdFromCredentials(credentials) {
|
|
3656
|
+
if (credentials && isCredentialsObject(credentials)) {
|
|
3657
|
+
return credentials.clientId;
|
|
3658
|
+
}
|
|
3659
|
+
return void 0;
|
|
3660
|
+
}
|
|
3835
3661
|
|
|
3836
|
-
// src/
|
|
3837
|
-
var
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3662
|
+
// src/auth.ts
|
|
3663
|
+
var tokenCache = /* @__PURE__ */ new Map();
|
|
3664
|
+
var pendingExchanges = /* @__PURE__ */ new Map();
|
|
3665
|
+
function clearTokenCache() {
|
|
3666
|
+
tokenCache.clear();
|
|
3667
|
+
pendingExchanges.clear();
|
|
3668
|
+
}
|
|
3669
|
+
var TOKEN_EXPIRATION_BUFFER = 5 * 60 * 1e3;
|
|
3670
|
+
function getCachedToken(clientId) {
|
|
3671
|
+
const cached = tokenCache.get(clientId);
|
|
3672
|
+
if (!cached) return void 0;
|
|
3673
|
+
if (cached.expiresAt > Date.now() + TOKEN_EXPIRATION_BUFFER) {
|
|
3674
|
+
return cached.accessToken;
|
|
3675
|
+
}
|
|
3676
|
+
tokenCache.delete(clientId);
|
|
3677
|
+
return void 0;
|
|
3678
|
+
}
|
|
3679
|
+
function cacheToken(clientId, accessToken, expiresIn) {
|
|
3680
|
+
tokenCache.set(clientId, {
|
|
3681
|
+
accessToken,
|
|
3682
|
+
expiresAt: Date.now() + expiresIn * 1e3
|
|
3683
|
+
});
|
|
3684
|
+
}
|
|
3685
|
+
function invalidateCachedToken(clientId) {
|
|
3686
|
+
tokenCache.delete(clientId);
|
|
3687
|
+
}
|
|
3688
|
+
function getTokenEndpointUrl(baseUrl) {
|
|
3689
|
+
const base = baseUrl || ZAPIER_BASE_URL;
|
|
3690
|
+
return `${base}/oauth/token/`;
|
|
3691
|
+
}
|
|
3692
|
+
async function exchangeClientCredentials(options) {
|
|
3693
|
+
const { clientId, clientSecret, baseUrl, scope, onEvent } = options;
|
|
3694
|
+
const fetchFn = options.fetch || globalThis.fetch;
|
|
3695
|
+
const tokenUrl = getTokenEndpointUrl(baseUrl);
|
|
3696
|
+
onEvent?.({
|
|
3697
|
+
type: "auth_exchanging",
|
|
3698
|
+
payload: {
|
|
3699
|
+
message: "Exchanging client credentials for token...",
|
|
3700
|
+
operation: "client_credentials"
|
|
3701
|
+
},
|
|
3702
|
+
timestamp: Date.now()
|
|
3703
|
+
});
|
|
3704
|
+
const response = await fetchFn(tokenUrl, {
|
|
3705
|
+
method: "POST",
|
|
3706
|
+
headers: {
|
|
3707
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
3708
|
+
},
|
|
3709
|
+
body: new URLSearchParams({
|
|
3710
|
+
grant_type: "client_credentials",
|
|
3711
|
+
client_id: clientId,
|
|
3712
|
+
client_secret: clientSecret,
|
|
3713
|
+
scope: scope || "external",
|
|
3714
|
+
audience: "zapier.com"
|
|
3715
|
+
})
|
|
3716
|
+
});
|
|
3717
|
+
if (!response.ok) {
|
|
3718
|
+
const errorText = await response.text();
|
|
3719
|
+
onEvent?.({
|
|
3720
|
+
type: "auth_error",
|
|
3721
|
+
payload: {
|
|
3722
|
+
message: `Client credentials exchange failed: ${response.status}`,
|
|
3723
|
+
error: errorText,
|
|
3724
|
+
operation: "client_credentials"
|
|
3725
|
+
},
|
|
3726
|
+
timestamp: Date.now()
|
|
3727
|
+
});
|
|
3728
|
+
throw new Error(
|
|
3729
|
+
`Client credentials exchange failed: ${response.status} ${response.statusText}`
|
|
3730
|
+
);
|
|
3843
3731
|
}
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3732
|
+
const data = await response.json();
|
|
3733
|
+
if (!data.access_token) {
|
|
3734
|
+
throw new Error("Client credentials response missing access_token");
|
|
3735
|
+
}
|
|
3736
|
+
const expiresIn = data.expires_in || 3600;
|
|
3737
|
+
cacheToken(clientId, data.access_token, expiresIn);
|
|
3738
|
+
onEvent?.({
|
|
3739
|
+
type: "auth_success",
|
|
3740
|
+
payload: {
|
|
3741
|
+
message: "Client credentials exchange successful",
|
|
3742
|
+
operation: "client_credentials"
|
|
3743
|
+
},
|
|
3744
|
+
timestamp: Date.now()
|
|
3745
|
+
});
|
|
3746
|
+
return data.access_token;
|
|
3747
|
+
}
|
|
3748
|
+
async function getTokenFromCliLogin(options) {
|
|
3749
|
+
try {
|
|
3750
|
+
const cliLogin = await import('@zapier/zapier-sdk-cli-login');
|
|
3751
|
+
return await cliLogin.getToken(options);
|
|
3752
|
+
} catch {
|
|
3753
|
+
return void 0;
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
async function resolveAuthToken(options = {}) {
|
|
3757
|
+
const credentials = await resolveCredentials({
|
|
3758
|
+
credentials: options.credentials,
|
|
3759
|
+
token: options.token
|
|
3760
|
+
});
|
|
3761
|
+
if (credentials !== void 0) {
|
|
3762
|
+
return resolveAuthTokenFromCredentials(credentials, options);
|
|
3763
|
+
}
|
|
3764
|
+
return getTokenFromCliLogin({
|
|
3765
|
+
onEvent: options.onEvent,
|
|
3766
|
+
fetch: options.fetch
|
|
3767
|
+
});
|
|
3768
|
+
}
|
|
3769
|
+
async function resolveAuthTokenFromCredentials(credentials, options) {
|
|
3770
|
+
if (typeof credentials === "string") {
|
|
3771
|
+
return credentials;
|
|
3772
|
+
}
|
|
3773
|
+
if (isClientCredentials(credentials)) {
|
|
3774
|
+
const { clientId } = credentials;
|
|
3775
|
+
const cached = getCachedToken(clientId);
|
|
3776
|
+
if (cached) {
|
|
3777
|
+
return cached;
|
|
3778
|
+
}
|
|
3779
|
+
const pending = pendingExchanges.get(clientId);
|
|
3780
|
+
if (pending) {
|
|
3781
|
+
return pending;
|
|
3782
|
+
}
|
|
3783
|
+
const exchangePromise = exchangeClientCredentials({
|
|
3784
|
+
clientId: credentials.clientId,
|
|
3785
|
+
clientSecret: credentials.clientSecret,
|
|
3786
|
+
baseUrl: credentials.baseUrl || options.baseUrl,
|
|
3787
|
+
scope: credentials.scope,
|
|
3788
|
+
fetch: options.fetch,
|
|
3789
|
+
onEvent: options.onEvent
|
|
3790
|
+
}).finally(() => {
|
|
3791
|
+
pendingExchanges.delete(clientId);
|
|
3792
|
+
});
|
|
3793
|
+
pendingExchanges.set(clientId, exchangePromise);
|
|
3794
|
+
return exchangePromise;
|
|
3795
|
+
}
|
|
3796
|
+
if (isPkceCredentials(credentials)) {
|
|
3797
|
+
const storedToken = await getTokenFromCliLogin({
|
|
3798
|
+
onEvent: options.onEvent,
|
|
3799
|
+
fetch: options.fetch,
|
|
3800
|
+
credentials
|
|
3801
|
+
});
|
|
3802
|
+
if (storedToken) {
|
|
3803
|
+
return storedToken;
|
|
3860
3804
|
}
|
|
3805
|
+
throw new Error(
|
|
3806
|
+
"PKCE credentials require interactive login. Please run the 'login' command with the CLI first, or use client_credentials flow."
|
|
3807
|
+
);
|
|
3861
3808
|
}
|
|
3862
|
-
|
|
3809
|
+
throw new Error("Unknown credentials type");
|
|
3863
3810
|
}
|
|
3864
|
-
function
|
|
3865
|
-
|
|
3811
|
+
async function invalidateCredentialsToken(options) {
|
|
3812
|
+
const resolved = await resolveCredentials(options);
|
|
3813
|
+
const clientId = getClientIdFromCredentials(resolved);
|
|
3814
|
+
if (clientId) {
|
|
3815
|
+
invalidateCachedToken(clientId);
|
|
3816
|
+
}
|
|
3866
3817
|
}
|
|
3867
3818
|
|
|
3868
3819
|
// src/api/client.ts
|
|
@@ -3922,13 +3873,11 @@ var ZapierApiClient = class {
|
|
|
3922
3873
|
// Helper to get a token from the different places it could be gotten
|
|
3923
3874
|
async getAuthToken() {
|
|
3924
3875
|
return resolveAuthToken({
|
|
3876
|
+
credentials: this.options.credentials,
|
|
3925
3877
|
token: this.options.token,
|
|
3926
|
-
getToken: this.options.getToken,
|
|
3927
3878
|
onEvent: this.options.onEvent,
|
|
3928
3879
|
fetch: this.options.fetch,
|
|
3929
|
-
baseUrl: this.options.baseUrl
|
|
3930
|
-
authBaseUrl: this.options.authBaseUrl,
|
|
3931
|
-
authClientId: this.options.authClientId
|
|
3880
|
+
baseUrl: this.options.baseUrl
|
|
3932
3881
|
});
|
|
3933
3882
|
}
|
|
3934
3883
|
// Helper to handle responses
|
|
@@ -3966,10 +3915,16 @@ var ZapierApiClient = class {
|
|
|
3966
3915
|
if (response.status === 401 || response.status === 403) {
|
|
3967
3916
|
if (wasMissingAuthToken) {
|
|
3968
3917
|
throw new ZapierAuthenticationError(
|
|
3969
|
-
`Authentication required (HTTP ${response.status}). Please provide
|
|
3918
|
+
`Authentication required (HTTP ${response.status}). Please provide credentials in options or set ZAPIER_CREDENTIALS environment variable.`,
|
|
3970
3919
|
errorOptions
|
|
3971
3920
|
);
|
|
3972
3921
|
}
|
|
3922
|
+
if (response.status === 401) {
|
|
3923
|
+
await invalidateCredentialsToken({
|
|
3924
|
+
credentials: this.options.credentials,
|
|
3925
|
+
token: this.options.token
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3973
3928
|
throw new ZapierAuthenticationError(message, errorOptions);
|
|
3974
3929
|
}
|
|
3975
3930
|
if (response.status === 400) {
|
|
@@ -4105,7 +4060,7 @@ var ZapierApiClient = class {
|
|
|
4105
4060
|
if (options.authRequired) {
|
|
4106
4061
|
if (headers.get("Authorization") == null && authToken == null) {
|
|
4107
4062
|
throw new ZapierAuthenticationError(
|
|
4108
|
-
`Authentication required but no
|
|
4063
|
+
`Authentication required but no credentials available. Please set ZAPIER_CREDENTIALS, or run the 'login' command with the CLI.`
|
|
4109
4064
|
);
|
|
4110
4065
|
}
|
|
4111
4066
|
}
|
|
@@ -4113,20 +4068,6 @@ var ZapierApiClient = class {
|
|
|
4113
4068
|
}
|
|
4114
4069
|
// Helper to perform HTTP requests with JSON handling
|
|
4115
4070
|
async fetchJson(method, path, data, options = {}) {
|
|
4116
|
-
const routeMatch = matchRoute(method, path);
|
|
4117
|
-
if (routeMatch) {
|
|
4118
|
-
const handlerRequest = {
|
|
4119
|
-
...typeof data === "object" ? data : {},
|
|
4120
|
-
...options.searchParams,
|
|
4121
|
-
...routeMatch.params
|
|
4122
|
-
};
|
|
4123
|
-
return routeMatch.handler({
|
|
4124
|
-
request: handlerRequest,
|
|
4125
|
-
deps: {
|
|
4126
|
-
httpClient: this
|
|
4127
|
-
}
|
|
4128
|
-
});
|
|
4129
|
-
}
|
|
4130
4071
|
const headers = { ...options.headers };
|
|
4131
4072
|
if (data && typeof data === "object") {
|
|
4132
4073
|
headers["Content-Type"] = "application/json";
|
|
@@ -4195,27 +4136,28 @@ var apiPlugin = (params) => {
|
|
|
4195
4136
|
const {
|
|
4196
4137
|
fetch: customFetch = globalThis.fetch,
|
|
4197
4138
|
baseUrl = ZAPIER_BASE_URL,
|
|
4198
|
-
|
|
4199
|
-
authClientId,
|
|
4139
|
+
credentials,
|
|
4200
4140
|
token,
|
|
4201
|
-
getToken,
|
|
4202
4141
|
onEvent,
|
|
4203
4142
|
debug = false
|
|
4204
4143
|
} = params.context.options;
|
|
4205
4144
|
const api = createZapierApi({
|
|
4206
4145
|
baseUrl,
|
|
4207
|
-
|
|
4208
|
-
authClientId,
|
|
4146
|
+
credentials,
|
|
4209
4147
|
token,
|
|
4210
|
-
getToken,
|
|
4211
4148
|
debug,
|
|
4212
4149
|
fetch: customFetch,
|
|
4213
4150
|
onEvent
|
|
4214
4151
|
});
|
|
4215
4152
|
return {
|
|
4216
4153
|
context: {
|
|
4217
|
-
api
|
|
4154
|
+
api,
|
|
4218
4155
|
// Provide API client in context for other plugins to use
|
|
4156
|
+
resolveCredentials: () => resolveCredentials({
|
|
4157
|
+
credentials,
|
|
4158
|
+
token,
|
|
4159
|
+
baseUrl
|
|
4160
|
+
})
|
|
4219
4161
|
}
|
|
4220
4162
|
};
|
|
4221
4163
|
};
|
|
@@ -4809,7 +4751,7 @@ function getCpuTime() {
|
|
|
4809
4751
|
|
|
4810
4752
|
// package.json
|
|
4811
4753
|
var package_default = {
|
|
4812
|
-
version: "0.
|
|
4754
|
+
version: "1.0.0"};
|
|
4813
4755
|
|
|
4814
4756
|
// src/plugins/eventEmission/builders.ts
|
|
4815
4757
|
function createBaseEvent(context = {}) {
|
|
@@ -4982,11 +4924,9 @@ var eventEmissionPlugin = ({ context }) => {
|
|
|
4982
4924
|
const getUserContext = (async () => {
|
|
4983
4925
|
try {
|
|
4984
4926
|
const token = await resolveAuthToken({
|
|
4927
|
+
credentials: context.options.credentials,
|
|
4985
4928
|
token: context.options.token,
|
|
4986
|
-
getToken: context.options.getToken,
|
|
4987
4929
|
baseUrl: context.options.baseUrl,
|
|
4988
|
-
authBaseUrl: context.options.authBaseUrl,
|
|
4989
|
-
authClientId: context.options.authClientId,
|
|
4990
4930
|
onEvent: context.options.onEvent,
|
|
4991
4931
|
fetch: context.options.fetch
|
|
4992
4932
|
});
|
|
@@ -5265,7 +5205,15 @@ exports.OutputPropertySchema = OutputPropertySchema;
|
|
|
5265
5205
|
exports.ParamsPropertySchema = ParamsPropertySchema;
|
|
5266
5206
|
exports.RelayFetchSchema = RelayFetchSchema;
|
|
5267
5207
|
exports.RelayRequestSchema = RelayRequestSchema;
|
|
5208
|
+
exports.ZAPIER_AUTH_BASE_URL = ZAPIER_AUTH_BASE_URL;
|
|
5209
|
+
exports.ZAPIER_AUTH_CLIENT_ID = ZAPIER_AUTH_CLIENT_ID;
|
|
5268
5210
|
exports.ZAPIER_BASE_URL = ZAPIER_BASE_URL;
|
|
5211
|
+
exports.ZAPIER_CREDENTIALS = ZAPIER_CREDENTIALS;
|
|
5212
|
+
exports.ZAPIER_CREDENTIALS_BASE_URL = ZAPIER_CREDENTIALS_BASE_URL;
|
|
5213
|
+
exports.ZAPIER_CREDENTIALS_CLIENT_ID = ZAPIER_CREDENTIALS_CLIENT_ID;
|
|
5214
|
+
exports.ZAPIER_CREDENTIALS_CLIENT_SECRET = ZAPIER_CREDENTIALS_CLIENT_SECRET;
|
|
5215
|
+
exports.ZAPIER_CREDENTIALS_SCOPE = ZAPIER_CREDENTIALS_SCOPE;
|
|
5216
|
+
exports.ZAPIER_TOKEN = ZAPIER_TOKEN;
|
|
5269
5217
|
exports.ZapierActionError = ZapierActionError;
|
|
5270
5218
|
exports.ZapierApiError = ZapierApiError;
|
|
5271
5219
|
exports.ZapierAppNotFoundError = ZapierAppNotFoundError;
|
|
@@ -5290,6 +5238,7 @@ exports.buildApplicationLifecycleEvent = buildApplicationLifecycleEvent;
|
|
|
5290
5238
|
exports.buildErrorEvent = buildErrorEvent;
|
|
5291
5239
|
exports.buildErrorEventWithContext = buildErrorEventWithContext;
|
|
5292
5240
|
exports.buildMethodCalledEvent = buildMethodCalledEvent;
|
|
5241
|
+
exports.clearTokenCache = clearTokenCache;
|
|
5293
5242
|
exports.createBaseEvent = createBaseEvent;
|
|
5294
5243
|
exports.createFunction = createFunction;
|
|
5295
5244
|
exports.createSdk = createSdk;
|
|
@@ -5304,7 +5253,9 @@ exports.generateEventId = generateEventId;
|
|
|
5304
5253
|
exports.getActionPlugin = getActionPlugin;
|
|
5305
5254
|
exports.getAppPlugin = getAppPlugin;
|
|
5306
5255
|
exports.getAuthenticationPlugin = getAuthenticationPlugin;
|
|
5256
|
+
exports.getBaseUrlFromCredentials = getBaseUrlFromCredentials;
|
|
5307
5257
|
exports.getCiPlatform = getCiPlatform;
|
|
5258
|
+
exports.getClientIdFromCredentials = getClientIdFromCredentials;
|
|
5308
5259
|
exports.getCpuTime = getCpuTime;
|
|
5309
5260
|
exports.getCurrentTimestamp = getCurrentTimestamp;
|
|
5310
5261
|
exports.getMemoryUsage = getMemoryUsage;
|
|
@@ -5314,22 +5265,30 @@ exports.getPreferredManifestEntryKey = getPreferredManifestEntryKey;
|
|
|
5314
5265
|
exports.getProfilePlugin = getProfilePlugin;
|
|
5315
5266
|
exports.getReleaseId = getReleaseId;
|
|
5316
5267
|
exports.getTokenFromCliLogin = getTokenFromCliLogin;
|
|
5317
|
-
exports.getTokenFromEnv = getTokenFromEnv;
|
|
5318
|
-
exports.getTokenFromEnvOrConfig = getTokenFromEnvOrConfig;
|
|
5319
5268
|
exports.inputFieldKeyResolver = inputFieldKeyResolver;
|
|
5320
5269
|
exports.inputsAllOptionalResolver = inputsAllOptionalResolver;
|
|
5321
5270
|
exports.inputsResolver = inputsResolver;
|
|
5271
|
+
exports.invalidateCachedToken = invalidateCachedToken;
|
|
5272
|
+
exports.invalidateCredentialsToken = invalidateCredentialsToken;
|
|
5322
5273
|
exports.isCi = isCi;
|
|
5274
|
+
exports.isClientCredentials = isClientCredentials;
|
|
5275
|
+
exports.isCredentialsFunction = isCredentialsFunction;
|
|
5276
|
+
exports.isCredentialsObject = isCredentialsObject;
|
|
5277
|
+
exports.isPkceCredentials = isPkceCredentials;
|
|
5323
5278
|
exports.isPositional = isPositional;
|
|
5324
5279
|
exports.listActionsPlugin = listActionsPlugin;
|
|
5325
5280
|
exports.listAppsPlugin = listAppsPlugin;
|
|
5326
5281
|
exports.listAuthenticationsPlugin = listAuthenticationsPlugin;
|
|
5327
5282
|
exports.listInputFieldsPlugin = listInputFieldsPlugin;
|
|
5283
|
+
exports.logDeprecation = logDeprecation;
|
|
5328
5284
|
exports.manifestPlugin = manifestPlugin;
|
|
5329
5285
|
exports.readManifestFromFile = readManifestFromFile;
|
|
5330
5286
|
exports.registryPlugin = registryPlugin;
|
|
5331
5287
|
exports.requestPlugin = requestPlugin;
|
|
5288
|
+
exports.resetDeprecationWarnings = resetDeprecationWarnings;
|
|
5332
5289
|
exports.resolveAuthToken = resolveAuthToken;
|
|
5290
|
+
exports.resolveCredentials = resolveCredentials;
|
|
5291
|
+
exports.resolveCredentialsFromEnv = resolveCredentialsFromEnv;
|
|
5333
5292
|
exports.runActionPlugin = runActionPlugin;
|
|
5334
5293
|
exports.toSnakeCase = toSnakeCase;
|
|
5335
5294
|
exports.toTitleCase = toTitleCase;
|