@octaviaflow/flow-rules 0.1.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.
Files changed (146) hide show
  1. package/README.md +96 -0
  2. package/dist/catalog/actions/console-log/config.d.ts +58 -0
  3. package/dist/catalog/actions/console-log/config.js +70 -0
  4. package/dist/catalog/actions/console-log/index.d.ts +7 -0
  5. package/dist/catalog/actions/console-log/index.js +89 -0
  6. package/dist/catalog/actions/delay/config.d.ts +50 -0
  7. package/dist/catalog/actions/delay/config.js +79 -0
  8. package/dist/catalog/actions/delay/index.d.ts +7 -0
  9. package/dist/catalog/actions/delay/index.js +71 -0
  10. package/dist/catalog/actions/delay/migrate.d.ts +18 -0
  11. package/dist/catalog/actions/delay/migrate.js +38 -0
  12. package/dist/catalog/actions/delay/types.d.ts +58 -0
  13. package/dist/catalog/actions/delay/types.js +17 -0
  14. package/dist/catalog/actions/http-request/config.d.ts +114 -0
  15. package/dist/catalog/actions/http-request/config.js +111 -0
  16. package/dist/catalog/actions/http-request/index.d.ts +7 -0
  17. package/dist/catalog/actions/http-request/index.js +223 -0
  18. package/dist/catalog/ai/ai-agent/index.d.ts +12 -0
  19. package/dist/catalog/ai/ai-agent/index.js +72 -0
  20. package/dist/catalog/ai/idp-extract/index.d.ts +18 -0
  21. package/dist/catalog/ai/idp-extract/index.js +90 -0
  22. package/dist/catalog/api/graphql-query/config.d.ts +36 -0
  23. package/dist/catalog/api/graphql-query/config.js +31 -0
  24. package/dist/catalog/api/graphql-query/index.d.ts +7 -0
  25. package/dist/catalog/api/graphql-query/index.js +75 -0
  26. package/dist/catalog/communication/email-send/config.d.ts +80 -0
  27. package/dist/catalog/communication/email-send/config.js +80 -0
  28. package/dist/catalog/communication/email-send/index.d.ts +11 -0
  29. package/dist/catalog/communication/email-send/index.js +152 -0
  30. package/dist/catalog/communication/google-chat/config.d.ts +45 -0
  31. package/dist/catalog/communication/google-chat/config.js +28 -0
  32. package/dist/catalog/communication/google-chat/index.d.ts +5 -0
  33. package/dist/catalog/communication/google-chat/index.js +36 -0
  34. package/dist/catalog/communication/slack-message/config.d.ts +47 -0
  35. package/dist/catalog/communication/slack-message/config.js +36 -0
  36. package/dist/catalog/communication/slack-message/index.d.ts +5 -0
  37. package/dist/catalog/communication/slack-message/index.js +37 -0
  38. package/dist/catalog/communication/teams-message/config.d.ts +48 -0
  39. package/dist/catalog/communication/teams-message/config.js +29 -0
  40. package/dist/catalog/communication/teams-message/index.d.ts +5 -0
  41. package/dist/catalog/communication/teams-message/index.js +39 -0
  42. package/dist/catalog/communication/webhook-call/config.d.ts +36 -0
  43. package/dist/catalog/communication/webhook-call/config.js +31 -0
  44. package/dist/catalog/communication/webhook-call/index.d.ts +5 -0
  45. package/dist/catalog/communication/webhook-call/index.js +43 -0
  46. package/dist/catalog/communication/whatsapp-send/config.d.ts +23 -0
  47. package/dist/catalog/communication/whatsapp-send/config.js +36 -0
  48. package/dist/catalog/communication/whatsapp-send/index.d.ts +15 -0
  49. package/dist/catalog/communication/whatsapp-send/index.js +57 -0
  50. package/dist/catalog/general/query/config.d.ts +36 -0
  51. package/dist/catalog/general/query/config.js +257 -0
  52. package/dist/catalog/general/query/index.d.ts +11 -0
  53. package/dist/catalog/general/query/index.js +271 -0
  54. package/dist/catalog/general/query/types.d.ts +205 -0
  55. package/dist/catalog/general/query/types.js +82 -0
  56. package/dist/catalog/general/transform/config.d.ts +117 -0
  57. package/dist/catalog/general/transform/config.js +95 -0
  58. package/dist/catalog/general/transform/index.d.ts +8 -0
  59. package/dist/catalog/general/transform/index.js +63 -0
  60. package/dist/catalog/index.d.ts +57 -0
  61. package/dist/catalog/index.js +168 -0
  62. package/dist/catalog/logic/condition/config.d.ts +54 -0
  63. package/dist/catalog/logic/condition/config.js +93 -0
  64. package/dist/catalog/logic/condition/index.d.ts +7 -0
  65. package/dist/catalog/logic/condition/index.js +64 -0
  66. package/dist/catalog/logic/for-each/config.d.ts +100 -0
  67. package/dist/catalog/logic/for-each/config.js +75 -0
  68. package/dist/catalog/logic/for-each/index.d.ts +7 -0
  69. package/dist/catalog/logic/for-each/index.js +92 -0
  70. package/dist/catalog/logic/for-each/pathOptions.d.ts +62 -0
  71. package/dist/catalog/logic/for-each/pathOptions.js +151 -0
  72. package/dist/catalog/logic/group/index.d.ts +15 -0
  73. package/dist/catalog/logic/group/index.js +46 -0
  74. package/dist/catalog/policies.d.ts +75 -0
  75. package/dist/catalog/policies.js +62 -0
  76. package/dist/catalog/storage/csv-action/index.d.ts +2 -0
  77. package/dist/catalog/storage/csv-action/index.js +38 -0
  78. package/dist/catalog/storage/dropbox-action/index.d.ts +2 -0
  79. package/dist/catalog/storage/dropbox-action/index.js +33 -0
  80. package/dist/catalog/storage/excel-action/index.d.ts +2 -0
  81. package/dist/catalog/storage/excel-action/index.js +32 -0
  82. package/dist/catalog/storage/file-action/index.d.ts +2 -0
  83. package/dist/catalog/storage/file-action/index.js +119 -0
  84. package/dist/catalog/storage/file-operation/config.d.ts +48 -0
  85. package/dist/catalog/storage/file-operation/config.js +45 -0
  86. package/dist/catalog/storage/file-operation/index.d.ts +8 -0
  87. package/dist/catalog/storage/file-operation/index.js +111 -0
  88. package/dist/catalog/storage/ftp-action/index.d.ts +2 -0
  89. package/dist/catalog/storage/ftp-action/index.js +33 -0
  90. package/dist/catalog/storage/google-drive-action/index.d.ts +2 -0
  91. package/dist/catalog/storage/google-drive-action/index.js +38 -0
  92. package/dist/catalog/storage/json-action/index.d.ts +2 -0
  93. package/dist/catalog/storage/json-action/index.js +31 -0
  94. package/dist/catalog/storage/onedrive-action/index.d.ts +2 -0
  95. package/dist/catalog/storage/onedrive-action/index.js +33 -0
  96. package/dist/catalog/storage/s3-action/index.d.ts +2 -0
  97. package/dist/catalog/storage/s3-action/index.js +36 -0
  98. package/dist/catalog/storage/storage-action/index.d.ts +13 -0
  99. package/dist/catalog/storage/storage-action/index.js +72 -0
  100. package/dist/catalog/storage/storageCapabilities.d.ts +57 -0
  101. package/dist/catalog/storage/storageCapabilities.js +207 -0
  102. package/dist/catalog/storage/xml-action/index.d.ts +2 -0
  103. package/dist/catalog/storage/xml-action/index.js +31 -0
  104. package/dist/catalog/transforms/format/config.d.ts +23 -0
  105. package/dist/catalog/transforms/format/config.js +19 -0
  106. package/dist/catalog/transforms/format/index.d.ts +5 -0
  107. package/dist/catalog/transforms/format/index.js +39 -0
  108. package/dist/catalog/triggers/connector-trigger/index.d.ts +7 -0
  109. package/dist/catalog/triggers/connector-trigger/index.js +72 -0
  110. package/dist/catalog/triggers/manual-trigger/config.d.ts +40 -0
  111. package/dist/catalog/triggers/manual-trigger/config.js +60 -0
  112. package/dist/catalog/triggers/manual-trigger/index.d.ts +10 -0
  113. package/dist/catalog/triggers/manual-trigger/index.js +74 -0
  114. package/dist/catalog/triggers/schedule-trigger/config.d.ts +42 -0
  115. package/dist/catalog/triggers/schedule-trigger/config.js +42 -0
  116. package/dist/catalog/triggers/schedule-trigger/index.d.ts +7 -0
  117. package/dist/catalog/triggers/schedule-trigger/index.js +102 -0
  118. package/dist/catalog/triggers/webhook-trigger/config.d.ts +31 -0
  119. package/dist/catalog/triggers/webhook-trigger/config.js +27 -0
  120. package/dist/catalog/triggers/webhook-trigger/index.d.ts +7 -0
  121. package/dist/catalog/triggers/webhook-trigger/index.js +89 -0
  122. package/dist/catalog/types.d.ts +360 -0
  123. package/dist/catalog/types.js +135 -0
  124. package/dist/catalog/utility/debug/config.d.ts +72 -0
  125. package/dist/catalog/utility/debug/config.js +90 -0
  126. package/dist/catalog/utility/debug/index.d.ts +11 -0
  127. package/dist/catalog/utility/debug/index.js +38 -0
  128. package/dist/catalog/utility/error/config.d.ts +26 -0
  129. package/dist/catalog/utility/error/config.js +25 -0
  130. package/dist/catalog/utility/error/index.d.ts +7 -0
  131. package/dist/catalog/utility/error/index.js +46 -0
  132. package/dist/catalog/utility/variables/config.d.ts +76 -0
  133. package/dist/catalog/utility/variables/config.js +70 -0
  134. package/dist/catalog/utility/variables/index.d.ts +13 -0
  135. package/dist/catalog/utility/variables/index.js +40 -0
  136. package/dist/catalog/workflow.d.ts +308 -0
  137. package/dist/catalog/workflow.js +25 -0
  138. package/dist/ids.d.ts +31 -0
  139. package/dist/ids.js +53 -0
  140. package/dist/index.d.ts +25 -0
  141. package/dist/index.js +28 -0
  142. package/dist/rules/nodeConfigStatus.d.ts +33 -0
  143. package/dist/rules/nodeConfigStatus.js +217 -0
  144. package/dist/rules/workflowValidator.d.ts +53 -0
  145. package/dist/rules/workflowValidator.js +358 -0
  146. package/package.json +41 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Slack Message Action
