strapi-plugin-hubspot 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +116 -4
  3. package/dist/_chunks/Forms-BF4_zA-m.js +1007 -0
  4. package/dist/_chunks/Forms-CW1KFO9U.mjs +989 -0
  5. package/dist/_chunks/{HubspotObjectInput-DutelVp6.mjs → HubspotObjectInput-CpxeM2J0.mjs} +4 -16
  6. package/dist/_chunks/{HubspotObjectInput-Br2jTFkG.js → HubspotObjectInput-hjAYWtaU.js} +4 -16
  7. package/dist/_chunks/HubspotPropertyInput-C-52Lu24.mjs +227 -0
  8. package/dist/_chunks/HubspotPropertyInput-OSeIBaRC.js +245 -0
  9. package/dist/_chunks/Settings-2V7TH5CX.mjs +321 -0
  10. package/dist/_chunks/Settings-DcA9M5Tw.js +339 -0
  11. package/dist/_chunks/en-CJ9wYHgN.mjs +197 -0
  12. package/dist/_chunks/en-C_-N8cjv.js +197 -0
  13. package/dist/_chunks/fr-BHObPoUp.js +197 -0
  14. package/dist/_chunks/fr-DttDn-2Y.mjs +197 -0
  15. package/dist/_chunks/{Settings-CQsB0B2T.mjs → index-C1UJXE_o.mjs} +576 -317
  16. package/dist/_chunks/{index-BUlB1rK9.js → index-CMzg-x5i.js} +12 -4
  17. package/dist/_chunks/{Settings-CvbKVl-t.js → index-Dgbid2LK.js} +580 -322
  18. package/dist/_chunks/{index-CKoBcX1T.mjs → index-DkGOTp8p.mjs} +12 -4
  19. package/dist/_chunks/{objectLabels-dM4o67Fz.mjs → objectLabels-D9UEuOGr.mjs} +1 -1
  20. package/dist/_chunks/{objectLabels-B76t8qqg.js → objectLabels-Th7aYW-B.js} +1 -1
  21. package/dist/_chunks/useHubspotSchema-Bgrgg8Mt.js +75 -0
  22. package/dist/_chunks/useHubspotSchema-DQkQcA_V.mjs +58 -0
  23. package/dist/admin/index.js +2 -1
  24. package/dist/admin/index.mjs +2 -1
  25. package/dist/admin/src/builder/ConditionEditor.d.ts +17 -0
  26. package/dist/admin/src/builder/FieldPanel.d.ts +16 -0
  27. package/dist/admin/src/builder/types.d.ts +90 -0
  28. package/dist/admin/src/index.d.ts +1 -0
  29. package/dist/admin/src/pages/FormEditor.d.ts +9 -0
  30. package/dist/admin/src/pages/Forms.d.ts +4 -0
  31. package/dist/admin/src/pages/FormsList.d.ts +8 -0
  32. package/dist/admin/src/useHubspotSchema.d.ts +28 -0
  33. package/dist/server/index.js +880 -5
  34. package/dist/server/index.mjs +880 -5
  35. package/dist/server/src/__tests__/conditions.test.d.ts +1 -0
  36. package/dist/server/src/__tests__/forms.test.d.ts +1 -0
  37. package/dist/server/src/__tests__/formsSubmit.test.d.ts +1 -0
  38. package/dist/server/src/__tests__/importLegacy.test.d.ts +1 -0
  39. package/dist/server/src/conditions.d.ts +88 -0
  40. package/dist/server/src/content-types.d.ts +161 -9
  41. package/dist/server/src/forms.d.ts +81 -0
  42. package/dist/server/src/formsAdmin.d.ts +39 -0
  43. package/dist/server/src/importLegacy.d.ts +25 -0
  44. package/dist/server/src/index.d.ts +214 -16
  45. package/dist/shared/types.d.ts +103 -0
  46. package/dist/shared/types.js +2 -0
  47. package/dist/shared/types.mjs +2 -0
  48. package/package.json +23 -6
  49. package/dist/_chunks/HubspotPropertyInput-CK6Yj9rC.mjs +0 -177
  50. package/dist/_chunks/HubspotPropertyInput-DIPDPRXJ.js +0 -195
  51. package/dist/_chunks/en-D4ueeUcJ.mjs +0 -82
  52. package/dist/_chunks/en-PBG7-vMR.js +0 -82
  53. package/dist/_chunks/fr-DL4wdV8I.js +0 -82
  54. package/dist/_chunks/fr-DYnxVmIO.mjs +0 -82
