@zapier/zapier-sdk 0.9.0 → 0.11.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 +18 -0
- package/README.md +7 -7
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +14 -0
- package/dist/api/debug.d.ts +1 -0
- package/dist/api/debug.d.ts.map +1 -1
- package/dist/api/debug.js +42 -1
- package/dist/api/debug.test.d.ts +2 -0
- package/dist/api/debug.test.d.ts.map +1 -0
- package/dist/api/debug.test.js +59 -0
- package/dist/api/schemas.d.ts +451 -251
- package/dist/api/schemas.d.ts.map +1 -1
- package/dist/api/schemas.js +51 -29
- package/dist/index.cjs +968 -582
- package/dist/index.d.mts +2537 -2229
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.mjs +966 -576
- package/dist/plugins/findFirstAuthentication/index.d.ts +1 -1
- package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.js +9 -1
- package/dist/plugins/findFirstAuthentication/index.test.js +3 -4
- package/dist/plugins/findFirstAuthentication/schemas.d.ts +5 -3
- package/dist/plugins/findFirstAuthentication/schemas.d.ts.map +1 -1
- package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findUniqueAuthentication/index.js +4 -0
- package/dist/plugins/findUniqueAuthentication/schemas.d.ts +5 -3
- package/dist/plugins/findUniqueAuthentication/schemas.d.ts.map +1 -1
- package/dist/plugins/getAction/index.d.ts.map +1 -1
- package/dist/plugins/getAction/index.js +10 -0
- package/dist/plugins/getAction/schemas.d.ts +5 -3
- package/dist/plugins/getAction/schemas.d.ts.map +1 -1
- package/dist/plugins/getApp/index.d.ts.map +1 -1
- package/dist/plugins/getApp/index.js +8 -0
- package/dist/plugins/getApp/index.test.js +2 -2
- package/dist/plugins/getApp/schemas.d.ts +3 -1
- package/dist/plugins/getApp/schemas.d.ts.map +1 -1
- package/dist/plugins/getApp/schemas.js +2 -4
- package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/getAuthentication/index.js +8 -0
- package/dist/plugins/getProfile/index.d.ts.map +1 -1
- package/dist/plugins/getProfile/index.js +4 -0
- package/dist/plugins/getProfile/schemas.d.ts.map +1 -1
- package/dist/plugins/getProfile/schemas.js +4 -3
- package/dist/plugins/listActions/index.d.ts.map +1 -1
- package/dist/plugins/listActions/index.js +9 -0
- package/dist/plugins/listActions/schemas.d.ts +5 -3
- package/dist/plugins/listActions/schemas.d.ts.map +1 -1
- package/dist/plugins/listActions/schemas.js +2 -4
- package/dist/plugins/listApps/index.d.ts.map +1 -1
- package/dist/plugins/listApps/index.js +4 -0
- package/dist/plugins/listApps/index.test.js +1 -1
- package/dist/plugins/listApps/schemas.d.ts.map +1 -1
- package/dist/plugins/listApps/schemas.js +3 -9
- package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
- package/dist/plugins/listAuthentications/index.js +8 -0
- package/dist/plugins/listAuthentications/schemas.d.ts +5 -3
- package/dist/plugins/listAuthentications/schemas.d.ts.map +1 -1
- package/dist/plugins/listInputFieldChoices/index.d.ts.map +1 -1
- package/dist/plugins/listInputFieldChoices/index.js +14 -2
- package/dist/plugins/listInputFieldChoices/schemas.d.ts +5 -3
- package/dist/plugins/listInputFieldChoices/schemas.d.ts.map +1 -1
- package/dist/plugins/listInputFieldChoices/schemas.js +10 -19
- package/dist/plugins/listInputFields/index.d.ts +4 -4
- package/dist/plugins/listInputFields/index.d.ts.map +1 -1
- package/dist/plugins/listInputFields/index.js +71 -5
- package/dist/plugins/listInputFields/index.test.js +5 -9
- package/dist/plugins/listInputFields/schemas.d.ts +8 -6
- package/dist/plugins/listInputFields/schemas.d.ts.map +1 -1
- package/dist/plugins/registry/index.d.ts.map +1 -1
- package/dist/plugins/registry/index.js +8 -2
- package/dist/plugins/request/index.d.ts.map +1 -1
- package/dist/plugins/request/index.js +1 -0
- package/dist/plugins/runAction/index.d.ts.map +1 -1
- package/dist/plugins/runAction/index.js +12 -0
- package/dist/plugins/runAction/schemas.d.ts +5 -3
- package/dist/plugins/runAction/schemas.d.ts.map +1 -1
- package/dist/resolvers/actionKey.d.ts +13 -7
- package/dist/resolvers/actionKey.d.ts.map +1 -1
- package/dist/resolvers/actionType.d.ts +8 -7
- package/dist/resolvers/actionType.d.ts.map +1 -1
- package/dist/resolvers/appKey.d.ts +2 -6
- package/dist/resolvers/appKey.d.ts.map +1 -1
- package/dist/resolvers/authenticationId.d.ts +7 -7
- package/dist/resolvers/authenticationId.d.ts.map +1 -1
- package/dist/resolvers/authenticationId.js +16 -7
- package/dist/resolvers/index.d.ts +3 -35
- package/dist/resolvers/index.d.ts.map +1 -1
- package/dist/resolvers/index.js +4 -87
- package/dist/resolvers/inputFieldKey.d.ts +11 -0
- package/dist/resolvers/inputFieldKey.d.ts.map +1 -0
- package/dist/resolvers/inputFieldKey.js +47 -0
- package/dist/resolvers/inputs.d.ts +13 -4
- package/dist/resolvers/inputs.d.ts.map +1 -1
- package/dist/resolvers/inputs.js +36 -0
- package/dist/schemas/Action.d.ts +8 -8
- package/dist/schemas/Action.d.ts.map +1 -1
- package/dist/schemas/Action.js +8 -3
- package/dist/schemas/App.d.ts +183 -11
- package/dist/schemas/App.d.ts.map +1 -1
- package/dist/schemas/App.js +7 -9
- package/dist/schemas/Auth.d.ts +12 -12
- package/dist/schemas/Auth.js +1 -1
- package/dist/schemas/Field.d.ts +112 -97
- package/dist/schemas/Field.d.ts.map +1 -1
- package/dist/schemas/Field.js +63 -52
- package/dist/schemas/Run.d.ts +3 -0
- package/dist/schemas/Run.d.ts.map +1 -0
- package/dist/schemas/Run.js +31 -0
- package/dist/schemas/UserProfile.d.ts +11 -11
- package/dist/schemas/UserProfile.d.ts.map +1 -1
- package/dist/schemas/UserProfile.js +21 -7
- package/dist/sdk.d.ts +11 -4
- package/dist/sdk.d.ts.map +1 -1
- package/dist/types/domain.d.ts +17 -1
- package/dist/types/domain.d.ts.map +1 -1
- package/dist/types/plugin.d.ts +5 -0
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/properties.d.ts +3 -1
- package/dist/types/properties.d.ts.map +1 -1
- package/dist/types/sdk.d.ts +5 -0
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/utils/domain-utils.d.ts +1 -16
- package/dist/utils/domain-utils.d.ts.map +1 -1
- package/dist/utils/domain-utils.js +7 -51
- package/dist/utils/schema-utils.d.ts +44 -21
- package/dist/utils/schema-utils.d.ts.map +1 -1
- package/dist/utils/schema-utils.js +17 -11
- package/dist/utils/string-utils.d.ts +12 -0
- package/dist/utils/string-utils.d.ts.map +1 -0
- package/dist/utils/string-utils.js +23 -0
- package/dist/utils/string-utils.test.d.ts +2 -0
- package/dist/utils/string-utils.test.d.ts.map +1 -0
- package/dist/utils/string-utils.test.js +36 -0
- package/package.json +1 -1
- package/src/api/client.ts +12 -0
- package/src/api/debug.test.ts +76 -0
- package/src/api/debug.ts +46 -2
- package/src/api/schemas.ts +51 -29
- package/src/index.ts +4 -5
- package/src/plugins/findFirstAuthentication/index.test.ts +8 -5
- package/src/plugins/findFirstAuthentication/index.ts +14 -2
- package/src/plugins/findUniqueAuthentication/index.ts +4 -0
- package/src/plugins/getAction/index.ts +14 -0
- package/src/plugins/getApp/index.test.ts +2 -2
- package/src/plugins/getApp/index.ts +8 -0
- package/src/plugins/getApp/schemas.ts +7 -12
- package/src/plugins/getAuthentication/index.ts +8 -0
- package/src/plugins/getProfile/index.ts +4 -0
- package/src/plugins/getProfile/schemas.ts +4 -6
- package/src/plugins/listActions/index.ts +9 -0
- package/src/plugins/listActions/schemas.ts +20 -25
- package/src/plugins/listApps/index.test.ts +1 -1
- package/src/plugins/listApps/index.ts +4 -0
- package/src/plugins/listApps/schemas.ts +17 -26
- package/src/plugins/listAuthentications/index.ts +8 -0
- package/src/plugins/listInputFieldChoices/index.ts +21 -1
- package/src/plugins/listInputFieldChoices/schemas.ts +61 -76
- package/src/plugins/listInputFields/index.test.ts +5 -9
- package/src/plugins/listInputFields/index.ts +89 -11
- package/src/plugins/listInputFields/schemas.ts +6 -3
- package/src/plugins/registry/index.ts +8 -2
- package/src/plugins/request/index.ts +1 -0
- package/src/plugins/runAction/index.ts +18 -0
- package/src/resolvers/actionKey.ts +15 -13
- package/src/resolvers/actionType.ts +10 -12
- package/src/resolvers/appKey.ts +2 -6
- package/src/resolvers/authenticationId.ts +25 -19
- package/src/resolvers/index.ts +7 -113
- package/src/resolvers/inputFieldKey.ts +70 -0
- package/src/resolvers/inputs.ts +51 -7
- package/src/schemas/Action.ts +8 -3
- package/src/schemas/App.ts +7 -9
- package/src/schemas/Auth.ts +1 -1
- package/src/schemas/Field.ts +97 -60
- package/src/schemas/Run.ts +40 -0
- package/src/schemas/UserProfile.ts +24 -7
- package/src/sdk.ts +17 -7
- package/src/types/domain.ts +24 -1
- package/src/types/plugin.ts +5 -0
- package/src/types/sdk.ts +5 -0
- package/src/utils/domain-utils.ts +9 -67
- package/src/utils/schema-utils.ts +96 -44
- package/src/utils/string-utils.test.ts +45 -0
- package/src/utils/string-utils.ts +26 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { withFormatter, type FormattedItem } from "../utils/schema-utils";
|
|
3
|
+
|
|
4
|
+
// Type guard to safely access object properties
|
|
5
|
+
function getStringProperty(obj: unknown, key: string): string | undefined {
|
|
6
|
+
if (typeof obj === "object" && obj !== null && key in obj) {
|
|
7
|
+
const value = (obj as Record<string, unknown>)[key];
|
|
8
|
+
return typeof value === "string" ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Formatter for action results - handles any data structure
|
|
14
|
+
function formatActionResult(item: unknown): FormattedItem {
|
|
15
|
+
// Try to extract common fields for structured display
|
|
16
|
+
const obj = typeof item === "object" && item !== null ? item : {};
|
|
17
|
+
|
|
18
|
+
// Try common title fields
|
|
19
|
+
const title =
|
|
20
|
+
getStringProperty(obj, "title") ||
|
|
21
|
+
getStringProperty(obj, "name") ||
|
|
22
|
+
getStringProperty(obj, "label") ||
|
|
23
|
+
getStringProperty(obj, "subject") ||
|
|
24
|
+
"Action Result";
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
title,
|
|
28
|
+
id: getStringProperty(obj, "id"),
|
|
29
|
+
key: getStringProperty(obj, "key"),
|
|
30
|
+
description: getStringProperty(obj, "description"),
|
|
31
|
+
data: item, // Let formatJsonOutput handle the JSON rendering
|
|
32
|
+
details: [], // Not used when data is provided
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Flexible schema for action results - can be any object
|
|
37
|
+
export const ActionResultItemSchema = withFormatter(
|
|
38
|
+
z.unknown().describe("Action execution result"),
|
|
39
|
+
{ format: formatActionResult },
|
|
40
|
+
);
|
|
@@ -15,21 +15,38 @@ export const UserProfileItemSchema = withFormatter(
|
|
|
15
15
|
{
|
|
16
16
|
format: (item) => {
|
|
17
17
|
const details = [];
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
if (
|
|
19
|
+
item == null ||
|
|
20
|
+
typeof item !== "object" ||
|
|
21
|
+
!("full_name" in item) ||
|
|
22
|
+
!("username" in item)
|
|
23
|
+
) {
|
|
24
|
+
return {
|
|
25
|
+
title: "User Profile",
|
|
26
|
+
subtitle: "Malformatted result item",
|
|
27
|
+
details: [],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if ("email" in item) {
|
|
32
|
+
details.push({ text: item.email, style: "dim" as const });
|
|
33
|
+
}
|
|
34
|
+
if ("timezone" in item && item.timezone) {
|
|
20
35
|
details.push({
|
|
21
36
|
text: `Timezone: ${item.timezone}`,
|
|
22
37
|
style: "accent" as const,
|
|
23
38
|
});
|
|
24
39
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
if ("since_signup" in item && item.since_signup) {
|
|
41
|
+
details.push({
|
|
42
|
+
text: `Member since: ${item.since_signup}`,
|
|
43
|
+
style: "dim" as const,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
29
46
|
|
|
30
47
|
return {
|
|
31
48
|
title: item.full_name,
|
|
32
|
-
|
|
49
|
+
id: item.id.toString(),
|
|
33
50
|
details,
|
|
34
51
|
};
|
|
35
52
|
},
|
package/src/sdk.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
Sdk,
|
|
10
10
|
Plugin,
|
|
11
11
|
ExtractContextProperties,
|
|
12
|
+
ExtractSdkProperties,
|
|
12
13
|
PluginProvides,
|
|
13
14
|
PluginMeta,
|
|
14
15
|
} from "./types/plugin";
|
|
@@ -41,12 +42,14 @@ export interface ZapierSdkOptions extends BaseSdkOptions {}
|
|
|
41
42
|
// Create SDK that supports flat plugins - returns an SDK, not a builder
|
|
42
43
|
export function createSdk<
|
|
43
44
|
TCurrentSdk = {},
|
|
44
|
-
TCurrentContext
|
|
45
|
+
TCurrentContext extends { meta: Record<string, PluginMeta> } = {
|
|
46
|
+
meta: Record<string, PluginMeta>;
|
|
47
|
+
},
|
|
45
48
|
>(
|
|
46
49
|
options: ZapierSdkOptions = {},
|
|
47
50
|
initialSdk: TCurrentSdk = {} as TCurrentSdk,
|
|
48
51
|
initialContext: TCurrentContext = { meta: {} } as TCurrentContext,
|
|
49
|
-
)
|
|
52
|
+
) {
|
|
50
53
|
return {
|
|
51
54
|
...initialSdk,
|
|
52
55
|
getContext: () => initialContext,
|
|
@@ -56,8 +59,11 @@ export function createSdk<
|
|
|
56
59
|
TRequiresContext,
|
|
57
60
|
TProvides
|
|
58
61
|
>,
|
|
59
|
-
addPluginOptions:
|
|
60
|
-
)
|
|
62
|
+
addPluginOptions: Record<string, unknown> = {},
|
|
63
|
+
): Sdk<
|
|
64
|
+
TCurrentSdk & ExtractSdkProperties<TProvides>,
|
|
65
|
+
TCurrentContext & NonNullable<ExtractContextProperties<TProvides>>
|
|
66
|
+
> {
|
|
61
67
|
// Create SDK with getContext method for plugins to use
|
|
62
68
|
const currentSdkWithContext = {
|
|
63
69
|
...initialSdk,
|
|
@@ -71,7 +77,7 @@ export function createSdk<
|
|
|
71
77
|
...initialContext,
|
|
72
78
|
// Add the options that createSdk was called with to context
|
|
73
79
|
options,
|
|
74
|
-
},
|
|
80
|
+
} as TCurrentContext & { options: ZapierSdkOptions } & TRequiresContext,
|
|
75
81
|
...addPluginOptions,
|
|
76
82
|
});
|
|
77
83
|
|
|
@@ -86,7 +92,8 @@ export function createSdk<
|
|
|
86
92
|
let newContext = {
|
|
87
93
|
...initialContext,
|
|
88
94
|
...addPluginOptions,
|
|
89
|
-
meta:
|
|
95
|
+
meta:
|
|
96
|
+
(initialContext as { meta?: Record<string, PluginMeta> }).meta || {},
|
|
90
97
|
} as TCurrentContext & NonNullable<ExtractContextProperties<TProvides>>;
|
|
91
98
|
|
|
92
99
|
if (pluginContext) {
|
|
@@ -112,7 +119,10 @@ export function createSdk<
|
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
// Recursively create new SDK with updated properties
|
|
115
|
-
return createSdk(options, newSdk, newContext) as
|
|
122
|
+
return createSdk(options, newSdk, newContext) as Sdk<
|
|
123
|
+
TCurrentSdk & ExtractSdkProperties<TProvides>,
|
|
124
|
+
TCurrentContext & NonNullable<ExtractContextProperties<TProvides>>
|
|
125
|
+
>;
|
|
116
126
|
},
|
|
117
127
|
};
|
|
118
128
|
}
|
package/src/types/domain.ts
CHANGED
|
@@ -9,8 +9,13 @@ import type { z } from "zod";
|
|
|
9
9
|
import type { AppItemSchema } from "../schemas/App";
|
|
10
10
|
import type { AuthenticationItemSchema } from "../schemas/Auth";
|
|
11
11
|
import type { ActionItemSchema } from "../schemas/Action";
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
InputFieldItemSchema,
|
|
14
|
+
InfoFieldItemSchema,
|
|
15
|
+
RootFieldItemSchema,
|
|
16
|
+
} from "../schemas/Field";
|
|
13
17
|
import type { UserProfileItemSchema } from "../schemas/UserProfile";
|
|
18
|
+
import type { FieldsetItem } from "../schemas/Field";
|
|
14
19
|
|
|
15
20
|
/**
|
|
16
21
|
* Represents an app item returned by getApp and listApps functions
|
|
@@ -36,6 +41,24 @@ export type ActionItem = z.infer<typeof ActionItemSchema>;
|
|
|
36
41
|
*/
|
|
37
42
|
export type InputFieldItem = z.infer<typeof InputFieldItemSchema>;
|
|
38
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Represents an info field item (help text/copy) returned by listInputFields functions
|
|
46
|
+
* Inferred from InfoFieldItemSchema
|
|
47
|
+
*/
|
|
48
|
+
export type InfoFieldItem = z.infer<typeof InfoFieldItemSchema>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Represents a fieldset (group of fields) returned by listInputFields functions
|
|
52
|
+
* This is defined as an interface rather than inferred due to recursive nature
|
|
53
|
+
*/
|
|
54
|
+
export type { FieldsetItem };
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Represents a root field item (any field/fieldset type) returned by listInputFields
|
|
58
|
+
* Inferred from RootFieldItemSchema - use as RootFieldItem[]
|
|
59
|
+
*/
|
|
60
|
+
export type RootFieldItem = z.infer<typeof RootFieldItemSchema>;
|
|
61
|
+
|
|
39
62
|
/**
|
|
40
63
|
* Represents a user profile item returned by getProfile function
|
|
41
64
|
* Inferred from UserProfileItemSchema which extends the base UserProfile API schema
|
package/src/types/plugin.ts
CHANGED
|
@@ -22,7 +22,12 @@ export interface PluginProvides extends Record<string, any> {
|
|
|
22
22
|
|
|
23
23
|
export interface PluginMeta {
|
|
24
24
|
categories: string[];
|
|
25
|
+
type?: "list" | "item";
|
|
26
|
+
itemType?: string;
|
|
27
|
+
returnType?: string;
|
|
25
28
|
inputSchema: z.ZodSchema;
|
|
29
|
+
outputSchema?: z.ZodSchema;
|
|
30
|
+
resolvers?: Record<string, any>;
|
|
26
31
|
[key: string]: any;
|
|
27
32
|
}
|
|
28
33
|
|
package/src/types/sdk.ts
CHANGED
|
@@ -57,8 +57,13 @@ import type { ManifestPluginProvides } from "../plugins/manifest";
|
|
|
57
57
|
// Registry entry interface with proper types
|
|
58
58
|
export interface FunctionRegistryEntry {
|
|
59
59
|
name: string;
|
|
60
|
+
type?: "list" | "item";
|
|
61
|
+
itemType?: string;
|
|
62
|
+
returnType?: string;
|
|
60
63
|
inputSchema: z.ZodSchema;
|
|
64
|
+
outputSchema?: z.ZodSchema;
|
|
61
65
|
categories: string[];
|
|
66
|
+
resolvers?: Record<string, any>;
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
// Compose SDK functions from individual function interfaces
|
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
* Domain utility functions for working with app identifiers and data normalization
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
Action,
|
|
7
|
-
App,
|
|
8
|
-
Authentication,
|
|
9
|
-
Implementation,
|
|
10
|
-
ImplementationMeta,
|
|
11
|
-
Service,
|
|
12
|
-
} from "../api/types";
|
|
5
|
+
import type { Action, Authentication, ImplementationMeta } from "../api/types";
|
|
13
6
|
import type { ActionItem, AppItem, AuthenticationItem } from "../types/domain";
|
|
14
7
|
|
|
15
8
|
/**
|
|
@@ -34,48 +27,6 @@ export function splitVersionedKey(
|
|
|
34
27
|
return [versionedKey, undefined];
|
|
35
28
|
}
|
|
36
29
|
|
|
37
|
-
/**
|
|
38
|
-
* Converts an API App to an AppItem with normalized field names
|
|
39
|
-
*
|
|
40
|
-
* @param app - Raw App from API
|
|
41
|
-
* @returns Normalized AppItem
|
|
42
|
-
*/
|
|
43
|
-
export function normalizeAppItem(app: App): AppItem {
|
|
44
|
-
// Extract API name and version from current_implementation_id
|
|
45
|
-
const [apiName, appVersion] = app.current_implementation_id
|
|
46
|
-
? splitVersionedKey(app.current_implementation_id)
|
|
47
|
-
: [app.current_implementation_id || "", undefined];
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
title: app.name,
|
|
51
|
-
key: app.slug || apiName,
|
|
52
|
-
current_implementation_id: app.current_implementation_id || "",
|
|
53
|
-
version: appVersion, // Extract version separately
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Converts an Implementation to an AppItem with normalized field names
|
|
59
|
-
*
|
|
60
|
-
* @param implementation - Raw Implementation from API
|
|
61
|
-
* @returns Normalized AppItem
|
|
62
|
-
*/
|
|
63
|
-
export function normalizeImplementationToAppItem(
|
|
64
|
-
implementation: Implementation,
|
|
65
|
-
): AppItem {
|
|
66
|
-
// Extract API name and version from selected_api
|
|
67
|
-
const [selectedApi, appVersion] = implementation.selected_api
|
|
68
|
-
? splitVersionedKey(implementation.selected_api)
|
|
69
|
-
: [implementation.selected_api || "", undefined];
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
title: implementation.name || selectedApi,
|
|
73
|
-
key: selectedApi,
|
|
74
|
-
current_implementation_id: implementation.selected_api || "",
|
|
75
|
-
version: appVersion, // Extract version separately
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
30
|
/**
|
|
80
31
|
* Converts a lightweight ImplementationMeta to a slimmed AppItem
|
|
81
32
|
*
|
|
@@ -88,26 +39,17 @@ export function normalizeImplementationMetaToAppItem(
|
|
|
88
39
|
// Extract API name and version from the implementation ID
|
|
89
40
|
const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
|
|
90
41
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
key: selectedApi,
|
|
94
|
-
current_implementation_id: implementationMeta.id, // Keep the full versioned ID
|
|
95
|
-
version: appVersion, // Extract version separately
|
|
96
|
-
slug: implementationMeta.slug,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function normalizeServiceToAppItem(service: Service): AppItem {
|
|
101
|
-
const [selectedApi, appVersion] = service.current_implementation_id
|
|
102
|
-
? splitVersionedKey(service.current_implementation_id)
|
|
103
|
-
: ["", undefined];
|
|
42
|
+
// Destructure to exclude id and name before spreading
|
|
43
|
+
const { id, name, ...restOfImplementationMeta } = implementationMeta;
|
|
104
44
|
|
|
105
45
|
return {
|
|
106
|
-
|
|
46
|
+
// Pass through all ImplementationMeta fields except id and name
|
|
47
|
+
...restOfImplementationMeta,
|
|
48
|
+
// Transform key fields
|
|
49
|
+
title: name,
|
|
107
50
|
key: selectedApi,
|
|
108
|
-
|
|
109
|
-
version: appVersion,
|
|
110
|
-
description: service.description,
|
|
51
|
+
implementation_id: id, // Keep the full versioned ID
|
|
52
|
+
version: appVersion, // Extract version separately
|
|
111
53
|
};
|
|
112
54
|
}
|
|
113
55
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { ZapierSdk } from "../types/sdk";
|
|
3
|
+
import type { InputFieldItem } from "../schemas/Field";
|
|
2
4
|
|
|
3
5
|
// ============================================================================
|
|
4
6
|
// Format Metadata Types
|
|
@@ -6,92 +8,121 @@ import { z } from "zod";
|
|
|
6
8
|
|
|
7
9
|
export interface FormattedItem {
|
|
8
10
|
title: string;
|
|
9
|
-
|
|
11
|
+
id?: string;
|
|
12
|
+
key?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
data?: unknown; // Optional: if provided, CLI will use formatJsonOutput instead of details
|
|
10
15
|
details: Array<{
|
|
11
16
|
text: string;
|
|
12
17
|
style: "normal" | "dim" | "accent" | "warning" | "success";
|
|
13
18
|
}>;
|
|
14
19
|
}
|
|
15
20
|
|
|
16
|
-
export interface FormatMetadata {
|
|
17
|
-
format: (item:
|
|
21
|
+
export interface FormatMetadata<TItem = unknown> {
|
|
22
|
+
format: (item: TItem) => FormattedItem;
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
// Helper function to add format metadata to schemas
|
|
21
26
|
export function withFormatter<T extends z.ZodType>(
|
|
22
27
|
schema: T,
|
|
23
|
-
formatMeta: FormatMetadata
|
|
28
|
+
formatMeta: FormatMetadata<z.infer<T>>,
|
|
24
29
|
): T {
|
|
25
30
|
// Store format metadata on the schema definition
|
|
26
|
-
(schema._def
|
|
27
|
-
|
|
31
|
+
Object.assign(schema._def, {
|
|
32
|
+
formatMeta: formatMeta,
|
|
33
|
+
});
|
|
34
|
+
return schema as T & {
|
|
35
|
+
_def: T["_def"] & { formatMeta: FormatMetadata<z.infer<T>> };
|
|
36
|
+
};
|
|
28
37
|
}
|
|
29
38
|
|
|
30
|
-
// Helper function to get
|
|
31
|
-
export function
|
|
32
|
-
|
|
33
|
-
): FormatMetadata | undefined {
|
|
34
|
-
return (schema._def as any).formatMeta;
|
|
39
|
+
// Helper function to get output schema from an input schema
|
|
40
|
+
export function getOutputSchema(inputSchema: z.ZodType): z.ZodType | undefined {
|
|
41
|
+
return (inputSchema._def as { outputSchema?: z.ZodType }).outputSchema;
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
// Helper function to link input schemas to output schemas
|
|
38
45
|
export function withOutputSchema<T extends z.ZodType>(
|
|
39
46
|
inputSchema: T,
|
|
40
47
|
outputSchema: z.ZodType,
|
|
41
|
-
): T {
|
|
48
|
+
): T & {
|
|
49
|
+
_def: T["_def"] & { outputSchema: z.ZodType };
|
|
50
|
+
} {
|
|
42
51
|
// Store output schema reference on the input schema
|
|
43
|
-
(inputSchema._def
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return (inputSchema._def as any).outputSchema;
|
|
52
|
+
Object.assign(inputSchema._def, {
|
|
53
|
+
outputSchema,
|
|
54
|
+
});
|
|
55
|
+
return inputSchema as T & {
|
|
56
|
+
_def: T["_def"] & { outputSchema: z.ZodType };
|
|
57
|
+
};
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
// ============================================================================
|
|
53
61
|
// Resolution Metadata Types
|
|
54
62
|
// ============================================================================
|
|
55
63
|
|
|
56
|
-
export interface
|
|
64
|
+
export interface PromptConfig {
|
|
65
|
+
type: "list";
|
|
66
|
+
name: string;
|
|
67
|
+
message: string;
|
|
68
|
+
choices: Array<{
|
|
69
|
+
name: string;
|
|
70
|
+
value: unknown;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface Resolver {
|
|
75
|
+
type: string;
|
|
76
|
+
depends?: readonly string[] | string[]; // Parameters this resolver depends on
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface StaticResolver extends Resolver {
|
|
57
80
|
type: "static";
|
|
58
81
|
inputType?: "text" | "password" | "email";
|
|
59
82
|
placeholder?: string;
|
|
60
83
|
}
|
|
61
84
|
|
|
62
|
-
export interface DynamicResolver
|
|
85
|
+
export interface DynamicResolver<
|
|
86
|
+
TItem = unknown,
|
|
87
|
+
TParams = Record<string, unknown>,
|
|
88
|
+
> extends Resolver {
|
|
63
89
|
type: "dynamic";
|
|
64
|
-
fetch: (sdk:
|
|
65
|
-
prompt: (items:
|
|
66
|
-
depends?: string[]; // Parameters this resolver depends on
|
|
90
|
+
fetch: (sdk: ZapierSdk, resolvedParams: TParams) => Promise<TItem[]>; // Function to fetch data using SDK
|
|
91
|
+
prompt: (items: TItem[], params: TParams) => PromptConfig;
|
|
67
92
|
}
|
|
68
93
|
|
|
69
|
-
export interface FieldsResolver
|
|
94
|
+
export interface FieldsResolver<TParams = Record<string, unknown>>
|
|
95
|
+
extends Resolver {
|
|
70
96
|
type: "fields";
|
|
71
|
-
fetch: (sdk:
|
|
72
|
-
depends?: string[]; // Parameters this resolver depends on
|
|
97
|
+
fetch: (sdk: ZapierSdk, resolvedParams: TParams) => Promise<InputFieldItem[]>; // Function to fetch fields using SDK
|
|
73
98
|
}
|
|
74
99
|
|
|
75
|
-
export type ResolverMetadata
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
export type ResolverMetadata<
|
|
101
|
+
TItem = unknown,
|
|
102
|
+
TParams = Record<string, unknown>,
|
|
103
|
+
> = StaticResolver | DynamicResolver<TItem, TParams> | FieldsResolver<TParams>;
|
|
79
104
|
|
|
80
105
|
// Wrapper interface for resolver metadata to allow future extensibility
|
|
81
|
-
export interface ResolverConfig
|
|
82
|
-
|
|
106
|
+
export interface ResolverConfig<
|
|
107
|
+
TItem = unknown,
|
|
108
|
+
TParams = Record<string, unknown>,
|
|
109
|
+
> {
|
|
110
|
+
resolver: ResolverMetadata<TItem, TParams>;
|
|
83
111
|
// Future metadata types can be added here:
|
|
84
112
|
// validation?: ValidationMetadata;
|
|
85
113
|
// display?: DisplayMetadata;
|
|
86
114
|
}
|
|
87
115
|
|
|
88
116
|
// Helper function to add resolver metadata to schemas
|
|
89
|
-
export function withResolver<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
117
|
+
export function withResolver<
|
|
118
|
+
T extends z.ZodType,
|
|
119
|
+
TItem = unknown,
|
|
120
|
+
TParams = Record<string, unknown>,
|
|
121
|
+
>(schema: T, config: ResolverConfig<TItem, TParams>): T {
|
|
93
122
|
// Store resolver metadata on the schema definition
|
|
94
|
-
(
|
|
123
|
+
(
|
|
124
|
+
schema._def as { resolverMeta?: ResolverConfig<TItem, TParams> }
|
|
125
|
+
).resolverMeta = config;
|
|
95
126
|
return schema;
|
|
96
127
|
}
|
|
97
128
|
|
|
@@ -104,7 +135,7 @@ export function getSchemaDescription(schema: z.ZodSchema): string | undefined {
|
|
|
104
135
|
}
|
|
105
136
|
|
|
106
137
|
export function getFieldDescriptions(
|
|
107
|
-
schema: z.ZodObject<
|
|
138
|
+
schema: z.ZodObject<z.ZodRawShape>,
|
|
108
139
|
): Record<string, string> {
|
|
109
140
|
const descriptions: Record<string, string> = {};
|
|
110
141
|
const shape = schema.shape;
|
|
@@ -123,20 +154,41 @@ export function getFieldDescriptions(
|
|
|
123
154
|
// ============================================================================
|
|
124
155
|
|
|
125
156
|
export interface PositionalMetadata {
|
|
126
|
-
|
|
157
|
+
positionalMeta: {
|
|
158
|
+
positional: true;
|
|
159
|
+
};
|
|
127
160
|
}
|
|
128
161
|
|
|
129
162
|
// Helper function to mark a parameter as positional for CLI
|
|
130
|
-
export function withPositional<T extends z.ZodType>(
|
|
163
|
+
export function withPositional<T extends z.ZodType>(
|
|
164
|
+
schema: T,
|
|
165
|
+
): T & {
|
|
166
|
+
_def: T["_def"] & PositionalMetadata;
|
|
167
|
+
} {
|
|
131
168
|
// Store positional metadata on the schema definition
|
|
132
|
-
(schema._def
|
|
133
|
-
|
|
169
|
+
Object.assign(schema._def, {
|
|
170
|
+
positionalMeta: { positional: true },
|
|
171
|
+
} satisfies PositionalMetadata);
|
|
172
|
+
return schema as T & {
|
|
173
|
+
_def: T["_def"] & PositionalMetadata;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function schemaHasPositionalMeta<T extends z.ZodType>(
|
|
178
|
+
schema: T,
|
|
179
|
+
): schema is T & {
|
|
180
|
+
_def: T["_def"] & PositionalMetadata;
|
|
181
|
+
} {
|
|
182
|
+
return "positionalMeta" in schema._def;
|
|
134
183
|
}
|
|
135
184
|
|
|
136
185
|
// Helper function to check if a parameter should be positional
|
|
137
186
|
export function isPositional(schema: z.ZodType): boolean {
|
|
138
187
|
// Check the current schema first
|
|
139
|
-
if (
|
|
188
|
+
if (
|
|
189
|
+
schemaHasPositionalMeta(schema) &&
|
|
190
|
+
schema._def.positionalMeta?.positional
|
|
191
|
+
) {
|
|
140
192
|
return true;
|
|
141
193
|
}
|
|
142
194
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { toTitleCase } from "./string-utils";
|
|
3
|
+
|
|
4
|
+
describe("toTitleCase", () => {
|
|
5
|
+
it("converts snake_case to title case", () => {
|
|
6
|
+
expect(toTitleCase("first_name")).toBe("First Name");
|
|
7
|
+
expect(toTitleCase("sender_settings")).toBe("Sender Settings");
|
|
8
|
+
expect(toTitleCase("api_key_config")).toBe("Api Key Config");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("converts camelCase to title case", () => {
|
|
12
|
+
expect(toTitleCase("firstName")).toBe("First Name");
|
|
13
|
+
expect(toTitleCase("senderSettings")).toBe("Sender Settings");
|
|
14
|
+
expect(toTitleCase("apiKeyConfig")).toBe("Api Key Config");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("converts kebab-case to title case", () => {
|
|
18
|
+
expect(toTitleCase("first-name")).toBe("First Name");
|
|
19
|
+
expect(toTitleCase("sender-settings")).toBe("Sender Settings");
|
|
20
|
+
expect(toTitleCase("api-key-config")).toBe("Api Key Config");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("handles mixed formats", () => {
|
|
24
|
+
expect(toTitleCase("first_name-value")).toBe("First Name Value");
|
|
25
|
+
expect(toTitleCase("sender_settings-config")).toBe(
|
|
26
|
+
"Sender Settings Config",
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("handles single words", () => {
|
|
31
|
+
expect(toTitleCase("name")).toBe("Name");
|
|
32
|
+
expect(toTitleCase("settings")).toBe("Settings");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("handles multiple spaces and trims", () => {
|
|
36
|
+
expect(toTitleCase(" first name ")).toBe("First Name");
|
|
37
|
+
expect(toTitleCase("sender__settings")).toBe("Sender Settings");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("handles empty and edge cases", () => {
|
|
41
|
+
expect(toTitleCase("")).toBe("");
|
|
42
|
+
expect(toTitleCase("a")).toBe("A");
|
|
43
|
+
expect(toTitleCase("_")).toBe("");
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String utility functions for the Zapier SDK
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Converts a string to title case, handling various input formats:
|
|
7
|
+
* - camelCase: "firstName" → "First Name"
|
|
8
|
+
* - snake_case: "first_name" → "First Name"
|
|
9
|
+
* - kebab-case: "first-name" → "First Name"
|
|
10
|
+
* - mixed formats: "first_name-value" → "First Name Value"
|
|
11
|
+
*/
|
|
12
|
+
export function toTitleCase(input: string): string {
|
|
13
|
+
return (
|
|
14
|
+
input
|
|
15
|
+
// insert a space before capital letters (handles camelCase)
|
|
16
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
17
|
+
// replace delimiters (underscore, dash, multiple spaces) with single space
|
|
18
|
+
.replace(/[_\-]+/g, " ")
|
|
19
|
+
.replace(/\s+/g, " ")
|
|
20
|
+
.trim()
|
|
21
|
+
// split and capitalize each word
|
|
22
|
+
.split(" ")
|
|
23
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
24
|
+
.join(" ")
|
|
25
|
+
);
|
|
26
|
+
}
|