3
+ */
4
+ import { ActionCategory, ActionType, ActionStatus, FieldType } from '../../types';
5
+ export const slackMessageDefinition = {
6
+ id: 'slack_message',
7
+ name: 'Slack',
8
+ description: 'Send messages to Slack channels or users',
9
+ category: ActionCategory.Communication,
10
+ type: ActionType.SlackMessage,
11
+ tags: ['communication', 'slack', 'chat', 'built-in'],
12
+ status: ActionStatus.Stable,
13
+ icon: 'brand:slack',
14
+ color: '#4A154B',
15
+ inputSchema: {
16
+ fields: [
17
+ { key: 'connection', label: 'Slack Workspace', type: FieldType.Connection, validation: { required: true } },
18
+ { key: 'channel', label: 'Channel/User', type: FieldType.String, validation: { required: true } },
19
+ { key: 'message', label: 'Message', type: FieldType.String, validation: { required: true } },
20
+ { key: 'blocks', label: 'Blocks (JSON)', type: FieldType.JSON, validation: { required: false } },
21
+ ],
22
+ },
23
+ outputSchema: {
24
+ type: 'object',
25
+ properties: [
26
+ { key: 'success', type: FieldType.Boolean, description: 'Whether message was sent' },
27
+ { key: 'timestamp', type: FieldType.String, description: 'Message timestamp' },
28
+ ],
29
+ sampleOutput: { success: true, timestamp: '1234567890.123456' },
30
+ },
31
+ version: '1.0.0',
32
+ createdAt: '2025-01-01T00:00:00Z',
33
+ updatedAt: '2025-12-15T00:00:00Z',
34
+ createdBy: 'system',
35
+ isOfficial: true,
36
+ testable: true,
37
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Teams Message Configuration
3
+ */
4
+ export interface TeamsMessageConfigType {
5
+ /** Teams connector instance id (OAuth). */
6
+ connection: string;
7
+ /** Target team id + human-readable name (for logs/labels). */
8
+ teamId: string;
9
+ teamName?: string;
10
+ /** Target channel id + human-readable name. */
11
+ channelId: string;
12
+ channelName?: string;
13
+ /** Optional message subject. */
14
+ title?: string;
15
+ /** Message body. */
16
+ message: string;
17
+ }
18
+ export declare const TeamsMessageConfig: {
19
+ defaults: TeamsMessageConfigType;
20
+ schema: {
21
+ connection: {
22
+ type: string;
23
+ required: boolean;
24
+ };
25
+ teamId: {
26
+ type: string;
27
+ required: boolean;
28
+ };
29
+ channelId: {
30
+ type: string;
31
+ required: boolean;
32
+ };
33
+ title: {
34
+ type: string;
35
+ required: boolean;
36
+ };
37
+ message: {
38
+ type: string;
39
+ required: boolean;
40
+ };
41
+ };
42
+ validate: (config: Partial<TeamsMessageConfigType>) => {
43
+ valid: boolean;
44
+ errors: string[];
45
+ };
46
+ merge: (userConfig: Partial<TeamsMessageConfigType>) => TeamsMessageConfigType;
47
+ getLabel: (config: TeamsMessageConfigType) => string;
48
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Teams Message Configuration
3
+ */
4
+ export const TeamsMessageConfig = {
5
+ defaults: { connection: '', teamId: '', teamName: '', channelId: '', channelName: '', title: '', message: '' },
6
+ schema: {
7
+ connection: { type: 'connection', required: true },
8
+ teamId: { type: 'string', required: true },
9
+ channelId: { type: 'string', required: true },
10
+ title: { type: 'string', required: false },
11
+ message: { type: 'string', required: true },
12
+ },
13
+ validate: (config) => {
14
+ const errors = [];
15
+ if (!config.connection)
16
+ errors.push('Connect a Microsoft Teams account');
17
+ if (!config.teamId)
18
+ errors.push('Pick a team');
19
+ if (!config.channelId)
20
+ errors.push('Pick a channel');
21
+ if (!config.message)
22
+ errors.push('Add a message');
23
+ return { valid: errors.length === 0, errors };
24
+ },
25
+ merge: (userConfig) => {
26
+ return { ...TeamsMessageConfig.defaults, ...userConfig };
27
+ },
28
+ getLabel: (config) => (config.channelName ? `Teams: #${config.channelName}` : 'Teams'),
29
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Teams Message Action
3
+ */
4
+ import { ActionDefinition } from '../../types';
5
+ export declare const teamsMessageDefinition: ActionDefinition;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Teams Message Action
3
+ */
4
+ import { ActionCategory, ActionType, ActionStatus, FieldType } from '../../types';
5
+ export const teamsMessageDefinition = {
6
+ id: 'teams_message',
7
+ name: 'Teams',
8
+ description: 'Post messages to Microsoft Teams channels via OAuth 2.0',
9
+ category: ActionCategory.Communication,
10
+ type: ActionType.TeamsMessage,
11
+ tags: ['communication', 'teams', 'microsoft', 'chat', 'built-in'],
12
+ status: ActionStatus.Stable,
13
+ icon: 'brand:teams',
14
+ color: '#4B53BC',
15
+ inputSchema: {
16
+ fields: [
17
+ { key: 'connection', label: 'Teams Account', type: FieldType.Connection, validation: { required: true } },
18
+ { key: 'teamId', label: 'Team', type: FieldType.String, validation: { required: true } },
19
+ { key: 'channelId', label: 'Channel', type: FieldType.String, validation: { required: true } },
20
+ { key: 'title', label: 'Subject', type: FieldType.String, validation: { required: false } },
21
+ { key: 'message', label: 'Message', type: FieldType.String, validation: { required: true } },
22
+ ],
23
+ },
24
+ outputSchema: {
25
+ type: 'object',
26
+ properties: [
27
+ { key: 'ok', type: FieldType.Boolean, description: 'Whether the message was sent' },
28
+ { key: 'id', type: FieldType.String, description: 'Sent message id' },
29
+ { key: 'webUrl', type: FieldType.String, description: 'Deep link to the message' },
30
+ ],
31
+ sampleOutput: { ok: true, id: '1700000000000', webUrl: 'https://teams.microsoft.com/l/message/...' },
32
+ },
33
+ version: '1.0.0',
34
+ createdAt: '2025-01-01T00:00:00Z',
35
+ updatedAt: '2025-12-15T00:00:00Z',
36
+ createdBy: 'system',
37
+ isOfficial: true,
38
+ testable: true,
39
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Webhook Call Configuration
3
+ */
4
+ export interface WebhookCallConfigType {
5
+ url: string;
6
+ method: 'POST' | 'PUT' | 'PATCH' | 'GET';
7
+ payload?: Record<string, unknown>;
8
+ headers?: Record<string, string>;
9
+ }
10
+ export declare const WebhookCallConfig: {
11
+ defaults: WebhookCallConfigType;
12
+ schema: {
13
+ url: {
14
+ type: string;
15
+ required: boolean;
16
+ };
17
+ method: {
18
+ type: string;
19
+ required: boolean;
20
+ };
21
+ payload: {
22
+ type: string;
23
+ required: boolean;
24
+ };
25
+ headers: {
26
+ type: string;
27
+ required: boolean;
28
+ };
29
+ };
30
+ validate: (config: Partial<WebhookCallConfigType>) => {
31
+ valid: boolean;
32
+ errors: string[];
33
+ };
34
+ merge: (userConfig: Partial<WebhookCallConfigType>) => WebhookCallConfigType;
35
+ getLabel: (config: WebhookCallConfigType) => string;
36
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Webhook Call Configuration
3
+ */
4
+ export const WebhookCallConfig = {
5
+ defaults: {
6
+ url: '',
7
+ method: 'POST',
8
+ payload: {},
9
+ headers: {},
10
+ },
11
+ schema: {
12
+ url: { type: 'url', required: true },
13
+ method: { type: 'select', required: true },
14
+ payload: { type: 'json', required: false },
15
+ headers: { type: 'json', required: false },
16
+ },
17
+ validate: (config) => {
18
+ const errors = [];
19
+ if (!config.url)
20
+ errors.push('Webhook URL is required');
21
+ if (!config.method)
22
+ errors.push('HTTP method is required');
23
+ return { valid: errors.length === 0, errors };
24
+ },
25
+ merge: (userConfig) => {
26
+ return { ...WebhookCallConfig.defaults, ...userConfig };
27
+ },
28
+ getLabel: (config) => {
29
+ return `${config.method}: ${config.url.substring(0, 40)}...`;
30
+ },
31
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Webhook Call Action
3
+ */
4
+ import { ActionDefinition } from '../../types';
5
+ export declare const webhookCallDefinition: ActionDefinition;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Webhook Call Action
3
+ */
4
+ import { ActionCategory, ActionType, ActionStatus, FieldType } from '../../types';
5
+ export const webhookCallDefinition = {
6
+ id: 'webhook_call',
7
+ name: 'Webhook Call',
8
+ description: 'Call external webhooks with custom payloads',
9
+ category: ActionCategory.Communication,
10
+ type: ActionType.WebhookCall,
11
+ tags: ['communication', 'webhook', 'http', 'built-in'],
12
+ status: ActionStatus.Stable,
13
+ icon: 'Webhook',
14
+ color: '#0043ce',
15
+ inputSchema: {
16
+ fields: [
17
+ { key: 'url', label: 'Webhook URL', type: FieldType.URL, validation: { required: true } },
18
+ { key: 'method', label: 'Method', type: FieldType.Select, options: [
19
+ { label: 'POST', value: 'POST' },
20
+ { label: 'PUT', value: 'PUT' },
21
+ { label: 'PATCH', value: 'PATCH' },
22
+ { label: 'GET', value: 'GET' },
23
+ ], defaultValue: 'POST', validation: { required: true } },
24
+ { key: 'payload', label: 'Payload', type: FieldType.JSON, validation: { required: false } },
25
+ { key: 'headers', label: 'Headers', type: FieldType.JSON, validation: { required: false } },
26
+ ],
27
+ },
28
+ outputSchema: {
29
+ type: 'object',
30
+ properties: [
31
+ { key: 'statusCode', type: FieldType.Number, description: 'HTTP status code' },
32
+ { key: 'response', type: FieldType.JSON, description: 'Response body' },
33
+ { key: 'success', type: FieldType.Boolean, description: 'Whether call succeeded' },
34
+ ],
35
+ sampleOutput: { statusCode: 200, response: {}, success: true },
36
+ },
37
+ version: '1.0.0',
38
+ createdAt: '2025-01-01T00:00:00Z',
39
+ updatedAt: '2025-12-15T00:00:00Z',
40
+ createdBy: 'system',
41
+ isOfficial: true,
42
+ testable: true,
43
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * WhatsApp Send — config contract (DEV-285)
3
+ */
4
+ export interface WhatsappSendConfigType {
5
+ connection: string;
6
+ to: string;
7
+ mode: 'template' | 'text';
8
+ templateName?: string;
9
+ templateLanguage?: string;
10
+ /** Positional body variables, in {{1}}, {{2}} order. */
11
+ templateVariables?: string[];
12
+ text?: string;
13
+ previewUrl?: boolean;
14
+ }
15
+ export declare const WhatsappSendConfig: {
16
+ defaults: WhatsappSendConfigType;
17
+ validate: (config: Partial<WhatsappSendConfigType>) => {
18
+ valid: boolean;
19
+ errors: string[];
20
+ };
21
+ merge: (userConfig: Partial<WhatsappSendConfigType>) => WhatsappSendConfigType;
22
+ getLabel: (config: WhatsappSendConfigType) => string;
23
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * WhatsApp Send — config contract (DEV-285)
3
+ */
4
+ export const WhatsappSendConfig = {
5
+ // Template is the default because it is the mode that always delivers;
6
+ // freeform silently depends on a 24-hour window the author can't see.
7
+ defaults: {
8
+ connection: '',
9
+ to: '',
10
+ mode: 'template',
11
+ templateLanguage: 'en_US',
12
+ templateVariables: [],
13
+ },
14
+ validate: (config) => {
15
+ const errors = [];
16
+ if (!config.connection)
17
+ errors.push('Select a WhatsApp connection');
18
+ if (!config.to?.trim())
19
+ errors.push('Recipient phone number is required');
20
+ if (config.mode === 'text') {
21
+ if (!config.text?.trim())
22
+ errors.push('Message text is required');
23
+ }
24
+ else {
25
+ if (!config.templateName?.trim())
26
+ errors.push('Choose an approved template');
27
+ }
28
+ return { valid: errors.length === 0, errors };
29
+ },
30
+ merge: (userConfig) => {
31
+ return { ...WhatsappSendConfig.defaults, ...userConfig };
32
+ },
33
+ getLabel: (config) => config.mode === 'text'
34
+ ? `WhatsApp to ${config.to || '—'}`
35
+ : `WhatsApp template "${config.templateName || '—'}" to ${config.to || '—'}`,
36
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * WhatsApp Send Action (DEV-285)
3
+ *
4
+ * Two modes, because WhatsApp has two genuinely different sends:
5
+ * template — the ONLY thing that delivers outside the 24-hour
6
+ * customer-service window. Meta charges by the template's
7
+ * CATEGORY (Marketing costs ~6× Utility), so the picker shows it.
8
+ * text — freeform; delivers only within 24 hours of the contact's last
9
+ * inbound message.
10
+ *
11
+ * A single "message" box would look like it works in testing and then fail
12
+ * the next day — which is why mode is an explicit, required choice.
13
+ */
14
+ import { ActionDefinition } from '../../types';
15
+ export declare const whatsappSendDefinition: ActionDefinition;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * WhatsApp Send Action (DEV-285)
3
+ *
4
+ * Two modes, because WhatsApp has two genuinely different sends:
5
+ * template — the ONLY thing that delivers outside the 24-hour
6
+ * customer-service window. Meta charges by the template's
7
+ * CATEGORY (Marketing costs ~6× Utility), so the picker shows it.
8
+ * text — freeform; delivers only within 24 hours of the contact's last
9
+ * inbound message.
10
+ *
11
+ * A single "message" box would look like it works in testing and then fail
12
+ * the next day — which is why mode is an explicit, required choice.
13
+ */
14
+ import { ActionCategory, ActionType, ActionStatus, FieldType } from '../../types';
15
+ export const whatsappSendDefinition = {
16
+ id: 'whatsapp_send',
17
+ name: 'WhatsApp',
18
+ description: 'Send a WhatsApp message — an approved template, or freeform text inside the 24-hour reply window',
19
+ category: ActionCategory.Communication,
20
+ type: ActionType.WhatsappSend,
21
+ tags: ['communication', 'whatsapp', 'messaging', 'template', 'built-in'],
22
+ status: ActionStatus.Beta,
23
+ icon: 'brand:whatsapp',
24
+ color: '#25D366',
25
+ inputSchema: {
26
+ fields: [
27
+ { key: 'connection', label: 'WhatsApp Connection', type: FieldType.Connection, validation: { required: true } },
28
+ { key: 'to', label: 'To (phone number)', type: FieldType.String, validation: { required: true } },
29
+ { key: 'mode', label: 'Message Type', type: FieldType.Select, validation: { required: true } },
30
+ { key: 'templateName', label: 'Template', type: FieldType.String, validation: { required: false } },
31
+ { key: 'templateLanguage', label: 'Template Language', type: FieldType.String, validation: { required: false } },
32
+ { key: 'templateVariables', label: 'Template Variables', type: FieldType.JSON, validation: { required: false } },
33
+ { key: 'text', label: 'Message', type: FieldType.String, validation: { required: false } },
34
+ ],
35
+ },
36
+ outputSchema: {
37
+ type: 'object',
38
+ properties: [
39
+ { key: 'ok', type: FieldType.Boolean, description: 'Whether WhatsApp accepted the message' },
40
+ { key: 'messageId', type: FieldType.String, description: 'WhatsApp message ID (wamid…)' },
41
+ { key: 'waId', type: FieldType.String, description: "Recipient's resolved WhatsApp ID" },
42
+ { key: 'mode', type: FieldType.String, description: 'template | text' },
43
+ ],
44
+ sampleOutput: {
45
+ ok: true,
46
+ messageId: 'wamid.HBgMOTE4ODAyODg1MTQ1FQIAERgSN0YxN0E5RkQ5MEQ4RkE5QzFEAA==',
47
+ waId: '919876543210',
48
+ mode: 'template',
49
+ },
50
+ },
51
+ version: '1.0.0',
52
+ createdAt: '2026-07-30T00:00:00Z',
53
+ updatedAt: '2026-07-30T00:00:00Z',
54
+ createdBy: 'system',
55
+ isOfficial: true,
56
+ testable: true,
57
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Build Query Configuration
3
+ *
4
+ * Configuration utilities and validation for the Build Query action
5
+ * Supports dual modes: Visual Builder (no-code) and SQL Editor (advanced)
6
+ */
7
+ import { BuildQueryConfig, QueryMode, QueryType, QueryValidationResult, VisualQueryConfig, SQLQueryConfig } from './types';
8
+ export declare const BuildQueryConfigDefaults: {
9
+ mode: QueryMode;
10
+ queryType: QueryType;
11
+ timeout: number;
12
+ maxRows: number;
13
+ visualConfig: VisualQueryConfig;
14
+ sqlConfig: SQLQueryConfig;
15
+ };
16
+ /**
17
+ * Validate Build Query configuration
18
+ */
19
+ export declare const validateBuildQueryConfig: (config: Partial<BuildQueryConfig>) => QueryValidationResult;
20
+ /**
21
+ * Merge user config with defaults
22
+ */
23
+ export declare const mergeBuildQueryConfig: (userConfig: Partial<BuildQueryConfig>) => BuildQueryConfig;
24
+ /**
25
+ * Get display label for configuration
26
+ */
27
+ export declare const getBuildQueryLabel: (config: BuildQueryConfig) => string;
28
+ /**
29
+ * Check if a connector is queryable (excludes storage-type connectors)
30
+ * Uses the isQueryable flag from connector metadata if available
31
+ */
32
+ export declare function isQueryableConnector(connector: {
33
+ type?: string;
34
+ category?: string;
35
+ isQueryable?: boolean;
36
+ }): boolean;