@keystrokehq/salesforce 0.0.1

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 (57) hide show
  1. package/README.md +205 -0
  2. package/dist/_official/index.d.mts +42 -0
  3. package/dist/_official/index.mjs +3 -0
  4. package/dist/_runtime/index.d.mts +6 -0
  5. package/dist/_runtime/index.mjs +89 -0
  6. package/dist/accounts.d.mts +97 -0
  7. package/dist/accounts.mjs +30 -0
  8. package/dist/associations.d.mts +40 -0
  9. package/dist/associations.mjs +70 -0
  10. package/dist/campaign-members.d.mts +97 -0
  11. package/dist/campaign-members.mjs +27 -0
  12. package/dist/campaigns.d.mts +97 -0
  13. package/dist/campaigns.mjs +28 -0
  14. package/dist/cases.d.mts +97 -0
  15. package/dist/cases.mjs +30 -0
  16. package/dist/client.d.mts +8 -0
  17. package/dist/client.mjs +26 -0
  18. package/dist/common-BUAhHMqn.mjs +28 -0
  19. package/dist/connection.d.mts +2 -0
  20. package/dist/connection.mjs +3 -0
  21. package/dist/contacts.d.mts +97 -0
  22. package/dist/contacts.mjs +29 -0
  23. package/dist/dashboards.d.mts +32 -0
  24. package/dist/dashboards.mjs +44 -0
  25. package/dist/factory-BBQAdBIT.mjs +8 -0
  26. package/dist/index.d.mts +1 -0
  27. package/dist/index.mjs +1 -0
  28. package/dist/integration-CGYEE2Ge.d.mts +62 -0
  29. package/dist/integration-C_hbWu9t.mjs +131 -0
  30. package/dist/leads.d.mts +97 -0
  31. package/dist/leads.mjs +30 -0
  32. package/dist/messaging.d.mts +1 -0
  33. package/dist/messaging.mjs +1 -0
  34. package/dist/notes.d.mts +97 -0
  35. package/dist/notes.mjs +26 -0
  36. package/dist/objects.d.mts +23 -0
  37. package/dist/objects.mjs +31 -0
  38. package/dist/opportunities.d.mts +97 -0
  39. package/dist/opportunities.mjs +29 -0
  40. package/dist/opportunity-line-items.d.mts +97 -0
  41. package/dist/opportunity-line-items.mjs +29 -0
  42. package/dist/ownership.d.mts +25 -0
  43. package/dist/ownership.mjs +49 -0
  44. package/dist/reports.d.mts +40 -0
  45. package/dist/reports.mjs +59 -0
  46. package/dist/schemas/index.d.mts +40 -0
  47. package/dist/schemas/index.mjs +3 -0
  48. package/dist/shared-B8YQavkg.mjs +196 -0
  49. package/dist/soql.d.mts +47 -0
  50. package/dist/soql.mjs +30 -0
  51. package/dist/tasks.d.mts +97 -0
  52. package/dist/tasks.mjs +29 -0
  53. package/dist/triggers.d.mts +83 -0
  54. package/dist/triggers.mjs +318 -0
  55. package/dist/users.d.mts +14 -0
  56. package/dist/users.mjs +20 -0
  57. package/package.json +153 -0
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # @keystrokehq/salesforce
2
+
3
+ Salesforce CRM and platform integration for Keystroke workflows.
4
+
5
+ ## Overview
6
+
7
+ This package provides:
8
+
9
+ - Explicit support surfaces for `connection`, `client`, `schemas`, `triggers`, and CRM domain modules
10
+ - CRUD-backed Salesforce record operations for accounts, contacts, leads, opportunities, cases, tasks, campaigns, campaign members, opportunity line items, and notes
11
+ - Focused Salesforce helpers for contact-account associations, ownership transfer, current-user identity, SOQL pagination, reports, and dashboards
12
+ - Direct-binding polling triggers for common Salesforce record activity with stable `eventType` payloads
13
+ - A thin JSforce client wrapper for resolved OAuth credentials
14
+
15
+ The package root is intentionally non-canonical. Import from explicit subpaths instead of `@keystrokehq/salesforce`.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pnpm add @keystrokehq/salesforce
21
+ ```
22
+
23
+ ## Credentials
24
+
25
+ The public Salesforce connection exposes two OAuth credentials to workflow authors:
26
+
27
+ - `SALESFORCE_ACCESS_TOKEN`
28
+ - `SALESFORCE_INSTANCE_URL`
29
+
30
+ ```ts
31
+ import { salesforce } from '@keystrokehq/salesforce/connection';
32
+ ```
33
+
34
+ The internal Salesforce Connected App credential set stores `clientId` and `clientSecret` separately from the public runtime auth contract.
35
+
36
+ For sandbox tenants, the provider app metadata can set either:
37
+
38
+ - `environment: "sandbox"`
39
+ - `loginBaseUrl: "https://test.salesforce.com"`
40
+
41
+ ## Operations
42
+
43
+ Operations are regular Keystroke steps, so call them with `.run(...)` inside workflow code.
44
+
45
+ ```ts
46
+ import { Workflow } from '@keystrokehq/core';
47
+ import { z } from 'zod';
48
+ import { getAccount } from '@keystrokehq/salesforce/accounts';
49
+ import { associateContactToAccount } from '@keystrokehq/salesforce/associations';
50
+ import { createLead } from '@keystrokehq/salesforce/leads';
51
+ import { queryMore, runSoqlQuery } from '@keystrokehq/salesforce/soql';
52
+
53
+ export const salesforceFollowUpWorkflow = new Workflow({
54
+ id: 'salesforce-follow-up',
55
+ name: 'Salesforce Follow Up',
56
+ input: z.object({ accountId: z.string() }),
57
+ output: z.object({ success: z.boolean() }),
58
+ run: async (input) => {
59
+ const account = await getAccount.run({
60
+ id: input.accountId,
61
+ fields: ['Id', 'Name', 'Industry', 'LastModifiedDate'],
62
+ });
63
+
64
+ await createLead.run({
65
+ fields: {
66
+ FirstName: 'Avery',
67
+ LastName: 'Stone',
68
+ Company: account.Name ?? 'Unknown',
69
+ Status: 'Open - Not Contacted',
70
+ },
71
+ returnFields: ['Id', 'FirstName', 'LastName', 'Company', 'Status'],
72
+ });
73
+
74
+ const recentContacts = await runSoqlQuery.run({
75
+ query:
76
+ "SELECT Id, FirstName, LastName, Email FROM Contact WHERE AccountId != NULL ORDER BY LastModifiedDate DESC LIMIT 10",
77
+ });
78
+
79
+ if (recentContacts.records[0]?.Id) {
80
+ await associateContactToAccount.run({
81
+ contactId: recentContacts.records[0].Id,
82
+ accountId: input.accountId,
83
+ });
84
+ }
85
+
86
+ if (recentContacts.nextRecordsUrl) {
87
+ await queryMore.run({ nextRecordsUrl: recentContacts.nextRecordsUrl });
88
+ }
89
+
90
+ return { success: recentContacts.records.length >= 0 };
91
+ },
92
+ });
93
+ ```
94
+
95
+ Additional helpers are available from:
96
+
97
+ - `@keystrokehq/salesforce/associations`
98
+ - `@keystrokehq/salesforce/campaign-members`
99
+ - `@keystrokehq/salesforce/opportunity-line-items`
100
+ - `@keystrokehq/salesforce/ownership`
101
+ - `@keystrokehq/salesforce/users`
102
+
103
+ ## Triggers
104
+
105
+ Salesforce trigger helpers are direct-binding only. Call the helper once with optional `name`, `description`, `schedule`, `filter`, or `transform` fields and use the returned bound trigger in your workflow.
106
+
107
+ Every mapped trigger payload includes:
108
+
109
+ - `eventType`: a stable event identifier such as `lead.created` or `task.completed`
110
+ - `objectName`: the Salesforce object being polled
111
+ - `records`: normalized Salesforce records
112
+ - `taskEventType`: present for task triggers so created vs. completed is explicit in filters and transforms
113
+
114
+ ```ts
115
+ import { polling } from '@keystrokehq/salesforce/triggers';
116
+
117
+ const newLeadTrigger = polling.newLead({
118
+ name: 'Salesforce New Lead',
119
+ schedule: '*/10 * * * *',
120
+ transform: (payload) => ({
121
+ eventType: payload.eventType,
122
+ leadIds: payload.records
123
+ .map((record) => (typeof record.Id === 'string' ? record.Id : undefined))
124
+ .filter((value): value is string => value !== undefined),
125
+ count: payload.records.length,
126
+ }),
127
+ });
128
+
129
+ const opportunityTrigger = polling.opportunityCreatedOrUpdated({
130
+ stages: ['Prospecting', 'Closed Won'],
131
+ schedule: '15m',
132
+ });
133
+
134
+ void newLeadTrigger;
135
+ void opportunityTrigger;
136
+ ```
137
+
138
+ Use `polling.sObjectRecordUpdated(...)` when you need a generic object poller with custom `fields`, `watermarkField`, and `where` filters.
139
+
140
+ ## Analytics
141
+
142
+ Analytics helpers expose low-risk report and dashboard endpoints:
143
+
144
+ - `listReports`, `listReportTypes`, `getReportMetadata`, `runReport`
145
+ - `listDashboards`, `getDashboard`, `refreshDashboard`
146
+
147
+ The `refreshDashboard` operation is marked `needsApproval: true` because it triggers a dashboard refresh job.
148
+
149
+ ## Testing
150
+
151
+ This package now uses the repo’s two-project Vitest layout:
152
+
153
+ - `pnpm test:unit` for deterministic unit tests
154
+ - `pnpm test:int` for deterministic integration tests and env-gated live Salesforce smoke tests
155
+
156
+ The package coverage inventory lives in `TEST_MATRIX.md`.
157
+
158
+ Deterministic integration coverage does not require live Salesforce credentials. It uses package-local `*.int.test.ts` files to exercise:
159
+
160
+ - every exported operation in `src/operations.ts`
161
+ - trigger polling behavior with realistic mapped payloads
162
+ - client error normalization and auth failure handling
163
+ - schema and shared query/mutation helpers
164
+
165
+ Live Salesforce tests are opt-in and stay skipped unless all required env values exist in `.env.test`:
166
+
167
+ - `RUN_LIVE_INT="true"`
168
+ - `SALESFORCE_ACCESS_TOKEN`
169
+ - `SALESFORCE_INSTANCE_URL`
170
+
171
+ Optional live analytics and line-item smoke tests also use:
172
+
173
+ - `SALESFORCE_TEST_REPORT_ID`
174
+ - `SALESFORCE_TEST_DASHBOARD_ID`
175
+ - `SALESFORCE_TEST_PRICEBOOK_ENTRY_ID`
176
+
177
+ Use a Salesforce sandbox or scratch org only.
178
+
179
+ ## High-Risk Follow-Ups
180
+
181
+ The initial package intentionally leaves a few Salesforce-specific behaviors as separately scoped follow-up work. See `HIGH_RISK_BEHAVIORS.md` for the current decision notes around assignment rules, cloning, outbound email, and richer trigger semantics.
182
+
183
+ ## Canonical Imports
184
+
185
+ - `@keystrokehq/salesforce/connection`
186
+ - `@keystrokehq/salesforce/client`
187
+ - `@keystrokehq/salesforce/schemas`
188
+ - `@keystrokehq/salesforce/triggers`
189
+ - `@keystrokehq/salesforce/accounts`
190
+ - `@keystrokehq/salesforce/associations`
191
+ - `@keystrokehq/salesforce/campaign-members`
192
+ - `@keystrokehq/salesforce/contacts`
193
+ - `@keystrokehq/salesforce/leads`
194
+ - `@keystrokehq/salesforce/opportunities`
195
+ - `@keystrokehq/salesforce/opportunity-line-items`
196
+ - `@keystrokehq/salesforce/ownership`
197
+ - `@keystrokehq/salesforce/cases`
198
+ - `@keystrokehq/salesforce/tasks`
199
+ - `@keystrokehq/salesforce/campaigns`
200
+ - `@keystrokehq/salesforce/notes`
201
+ - `@keystrokehq/salesforce/users`
202
+ - `@keystrokehq/salesforce/soql`
203
+ - `@keystrokehq/salesforce/objects`
204
+ - `@keystrokehq/salesforce/reports`
205
+ - `@keystrokehq/salesforce/dashboards`
@@ -0,0 +1,42 @@
1
+ import { i as salesforceOfficialIntegration, r as salesforceBundle } from "../integration-CGYEE2Ge.mjs";
2
+ import { z } from "zod";
3
+ import { CredentialSet } from "@keystrokehq/core";
4
+ import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
5
+ import { InferCredentialSetAuth } from "@keystrokehq/core/credential-set";
6
+
7
+ //#region src/_official/provider-app.d.ts
8
+ declare const salesforceAppCredentialSet: CredentialSet<"salesforce-app", z.ZodObject<{
9
+ clientId: z.ZodString;
10
+ clientSecret: z.ZodString;
11
+ }, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
12
+ clientId: z.ZodString;
13
+ clientSecret: z.ZodString;
14
+ }, z.core.$strip>>[] | undefined>;
15
+ declare const salesforcePlatformProviderSeed: {
16
+ readonly provider: "salesforce";
17
+ readonly appRef: "salesforce-platform";
18
+ readonly displayName: "Salesforce Platform";
19
+ readonly credentialSetName: "Keystroke Salesforce Platform App";
20
+ readonly envShape: {
21
+ readonly KEYSTROKE_PLATFORM_SALESFORCE_CLIENT_ID: z.ZodOptional<z.ZodString>;
22
+ readonly KEYSTROKE_PLATFORM_SALESFORCE_CLIENT_SECRET: z.ZodOptional<z.ZodString>;
23
+ readonly KEYSTROKE_PLATFORM_SALESFORCE_ENVIRONMENT: z.ZodOptional<z.ZodEnum<{
24
+ production: "production";
25
+ sandbox: "sandbox";
26
+ }>>;
27
+ readonly KEYSTROKE_PLATFORM_SALESFORCE_LOGIN_BASE_URL: z.ZodOptional<z.ZodString>;
28
+ };
29
+ readonly requiredEnvKeys: readonly ["KEYSTROKE_PLATFORM_SALESFORCE_CLIENT_ID", "KEYSTROKE_PLATFORM_SALESFORCE_CLIENT_SECRET"];
30
+ readonly externalAppIdEnvKey: "KEYSTROKE_PLATFORM_SALESFORCE_CLIENT_ID";
31
+ readonly buildCredentials: (env: Record<string, string | undefined>) => {
32
+ clientId: string | undefined;
33
+ clientSecret: string | undefined;
34
+ };
35
+ readonly buildMetadata: (env: Record<string, string | undefined>) => {
36
+ loginBaseUrl?: string | undefined;
37
+ environment?: string | undefined;
38
+ } | undefined;
39
+ };
40
+ type SalesforceAppCredentials = InferCredentialSetAuth<typeof salesforceAppCredentialSet>;
41
+ //#endregion
42
+ export { SalesforceAppCredentials, salesforceAppCredentialSet, salesforceBundle, salesforceOfficialIntegration, salesforcePlatformProviderSeed };
@@ -0,0 +1,3 @@
1
+ import { a as salesforcePlatformProviderSeed, i as salesforceAppCredentialSet, n as salesforceBundle, r as salesforceOfficialIntegration } from "../integration-C_hbWu9t.mjs";
2
+
3
+ export { salesforceAppCredentialSet, salesforceBundle, salesforceOfficialIntegration, salesforcePlatformProviderSeed };
@@ -0,0 +1,6 @@
1
+ import { AnyOperation } from "@keystrokehq/core/operation";
2
+
3
+ //#region src/operations.d.ts
4
+ declare const salesforceOperations: Readonly<Record<string, AnyOperation>>;
5
+ //#endregion
6
+ export { salesforceOperations };
@@ -0,0 +1,89 @@
1
+ import { createAccount, deleteAccount, getAccount, listAccounts, updateAccount } from "../accounts.mjs";
2
+ import { associateContactToAccount, dissociateContactFromAccount } from "../associations.mjs";
3
+ import { createCampaignMember, deleteCampaignMember, getCampaignMember, listCampaignMembers, updateCampaignMember } from "../campaign-members.mjs";
4
+ import { createCampaign, deleteCampaign, getCampaign, listCampaigns, updateCampaign } from "../campaigns.mjs";
5
+ import { createCase, deleteCase, getCase, listCases, updateCase } from "../cases.mjs";
6
+ import { createContact, deleteContact, getContact, listContacts, updateContact } from "../contacts.mjs";
7
+ import { getDashboard, listDashboards, refreshDashboard } from "../dashboards.mjs";
8
+ import { createLead, deleteLead, getLead, listLeads, updateLead } from "../leads.mjs";
9
+ import { createNote, deleteNote, getNote, listNotes, updateNote } from "../notes.mjs";
10
+ import { describeObject, listObjects } from "../objects.mjs";
11
+ import { createOpportunity, deleteOpportunity, getOpportunity, listOpportunities, updateOpportunity } from "../opportunities.mjs";
12
+ import { createOpportunityLineItem, deleteOpportunityLineItem, getOpportunityLineItem, listOpportunityLineItems, updateOpportunityLineItem } from "../opportunity-line-items.mjs";
13
+ import { transferRecordOwnership } from "../ownership.mjs";
14
+ import { getReportMetadata, listReportTypes, listReports, runReport } from "../reports.mjs";
15
+ import { queryMore, runSoqlQuery } from "../soql.mjs";
16
+ import { createTask, deleteTask, getTask, listTasks, updateTask } from "../tasks.mjs";
17
+ import { getCurrentUserInfo } from "../users.mjs";
18
+
19
+ //#region src/operations.ts
20
+ const salesforceOperations = {
21
+ get_account: getAccount,
22
+ list_accounts: listAccounts,
23
+ create_account: createAccount,
24
+ update_account: updateAccount,
25
+ delete_account: deleteAccount,
26
+ get_campaign: getCampaign,
27
+ list_campaigns: listCampaigns,
28
+ create_campaign: createCampaign,
29
+ update_campaign: updateCampaign,
30
+ delete_campaign: deleteCampaign,
31
+ get_campaign_member: getCampaignMember,
32
+ list_campaign_members: listCampaignMembers,
33
+ create_campaign_member: createCampaignMember,
34
+ update_campaign_member: updateCampaignMember,
35
+ delete_campaign_member: deleteCampaignMember,
36
+ get_contact: getContact,
37
+ list_contacts: listContacts,
38
+ create_contact: createContact,
39
+ update_contact: updateContact,
40
+ delete_contact: deleteContact,
41
+ associate_contact_to_account: associateContactToAccount,
42
+ dissociate_contact_from_account: dissociateContactFromAccount,
43
+ get_lead: getLead,
44
+ list_leads: listLeads,
45
+ create_lead: createLead,
46
+ update_lead: updateLead,
47
+ delete_lead: deleteLead,
48
+ get_opportunity: getOpportunity,
49
+ list_opportunities: listOpportunities,
50
+ create_opportunity: createOpportunity,
51
+ update_opportunity: updateOpportunity,
52
+ delete_opportunity: deleteOpportunity,
53
+ get_opportunity_line_item: getOpportunityLineItem,
54
+ list_opportunity_line_items: listOpportunityLineItems,
55
+ create_opportunity_line_item: createOpportunityLineItem,
56
+ update_opportunity_line_item: updateOpportunityLineItem,
57
+ delete_opportunity_line_item: deleteOpportunityLineItem,
58
+ get_case: getCase,
59
+ list_cases: listCases,
60
+ create_case: createCase,
61
+ update_case: updateCase,
62
+ delete_case: deleteCase,
63
+ get_note: getNote,
64
+ list_notes: listNotes,
65
+ create_note: createNote,
66
+ update_note: updateNote,
67
+ delete_note: deleteNote,
68
+ get_task: getTask,
69
+ list_tasks: listTasks,
70
+ create_task: createTask,
71
+ update_task: updateTask,
72
+ delete_task: deleteTask,
73
+ transfer_record_ownership: transferRecordOwnership,
74
+ get_current_user_info: getCurrentUserInfo,
75
+ run_soql_query: runSoqlQuery,
76
+ query_more: queryMore,
77
+ list_objects: listObjects,
78
+ describe_object: describeObject,
79
+ list_reports: listReports,
80
+ list_report_types: listReportTypes,
81
+ get_report_metadata: getReportMetadata,
82
+ run_report: runReport,
83
+ list_dashboards: listDashboards,
84
+ get_dashboard: getDashboard,
85
+ refresh_dashboard: refreshDashboard
86
+ };
87
+
88
+ //#endregion
89
+ export { salesforceOperations };
@@ -0,0 +1,97 @@
1
+ import * as zod from "zod";
2
+ import * as _keystrokehq_core0 from "@keystrokehq/core";
3
+ import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
4
+ import * as zod_v4_core0 from "zod/v4/core";
5
+
6
+ //#region src/accounts.d.ts
7
+ declare const getAccount: _keystrokehq_core0.Operation<zod.ZodObject<{
8
+ id: zod.ZodString;
9
+ fields: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
10
+ }, zod_v4_core0.$strip>, zod.ZodObject<{
11
+ Id: zod.ZodOptional<zod.ZodString>;
12
+ attributes: zod.ZodOptional<zod.ZodObject<{
13
+ type: zod.ZodString;
14
+ url: zod.ZodString;
15
+ }, zod_v4_core0.$strip>>;
16
+ }, zod_v4_core0.$catchall<zod.ZodUnknown>>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", zod.ZodObject<{
17
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
18
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
19
+ }, zod_v4_core0.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<zod.ZodObject<{
20
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
21
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
22
+ }, zod_v4_core0.$strip>>[] | undefined>], undefined>;
23
+ declare const listAccounts: _keystrokehq_core0.Operation<zod.ZodObject<{
24
+ fields: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
25
+ where: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodUnion<readonly [zod.ZodString, zod.ZodNumber, zod.ZodBoolean, zod.ZodNull]>>>;
26
+ orderBy: zod.ZodOptional<zod.ZodString>;
27
+ orderDirection: zod.ZodOptional<zod.ZodEnum<{
28
+ ASC: "ASC";
29
+ DESC: "DESC";
30
+ }>>;
31
+ limit: zod.ZodOptional<zod.ZodNumber>;
32
+ }, zod_v4_core0.$strip>, zod.ZodObject<{
33
+ totalSize: zod.ZodNumber;
34
+ done: zod.ZodBoolean;
35
+ nextRecordsUrl: zod.ZodOptional<zod.ZodString>;
36
+ records: zod.ZodArray<zod.ZodObject<{
37
+ Id: zod.ZodOptional<zod.ZodString>;
38
+ attributes: zod.ZodOptional<zod.ZodObject<{
39
+ type: zod.ZodString;
40
+ url: zod.ZodString;
41
+ }, zod_v4_core0.$strip>>;
42
+ }, zod_v4_core0.$catchall<zod.ZodUnknown>>>;
43
+ }, zod_v4_core0.$strip>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", zod.ZodObject<{
44
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
45
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
46
+ }, zod_v4_core0.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<zod.ZodObject<{
47
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
48
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
49
+ }, zod_v4_core0.$strip>>[] | undefined>], undefined>;
50
+ declare const createAccount: _keystrokehq_core0.Operation<zod.ZodObject<{
51
+ fields: zod.ZodRecord<zod.ZodString, zod.ZodUnknown>;
52
+ returnFields: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
53
+ }, zod_v4_core0.$strip>, zod.ZodObject<{
54
+ Id: zod.ZodOptional<zod.ZodString>;
55
+ attributes: zod.ZodOptional<zod.ZodObject<{
56
+ type: zod.ZodString;
57
+ url: zod.ZodString;
58
+ }, zod_v4_core0.$strip>>;
59
+ }, zod_v4_core0.$catchall<zod.ZodUnknown>>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", zod.ZodObject<{
60
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
61
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
62
+ }, zod_v4_core0.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<zod.ZodObject<{
63
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
64
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
65
+ }, zod_v4_core0.$strip>>[] | undefined>], undefined>;
66
+ declare const updateAccount: _keystrokehq_core0.Operation<zod.ZodObject<{
67
+ id: zod.ZodString;
68
+ fields: zod.ZodRecord<zod.ZodString, zod.ZodUnknown>;
69
+ returnFields: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
70
+ }, zod_v4_core0.$strip>, zod.ZodObject<{
71
+ Id: zod.ZodOptional<zod.ZodString>;
72
+ attributes: zod.ZodOptional<zod.ZodObject<{
73
+ type: zod.ZodString;
74
+ url: zod.ZodString;
75
+ }, zod_v4_core0.$strip>>;
76
+ }, zod_v4_core0.$catchall<zod.ZodUnknown>>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", zod.ZodObject<{
77
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
78
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
79
+ }, zod_v4_core0.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<zod.ZodObject<{
80
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
81
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
82
+ }, zod_v4_core0.$strip>>[] | undefined>], undefined>;
83
+ declare const deleteAccount: _keystrokehq_core0.Operation<zod.ZodObject<{
84
+ id: zod.ZodString;
85
+ }, zod_v4_core0.$strip>, zod.ZodObject<{
86
+ success: zod.ZodBoolean;
87
+ id: zod.ZodOptional<zod.ZodString>;
88
+ errors: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
89
+ }, zod_v4_core0.$strip>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", zod.ZodObject<{
90
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
91
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
92
+ }, zod_v4_core0.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<zod.ZodObject<{
93
+ SALESFORCE_ACCESS_TOKEN: zod.ZodString;
94
+ SALESFORCE_INSTANCE_URL: zod.ZodURL;
95
+ }, zod_v4_core0.$strip>>[] | undefined>], undefined>;
96
+ //#endregion
97
+ export { createAccount, deleteAccount, getAccount, listAccounts, updateAccount };
@@ -0,0 +1,30 @@
1
+ import { n as createSalesforceCrudOperations } from "./shared-B8YQavkg.mjs";
2
+
3
+ //#region src/accounts.ts
4
+ const accountCrud = createSalesforceCrudOperations({
5
+ objectName: "Account",
6
+ singularName: "Account",
7
+ pluralName: "Accounts",
8
+ operationPrefix: "account",
9
+ defaultFields: [
10
+ "Id",
11
+ "Name",
12
+ "Type",
13
+ "Industry",
14
+ "Phone",
15
+ "Website",
16
+ "BillingCity",
17
+ "BillingState",
18
+ "BillingCountry",
19
+ "CreatedDate",
20
+ "LastModifiedDate"
21
+ ]
22
+ });
23
+ const getAccount = accountCrud.getRecord;
24
+ const listAccounts = accountCrud.listRecords;
25
+ const createAccount = accountCrud.createRecord;
26
+ const updateAccount = accountCrud.updateRecord;
27
+ const deleteAccount = accountCrud.deleteRecord;
28
+
29
+ //#endregion
30
+ export { createAccount, deleteAccount, getAccount, listAccounts, updateAccount };
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import * as _keystrokehq_core0 from "@keystrokehq/core";
3
+ import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
4
+
5
+ //#region src/associations.d.ts
6
+ declare const associateContactToAccount: _keystrokehq_core0.Operation<z.ZodObject<{
7
+ contactId: z.ZodString;
8
+ accountId: z.ZodString;
9
+ returnFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
10
+ }, z.core.$strip>, z.ZodObject<{
11
+ Id: z.ZodOptional<z.ZodString>;
12
+ attributes: z.ZodOptional<z.ZodObject<{
13
+ type: z.ZodString;
14
+ url: z.ZodString;
15
+ }, z.core.$strip>>;
16
+ }, z.core.$catchall<z.ZodUnknown>>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", z.ZodObject<{
17
+ SALESFORCE_ACCESS_TOKEN: z.ZodString;
18
+ SALESFORCE_INSTANCE_URL: z.ZodURL;
19
+ }, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
20
+ SALESFORCE_ACCESS_TOKEN: z.ZodString;
21
+ SALESFORCE_INSTANCE_URL: z.ZodURL;
22
+ }, z.core.$strip>>[] | undefined>], undefined>;
23
+ declare const dissociateContactFromAccount: _keystrokehq_core0.Operation<z.ZodObject<{
24
+ contactId: z.ZodString;
25
+ returnFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strip>, z.ZodObject<{
27
+ Id: z.ZodOptional<z.ZodString>;
28
+ attributes: z.ZodOptional<z.ZodObject<{
29
+ type: z.ZodString;
30
+ url: z.ZodString;
31
+ }, z.core.$strip>>;
32
+ }, z.core.$catchall<z.ZodUnknown>>, readonly [_keystrokehq_core0.CredentialSet<"salesforce", z.ZodObject<{
33
+ SALESFORCE_ACCESS_TOKEN: z.ZodString;
34
+ SALESFORCE_INSTANCE_URL: z.ZodURL;
35
+ }, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
36
+ SALESFORCE_ACCESS_TOKEN: z.ZodString;
37
+ SALESFORCE_INSTANCE_URL: z.ZodURL;
38
+ }, z.core.$strip>>[] | undefined>], undefined>;
39
+ //#endregion
40
+ export { associateContactToAccount, dissociateContactFromAccount };
@@ -0,0 +1,70 @@
1
+ import { createSalesforceClient } from "./client.mjs";
2
+ import { i as salesforceIdSchema, s as salesforceRecordSchema } from "./common-BUAhHMqn.mjs";
3
+ import { t as salesforceOperation } from "./factory-BBQAdBIT.mjs";
4
+ import { a as normalizeSalesforceQueryResult, i as getSelectFields, o as salesforceFieldListSchema, r as ensureMutationSuccess, t as buildSelectQuery } from "./shared-B8YQavkg.mjs";
5
+ import { z } from "zod";
6
+
7
+ //#region src/associations.ts
8
+ const defaultContactFields = [
9
+ "Id",
10
+ "AccountId",
11
+ "FirstName",
12
+ "LastName",
13
+ "Email",
14
+ "LastModifiedDate"
15
+ ];
16
+ function getClient(credentials) {
17
+ return createSalesforceClient(credentials);
18
+ }
19
+ async function getContactRecord(client, contactId, returnFields) {
20
+ const record = normalizeSalesforceQueryResult(await client.query(buildSelectQuery({
21
+ objectName: "Contact",
22
+ fields: getSelectFields(returnFields, defaultContactFields),
23
+ where: { Id: contactId },
24
+ limit: 1
25
+ }))).records[0];
26
+ if (!record) throw new Error(`Salesforce Contact record ${contactId} was not found.`);
27
+ return salesforceRecordSchema.parse(record);
28
+ }
29
+ const associateContactToAccount = salesforceOperation({
30
+ id: "associate_contact_to_account",
31
+ name: "Associate Salesforce Contact To Account",
32
+ description: "Associate a Salesforce contact to an account by setting AccountId",
33
+ input: z.object({
34
+ contactId: salesforceIdSchema,
35
+ accountId: salesforceIdSchema,
36
+ returnFields: salesforceFieldListSchema.optional()
37
+ }),
38
+ output: salesforceRecordSchema,
39
+ needsApproval: true,
40
+ run: async (input, credentials) => {
41
+ const client = getClient(credentials);
42
+ ensureMutationSuccess("update", "Contact", await client.sobject("Contact").update({
43
+ Id: input.contactId,
44
+ AccountId: input.accountId
45
+ }));
46
+ return getContactRecord(client, input.contactId, input.returnFields);
47
+ }
48
+ });
49
+ const dissociateContactFromAccount = salesforceOperation({
50
+ id: "dissociate_contact_from_account",
51
+ name: "Dissociate Salesforce Contact From Account",
52
+ description: "Remove the account association from a Salesforce contact by clearing AccountId",
53
+ input: z.object({
54
+ contactId: salesforceIdSchema,
55
+ returnFields: salesforceFieldListSchema.optional()
56
+ }),
57
+ output: salesforceRecordSchema,
58
+ needsApproval: true,
59
+ run: async (input, credentials) => {
60
+ const client = getClient(credentials);
61
+ ensureMutationSuccess("update", "Contact", await client.sobject("Contact").update({
62
+ Id: input.contactId,
63
+ AccountId: null
64
+ }));
65
+ return getContactRecord(client, input.contactId, input.returnFields);
66
+ }
67
+ });
68
+
69
+ //#endregion
70
+ export { associateContactToAccount, dissociateContactFromAccount };