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,11 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
2
  const React = require("react");
5
- const objectLabels = require("./objectLabels-B76t8qqg.js");
6
- const designSystem = require("@strapi/design-system");
7
- const admin = require("@strapi/strapi/admin");
8
- const index = require("./index-BUlB1rK9.js");
9
3
  require("react-dom");
10
4
  function _interopNamespace(e) {
11
5
  if (e && e.__esModule) return e;
@@ -100,6 +94,166 @@ var ResultType;
100
94
  ResultType2["redirect"] = "redirect";
101
95
  ResultType2["error"] = "error";
102
96
  })(ResultType || (ResultType = {}));
97
+ function matchRoutes(routes, locationArg, basename) {
98
+ if (basename === void 0) {
99
+ basename = "/";
100
+ }
101
+ return matchRoutesImpl(routes, locationArg, basename);
102
+ }
103
+ function matchRoutesImpl(routes, locationArg, basename, allowPartial) {
104
+ let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
105
+ let pathname = stripBasename(location.pathname || "/", basename);
106
+ if (pathname == null) {
107
+ return null;
108
+ }
109
+ let branches = flattenRoutes(routes);
110
+ rankRouteBranches(branches);
111
+ let matches = null;
112
+ let decoded = decodePath(pathname);
113
+ for (let i = 0; matches == null && i < branches.length; ++i) {
114
+ matches = matchRouteBranch(branches[i], decoded);
115
+ }
116
+ return matches;
117
+ }
118
+ function flattenRoutes(routes, branches, parentsMeta, parentPath) {
119
+ if (branches === void 0) {
120
+ branches = [];
121
+ }
122
+ if (parentsMeta === void 0) {
123
+ parentsMeta = [];
124
+ }
125
+ if (parentPath === void 0) {
126
+ parentPath = "";
127
+ }
128
+ let flattenRoute = (route, index, relativePath) => {
129
+ let meta = {
130
+ relativePath: relativePath === void 0 ? route.path || "" : relativePath,
131
+ caseSensitive: route.caseSensitive === true,
132
+ childrenIndex: index,
133
+ route
134
+ };
135
+ if (meta.relativePath.startsWith("/")) {
136
+ invariant(meta.relativePath.startsWith(parentPath), 'Absolute route path "' + meta.relativePath + '" nested under path ' + ('"' + parentPath + '" is not valid. An absolute child route path ') + "must start with the combined path of all its parent routes.");
137
+ meta.relativePath = meta.relativePath.slice(parentPath.length);
138
+ }
139
+ let path = joinPaths([parentPath, meta.relativePath]);
140
+ let routesMeta = parentsMeta.concat(meta);
141
+ if (route.children && route.children.length > 0) {
142
+ invariant(
143
+ // Our types know better, but runtime JS may not!
144
+ // @ts-expect-error
145
+ route.index !== true,
146
+ "Index routes must not have child routes. Please remove " + ('all child routes from route path "' + path + '".')
147
+ );
148
+ flattenRoutes(route.children, branches, routesMeta, path);
149
+ }
150
+ if (route.path == null && !route.index) {
151
+ return;
152
+ }
153
+ branches.push({
154
+ path,
155
+ score: computeScore(path, route.index),
156
+ routesMeta
157
+ });
158
+ };
159
+ routes.forEach((route, index) => {
160
+ var _route$path;
161
+ if (route.path === "" || !((_route$path = route.path) != null && _route$path.includes("?"))) {
162
+ flattenRoute(route, index);
163
+ } else {
164
+ for (let exploded of explodeOptionalSegments(route.path)) {
165
+ flattenRoute(route, index, exploded);
166
+ }
167
+ }
168
+ });
169
+ return branches;
170
+ }
171
+ function explodeOptionalSegments(path) {
172
+ let segments = path.split("/");
173
+ if (segments.length === 0) return [];
174
+ let [first, ...rest] = segments;
175
+ let isOptional = first.endsWith("?");
176
+ let required = first.replace(/\?$/, "");
177
+ if (rest.length === 0) {
178
+ return isOptional ? [required, ""] : [required];
179
+ }
180
+ let restExploded = explodeOptionalSegments(rest.join("/"));
181
+ let result = [];
182
+ result.push(...restExploded.map((subpath) => subpath === "" ? required : [required, subpath].join("/")));
183
+ if (isOptional) {
184
+ result.push(...restExploded);
185
+ }
186
+ return result.map((exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded);
187
+ }
188
+ function rankRouteBranches(branches) {
189
+ branches.sort((a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(a.routesMeta.map((meta) => meta.childrenIndex), b.routesMeta.map((meta) => meta.childrenIndex)));
190
+ }
191
+ const paramRe = /^:[\w-]+$/;
192
+ const dynamicSegmentValue = 3;
193
+ const indexRouteValue = 2;
194
+ const emptySegmentValue = 1;
195
+ const staticSegmentValue = 10;
196
+ const splatPenalty = -2;
197
+ const isSplat = (s) => s === "*";
198
+ function computeScore(path, index) {
199
+ let segments = path.split("/");
200
+ let initialScore = segments.length;
201
+ if (segments.some(isSplat)) {
202
+ initialScore += splatPenalty;
203
+ }
204
+ if (index) {
205
+ initialScore += indexRouteValue;
206
+ }
207
+ return segments.filter((s) => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
208
+ }
209
+ function compareIndexes(a, b) {
210
+ let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
211
+ return siblings ? (
212
+ // If two routes are siblings, we should try to match the earlier sibling
213
+ // first. This allows people to have fine-grained control over the matching
214
+ // behavior by simply putting routes with identical paths in the order they
215
+ // want them tried.
216
+ a[a.length - 1] - b[b.length - 1]
217
+ ) : (
218
+ // Otherwise, it doesn't really make sense to rank non-siblings by index,
219
+ // so they sort equally.
220
+ 0
221
+ );
222
+ }
223
+ function matchRouteBranch(branch, pathname, allowPartial) {
224
+ let {
225
+ routesMeta
226
+ } = branch;
227
+ let matchedParams = {};
228
+ let matchedPathname = "/";
229
+ let matches = [];
230
+ for (let i = 0; i < routesMeta.length; ++i) {
231
+ let meta = routesMeta[i];
232
+ let end = i === routesMeta.length - 1;
233
+ let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
234
+ let match = matchPath({
235
+ path: meta.relativePath,
236
+ caseSensitive: meta.caseSensitive,
237
+ end
238
+ }, remainingPathname);
239
+ let route = meta.route;
240
+ if (!match) {
241
+ return null;
242
+ }
243
+ Object.assign(matchedParams, match.params);
244
+ matches.push({
245
+ // TODO: Can this as be avoided?
246
+ params: matchedParams,
247
+ pathname: joinPaths([matchedPathname, match.pathname]),
248
+ pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])),
249
+ route
250
+ });
251
+ if (match.pathnameBase !== "/") {
252
+ matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
253
+ }
254
+ }
255
+ return matches;
256
+ }
103
257
  function matchPath(pattern, pathname) {
104
258
  if (typeof pattern === "string") {
105
259
  pattern = {
@@ -114,16 +268,16 @@ function matchPath(pattern, pathname) {
114
268
  let matchedPathname = match[0];
115
269
  let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
116
270
  let captureGroups = match.slice(1);
117
- let params = compiledParams.reduce((memo, _ref, index2) => {
271
+ let params = compiledParams.reduce((memo, _ref, index) => {
118
272
  let {
119
273
  paramName,
120
274
  isOptional
121
275
  } = _ref;
122
276
  if (paramName === "*") {
123
- let splatValue = captureGroups[index2] || "";
277
+ let splatValue = captureGroups[index] || "";
124
278
  pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
125
279
  }
126
- const value = captureGroups[index2];
280
+ const value = captureGroups[index];
127
281
  if (isOptional && !value) {
128
282
  memo[paramName] = void 0;
129
283
  } else {
@@ -167,6 +321,14 @@ function compilePath(path, caseSensitive, end) {
167
321
  let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
168
322
  return [matcher, params];
169
323
  }
324
+ function decodePath(value) {
325
+ try {
326
+ return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
327
+ } catch (error) {
328
+ warning(false, 'The URL path "' + value + '" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent ' + ("encoding (" + error + ")."));
329
+ return value;
330
+ }
331
+ }
170
332
  function stripBasename(pathname, basename) {
171
333
  if (basename === "/") return pathname;
172
334
  if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
@@ -231,7 +393,7 @@ function getInvalidPathError(char, field, dest, path) {
231
393
  return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + 'a string in <Link to="..."> and the router will parse it for you.';
232
394
  }
233
395
  function getPathContributingMatches(matches) {
234
- return matches.filter((match, index2) => index2 === 0 || match.route.path && match.route.path.length > 0);
396
+ return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);
235
397
  }
236
398
  function getResolveToMatches(matches, v7_relativeSplatPath) {
237
399
  let pathMatches = getPathContributingMatches(matches);
@@ -280,8 +442,12 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
280
442
  }
281
443
  const removeDoubleSlashes = (path) => path.replace(/\/\/+/g, "/");
282
444
  const joinPaths = (paths) => removeDoubleSlashes(paths.join("/"));
445
+ const normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
283
446
  const normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
284
447
  const normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
448
+ function isRouteErrorResponse(error) {
449
+ return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
450
+ }
285
451
  const validMutationMethodsArr = ["post", "put", "patch", "delete"];
286
452
  new Set(validMutationMethodsArr);
287
453
  const validRequestMethodsArr = ["get", ...validMutationMethodsArr];
@@ -435,6 +601,13 @@ function useNavigateUnstable() {
435
601
  }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);
436
602
  return navigate;
437
603
  }
604
+ function useParams() {
605
+ let {
606
+ matches
607
+ } = React__namespace.useContext(RouteContext);
608
+ let routeMatch = matches[matches.length - 1];
609
+ return routeMatch ? routeMatch.params : {};
610
+ }
438
611
  function useResolvedPath(to, _temp2) {
439
612
  let {
440
613
  relative
@@ -451,6 +624,285 @@ function useResolvedPath(to, _temp2) {
451
624
  let routePathnamesJson = JSON.stringify(getResolveToMatches(matches, future.v7_relativeSplatPath));
452
625
  return React__namespace.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
453
626
  }
627
+ function useRoutes(routes, locationArg) {
628
+ return useRoutesImpl(routes, locationArg);
629
+ }
630
+ function useRoutesImpl(routes, locationArg, dataRouterState, future) {
631
+ !useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(
632
+ false,
633
+ // TODO: This error is probably because they somehow have 2 versions of the
634
+ // router loaded. We can help them understand how to avoid that.
635
+ "useRoutes() may be used only in the context of a <Router> component."
636
+ ) : invariant(false) : void 0;
637
+ let {
638
+ navigator
639
+ } = React__namespace.useContext(NavigationContext);
640
+ let {
641
+ matches: parentMatches
642
+ } = React__namespace.useContext(RouteContext);
643
+ let routeMatch = parentMatches[parentMatches.length - 1];
644
+ let parentParams = routeMatch ? routeMatch.params : {};
645
+ let parentPathname = routeMatch ? routeMatch.pathname : "/";
646
+ let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
647
+ let parentRoute = routeMatch && routeMatch.route;
648
+ if (process.env.NODE_ENV !== "production") {
649
+ let parentPath = parentRoute && parentRoute.path || "";
650
+ warningOnce(parentPathname, !parentRoute || parentPath.endsWith("*"), "You rendered descendant <Routes> (or called `useRoutes()`) at " + ('"' + parentPathname + '" (under <Route path="' + parentPath + '">) but the ') + `parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
651
+
652
+ ` + ('Please change the parent <Route path="' + parentPath + '"> to <Route ') + ('path="' + (parentPath === "/" ? "*" : parentPath + "/*") + '">.'));
653
+ }
654
+ let locationFromContext = useLocation();
655
+ let location;
656
+ if (locationArg) {
657
+ var _parsedLocationArg$pa;
658
+ let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
659
+ !(parentPathnameBase === "/" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? process.env.NODE_ENV !== "production" ? invariant(false, "When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, the location pathname must begin with the portion of the URL pathname that was " + ('matched by all parent routes. The current pathname base is "' + parentPathnameBase + '" ') + ('but pathname "' + parsedLocationArg.pathname + '" was given in the `location` prop.')) : invariant(false) : void 0;
660
+ location = parsedLocationArg;
661
+ } else {
662
+ location = locationFromContext;
663
+ }
664
+ let pathname = location.pathname || "/";
665
+ let remainingPathname = pathname;
666
+ if (parentPathnameBase !== "/") {
667
+ let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
668
+ let segments = pathname.replace(/^\//, "").split("/");
669
+ remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
670
+ }
671
+ let matches = matchRoutes(routes, {
672
+ pathname: remainingPathname
673
+ });
674
+ if (process.env.NODE_ENV !== "production") {
675
+ process.env.NODE_ENV !== "production" ? warning(parentRoute || matches != null, 'No routes matched location "' + location.pathname + location.search + location.hash + '" ') : void 0;
676
+ process.env.NODE_ENV !== "production" ? warning(matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0, 'Matched leaf route at location "' + location.pathname + location.search + location.hash + '" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.') : void 0;
677
+ }
678
+ let renderedMatches = _renderMatches(matches && matches.map((match) => Object.assign({}, match, {
679
+ params: Object.assign({}, parentParams, match.params),
680
+ pathname: joinPaths([
681
+ parentPathnameBase,
682
+ // Re-encode pathnames that were decoded inside matchRoutes
683
+ navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname
684
+ ]),
685
+ pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([
686
+ parentPathnameBase,
687
+ // Re-encode pathnames that were decoded inside matchRoutes
688
+ navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase
689
+ ])
690
+ })), parentMatches, dataRouterState, future);
691
+ if (locationArg && renderedMatches) {
692
+ return /* @__PURE__ */ React__namespace.createElement(LocationContext.Provider, {
693
+ value: {
694
+ location: _extends$1({
695
+ pathname: "/",
696
+ search: "",
697
+ hash: "",
698
+ state: null,
699
+ key: "default"
700
+ }, location),
701
+ navigationType: Action.Pop
702
+ }
703
+ }, renderedMatches);
704
+ }
705
+ return renderedMatches;
706
+ }
707
+ function DefaultErrorComponent() {
708
+ let error = useRouteError();
709
+ let message = isRouteErrorResponse(error) ? error.status + " " + error.statusText : error instanceof Error ? error.message : JSON.stringify(error);
710
+ let stack = error instanceof Error ? error.stack : null;
711
+ let lightgrey = "rgba(200,200,200, 0.5)";
712
+ let preStyles = {
713
+ padding: "0.5rem",
714
+ backgroundColor: lightgrey
715
+ };
716
+ let codeStyles = {
717
+ padding: "2px 4px",
718
+ backgroundColor: lightgrey
719
+ };
720
+ let devInfo = null;
721
+ if (process.env.NODE_ENV !== "production") {
722
+ console.error("Error handled by React Router default ErrorBoundary:", error);
723
+ devInfo = /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement("p", null, "💿 Hey developer 👋"), /* @__PURE__ */ React__namespace.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", /* @__PURE__ */ React__namespace.createElement("code", {
724
+ style: codeStyles
725
+ }, "ErrorBoundary"), " or", " ", /* @__PURE__ */ React__namespace.createElement("code", {
726
+ style: codeStyles
727
+ }, "errorElement"), " prop on your route."));
728
+ }
729
+ return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement("h2", null, "Unexpected Application Error!"), /* @__PURE__ */ React__namespace.createElement("h3", {
730
+ style: {
731
+ fontStyle: "italic"
732
+ }
733
+ }, message), stack ? /* @__PURE__ */ React__namespace.createElement("pre", {
734
+ style: preStyles
735
+ }, stack) : null, devInfo);
736
+ }
737
+ const defaultErrorElement = /* @__PURE__ */ React__namespace.createElement(DefaultErrorComponent, null);
738
+ class RenderErrorBoundary extends React__namespace.Component {
739
+ constructor(props) {
740
+ super(props);
741
+ this.state = {
742
+ location: props.location,
743
+ revalidation: props.revalidation,
744
+ error: props.error
745
+ };
746
+ }
747
+ static getDerivedStateFromError(error) {
748
+ return {
749
+ error
750
+ };
751
+ }
752
+ static getDerivedStateFromProps(props, state) {
753
+ if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") {
754
+ return {
755
+ error: props.error,
756
+ location: props.location,
757
+ revalidation: props.revalidation
758
+ };
759
+ }
760
+ return {
761
+ error: props.error !== void 0 ? props.error : state.error,
762
+ location: state.location,
763
+ revalidation: props.revalidation || state.revalidation
764
+ };
765
+ }
766
+ componentDidCatch(error, errorInfo) {
767
+ console.error("React Router caught the following error during render", error, errorInfo);
768
+ }
769
+ render() {
770
+ return this.state.error !== void 0 ? /* @__PURE__ */ React__namespace.createElement(RouteContext.Provider, {
771
+ value: this.props.routeContext
772
+ }, /* @__PURE__ */ React__namespace.createElement(RouteErrorContext.Provider, {
773
+ value: this.state.error,
774
+ children: this.props.component
775
+ })) : this.props.children;
776
+ }
777
+ }
778
+ function RenderedRoute(_ref) {
779
+ let {
780
+ routeContext,
781
+ match,
782
+ children
783
+ } = _ref;
784
+ let dataRouterContext = React__namespace.useContext(DataRouterContext);
785
+ if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
786
+ dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
787
+ }
788
+ return /* @__PURE__ */ React__namespace.createElement(RouteContext.Provider, {
789
+ value: routeContext
790
+ }, children);
791
+ }
792
+ function _renderMatches(matches, parentMatches, dataRouterState, future) {
793
+ var _dataRouterState;
794
+ if (parentMatches === void 0) {
795
+ parentMatches = [];
796
+ }
797
+ if (dataRouterState === void 0) {
798
+ dataRouterState = null;
799
+ }
800
+ if (future === void 0) {
801
+ future = null;
802
+ }
803
+ if (matches == null) {
804
+ var _future;
805
+ if (!dataRouterState) {
806
+ return null;
807
+ }
808
+ if (dataRouterState.errors) {
809
+ matches = dataRouterState.matches;
810
+ } else if ((_future = future) != null && _future.v7_partialHydration && parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {
811
+ matches = dataRouterState.matches;
812
+ } else {
813
+ return null;
814
+ }
815
+ }
816
+ let renderedMatches = matches;
817
+ let errors = (_dataRouterState = dataRouterState) == null ? void 0 : _dataRouterState.errors;
818
+ if (errors != null) {
819
+ let errorIndex = renderedMatches.findIndex((m) => m.route.id && (errors == null ? void 0 : errors[m.route.id]) !== void 0);
820
+ !(errorIndex >= 0) ? process.env.NODE_ENV !== "production" ? invariant(false, "Could not find a matching route for errors on route IDs: " + Object.keys(errors).join(",")) : invariant(false) : void 0;
821
+ renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
822
+ }
823
+ let renderFallback = false;
824
+ let fallbackIndex = -1;
825
+ if (dataRouterState && future && future.v7_partialHydration) {
826
+ for (let i = 0; i < renderedMatches.length; i++) {
827
+ let match = renderedMatches[i];
828
+ if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {
829
+ fallbackIndex = i;
830
+ }
831
+ if (match.route.id) {
832
+ let {
833
+ loaderData,
834
+ errors: errors2
835
+ } = dataRouterState;
836
+ let needsToRunLoader = match.route.loader && loaderData[match.route.id] === void 0 && (!errors2 || errors2[match.route.id] === void 0);
837
+ if (match.route.lazy || needsToRunLoader) {
838
+ renderFallback = true;
839
+ if (fallbackIndex >= 0) {
840
+ renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
841
+ } else {
842
+ renderedMatches = [renderedMatches[0]];
843
+ }
844
+ break;
845
+ }
846
+ }
847
+ }
848
+ }
849
+ return renderedMatches.reduceRight((outlet, match, index) => {
850
+ let error;
851
+ let shouldRenderHydrateFallback = false;
852
+ let errorElement = null;
853
+ let hydrateFallbackElement = null;
854
+ if (dataRouterState) {
855
+ error = errors && match.route.id ? errors[match.route.id] : void 0;
856
+ errorElement = match.route.errorElement || defaultErrorElement;
857
+ if (renderFallback) {
858
+ if (fallbackIndex < 0 && index === 0) {
859
+ warningOnce("route-fallback", false, "No `HydrateFallback` element provided to render during initial hydration");
860
+ shouldRenderHydrateFallback = true;
861
+ hydrateFallbackElement = null;
862
+ } else if (fallbackIndex === index) {
863
+ shouldRenderHydrateFallback = true;
864
+ hydrateFallbackElement = match.route.hydrateFallbackElement || null;
865
+ }
866
+ }
867
+ }
868
+ let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1));
869
+ let getChildren = () => {
870
+ let children;
871
+ if (error) {
872
+ children = errorElement;
873
+ } else if (shouldRenderHydrateFallback) {
874
+ children = hydrateFallbackElement;
875
+ } else if (match.route.Component) {
876
+ children = /* @__PURE__ */ React__namespace.createElement(match.route.Component, null);
877
+ } else if (match.route.element) {
878
+ children = match.route.element;
879
+ } else {
880
+ children = outlet;
881
+ }
882
+ return /* @__PURE__ */ React__namespace.createElement(RenderedRoute, {
883
+ match,
884
+ routeContext: {
885
+ outlet,
886
+ matches: matches2,
887
+ isDataRoute: dataRouterState != null
888
+ },
889
+ children
890
+ });
891
+ };
892
+ return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /* @__PURE__ */ React__namespace.createElement(RenderErrorBoundary, {
893
+ location: dataRouterState.location,
894
+ revalidation: dataRouterState.revalidation,
895
+ component: errorElement,
896
+ error,
897
+ children: getChildren(),
898
+ routeContext: {
899
+ outlet: null,
900
+ matches: matches2,
901
+ isDataRoute: true
902
+ }
903
+ }) : getChildren();
904
+ }, null);
905
+ }
454
906
  var DataRouterHook$1 = /* @__PURE__ */ function(DataRouterHook2) {
455
907
  DataRouterHook2["UseBlocker"] = "useBlocker";
456
908
  DataRouterHook2["UseRevalidator"] = "useRevalidator";
@@ -478,6 +930,11 @@ function useDataRouterContext$1(hookName) {
478
930
  !ctx ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
479
931
  return ctx;
480
932
  }
933
+ function useDataRouterState(hookName) {
934
+ let state = React__namespace.useContext(DataRouterStateContext);
935
+ !state ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
936
+ return state;
937
+ }
481
938
  function useRouteContext(hookName) {
482
939
  let route = React__namespace.useContext(RouteContext);
483
940
  !route ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
@@ -492,6 +949,16 @@ function useCurrentRouteId(hookName) {
492
949
  function useRouteId() {
493
950
  return useCurrentRouteId(DataRouterStateHook$1.UseRouteId);
494
951
  }
952
+ function useRouteError() {
953
+ var _state$errors;
954
+ let error = React__namespace.useContext(RouteErrorContext);
955
+ let state = useDataRouterState(DataRouterStateHook$1.UseRouteError);
956
+ let routeId = useCurrentRouteId(DataRouterStateHook$1.UseRouteError);
957
+ if (error !== void 0) {
958
+ return error;
959
+ }
960
+ return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];
961
+ }
495
962
  function useNavigateStable() {
496
963
  let {
497
964
  router
@@ -517,8 +984,64 @@ function useNavigateStable() {
517
984
  }, [router, id]);
518
985
  return navigate;
519
986
  }
987
+ const alreadyWarned$1 = {};
988
+ function warningOnce(key, cond, message) {
989
+ if (!cond && !alreadyWarned$1[key]) {
990
+ alreadyWarned$1[key] = true;
991
+ process.env.NODE_ENV !== "production" ? warning(false, message) : void 0;
992
+ }
993
+ }
994
+ function Route(_props) {
995
+ process.env.NODE_ENV !== "production" ? invariant(false, "A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.") : invariant(false);
996
+ }
997
+ function Routes(_ref6) {
998
+ let {
999
+ children,
1000
+ location
1001
+ } = _ref6;
1002
+ return useRoutes(createRoutesFromChildren(children), location);
1003
+ }
520
1004
  new Promise(() => {
521
1005
  });
1006
+ function createRoutesFromChildren(children, parentPath) {
1007
+ if (parentPath === void 0) {
1008
+ parentPath = [];
1009
+ }
1010
+ let routes = [];
1011
+ React__namespace.Children.forEach(children, (element, index) => {
1012
+ if (!/* @__PURE__ */ React__namespace.isValidElement(element)) {
1013
+ return;
1014
+ }
1015
+ let treePath = [...parentPath, index];
1016
+ if (element.type === React__namespace.Fragment) {
1017
+ routes.push.apply(routes, createRoutesFromChildren(element.props.children, treePath));
1018
+ return;
1019
+ }
1020
+ !(element.type === Route) ? process.env.NODE_ENV !== "production" ? invariant(false, "[" + (typeof element.type === "string" ? element.type : element.type.name) + "] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>") : invariant(false) : void 0;
1021
+ !(!element.props.index || !element.props.children) ? process.env.NODE_ENV !== "production" ? invariant(false, "An index route cannot have child routes.") : invariant(false) : void 0;
1022
+ let route = {
1023
+ id: element.props.id || treePath.join("-"),
1024
+ caseSensitive: element.props.caseSensitive,
1025
+ element: element.props.element,
1026
+ Component: element.props.Component,
1027
+ index: element.props.index,
1028
+ path: element.props.path,
1029
+ loader: element.props.loader,
1030
+ action: element.props.action,
1031
+ errorElement: element.props.errorElement,
1032
+ ErrorBoundary: element.props.ErrorBoundary,
1033
+ hasErrorBoundary: element.props.ErrorBoundary != null || element.props.errorElement != null,
1034
+ shouldRevalidate: element.props.shouldRevalidate,
1035
+ handle: element.props.handle,
1036
+ lazy: element.props.lazy
1037
+ };
1038
+ if (element.props.children) {
1039
+ route.children = createRoutesFromChildren(element.props.children, treePath);
1040
+ }
1041
+ routes.push(route);
1042
+ });
1043
+ return routes;
1044
+ }
522
1045
  /**
523
1046
  * React Router DOM v6.30.4
524
1047
  *
@@ -569,6 +1092,28 @@ function shouldProcessLinkClick(event, target) {
569
1092
  (!target || target === "_self") && // Let browser handle "target=_blank" etc.
570
1093
  !isModifiedEvent(event);
571
1094
  }
1095
+ function createSearchParams(init) {
1096
+ if (init === void 0) {
1097
+ init = "";
1098
+ }
1099
+ return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
1100
+ let value = init[key];
1101
+ return memo.concat(Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]);
1102
+ }, []));
1103
+ }
1104
+ function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
1105
+ let searchParams = createSearchParams(locationSearch);
1106
+ if (defaultSearchParams) {
1107
+ defaultSearchParams.forEach((_, key) => {
1108
+ if (!searchParams.has(key)) {
1109
+ defaultSearchParams.getAll(key).forEach((value) => {
1110
+ searchParams.append(key, value);
1111
+ });
1112
+ }
1113
+ });
1114
+ }
1115
+ return searchParams;
1116
+ }
572
1117
  let _formDataSupportsSubmitter = null;
573
1118
  function isFormDataSubmitterSupported() {
574
1119
  if (_formDataSupportsSubmitter === null) {
@@ -891,6 +1436,25 @@ function useLinkClickHandler(to, _temp) {
891
1436
  }
892
1437
  }, [location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, viewTransition]);
893
1438
  }
1439
+ function useSearchParams(defaultInit) {
1440
+ process.env.NODE_ENV !== "production" ? warning(typeof URLSearchParams !== "undefined", "You cannot use the `useSearchParams` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.") : void 0;
1441
+ let defaultSearchParamsRef = React__namespace.useRef(createSearchParams(defaultInit));
1442
+ let hasSetSearchParamsRef = React__namespace.useRef(false);
1443
+ let location = useLocation();
1444
+ let searchParams = React__namespace.useMemo(() => (
1445
+ // Only merge in the defaults if we haven't yet called setSearchParams.
1446
+ // Once we call that we want those to take precedence, otherwise you can't
1447
+ // remove a param with setSearchParams({}) if it has an initial value
1448
+ getSearchParamsForLocation(location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current)
1449
+ ), [location.search]);
1450
+ let navigate = useNavigate();
1451
+ let setSearchParams = React__namespace.useCallback((nextInit, navigateOptions) => {
1452
+ const newSearchParams = createSearchParams(typeof nextInit === "function" ? nextInit(searchParams) : nextInit);
1453
+ hasSetSearchParamsRef.current = true;
1454
+ navigate("?" + newSearchParams, navigateOptions);
1455
+ }, [navigate, searchParams]);
1456
+ return [searchParams, setSearchParams];
1457
+ }
894
1458
  function validateClientSideSubmission() {
895
1459
  if (typeof document === "undefined") {
896
1460
  throw new Error("You are calling submit during the server render. Try calling submit within a `useEffect` or callback instead.");
@@ -997,315 +1561,9 @@ function useViewTransitionState(to, opts) {
997
1561
  let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
998
1562
  return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
999
1563
  }
1000
- const AuditSection = ({ configured }) => {
1001
- const intl = objectLabels.useIntl();
1002
- const { formatMessage } = intl;
1003
- const { get } = admin.useFetchClient();
1004
- const [busy, setBusy] = React__namespace.useState(false);
1005
- const [error, setError] = React__namespace.useState(false);
1006
- const [result, setResult] = React__namespace.useState(null);
1007
- const t = (id, defaultMessage, values) => formatMessage({ id: index.getTranslation(id), defaultMessage }, values);
1008
- const problemText = (p) => {
1009
- switch (p.code) {
1010
- case "unknown":
1011
- return t("problem.unknown", "“{property}” does not exist on {object} in this portal", {
1012
- property: p.property,
1013
- object: objectLabels.objectLabel(intl, p.object)
1014
- });
1015
- case "wrong-object":
1016
- return t("problem.wrong-object", "“{property}” exists on {actual}, not on {object}", {
1017
- property: p.property,
1018
- object: objectLabels.objectLabel(intl, p.object),
1019
- actual: objectLabels.objectLabel(intl, p.actualObject)
1020
- });
1021
- case "whitespace":
1022
- return t("problem.whitespace", "“{property}” has surrounding whitespace", {
1023
- property: p.property
1024
- });
1025
- case "bad-option":
1026
- return t("problem.bad-option", "“{property}” does not accept {values}", {
1027
- property: p.property,
1028
- values: p.values.join(", ")
1029
- });
1030
- }
1031
- };
1032
- const run = async () => {
1033
- setBusy(true);
1034
- setError(false);
1035
- setResult(null);
1036
- try {
1037
- const { data } = await get(`/${index.PLUGIN_ID}/audit`);
1038
- setResult(data);
1039
- } catch {
1040
- setError(true);
1041
- } finally {
1042
- setBusy(false);
1043
- }
1044
- };
1045
- const entryLink = (uid, entry) => `/content-manager/collection-types/${uid}/${entry.documentId}` + (entry.locale ? `?plugins[i18n][locale]=${entry.locale}` : "");
1046
- const totalInvalid = result?.targets.reduce((n, r) => n + r.invalid.length, 0) ?? 0;
1047
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
1048
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
1049
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
1050
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: t("audit.title", "Mapping audit") }),
1051
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: t(
1052
- "audit.subtitle",
1053
- "Scans every entry of the validated content types and lists the mappings the portal would reject today — including properties deleted in HubSpot since they were saved."
1054
- ) })
1055
- ] }),
1056
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: run, loading: busy, disabled: !configured, children: t("audit.run", "Run the audit") }) }),
1057
- error ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "danger600", children: t("audit.error", "Audit failed — HubSpot unreachable?") }) : null,
1058
- result && !result.targets.length ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
1059
- "audit.no-targets",
1060
- "No content type to audit — declare them under `validate` in the plugin config."
1061
- ) }) : null,
1062
- result && result.targets.length ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
1063
- totalInvalid === 0 && result.targets.every((r) => !r.error) ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "success600", children: t("audit.clean", "Nothing to report — every mapping is valid.") }) : null,
1064
- result.targets.map((report) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
1065
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", paddingBottom: 2, children: [
1066
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: report.uid }),
1067
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t("audit.summary", "{entries} entries · {mappings} mappings", {
1068
- entries: report.entries,
1069
- mappings: report.mappings
1070
- }) })
1071
- ] }),
1072
- report.error ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "danger600", children: t("audit.target-error", "Could not scan: {error}", { error: report.error }) }) : null,
1073
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: report.invalid.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
1074
- designSystem.Box,
1075
- {
1076
- padding: 3,
1077
- background: "neutral100",
1078
- hasRadius: true,
1079
- children: [
1080
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1081
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { tag: Link, to: entryLink(report.uid, entry), children: entry.label }),
1082
- entry.locale ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: entry.locale }) : null
1083
- ] }),
1084
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 1, children: entry.problems.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "danger600", tag: "p", children: problemText(p) }, i)) })
1085
- ]
1086
- },
1087
- `${entry.documentId}-${entry.locale ?? ""}`
1088
- )) })
1089
- ] }, report.uid))
1090
- ] }) : null
1091
- ] });
1092
- };
1093
- const FailuresSection = ({ configured }) => {
1094
- const { formatMessage } = objectLabels.useIntl();
1095
- const { get, post } = admin.useFetchClient();
1096
- const [total, setTotal] = React__namespace.useState(null);
1097
- const [busy, setBusy] = React__namespace.useState(false);
1098
- const [feedback, setFeedback] = React__namespace.useState(
1099
- null
1100
- );
1101
- const t = (id, defaultMessage, values) => formatMessage({ id: index.getTranslation(id), defaultMessage }, values);
1102
- const load = React__namespace.useCallback(async () => {
1103
- try {
1104
- const { data } = await get(`/${index.PLUGIN_ID}/failures`);
1105
- setTotal(data.total);
1106
- } catch {
1107
- setTotal(null);
1108
- }
1109
- }, [get]);
1110
- React__namespace.useEffect(() => {
1111
- load();
1112
- }, [load]);
1113
- const retry = async () => {
1114
- setBusy(true);
1115
- setFeedback(null);
1116
- try {
1117
- const { data } = await post(
1118
- `/${index.PLUGIN_ID}/failures/retry`
1119
- );
1120
- setFeedback({
1121
- tone: data.failed ? "danger" : "success",
1122
- text: t("failures.retried", "{succeeded} replayed, {failed} still failing.", {
1123
- succeeded: data.succeeded,
1124
- failed: data.failed
1125
- })
1126
- });
1127
- await load();
1128
- } catch {
1129
- setFeedback({ tone: "danger", text: t("failures.error", "Replay failed.") });
1130
- } finally {
1131
- setBusy(false);
1132
- }
1133
- };
1134
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
1135
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
1136
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
1137
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: t("failures.title", "Failed submissions") }),
1138
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: t(
1139
- "failures.subtitle",
1140
- "Submissions HubSpot couldn't take after the automatic retries. They can be inspected under Content Manager → HubSpot failed submissions."
1141
- ) })
1142
- ] }),
1143
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1144
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { active: Boolean(total), children: t("failures.count", "{count} queued", { count: total ?? 0 }) }),
1145
- /* @__PURE__ */ jsxRuntime.jsx(
1146
- designSystem.Button,
1147
- {
1148
- variant: "secondary",
1149
- onClick: retry,
1150
- loading: busy,
1151
- disabled: !configured || !total,
1152
- children: t("failures.retry", "Replay now")
1153
- }
1154
- )
1155
- ] }),
1156
- feedback ? /* @__PURE__ */ jsxRuntime.jsx(
1157
- designSystem.Typography,
1158
- {
1159
- variant: "pi",
1160
- textColor: feedback.tone === "success" ? "success600" : "danger600",
1161
- children: feedback.text
1162
- }
1163
- ) : null
1164
- ] });
1165
- };
1166
- const HubspotSettings = () => {
1167
- const { formatMessage } = objectLabels.useIntl();
1168
- const { get, put, del } = admin.useFetchClient();
1169
- const [settings, setSettings] = React__namespace.useState(null);
1170
- const [apiKey, setApiKey] = React__namespace.useState("");
1171
- const [busy, setBusy] = React__namespace.useState(false);
1172
- const [feedback, setFeedback] = React__namespace.useState(
1173
- null
1174
- );
1175
- const t = (id, defaultMessage, values) => formatMessage({ id: index.getTranslation(id), defaultMessage }, values);
1176
- const load = React__namespace.useCallback(async () => {
1177
- const { data } = await get(`/${index.PLUGIN_ID}/settings`);
1178
- setSettings(data);
1179
- }, [get]);
1180
- React__namespace.useEffect(() => {
1181
- load().catch(
1182
- () => setFeedback({ tone: "danger", text: t("settings.load-error", "Could not load settings.") })
1183
- );
1184
- }, [load]);
1185
- const save = async () => {
1186
- setBusy(true);
1187
- setFeedback(null);
1188
- try {
1189
- const { data } = await put(`/${index.PLUGIN_ID}/settings`, { apiKey });
1190
- setSettings(data);
1191
- setApiKey("");
1192
- setFeedback({ tone: "success", text: t("settings.saved", "Key saved.") });
1193
- } catch {
1194
- setFeedback({ tone: "danger", text: t("settings.save-error", "Could not save the key.") });
1195
- } finally {
1196
- setBusy(false);
1197
- }
1198
- };
1199
- const remove = async () => {
1200
- setBusy(true);
1201
- setFeedback(null);
1202
- try {
1203
- const { data } = await del(`/${index.PLUGIN_ID}/settings`);
1204
- setSettings(data);
1205
- setApiKey("");
1206
- setFeedback({ tone: "success", text: t("settings.removed", "Key removed.") });
1207
- } catch {
1208
- setFeedback({ tone: "danger", text: t("settings.remove-error", "Could not remove the key.") });
1209
- } finally {
1210
- setBusy(false);
1211
- }
1212
- };
1213
- const test = async () => {
1214
- setBusy(true);
1215
- setFeedback(null);
1216
- try {
1217
- const { data } = await get(
1218
- `/${index.PLUGIN_ID}/properties?refresh=1`
1219
- );
1220
- setFeedback(
1221
- data.configured ? {
1222
- tone: "success",
1223
- text: t("settings.test-ok", "Connection established — {count} readable properties.", {
1224
- count: data.properties.length
1225
- })
1226
- } : { tone: "danger", text: t("settings.test-no-key", "No key configured.") }
1227
- );
1228
- } catch {
1229
- setFeedback({
1230
- tone: "danger",
1231
- text: t("settings.test-error", "HubSpot unreachable — invalid or revoked key?")
1232
- });
1233
- } finally {
1234
- setBusy(false);
1235
- }
1236
- };
1237
- if (!settings) {
1238
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 8, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true, children: t("settings.loading", "Loading…") }) });
1239
- }
1240
- const sourceLabel = {
1241
- settings: t("settings.source.settings", "set here"),
1242
- config: t("settings.source.config", "config/plugins.ts"),
1243
- env: t("settings.source.env", "environment variable")
1244
- };
1245
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 8, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
1246
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
1247
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", children: "HubSpot" }),
1248
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: t(
1249
- "settings.subtitle",
1250
- "The private app token used to read the portal's properties and validate form mappings."
1251
- ) })
1252
- ] }),
1253
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1254
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { active: settings.configured, children: settings.configured ? t("settings.configured", "Configured {hint}", { hint: settings.hint }) : t("settings.not-configured", "Not configured") }),
1255
- settings.keySource ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t("settings.source", "source: {source}", { source: sourceLabel[settings.keySource] }) }) : null
1256
- ] }),
1257
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { maxWidth: "32rem", children: /* @__PURE__ */ jsxRuntime.jsxs(
1258
- designSystem.Field.Root,
1259
- {
1260
- name: "apiKey",
1261
- hint: t(
1262
- "settings.key.hint",
1263
- "A key entered here overrides the ones from config/plugins.ts and HUBSPOT_API_KEY."
1264
- ),
1265
- children: [
1266
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: t("settings.key.label", "Private app token") }),
1267
- /* @__PURE__ */ jsxRuntime.jsx(
1268
- designSystem.Field.Input,
1269
- {
1270
- type: "password",
1271
- value: apiKey,
1272
- autoComplete: "off",
1273
- placeholder: settings.configured ? t("settings.key.placeholder.set", "•••••••• (leave empty to keep)") : t("settings.key.placeholder.empty", "pat-eu1-…"),
1274
- onChange: (e) => setApiKey(e.target.value)
1275
- }
1276
- ),
1277
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
1278
- ]
1279
- }
1280
- ) }),
1281
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
1282
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: save, loading: busy, disabled: !apiKey.trim(), children: t("settings.save", "Save") }),
1283
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: test, loading: busy, disabled: !settings.configured, children: t("settings.test", "Test connection") }),
1284
- /* @__PURE__ */ jsxRuntime.jsx(
1285
- designSystem.Button,
1286
- {
1287
- variant: "danger-light",
1288
- onClick: remove,
1289
- loading: busy,
1290
- disabled: settings.keySource !== "settings",
1291
- children: t("settings.remove", "Remove")
1292
- }
1293
- )
1294
- ] }),
1295
- feedback ? /* @__PURE__ */ jsxRuntime.jsx(
1296
- designSystem.Typography,
1297
- {
1298
- variant: "pi",
1299
- textColor: feedback.tone === "success" ? "success600" : "danger600",
1300
- children: feedback.text
1301
- }
1302
- ) : null,
1303
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: t(
1304
- "settings.scopes",
1305
- "The token needs the crm.schemas.contacts.read and crm.schemas.companies.read scopes to list properties. It is never returned to the browser: only its existence, its source and its last four characters are."
1306
- ) }) }),
1307
- /* @__PURE__ */ jsxRuntime.jsx(AuditSection, { configured: settings.configured }),
1308
- /* @__PURE__ */ jsxRuntime.jsx(FailuresSection, { configured: settings.configured })
1309
- ] }) });
1310
- };
1311
- exports.default = HubspotSettings;
1564
+ exports.Link = Link;
1565
+ exports.Route = Route;
1566
+ exports.Routes = Routes;
1567
+ exports.useNavigate = useNavigate;
1568
+ exports.useParams = useParams;
1569
+ exports.useSearchParams = useSearchParams;