@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.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { ListAppsQuerySchema, AppItemSchema as AppItemSchema$1 } from '@zapier/zapier-sdk-core/v0/schemas/apps';
|
|
2
3
|
import { ListAuthenticationsQuerySchema as ListAuthenticationsQuerySchema$1, AuthenticationItemSchema as AuthenticationItemSchema$1, GetAuthenticationParamSchema } from '@zapier/zapier-sdk-core/v0/schemas/authentications';
|
|
3
4
|
import { setTimeout as setTimeout$1 } from 'timers/promises';
|
|
4
5
|
import * as os from 'os';
|
|
@@ -35,6 +36,14 @@ function isPositional(schema) {
|
|
|
35
36
|
// src/constants.ts
|
|
36
37
|
var ZAPIER_BASE_URL = process.env.ZAPIER_BASE_URL || "https://zapier.com";
|
|
37
38
|
var MAX_PAGE_LIMIT = 1e4;
|
|
39
|
+
var ZAPIER_CREDENTIALS = process.env.ZAPIER_CREDENTIALS;
|
|
40
|
+
var ZAPIER_CREDENTIALS_CLIENT_ID = process.env.ZAPIER_CREDENTIALS_CLIENT_ID;
|
|
41
|
+
var ZAPIER_CREDENTIALS_CLIENT_SECRET = process.env.ZAPIER_CREDENTIALS_CLIENT_SECRET;
|
|
42
|
+
var ZAPIER_CREDENTIALS_BASE_URL = process.env.ZAPIER_CREDENTIALS_BASE_URL;
|
|
43
|
+
var ZAPIER_CREDENTIALS_SCOPE = process.env.ZAPIER_CREDENTIALS_SCOPE;
|
|
44
|
+
var ZAPIER_TOKEN = process.env.ZAPIER_TOKEN;
|
|
45
|
+
var ZAPIER_AUTH_BASE_URL = process.env.ZAPIER_AUTH_BASE_URL;
|
|
46
|
+
var ZAPIER_AUTH_CLIENT_ID = process.env.ZAPIER_AUTH_CLIENT_ID;
|
|
38
47
|
|
|
39
48
|
// src/types/properties.ts
|
|
40
49
|
var AppKeyPropertySchema = withPositional(
|
|
@@ -795,105 +804,230 @@ function createPaginatedFunction(coreFn, schema, telemetry, explicitFunctionName
|
|
|
795
804
|
};
|
|
796
805
|
return namedFunctions[functionName];
|
|
797
806
|
}
|
|
798
|
-
var
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
age_in_days: z.number().optional(),
|
|
803
|
-
auth_type: z.string().optional(),
|
|
804
|
-
banner: z.string().optional(),
|
|
805
|
-
categories: z.array(
|
|
806
|
-
z.object({
|
|
807
|
-
id: z.number(),
|
|
808
|
-
name: z.string(),
|
|
809
|
-
slug: z.string()
|
|
810
|
-
})
|
|
811
|
-
).optional(),
|
|
812
|
-
images: z.object({
|
|
813
|
-
url_16x16: z.string().optional(),
|
|
814
|
-
url_32x32: z.string().optional(),
|
|
815
|
-
url_64x64: z.string().optional(),
|
|
816
|
-
url_128x128: z.string().optional()
|
|
817
|
-
}).optional(),
|
|
818
|
-
popularity: z.number().optional(),
|
|
819
|
-
has_filters: z.boolean().optional(),
|
|
820
|
-
has_reads: z.boolean().optional(),
|
|
821
|
-
has_searches: z.boolean().optional(),
|
|
822
|
-
has_searches_or_writes: z.boolean().optional(),
|
|
823
|
-
has_upfront_fields: z.boolean().optional(),
|
|
824
|
-
has_writes: z.boolean().optional(),
|
|
825
|
-
is_beta: z.boolean().optional(),
|
|
826
|
-
is_built_in: z.boolean().optional(),
|
|
827
|
-
is_deprecated: z.boolean().optional(),
|
|
828
|
-
is_featured: z.boolean().optional(),
|
|
829
|
-
is_hidden: z.boolean().optional(),
|
|
830
|
-
is_invite: z.boolean().optional(),
|
|
831
|
-
is_premium: z.boolean().optional(),
|
|
832
|
-
is_public: z.boolean().optional(),
|
|
833
|
-
is_upcoming: z.boolean().optional(),
|
|
834
|
-
version: z.string().optional(),
|
|
835
|
-
visibility: z.string().optional(),
|
|
836
|
-
actions: z.object({
|
|
837
|
-
read: z.number().optional(),
|
|
838
|
-
read_bulk: z.number().optional(),
|
|
839
|
-
write: z.number().optional(),
|
|
840
|
-
search: z.number().optional(),
|
|
841
|
-
search_or_write: z.number().optional(),
|
|
842
|
-
search_and_write: z.number().optional(),
|
|
843
|
-
filter: z.number().optional()
|
|
844
|
-
}).optional(),
|
|
845
|
-
description: z.string().optional(),
|
|
846
|
-
primary_color: z.string().optional(),
|
|
847
|
-
secondary_color: z.string().optional(),
|
|
848
|
-
classification: z.string().optional(),
|
|
849
|
-
api_docs_url: z.string().optional(),
|
|
850
|
-
image: z.string().optional()
|
|
851
|
-
});
|
|
852
|
-
z.object({
|
|
853
|
-
count: z.number(),
|
|
854
|
-
next: z.string().nullable().optional(),
|
|
855
|
-
previous: z.string().nullable().optional(),
|
|
856
|
-
results: z.array(ImplementationMetaSchema)
|
|
857
|
-
});
|
|
858
|
-
|
|
859
|
-
// src/temporary-internal-core/schemas/apps/index.ts
|
|
860
|
-
var ListAppsOptionsSchema = z.object({
|
|
807
|
+
var ListAppsSchema = ListAppsQuerySchema.omit({
|
|
808
|
+
offset: true
|
|
809
|
+
}).extend({
|
|
810
|
+
// Override appKeys to be an array instead of comma-separated string
|
|
861
811
|
appKeys: z.array(z.string()).optional().describe(
|
|
862
812
|
"Filter apps by app keys (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
863
813
|
),
|
|
864
|
-
|
|
814
|
+
// Override pageSize to make optional (base has default value)
|
|
865
815
|
pageSize: z.number().min(1).optional().describe("Number of apps per page"),
|
|
816
|
+
// SDK specific property for pagination/iterator helpers
|
|
866
817
|
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
818
|
+
// SDK specific property for pagination/iterator helpers
|
|
867
819
|
cursor: z.string().optional().describe("Cursor to start from")
|
|
868
820
|
}).merge(TelemetryMarkerSchema).describe("List all available apps with optional filtering");
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
821
|
+
|
|
822
|
+
// src/utils/string-utils.ts
|
|
823
|
+
function toTitleCase(input) {
|
|
824
|
+
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(" ");
|
|
825
|
+
}
|
|
826
|
+
function toSnakeCase(input) {
|
|
827
|
+
let result = input.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s\-]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
828
|
+
if (/^[0-9]/.test(result)) {
|
|
829
|
+
result = "_" + result;
|
|
830
|
+
}
|
|
831
|
+
return result;
|
|
832
|
+
}
|
|
833
|
+
function stripPageSuffix(functionName) {
|
|
834
|
+
return functionName.replace(/Page$/, "");
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/schemas/App.ts
|
|
838
|
+
var AppItemSchema = withFormatter(AppItemSchema$1, {
|
|
839
|
+
format: (item) => {
|
|
840
|
+
const additionalKeys = [];
|
|
841
|
+
if (item.slug && item.slug !== item.key) {
|
|
842
|
+
additionalKeys.push(item.slug);
|
|
843
|
+
const snakeCaseSlug = toSnakeCase(item.slug);
|
|
844
|
+
if (snakeCaseSlug !== item.slug && snakeCaseSlug !== item.key) {
|
|
845
|
+
additionalKeys.push(snakeCaseSlug);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return {
|
|
849
|
+
title: item.title,
|
|
850
|
+
key: item.key,
|
|
851
|
+
keys: [item.key, ...additionalKeys],
|
|
852
|
+
description: item.description,
|
|
853
|
+
details: []
|
|
854
|
+
};
|
|
855
|
+
}
|
|
881
856
|
});
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
857
|
+
|
|
858
|
+
// src/utils/telemetry-utils.ts
|
|
859
|
+
function createTelemetryCallback(emitMethodCalled, methodName) {
|
|
860
|
+
return {
|
|
861
|
+
onMethodCalled: (data) => {
|
|
862
|
+
emitMethodCalled({
|
|
863
|
+
method_name: methodName,
|
|
864
|
+
execution_duration_ms: data.durationMs,
|
|
865
|
+
success_flag: data.success,
|
|
866
|
+
error_message: data.error?.message ?? null,
|
|
867
|
+
error_type: data.error?.constructor.name ?? null,
|
|
868
|
+
argument_count: data.argumentCount,
|
|
869
|
+
is_paginated: data.isPaginated
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// src/plugins/listApps/index.ts
|
|
876
|
+
var listAppsPlugin = ({ context }) => {
|
|
877
|
+
async function listAppsPage(options) {
|
|
878
|
+
const { api, resolveAppKeys: resolveAppKeys2 } = context;
|
|
879
|
+
const appKeys = options.appKeys ?? [];
|
|
880
|
+
const appLocators = await resolveAppKeys2({
|
|
881
|
+
appKeys: [...appKeys]
|
|
882
|
+
});
|
|
883
|
+
const implementationNameToLocator = {};
|
|
884
|
+
for (const locator of appLocators) {
|
|
885
|
+
implementationNameToLocator[locator.implementationName] = [
|
|
886
|
+
...implementationNameToLocator[locator.implementationName] ?? [],
|
|
887
|
+
locator
|
|
888
|
+
];
|
|
889
|
+
}
|
|
890
|
+
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
|
|
891
|
+
if (duplicatedLookupAppKeys.length > 0) {
|
|
892
|
+
throw new Error(
|
|
893
|
+
`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
if (appKeys.length > 0 && appLocators.length === 0 && !options.search) {
|
|
897
|
+
return {
|
|
898
|
+
data: [],
|
|
899
|
+
links: { next: null },
|
|
900
|
+
meta: { count: 0, limit: 0, offset: 0 }
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
const implementationIds = appLocators.map((locator) => {
|
|
904
|
+
const version = locator.version || "latest";
|
|
905
|
+
return `${locator.implementationName}@${version}`;
|
|
906
|
+
});
|
|
907
|
+
return await api.get("/api/v0/apps", {
|
|
908
|
+
searchParams: {
|
|
909
|
+
appKeys: implementationIds.join(","),
|
|
910
|
+
...options.search && { search: options.search },
|
|
911
|
+
pageSize: options.pageSize.toString(),
|
|
912
|
+
...options.cursor && { offset: options.cursor }
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
const methodName = stripPageSuffix(listAppsPage.name);
|
|
917
|
+
const listAppsDefinition = createPaginatedFunction(
|
|
918
|
+
listAppsPage,
|
|
919
|
+
ListAppsSchema,
|
|
920
|
+
createTelemetryCallback(context.eventEmission.emitMethodCalled, methodName),
|
|
921
|
+
methodName
|
|
922
|
+
);
|
|
923
|
+
return {
|
|
924
|
+
listApps: listAppsDefinition,
|
|
925
|
+
context: {
|
|
926
|
+
meta: {
|
|
927
|
+
listApps: {
|
|
928
|
+
categories: ["app"],
|
|
929
|
+
type: "list",
|
|
930
|
+
itemType: "App",
|
|
931
|
+
inputSchema: ListAppsSchema,
|
|
932
|
+
outputSchema: AppItemSchema
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
// src/utils/domain-utils.ts
|
|
940
|
+
function splitVersionedKey(versionedKey) {
|
|
941
|
+
const parts = versionedKey.split("@");
|
|
942
|
+
if (parts.length >= 2) {
|
|
943
|
+
const baseKey = parts[0];
|
|
944
|
+
const version = parts.slice(1).join("@");
|
|
945
|
+
return [baseKey, version];
|
|
946
|
+
}
|
|
947
|
+
return [versionedKey, void 0];
|
|
948
|
+
}
|
|
949
|
+
function normalizeImplementationMetaToAppItem(implementationMeta) {
|
|
950
|
+
const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
|
|
951
|
+
const { id, name, ...restOfImplementationMeta } = implementationMeta;
|
|
952
|
+
return {
|
|
953
|
+
...restOfImplementationMeta,
|
|
954
|
+
title: name,
|
|
955
|
+
key: selectedApi,
|
|
956
|
+
implementation_id: id,
|
|
957
|
+
version: appVersion
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
function normalizeActionItem(action) {
|
|
961
|
+
const { name, type, selected_api: selectedApi } = action;
|
|
962
|
+
const [appKey, appVersion] = selectedApi ? splitVersionedKey(selectedApi) : ["", void 0];
|
|
963
|
+
return {
|
|
964
|
+
// Only include the fields we want - explicitly list them
|
|
965
|
+
id: action.id,
|
|
966
|
+
key: action.key,
|
|
967
|
+
description: action.description,
|
|
968
|
+
is_important: action.is_important,
|
|
969
|
+
is_hidden: action.is_hidden,
|
|
970
|
+
// Transformed fields
|
|
971
|
+
app_key: appKey,
|
|
972
|
+
app_version: appVersion,
|
|
973
|
+
action_type: type,
|
|
974
|
+
title: name,
|
|
975
|
+
// Map name to title
|
|
976
|
+
type: "action"
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
function isSlug(slug) {
|
|
980
|
+
return !!slug.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
|
|
981
|
+
}
|
|
982
|
+
function isSnakeCasedSlug(slug) {
|
|
983
|
+
if (slug.match(/^_[0-9]/)) {
|
|
984
|
+
slug = slug.slice(1);
|
|
985
|
+
}
|
|
986
|
+
return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
|
|
987
|
+
}
|
|
988
|
+
function dashifySnakeCasedSlug(slug) {
|
|
989
|
+
if (!isSnakeCasedSlug(slug)) {
|
|
990
|
+
return slug;
|
|
991
|
+
}
|
|
992
|
+
if (slug.startsWith("_")) {
|
|
993
|
+
slug = slug.slice(1);
|
|
994
|
+
}
|
|
995
|
+
return slug.replace(/_/g, "-");
|
|
996
|
+
}
|
|
997
|
+
function isUuid(appKey) {
|
|
998
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
|
999
|
+
appKey
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
function toAppLocator(appKey) {
|
|
1003
|
+
const [appKeyWithoutVersion, version] = splitVersionedKey(appKey);
|
|
1004
|
+
if (isUuid(appKeyWithoutVersion)) {
|
|
1005
|
+
throw new Error(
|
|
1006
|
+
`UUID app keys are not supported. Use app slug or implementation ID instead of: ${appKey}`
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
const slug = isSlug(appKeyWithoutVersion) ? appKeyWithoutVersion : isSnakeCasedSlug(appKeyWithoutVersion) ? dashifySnakeCasedSlug(appKeyWithoutVersion) : void 0;
|
|
1010
|
+
return {
|
|
1011
|
+
lookupAppKey: appKeyWithoutVersion,
|
|
1012
|
+
slug,
|
|
1013
|
+
implementationName: slug ? void 0 : appKeyWithoutVersion,
|
|
1014
|
+
version
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
function isResolvedAppLocator(appLocator) {
|
|
1018
|
+
return !!appLocator.implementationName;
|
|
1019
|
+
}
|
|
1020
|
+
var ListActionsSchema = z.object({
|
|
1021
|
+
appKey: AppKeyPropertySchema.describe(
|
|
1022
|
+
"App key of actions to list (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
1023
|
+
),
|
|
1024
|
+
actionType: ActionTypePropertySchema.optional().describe(
|
|
1025
|
+
"Filter actions by type"
|
|
885
1026
|
),
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
cursor: z.string().optional().describe("
|
|
889
|
-
}).
|
|
890
|
-
// Normalize implementationIds to array
|
|
891
|
-
implementationIds: typeof data.implementationIds === "string" ? data.implementationIds === "" ? [] : data.implementationIds.split(",") : data.implementationIds ?? [],
|
|
892
|
-
search: data.search,
|
|
893
|
-
// Normalize pageSize to number
|
|
894
|
-
pageSize: typeof data.pageSize === "string" ? parseInt(data.pageSize, 10) : data.pageSize,
|
|
895
|
-
cursor: data.cursor
|
|
896
|
-
}));
|
|
1027
|
+
pageSize: z.number().min(1).optional().describe("Number of actions per page"),
|
|
1028
|
+
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
1029
|
+
cursor: z.string().optional().describe("Cursor to start from")
|
|
1030
|
+
}).merge(TelemetryMarkerSchema).describe("List all actions for a specific app");
|
|
897
1031
|
var NeedChoicesSchema = z.object({
|
|
898
1032
|
key: z.string().optional(),
|
|
899
1033
|
label: z.string().optional(),
|
|
@@ -1082,394 +1216,116 @@ z.object({
|
|
|
1082
1216
|
internal_id: z.string(),
|
|
1083
1217
|
invite_url: z.string().nullable().optional(),
|
|
1084
1218
|
is_beta: z.string().optional(),
|
|
1085
|
-
is_built_in: z.string().optional(),
|
|
1086
|
-
is_featured: z.string().optional(),
|
|
1087
|
-
is_premium: z.boolean().optional(),
|
|
1088
|
-
is_public: z.string().optional(),
|
|
1089
|
-
is_upcoming: z.string().optional(),
|
|
1090
|
-
learn_more_url: z.string(),
|
|
1091
|
-
name: z.string(),
|
|
1092
|
-
popularity: z.number(),
|
|
1093
|
-
primary_color: z.string(),
|
|
1094
|
-
request_count: z.string().optional(),
|
|
1095
|
-
slug: z.string(),
|
|
1096
|
-
zap_usage_count: z.number().nullable().optional()
|
|
1097
|
-
});
|
|
1098
|
-
var ServiceSchema = z.object({
|
|
1099
|
-
id: z.number().optional(),
|
|
1100
|
-
canonical_id: z.string().optional(),
|
|
1101
|
-
current_implementation_id: z.string(),
|
|
1102
|
-
name: z.string(),
|
|
1103
|
-
slug: z.string(),
|
|
1104
|
-
app_url: z.string().optional(),
|
|
1105
|
-
learn_more_url: z.string().optional(),
|
|
1106
|
-
description: z.string(),
|
|
1107
|
-
primary_color: z.string(),
|
|
1108
|
-
popularity: z.number(),
|
|
1109
|
-
image: z.string().optional(),
|
|
1110
|
-
images: z.string().optional()
|
|
1111
|
-
});
|
|
1112
|
-
z.object({
|
|
1113
|
-
results: z.array(ServiceSchema),
|
|
1114
|
-
next: z.string().nullable().optional(),
|
|
1115
|
-
previous: z.string().nullable().optional()
|
|
1116
|
-
});
|
|
1117
|
-
z.object({
|
|
1118
|
-
selected_api: z.string(),
|
|
1119
|
-
action: z.string(),
|
|
1120
|
-
type_of: z.string(),
|
|
1121
|
-
authentication_id: z.number().optional(),
|
|
1122
|
-
params: z.record(z.string(), z.unknown()).optional()
|
|
1123
|
-
});
|
|
1124
|
-
z.object({
|
|
1125
|
-
success: z.boolean(),
|
|
1126
|
-
needs: z.array(NeedSchema).optional(),
|
|
1127
|
-
errors: z.array(z.string()).optional(),
|
|
1128
|
-
last_fetched_at: z.string().optional(),
|
|
1129
|
-
schema: z.record(z.string(), z.unknown()).optional()
|
|
1130
|
-
});
|
|
1131
|
-
var ImplementationSchema = z.object({
|
|
1132
|
-
selected_api: z.string(),
|
|
1133
|
-
app_id: z.number().optional(),
|
|
1134
|
-
auth_type: z.string().optional(),
|
|
1135
|
-
auth_fields: z.string().optional(),
|
|
1136
|
-
actions: z.array(ActionSchema).optional(),
|
|
1137
|
-
is_deprecated: z.boolean().optional(),
|
|
1138
|
-
is_private_only: z.boolean().optional(),
|
|
1139
|
-
is_invite_only: z.boolean().optional(),
|
|
1140
|
-
is_beta: z.boolean().optional().default(false),
|
|
1141
|
-
is_premium: z.boolean().optional().default(false),
|
|
1142
|
-
is_hidden: z.string().optional(),
|
|
1143
|
-
name: z.string().optional(),
|
|
1144
|
-
slug: z.string().optional(),
|
|
1145
|
-
images: z.record(z.string(), z.string().nullable()).optional(),
|
|
1146
|
-
primary_color: z.string().optional(),
|
|
1147
|
-
secondary_color: z.string().optional(),
|
|
1148
|
-
current_implementation: z.string().optional(),
|
|
1149
|
-
other_implementations: z.string().optional()
|
|
1150
|
-
});
|
|
1151
|
-
z.object({
|
|
1152
|
-
count: z.number(),
|
|
1153
|
-
next: z.string().nullable().optional(),
|
|
1154
|
-
previous: z.string().nullable().optional(),
|
|
1155
|
-
results: z.array(ImplementationSchema)
|
|
1156
|
-
});
|
|
1157
|
-
var
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
id: z.number(),
|
|
1168
|
-
name: z.string(),
|
|
1169
|
-
slug: z.string()
|
|
1170
|
-
})
|
|
1171
|
-
).optional(),
|
|
1172
|
-
images: z.object({
|
|
1173
|
-
url_16x16: z.string().optional(),
|
|
1174
|
-
url_32x32: z.string().optional(),
|
|
1175
|
-
url_64x64: z.string().optional(),
|
|
1176
|
-
url_128x128: z.string().optional()
|
|
1177
|
-
}).optional(),
|
|
1178
|
-
popularity: z.number().optional(),
|
|
1179
|
-
has_filters: z.boolean().optional(),
|
|
1180
|
-
has_reads: z.boolean().optional(),
|
|
1181
|
-
has_searches: z.boolean().optional(),
|
|
1182
|
-
has_searches_or_writes: z.boolean().optional(),
|
|
1183
|
-
has_upfront_fields: z.boolean().optional(),
|
|
1184
|
-
has_writes: z.boolean().optional(),
|
|
1185
|
-
is_beta: z.boolean().optional(),
|
|
1186
|
-
is_built_in: z.boolean().optional(),
|
|
1187
|
-
is_deprecated: z.boolean().optional(),
|
|
1188
|
-
is_featured: z.boolean().optional(),
|
|
1189
|
-
is_hidden: z.boolean().optional(),
|
|
1190
|
-
is_invite: z.boolean().optional(),
|
|
1191
|
-
is_premium: z.boolean().optional(),
|
|
1192
|
-
is_public: z.boolean().optional(),
|
|
1193
|
-
is_upcoming: z.boolean().optional(),
|
|
1194
|
-
version: z.string().optional(),
|
|
1195
|
-
visibility: z.string().optional(),
|
|
1196
|
-
actions: z.object({
|
|
1197
|
-
read: z.number().optional(),
|
|
1198
|
-
read_bulk: z.number().optional(),
|
|
1199
|
-
write: z.number().optional(),
|
|
1200
|
-
search: z.number().optional(),
|
|
1201
|
-
search_or_write: z.number().optional(),
|
|
1202
|
-
search_and_write: z.number().optional(),
|
|
1203
|
-
filter: z.number().optional()
|
|
1204
|
-
}).optional(),
|
|
1205
|
-
description: z.string().optional(),
|
|
1206
|
-
primary_color: z.string().optional(),
|
|
1207
|
-
secondary_color: z.string().optional(),
|
|
1208
|
-
classification: z.string().optional(),
|
|
1209
|
-
api_docs_url: z.string().optional(),
|
|
1210
|
-
image: z.string().optional()
|
|
1211
|
-
});
|
|
1212
|
-
z.object({
|
|
1213
|
-
count: z.number(),
|
|
1214
|
-
next: z.string().nullable().optional(),
|
|
1215
|
-
previous: z.string().nullable().optional(),
|
|
1216
|
-
results: z.array(ImplementationMetaSchema2)
|
|
1217
|
-
});
|
|
1218
|
-
var NeedChoicesResponseMetaSchema = z.object({
|
|
1219
|
-
page: z.string().nullable().optional()
|
|
1220
|
-
});
|
|
1221
|
-
var NeedChoicesResponseLinksSchema = z.object({
|
|
1222
|
-
next: z.string().nullable().optional(),
|
|
1223
|
-
prev: z.string().nullable().optional()
|
|
1224
|
-
});
|
|
1225
|
-
z.object({
|
|
1226
|
-
selected_api: z.string().optional().describe(
|
|
1227
|
-
"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."
|
|
1228
|
-
),
|
|
1229
|
-
authentication_id: z.coerce.number().optional().describe(
|
|
1230
|
-
"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)."
|
|
1231
|
-
),
|
|
1232
|
-
params: z.record(z.string(), z.unknown()).optional().describe(
|
|
1233
|
-
"Object that matches the input the node would normally get. Has all the same keys/types as the `needs` of the action."
|
|
1234
|
-
),
|
|
1235
|
-
page: z.number().optional().default(0),
|
|
1236
|
-
prefill: z.string().optional().describe(
|
|
1237
|
-
"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."
|
|
1238
|
-
),
|
|
1239
|
-
action_id: z.string().optional().describe(
|
|
1240
|
-
"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."
|
|
1241
|
-
),
|
|
1242
|
-
input_field_id: z.string().optional().describe(
|
|
1243
|
-
"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."
|
|
1244
|
-
)
|
|
1245
|
-
});
|
|
1246
|
-
z.object({
|
|
1247
|
-
success: z.boolean(),
|
|
1248
|
-
choices: z.array(NeedChoicesSchema).optional(),
|
|
1249
|
-
next_page: z.number().optional(),
|
|
1250
|
-
errors: z.array(z.string()).optional(),
|
|
1251
|
-
meta: NeedChoicesResponseMetaSchema.optional(),
|
|
1252
|
-
links: NeedChoicesResponseLinksSchema.optional()
|
|
1253
|
-
});
|
|
1254
|
-
|
|
1255
|
-
// src/utils/string-utils.ts
|
|
1256
|
-
function toTitleCase(input) {
|
|
1257
|
-
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(" ");
|
|
1258
|
-
}
|
|
1259
|
-
function toSnakeCase(input) {
|
|
1260
|
-
let result = input.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s\-]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
1261
|
-
if (/^[0-9]/.test(result)) {
|
|
1262
|
-
result = "_" + result;
|
|
1263
|
-
}
|
|
1264
|
-
return result;
|
|
1265
|
-
}
|
|
1266
|
-
function stripPageSuffix(functionName) {
|
|
1267
|
-
return functionName.replace(/Page$/, "");
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
// src/schemas/App.ts
|
|
1271
|
-
var AppItemSchema2 = withFormatter(
|
|
1272
|
-
ImplementationMetaSchema2.omit({ name: true, id: true }).extend({
|
|
1273
|
-
title: z.string(),
|
|
1274
|
-
// Mapped from name
|
|
1275
|
-
key: z.string(),
|
|
1276
|
-
// Extracted from id (base part without version)
|
|
1277
|
-
implementation_id: z.string()
|
|
1278
|
-
// Mapped from id (full versioned ID)
|
|
1279
|
-
}),
|
|
1280
|
-
{
|
|
1281
|
-
format: (item) => {
|
|
1282
|
-
const additionalKeys = [];
|
|
1283
|
-
if (item.slug && item.slug !== item.key) {
|
|
1284
|
-
additionalKeys.push(item.slug);
|
|
1285
|
-
const snakeCaseSlug = toSnakeCase(item.slug);
|
|
1286
|
-
if (snakeCaseSlug !== item.slug && snakeCaseSlug !== item.key) {
|
|
1287
|
-
additionalKeys.push(snakeCaseSlug);
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
return {
|
|
1291
|
-
title: item.title,
|
|
1292
|
-
key: item.key,
|
|
1293
|
-
keys: [item.key, ...additionalKeys],
|
|
1294
|
-
description: item.description,
|
|
1295
|
-
details: []
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
);
|
|
1300
|
-
|
|
1301
|
-
// src/utils/telemetry-utils.ts
|
|
1302
|
-
function createTelemetryCallback(emitMethodCalled, methodName) {
|
|
1303
|
-
return {
|
|
1304
|
-
onMethodCalled: (data) => {
|
|
1305
|
-
emitMethodCalled({
|
|
1306
|
-
method_name: methodName,
|
|
1307
|
-
execution_duration_ms: data.durationMs,
|
|
1308
|
-
success_flag: data.success,
|
|
1309
|
-
error_message: data.error?.message ?? null,
|
|
1310
|
-
error_type: data.error?.constructor.name ?? null,
|
|
1311
|
-
argument_count: data.argumentCount,
|
|
1312
|
-
is_paginated: data.isPaginated
|
|
1313
|
-
});
|
|
1314
|
-
}
|
|
1315
|
-
};
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
// src/plugins/listApps/index.ts
|
|
1319
|
-
var listAppsPlugin = ({ context }) => {
|
|
1320
|
-
async function listAppsPage(options) {
|
|
1321
|
-
const { api, resolveAppKeys: resolveAppKeys2 } = context;
|
|
1322
|
-
const appKeys = options.appKeys ?? [];
|
|
1323
|
-
const appLocators = await resolveAppKeys2({
|
|
1324
|
-
appKeys: [...appKeys]
|
|
1325
|
-
});
|
|
1326
|
-
const implementationNameToLocator = {};
|
|
1327
|
-
for (const locator of appLocators) {
|
|
1328
|
-
implementationNameToLocator[locator.implementationName] = [
|
|
1329
|
-
...implementationNameToLocator[locator.implementationName] ?? [],
|
|
1330
|
-
locator
|
|
1331
|
-
];
|
|
1332
|
-
}
|
|
1333
|
-
const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
|
|
1334
|
-
if (duplicatedLookupAppKeys.length > 0) {
|
|
1335
|
-
throw new Error(
|
|
1336
|
-
`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
|
|
1337
|
-
);
|
|
1338
|
-
}
|
|
1339
|
-
if (appKeys.length > 0 && appLocators.length === 0 && !options.search) {
|
|
1340
|
-
return {
|
|
1341
|
-
data: [],
|
|
1342
|
-
nextCursor: void 0
|
|
1343
|
-
};
|
|
1344
|
-
}
|
|
1345
|
-
const implementationIds = appLocators.map((locator) => {
|
|
1346
|
-
const version = locator.version || "latest";
|
|
1347
|
-
return `${locator.implementationName}@${version}`;
|
|
1348
|
-
});
|
|
1349
|
-
return await api.get("/api/v0/apps", {
|
|
1350
|
-
searchParams: {
|
|
1351
|
-
implementationIds: implementationIds.join(","),
|
|
1352
|
-
...options.search && { search: options.search },
|
|
1353
|
-
pageSize: options.pageSize.toString(),
|
|
1354
|
-
...options.cursor && { cursor: options.cursor }
|
|
1355
|
-
}
|
|
1356
|
-
});
|
|
1357
|
-
}
|
|
1358
|
-
const methodName = stripPageSuffix(listAppsPage.name);
|
|
1359
|
-
const listAppsDefinition = createPaginatedFunction(
|
|
1360
|
-
listAppsPage,
|
|
1361
|
-
ListAppsOptionsSchema,
|
|
1362
|
-
createTelemetryCallback(context.eventEmission.emitMethodCalled, methodName),
|
|
1363
|
-
methodName
|
|
1364
|
-
);
|
|
1365
|
-
return {
|
|
1366
|
-
listApps: listAppsDefinition,
|
|
1367
|
-
context: {
|
|
1368
|
-
meta: {
|
|
1369
|
-
listApps: {
|
|
1370
|
-
categories: ["app"],
|
|
1371
|
-
type: "list",
|
|
1372
|
-
itemType: "App",
|
|
1373
|
-
inputSchema: ListAppsOptionsSchema,
|
|
1374
|
-
outputSchema: AppItemSchema2
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
};
|
|
1379
|
-
};
|
|
1380
|
-
|
|
1381
|
-
// src/utils/domain-utils.ts
|
|
1382
|
-
function splitVersionedKey(versionedKey) {
|
|
1383
|
-
const parts = versionedKey.split("@");
|
|
1384
|
-
if (parts.length >= 2) {
|
|
1385
|
-
const baseKey = parts[0];
|
|
1386
|
-
const version = parts.slice(1).join("@");
|
|
1387
|
-
return [baseKey, version];
|
|
1388
|
-
}
|
|
1389
|
-
return [versionedKey, void 0];
|
|
1390
|
-
}
|
|
1391
|
-
function normalizeImplementationMetaToAppItem(implementationMeta) {
|
|
1392
|
-
const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
|
|
1393
|
-
const { id, name, ...restOfImplementationMeta } = implementationMeta;
|
|
1394
|
-
return {
|
|
1395
|
-
...restOfImplementationMeta,
|
|
1396
|
-
title: name,
|
|
1397
|
-
key: selectedApi,
|
|
1398
|
-
implementation_id: id,
|
|
1399
|
-
version: appVersion
|
|
1400
|
-
};
|
|
1401
|
-
}
|
|
1402
|
-
function normalizeActionItem(action) {
|
|
1403
|
-
const { name, type, selected_api: selectedApi } = action;
|
|
1404
|
-
const [appKey, appVersion] = selectedApi ? splitVersionedKey(selectedApi) : ["", void 0];
|
|
1405
|
-
return {
|
|
1406
|
-
// Only include the fields we want - explicitly list them
|
|
1407
|
-
id: action.id,
|
|
1408
|
-
key: action.key,
|
|
1409
|
-
description: action.description,
|
|
1410
|
-
is_important: action.is_important,
|
|
1411
|
-
is_hidden: action.is_hidden,
|
|
1412
|
-
// Transformed fields
|
|
1413
|
-
app_key: appKey,
|
|
1414
|
-
app_version: appVersion,
|
|
1415
|
-
action_type: type,
|
|
1416
|
-
title: name,
|
|
1417
|
-
// Map name to title
|
|
1418
|
-
type: "action"
|
|
1419
|
-
};
|
|
1420
|
-
}
|
|
1421
|
-
function isSlug(slug) {
|
|
1422
|
-
return !!slug.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
|
|
1423
|
-
}
|
|
1424
|
-
function isSnakeCasedSlug(slug) {
|
|
1425
|
-
if (slug.match(/^_[0-9]/)) {
|
|
1426
|
-
slug = slug.slice(1);
|
|
1427
|
-
}
|
|
1428
|
-
return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
|
|
1429
|
-
}
|
|
1430
|
-
function dashifySnakeCasedSlug(slug) {
|
|
1431
|
-
if (!isSnakeCasedSlug(slug)) {
|
|
1432
|
-
return slug;
|
|
1433
|
-
}
|
|
1434
|
-
if (slug.startsWith("_")) {
|
|
1435
|
-
slug = slug.slice(1);
|
|
1436
|
-
}
|
|
1437
|
-
return slug.replace(/_/g, "-");
|
|
1438
|
-
}
|
|
1439
|
-
function isUuid(appKey) {
|
|
1440
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
|
1441
|
-
appKey
|
|
1442
|
-
);
|
|
1443
|
-
}
|
|
1444
|
-
function toAppLocator(appKey) {
|
|
1445
|
-
const [appKeyWithoutVersion, version] = splitVersionedKey(appKey);
|
|
1446
|
-
if (isUuid(appKeyWithoutVersion)) {
|
|
1447
|
-
throw new Error(
|
|
1448
|
-
`UUID app keys are not supported. Use app slug or implementation ID instead of: ${appKey}`
|
|
1449
|
-
);
|
|
1450
|
-
}
|
|
1451
|
-
const slug = isSlug(appKeyWithoutVersion) ? appKeyWithoutVersion : isSnakeCasedSlug(appKeyWithoutVersion) ? dashifySnakeCasedSlug(appKeyWithoutVersion) : void 0;
|
|
1452
|
-
return {
|
|
1453
|
-
lookupAppKey: appKeyWithoutVersion,
|
|
1454
|
-
slug,
|
|
1455
|
-
implementationName: slug ? void 0 : appKeyWithoutVersion,
|
|
1456
|
-
version
|
|
1457
|
-
};
|
|
1458
|
-
}
|
|
1459
|
-
function isResolvedAppLocator(appLocator) {
|
|
1460
|
-
return !!appLocator.implementationName;
|
|
1461
|
-
}
|
|
1462
|
-
var ListActionsSchema = z.object({
|
|
1463
|
-
appKey: AppKeyPropertySchema.describe(
|
|
1464
|
-
"App key of actions to list (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
1219
|
+
is_built_in: z.string().optional(),
|
|
1220
|
+
is_featured: z.string().optional(),
|
|
1221
|
+
is_premium: z.boolean().optional(),
|
|
1222
|
+
is_public: z.string().optional(),
|
|
1223
|
+
is_upcoming: z.string().optional(),
|
|
1224
|
+
learn_more_url: z.string(),
|
|
1225
|
+
name: z.string(),
|
|
1226
|
+
popularity: z.number(),
|
|
1227
|
+
primary_color: z.string(),
|
|
1228
|
+
request_count: z.string().optional(),
|
|
1229
|
+
slug: z.string(),
|
|
1230
|
+
zap_usage_count: z.number().nullable().optional()
|
|
1231
|
+
});
|
|
1232
|
+
var ServiceSchema = z.object({
|
|
1233
|
+
id: z.number().optional(),
|
|
1234
|
+
canonical_id: z.string().optional(),
|
|
1235
|
+
current_implementation_id: z.string(),
|
|
1236
|
+
name: z.string(),
|
|
1237
|
+
slug: z.string(),
|
|
1238
|
+
app_url: z.string().optional(),
|
|
1239
|
+
learn_more_url: z.string().optional(),
|
|
1240
|
+
description: z.string(),
|
|
1241
|
+
primary_color: z.string(),
|
|
1242
|
+
popularity: z.number(),
|
|
1243
|
+
image: z.string().optional(),
|
|
1244
|
+
images: z.string().optional()
|
|
1245
|
+
});
|
|
1246
|
+
z.object({
|
|
1247
|
+
results: z.array(ServiceSchema),
|
|
1248
|
+
next: z.string().nullable().optional(),
|
|
1249
|
+
previous: z.string().nullable().optional()
|
|
1250
|
+
});
|
|
1251
|
+
z.object({
|
|
1252
|
+
selected_api: z.string(),
|
|
1253
|
+
action: z.string(),
|
|
1254
|
+
type_of: z.string(),
|
|
1255
|
+
authentication_id: z.number().optional(),
|
|
1256
|
+
params: z.record(z.string(), z.unknown()).optional()
|
|
1257
|
+
});
|
|
1258
|
+
z.object({
|
|
1259
|
+
success: z.boolean(),
|
|
1260
|
+
needs: z.array(NeedSchema).optional(),
|
|
1261
|
+
errors: z.array(z.string()).optional(),
|
|
1262
|
+
last_fetched_at: z.string().optional(),
|
|
1263
|
+
schema: z.record(z.string(), z.unknown()).optional()
|
|
1264
|
+
});
|
|
1265
|
+
var ImplementationSchema = z.object({
|
|
1266
|
+
selected_api: z.string(),
|
|
1267
|
+
app_id: z.number().optional(),
|
|
1268
|
+
auth_type: z.string().optional(),
|
|
1269
|
+
auth_fields: z.string().optional(),
|
|
1270
|
+
actions: z.array(ActionSchema).optional(),
|
|
1271
|
+
is_deprecated: z.boolean().optional(),
|
|
1272
|
+
is_private_only: z.boolean().optional(),
|
|
1273
|
+
is_invite_only: z.boolean().optional(),
|
|
1274
|
+
is_beta: z.boolean().optional().default(false),
|
|
1275
|
+
is_premium: z.boolean().optional().default(false),
|
|
1276
|
+
is_hidden: z.string().optional(),
|
|
1277
|
+
name: z.string().optional(),
|
|
1278
|
+
slug: z.string().optional(),
|
|
1279
|
+
images: z.record(z.string(), z.string().nullable()).optional(),
|
|
1280
|
+
primary_color: z.string().optional(),
|
|
1281
|
+
secondary_color: z.string().optional(),
|
|
1282
|
+
current_implementation: z.string().optional(),
|
|
1283
|
+
other_implementations: z.string().optional()
|
|
1284
|
+
});
|
|
1285
|
+
z.object({
|
|
1286
|
+
count: z.number(),
|
|
1287
|
+
next: z.string().nullable().optional(),
|
|
1288
|
+
previous: z.string().nullable().optional(),
|
|
1289
|
+
results: z.array(ImplementationSchema)
|
|
1290
|
+
});
|
|
1291
|
+
var NeedChoicesResponseMetaSchema = z.object({
|
|
1292
|
+
page: z.string().nullable().optional()
|
|
1293
|
+
});
|
|
1294
|
+
var NeedChoicesResponseLinksSchema = z.object({
|
|
1295
|
+
next: z.string().nullable().optional(),
|
|
1296
|
+
prev: z.string().nullable().optional()
|
|
1297
|
+
});
|
|
1298
|
+
z.object({
|
|
1299
|
+
selected_api: z.string().optional().describe(
|
|
1300
|
+
"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."
|
|
1465
1301
|
),
|
|
1466
|
-
|
|
1467
|
-
"
|
|
1302
|
+
authentication_id: z.coerce.number().optional().describe(
|
|
1303
|
+
"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)."
|
|
1468
1304
|
),
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1305
|
+
params: z.record(z.string(), z.unknown()).optional().describe(
|
|
1306
|
+
"Object that matches the input the node would normally get. Has all the same keys/types as the `needs` of the action."
|
|
1307
|
+
),
|
|
1308
|
+
page: z.number().optional().default(0),
|
|
1309
|
+
prefill: z.string().optional().describe(
|
|
1310
|
+
"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."
|
|
1311
|
+
),
|
|
1312
|
+
action_id: z.string().optional().describe(
|
|
1313
|
+
"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."
|
|
1314
|
+
),
|
|
1315
|
+
input_field_id: z.string().optional().describe(
|
|
1316
|
+
"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."
|
|
1317
|
+
)
|
|
1318
|
+
});
|
|
1319
|
+
z.object({
|
|
1320
|
+
success: z.boolean(),
|
|
1321
|
+
choices: z.array(NeedChoicesSchema).optional(),
|
|
1322
|
+
next_page: z.number().optional(),
|
|
1323
|
+
errors: z.array(z.string()).optional(),
|
|
1324
|
+
meta: NeedChoicesResponseMetaSchema.optional(),
|
|
1325
|
+
links: NeedChoicesResponseLinksSchema.optional()
|
|
1326
|
+
});
|
|
1327
|
+
|
|
1328
|
+
// src/schemas/Action.ts
|
|
1473
1329
|
var ActionItemSchema = withFormatter(
|
|
1474
1330
|
ActionSchema.omit({ type: true, name: true, selected_api: true }).extend({
|
|
1475
1331
|
app_key: z.string(),
|
|
@@ -2330,7 +2186,7 @@ var getAppPlugin = ({ sdk, context }) => {
|
|
|
2330
2186
|
type: "item",
|
|
2331
2187
|
itemType: "App",
|
|
2332
2188
|
inputSchema: GetAppSchema,
|
|
2333
|
-
outputSchema:
|
|
2189
|
+
outputSchema: AppItemSchema,
|
|
2334
2190
|
resolvers: {
|
|
2335
2191
|
appKey: appKeyResolver
|
|
2336
2192
|
}
|
|
@@ -3595,36 +3451,29 @@ async function pollUntilComplete(options) {
|
|
|
3595
3451
|
}
|
|
3596
3452
|
}
|
|
3597
3453
|
|
|
3598
|
-
// src/
|
|
3599
|
-
function
|
|
3600
|
-
return
|
|
3454
|
+
// src/types/credentials.ts
|
|
3455
|
+
function isClientCredentials(credentials) {
|
|
3456
|
+
return typeof credentials === "object" && credentials !== null && "clientId" in credentials && "clientSecret" in credentials;
|
|
3601
3457
|
}
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
const { getToken } = await import('@zapier/zapier-sdk-cli-login');
|
|
3605
|
-
return await getToken(options);
|
|
3606
|
-
} catch {
|
|
3607
|
-
return void 0;
|
|
3608
|
-
}
|
|
3458
|
+
function isPkceCredentials(credentials) {
|
|
3459
|
+
return typeof credentials === "object" && credentials !== null && "clientId" in credentials && !("clientSecret" in credentials);
|
|
3609
3460
|
}
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
if (envToken) {
|
|
3613
|
-
return envToken;
|
|
3614
|
-
}
|
|
3615
|
-
return getTokenFromCliLogin(options);
|
|
3461
|
+
function isCredentialsObject(credentials) {
|
|
3462
|
+
return typeof credentials === "object" && credentials !== null && "clientId" in credentials;
|
|
3616
3463
|
}
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
}
|
|
3627
|
-
|
|
3464
|
+
function isCredentialsFunction(credentials) {
|
|
3465
|
+
return typeof credentials === "function";
|
|
3466
|
+
}
|
|
3467
|
+
|
|
3468
|
+
// src/utils/logging.ts
|
|
3469
|
+
var loggedDeprecations = /* @__PURE__ */ new Set();
|
|
3470
|
+
function logDeprecation(message) {
|
|
3471
|
+
if (loggedDeprecations.has(message)) return;
|
|
3472
|
+
loggedDeprecations.add(message);
|
|
3473
|
+
console.warn(`[zapier-sdk] Deprecation: ${message}`);
|
|
3474
|
+
}
|
|
3475
|
+
function resetDeprecationWarnings() {
|
|
3476
|
+
loggedDeprecations.clear();
|
|
3628
3477
|
}
|
|
3629
3478
|
|
|
3630
3479
|
// src/utils/url-utils.ts
|
|
@@ -3673,174 +3522,276 @@ function getTrackingBaseUrl({
|
|
|
3673
3522
|
return ZAPIER_BASE_URL;
|
|
3674
3523
|
}
|
|
3675
3524
|
|
|
3676
|
-
// src/
|
|
3677
|
-
function
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
const baseKey = parts[0];
|
|
3681
|
-
const version = parts.slice(1).join("@");
|
|
3682
|
-
return [baseKey, version];
|
|
3683
|
-
}
|
|
3684
|
-
return [versionedKey, void 0];
|
|
3525
|
+
// src/credentials.ts
|
|
3526
|
+
function deriveAuthBaseUrl(sdkBaseUrl) {
|
|
3527
|
+
if (!sdkBaseUrl) return void 0;
|
|
3528
|
+
return getZapierBaseUrl(sdkBaseUrl);
|
|
3685
3529
|
}
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3530
|
+
function normalizeCredentialsObject(obj, sdkBaseUrl) {
|
|
3531
|
+
const resolvedBaseUrl = obj.baseUrl || deriveAuthBaseUrl(sdkBaseUrl);
|
|
3532
|
+
if (obj.type === "client_credentials" || "clientSecret" in obj && obj.clientSecret) {
|
|
3533
|
+
return {
|
|
3534
|
+
type: "client_credentials",
|
|
3535
|
+
clientId: obj.clientId,
|
|
3536
|
+
clientSecret: obj.clientSecret,
|
|
3537
|
+
baseUrl: resolvedBaseUrl,
|
|
3538
|
+
scope: obj.scope
|
|
3539
|
+
};
|
|
3540
|
+
}
|
|
3691
3541
|
return {
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
version: appVersion
|
|
3542
|
+
type: "pkce",
|
|
3543
|
+
clientId: obj.clientId,
|
|
3544
|
+
baseUrl: resolvedBaseUrl,
|
|
3545
|
+
scope: obj.scope
|
|
3697
3546
|
};
|
|
3698
3547
|
}
|
|
3699
|
-
function
|
|
3700
|
-
if (
|
|
3701
|
-
return
|
|
3702
|
-
}
|
|
3703
|
-
try {
|
|
3704
|
-
const url = new URL(response.next);
|
|
3705
|
-
const offset = url.searchParams.get("offset");
|
|
3706
|
-
return offset || void 0;
|
|
3707
|
-
} catch {
|
|
3708
|
-
return void 0;
|
|
3548
|
+
function resolveCredentialsFromEnv(sdkBaseUrl) {
|
|
3549
|
+
if (ZAPIER_CREDENTIALS) {
|
|
3550
|
+
return ZAPIER_CREDENTIALS;
|
|
3709
3551
|
}
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
const [implementationName] = splitVersionedKey2(result.id);
|
|
3728
|
-
const isPublic = result.visibility === "public";
|
|
3729
|
-
const existing = byImplementationName.get(implementationName);
|
|
3730
|
-
if (!existing || isPublic && !existing.isPublic) {
|
|
3731
|
-
byImplementationName.set(implementationName, { result, isPublic });
|
|
3552
|
+
if (ZAPIER_CREDENTIALS_CLIENT_ID) {
|
|
3553
|
+
const resolvedBaseUrl = ZAPIER_CREDENTIALS_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
|
|
3554
|
+
if (ZAPIER_CREDENTIALS_CLIENT_SECRET) {
|
|
3555
|
+
return {
|
|
3556
|
+
type: "client_credentials",
|
|
3557
|
+
clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
|
|
3558
|
+
clientSecret: ZAPIER_CREDENTIALS_CLIENT_SECRET,
|
|
3559
|
+
baseUrl: resolvedBaseUrl,
|
|
3560
|
+
scope: ZAPIER_CREDENTIALS_SCOPE
|
|
3561
|
+
};
|
|
3562
|
+
} else {
|
|
3563
|
+
return {
|
|
3564
|
+
type: "pkce",
|
|
3565
|
+
clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
|
|
3566
|
+
baseUrl: resolvedBaseUrl,
|
|
3567
|
+
scope: ZAPIER_CREDENTIALS_SCOPE
|
|
3568
|
+
};
|
|
3732
3569
|
}
|
|
3733
3570
|
}
|
|
3734
|
-
|
|
3735
|
-
(
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
additionalIds.push(result.implementation_id);
|
|
3571
|
+
if (ZAPIER_TOKEN) {
|
|
3572
|
+
logDeprecation(
|
|
3573
|
+
"ZAPIER_TOKEN is deprecated. Use ZAPIER_CREDENTIALS instead."
|
|
3574
|
+
);
|
|
3575
|
+
return ZAPIER_TOKEN;
|
|
3576
|
+
}
|
|
3577
|
+
if (ZAPIER_AUTH_CLIENT_ID) {
|
|
3578
|
+
logDeprecation(
|
|
3579
|
+
"ZAPIER_AUTH_CLIENT_ID is deprecated. Use ZAPIER_CREDENTIALS_CLIENT_ID instead."
|
|
3580
|
+
);
|
|
3581
|
+
if (ZAPIER_AUTH_BASE_URL) {
|
|
3582
|
+
logDeprecation(
|
|
3583
|
+
"ZAPIER_AUTH_BASE_URL is deprecated. Use ZAPIER_CREDENTIALS_BASE_URL instead."
|
|
3584
|
+
);
|
|
3749
3585
|
}
|
|
3586
|
+
const resolvedBaseUrl = ZAPIER_AUTH_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
|
|
3587
|
+
return {
|
|
3588
|
+
type: "pkce",
|
|
3589
|
+
clientId: ZAPIER_AUTH_CLIENT_ID,
|
|
3590
|
+
baseUrl: resolvedBaseUrl
|
|
3591
|
+
};
|
|
3750
3592
|
}
|
|
3751
|
-
return
|
|
3593
|
+
return void 0;
|
|
3752
3594
|
}
|
|
3753
|
-
|
|
3754
|
-
const
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
return {
|
|
3768
|
-
data: [],
|
|
3769
|
-
nextCursor: void 0
|
|
3770
|
-
};
|
|
3595
|
+
async function resolveCredentials(options = {}) {
|
|
3596
|
+
const { baseUrl } = options;
|
|
3597
|
+
if (options.credentials !== void 0) {
|
|
3598
|
+
if (isCredentialsFunction(options.credentials)) {
|
|
3599
|
+
const resolved = await options.credentials();
|
|
3600
|
+
if (typeof resolved === "function") {
|
|
3601
|
+
throw new Error(
|
|
3602
|
+
"Credentials function returned another function. Credentials functions must return a string or credentials object."
|
|
3603
|
+
);
|
|
3604
|
+
}
|
|
3605
|
+
if (isCredentialsObject(resolved)) {
|
|
3606
|
+
return normalizeCredentialsObject(resolved, baseUrl);
|
|
3607
|
+
}
|
|
3608
|
+
return resolved;
|
|
3771
3609
|
}
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
selected_apis: "",
|
|
3775
|
-
limit: pageSize.toString()
|
|
3776
|
-
};
|
|
3777
|
-
if (validatedRequest.cursor) {
|
|
3778
|
-
searchParams2.offset = validatedRequest.cursor;
|
|
3610
|
+
if (isCredentialsObject(options.credentials)) {
|
|
3611
|
+
return normalizeCredentialsObject(options.credentials, baseUrl);
|
|
3779
3612
|
}
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3613
|
+
return options.credentials;
|
|
3614
|
+
}
|
|
3615
|
+
if (options.token !== void 0) {
|
|
3616
|
+
logDeprecation(
|
|
3617
|
+
"The `token` option is deprecated. Use `credentials` instead."
|
|
3785
3618
|
);
|
|
3786
|
-
return
|
|
3787
|
-
data: implementationsResponse2.results.map(
|
|
3788
|
-
transformImplementationMetaToAppItem
|
|
3789
|
-
),
|
|
3790
|
-
nextCursor: extractPaginationCursor(implementationsResponse2)
|
|
3791
|
-
};
|
|
3619
|
+
return options.token;
|
|
3792
3620
|
}
|
|
3793
|
-
const
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
};
|
|
3797
|
-
if (validatedRequest.cursor) {
|
|
3798
|
-
searchParams.offset = validatedRequest.cursor;
|
|
3621
|
+
const envCredentials = resolveCredentialsFromEnv(baseUrl);
|
|
3622
|
+
if (envCredentials !== void 0) {
|
|
3623
|
+
return envCredentials;
|
|
3799
3624
|
}
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
return
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
}
|
|
3812
|
-
|
|
3625
|
+
return void 0;
|
|
3626
|
+
}
|
|
3627
|
+
function getBaseUrlFromCredentials(credentials) {
|
|
3628
|
+
if (credentials && isCredentialsObject(credentials)) {
|
|
3629
|
+
return credentials.baseUrl;
|
|
3630
|
+
}
|
|
3631
|
+
return void 0;
|
|
3632
|
+
}
|
|
3633
|
+
function getClientIdFromCredentials(credentials) {
|
|
3634
|
+
if (credentials && isCredentialsObject(credentials)) {
|
|
3635
|
+
return credentials.clientId;
|
|
3636
|
+
}
|
|
3637
|
+
return void 0;
|
|
3638
|
+
}
|
|
3813
3639
|
|
|
3814
|
-
// src/
|
|
3815
|
-
var
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3640
|
+
// src/auth.ts
|
|
3641
|
+
var tokenCache = /* @__PURE__ */ new Map();
|
|
3642
|
+
var pendingExchanges = /* @__PURE__ */ new Map();
|
|
3643
|
+
function clearTokenCache() {
|
|
3644
|
+
tokenCache.clear();
|
|
3645
|
+
pendingExchanges.clear();
|
|
3646
|
+
}
|
|
3647
|
+
var TOKEN_EXPIRATION_BUFFER = 5 * 60 * 1e3;
|
|
3648
|
+
function getCachedToken(clientId) {
|
|
3649
|
+
const cached = tokenCache.get(clientId);
|
|
3650
|
+
if (!cached) return void 0;
|
|
3651
|
+
if (cached.expiresAt > Date.now() + TOKEN_EXPIRATION_BUFFER) {
|
|
3652
|
+
return cached.accessToken;
|
|
3653
|
+
}
|
|
3654
|
+
tokenCache.delete(clientId);
|
|
3655
|
+
return void 0;
|
|
3656
|
+
}
|
|
3657
|
+
function cacheToken(clientId, accessToken, expiresIn) {
|
|
3658
|
+
tokenCache.set(clientId, {
|
|
3659
|
+
accessToken,
|
|
3660
|
+
expiresAt: Date.now() + expiresIn * 1e3
|
|
3661
|
+
});
|
|
3662
|
+
}
|
|
3663
|
+
function invalidateCachedToken(clientId) {
|
|
3664
|
+
tokenCache.delete(clientId);
|
|
3665
|
+
}
|
|
3666
|
+
function getTokenEndpointUrl(baseUrl) {
|
|
3667
|
+
const base = baseUrl || ZAPIER_BASE_URL;
|
|
3668
|
+
return `${base}/oauth/token/`;
|
|
3669
|
+
}
|
|
3670
|
+
async function exchangeClientCredentials(options) {
|
|
3671
|
+
const { clientId, clientSecret, baseUrl, scope, onEvent } = options;
|
|
3672
|
+
const fetchFn = options.fetch || globalThis.fetch;
|
|
3673
|
+
const tokenUrl = getTokenEndpointUrl(baseUrl);
|
|
3674
|
+
onEvent?.({
|
|
3675
|
+
type: "auth_exchanging",
|
|
3676
|
+
payload: {
|
|
3677
|
+
message: "Exchanging client credentials for token...",
|
|
3678
|
+
operation: "client_credentials"
|
|
3679
|
+
},
|
|
3680
|
+
timestamp: Date.now()
|
|
3681
|
+
});
|
|
3682
|
+
const response = await fetchFn(tokenUrl, {
|
|
3683
|
+
method: "POST",
|
|
3684
|
+
headers: {
|
|
3685
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
3686
|
+
},
|
|
3687
|
+
body: new URLSearchParams({
|
|
3688
|
+
grant_type: "client_credentials",
|
|
3689
|
+
client_id: clientId,
|
|
3690
|
+
client_secret: clientSecret,
|
|
3691
|
+
scope: scope || "external",
|
|
3692
|
+
audience: "zapier.com"
|
|
3693
|
+
})
|
|
3694
|
+
});
|
|
3695
|
+
if (!response.ok) {
|
|
3696
|
+
const errorText = await response.text();
|
|
3697
|
+
onEvent?.({
|
|
3698
|
+
type: "auth_error",
|
|
3699
|
+
payload: {
|
|
3700
|
+
message: `Client credentials exchange failed: ${response.status}`,
|
|
3701
|
+
error: errorText,
|
|
3702
|
+
operation: "client_credentials"
|
|
3703
|
+
},
|
|
3704
|
+
timestamp: Date.now()
|
|
3705
|
+
});
|
|
3706
|
+
throw new Error(
|
|
3707
|
+
`Client credentials exchange failed: ${response.status} ${response.statusText}`
|
|
3708
|
+
);
|
|
3821
3709
|
}
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3710
|
+
const data = await response.json();
|
|
3711
|
+
if (!data.access_token) {
|
|
3712
|
+
throw new Error("Client credentials response missing access_token");
|
|
3713
|
+
}
|
|
3714
|
+
const expiresIn = data.expires_in || 3600;
|
|
3715
|
+
cacheToken(clientId, data.access_token, expiresIn);
|
|
3716
|
+
onEvent?.({
|
|
3717
|
+
type: "auth_success",
|
|
3718
|
+
payload: {
|
|
3719
|
+
message: "Client credentials exchange successful",
|
|
3720
|
+
operation: "client_credentials"
|
|
3721
|
+
},
|
|
3722
|
+
timestamp: Date.now()
|
|
3723
|
+
});
|
|
3724
|
+
return data.access_token;
|
|
3725
|
+
}
|
|
3726
|
+
async function getTokenFromCliLogin(options) {
|
|
3727
|
+
try {
|
|
3728
|
+
const cliLogin = await import('@zapier/zapier-sdk-cli-login');
|
|
3729
|
+
return await cliLogin.getToken(options);
|
|
3730
|
+
} catch {
|
|
3731
|
+
return void 0;
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
async function resolveAuthToken(options = {}) {
|
|
3735
|
+
const credentials = await resolveCredentials({
|
|
3736
|
+
credentials: options.credentials,
|
|
3737
|
+
token: options.token
|
|
3738
|
+
});
|
|
3739
|
+
if (credentials !== void 0) {
|
|
3740
|
+
return resolveAuthTokenFromCredentials(credentials, options);
|
|
3741
|
+
}
|
|
3742
|
+
return getTokenFromCliLogin({
|
|
3743
|
+
onEvent: options.onEvent,
|
|
3744
|
+
fetch: options.fetch
|
|
3745
|
+
});
|
|
3746
|
+
}
|
|
3747
|
+
async function resolveAuthTokenFromCredentials(credentials, options) {
|
|
3748
|
+
if (typeof credentials === "string") {
|
|
3749
|
+
return credentials;
|
|
3750
|
+
}
|
|
3751
|
+
if (isClientCredentials(credentials)) {
|
|
3752
|
+
const { clientId } = credentials;
|
|
3753
|
+
const cached = getCachedToken(clientId);
|
|
3754
|
+
if (cached) {
|
|
3755
|
+
return cached;
|
|
3756
|
+
}
|
|
3757
|
+
const pending = pendingExchanges.get(clientId);
|
|
3758
|
+
if (pending) {
|
|
3759
|
+
return pending;
|
|
3760
|
+
}
|
|
3761
|
+
const exchangePromise = exchangeClientCredentials({
|
|
3762
|
+
clientId: credentials.clientId,
|
|
3763
|
+
clientSecret: credentials.clientSecret,
|
|
3764
|
+
baseUrl: credentials.baseUrl || options.baseUrl,
|
|
3765
|
+
scope: credentials.scope,
|
|
3766
|
+
fetch: options.fetch,
|
|
3767
|
+
onEvent: options.onEvent
|
|
3768
|
+
}).finally(() => {
|
|
3769
|
+
pendingExchanges.delete(clientId);
|
|
3770
|
+
});
|
|
3771
|
+
pendingExchanges.set(clientId, exchangePromise);
|
|
3772
|
+
return exchangePromise;
|
|
3773
|
+
}
|
|
3774
|
+
if (isPkceCredentials(credentials)) {
|
|
3775
|
+
const storedToken = await getTokenFromCliLogin({
|
|
3776
|
+
onEvent: options.onEvent,
|
|
3777
|
+
fetch: options.fetch,
|
|
3778
|
+
credentials
|
|
3779
|
+
});
|
|
3780
|
+
if (storedToken) {
|
|
3781
|
+
return storedToken;
|
|
3838
3782
|
}
|
|
3783
|
+
throw new Error(
|
|
3784
|
+
"PKCE credentials require interactive login. Please run the 'login' command with the CLI first, or use client_credentials flow."
|
|
3785
|
+
);
|
|
3839
3786
|
}
|
|
3840
|
-
|
|
3787
|
+
throw new Error("Unknown credentials type");
|
|
3841
3788
|
}
|
|
3842
|
-
function
|
|
3843
|
-
|
|
3789
|
+
async function invalidateCredentialsToken(options) {
|
|
3790
|
+
const resolved = await resolveCredentials(options);
|
|
3791
|
+
const clientId = getClientIdFromCredentials(resolved);
|
|
3792
|
+
if (clientId) {
|
|
3793
|
+
invalidateCachedToken(clientId);
|
|
3794
|
+
}
|
|
3844
3795
|
}
|
|
3845
3796
|
|
|
3846
3797
|
// src/api/client.ts
|
|
@@ -3900,13 +3851,11 @@ var ZapierApiClient = class {
|
|
|
3900
3851
|
// Helper to get a token from the different places it could be gotten
|
|
3901
3852
|
async getAuthToken() {
|
|
3902
3853
|
return resolveAuthToken({
|
|
3854
|
+
credentials: this.options.credentials,
|
|
3903
3855
|
token: this.options.token,
|
|
3904
|
-
getToken: this.options.getToken,
|
|
3905
3856
|
onEvent: this.options.onEvent,
|
|
3906
3857
|
fetch: this.options.fetch,
|
|
3907
|
-
baseUrl: this.options.baseUrl
|
|
3908
|
-
authBaseUrl: this.options.authBaseUrl,
|
|
3909
|
-
authClientId: this.options.authClientId
|
|
3858
|
+
baseUrl: this.options.baseUrl
|
|
3910
3859
|
});
|
|
3911
3860
|
}
|
|
3912
3861
|
// Helper to handle responses
|
|
@@ -3944,10 +3893,16 @@ var ZapierApiClient = class {
|
|
|
3944
3893
|
if (response.status === 401 || response.status === 403) {
|
|
3945
3894
|
if (wasMissingAuthToken) {
|
|
3946
3895
|
throw new ZapierAuthenticationError(
|
|
3947
|
-
`Authentication required (HTTP ${response.status}). Please provide
|
|
3896
|
+
`Authentication required (HTTP ${response.status}). Please provide credentials in options or set ZAPIER_CREDENTIALS environment variable.`,
|
|
3948
3897
|
errorOptions
|
|
3949
3898
|
);
|
|
3950
3899
|
}
|
|
3900
|
+
if (response.status === 401) {
|
|
3901
|
+
await invalidateCredentialsToken({
|
|
3902
|
+
credentials: this.options.credentials,
|
|
3903
|
+
token: this.options.token
|
|
3904
|
+
});
|
|
3905
|
+
}
|
|
3951
3906
|
throw new ZapierAuthenticationError(message, errorOptions);
|
|
3952
3907
|
}
|
|
3953
3908
|
if (response.status === 400) {
|
|
@@ -4083,7 +4038,7 @@ var ZapierApiClient = class {
|
|
|
4083
4038
|
if (options.authRequired) {
|
|
4084
4039
|
if (headers.get("Authorization") == null && authToken == null) {
|
|
4085
4040
|
throw new ZapierAuthenticationError(
|
|
4086
|
-
`Authentication required but no
|
|
4041
|
+
`Authentication required but no credentials available. Please set ZAPIER_CREDENTIALS, or run the 'login' command with the CLI.`
|
|
4087
4042
|
);
|
|
4088
4043
|
}
|
|
4089
4044
|
}
|
|
@@ -4091,20 +4046,6 @@ var ZapierApiClient = class {
|
|
|
4091
4046
|
}
|
|
4092
4047
|
// Helper to perform HTTP requests with JSON handling
|
|
4093
4048
|
async fetchJson(method, path, data, options = {}) {
|
|
4094
|
-
const routeMatch = matchRoute(method, path);
|
|
4095
|
-
if (routeMatch) {
|
|
4096
|
-
const handlerRequest = {
|
|
4097
|
-
...typeof data === "object" ? data : {},
|
|
4098
|
-
...options.searchParams,
|
|
4099
|
-
...routeMatch.params
|
|
4100
|
-
};
|
|
4101
|
-
return routeMatch.handler({
|
|
4102
|
-
request: handlerRequest,
|
|
4103
|
-
deps: {
|
|
4104
|
-
httpClient: this
|
|
4105
|
-
}
|
|
4106
|
-
});
|
|
4107
|
-
}
|
|
4108
4049
|
const headers = { ...options.headers };
|
|
4109
4050
|
if (data && typeof data === "object") {
|
|
4110
4051
|
headers["Content-Type"] = "application/json";
|
|
@@ -4173,27 +4114,28 @@ var apiPlugin = (params) => {
|
|
|
4173
4114
|
const {
|
|
4174
4115
|
fetch: customFetch = globalThis.fetch,
|
|
4175
4116
|
baseUrl = ZAPIER_BASE_URL,
|
|
4176
|
-
|
|
4177
|
-
authClientId,
|
|
4117
|
+
credentials,
|
|
4178
4118
|
token,
|
|
4179
|
-
getToken,
|
|
4180
4119
|
onEvent,
|
|
4181
4120
|
debug = false
|
|
4182
4121
|
} = params.context.options;
|
|
4183
4122
|
const api = createZapierApi({
|
|
4184
4123
|
baseUrl,
|
|
4185
|
-
|
|
4186
|
-
authClientId,
|
|
4124
|
+
credentials,
|
|
4187
4125
|
token,
|
|
4188
|
-
getToken,
|
|
4189
4126
|
debug,
|
|
4190
4127
|
fetch: customFetch,
|
|
4191
4128
|
onEvent
|
|
4192
4129
|
});
|
|
4193
4130
|
return {
|
|
4194
4131
|
context: {
|
|
4195
|
-
api
|
|
4132
|
+
api,
|
|
4196
4133
|
// Provide API client in context for other plugins to use
|
|
4134
|
+
resolveCredentials: () => resolveCredentials({
|
|
4135
|
+
credentials,
|
|
4136
|
+
token,
|
|
4137
|
+
baseUrl
|
|
4138
|
+
})
|
|
4197
4139
|
}
|
|
4198
4140
|
};
|
|
4199
4141
|
};
|
|
@@ -4787,7 +4729,7 @@ function getCpuTime() {
|
|
|
4787
4729
|
|
|
4788
4730
|
// package.json
|
|
4789
4731
|
var package_default = {
|
|
4790
|
-
version: "0.
|
|
4732
|
+
version: "1.0.0"};
|
|
4791
4733
|
|
|
4792
4734
|
// src/plugins/eventEmission/builders.ts
|
|
4793
4735
|
function createBaseEvent(context = {}) {
|
|
@@ -4960,11 +4902,9 @@ var eventEmissionPlugin = ({ context }) => {
|
|
|
4960
4902
|
const getUserContext = (async () => {
|
|
4961
4903
|
try {
|
|
4962
4904
|
const token = await resolveAuthToken({
|
|
4905
|
+
credentials: context.options.credentials,
|
|
4963
4906
|
token: context.options.token,
|
|
4964
|
-
getToken: context.options.getToken,
|
|
4965
4907
|
baseUrl: context.options.baseUrl,
|
|
4966
|
-
authBaseUrl: context.options.authBaseUrl,
|
|
4967
|
-
authClientId: context.options.authClientId,
|
|
4968
4908
|
onEvent: context.options.onEvent,
|
|
4969
4909
|
fetch: context.options.fetch
|
|
4970
4910
|
});
|
|
@@ -5229,4 +5169,4 @@ function createZapierSdk(options = {}) {
|
|
|
5229
5169
|
return createZapierSdkWithoutRegistry(options).addPlugin(registryPlugin);
|
|
5230
5170
|
}
|
|
5231
5171
|
|
|
5232
|
-
export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DEFAULT_CONFIG_PATH, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZAPIER_BASE_URL, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin,
|
|
5172
|
+
export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DEFAULT_CONFIG_PATH, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZAPIER_AUTH_BASE_URL, ZAPIER_AUTH_CLIENT_ID, ZAPIER_BASE_URL, ZAPIER_CREDENTIALS, ZAPIER_CREDENTIALS_BASE_URL, ZAPIER_CREDENTIALS_CLIENT_ID, ZAPIER_CREDENTIALS_CLIENT_SECRET, ZAPIER_CREDENTIALS_SCOPE, ZAPIER_TOKEN, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, clearTokenCache, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getBaseUrlFromCredentials, getCiPlatform, getClientIdFromCredentials, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isClientCredentials, isCredentialsFunction, isCredentialsObject, isPkceCredentials, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, logDeprecation, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, runActionPlugin, toSnakeCase, toTitleCase };
|