Skip to content
Merged
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Visit [http://localhost:3000](http://localhost:3000) to get started.
<!-- PLUGINS:START - Do not remove. Auto-generated by discover-plugins -->
- **AI Gateway**: Generate Text, Generate Image
- **Blob**: Put Blob, List Blobs
- **Clerk**: Get User, Create User, Update User, Delete User
- **fal.ai**: Generate Image, Generate Video, Upscale Image, Remove Background, Image to Image
- **Firecrawl**: Scrape URL, Search Web
- **GitHub**: Create Issue, List Issues, Get Issue, Update Issue
Expand Down
83 changes: 83 additions & 0 deletions lib/workflow-codegen-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,84 @@ export function generateWorkflowSDKCode(
"apiKey: process.env.V0_API_KEY!",
];
}

function buildClerkGetUserParams(config: Record<string, unknown>): string[] {
return [
`userId: \`${convertTemplateToJS((config.userId as string) || "")}\``,
];
}

function buildClerkCreateUserParams(
config: Record<string, unknown>
): string[] {
const params = [
`emailAddress: \`${convertTemplateToJS((config.emailAddress as string) || "")}\``,
];
if (config.password) {
params.push(
`password: \`${convertTemplateToJS(config.password as string)}\``
);
}
if (config.firstName) {
params.push(
`firstName: \`${convertTemplateToJS(config.firstName as string)}\``
);
}
if (config.lastName) {
params.push(
`lastName: \`${convertTemplateToJS(config.lastName as string)}\``
);
}
if (config.publicMetadata) {
params.push(
`publicMetadata: \`${convertTemplateToJS(config.publicMetadata as string)}\``
);
}
if (config.privateMetadata) {
params.push(
`privateMetadata: \`${convertTemplateToJS(config.privateMetadata as string)}\``
);
}
return params;
}

function buildClerkUpdateUserParams(
config: Record<string, unknown>
): string[] {
const params = [
`userId: \`${convertTemplateToJS((config.userId as string) || "")}\``,
];
if (config.firstName) {
params.push(
`firstName: \`${convertTemplateToJS(config.firstName as string)}\``
);
}
if (config.lastName) {
params.push(
`lastName: \`${convertTemplateToJS(config.lastName as string)}\``
);
}
if (config.publicMetadata) {
params.push(
`publicMetadata: \`${convertTemplateToJS(config.publicMetadata as string)}\``
);
}
if (config.privateMetadata) {
params.push(
`privateMetadata: \`${convertTemplateToJS(config.privateMetadata as string)}\``
);
}
return params;
}

function buildClerkDeleteUserParams(
config: Record<string, unknown>
): string[] {
return [
`userId: \`${convertTemplateToJS((config.userId as string) || "")}\``,
];
}

