strapi-plugin-hubspot 0.16.2 → 0.16.3
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 +8 -0
- package/README.md +8 -5
- package/dist/_chunks/{Forms-BOQWely0.mjs → Forms-BBaw53Tz.mjs} +3 -3
- package/dist/_chunks/{Forms-mMNP7hc9.js → Forms-CIJrUB_n.js} +3 -3
- package/dist/_chunks/{HubspotFormInput-DCkoavrN.mjs → HubspotFormInput-DIo6hCNz.mjs} +1 -1
- package/dist/_chunks/{HubspotFormInput-DI35Aqiu.js → HubspotFormInput-DSTuQ_bx.js} +1 -1
- package/dist/_chunks/{HubspotObjectInput-BbnvhdbD.mjs → HubspotObjectInput-BA16dswz.mjs} +3 -3
- package/dist/_chunks/{HubspotObjectInput-Cq1TuL_l.js → HubspotObjectInput-BIqC8tl2.js} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-BLZzsW08.js → HubspotPropertyInput-C77Op1Wm.js} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-BHfpBD36.mjs → HubspotPropertyInput-Dsn7ikop.mjs} +3 -3
- package/dist/_chunks/{Settings-DqRpHtnT.mjs → Settings-DxX9Uh_2.mjs} +21 -3
- package/dist/_chunks/{Settings-BAsx0LGv.js → Settings-PVhJVPqq.js} +21 -3
- package/dist/_chunks/{index-CLAy5dVN.mjs → index-B8GYi6sw.mjs} +5 -5
- package/dist/_chunks/{index-R3ReZXF1.js → index-XEuSPuUj.js} +5 -5
- package/dist/_chunks/{objectLabels--zOmqsfm.mjs → objectLabels-DybqhBdT.mjs} +1 -1
- package/dist/_chunks/{objectLabels-CW2iBOkD.js → objectLabels-wBwfLdZt.js} +1 -1
- package/dist/_chunks/{useHubspotSchema-Bz2o1BU-.mjs → useHubspotSchema-DtcHHUOb.mjs} +1 -1
- package/dist/_chunks/{useHubspotSchema-BRzzvs9t.js → useHubspotSchema-WvgW3od8.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +9 -5
- package/dist/server/index.mjs +9 -5
- package/dist/server/src/forms.d.ts +3 -2
- package/dist/server/src/index.d.ts +1 -0
- package/dist/server/src/settings.d.ts +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.16.3 — 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Timeline recap notes (`forms.timelineNote`, default `true`) now also write
|
|
9
|
+
after a native Forms API conversion: page URL and originating subject sit
|
|
10
|
+
on the contact next to the conversion. The Forms API already forwards
|
|
11
|
+
`context.pageUri` / `pageName`. Toggle lives in Settings → HubSpot.
|
|
12
|
+
|
|
5
13
|
## 0.16.2 — 2026-09-22
|
|
6
14
|
|
|
7
15
|
### Added
|
package/README.md
CHANGED
|
@@ -54,11 +54,14 @@ upserts can share the same plugin:
|
|
|
54
54
|
| `forms.submissionMode` | `auto` | `auto`: Forms API when a marketing GUID is linked, else CRM upsert. `forms`: always try the Forms API. `crm`: never count as a conversion |
|
|
55
55
|
| `forms.writeExtraProperties` | `true` | After a conversion, CRM-write mapped contact fields the HubSpot form dropped (they 400 the Forms API) |
|
|
56
56
|
| `forms.syncFieldsOnPublish` | `false` | On publish, PATCH missing mapped **contact** fields onto the HubSpot form. Off by default so HubSpot-first installs aren't mutated |
|
|
57
|
+
| `forms.timelineNote` | `true` | Recap note on the contact after a successful sync (page URL, subject, answers). Sits next to a native conversion; turn off if you only want the form submission |
|
|
57
58
|
|
|
58
|
-
The visitor's `hutk` is forwarded so attribution sticks.
|
|
59
|
-
|
|
60
|
-
is
|
|
61
|
-
|
|
59
|
+
The visitor's `hutk` is forwarded so attribution sticks. The conversion carries
|
|
60
|
+
`context.pageUri` / `pageName` (the page the visitor submitted from). Then the
|
|
61
|
+
contact is looked up by email and, when the address is on a corporate domain,
|
|
62
|
+
the company is found-or-created and associated. Timeline notes (`forms.timelineNote`,
|
|
63
|
+
default `true`) add a recap of that page plus the originating subject on the
|
|
64
|
+
contact timeline — they don't replace the conversion.
|
|
62
65
|
|
|
63
66
|
CRM properties are **never created**. Map to properties that already exist in
|
|
64
67
|
the portal; opting into field sync only adds form fields that point at those
|
|
@@ -75,7 +78,7 @@ hubspot: {
|
|
|
75
78
|
region: env("HUBSPOT_REGION", "eu1"), // eu1 → api-eu1.hsforms.com
|
|
76
79
|
forms: {
|
|
77
80
|
companyFromDomain: true, // Company by corporate domain + association
|
|
78
|
-
timelineNote:
|
|
81
|
+
timelineNote: true, // recap note (page + subject) next to the conversion
|
|
79
82
|
defaultFormId: env("HUBSPOT_DEFAULT_FORM_ID", ""),
|
|
80
83
|
submissionMode: "auto", // auto | forms | crm
|
|
81
84
|
writeExtraProperties: true,
|
|
@@ -5,12 +5,12 @@ import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
|
5
5
|
import { Typography, Flex, Box, SingleSelect, SingleSelectOption, MultiSelect, MultiSelectOption, TextInput, IconButton, Button, Combobox, ComboboxOption, Field, Textarea, Checkbox, Divider, Loader, Badge, Table, Thead, Tr, Th, Tbody, Td, Modal } from "@strapi/design-system";
|
|
6
6
|
import { Trash, Plus, ArrowClockwise, ArrowLeft, Drag, ArrowUp, ArrowDown, List, Duplicate, Download } from "@strapi/icons";
|
|
7
7
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
8
|
-
import { g as getTranslation, P as PLUGIN_ID } from "./index-
|
|
8
|
+
import { g as getTranslation, P as PLUGIN_ID } from "./index-B8GYi6sw.mjs";
|
|
9
9
|
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, useDroppable, closestCorners } from "@dnd-kit/core";
|
|
10
10
|
import { arrayMove, sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
|
|
11
11
|
import { CSS } from "@dnd-kit/utilities";
|
|
12
|
-
import { o as objectLabel } from "./objectLabels
|
|
13
|
-
import { u as useHubspotSchema } from "./useHubspotSchema-
|
|
12
|
+
import { o as objectLabel } from "./objectLabels-DybqhBdT.mjs";
|
|
13
|
+
import { u as useHubspotSchema } from "./useHubspotSchema-DtcHHUOb.mjs";
|
|
14
14
|
const OPERATORS = [
|
|
15
15
|
"eq",
|
|
16
16
|
"neq",
|
|
@@ -7,12 +7,12 @@ const index = require("./index-DkTxsEqL.js");
|
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const admin = require("@strapi/strapi/admin");
|
|
10
|
-
const index$1 = require("./index-
|
|
10
|
+
const index$1 = require("./index-XEuSPuUj.js");
|
|
11
11
|
const core = require("@dnd-kit/core");
|
|
12
12
|
const sortable = require("@dnd-kit/sortable");
|
|
13
13
|
const utilities = require("@dnd-kit/utilities");
|
|
14
|
-
const objectLabels = require("./objectLabels-
|
|
15
|
-
const useHubspotSchema = require("./useHubspotSchema-
|
|
14
|
+
const objectLabels = require("./objectLabels-wBwfLdZt.js");
|
|
15
|
+
const useHubspotSchema = require("./useHubspotSchema-WvgW3od8.js");
|
|
16
16
|
function _interopNamespace(e) {
|
|
17
17
|
if (e && e.__esModule) return e;
|
|
18
18
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
4
4
|
import { Field, Flex, Loader, Combobox, ComboboxOption } from "@strapi/design-system";
|
|
5
5
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
6
|
-
import { P as PLUGIN_ID, g as getTranslation } from "./index-
|
|
6
|
+
import { P as PLUGIN_ID, g as getTranslation } from "./index-B8GYi6sw.mjs";
|
|
7
7
|
const HubspotFormInput = React.forwardRef(
|
|
8
8
|
({ name, value, onChange, disabled, error, required, label, hint, labelAction }, ref) => {
|
|
9
9
|
const { formatMessage } = useIntl();
|
|
@@ -5,7 +5,7 @@ const React = require("react");
|
|
|
5
5
|
const index = require("./index-DkTxsEqL.js");
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
7
|
const admin = require("@strapi/strapi/admin");
|
|
8
|
-
const index$1 = require("./index-
|
|
8
|
+
const index$1 = require("./index-XEuSPuUj.js");
|
|
9
9
|
function _interopNamespace(e) {
|
|
10
10
|
if (e && e.__esModule) return e;
|
|
11
11
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -2,9 +2,9 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
4
4
|
import { Field, Flex, Loader, SingleSelect, SingleSelectOption } from "@strapi/design-system";
|
|
5
|
-
import { g as getTranslation } from "./index-
|
|
6
|
-
import { o as objectLabel } from "./objectLabels
|
|
7
|
-
import { u as useHubspotSchema } from "./useHubspotSchema-
|
|
5
|
+
import { g as getTranslation } from "./index-B8GYi6sw.mjs";
|
|
6
|
+
import { o as objectLabel } from "./objectLabels-DybqhBdT.mjs";
|
|
7
|
+
import { u as useHubspotSchema } from "./useHubspotSchema-DtcHHUOb.mjs";
|
|
8
8
|
const HubspotObjectInput = React.forwardRef(
|
|
9
9
|
({ name, value, onChange, disabled, error, required, label, hint, labelAction }, ref) => {
|
|
10
10
|
const intl = useIntl();
|
|
@@ -4,9 +4,9 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const React = require("react");
|
|
5
5
|
const index = require("./index-DkTxsEqL.js");
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
|
-
const index$1 = require("./index-
|
|
8
|
-
const objectLabels = require("./objectLabels-
|
|
9
|
-
const useHubspotSchema = require("./useHubspotSchema-
|
|
7
|
+
const index$1 = require("./index-XEuSPuUj.js");
|
|
8
|
+
const objectLabels = require("./objectLabels-wBwfLdZt.js");
|
|
9
|
+
const useHubspotSchema = require("./useHubspotSchema-WvgW3od8.js");
|
|
10
10
|
function _interopNamespace(e) {
|
|
11
11
|
if (e && e.__esModule) return e;
|
|
12
12
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -6,9 +6,9 @@ const index = require("./index-DkTxsEqL.js");
|
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
7
|
const icons = require("@strapi/icons");
|
|
8
8
|
const admin = require("@strapi/strapi/admin");
|
|
9
|
-
const index$1 = require("./index-
|
|
10
|
-
const objectLabels = require("./objectLabels-
|
|
11
|
-
const useHubspotSchema = require("./useHubspotSchema-
|
|
9
|
+
const index$1 = require("./index-XEuSPuUj.js");
|
|
10
|
+
const objectLabels = require("./objectLabels-wBwfLdZt.js");
|
|
11
|
+
const useHubspotSchema = require("./useHubspotSchema-WvgW3od8.js");
|
|
12
12
|
function _interopNamespace(e) {
|
|
13
13
|
if (e && e.__esModule) return e;
|
|
14
14
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
package/dist/_chunks/{HubspotPropertyInput-BHfpBD36.mjs → HubspotPropertyInput-Dsn7ikop.mjs}
RENAMED
|
@@ -4,9 +4,9 @@ import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
|
4
4
|
import { Field, Flex, Loader, Combobox, ComboboxOption, IconButton, Button, Typography, Link } from "@strapi/design-system";
|
|
5
5
|
import { ArrowClockwise } from "@strapi/icons";
|
|
6
6
|
import { useField } from "@strapi/strapi/admin";
|
|
7
|
-
import { g as getTranslation } from "./index-
|
|
8
|
-
import { o as objectLabel } from "./objectLabels
|
|
9
|
-
import { u as useHubspotSchema } from "./useHubspotSchema-
|
|
7
|
+
import { g as getTranslation } from "./index-B8GYi6sw.mjs";
|
|
8
|
+
import { o as objectLabel } from "./objectLabels-DybqhBdT.mjs";
|
|
9
|
+
import { u as useHubspotSchema } from "./useHubspotSchema-DtcHHUOb.mjs";
|
|
10
10
|
const oneLine = {
|
|
11
11
|
display: "block",
|
|
12
12
|
whiteSpace: "nowrap",
|
|
@@ -3,9 +3,9 @@ import * as React from "react";
|
|
|
3
3
|
import { u as useIntl } from "./index-CEh8vkxY.mjs";
|
|
4
4
|
import { Flex, Divider, Typography, Button, Box, Link, Badge, Loader, Field, SingleSelect, SingleSelectOption, Checkbox } from "@strapi/design-system";
|
|
5
5
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
6
|
-
import { g as getTranslation, P as PLUGIN_ID } from "./index-
|
|
6
|
+
import { g as getTranslation, P as PLUGIN_ID } from "./index-B8GYi6sw.mjs";
|
|
7
7
|
import { Link as Link$1 } from "react-router-dom";
|
|
8
|
-
import { o as objectLabel } from "./objectLabels
|
|
8
|
+
import { o as objectLabel } from "./objectLabels-DybqhBdT.mjs";
|
|
9
9
|
const AuditSection = ({ configured }) => {
|
|
10
10
|
const intl = useIntl();
|
|
11
11
|
const { formatMessage } = intl;
|
|
@@ -184,6 +184,7 @@ const HubspotSettings = () => {
|
|
|
184
184
|
const [submissionMode, setSubmissionMode] = React.useState("auto");
|
|
185
185
|
const [writeExtraProperties, setWriteExtraProperties] = React.useState(true);
|
|
186
186
|
const [syncFieldsOnPublish, setSyncFieldsOnPublish] = React.useState(false);
|
|
187
|
+
const [timelineNote, setTimelineNote] = React.useState(true);
|
|
187
188
|
const [forms, setForms] = React.useState([]);
|
|
188
189
|
const [busy, setBusy] = React.useState(false);
|
|
189
190
|
const [feedback, setFeedback] = React.useState(
|
|
@@ -198,6 +199,7 @@ const HubspotSettings = () => {
|
|
|
198
199
|
setSubmissionMode(data.submissionMode === "crm" || data.submissionMode === "forms" ? data.submissionMode : "auto");
|
|
199
200
|
setWriteExtraProperties(data.writeExtraProperties !== false);
|
|
200
201
|
setSyncFieldsOnPublish(data.syncFieldsOnPublish === true);
|
|
202
|
+
setTimelineNote(data.timelineNote !== false);
|
|
201
203
|
setForms(Array.isArray(data.forms) ? data.forms : []);
|
|
202
204
|
};
|
|
203
205
|
const load = React.useCallback(async () => {
|
|
@@ -220,7 +222,8 @@ const HubspotSettings = () => {
|
|
|
220
222
|
defaultFormId,
|
|
221
223
|
submissionMode,
|
|
222
224
|
writeExtraProperties,
|
|
223
|
-
syncFieldsOnPublish
|
|
225
|
+
syncFieldsOnPublish,
|
|
226
|
+
timelineNote
|
|
224
227
|
});
|
|
225
228
|
setApiKey("");
|
|
226
229
|
await load();
|
|
@@ -454,6 +457,21 @@ const HubspotSettings = () => {
|
|
|
454
457
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
455
458
|
"settings.sync.hint",
|
|
456
459
|
"Strapi-first installs: a field added here appears on the HubSpot form next publish. HubSpot-first installs should leave this off — importing a form already carries its fields. Properties themselves are never created; map to ones that exist in the portal."
|
|
460
|
+
) }),
|
|
461
|
+
/* @__PURE__ */ jsx(
|
|
462
|
+
Checkbox,
|
|
463
|
+
{
|
|
464
|
+
checked: timelineNote,
|
|
465
|
+
onCheckedChange: (checked) => setTimelineNote(checked === true),
|
|
466
|
+
children: t(
|
|
467
|
+
"settings.note.label",
|
|
468
|
+
"Also write a recap note on the contact (page, subject, answers)"
|
|
469
|
+
)
|
|
470
|
+
}
|
|
471
|
+
),
|
|
472
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
473
|
+
"settings.note.hint",
|
|
474
|
+
"The conversion already carries the page URL (pageUri). The note puts that page plus the originating subject on the contact timeline, next to the native form submission."
|
|
457
475
|
) })
|
|
458
476
|
] }) }),
|
|
459
477
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
@@ -5,9 +5,9 @@ const React = require("react");
|
|
|
5
5
|
const index = require("./index-DkTxsEqL.js");
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
7
|
const admin = require("@strapi/strapi/admin");
|
|
8
|
-
const index$1 = require("./index-
|
|
8
|
+
const index$1 = require("./index-XEuSPuUj.js");
|
|
9
9
|
const reactRouterDom = require("react-router-dom");
|
|
10
|
-
const objectLabels = require("./objectLabels-
|
|
10
|
+
const objectLabels = require("./objectLabels-wBwfLdZt.js");
|
|
11
11
|
function _interopNamespace(e) {
|
|
12
12
|
if (e && e.__esModule) return e;
|
|
13
13
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -204,6 +204,7 @@ const HubspotSettings = () => {
|
|
|
204
204
|
const [submissionMode, setSubmissionMode] = React__namespace.useState("auto");
|
|
205
205
|
const [writeExtraProperties, setWriteExtraProperties] = React__namespace.useState(true);
|
|
206
206
|
const [syncFieldsOnPublish, setSyncFieldsOnPublish] = React__namespace.useState(false);
|
|
207
|
+
const [timelineNote, setTimelineNote] = React__namespace.useState(true);
|
|
207
208
|
const [forms, setForms] = React__namespace.useState([]);
|
|
208
209
|
const [busy, setBusy] = React__namespace.useState(false);
|
|
209
210
|
const [feedback, setFeedback] = React__namespace.useState(
|
|
@@ -218,6 +219,7 @@ const HubspotSettings = () => {
|
|
|
218
219
|
setSubmissionMode(data.submissionMode === "crm" || data.submissionMode === "forms" ? data.submissionMode : "auto");
|
|
219
220
|
setWriteExtraProperties(data.writeExtraProperties !== false);
|
|
220
221
|
setSyncFieldsOnPublish(data.syncFieldsOnPublish === true);
|
|
222
|
+
setTimelineNote(data.timelineNote !== false);
|
|
221
223
|
setForms(Array.isArray(data.forms) ? data.forms : []);
|
|
222
224
|
};
|
|
223
225
|
const load = React__namespace.useCallback(async () => {
|
|
@@ -240,7 +242,8 @@ const HubspotSettings = () => {
|
|
|
240
242
|
defaultFormId,
|
|
241
243
|
submissionMode,
|
|
242
244
|
writeExtraProperties,
|
|
243
|
-
syncFieldsOnPublish
|
|
245
|
+
syncFieldsOnPublish,
|
|
246
|
+
timelineNote
|
|
244
247
|
});
|
|
245
248
|
setApiKey("");
|
|
246
249
|
await load();
|
|
@@ -474,6 +477,21 @@ const HubspotSettings = () => {
|
|
|
474
477
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
475
478
|
"settings.sync.hint",
|
|
476
479
|
"Strapi-first installs: a field added here appears on the HubSpot form next publish. HubSpot-first installs should leave this off — importing a form already carries its fields. Properties themselves are never created; map to ones that exist in the portal."
|
|
480
|
+
) }),
|
|
481
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
482
|
+
designSystem.Checkbox,
|
|
483
|
+
{
|
|
484
|
+
checked: timelineNote,
|
|
485
|
+
onCheckedChange: (checked) => setTimelineNote(checked === true),
|
|
486
|
+
children: t(
|
|
487
|
+
"settings.note.label",
|
|
488
|
+
"Also write a recap note on the contact (page, subject, answers)"
|
|
489
|
+
)
|
|
490
|
+
}
|
|
491
|
+
),
|
|
492
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
|
|
493
|
+
"settings.note.hint",
|
|
494
|
+
"The conversion already carries the page URL (pageUri). The note puts that page plus the originating subject on the contact timeline, next to the native form submission."
|
|
477
495
|
) })
|
|
478
496
|
] }) }),
|
|
479
497
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
@@ -25,7 +25,7 @@ const index = {
|
|
|
25
25
|
icon: PaperPlane,
|
|
26
26
|
intlLabel: { id: `${PLUGIN_ID}.menu.label`, defaultMessage: "HubSpot Forms" },
|
|
27
27
|
permissions: [{ action: `plugin::${PLUGIN_ID}.forms`, subject: null }],
|
|
28
|
-
Component: async () => (await import("./Forms-
|
|
28
|
+
Component: async () => (await import("./Forms-BBaw53Tz.mjs")).default
|
|
29
29
|
});
|
|
30
30
|
app.customFields.register({
|
|
31
31
|
name: "property",
|
|
@@ -40,7 +40,7 @@ const index = {
|
|
|
40
40
|
defaultMessage: "Picked from the portal's real properties"
|
|
41
41
|
},
|
|
42
42
|
components: {
|
|
43
|
-
Input: async () => import("./HubspotPropertyInput-
|
|
43
|
+
Input: async () => import("./HubspotPropertyInput-Dsn7ikop.mjs")
|
|
44
44
|
},
|
|
45
45
|
// Exposed in the Content-Type Builder. Without this, `objectField` could
|
|
46
46
|
// only be set by hand-editing schema.json — which is not how anyone
|
|
@@ -103,7 +103,7 @@ const index = {
|
|
|
103
103
|
defaultMessage: "Picked from the portal's configured objects"
|
|
104
104
|
},
|
|
105
105
|
components: {
|
|
106
|
-
Input: async () => import("./HubspotObjectInput-
|
|
106
|
+
Input: async () => import("./HubspotObjectInput-BA16dswz.mjs")
|
|
107
107
|
}
|
|
108
108
|
});
|
|
109
109
|
app.customFields.register({
|
|
@@ -119,7 +119,7 @@ const index = {
|
|
|
119
119
|
defaultMessage: "A form built in the HubSpot form builder, stored by slug"
|
|
120
120
|
},
|
|
121
121
|
components: {
|
|
122
|
-
Input: async () => import("./HubspotFormInput-
|
|
122
|
+
Input: async () => import("./HubspotFormInput-DIo6hCNz.mjs")
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
app.createSettingSection(
|
|
@@ -135,7 +135,7 @@ const index = {
|
|
|
135
135
|
// Mirrors the RBAC action registered server-side: a role without it
|
|
136
136
|
// doesn't see the link at all — the routes refuse it anyway.
|
|
137
137
|
permissions: [{ action: `plugin::${PLUGIN_ID}.settings`, subject: null }],
|
|
138
|
-
Component: async () => (await import("./Settings-
|
|
138
|
+
Component: async () => (await import("./Settings-DxX9Uh_2.mjs")).default
|
|
139
139
|
}
|
|
140
140
|
]
|
|
141
141
|
);
|
|
@@ -26,7 +26,7 @@ const index = {
|
|
|
26
26
|
icon: icons.PaperPlane,
|
|
27
27
|
intlLabel: { id: `${PLUGIN_ID}.menu.label`, defaultMessage: "HubSpot Forms" },
|
|
28
28
|
permissions: [{ action: `plugin::${PLUGIN_ID}.forms`, subject: null }],
|
|
29
|
-
Component: async () => (await Promise.resolve().then(() => require("./Forms-
|
|
29
|
+
Component: async () => (await Promise.resolve().then(() => require("./Forms-CIJrUB_n.js"))).default
|
|
30
30
|
});
|
|
31
31
|
app.customFields.register({
|
|
32
32
|
name: "property",
|
|
@@ -41,7 +41,7 @@ const index = {
|
|
|
41
41
|
defaultMessage: "Picked from the portal's real properties"
|
|
42
42
|
},
|
|
43
43
|
components: {
|
|
44
|
-
Input: async () => Promise.resolve().then(() => require("./HubspotPropertyInput-
|
|
44
|
+
Input: async () => Promise.resolve().then(() => require("./HubspotPropertyInput-C77Op1Wm.js"))
|
|
45
45
|
},
|
|
46
46
|
// Exposed in the Content-Type Builder. Without this, `objectField` could
|
|
47
47
|
// only be set by hand-editing schema.json — which is not how anyone
|
|
@@ -104,7 +104,7 @@ const index = {
|
|
|
104
104
|
defaultMessage: "Picked from the portal's configured objects"
|
|
105
105
|
},
|
|
106
106
|
components: {
|
|
107
|
-
Input: async () => Promise.resolve().then(() => require("./HubspotObjectInput-
|
|
107
|
+
Input: async () => Promise.resolve().then(() => require("./HubspotObjectInput-BIqC8tl2.js"))
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
110
|
app.customFields.register({
|
|
@@ -120,7 +120,7 @@ const index = {
|
|
|
120
120
|
defaultMessage: "A form built in the HubSpot form builder, stored by slug"
|
|
121
121
|
},
|
|
122
122
|
components: {
|
|
123
|
-
Input: async () => Promise.resolve().then(() => require("./HubspotFormInput-
|
|
123
|
+
Input: async () => Promise.resolve().then(() => require("./HubspotFormInput-DSTuQ_bx.js"))
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
app.createSettingSection(
|
|
@@ -136,7 +136,7 @@ const index = {
|
|
|
136
136
|
// Mirrors the RBAC action registered server-side: a role without it
|
|
137
137
|
// doesn't see the link at all — the routes refuse it anyway.
|
|
138
138
|
permissions: [{ action: `plugin::${PLUGIN_ID}.settings`, subject: null }],
|
|
139
|
-
Component: async () => (await Promise.resolve().then(() => require("./Settings-
|
|
139
|
+
Component: async () => (await Promise.resolve().then(() => require("./Settings-PVhJVPqq.js"))).default
|
|
140
140
|
}
|
|
141
141
|
]
|
|
142
142
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
3
|
-
import { P as PLUGIN_ID } from "./index-
|
|
3
|
+
import { P as PLUGIN_ID } from "./index-B8GYi6sw.mjs";
|
|
4
4
|
let cached = null;
|
|
5
5
|
let inFlight = null;
|
|
6
6
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const React = require("react");
|
|
3
3
|
const admin = require("@strapi/strapi/admin");
|
|
4
|
-
const index = require("./index-
|
|
4
|
+
const index = require("./index-XEuSPuUj.js");
|
|
5
5
|
function _interopNamespace(e) {
|
|
6
6
|
if (e && e.__esModule) return e;
|
|
7
7
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -191,7 +191,8 @@ function policyFrom(stored, forms) {
|
|
|
191
191
|
return {
|
|
192
192
|
submissionMode: asSubmissionMode(stored.submissionMode) ?? asSubmissionMode(forms.submissionMode) ?? "auto",
|
|
193
193
|
writeExtraProperties: asBool(stored.writeExtraProperties) ?? asBool(forms.writeExtraProperties) ?? true,
|
|
194
|
-
syncFieldsOnPublish: asBool(stored.syncFieldsOnPublish) ?? asBool(forms.syncFieldsOnPublish) ?? false
|
|
194
|
+
syncFieldsOnPublish: asBool(stored.syncFieldsOnPublish) ?? asBool(forms.syncFieldsOnPublish) ?? false,
|
|
195
|
+
timelineNote: asBool(stored.timelineNote) ?? asBool(forms.timelineNote) ?? true
|
|
195
196
|
};
|
|
196
197
|
}
|
|
197
198
|
async function resolvePolicy(strapi) {
|
|
@@ -275,6 +276,9 @@ async function patchStoredSettings(strapi, body) {
|
|
|
275
276
|
if ("syncFieldsOnPublish" in body && typeof body.syncFieldsOnPublish === "boolean") {
|
|
276
277
|
next.syncFieldsOnPublish = body.syncFieldsOnPublish;
|
|
277
278
|
}
|
|
279
|
+
if ("timelineNote" in body && typeof body.timelineNote === "boolean") {
|
|
280
|
+
next.timelineNote = body.timelineNote;
|
|
281
|
+
}
|
|
278
282
|
await setStoredSettings(strapi, next);
|
|
279
283
|
}
|
|
280
284
|
async function clearStoredApiKey(strapi) {
|
|
@@ -2445,7 +2449,7 @@ function createFormsService(strapi, _opts = {}) {
|
|
|
2445
2449
|
context: {
|
|
2446
2450
|
hutk: sanitizeHutk(meta.hutk),
|
|
2447
2451
|
pageUri: typeof meta.pageUrl === "string" ? meta.pageUrl : void 0,
|
|
2448
|
-
pageName: typeof meta.pageName === "string" && meta.pageName || (form.title || form.name) || void 0,
|
|
2452
|
+
pageName: typeof meta.pageName === "string" && meta.pageName || typeof meta.originLabel === "string" && meta.originLabel || (form.title || form.name) || void 0,
|
|
2449
2453
|
ipAddress: sanitizeIp(meta.ipAddress)
|
|
2450
2454
|
},
|
|
2451
2455
|
consent: { given: meta.consent === true },
|
|
@@ -2525,7 +2529,7 @@ function createFormsService(strapi, _opts = {}) {
|
|
|
2525
2529
|
strapi.log.warn(`[hubspot] company sync failed (contact OK) — ${err.message}`);
|
|
2526
2530
|
}
|
|
2527
2531
|
}
|
|
2528
|
-
if (contactId &&
|
|
2532
|
+
if (contactId && policy.timelineNote) {
|
|
2529
2533
|
try {
|
|
2530
2534
|
await createLeadNote(apiKey, {
|
|
2531
2535
|
contactId,
|
|
@@ -3334,8 +3338,8 @@ const config = {
|
|
|
3334
3338
|
// Submission pipeline of the built forms:
|
|
3335
3339
|
// - companyFromDomain: a corporate email upserts the Company (deduped by
|
|
3336
3340
|
// domain) and associates it to the contact;
|
|
3337
|
-
// - timelineNote: recap note on the
|
|
3338
|
-
//
|
|
3341
|
+
// - timelineNote: recap note on the contact after a successful sync
|
|
3342
|
+
// (page URL, subject, answers) — alongside a Forms API conversion;
|
|
3339
3343
|
// - defaultFormId: portal-wide marketing form GUID when a builder form
|
|
3340
3344
|
// doesn't set its own — swap with the portal at production cutover.
|
|
3341
3345
|
// - submissionMode / writeExtraProperties / syncFieldsOnPublish: see
|
package/dist/server/index.mjs
CHANGED
|
@@ -190,7 +190,8 @@ function policyFrom(stored, forms) {
|
|
|
190
190
|
return {
|
|
191
191
|
submissionMode: asSubmissionMode(stored.submissionMode) ?? asSubmissionMode(forms.submissionMode) ?? "auto",
|
|
192
192
|
writeExtraProperties: asBool(stored.writeExtraProperties) ?? asBool(forms.writeExtraProperties) ?? true,
|
|
193
|
-
syncFieldsOnPublish: asBool(stored.syncFieldsOnPublish) ?? asBool(forms.syncFieldsOnPublish) ?? false
|
|
193
|
+
syncFieldsOnPublish: asBool(stored.syncFieldsOnPublish) ?? asBool(forms.syncFieldsOnPublish) ?? false,
|
|
194
|
+
timelineNote: asBool(stored.timelineNote) ?? asBool(forms.timelineNote) ?? true
|
|
194
195
|
};
|
|
195
196
|
}
|
|
196
197
|
async function resolvePolicy(strapi) {
|
|
@@ -274,6 +275,9 @@ async function patchStoredSettings(strapi, body) {
|
|
|
274
275
|
if ("syncFieldsOnPublish" in body && typeof body.syncFieldsOnPublish === "boolean") {
|
|
275
276
|
next.syncFieldsOnPublish = body.syncFieldsOnPublish;
|
|
276
277
|
}
|
|
278
|
+
if ("timelineNote" in body && typeof body.timelineNote === "boolean") {
|
|
279
|
+
next.timelineNote = body.timelineNote;
|
|
280
|
+
}
|
|
277
281
|
await setStoredSettings(strapi, next);
|
|
278
282
|
}
|
|
279
283
|
async function clearStoredApiKey(strapi) {
|
|
@@ -2444,7 +2448,7 @@ function createFormsService(strapi, _opts = {}) {
|
|
|
2444
2448
|
context: {
|
|
2445
2449
|
hutk: sanitizeHutk(meta.hutk),
|
|
2446
2450
|
pageUri: typeof meta.pageUrl === "string" ? meta.pageUrl : void 0,
|
|
2447
|
-
pageName: typeof meta.pageName === "string" && meta.pageName || (form.title || form.name) || void 0,
|
|
2451
|
+
pageName: typeof meta.pageName === "string" && meta.pageName || typeof meta.originLabel === "string" && meta.originLabel || (form.title || form.name) || void 0,
|
|
2448
2452
|
ipAddress: sanitizeIp(meta.ipAddress)
|
|
2449
2453
|
},
|
|
2450
2454
|
consent: { given: meta.consent === true },
|
|
@@ -2524,7 +2528,7 @@ function createFormsService(strapi, _opts = {}) {
|
|
|
2524
2528
|
strapi.log.warn(`[hubspot] company sync failed (contact OK) — ${err.message}`);
|
|
2525
2529
|
}
|
|
2526
2530
|
}
|
|
2527
|
-
if (contactId &&
|
|
2531
|
+
if (contactId && policy.timelineNote) {
|
|
2528
2532
|
try {
|
|
2529
2533
|
await createLeadNote(apiKey, {
|
|
2530
2534
|
contactId,
|
|
@@ -3333,8 +3337,8 @@ const config = {
|
|
|
3333
3337
|
// Submission pipeline of the built forms:
|
|
3334
3338
|
// - companyFromDomain: a corporate email upserts the Company (deduped by
|
|
3335
3339
|
// domain) and associates it to the contact;
|
|
3336
|
-
// - timelineNote: recap note on the
|
|
3337
|
-
//
|
|
3340
|
+
// - timelineNote: recap note on the contact after a successful sync
|
|
3341
|
+
// (page URL, subject, answers) — alongside a Forms API conversion;
|
|
3338
3342
|
// - defaultFormId: portal-wide marketing form GUID when a builder form
|
|
3339
3343
|
// doesn't set its own — swap with the portal at production cutover.
|
|
3340
3344
|
// - submissionMode / writeExtraProperties / syncFieldsOnPublish: see
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* conversion (with leftover CRM writes for mapped fields the HubSpot form
|
|
7
7
|
* dropped), CRM upsert only, or automatic (Forms API when a GUID is linked).
|
|
8
8
|
* Company find-or-create still runs after a successful submit. Timeline notes
|
|
9
|
-
*
|
|
10
|
-
* the lead — a CRM
|
|
9
|
+
* (page URL, subject, answers) are optional extra context on the contact,
|
|
10
|
+
* alongside a native conversion. The form submission is the lead — a CRM
|
|
11
|
+
* outage never loses it.
|
|
11
12
|
*/
|
|
12
13
|
import type { Core } from "@strapi/strapi";
|
|
13
14
|
import { type FormDefinition, type Primitive } from "./conditions";
|
|
@@ -24,6 +24,7 @@ export interface StoredSettings {
|
|
|
24
24
|
submissionMode?: SubmissionMode;
|
|
25
25
|
writeExtraProperties?: boolean;
|
|
26
26
|
syncFieldsOnPublish?: boolean;
|
|
27
|
+
timelineNote?: boolean;
|
|
27
28
|
}
|
|
28
29
|
export interface HubspotPolicy {
|
|
29
30
|
/** How submissions reach HubSpot. `auto` uses Forms API when a GUID is set. */
|
|
@@ -32,6 +33,8 @@ export interface HubspotPolicy {
|
|
|
32
33
|
writeExtraProperties: boolean;
|
|
33
34
|
/** On publish, PATCH missing mapped contact fields onto the HubSpot form. */
|
|
34
35
|
syncFieldsOnPublish: boolean;
|
|
36
|
+
/** Recap note on the contact (page URL, subject, answers) after a successful sync. */
|
|
37
|
+
timelineNote: boolean;
|
|
35
38
|
}
|
|
36
39
|
export interface PublicSettings {
|
|
37
40
|
configured: boolean;
|
|
@@ -48,6 +51,7 @@ export interface PublicSettings {
|
|
|
48
51
|
submissionMode: SubmissionMode;
|
|
49
52
|
writeExtraProperties: boolean;
|
|
50
53
|
syncFieldsOnPublish: boolean;
|
|
54
|
+
timelineNote: boolean;
|
|
51
55
|
}
|
|
52
56
|
export interface HubspotAccount {
|
|
53
57
|
portalId: string;
|
|
@@ -62,6 +66,7 @@ interface FormsCfg {
|
|
|
62
66
|
submissionMode?: unknown;
|
|
63
67
|
writeExtraProperties?: unknown;
|
|
64
68
|
syncFieldsOnPublish?: unknown;
|
|
69
|
+
timelineNote?: unknown;
|
|
65
70
|
}
|
|
66
71
|
export declare function policyFrom(stored: StoredSettings, forms: FormsCfg): HubspotPolicy;
|
|
67
72
|
export declare function resolvePolicy(strapi: Core.Strapi): Promise<HubspotPolicy>;
|
|
@@ -80,6 +85,7 @@ export interface SettingsPatch {
|
|
|
80
85
|
submissionMode?: unknown;
|
|
81
86
|
writeExtraProperties?: unknown;
|
|
82
87
|
syncFieldsOnPublish?: unknown;
|
|
88
|
+
timelineNote?: unknown;
|
|
83
89
|
}
|
|
84
90
|
/** Merge a PATCH-like body into the store without dropping the saved key. */
|
|
85
91
|
export declare function patchStoredSettings(strapi: Core.Strapi, body: SettingsPatch): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-hubspot",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.3",
|
|
4
4
|
"description": "The form builder for HubSpot in Strapi — multi-step forms with conditional fields mapped to real CRM properties, a public submit pipeline with retries, and save-time mapping validation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"strapi",
|