@@ -1,3 +1,4 @@
1
+ import { PaperPlane } from "@strapi/icons";
1
2
  const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
2
3
  const v = glob[path];
3
4
  if (v) {
@@ -19,6 +20,13 @@ const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
19
20
  const prefixPluginTranslations = (trad) => Object.fromEntries(Object.entries(trad).map(([key, value]) => [getTranslation(key), value]));
20
21
  const index = {
21
22
  register(app) {
23
+ app.addMenuLink({
24
+ to: `plugins/${PLUGIN_ID}`,
25
+ icon: PaperPlane,
26
+ intlLabel: { id: `${PLUGIN_ID}.menu.label`, defaultMessage: "HubSpot Forms" },
27
+ permissions: [{ action: `plugin::${PLUGIN_ID}.forms`, subject: null }],
28
+ Component: async () => (await import("./Forms-CW1KFO9U.mjs")).default
29
+ });
22
30
  app.customFields.register({
23
31
  name: "property",
24
32
  pluginId: PLUGIN_ID,
@@ -32,7 +40,7 @@ const index = {
32
40
  defaultMessage: "Picked from the portal's real properties"
33
41
  },
34
42
  components: {
35
- Input: async () => import("./HubspotPropertyInput-CK6Yj9rC.mjs")
43
+ Input: async () => import("./HubspotPropertyInput-C-52Lu24.mjs")
36
44
  },
37
45
  // Exposed in the Content-Type Builder. Without this, `objectField` could
38
46
  // only be set by hand-editing schema.json — which is not how anyone
@@ -95,7 +103,7 @@ const index = {
95
103
  defaultMessage: "Picked from the portal's configured objects"
96
104
  },
97
105
  components: {
98
- Input: async () => import("./HubspotObjectInput-DutelVp6.mjs")
106
+ Input: async () => import("./HubspotObjectInput-CpxeM2J0.mjs")
99
107
  }
100
108
  });
101
109
  app.createSettingSection(
@@ -111,7 +119,7 @@ const index = {
111
119
  // Mirrors the RBAC action registered server-side: a role without it
112
120
  // doesn't see the link at all — the routes refuse it anyway.
113
121
  permissions: [{ action: `plugin::${PLUGIN_ID}.settings`, subject: null }],
114
- Component: async () => (await import("./Settings-CQsB0B2T.mjs")).default
122
+ Component: async () => (await import("./Settings-2V7TH5CX.mjs")).default
115
123
  }
116
124
  ]
117
125
  );
@@ -121,7 +129,7 @@ const index = {
121
129
  return Promise.all(
122
130
  locales.map(async (locale) => {
123
131
  try {
124
- const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-D4ueeUcJ.mjs"), "./translations/fr.json": () => import("./fr-DYnxVmIO.mjs") }), `./translations/${locale}.json`, 3);
132
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-CJ9wYHgN.mjs"), "./translations/fr.json": () => import("./fr-DttDn-2Y.mjs") }), `./translations/${locale}.json`, 3);
125
133
  return { data: prefixPluginTranslations(data), locale };
126
134
  } catch {
127
135
  return { data: {}, locale };
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { g as getTranslation } from "./index-CKoBcX1T.mjs";
2
+ import { g as getTranslation } from "./index-DkGOTp8p.mjs";
3
3
  var __assign = function() {
4
4
  __assign = Object.assign || function __assign2(t) {
5
5
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const React = require("react");
3
- const index = require("./index-BUlB1rK9.js");
3
+ const index = require("./index-CMzg-x5i.js");
4
4
  function _interopNamespace(e) {
5
5
  if (e && e.__esModule) return e;
6
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ const React = require("react");
3
+ const admin = require("@strapi/strapi/admin");
4
+ const index = require("./index-CMzg-x5i.js");
5
+ function _interopNamespace(e) {
6
+ if (e && e.__esModule) return e;
7
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
+ if (e) {
9
+ for (const k in e) {
10
+ if (k !== "default") {
11
+ const d = Object.getOwnPropertyDescriptor(e, k);
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: () => e[k]
15
+ });
16
+ }
17
+ }
18
+ }
19
+ n.default = e;
20
+ return Object.freeze(n);
21
+ }
22
+ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
23
+ let cached = null;
24
+ let inFlight = null;
25
+ const listeners = /* @__PURE__ */ new Set();
26
+ const EMPTY = {
27
+ configured: false,
28
+ properties: [],
29
+ objects: [],
30
+ unavailable: []
31
+ };
32
+ const messageOf = (err) => err?.response?.data?.error?.message;
33
+ function useHubspotSchema() {
34
+ const { get } = admin.useFetchClient();
35
+ const [schema, setSchema] = React__namespace.useState(cached);
36
+ const [loadError, setLoadError] = React__namespace.useState(null);
37
+ const [refreshing, setRefreshing] = React__namespace.useState(false);
38
+ const load = React__namespace.useCallback(
39
+ async (refresh2) => {
40
+ if (!refresh2 && cached) return;
41
+ if (refresh2) setRefreshing(true);
42
+ if (refresh2 || !inFlight) {
43
+ inFlight = get(
44
+ `/${index.PLUGIN_ID}/properties${refresh2 ? "?refresh=1" : ""}`
45
+ ).then(({ data }) => data);
46
+ }
47
+ const request = inFlight;
48
+ try {
49
+ const data = await request;
50
+ cached = data;
51
+ setLoadError(null);
52
+ for (const notify of listeners) notify(data);
53
+ } catch (err) {
54
+ setSchema((current) => current ?? EMPTY);
55
+ setLoadError(messageOf(err) ?? "");
56
+ } finally {
57
+ if (inFlight === request) inFlight = null;
58
+ setRefreshing(false);
59
+ }
60
+ },
61
+ [get]
62
+ );
63
+ React__namespace.useEffect(() => {
64
+ const notify = (data) => setSchema(data);
65
+ listeners.add(notify);
66
+ if (cached) setSchema(cached);
67
+ load(false);
68
+ return () => {
69
+ listeners.delete(notify);
70
+ };
71
+ }, [load]);
72
+ const refresh = React__namespace.useCallback(() => load(true), [load]);
73
+ return { schema, loadError, refresh, refreshing };
74
+ }
75
+ exports.useHubspotSchema = useHubspotSchema;
@@ -0,0 +1,58 @@
1
+ import * as React from "react";
2
+ import { useFetchClient } from "@strapi/strapi/admin";
3
+ import { P as PLUGIN_ID } from "./index-DkGOTp8p.mjs";
4
+ let cached = null;
5
+ let inFlight = null;
6
+ const listeners = /* @__PURE__ */ new Set();
7
+ const EMPTY = {
8
+ configured: false,
9
+ properties: [],
10
+ objects: [],
11
+ unavailable: []
12
+ };
13
+ const messageOf = (err) => err?.response?.data?.error?.message;
14
+ function useHubspotSchema() {
15
+ const { get } = useFetchClient();
16
+ const [schema, setSchema] = React.useState(cached);
17
+ const [loadError, setLoadError] = React.useState(null);
18
+ const [refreshing, setRefreshing] = React.useState(false);
19
+ const load = React.useCallback(
20
+ async (refresh2) => {
21
+ if (!refresh2 && cached) return;
22
+ if (refresh2) setRefreshing(true);
23
+ if (refresh2 || !inFlight) {
24
+ inFlight = get(
25
+ `/${PLUGIN_ID}/properties${refresh2 ? "?refresh=1" : ""}`
26
+ ).then(({ data }) => data);
27
+ }
28
+ const request = inFlight;
29
+ try {
30
+ const data = await request;
31
+ cached = data;
32
+ setLoadError(null);
33
+ for (const notify of listeners) notify(data);
34
+ } catch (err) {
35
+ setSchema((current) => current ?? EMPTY);
36
+ setLoadError(messageOf(err) ?? "");
37
+ } finally {
38
+ if (inFlight === request) inFlight = null;
39
+ setRefreshing(false);
40
+ }
41
+ },
42
+ [get]
43
+ );
44
+ React.useEffect(() => {
45
+ const notify = (data) => setSchema(data);
46
+ listeners.add(notify);
47
+ if (cached) setSchema(cached);
48
+ load(false);
49
+ return () => {
50
+ listeners.delete(notify);
51
+ };
52
+ }, [load]);
53
+ const refresh = React.useCallback(() => load(true), [load]);
54
+ return { schema, loadError, refresh, refreshing };
55
+ }
56
+ export {
57
+ useHubspotSchema as u
58
+ };
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-BUlB1rK9.js");
2
+ const index = require("../_chunks/index-CMzg-x5i.js");
3
+ require("@strapi/icons");
3
4
  module.exports = index.index;
@@ -1,4 +1,5 @@
1
- import { i } from "../_chunks/index-CKoBcX1T.mjs";
1
+ import { i } from "../_chunks/index-DkGOTp8p.mjs";
2
+ import "@strapi/icons";
2
3
  export {
3
4
  i as default
4
5
  };
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+ import type { Condition, FormField } from "./types";
3
+ interface Props {
4
+ /** The condition being edited (null/undefined = always visible). */
5
+ condition: Condition | null | undefined;
6
+ /** Fields a rule may reference — only the ones BEFORE the owner. */
7
+ candidates: FormField[];
8
+ onChange: (condition: Condition | null) => void;
9
+ }
10
+ /**
11
+ * "[earlier field ▾] [operator ▾] [value]" rows joined by AND/OR. Only earlier
12
+ * fields are offered, so the engine's single forward pass always has what a
13
+ * rule reads. The value input becomes a select when the referenced field has
14
+ * declared options.
15
+ */
16
+ declare const ConditionEditor: ({ condition, candidates, onChange }: Props) => React.JSX.Element;
17
+ export default ConditionEditor;
@@ -0,0 +1,16 @@
1
+ import * as React from "react";
2
+ import { type FormField, type MappingProblem } from "./types";
3
+ interface Props {
4
+ field: FormField;
5
+ /** Fields before this one — what its condition may read. */
6
+ candidates: FormField[];
7
+ problem?: MappingProblem;
8
+ onChange: (patch: Partial<FormField>) => void;
9
+ }
10
+ /**
11
+ * Everything about the selected field: identity, behaviour, options, the CRM
12
+ * mapping (object picker + property picker fed by the portal, one-click
13
+ * option import for enumerations) and its visibility condition.
14
+ */
15
+ declare const FieldPanel: ({ field, candidates, problem, onChange }: Props) => React.JSX.Element;
16
+ export default FieldPanel;
@@ -0,0 +1,90 @@
1
+ /** Client-side mirror of the server's definition types (server/src/conditions.ts). */
2
+ export type Operator = "eq" | "neq" | "contains" | "empty" | "notEmpty" | "gt" | "lt";
3
+ export interface Rule {
4
+ field: string;
5
+ operator: Operator;
6
+ value?: string;
7
+ }
8
+ export interface Condition {
9
+ logic: "and" | "or";
10
+ rules: Rule[];
11
+ }
12
+ export type FieldType = "text" | "email" | "tel" | "number" | "website" | "textarea" | "select" | "checkbox" | "radio";
13
+ export declare const FIELD_TYPES: FieldType[];
14
+ export interface FieldOption {
15
+ value: string;
16
+ label?: string;
17
+ }
18
+ export interface FormField {
19
+ id: string;
20
+ name: string;
21
+ label: string;
22
+ type: FieldType;
23
+ placeholder?: string;
24
+ helpText?: string;
25
+ icon?: string;
26
+ class?: string;
27
+ width?: "full" | "half";
28
+ required?: boolean;
29
+ persist?: "session" | "days30";
30
+ options?: FieldOption[];
31
+ hubspot?: {
32
+ object?: string;
33
+ property?: string;
34
+ };
35
+ visibleIf?: Condition | null;
36
+ }
37
+ export interface FormStep {
38
+ id: string;
39
+ title?: string;
40
+ description?: string;
41
+ class?: string;
42
+ visibleIf?: Condition | null;
43
+ fields: FormField[];
44
+ }
45
+ export interface FormDefinition {
46
+ version: 1;
47
+ steps: FormStep[];
48
+ }
49
+ export interface FormEntryDto {
50
+ documentId: string;
51
+ name: string;
52
+ slug: string;
53
+ title?: string | null;
54
+ subtitle?: string | null;
55
+ nextLabel?: string | null;
56
+ submitLabel?: string | null;
57
+ successMessage?: string | null;
58
+ locale?: string | null;
59
+ updatedAt?: string;
60
+ definition: FormDefinition;
61
+ }
62
+ export interface FormListRow {
63
+ documentId: string;
64
+ name: string;
65
+ slug: string;
66
+ updatedAt: string;
67
+ published: boolean;
68
+ steps: number;
69
+ fields: number;
70
+ }
71
+ export interface DefinitionError {
72
+ code: "duplicate-name" | "missing-name" | "unknown-field" | "forward-reference" | "missing-value";
73
+ fieldId?: string;
74
+ stepId?: string;
75
+ name?: string;
76
+ target?: string;
77
+ }
78
+ export interface MappingProblem {
79
+ code: "unknown" | "wrong-object" | "whitespace" | "bad-option";
80
+ fieldId: string;
81
+ property: string;
82
+ object: string;
83
+ actualObject?: string;
84
+ }
85
+ /** Stable, unique-enough ids for steps and fields (never shown to anyone). */
86
+ export declare const makeId: (prefix: "stp" | "fld") => string;
87
+ /** Every field that comes before `beforeId` (a field or step id) in form order. */
88
+ export declare function fieldsBefore(definition: FormDefinition, beforeId: string): FormField[];
89
+ /** Field lookup across steps. */
90
+ export declare function findField(definition: FormDefinition, fieldId: string): FormField | undefined;
@@ -14,6 +14,7 @@ declare const _default: {
14
14
  customFields: {
15
15
  register: (field: unknown) => void;
16
16
  };
17
+ addMenuLink: (link: unknown) => void;
17
18
  createSettingSection: (section: {
18
19
  id: string;
19
20
  intlLabel: {
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ /**
3
+ * The builder: steps and field cards on the left (reordered with the arrows —
4
+ * a field pushed past the edge of its step slides into the neighbour), the
5
+ * properties of the selection on the right, save/publish on top. Structure
6
+ * problems and CRM mapping problems land as badges on the cards they concern.
7
+ */
8
+ declare const FormEditor: () => React.JSX.Element;
9
+ export default FormEditor;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ /** The Forms menu entry: the list at the root, the builder at /:documentId. */
3
+ declare const Forms: () => import("react").JSX.Element;
4
+ export default Forms;
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ /**
3
+ * The forms list: every form built with the plugin, its publication state,
4
+ * and the door to the builder. Creating a form only asks for a name — slug
5
+ * and everything else happen in the editor.
6
+ */
7
+ declare const FormsList: () => React.JSX.Element;
8
+ export default FormsList;
@@ -0,0 +1,28 @@
1
+ export interface HsProperty {
2
+ name: string;
3
+ label: string;
4
+ object: string;
5
+ type?: string;
6
+ options: {
7
+ value: string;
8
+ label?: string;
9
+ }[];
10
+ group?: string;
11
+ }
12
+ export interface SchemaResponse {
13
+ configured: boolean;
14
+ properties: HsProperty[];
15
+ objects: string[];
16
+ unavailable: {
17
+ object: string;
18
+ reason: string;
19
+ }[];
20
+ portalId?: number;
21
+ uiDomain?: string;
22
+ }
23
+ export declare function useHubspotSchema(): {
24
+ schema: SchemaResponse | null;
25
+ loadError: string | null;
26
+ refresh: () => Promise<void>;
27
+ refreshing: boolean;
28
+ };