function buildStepInputParams(
actionType: string,
config: Record<string, unknown>
Expand All @@ -410,6 +488,11 @@ export function generateWorkflowSDKCode(
Search: () => buildFirecrawlParams(actionType, config),
"Create Chat": () => buildV0CreateChatParams(config),
"Send Message": () => buildV0SendMessageParams(config),
// Clerk
"Get User": () => buildClerkGetUserParams(config),
"Create User": () => buildClerkCreateUserParams(config),
"Update User": () => buildClerkUpdateUserParams(config),
"Delete User": () => buildClerkDeleteUserParams(config),
};

const builder = paramBuilders[actionType];
Expand Down
3 changes: 3 additions & 0 deletions plugins/clerk/credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type ClerkCredentials = {
CLERK_SECRET_KEY?: string;
};
21 changes: 21 additions & 0 deletions plugins/clerk/icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export function ClerkIcon({ className }: { className?: string }) {
return (
<svg
className={className}
role="img"
viewBox="0 0 128 128"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="64" cy="64" r="20" fill="currentColor" />
<path
fill="currentColor"
fillOpacity="0.6"
d="M99.5716 10.788C101.571 12.1272 101.742 14.9444 100.04 16.646L85.4244 31.2618C84.1035 32.5828 82.0542 32.7914 80.3915 31.9397C75.4752 29.421 69.9035 28 64 28C44.1177 28 28 44.1177 28 64C28 69.9035 29.421 75.4752 31.9397 80.3915C32.7914 82.0542 32.5828 84.1035 31.2618 85.4244L16.646 100.04C14.9444 101.742 12.1272 101.571 10.788 99.5716C3.97411 89.3989 0 77.1635 0 64C0 28.6538 28.6538 0 64 0C77.1635 0 89.3989 3.97411 99.5716 10.788Z"
/>
<path
fill="currentColor"
d="M100.04 111.354C101.742 113.056 101.571 115.873 99.5717 117.212C89.3989 124.026 77.1636 128 64 128C50.8364 128 38.6011 124.026 28.4283 117.212C26.4289 115.873 26.2581 113.056 27.9597 111.354L42.5755 96.7382C43.8965 95.4172 45.9457 95.2085 47.6084 96.0603C52.5248 98.579 58.0964 100 64 100C69.9036 100 75.4753 98.579 80.3916 96.0603C82.0543 95.2085 84.1036 95.4172 85.4245 96.7382L100.04 111.354Z"
/>
</svg>
);
}
205 changes: 205 additions & 0 deletions plugins/clerk/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import type { IntegrationPlugin } from "../registry";
import { registerIntegration } from "../registry";
import { ClerkIcon } from "./icon";

const clerkPlugin: IntegrationPlugin = {
type: "clerk",
label: "Clerk",
description: "User authentication and management",

icon: ClerkIcon,

formFields: [
{
id: "clerkSecretKey",
label: "Secret Key",
type: "password",
placeholder: "sk_live_... or sk_test_...",
configKey: "clerkSecretKey",
envVar: "CLERK_SECRET_KEY",
helpText: "Get your secret key from ",
helpLink: {
text: "Clerk Dashboard",
url: "https://dashboard.clerk.com",
},
},
],

testConfig: {
getTestFunction: async () => {
const { testClerk } = await import("./test");
return testClerk;
},
},

actions: [
{
slug: "get-user",
label: "Get User",
description: "Fetch a user by ID from Clerk",
category: "Clerk",
stepFunction: "clerkGetUserStep",
stepImportPath: "get-user",
outputFields: [
{ field: "user.id", description: "User ID" },
{ field: "user.first_name", description: "First name" },
{ field: "user.last_name", description: "Last name" },
],
configFields: [
{
key: "userId",
label: "User ID",
type: "template-input",
placeholder: "user_... or {{NodeName.userId}}",
example: "user_2abc123",
required: true,
},
],
},
{
slug: "create-user",
label: "Create User",
description: "Create a new user in Clerk",
category: "Clerk",
stepFunction: "clerkCreateUserStep",
stepImportPath: "create-user",
outputFields: [
{ field: "user.id", description: "User ID" },
{ field: "user.first_name", description: "First name" },
{ field: "user.last_name", description: "Last name" },
],
configFields: [
{
key: "emailAddress",
label: "Email Address",
type: "template-input",
placeholder: "user@example.com or {{NodeName.email}}",
example: "user@example.com",
required: true,
},
{
key: "firstName",
label: "First Name",
type: "template-input",
placeholder: "John or {{NodeName.firstName}}",
example: "John",
},
{
key: "lastName",
label: "Last Name",
type: "template-input",
placeholder: "Doe or {{NodeName.lastName}}",
example: "Doe",
},
{
key: "password",
label: "Password",
type: "template-input",
placeholder: "Password (min 8 chars) or leave empty",
example: "securepassword123",
},
{
label: "Metadata",
type: "group",
defaultExpanded: false,
fields: [
{
key: "publicMetadata",
label: "Public Metadata (JSON)",
type: "template-textarea",
placeholder: '{"role": "admin"} or {{NodeName.metadata}}',
rows: 3,
},
{
key: "privateMetadata",
label: "Private Metadata (JSON)",
type: "template-textarea",
placeholder: '{"internal_id": "123"}',
rows: 3,
},
],
},
],
},
{
slug: "update-user",
label: "Update User",
description: "Update an existing user in Clerk",
category: "Clerk",
stepFunction: "clerkUpdateUserStep",
stepImportPath: "update-user",
outputFields: [
{ field: "user.id", description: "User ID" },
{ field: "user.first_name", description: "First name" },
{ field: "user.last_name", description: "Last name" },
],
configFields: [
{
key: "userId",
label: "User ID",
type: "template-input",
placeholder: "user_... or {{NodeName.user.id}}",
example: "user_2abc123",
required: true,
},
{
key: "firstName",
label: "First Name",
type: "template-input",
placeholder: "Jane or {{NodeName.firstName}}",
},
{
key: "lastName",
label: "Last Name",
type: "template-input",
placeholder: "Doe or {{NodeName.lastName}}",
},
{
label: "Metadata",
type: "group",
defaultExpanded: false,
fields: [
{
key: "publicMetadata",
label: "Public Metadata (JSON)",
type: "template-textarea",
placeholder: '{"role": "admin"} or {{NodeName.metadata}}',
rows: 3,
},
{
key: "privateMetadata",
label: "Private Metadata (JSON)",
type: "template-textarea",
placeholder: '{"internal_id": "123"}',
rows: 3,
},
],
},
],
},
{
slug: "delete-user",
label: "Delete User",
description: "Delete a user from Clerk",
category: "Clerk",
stepFunction: "clerkDeleteUserStep",
stepImportPath: "delete-user",
outputFields: [{ field: "deleted", description: "Deletion success" }],
configFields: [
{
key: "userId",
label: "User ID",
type: "template-input",
placeholder: "user_... or {{NodeName.user.id}}",
example: "user_2abc123",
required: true,
},
],
},
],
};

// Auto-register on import
registerIntegration(clerkPlugin);

export default clerkPlugin;
Loading