-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathaction.zod.ts
More file actions
108 lines (91 loc) · 3.79 KB
/
action.zod.ts
File metadata and controls
108 lines (91 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { z } from 'zod';
import { FieldType } from '../data/field.zod';
import { SnakeCaseIdentifierSchema } from '../shared/identifiers.zod';
/**
* Action Parameter Schema
* Defines inputs required before executing an action.
*/
export const ActionParamSchema = z.object({
name: z.string(),
label: z.string(),
type: FieldType,
required: z.boolean().default(false),
options: z.array(z.object({ label: z.string(), value: z.string() })).optional(),
});
/**
* Action Schema
*
* **NAMING CONVENTION:**
* Action names are machine identifiers used in code and must be lowercase snake_case.
*
* @example Good action names
* - 'on_close_deal'
* - 'send_welcome_email'
* - 'approve_contract'
* - 'export_report'
*
* @example Bad action names (will be rejected)
* - 'OnCloseDeal' (PascalCase)
* - 'sendEmail' (camelCase)
* - 'Send Email' (spaces)
*
* Note: The action name is the configuration ID. JavaScript function names can use camelCase,
* but the metadata ID must be lowercase snake_case.
*/
export const ActionSchema = z.object({
/** Machine name of the action */
name: SnakeCaseIdentifierSchema.describe('Machine name (lowercase snake_case)'),
/** Display label */
label: z.string().describe('Display label'),
/** Icon name (Lucide) */
icon: z.string().optional().describe('Icon name'),
/** Where does this action appear? */
locations: z.array(z.enum([
'list_toolbar', 'list_item',
'record_header', 'record_more', 'record_related',
'global_nav'
])).optional().describe('Locations where this action is visible'),
/**
* Visual Component Type
* Defaults to 'button' or 'menu_item' based on location,
* but can be overridden.
*/
component: z.enum([
'action:button', // Standard Button
'action:icon', // Icon only
'action:menu', // Dropdown menu
'action:group' // Button Group
]).optional().describe('Visual component override'),
/** @deprecated Use `locations` instead. Will be removed in v2.0.0 */
location: z.unknown().optional()
.describe('DEPRECATED: Use `locations` field instead. Scheduled for removal in v2.0.0'),
/** What type of interaction? */
type: z.enum(['script', 'url', 'modal', 'flow', 'api']).default('script').describe('Action functionality type'),
/** Payload / Target */
target: z.string().optional().describe('URL, Script Name, Flow ID, or API Endpoint'), // For URL/Flow types
execute: z.string().optional().describe('Legacy execution logic'),
/** User Input Requirements */
params: z.array(ActionParamSchema).optional().describe('Input parameters required from user'),
/** UX Behavior */
confirmText: z.string().optional().describe('Confirmation message before execution'),
successMessage: z.string().optional().describe('Success message to show after execution'),
refreshAfter: z.boolean().default(false).describe('Refresh view after execution'),
/** Access */
visible: z.string().optional().describe('Formula returning boolean'),
disabled: z.union([z.boolean(), z.string()]).optional().describe('Whether the action is disabled, or a condition expression string'),
/** Keyboard Shortcut */
shortcut: z.string().optional().describe('Keyboard shortcut to trigger this action (e.g., "Ctrl+S")'),
/** Bulk Operations */
bulkEnabled: z.boolean().optional().describe('Whether this action can be applied to multiple selected records'),
/** Execution */
timeout: z.number().optional().describe('Maximum execution time in milliseconds for the action'),
});
export type Action = z.infer<typeof ActionSchema>;
export type ActionParam = z.infer<typeof ActionParamSchema>;
export type ActionInput = z.input<typeof ActionSchema>;
/**
* Action Factory Helper
*/
export const Action = {
create: (config: z.input<typeof ActionSchema>): Action => ActionSchema.parse(config),
} as const;