strapi-plugin-hubspot 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/README.md +110 -4
- package/dist/_chunks/Forms-B2y_0-x4.mjs +989 -0
- package/dist/_chunks/Forms-CaT0YEJo.js +1007 -0
- package/dist/_chunks/{HubspotObjectInput-DpXMFiPg.js → HubspotObjectInput-Crpcpa8T.js} +3 -3
- package/dist/_chunks/{HubspotObjectInput-D9r_sGFe.mjs → HubspotObjectInput-DdLAUh0N.mjs} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-Dk0t0NVe.js → HubspotPropertyInput-SnJMFsII.js} +3 -3
- package/dist/_chunks/{HubspotPropertyInput-av9782v6.mjs → HubspotPropertyInput-k7wMSmeF.mjs} +3 -3
- package/dist/_chunks/Settings-BMOmj4NJ.mjs +321 -0
- package/dist/_chunks/Settings-BPAAD-QW.js +339 -0
- package/dist/_chunks/en-CJ9wYHgN.mjs +197 -0
- package/dist/_chunks/en-C_-N8cjv.js +197 -0
- package/dist/_chunks/fr-BHObPoUp.js +197 -0
- package/dist/_chunks/fr-DttDn-2Y.mjs +197 -0
- package/dist/_chunks/{index-B3c9qEYU.js → index-D_CPrIHe.js} +12 -4
- package/dist/_chunks/{index-C0XHwXog.mjs → index-foVSGFWb.mjs} +12 -4
- package/dist/_chunks/{objectLabels-DwOMxLfh.mjs → objectLabels-C9ocOgVY.mjs} +1 -1
- package/dist/_chunks/{objectLabels-DksWJnOK.js → objectLabels-VTt_-qTZ.js} +1 -1
- package/dist/_chunks/{useHubspotSchema-C3vn1DuR.js → useHubspotSchema-B8SctALV.js} +1 -1
- package/dist/_chunks/{useHubspotSchema-BGtg7Ffj.mjs → useHubspotSchema-Du3rLY_O.mjs} +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.mjs +2 -1
- package/dist/admin/src/builder/ConditionEditor.d.ts +17 -0
- package/dist/admin/src/builder/FieldPanel.d.ts +16 -0
- package/dist/admin/src/builder/types.d.ts +90 -0
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/FormEditor.d.ts +9 -0
- package/dist/admin/src/pages/Forms.d.ts +4 -0
- package/dist/admin/src/pages/FormsList.d.ts +8 -0
- package/dist/server/index.js +880 -5
- package/dist/server/index.mjs +880 -5
- package/dist/server/src/__tests__/conditions.test.d.ts +1 -0
- package/dist/server/src/__tests__/forms.test.d.ts +1 -0
- package/dist/server/src/__tests__/formsSubmit.test.d.ts +1 -0
- package/dist/server/src/__tests__/importLegacy.test.d.ts +1 -0
- package/dist/server/src/conditions.d.ts +88 -0
- package/dist/server/src/content-types.d.ts +161 -9
- package/dist/server/src/forms.d.ts +81 -0
- package/dist/server/src/formsAdmin.d.ts +39 -0
- package/dist/server/src/importLegacy.d.ts +25 -0
- package/dist/server/src/index.d.ts +214 -16
- package/dist/shared/types.d.ts +103 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.mjs +2 -0
- package/package.json +24 -6
- package/dist/_chunks/Settings-CPxe6LdH.js +0 -1311
- package/dist/_chunks/Settings-DTzk6GWO.mjs +0 -1293
- package/dist/_chunks/en-BN5fD3ai.js +0 -83
- package/dist/_chunks/en-xeTTAUtX.mjs +0 -83
- package/dist/_chunks/fr-BKODkfPy.mjs +0 -83
- package/dist/_chunks/fr-D3-oO8Lt.js +0 -83
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.6.1 — 2026-08-28
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Admin crash on the HubSpot Forms page** ("Error" with no message, from a
|
|
7
|
+
react-router invariant): `react-router-dom` was missing from
|
|
8
|
+
`peerDependencies`, so 0.6.0 shipped its own inlined copy — a second Router
|
|
9
|
+
context the plugin's `<Routes>` could not reach. It is now externalized to
|
|
10
|
+
the host admin's copy, like every other shared library.
|
|
11
|
+
- A `check-externals` step now runs on every build and fails when a
|
|
12
|
+
must-be-external library gets inlined, so this class of bug can't ship again.
|
|
13
|
+
|
|
14
|
+
## 0.6.0 — 2026-08-28
|
|
15
|
+
|
|
16
|
+
The plugin becomes **the form builder for HubSpot**.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `plugin::hubspot.form` content type (draft & publish, i18n) with a versioned
|
|
20
|
+
JSON `definition` — steps → fields → conditions — hidden from the Content
|
|
21
|
+
Manager: the builder is its editor.
|
|
22
|
+
- **HubSpot Forms** admin page (new RBAC action `plugin::hubspot.forms`):
|
|
23
|
+
list, create, delete; builder with reorderable step/field cards, a field
|
|
24
|
+
panel reusing the portal pickers (object, property, enumeration option
|
|
25
|
+
import, deep link), and a condition editor (AND/OR, earlier fields only,
|
|
26
|
+
option-aware values).
|
|
27
|
+
- Conditional visibility for fields **and steps** — `eq`, `neq`, `contains`,
|
|
28
|
+
`empty`, `notEmpty`, `gt`, `lt` — enforced server-side at submission: hidden
|
|
29
|
+
fields lose `required` and their values never reach the CRM.
|
|
30
|
+
- Public content-api routes: `GET /api/hubspot/forms/:slug` (published form,
|
|
31
|
+
CRM mapping stripped) and `POST /api/hubspot/forms/:slug/submit`
|
|
32
|
+
(bounds-checked, conditions re-evaluated, contact upsert through the
|
|
33
|
+
existing retry/replay pipeline, optional company-by-corporate-domain +
|
|
34
|
+
association, optional timeline recap note).
|
|
35
|
+
- `plugin::hubspot.submission` collection — every submission stored, synced
|
|
36
|
+
or not, visible in the Content Manager.
|
|
37
|
+
- One-click **import** of legacy content-type forms (`forms.import.uid`,
|
|
38
|
+
attribute names remappable) — all locales, same slug, source untouched.
|
|
39
|
+
- Structural validation of definitions (duplicate names, forward/unknown
|
|
40
|
+
references, incomplete rules) blocking saves; mapping validation flagging
|
|
41
|
+
drafts and blocking publish.
|
|
42
|
+
- `strapi-plugin-hubspot/types` export: typed public payloads for host apps.
|
|
43
|
+
- ESLint (typescript-eslint + react-hooks) and a `lint` CI step.
|
|
44
|
+
|
|
45
|
+
### Config
|
|
46
|
+
- New `forms` block: `companyFromDomain` (default `true`), `timelineNote`
|
|
47
|
+
(default `true`), `import` (off unless configured).
|
|
48
|
+
|
|
49
|
+
## 0.5.0
|
|
50
|
+
|
|
51
|
+
- Shared schema cache across pickers, refresh button, auto-clear of a
|
|
52
|
+
property orphaned by an object switch.
|
|
53
|
+
|
|
54
|
+
## 0.4.0
|
|
55
|
+
|
|
56
|
+
- Sending service (`submit.upsert`) with pre-validation, retries and the
|
|
57
|
+
failed-submissions replay queue; mapping audit; `hubspot.object` custom
|
|
58
|
+
field; enumeration option import; strict/non-strict validate targets;
|
|
59
|
+
admin i18n (en/fr); RBAC-gated settings; CI + npm publish workflows.
|
package/README.md
CHANGED
|
@@ -1,9 +1,115 @@
|
|
|
1
1
|
# Strapi HubSpot
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
**The form builder for HubSpot** — and the safety net under it.
|
|
4
|
+
|
|
5
|
+
Build multi-step lead forms in a dedicated admin page: fields mapped to your
|
|
6
|
+
portal's *real* CRM properties through a searchable picker, conditional fields
|
|
7
|
+
and steps (AND/OR rules re-evaluated server-side), a public API your frontend
|
|
8
|
+
renders and posts to, and a submission pipeline that upserts the Contact,
|
|
9
|
+
finds-or-creates the Company by corporate domain, drops a recap note on the
|
|
10
|
+
timeline, and stores every submission in Strapi whatever the CRM's mood.
|
|
11
|
+
|
|
12
|
+
Under it, the safety net this plugin has always been: property pickers as
|
|
13
|
+
custom fields for your own content types, save-time mapping validation, a
|
|
14
|
+
portal-wide audit, and a sending service with retries and a replay queue.
|
|
15
|
+
|
|
16
|
+
## The form builder
|
|
17
|
+
|
|
18
|
+
**HubSpot Forms**, in the admin menu (RBAC-gated), is a builder page — not a
|
|
19
|
+
Content Manager view. Steps and fields are cards you reorder and configure;
|
|
20
|
+
the right-hand panel holds the selected field's settings, including its CRM
|
|
21
|
+
mapping picked from the portal (object select, property search, one-click
|
|
22
|
+
import of an enumeration's options, deep link to the property).
|
|
23
|
+
|
|
24
|
+
### Conditional fields and steps
|
|
25
|
+
|
|
26
|
+
Any field or step can declare `visibleIf`: rules like *[field] [is] [value]*
|
|
27
|
+
combined with AND/OR. The editor only offers fields placed **earlier** in the
|
|
28
|
+
form, so evaluation is a single deterministic pass. Operators: `eq`, `neq`,
|
|
29
|
+
`contains`, `empty`, `notEmpty`, `gt`, `lt`.
|
|
30
|
+
|
|
31
|
+
Conditions are enforced **server-side at submission**, not just in the UI: a
|
|
32
|
+
hidden field loses its `required`, and its value is discarded even if the
|
|
33
|
+
browser sent it — the payload that reaches HubSpot is the payload the visitor
|
|
34
|
+
actually saw.
|
|
35
|
+
|
|
36
|
+
### The public API
|
|
37
|
+
|
|
38
|
+
Two content-api routes (grant them to the Public role in **Settings → Users &
|
|
39
|
+
Permissions**):
|
|
40
|
+
|
|
41
|
+
| Method | Path | Purpose |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `GET` | `/api/hubspot/forms/:slug?locale=` | The published form — meta, steps, fields, conditions. The CRM mapping is stripped: the browser never learns your property names |
|
|
44
|
+
| `POST` | `/api/hubspot/forms/:slug/submit` | Validates (bounds, conditions, required), maps server-side, syncs HubSpot, stores the submission |
|
|
45
|
+
|
|
46
|
+
The submit pipeline, in order: contact upsert (`email` is the find-or-create
|
|
47
|
+
key) through the plugin's sending service — pre-validation against the portal
|
|
48
|
+
schema (a stale mapping costs one answer, never the lead), retries, replay
|
|
49
|
+
queue; then, when the email is on a corporate domain, company found-or-created
|
|
50
|
+
by `domain` and associated to the contact; then a timeline note recapping the
|
|
51
|
+
answers and the lead's origin. Company and note are best-effort and can be
|
|
52
|
+
turned off:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
hubspot: {
|
|
56
|
+
config: {
|
|
57
|
+
forms: {
|
|
58
|
+
companyFromDomain: true, // Company by corporate domain + association
|
|
59
|
+
timelineNote: true, // recap note on the contact (and company)
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Every submission is stored in **HubSpot form submissions** (Content Manager),
|
|
66
|
+
synced or not, with the CRM ids when the sync succeeded — the source of truth
|
|
67
|
+
lives in your database, not in HubSpot's availability.
|
|
68
|
+
|
|
69
|
+
Typed payloads for your frontend:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import type { PublicForm, SubmitRequest } from "strapi-plugin-hubspot/types";
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Importing existing forms
|
|
76
|
+
|
|
77
|
+
If your forms currently live in a content type (the `steps`/`fields` +
|
|
78
|
+
`hsObject`/`hsProperty` shape this README documents below), point the builder
|
|
79
|
+
at it:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
hubspot: {
|
|
83
|
+
config: {
|
|
84
|
+
forms: {
|
|
85
|
+
import: {
|
|
86
|
+
uid: "api::form.form",
|
|
87
|
+
// Optional remapping when your attribute names differ:
|
|
88
|
+
// steps: "etapes", fields: "champs",
|
|
89
|
+
// field: { label: "libelle", object: "objet", property: "propriete" },
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The list page then offers **Import an existing form**: one click converts the
|
|
97
|
+
entry — every locale — into a builder draft with the same slug. The source is
|
|
98
|
+
never modified, re-importing overwrites the draft only, and unpublishing rolls
|
|
99
|
+
a migrated form back. Migrate form by form; the validation middleware keeps
|
|
100
|
+
protecting the ones that stay.
|
|
101
|
+
|
|
102
|
+
### i18n and publishing
|
|
103
|
+
|
|
104
|
+
Forms are draft & publish, localized like your content: `name` and `slug` are
|
|
105
|
+
shared, everything else — including the structure — is per-locale. Opening a
|
|
106
|
+
locale that doesn't exist yet starts it from the default locale's structure.
|
|
107
|
+
Publishing is blocked while a mapping problem remains; drafts save anyway,
|
|
108
|
+
with the problem flagged on the field carrying it.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## The safety net
|
|
7
113
|
|
|
8
114
|
## The problem it solves
|
|
9
115
|
|