@particle-academy/hubspot-js 0.4.0 → 0.5.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 +31 -0
- package/README.md +12 -0
- package/dist/{chunk-FFT5OGGS.js → chunk-SZT3VK7Z.js} +64 -4
- package/dist/chunk-SZT3VK7Z.js.map +1 -0
- package/dist/flow.cjs +74 -1
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.d.cts +2 -1
- package/dist/flow.d.ts +2 -1
- package/dist/flow.js +20 -5
- package/dist/flow.js.map +1 -1
- package/dist/index.cjs +65 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -2
- package/dist/index.d.ts +37 -2
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-FFT5OGGS.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,37 @@ The four packages share one version, because they are generated from one
|
|
|
7
7
|
`provider/` definition and a version that meant something different in each
|
|
8
8
|
would be a version nobody could reason about.
|
|
9
9
|
|
|
10
|
+
## [0.5.0] — 2026-11-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`crm_event`: HubSpot's CRM webhooks, verified.** HubSpot pushes a BATCH of
|
|
15
|
+
events (deal, contact and company created, property changed, deleted,
|
|
16
|
+
merged, restored, re-associated; which ones is set in the HubSpot app) to
|
|
17
|
+
the app's target URL. Each delivery is verified with **signature v3**
|
|
18
|
+
before anything reads it: base64 HMAC-SHA256 of method + URI + body +
|
|
19
|
+
timestamp under the app's `clientSecret`. The timestamp
|
|
20
|
+
(`X-HubSpot-Request-Timestamp`) is in MILLISECONDS, with a 5-minute window,
|
|
21
|
+
and the URI has only its query percent-decoded. HubSpot's own published
|
|
22
|
+
example verifies in TypeScript, PHP and Python; a changed byte, another
|
|
23
|
+
method, a late delivery and a missing request line are each refused.
|
|
24
|
+
- **The host must pass the request line.** `verifyHubspotDelivery({raw,
|
|
25
|
+
headers, method, url})` (js), `CrmEvent::verifyDelivery($raw, $headers,
|
|
26
|
+
$secret, method: …, url: …)` (php) and `verify_delivery(raw, headers,
|
|
27
|
+
secret, method=…, url=…)` (python) take the URL exactly as it arrived.
|
|
28
|
+
Without them a delivery is refused by name, never verified with a gap.
|
|
29
|
+
- **Routing is DECLARED** (`route: {by: "portalId", path: "[].portalId"}`,
|
|
30
|
+
on the descriptor, as `ROUTE`, and in the registry index). One URL serves
|
|
31
|
+
every portal that installed the app, so route each event by `portalId`
|
|
32
|
+
ONLY after the signature verifies, and only to a connection minted when
|
|
33
|
+
that portal installed. Drop an unmapped portal with a 2xx and a log line,
|
|
34
|
+
and create nothing.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **Requires `fancy-connector-core` ≥ 0.12.0**, which verifies a signed
|
|
39
|
+
request line and millisecond timestamps.
|
|
40
|
+
|
|
10
41
|
## [0.4.0] — 2026-11-01
|
|
11
42
|
|
|
12
43
|
### Added
|
package/README.md
CHANGED
|
@@ -285,6 +285,18 @@ Every property defined on deals, contacts or companies: name, label, type and th
|
|
|
285
285
|
|---|---|---|
|
|
286
286
|
| `objectType` | yes | Object |
|
|
287
287
|
|
|
288
|
+
### Triggers
|
|
289
|
+
|
|
290
|
+
#### `crm_event` — HubSpot CRM event
|
|
291
|
+
|
|
292
|
+
Start when HubSpot reports deals, contacts or companies created, changed, deleted, merged, restored or re-associated.
|
|
293
|
+
|
|
294
|
+
Delivered by webhook, and the signature is verified before anything runs.
|
|
295
|
+
|
|
296
|
+
**You have to set this up with the provider first:**
|
|
297
|
+
|
|
298
|
+
In the HubSpot app's webhook settings, set the target URL to the route your host mounts for this trigger and subscribe to the deal, contact and company events you want. Deliveries are signed with the app's client secret, already on the connection as `clientSecret`. ONE URL serves every portal that installed the app, so route each event by its portalId, and only after the signature has verified: map portalId to the connection created when that portal installed, and drop an unmapped portalId with a 2xx and a log line, creating nothing.
|
|
299
|
+
|
|
288
300
|
## Run it before you have credentials
|
|
289
301
|
|
|
290
302
|
Every operation ships a **faker**, whether or not HubSpot has a sandbox. Set a
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { callConnector } from '@particle-academy/fancy-connector-core';
|
|
1
|
+
import { callConnector, verifyDelivery } from '@particle-academy/fancy-connector-core';
|
|
2
2
|
|
|
3
3
|
// src/faker.ts
|
|
4
4
|
function fakeCompanyCreate({ config, fake }) {
|
|
@@ -392,6 +392,37 @@ function fakePropertyList({ config, fake }) {
|
|
|
392
392
|
]
|
|
393
393
|
};
|
|
394
394
|
}
|
|
395
|
+
function fakeCrmEvent({ config, fake }) {
|
|
396
|
+
return [
|
|
397
|
+
{
|
|
398
|
+
"eventId": 531833541,
|
|
399
|
+
"subscriptionId": 3923621,
|
|
400
|
+
"portalId": 48807704,
|
|
401
|
+
"appId": 16111050,
|
|
402
|
+
"occurredAt": 1752613920733,
|
|
403
|
+
"subscriptionType": "contact.creation",
|
|
404
|
+
"attemptNumber": 0,
|
|
405
|
+
"objectId": 138017612137,
|
|
406
|
+
"changeFlag": "CREATED",
|
|
407
|
+
"changeSource": "CRM_UI",
|
|
408
|
+
"sourceId": "userId:76023669"
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"eventId": 531833542,
|
|
412
|
+
"subscriptionId": 3923622,
|
|
413
|
+
"portalId": 48807704,
|
|
414
|
+
"appId": 16111050,
|
|
415
|
+
"occurredAt": 1752613921e3,
|
|
416
|
+
"subscriptionType": "deal.propertyChange",
|
|
417
|
+
"attemptNumber": 0,
|
|
418
|
+
"objectId": 9876543210,
|
|
419
|
+
"propertyName": "dealstage",
|
|
420
|
+
"propertyValue": "closedwon",
|
|
421
|
+
"changeSource": "CRM_UI",
|
|
422
|
+
"sourceId": "userId:76023669"
|
|
423
|
+
}
|
|
424
|
+
];
|
|
425
|
+
}
|
|
395
426
|
var hubspotFaker = (operation, request) => {
|
|
396
427
|
switch (operation) {
|
|
397
428
|
case "company_create":
|
|
@@ -430,6 +461,8 @@ var hubspotFaker = (operation, request) => {
|
|
|
430
461
|
return fakePipelineList(request);
|
|
431
462
|
case "property_list":
|
|
432
463
|
return fakePropertyList(request);
|
|
464
|
+
case "crm_event":
|
|
465
|
+
return fakeCrmEvent(request);
|
|
433
466
|
default:
|
|
434
467
|
throw new Error(
|
|
435
468
|
`hubspot: no fake response is defined for "${operation}". Add a fixture under provider/fixtures/ and regenerate \u2014 a connector without a faker cannot be developed against, tested, or demonstrated.`
|
|
@@ -1080,7 +1113,34 @@ async function hubspotPropertyList(options) {
|
|
|
1080
1113
|
}
|
|
1081
1114
|
});
|
|
1082
1115
|
}
|
|
1116
|
+
var HUBSPOT_CRM_EVENT_SIGNATURE_HEADER = "X-HubSpot-Signature-v3";
|
|
1117
|
+
var HUBSPOT_CRM_EVENT_TOLERANCE = 300;
|
|
1118
|
+
var HUBSPOT_CRM_EVENT_SCHEME = {
|
|
1119
|
+
algorithm: "SHA-256",
|
|
1120
|
+
payload: (raw, timestamp, _id, request) => `${request?.method ?? ""}${request?.uri ?? ""}${raw}${timestamp}`,
|
|
1121
|
+
tolerance: HUBSPOT_CRM_EVENT_TOLERANCE,
|
|
1122
|
+
timestampUnit: "ms",
|
|
1123
|
+
signsRequestLine: true,
|
|
1124
|
+
uri: "hubspot-v3",
|
|
1125
|
+
encoding: "base64"
|
|
1126
|
+
};
|
|
1127
|
+
var HUBSPOT_CRM_EVENT = {
|
|
1128
|
+
service: "hubspot",
|
|
1129
|
+
operation: "crm_event",
|
|
1130
|
+
delivery: "webhook",
|
|
1131
|
+
setup: "In the HubSpot app's webhook settings, set the target URL to the route your host mounts for this trigger and subscribe to the deal, contact and company events you want. Deliveries are signed with the app's client secret, already on the connection as `clientSecret`. ONE URL serves every portal that installed the app, so route each event by its portalId, and only after the signature has verified: map portalId to the connection created when that portal installed, and drop an unmapped portalId with a 2xx and a log line, creating nothing.",
|
|
1132
|
+
verification: {
|
|
1133
|
+
signatureHeader: HUBSPOT_CRM_EVENT_SIGNATURE_HEADER,
|
|
1134
|
+
scheme: HUBSPOT_CRM_EVENT_SCHEME,
|
|
1135
|
+
timestampHeader: "X-HubSpot-Request-Timestamp"
|
|
1136
|
+
},
|
|
1137
|
+
route: { by: "portalId", path: "[].portalId" },
|
|
1138
|
+
faker: hubspotFaker
|
|
1139
|
+
};
|
|
1140
|
+
function verifyHubspotDelivery(delivery, clientSecret, now) {
|
|
1141
|
+
return verifyDelivery(HUBSPOT_CRM_EVENT, delivery, clientSecret, now);
|
|
1142
|
+
}
|
|
1083
1143
|
|
|
1084
|
-
export { COMPANY_CREATE_OPERATION, COMPANY_GET_OPERATION, COMPANY_LIST_OPERATION, COMPANY_SEARCH_OPERATION, COMPANY_UPDATE_OPERATION, CONNECTOR_API_VERSION, CONTACT_CREATE_OPERATION, CONTACT_GET_OPERATION, CONTACT_LIST_OPERATION, CONTACT_SEARCH_OPERATION, CONTACT_UPDATE_OPERATION, DEAL_CREATE_OPERATION, DEAL_GET_OPERATION, DEAL_LIST_OPERATION, DEAL_SEARCH_OPERATION, DEAL_UPDATE_OPERATION, HUBSPOT, HUBSPOT_BASE_URLS, HUBSPOT_REQUIRES, OWNER_LIST_OPERATION, PIPELINE_LIST_OPERATION, PROPERTY_LIST_OPERATION, hubspotAuthorize, hubspotCompanyCreate, hubspotCompanyGet, hubspotCompanyList, hubspotCompanySearch, hubspotCompanyUpdate, hubspotContactCreate, hubspotContactGet, hubspotContactList, hubspotContactSearch, hubspotContactUpdate, hubspotDealCreate, hubspotDealGet, hubspotDealList, hubspotDealSearch, hubspotDealUpdate, hubspotFaker, hubspotOwnerList, hubspotPipelineList, hubspotPropertyList };
|
|
1085
|
-
//# sourceMappingURL=chunk-
|
|
1086
|
-
//# sourceMappingURL=chunk-
|
|
1144
|
+
export { COMPANY_CREATE_OPERATION, COMPANY_GET_OPERATION, COMPANY_LIST_OPERATION, COMPANY_SEARCH_OPERATION, COMPANY_UPDATE_OPERATION, CONNECTOR_API_VERSION, CONTACT_CREATE_OPERATION, CONTACT_GET_OPERATION, CONTACT_LIST_OPERATION, CONTACT_SEARCH_OPERATION, CONTACT_UPDATE_OPERATION, DEAL_CREATE_OPERATION, DEAL_GET_OPERATION, DEAL_LIST_OPERATION, DEAL_SEARCH_OPERATION, DEAL_UPDATE_OPERATION, HUBSPOT, HUBSPOT_BASE_URLS, HUBSPOT_CRM_EVENT, HUBSPOT_CRM_EVENT_SCHEME, HUBSPOT_CRM_EVENT_SIGNATURE_HEADER, HUBSPOT_CRM_EVENT_TOLERANCE, HUBSPOT_REQUIRES, OWNER_LIST_OPERATION, PIPELINE_LIST_OPERATION, PROPERTY_LIST_OPERATION, hubspotAuthorize, hubspotCompanyCreate, hubspotCompanyGet, hubspotCompanyList, hubspotCompanySearch, hubspotCompanyUpdate, hubspotContactCreate, hubspotContactGet, hubspotContactList, hubspotContactSearch, hubspotContactUpdate, hubspotDealCreate, hubspotDealGet, hubspotDealList, hubspotDealSearch, hubspotDealUpdate, hubspotFaker, hubspotOwnerList, hubspotPipelineList, hubspotPropertyList, verifyHubspotDelivery };
|
|
1145
|
+
//# sourceMappingURL=chunk-SZT3VK7Z.js.map
|
|
1146
|
+
//# sourceMappingURL=chunk-SZT3VK7Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/faker.ts","../src/service.ts","../src/actions/company-create.ts","../src/actions/company-get.ts","../src/actions/company-list.ts","../src/actions/company-search.ts","../src/actions/company-update.ts","../src/actions/contact-create.ts","../src/actions/contact-get.ts","../src/actions/contact-list.ts","../src/actions/contact-search.ts","../src/actions/contact-update.ts","../src/actions/deal-create.ts","../src/actions/deal-get.ts","../src/actions/deal-list.ts","../src/actions/deal-search.ts","../src/actions/deal-update.ts","../src/actions/owner-list.ts","../src/actions/pipeline-list.ts","../src/actions/property-list.ts","../src/triggers/crm-event.ts"],"names":["callConnector","propertiesMap","propertiesList"],"mappings":"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","file":"chunk-SZT3VK7Z.js","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/fixtures/ by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/fixtures/ (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * The HubSpot faker.\n *\n * Shapes, not behaviour: the goal is that a downstream node sees the field\n * NAMES HubSpot actually publishes, so an author can wire {{ $json.data.id }}\n * against a fake and have it keep working against the real thing.\n *\n * Deterministic — same inputs, same output. A faker returning a fresh uuid\n * every call cannot be asserted on, so its fixtures degrade to \"it did not\n * throw\", which is the assertion that catches nothing.\n */\n\nimport type { ConnectorFaker, FakeRequest } from \"@particle-academy/fancy-connector-core\";\n\nfunction fakeCompanyCreate({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"name\": \"Acme\",\n \"domain\": \"acme.example.test\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeCompanyGet({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"name\": \"Acme\",\n \"domain\": \"acme.example.test\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeCompanyList({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"results\": [\n {\n \"id\": boundRecordId,\n \"properties\": {\n \"name\": \"Acme\",\n \"domain\": \"acme.example.test\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakeCompanySearch({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"total\": 1,\n \"results\": [\n {\n \"id\": boundRecordId,\n \"properties\": {\n \"name\": \"Acme\",\n \"domain\": \"acme.example.test\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakeCompanyUpdate({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"name\": \"Acme\",\n \"domain\": \"acme.example.test\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeContactCreate({ config, fake }: FakeRequest): unknown {\n const boundContactId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundContactId,\n \"properties\": {\n \"email\": (config.email !== undefined && config.email !== null && config.email !== \"\" ? String(config.email) : null),\n \"firstname\": (config.firstName !== undefined && config.firstName !== null && config.firstName !== \"\" ? String(config.firstName) : null),\n \"lastname\": (config.lastName !== undefined && config.lastName !== null && config.lastName !== \"\" ? String(config.lastName) : null),\n \"company\": (config.company !== undefined && config.company !== null && config.company !== \"\" ? String(config.company) : null),\n \"phone\": (config.phone !== undefined && config.phone !== null && config.phone !== \"\" ? String(config.phone) : null),\n \"lifecyclestage\": (config.lifecycleStage !== undefined && config.lifecycleStage !== null && config.lifecycleStage !== \"\" ? String(config.lifecycleStage) : \"lead\"),\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n \"hs_object_id\": boundContactId,\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeContactGet({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"email\": \"rosa@example.test\",\n \"firstname\": \"Rosa\",\n \"lastname\": \"Diaz\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeContactList({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"results\": [\n {\n \"id\": boundRecordId,\n \"properties\": {\n \"email\": \"rosa@example.test\",\n \"firstname\": \"Rosa\",\n \"lastname\": \"Diaz\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakeContactSearch({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"total\": 1,\n \"results\": [\n {\n \"id\": boundRecordId,\n \"properties\": {\n \"email\": \"rosa@example.test\",\n \"firstname\": \"Rosa\",\n \"lastname\": \"Diaz\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakeContactUpdate({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"email\": \"rosa@example.test\",\n \"firstname\": \"Rosa\",\n \"lastname\": \"Diaz\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeDealCreate({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"dealname\": \"Acme renewal\",\n \"amount\": \"12000\",\n \"dealstage\": \"appointmentscheduled\",\n \"pipeline\": \"default\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeDealGet({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"dealname\": \"Acme renewal\",\n \"amount\": \"12000\",\n \"dealstage\": \"appointmentscheduled\",\n \"pipeline\": \"default\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeDealList({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"results\": [\n {\n \"id\": boundRecordId,\n \"properties\": {\n \"dealname\": \"Acme renewal\",\n \"amount\": \"12000\",\n \"dealstage\": \"appointmentscheduled\",\n \"pipeline\": \"default\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakeDealSearch({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"total\": 1,\n \"results\": [\n {\n \"id\": boundRecordId,\n \"properties\": {\n \"dealname\": \"Acme renewal\",\n \"amount\": \"12000\",\n \"dealstage\": \"appointmentscheduled\",\n \"pipeline\": \"default\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakeDealUpdate({ config, fake }: FakeRequest): unknown {\n const boundRecordId = Array.from({ length: 9 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"id\": boundRecordId,\n \"properties\": {\n \"dealname\": \"Acme renewal\",\n \"amount\": \"12000\",\n \"dealstage\": \"appointmentscheduled\",\n \"pipeline\": \"default\",\n \"hs_object_id\": boundRecordId,\n \"createdate\": \"2026-01-01T00:00:00.000Z\",\n \"lastmodifieddate\": \"2026-01-01T00:00:00.000Z\",\n },\n \"createdAt\": \"2026-01-01T00:00:00.000Z\",\n \"updatedAt\": \"2026-01-01T00:00:00.000Z\",\n \"archived\": false,\n };\n}\n\nfunction fakeOwnerList({ config, fake }: FakeRequest): unknown {\n const boundOwnerId = Array.from({ length: 8 }, () => fake.int(0, 9)).join(\"\");\n\n return {\n \"results\": [\n {\n \"id\": boundOwnerId,\n \"email\": \"rosa@example.test\",\n \"firstName\": \"Rosa\",\n \"lastName\": \"Diaz\",\n \"userId\": 4242,\n \"archived\": false,\n },\n ],\n \"paging\": {\n \"next\": {\n \"after\": \"10\",\n \"link\": \"?after=10\",\n },\n },\n };\n}\n\nfunction fakePipelineList({ config, fake }: FakeRequest): unknown {\n return {\n \"results\": [\n {\n \"id\": \"default\",\n \"label\": \"Sales pipeline\",\n \"displayOrder\": 0,\n \"archived\": false,\n \"stages\": [\n {\n \"id\": \"appointmentscheduled\",\n \"label\": \"Appointment scheduled\",\n \"displayOrder\": 0,\n \"metadata\": {\n \"probability\": \"0.2\",\n },\n },\n {\n \"id\": \"closedwon\",\n \"label\": \"Closed won\",\n \"displayOrder\": 1,\n \"metadata\": {\n \"probability\": \"1.0\",\n },\n },\n ],\n },\n ],\n };\n}\n\nfunction fakePropertyList({ config, fake }: FakeRequest): unknown {\n return {\n \"results\": [\n {\n \"name\": \"dealstage\",\n \"label\": \"Deal Stage\",\n \"type\": \"enumeration\",\n \"fieldType\": \"select\",\n \"groupName\": \"dealinformation\",\n \"options\": [\n {\n \"label\": \"Appointment scheduled\",\n \"value\": \"appointmentscheduled\",\n },\n ],\n },\n ],\n };\n}\n\nfunction fakeCrmEvent({ config, fake }: FakeRequest): unknown {\n return [\n {\n \"eventId\": 531833541,\n \"subscriptionId\": 3923621,\n \"portalId\": 48807704,\n \"appId\": 16111050,\n \"occurredAt\": 1752613920733,\n \"subscriptionType\": \"contact.creation\",\n \"attemptNumber\": 0,\n \"objectId\": 138017612137,\n \"changeFlag\": \"CREATED\",\n \"changeSource\": \"CRM_UI\",\n \"sourceId\": \"userId:76023669\",\n },\n {\n \"eventId\": 531833542,\n \"subscriptionId\": 3923622,\n \"portalId\": 48807704,\n \"appId\": 16111050,\n \"occurredAt\": 1752613921000,\n \"subscriptionType\": \"deal.propertyChange\",\n \"attemptNumber\": 0,\n \"objectId\": 9876543210,\n \"propertyName\": \"dealstage\",\n \"propertyValue\": \"closedwon\",\n \"changeSource\": \"CRM_UI\",\n \"sourceId\": \"userId:76023669\",\n },\n ];\n}\n\nexport const hubspotFaker: ConnectorFaker = (operation, request) => {\n switch (operation) {\n case \"company_create\":\n return fakeCompanyCreate(request);\n\n case \"company_get\":\n return fakeCompanyGet(request);\n\n case \"company_list\":\n return fakeCompanyList(request);\n\n case \"company_search\":\n return fakeCompanySearch(request);\n\n case \"company_update\":\n return fakeCompanyUpdate(request);\n\n case \"contact_create\":\n return fakeContactCreate(request);\n\n case \"contact_get\":\n return fakeContactGet(request);\n\n case \"contact_list\":\n return fakeContactList(request);\n\n case \"contact_search\":\n return fakeContactSearch(request);\n\n case \"contact_update\":\n return fakeContactUpdate(request);\n\n case \"deal_create\":\n return fakeDealCreate(request);\n\n case \"deal_get\":\n return fakeDealGet(request);\n\n case \"deal_list\":\n return fakeDealList(request);\n\n case \"deal_search\":\n return fakeDealSearch(request);\n\n case \"deal_update\":\n return fakeDealUpdate(request);\n\n case \"owner_list\":\n return fakeOwnerList(request);\n\n case \"pipeline_list\":\n return fakePipelineList(request);\n\n case \"property_list\":\n return fakePropertyList(request);\n\n case \"crm_event\":\n return fakeCrmEvent(request);\n\n default:\n // A faker asked for an operation it has no shape for must SAY so. Making\n // something up would produce a green run whose output silently has none\n // of the fields the author is about to reference.\n throw new Error(\n `hubspot: no fake response is defined for \"${operation}\". ` +\n \"Add a fixture under provider/fixtures/ and regenerate — a connector without a faker \" +\n \"cannot be developed against, tested, or demonstrated.\",\n );\n }\n};\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * HubSpot, as one service descriptor shared by every HubSpot operation.\n *\n * @particle-academy/fancy-connector-core carries what is true of ALL\n * connectors. This carries what is true of HubSpot: its base URL, its auth\n * scheme, its idempotency header, and its faker.\n *\n * ## The sandbox trap, written down where it is used\n *\n * HubSpot's test estate is a DEVELOPER TEST ACCOUNT: a separate portal you\n * create from the developer account, with its own portal id, its own data and\n * its own OAuth install. Same API host, different account -- so the credential\n * is different and the URL is not. Test accounts expire if unused and carry\n * reduced limits, which is why they are a place to test rather than a place to\n * build against.\n */\n\nimport type { ConnectorMode, PreparedRequest, ServiceDescriptor } from \"@particle-academy/fancy-connector-core\";\n\nimport { hubspotFaker } from \"./faker.js\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported. An imported constant lets an upgrade rewrite the\n * very claim it exists to detect, after which the copy agrees with itself\n * forever.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\nexport const HUBSPOT_BASE_URLS = {\n \"live\": \"https://api.hubapi.com\",\n \"sandbox\": \"https://api.hubapi.com\"\n} as const;\n\n/** Credential keys a remote call cannot proceed without. */\nexport const HUBSPOT_REQUIRES = [\n \"accessToken\"\n] as const;\n\n/**\n * Apply HubSpot's auth scheme to an outgoing request.\n *\n * An OAuth2 access token is presented exactly like a static bearer token. The\n * difference is not in the request -- it is that this one EXPIRES, and\n * something has to refresh it. That is the host's job, and `oauth` below is\n * what tells it how.\n *\n * The mode is passed in because for some providers auth and estate are the\n * same decision expressed in the URL; here it is unused, and saying so is\n * cheaper than wondering later whether it was forgotten.\n */\nexport function hubspotAuthorize(\n credentials: Record<string, string | undefined>,\n request: PreparedRequest,\n _mode: ConnectorMode,\n): void {\n request.headers.Authorization = `Bearer ${credentials.accessToken ?? \"\"}`;\n}\n\n/** The HubSpot service, for the TypeScript runtime. */\nexport const HUBSPOT: ServiceDescriptor = {\n service: \"hubspot\",\n title: \"HubSpot\",\n sandbox: \"separate-account\",\n baseUrls: { ...HUBSPOT_BASE_URLS },\n requires: [...HUBSPOT_REQUIRES],\n authorize: hubspotAuthorize,\n faker: hubspotFaker,\n};\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/company-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/company-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Create a company in HubSpot.\n *\n * POST /crm/v3/objects/companies —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/companies\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n *\n * sideEffects: unsafe-to-replay.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const COMPANY_CREATE_OPERATION = \"company_create\";\n\nexport type CompanyCreateOptions = {\n /** The node's resolved config. Keys: properties. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotCompanyCreate(options: CompanyCreateOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.properties === undefined || config.properties === null || config.properties === \"\") {\n throw new Error(`company_create: \"properties\" is required (Properties).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: COMPANY_CREATE_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"POST\",\n path: \"/crm/v3/objects/companies\",\n json: {\n \"properties\": propertiesMap(config.properties),\n \"associations\": [],\n },\n },\n });\n}\n\n/** `{ k: \"v\" }` → `{ \"properties\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction propertiesMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/company-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/company-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Read one company, with its associations when asked.\n *\n * GET /crm/v3/objects/companies/{companyId} —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/companies\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const COMPANY_GET_OPERATION = \"company_get\";\n\nexport type CompanyGetOptions = {\n /** The node's resolved config. Keys: companyId, properties, associations. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotCompanyGet(options: CompanyGetOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.companyId === undefined || config.companyId === null || config.companyId === \"\") {\n throw new Error(`company_get: \"companyId\" is required (Company id).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: COMPANY_GET_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/crm/v3/objects/companies/${encodeURIComponent(String(config.companyId))}`,\n query: {\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": String(config.properties) } : {}),\n ...(config.associations !== undefined && config.associations !== null && config.associations !== \"\" ? { \"associations\": String(config.associations) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/company-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/company-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Page through every company in the portal.\n *\n * GET /crm/v3/objects/companies —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/companies\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const COMPANY_LIST_OPERATION = \"company_list\";\n\nexport type CompanyListOptions = {\n /** The node's resolved config. Keys: limit, after, properties, associations. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotCompanyList(options: CompanyListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 100)) {\n throw new Error(\n `company_list: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: COMPANY_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: \"/crm/v3/objects/companies\",\n query: {\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": String(config.properties) } : {}),\n ...(config.associations !== undefined && config.associations !== null && config.associations !== \"\" ? { \"associations\": String(config.associations) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/company-search.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/company-search.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Find companies by property filters, sorts or a text query.\n *\n * POST /crm/v3/objects/companies/search —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/companies\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const COMPANY_SEARCH_OPERATION = \"company_search\";\n\nexport type CompanySearchOptions = {\n /** The node's resolved config. Keys: filterGroups, sorts, query, properties, limit, after. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotCompanySearch(options: CompanySearchOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (typeof config.filterGroups === \"string\" && config.filterGroups !== \"\") {\n try {\n JSON.parse(config.filterGroups);\n } catch (error) {\n throw new Error(`company_search: \"filterGroups\" must be JSON: ${(error as Error).message}`);\n }\n }\n\n if (typeof config.sorts === \"string\" && config.sorts !== \"\") {\n try {\n JSON.parse(config.sorts);\n } catch (error) {\n throw new Error(`company_search: \"sorts\" must be JSON: ${(error as Error).message}`);\n }\n }\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 200)) {\n throw new Error(\n `company_search: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: COMPANY_SEARCH_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"POST\",\n path: \"/crm/v3/objects/companies/search\",\n json: {\n ...(config.filterGroups !== undefined && config.filterGroups !== null && config.filterGroups !== \"\" ? { \"filterGroups\": typeof config.filterGroups === \"string\" ? JSON.parse(config.filterGroups) : config.filterGroups } : {}),\n ...(config.sorts !== undefined && config.sorts !== null && config.sorts !== \"\" ? { \"sorts\": typeof config.sorts === \"string\" ? JSON.parse(config.sorts) : config.sorts } : {}),\n ...(config.query !== undefined && config.query !== null && config.query !== \"\" ? { \"query\": String(config.query) } : {}),\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": propertiesList(config.properties) } : {}),\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n },\n },\n });\n}\n\n/** One value, a \",\"-separated string, or an array — all end up a list. */\nfunction propertiesList(value: unknown): string[] {\n const items = Array.isArray(value)\n ? value.map(String)\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n\n return items.map((item) => item.trim()).filter(Boolean);\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/company-update.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/company-update.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Change properties on an existing company.\n *\n * PATCH /crm/v3/objects/companies/{companyId} —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/companies\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const COMPANY_UPDATE_OPERATION = \"company_update\";\n\nexport type CompanyUpdateOptions = {\n /** The node's resolved config. Keys: companyId, properties. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotCompanyUpdate(options: CompanyUpdateOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.companyId === undefined || config.companyId === null || config.companyId === \"\") {\n throw new Error(`company_update: \"companyId\" is required (Company id).`);\n }\n\n if (config.properties === undefined || config.properties === null || config.properties === \"\") {\n throw new Error(`company_update: \"properties\" is required (Properties).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: COMPANY_UPDATE_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"PATCH\",\n path: `/crm/v3/objects/companies/${encodeURIComponent(String(config.companyId))}`,\n json: {\n \"properties\": propertiesMap(config.properties),\n },\n },\n });\n}\n\n/** `{ k: \"v\" }` → `{ \"properties\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction propertiesMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/contact-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/contact-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Create a contact in HubSpot.\n *\n * POST /crm/v3/objects/contacts —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/contacts\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n *\n * sideEffects: unsafe-to-replay.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const CONTACT_CREATE_OPERATION = \"contact_create\";\n\nexport type ContactCreateOptions = {\n /** The node's resolved config. Keys: email, firstName, lastName, company, phone, lifecycleStage. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotContactCreate(options: ContactCreateOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.email === undefined || config.email === null || config.email === \"\") {\n throw new Error(`contact_create: \"email\" is required (Email).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: CONTACT_CREATE_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"POST\",\n path: \"/crm/v3/objects/contacts\",\n json: nestFields({\n \"properties.email\": String(config.email).trim(),\n ...(config.firstName !== undefined && config.firstName !== null && config.firstName !== \"\" ? { \"properties.firstname\": String(config.firstName) } : {}),\n ...(config.lastName !== undefined && config.lastName !== null && config.lastName !== \"\" ? { \"properties.lastname\": String(config.lastName) } : {}),\n ...(config.company !== undefined && config.company !== null && config.company !== \"\" ? { \"properties.company\": String(config.company) } : {}),\n ...(config.phone !== undefined && config.phone !== null && config.phone !== \"\" ? { \"properties.phone\": String(config.phone) } : {}),\n ...(config.lifecycleStage !== undefined && config.lifecycleStage !== null && config.lifecycleStage !== \"\" ? { \"properties.lifecyclestage\": String(config.lifecycleStage) } : {}),\n \"associations\": [],\n }),\n },\n });\n}\n\n/**\n * `{\"properties.email\": x}` -> `{properties: {email: x}}`.\n *\n * A dotted `as` means NESTING, and only a JSON body can nest. The validator\n * refuses that spelling anywhere else, because in a form body it already means\n * something different — a literal dotted key.\n */\nfunction nestFields(flat: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n\n for (const [path, value] of Object.entries(flat)) {\n const parts = path.split(\".\");\n let node = out;\n\n while (parts.length > 1) {\n const key = parts.shift() as string;\n // A NUMERIC segment is an array index: `dateRanges.0.startDate` has to\n // become `[{startDate}]`, not `{\"0\": {startDate}}`. PHP produced the\n // array by accident (its integer-keyed arrays serialise as JSON lists)\n // and the other two produced an object, which the provider rejects as\n // the wrong type. The parity suite is what caught the disagreement.\n const wantsArray = /^\\d+$/.test(parts[0] ?? \"\");\n\n if (typeof node[key] !== \"object\" || node[key] === null) node[key] = wantsArray ? [] : {};\n node = node[key] as Record<string, unknown>;\n }\n\n node[parts[0] as string] = value;\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/contact-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/contact-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Read one contact, with its associations when asked.\n *\n * GET /crm/v3/objects/contacts/{contactId} —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/contacts\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const CONTACT_GET_OPERATION = \"contact_get\";\n\nexport type ContactGetOptions = {\n /** The node's resolved config. Keys: contactId, properties, associations. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotContactGet(options: ContactGetOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.contactId === undefined || config.contactId === null || config.contactId === \"\") {\n throw new Error(`contact_get: \"contactId\" is required (Contact id).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: CONTACT_GET_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/crm/v3/objects/contacts/${encodeURIComponent(String(config.contactId))}`,\n query: {\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": String(config.properties) } : {}),\n ...(config.associations !== undefined && config.associations !== null && config.associations !== \"\" ? { \"associations\": String(config.associations) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/contact-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/contact-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Page through every contact in the portal.\n *\n * GET /crm/v3/objects/contacts —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/contacts\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const CONTACT_LIST_OPERATION = \"contact_list\";\n\nexport type ContactListOptions = {\n /** The node's resolved config. Keys: limit, after, properties, associations. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotContactList(options: ContactListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 100)) {\n throw new Error(\n `contact_list: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: CONTACT_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: \"/crm/v3/objects/contacts\",\n query: {\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": String(config.properties) } : {}),\n ...(config.associations !== undefined && config.associations !== null && config.associations !== \"\" ? { \"associations\": String(config.associations) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/contact-search.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/contact-search.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Find contacts by property filters, sorts or a text query.\n *\n * POST /crm/v3/objects/contacts/search —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/contacts\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const CONTACT_SEARCH_OPERATION = \"contact_search\";\n\nexport type ContactSearchOptions = {\n /** The node's resolved config. Keys: filterGroups, sorts, query, properties, limit, after. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotContactSearch(options: ContactSearchOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (typeof config.filterGroups === \"string\" && config.filterGroups !== \"\") {\n try {\n JSON.parse(config.filterGroups);\n } catch (error) {\n throw new Error(`contact_search: \"filterGroups\" must be JSON: ${(error as Error).message}`);\n }\n }\n\n if (typeof config.sorts === \"string\" && config.sorts !== \"\") {\n try {\n JSON.parse(config.sorts);\n } catch (error) {\n throw new Error(`contact_search: \"sorts\" must be JSON: ${(error as Error).message}`);\n }\n }\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 200)) {\n throw new Error(\n `contact_search: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: CONTACT_SEARCH_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"POST\",\n path: \"/crm/v3/objects/contacts/search\",\n json: {\n ...(config.filterGroups !== undefined && config.filterGroups !== null && config.filterGroups !== \"\" ? { \"filterGroups\": typeof config.filterGroups === \"string\" ? JSON.parse(config.filterGroups) : config.filterGroups } : {}),\n ...(config.sorts !== undefined && config.sorts !== null && config.sorts !== \"\" ? { \"sorts\": typeof config.sorts === \"string\" ? JSON.parse(config.sorts) : config.sorts } : {}),\n ...(config.query !== undefined && config.query !== null && config.query !== \"\" ? { \"query\": String(config.query) } : {}),\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": propertiesList(config.properties) } : {}),\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n },\n },\n });\n}\n\n/** One value, a \",\"-separated string, or an array — all end up a list. */\nfunction propertiesList(value: unknown): string[] {\n const items = Array.isArray(value)\n ? value.map(String)\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n\n return items.map((item) => item.trim()).filter(Boolean);\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/contact-update.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/contact-update.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Change properties on an existing contact.\n *\n * PATCH /crm/v3/objects/contacts/{contactId} —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/contacts\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const CONTACT_UPDATE_OPERATION = \"contact_update\";\n\nexport type ContactUpdateOptions = {\n /** The node's resolved config. Keys: contactId, properties. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotContactUpdate(options: ContactUpdateOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.contactId === undefined || config.contactId === null || config.contactId === \"\") {\n throw new Error(`contact_update: \"contactId\" is required (Contact id).`);\n }\n\n if (config.properties === undefined || config.properties === null || config.properties === \"\") {\n throw new Error(`contact_update: \"properties\" is required (Properties).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: CONTACT_UPDATE_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"PATCH\",\n path: `/crm/v3/objects/contacts/${encodeURIComponent(String(config.contactId))}`,\n json: {\n \"properties\": propertiesMap(config.properties),\n },\n },\n });\n}\n\n/** `{ k: \"v\" }` → `{ \"properties\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction propertiesMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/deal-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/deal-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Create a deal in HubSpot.\n *\n * POST /crm/v3/objects/deals —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/deals\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n *\n * sideEffects: unsafe-to-replay.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const DEAL_CREATE_OPERATION = \"deal_create\";\n\nexport type DealCreateOptions = {\n /** The node's resolved config. Keys: properties. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotDealCreate(options: DealCreateOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.properties === undefined || config.properties === null || config.properties === \"\") {\n throw new Error(`deal_create: \"properties\" is required (Properties).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: DEAL_CREATE_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"POST\",\n path: \"/crm/v3/objects/deals\",\n json: {\n \"properties\": propertiesMap(config.properties),\n \"associations\": [],\n },\n },\n });\n}\n\n/** `{ k: \"v\" }` → `{ \"properties\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction propertiesMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/deal-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/deal-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Read one deal, with its associations when asked.\n *\n * GET /crm/v3/objects/deals/{dealId} —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/deals\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const DEAL_GET_OPERATION = \"deal_get\";\n\nexport type DealGetOptions = {\n /** The node's resolved config. Keys: dealId, properties, associations. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotDealGet(options: DealGetOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.dealId === undefined || config.dealId === null || config.dealId === \"\") {\n throw new Error(`deal_get: \"dealId\" is required (Deal id).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: DEAL_GET_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/crm/v3/objects/deals/${encodeURIComponent(String(config.dealId))}`,\n query: {\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": String(config.properties) } : {}),\n ...(config.associations !== undefined && config.associations !== null && config.associations !== \"\" ? { \"associations\": String(config.associations) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/deal-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/deal-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Page through every deal in the portal.\n *\n * GET /crm/v3/objects/deals —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/deals\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const DEAL_LIST_OPERATION = \"deal_list\";\n\nexport type DealListOptions = {\n /** The node's resolved config. Keys: limit, after, properties, associations. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotDealList(options: DealListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 100)) {\n throw new Error(\n `deal_list: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: DEAL_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: \"/crm/v3/objects/deals\",\n query: {\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": String(config.properties) } : {}),\n ...(config.associations !== undefined && config.associations !== null && config.associations !== \"\" ? { \"associations\": String(config.associations) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/deal-search.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/deal-search.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Find deals by property filters, sorts or a text query.\n *\n * POST /crm/v3/objects/deals/search —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/deals\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const DEAL_SEARCH_OPERATION = \"deal_search\";\n\nexport type DealSearchOptions = {\n /** The node's resolved config. Keys: filterGroups, sorts, query, properties, limit, after. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotDealSearch(options: DealSearchOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (typeof config.filterGroups === \"string\" && config.filterGroups !== \"\") {\n try {\n JSON.parse(config.filterGroups);\n } catch (error) {\n throw new Error(`deal_search: \"filterGroups\" must be JSON: ${(error as Error).message}`);\n }\n }\n\n if (typeof config.sorts === \"string\" && config.sorts !== \"\") {\n try {\n JSON.parse(config.sorts);\n } catch (error) {\n throw new Error(`deal_search: \"sorts\" must be JSON: ${(error as Error).message}`);\n }\n }\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 200)) {\n throw new Error(\n `deal_search: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: DEAL_SEARCH_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"POST\",\n path: \"/crm/v3/objects/deals/search\",\n json: {\n ...(config.filterGroups !== undefined && config.filterGroups !== null && config.filterGroups !== \"\" ? { \"filterGroups\": typeof config.filterGroups === \"string\" ? JSON.parse(config.filterGroups) : config.filterGroups } : {}),\n ...(config.sorts !== undefined && config.sorts !== null && config.sorts !== \"\" ? { \"sorts\": typeof config.sorts === \"string\" ? JSON.parse(config.sorts) : config.sorts } : {}),\n ...(config.query !== undefined && config.query !== null && config.query !== \"\" ? { \"query\": String(config.query) } : {}),\n ...(config.properties !== undefined && config.properties !== null && config.properties !== \"\" ? { \"properties\": propertiesList(config.properties) } : {}),\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n },\n },\n });\n}\n\n/** One value, a \",\"-separated string, or an array — all end up a list. */\nfunction propertiesList(value: unknown): string[] {\n const items = Array.isArray(value)\n ? value.map(String)\n : typeof value === \"string\"\n ? value.split(\",\")\n : [];\n\n return items.map((item) => item.trim()).filter(Boolean);\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/deal-update.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/deal-update.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Change properties on an existing deal.\n *\n * PATCH /crm/v3/objects/deals/{dealId} —\n * https://developers.hubspot.com/docs/reference/api/crm/objects/deals\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const DEAL_UPDATE_OPERATION = \"deal_update\";\n\nexport type DealUpdateOptions = {\n /** The node's resolved config. Keys: dealId, properties. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotDealUpdate(options: DealUpdateOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.dealId === undefined || config.dealId === null || config.dealId === \"\") {\n throw new Error(`deal_update: \"dealId\" is required (Deal id).`);\n }\n\n if (config.properties === undefined || config.properties === null || config.properties === \"\") {\n throw new Error(`deal_update: \"properties\" is required (Properties).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: DEAL_UPDATE_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"PATCH\",\n path: `/crm/v3/objects/deals/${encodeURIComponent(String(config.dealId))}`,\n json: {\n \"properties\": propertiesMap(config.properties),\n },\n },\n });\n}\n\n/** `{ k: \"v\" }` → `{ \"properties\": { \"k\": \"v\" } }` — a JSON body wants the real object. */\nfunction propertiesMap(value: unknown): Record<string, string> {\n if (!value || typeof value !== \"object\") return {};\n\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item !== undefined && item !== null && item !== \"\") out[key] = String(item);\n }\n\n return out;\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/owner-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/owner-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Page through the portal's owners: the users records can be assigned to.\n *\n * GET /crm/v3/owners —\n * https://developers.hubspot.com/docs/reference/api/crm/owners\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const OWNER_LIST_OPERATION = \"owner_list\";\n\nexport type OwnerListOptions = {\n /** The node's resolved config. Keys: email, limit, after. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotOwnerList(options: OwnerListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n {\n const n = Number(config.limit);\n const given = config.limit !== undefined && config.limit !== null && config.limit !== \"\";\n if (given && !(Number.isInteger(n) && n >= 1 && n <= 100)) {\n throw new Error(\n `owner_list: \"limit\" must be a integer, got ${JSON.stringify(config.limit)}.`,\n );\n }\n }\n\n return callConnector(HUBSPOT, {\n operation: OWNER_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: \"/crm/v3/owners\",\n query: {\n ...(config.email !== undefined && config.email !== null && config.email !== \"\" ? { \"email\": String(config.email) } : {}),\n ...(config.limit !== undefined && config.limit !== null && config.limit !== \"\" ? { \"limit\": Math.trunc(Number(config.limit)) } : {}),\n ...(config.after !== undefined && config.after !== null && config.after !== \"\" ? { \"after\": String(config.after) } : {}),\n },\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/pipeline-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/pipeline-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Every deal pipeline in the portal, with its stages in order.\n *\n * GET /crm/v3/pipelines/deals —\n * https://developers.hubspot.com/docs/reference/api/crm/pipelines\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const PIPELINE_LIST_OPERATION = \"pipeline_list\";\n\nexport type PipelineListOptions = {\n /** The node's resolved config. Keys: . */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotPipelineList(options: PipelineListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n return callConnector(HUBSPOT, {\n operation: PIPELINE_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: \"/crm/v3/pipelines/deals\",\n query: {},\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/property-list.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/property-list.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * Every property defined on deals, contacts or companies: name, label, type\n * and the options of an enumeration.\n *\n * GET /crm/v3/properties/{objectType} —\n * https://developers.hubspot.com/docs/reference/api/crm/properties\n *\n * Notice what is NOT here: no key, no base URL, no mode check, no retry loop,\n * no fake/real branch. This describes the request; callConnector resolves the\n * connection, picks the estate, and either calls HubSpot or calls the faker.\n */\n\nimport {\n callConnector,\n type ConnectorResult,\n type RequestedMode,\n type Transport,\n} from \"@particle-academy/fancy-connector-core\";\nimport { HUBSPOT } from \"../service.js\";\n\nexport const PROPERTY_LIST_OPERATION = \"property_list\";\n\nexport type PropertyListOptions = {\n /** The node's resolved config. Keys: objectType. */\n config: Record<string, unknown>;\n credentials?: Record<string, string | undefined>;\n mode?: RequestedMode;\n connectionId?: string | null;\n input?: unknown;\n attempts?: number;\n /** Override the transport. The only way to exercise this without a network. */\n transport?: Transport;\n};\n\nexport async function hubspotPropertyList(options: PropertyListOptions): Promise<ConnectorResult> {\n const config = options.config ?? {};\n\n if (config.objectType === undefined || config.objectType === null || config.objectType === \"\") {\n throw new Error(`property_list: \"objectType\" is required (Object).`);\n }\n\n return callConnector(HUBSPOT, {\n operation: PROPERTY_LIST_OPERATION,\n config,\n input: options.input,\n ...(options.credentials === undefined ? {} : { credentials: options.credentials }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.connectionId === undefined ? {} : { connectionId: options.connectionId }),\n ...(options.attempts === undefined ? {} : { attempts: options.attempts }),\n ...(options.transport === undefined ? {} : { transport: options.transport }),\n request: {\n method: \"GET\",\n path: `/crm/v3/properties/${encodeURIComponent(String(config.objectType))}`,\n query: {},\n },\n });\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/triggers/crm-event.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/triggers/crm-event.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- hubspot\n */\n\n/**\n * HubSpot's webhook trigger — the delivery contract.\n *\n * Kept beside the service descriptor rather than inside a node, because a\n * signature scheme is a fact about HUBSPOT. Two HubSpot triggers must not be\n * able to disagree about how a delivery is verified.\n */\n\nimport { verifyDelivery, type HmacScheme, type InboundDelivery, type TriggerDescriptor, type WebhookVerification } from \"@particle-academy/fancy-connector-core\";\nimport { hubspotFaker } from \"../faker.js\";\n\nexport const HUBSPOT_CRM_EVENT_SIGNATURE_HEADER = \"X-HubSpot-Signature-v3\";\n/** The provider's documented replay window, in seconds. */\nexport const HUBSPOT_CRM_EVENT_TOLERANCE = 300;\n\nexport const HUBSPOT_CRM_EVENT_SCHEME: HmacScheme = {\n algorithm: \"SHA-256\",\n payload: (raw, timestamp, _id, request) => `${request?.method ?? \"\"}${request?.uri ?? \"\"}${raw}${timestamp}`,\n tolerance: HUBSPOT_CRM_EVENT_TOLERANCE,\n timestampUnit: \"ms\",\n signsRequestLine: true,\n uri: \"hubspot-v3\",\n encoding: \"base64\",\n};\n\nexport const HUBSPOT_CRM_EVENT: TriggerDescriptor = {\n service: \"hubspot\",\n operation: \"crm_event\",\n delivery: \"webhook\",\n setup:\n \"In the HubSpot app's webhook settings, set the target URL to the route your host mounts for this trigger and subscribe to the deal, contact and company events you want. Deliveries are signed with the app's client secret, already on the connection as `clientSecret`. ONE URL serves every portal that installed the app, so route each event by its portalId, and only after the signature has verified: map portalId to the connection created when that portal installed, and drop an unmapped portalId with a 2xx and a log line, creating nothing.\",\n verification: {\n signatureHeader: HUBSPOT_CRM_EVENT_SIGNATURE_HEADER,\n scheme: HUBSPOT_CRM_EVENT_SCHEME,\n timestampHeader: \"X-HubSpot-Request-Timestamp\",\n },\n route: { by: \"portalId\", path: \"[].portalId\" },\n faker: hubspotFaker,\n};\n\n/**\n * Verify one inbound HubSpot delivery.\n *\n * The host calls this BEFORE starting a run, with the body exactly as\n * received. Re-serialised JSON changes key order and whitespace, and produces\n * a mismatch that looks precisely like a wrong secret — hours of debugging the\n * wrong thing.\n *\n * The secret is the connection's `clientSecret`.\n */\nexport function verifyHubspotDelivery(\n delivery: InboundDelivery,\n clientSecret: string | undefined,\n now?: number,\n): Promise<WebhookVerification> {\n return verifyDelivery(HUBSPOT_CRM_EVENT, delivery, clientSecret, now);\n}\n"]}
|
package/dist/flow.cjs
CHANGED
|
@@ -397,6 +397,37 @@ function fakePropertyList({ config, fake }) {
|
|
|
397
397
|
]
|
|
398
398
|
};
|
|
399
399
|
}
|
|
400
|
+
function fakeCrmEvent({ config, fake }) {
|
|
401
|
+
return [
|
|
402
|
+
{
|
|
403
|
+
"eventId": 531833541,
|
|
404
|
+
"subscriptionId": 3923621,
|
|
405
|
+
"portalId": 48807704,
|
|
406
|
+
"appId": 16111050,
|
|
407
|
+
"occurredAt": 1752613920733,
|
|
408
|
+
"subscriptionType": "contact.creation",
|
|
409
|
+
"attemptNumber": 0,
|
|
410
|
+
"objectId": 138017612137,
|
|
411
|
+
"changeFlag": "CREATED",
|
|
412
|
+
"changeSource": "CRM_UI",
|
|
413
|
+
"sourceId": "userId:76023669"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"eventId": 531833542,
|
|
417
|
+
"subscriptionId": 3923622,
|
|
418
|
+
"portalId": 48807704,
|
|
419
|
+
"appId": 16111050,
|
|
420
|
+
"occurredAt": 1752613921e3,
|
|
421
|
+
"subscriptionType": "deal.propertyChange",
|
|
422
|
+
"attemptNumber": 0,
|
|
423
|
+
"objectId": 9876543210,
|
|
424
|
+
"propertyName": "dealstage",
|
|
425
|
+
"propertyValue": "closedwon",
|
|
426
|
+
"changeSource": "CRM_UI",
|
|
427
|
+
"sourceId": "userId:76023669"
|
|
428
|
+
}
|
|
429
|
+
];
|
|
430
|
+
}
|
|
400
431
|
var hubspotFaker = (operation, request) => {
|
|
401
432
|
switch (operation) {
|
|
402
433
|
case "company_create":
|
|
@@ -435,6 +466,8 @@ var hubspotFaker = (operation, request) => {
|
|
|
435
466
|
return fakePipelineList(request);
|
|
436
467
|
case "property_list":
|
|
437
468
|
return fakePropertyList(request);
|
|
469
|
+
case "crm_event":
|
|
470
|
+
return fakeCrmEvent(request);
|
|
438
471
|
default:
|
|
439
472
|
throw new Error(
|
|
440
473
|
`hubspot: no fake response is defined for "${operation}". Add a fixture under provider/fixtures/ and regenerate \u2014 a connector without a faker cannot be developed against, tested, or demonstrated.`
|
|
@@ -1084,6 +1117,30 @@ async function hubspotPropertyList(options) {
|
|
|
1084
1117
|
}
|
|
1085
1118
|
});
|
|
1086
1119
|
}
|
|
1120
|
+
var HUBSPOT_CRM_EVENT_SIGNATURE_HEADER = "X-HubSpot-Signature-v3";
|
|
1121
|
+
var HUBSPOT_CRM_EVENT_TOLERANCE = 300;
|
|
1122
|
+
var HUBSPOT_CRM_EVENT_SCHEME = {
|
|
1123
|
+
algorithm: "SHA-256",
|
|
1124
|
+
payload: (raw, timestamp, _id, request) => `${request?.method ?? ""}${request?.uri ?? ""}${raw}${timestamp}`,
|
|
1125
|
+
tolerance: HUBSPOT_CRM_EVENT_TOLERANCE,
|
|
1126
|
+
timestampUnit: "ms",
|
|
1127
|
+
signsRequestLine: true,
|
|
1128
|
+
uri: "hubspot-v3",
|
|
1129
|
+
encoding: "base64"
|
|
1130
|
+
};
|
|
1131
|
+
var HUBSPOT_CRM_EVENT = {
|
|
1132
|
+
service: "hubspot",
|
|
1133
|
+
operation: "crm_event",
|
|
1134
|
+
delivery: "webhook",
|
|
1135
|
+
setup: "In the HubSpot app's webhook settings, set the target URL to the route your host mounts for this trigger and subscribe to the deal, contact and company events you want. Deliveries are signed with the app's client secret, already on the connection as `clientSecret`. ONE URL serves every portal that installed the app, so route each event by its portalId, and only after the signature has verified: map portalId to the connection created when that portal installed, and drop an unmapped portalId with a 2xx and a log line, creating nothing.",
|
|
1136
|
+
verification: {
|
|
1137
|
+
signatureHeader: HUBSPOT_CRM_EVENT_SIGNATURE_HEADER,
|
|
1138
|
+
scheme: HUBSPOT_CRM_EVENT_SCHEME,
|
|
1139
|
+
timestampHeader: "X-HubSpot-Request-Timestamp"
|
|
1140
|
+
},
|
|
1141
|
+
route: { by: "portalId", path: "[].portalId" },
|
|
1142
|
+
faker: hubspotFaker
|
|
1143
|
+
};
|
|
1087
1144
|
|
|
1088
1145
|
// src/flow.ts
|
|
1089
1146
|
var hubspotCompanyCreateExecutor = async (ctx) => {
|
|
@@ -1338,6 +1395,20 @@ var hubspotPropertyListExecutor = async (ctx) => {
|
|
|
1338
1395
|
});
|
|
1339
1396
|
return { __port: "out", value: result };
|
|
1340
1397
|
};
|
|
1398
|
+
var hubspotCrmEventTriggerExecutor = async (ctx) => {
|
|
1399
|
+
const config = ctx.node.data?.config ?? {};
|
|
1400
|
+
const connection = fancyConnectorCore.resolveConnection({
|
|
1401
|
+
service: HUBSPOT.service,
|
|
1402
|
+
operation: "crm_event",
|
|
1403
|
+
sandbox: HUBSPOT.sandbox,
|
|
1404
|
+
baseUrls: HUBSPOT.baseUrls,
|
|
1405
|
+
requires: HUBSPOT.requires,
|
|
1406
|
+
connectionId: typeof config.connection === "string" ? config.connection : null,
|
|
1407
|
+
requested: typeof config.mode === "string" ? config.mode : null
|
|
1408
|
+
});
|
|
1409
|
+
const event = fancyConnectorCore.triggerEvent(HUBSPOT_CRM_EVENT, connection, ctx.inputs?.in, config);
|
|
1410
|
+
return { __port: "out", value: event };
|
|
1411
|
+
};
|
|
1341
1412
|
var HUBSPOT_RUNNABLE_KINDS = [
|
|
1342
1413
|
{ ...hubspotUi.hubspotCompanyCreateKind, executor: hubspotCompanyCreateExecutor },
|
|
1343
1414
|
{ ...hubspotUi.hubspotCompanyGetKind, executor: hubspotCompanyGetExecutor },
|
|
@@ -1356,7 +1427,8 @@ var HUBSPOT_RUNNABLE_KINDS = [
|
|
|
1356
1427
|
{ ...hubspotUi.hubspotDealUpdateKind, executor: hubspotDealUpdateExecutor },
|
|
1357
1428
|
{ ...hubspotUi.hubspotOwnerListKind, executor: hubspotOwnerListExecutor },
|
|
1358
1429
|
{ ...hubspotUi.hubspotPipelineListKind, executor: hubspotPipelineListExecutor },
|
|
1359
|
-
{ ...hubspotUi.hubspotPropertyListKind, executor: hubspotPropertyListExecutor }
|
|
1430
|
+
{ ...hubspotUi.hubspotPropertyListKind, executor: hubspotPropertyListExecutor },
|
|
1431
|
+
{ ...hubspotUi.hubspotCrmEventTriggerKind, executor: hubspotCrmEventTriggerExecutor }
|
|
1360
1432
|
];
|
|
1361
1433
|
|
|
1362
1434
|
exports.HUBSPOT_RUNNABLE_KINDS = HUBSPOT_RUNNABLE_KINDS;
|
|
@@ -1370,6 +1442,7 @@ exports.hubspotContactGetExecutor = hubspotContactGetExecutor;
|
|
|
1370
1442
|
exports.hubspotContactListExecutor = hubspotContactListExecutor;
|
|
1371
1443
|
exports.hubspotContactSearchExecutor = hubspotContactSearchExecutor;
|
|
1372
1444
|
exports.hubspotContactUpdateExecutor = hubspotContactUpdateExecutor;
|
|
1445
|
+
exports.hubspotCrmEventTriggerExecutor = hubspotCrmEventTriggerExecutor;
|
|
1373
1446
|
exports.hubspotDealCreateExecutor = hubspotDealCreateExecutor;
|
|
1374
1447
|
exports.hubspotDealGetExecutor = hubspotDealGetExecutor;
|
|
1375
1448
|
exports.hubspotDealListExecutor = hubspotDealListExecutor;
|