@wavemaker-ai/react-runtime 1.0.0-rc.647712 → 12.0.0-rc.335

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 (106) hide show
  1. package/components/basic/richtexteditor/index.d.ts +1 -0
  2. package/components/basic/search/index.js +5 -4
  3. package/components/basic/search/utils.d.ts +1 -0
  4. package/components/basic/search/utils.js +9 -0
  5. package/components/common/index.d.ts +2 -0
  6. package/components/common/index.js +2 -0
  7. package/components/common/partial-content-wrapper.d.ts +15 -0
  8. package/components/common/partial-content-wrapper.js +11 -0
  9. package/components/container/index.js +5 -2
  10. package/components/container/tabs/index.js +5 -3
  11. package/components/container/wizard/index.js +36 -3
  12. package/components/container/wizard/props.d.ts +2 -2
  13. package/components/data/form/dynamic-fields/WmxDynamicFormField.js +9 -23
  14. package/components/data/form/form-controller/props.d.ts +2 -0
  15. package/components/data/form/form-controller/utils.js +3 -2
  16. package/components/data/form/form-controller/validation-contrustor.js +112 -1
  17. package/components/data/form/form-controller/withFormController.js +1 -1
  18. package/components/data/form/form-field/index.js +6 -3
  19. package/components/data/form/form-field/props.d.ts +1 -0
  20. package/components/data/list/components/ListItemWithTemplate.js +1 -1
  21. package/components/data/list/index.js +1 -1
  22. package/components/data/table/components/EditableCell.js +47 -24
  23. package/components/data/table/components/FieldValidationError.js +1 -1
  24. package/components/data/table/components/TableHeader.js +9 -3
  25. package/components/data/table/hooks/useFormWidget.js +11 -0
  26. package/components/data/table/hooks/useRowSelection.js +58 -1
  27. package/components/data/table/hooks/useTableEdit.d.ts +1 -1
  28. package/components/data/table/hooks/useTableEdit.js +115 -75
  29. package/components/data/table/hooks/useTableEditForms.d.ts +25 -0
  30. package/components/data/table/hooks/useTableEditForms.js +30 -0
  31. package/components/data/table/index.js +68 -32
  32. package/components/data/table/props.d.ts +42 -23
  33. package/components/data/table/utils/buildSelectionColumns.js +3 -3
  34. package/components/data/table/utils/columnProxy.d.ts +7 -1
  35. package/components/data/table/utils/columnProxy.js +21 -1
  36. package/components/data/table/utils/columnValidation.d.ts +19 -0
  37. package/components/data/table/utils/columnValidation.js +76 -0
  38. package/components/data/table/utils/constants.d.ts +2 -0
  39. package/components/data/table/utils/constants.js +2 -0
  40. package/components/data/table/utils/index.d.ts +4 -12
  41. package/components/data/table/utils/index.js +13 -77
  42. package/components/data/table/utils/selectionUtils.js +13 -5
  43. package/components/input/chips/index.d.ts +1 -0
  44. package/components/input/color-picker/index.d.ts +1 -0
  45. package/components/input/currency/index.d.ts +1 -0
  46. package/components/input/default/checkbox/index.d.ts +1 -0
  47. package/components/input/default/checkboxset/index.d.ts +1 -0
  48. package/components/input/default/radioset/index.d.ts +1 -0
  49. package/components/input/default/switch/index.d.ts +1 -0
  50. package/components/input/epoch/datetime/index.js +10 -2
  51. package/components/input/number/index.d.ts +1 -0
  52. package/components/input/rating/index.d.ts +1 -0
  53. package/components/input/select/index.d.ts +1 -0
  54. package/components/input/slider/index.d.ts +1 -0
  55. package/components/input/text/index.d.ts +1 -0
  56. package/components/input/textarea/index.d.ts +1 -0
  57. package/components/input/upload/index.d.ts +1 -0
  58. package/components/layout/footer/index.js +4 -2
  59. package/components/layout/footer/props.d.ts +1 -0
  60. package/components/layout/header/index.js +29 -3
  61. package/components/layout/header/props.d.ts +1 -0
  62. package/components/layout/leftnav/index.js +22 -6
  63. package/components/layout/leftnav/props.d.ts +1 -0
  64. package/components/layout/leftnav/utils/page-class-util.d.ts +1 -0
  65. package/components/layout/leftnav/utils/page-class-util.js +4 -3
  66. package/components/layout/rightnav/index.js +4 -2
  67. package/components/layout/rightnav/props.d.ts +1 -0
  68. package/components/layout/topnav/index.js +4 -2
  69. package/components/layout/topnav/props.d.ts +1 -0
  70. package/components/navbar/index.js +32 -7
  71. package/components/navigation/menu/index.js +6 -2
  72. package/components/page/index.js +60 -19
  73. package/components/page/page-context.d.ts +4 -0
  74. package/core/proxy-service.js +86 -19
  75. package/higherOrder/BaseApp.js +1 -1
  76. package/higherOrder/BasePage.js +2 -1
  77. package/higherOrder/withBaseWrapper.js +10 -2
  78. package/hooks/useHttp.d.ts +14 -4
  79. package/hooks/useHttp.js +47 -9
  80. package/package-lock.json +314 -308
  81. package/package.json +3 -3
  82. package/runtime-dynamic/App.js +21 -2
  83. package/runtime-dynamic/app-initializer.js +8 -1
  84. package/runtime-dynamic/factories/dynamic-component.js +4 -3
  85. package/runtime-dynamic/main.d.ts +1 -0
  86. package/runtime-dynamic/main.js +9 -1
  87. package/runtime-dynamic/services/compile-render.js +7 -0
  88. package/runtime-dynamic/services/css-scoping.d.ts +1 -1
  89. package/runtime-dynamic/services/css-scoping.js +2 -2
  90. package/runtime-dynamic/services/variable-factory.js +2 -1
  91. package/runtime-dynamic/services/variable-transpiler.js +4 -1
  92. package/runtime-dynamic/wmx-shared.d.ts +40 -0
  93. package/runtime-dynamic/wmx-shared.js +33 -0
  94. package/utils/style-utils.js +1 -1
  95. package/utils/wmx.utils.d.ts +0 -1
  96. package/utils/wmx.utils.js +0 -25
  97. package/variables/crud-variable.d.ts +10 -0
  98. package/variables/crud-variable.js +53 -2
  99. package/variables/live-variable.d.ts +1 -0
  100. package/variables/live-variable.js +2 -1
  101. package/variables/operation-params.d.ts +29 -0
  102. package/variables/operation-params.js +69 -0
  103. package/variables/service-variable.d.ts +9 -0
  104. package/variables/service-variable.js +21 -2
  105. package/components/data/table/utils/validation.d.ts +0 -13
  106. package/components/data/table/utils/validation.js +0 -82
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavemaker-ai/react-runtime",
3
- "version": "1.0.0-rc.647712",
3
+ "version": "12.0.0-rc.335",
4
4
  "description": "React runtime package for Wavemaker",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -58,8 +58,8 @@
58
58
  "@mui/x-date-pickers": "8.5.3",
59
59
  "@reduxjs/toolkit": "2.9.1",
60
60
  "@tanstack/react-table": "8.21.3",
61
- "@wavemaker-ai/react-codegen": "1.0.0-rc.647712",
62
- "@wavemaker-ai/variables": "1.0.0-rc.647712",
61
+ "@wavemaker-ai/react-codegen": "12.0.0-rc.335",
62
+ "@wavemaker-ai/variables": "12.0.0-rc.335",
63
63
  "@wavemaker/nvd3": "1.8.16",
64
64
  "axios": "1.15.1",
65
65
  "d3": "7.8.5",
@@ -1,3 +1,22 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1
20
  import { Fragment, jsx } from "react/jsx-runtime";
2
21
  import { Provider } from "react-redux";
3
22
  import { RouterProvider } from "react-router-dom";
@@ -93,7 +112,7 @@ function initPreviewRuntimeRouter(router) {
93
112
  pathname: pathname || "/",
94
113
  search: search ? `?${search}` : ""
95
114
  };
96
- router.navigate(navigationPayload, options);
115
+ router.navigate(navigationPayload, __spreadProps(__spreadValues({}, options), { flushSync: true }));
97
116
  }
98
117
  setRouter({
99
118
  push: (path) => navigateWithSearchParams(path),
@@ -108,7 +127,7 @@ function App() {
108
127
  "initPreviewRuntimeRouter() must be called after initializeApp() and before render."
109
128
  );
110
129
  }
111
- return /* @__PURE__ */ jsx(Provider, { store, children: /* @__PURE__ */ jsx(LocalizationProvider, { children: /* @__PURE__ */ jsx(WmThemeProvider, { children: /* @__PURE__ */ jsx(ToastProvider, { children: /* @__PURE__ */ jsx(WmApp, { children: /* @__PURE__ */ jsx(RouterProvider, { router: previewRouter }) }) }) }) }) });
130
+ return /* @__PURE__ */ jsx(Provider, { store, children: /* @__PURE__ */ jsx(LocalizationProvider, { children: /* @__PURE__ */ jsx(WmThemeProvider, { children: /* @__PURE__ */ jsx(WmApp, { children: /* @__PURE__ */ jsx(ToastProvider, { children: /* @__PURE__ */ jsx(RouterProvider, { router: previewRouter }) }) }) }) }) });
112
131
  }
113
132
  export {
114
133
  App,
@@ -228,11 +228,18 @@ async function initializeApp() {
228
228
  }
229
229
  }
230
230
  function getIconCssPathsFromFontConfig() {
231
+ var _a;
231
232
  const source = projectConfig.fontConfig;
232
233
  if (!source) {
233
234
  return [];
234
235
  }
235
- return [...source.matchAll(/"csspath":\s*"([^"]+)"/g)].map((match) => match[1]);
236
+ try {
237
+ const normalized = source.replace(/^\s*export\s+default\s+/m, "").replace(/;?\s*$/, "");
238
+ const fontConfig = new Function(`return (${normalized});`)();
239
+ return ((_a = fontConfig == null ? void 0 : fontConfig.fonts) != null ? _a : []).filter((font) => !!font.csspath).map((font) => font.csspath);
240
+ } catch (e) {
241
+ return [];
242
+ }
236
243
  }
237
244
  function resolvePreviewIconStylesheetUrl(csspath) {
238
245
  if (/^https?:\/\//i.test(csspath) || csspath.startsWith("//")) {
@@ -18,7 +18,7 @@ var __spreadValues = (a, b) => {
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
  import { jsx } from "react/jsx-runtime";
21
- import React, { useEffect, useReducer, useRef } from "react";
21
+ import React, { useEffect, useId, useReducer, useRef } from "react";
22
22
  import WmPrefab from "../../components/prefab";
23
23
  import { useAppState } from "../../context/WidgetProvider";
24
24
  import { useAppContext } from "../../context/AppContext";
@@ -76,12 +76,13 @@ function createDynamicComponent({
76
76
  const InnerComponent = (props) => {
77
77
  const appState = useAppState();
78
78
  usePageEvents(appState, componentType);
79
+ const uniqueId = useId();
79
80
  const appContext = useAppContext();
80
81
  useCrossScopeDataRefresh(appContext, componentType);
81
82
  const notification = appContext == null ? void 0 : appContext.notification;
82
83
  useEffect(() => {
83
84
  if (styles) {
84
- scopeComponentStyles(componentName, componentType, styles);
85
+ scopeComponentStyles(componentName, componentType, styles, uniqueId);
85
86
  }
86
87
  let id = null;
87
88
  if (appState) {
@@ -89,7 +90,7 @@ function createDynamicComponent({
89
90
  }
90
91
  return () => {
91
92
  if (id) clearTimeout(id);
92
- removeComponentStyles(componentName, componentType);
93
+ removeComponentStyles(`${componentType}-${componentName}-${uniqueId}`, componentType);
93
94
  };
94
95
  }, []);
95
96
  if (!transpiled) return null;
@@ -1,2 +1,3 @@
1
+ export { __wmxShared } from "./wmx-shared";
1
2
  declare const noop: () => void;
2
3
  export default noop;
@@ -4,11 +4,18 @@ import wmGlobalsCss from "@wavemaker-ai/react-codegen/styles/wm-styles.css";
4
4
  import { App, initPreviewRuntimeRouter } from "./App";
5
5
  import { initializeApp } from "./app-initializer";
6
6
  import { registerCustomWidget, getCustomWidget, hasCustomWidget } from "./registry";
7
+ import { registerWmxComponents } from "../utils/wmx.utils";
7
8
  import { createAppRouter } from "./routes";
9
+ import { __wmxShared } from "./wmx-shared";
8
10
  window.WMPreview = {
9
11
  registerCustomWidget,
10
12
  getCustomWidget,
11
- hasCustomWidget
13
+ hasCustomWidget,
14
+ registerWmxComponents
15
+ // React,
16
+ // ReactDOM,
17
+ // ReactDOMClient,
18
+ // jsxRuntime: ReactJsxRuntime,
12
19
  };
13
20
  function injectGlobalStyles() {
14
21
  if (document.querySelector('style[data-wm-scope="globals"]')) return;
@@ -56,5 +63,6 @@ const noop = () => {
56
63
  };
57
64
  var main_default = noop;
58
65
  export {
66
+ __wmxShared,
59
67
  main_default as default
60
68
  };
@@ -24,6 +24,7 @@ import { getCustomWidget } from "../registry/custom-widget-registry";
24
24
  import {
25
25
  WmxComponentPlaceholder
26
26
  } from "../components/wmx-placeholder";
27
+ import WmxRenderer from "../../components/wmx/WmxRenderer";
27
28
  import { formatMessage, _get, toNumber } from "../../core/util";
28
29
  import { getPartialNames } from "../app-initializer";
29
30
  import { createLazyPartial } from "./variable-registry";
@@ -75,6 +76,12 @@ function tryAddWmxScopeComponent(scopeName, seen, names, values) {
75
76
  values.push(registered);
76
77
  return true;
77
78
  }
79
+ if (scopeName === "WmxRenderer") {
80
+ seen.add(scopeName);
81
+ names.push(scopeName);
82
+ values.push(WmxRenderer);
83
+ return true;
84
+ }
78
85
  const component = (props) => {
79
86
  var _a, _b;
80
87
  return React.createElement(WmxComponentPlaceholder, __spreadProps(__spreadValues({}, props), {
@@ -1,4 +1,4 @@
1
1
  /** Resolves the prefab name used for CSS scope classes and `app-prefab-{name}` wrappers. */
2
2
  export declare function resolvePrefabScopeName(componentName: string, prefabname?: string): string;
3
- export declare function scopeComponentStyles(componentName: string, componentType: string, styles: string): string;
3
+ export declare function scopeComponentStyles(componentName: string, componentType: string, styles: string, uniqueId: string): string;
4
4
  export declare function removeComponentStyles(componentName: string, componentType: string): void;
@@ -35,7 +35,7 @@ function getCssScopeOptions(componentType, componentName) {
35
35
  }
36
36
  return void 0;
37
37
  }
38
- function scopeComponentStyles(componentName, componentType, styles) {
38
+ function scopeComponentStyles(componentName, componentType, styles, uniqueId) {
39
39
  var _a;
40
40
  if (!styles) return "";
41
41
  const scopeOptions = getCssScopeOptions(componentType, componentName);
@@ -48,7 +48,7 @@ function scopeComponentStyles(componentName, componentType, styles) {
48
48
  scopedCssCache.set(cacheKey, scopedCss);
49
49
  }
50
50
  const styleElement = document.createElement("style");
51
- styleElement.setAttribute("data-wm-scope", scopeAttribute);
51
+ styleElement.setAttribute("data-wm-scope", `${scopeAttribute}-${uniqueId}`);
52
52
  styleElement.textContent = scopedCss;
53
53
  const existing = document.querySelector(`style[data-wm-scope="${scopeAttribute}"]`);
54
54
  if (existing) {
@@ -23,6 +23,7 @@ import {
23
23
  EMPTY_RESULT,
24
24
  createLazyPartial
25
25
  } from "./variable-registry";
26
+ import { getPartialNames } from "../app-initializer";
26
27
  const EVENT_HANDLER_REGEX = /^(\w+)\(([^)]*)\)$/;
27
28
  const RETURN_VALUE_HANDLERS = /* @__PURE__ */ new Set([
28
29
  "onBeforeUpdate",
@@ -126,7 +127,7 @@ const enhanceNotification = (config, variable, scopeProxy) => {
126
127
  const dataBindings = variable.dataBinding;
127
128
  const pageBinding = dataBindings == null ? void 0 : dataBindings.find((b) => b.target === "page");
128
129
  if (pageBinding == null ? void 0 : pageBinding.value) {
129
- const partialName = pageBinding.value.charAt(0).toUpperCase() + pageBinding.value.slice(1);
130
+ const partialName = getPartialNames().find((p) => p.toLowerCase() === pageBinding.value.toLowerCase()) || pageBinding.value;
130
131
  config.partialContent = { component: createLazyPartial(partialName) };
131
132
  }
132
133
  };
@@ -23,6 +23,7 @@ import {
23
23
  EMPTY_RESULT,
24
24
  createLazyPartial
25
25
  } from "./variable-registry";
26
+ import { getPartialNames } from "../app-initializer";
26
27
  function buildEntityProviderShims(rawVariables) {
27
28
  const entityMap = /* @__PURE__ */ new Map();
28
29
  for (const config of Object.values(rawVariables || {})) {
@@ -99,8 +100,10 @@ function transpileAndBuildGetVariables(variablesCodeString, rawVariables) {
99
100
  getEntityPropertyMap,
100
101
  getEntityRelatedTables
101
102
  });
103
+ const knownPartials = getPartialNames();
102
104
  for (const name of extractPartialImports(variablesCodeString)) {
103
- scopeWithShims[name] = createLazyPartial(name);
105
+ const partialName = knownPartials.find((p) => p.toLowerCase() === name.toLowerCase()) || name;
106
+ scopeWithShims[name] = createLazyPartial(partialName);
104
107
  }
105
108
  const scopeNames = Object.keys(scopeWithShims);
106
109
  const scopeValues = Object.values(scopeWithShims);
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Packages the app's WMX bundle must borrow from this one instead of bundling
3
+ * its own copy.
4
+ *
5
+ * A WMX component is built separately and loaded as its own <script>, so any
6
+ * package used on both sides ends up loaded twice. For most packages that is
7
+ * harmless -- two copies of lodash or embla-carousel just cost bundle size,
8
+ * because everything they hold lives on the values they hand back.
9
+ *
10
+ * The ones below are different. Each keeps something private inside the package
11
+ * itself that both sides have to agree on:
12
+ *
13
+ * react / react-dom a second copy makes every hook throw "Invalid hook call"
14
+ * @emotion/* two copies write conflicting stylesheets
15
+ * @mui/* the app's <ThemeProvider> cannot be seen by a second copy
16
+ * react-redux,
17
+ * @reduxjs/toolkit the store cannot be seen by a second copy
18
+ * react-hook-form the form provider cannot be seen by a second copy
19
+ * react-router-dom the router cannot be seen by a second copy
20
+ * @dnd-kit/core,
21
+ * @base-ui-components same problem, their own providers
22
+ *
23
+ * Everything except React fails QUIETLY -- the component reads an empty default
24
+ * instead of the app's real value, with no error anywhere. That is why the list
25
+ * is written out by hand rather than guessed.
26
+ *
27
+ * It only needs to cover packages THIS runtime ships. A package a WMX component
28
+ * adds that the runtime does not have exists only once on the page, so there is
29
+ * nothing to share and nothing to break -- which is what stops this list from
30
+ * growing every time someone writes a new component.
31
+ *
32
+ * Handed over as a plain module export, not on `window`. The app's WMX bundle
33
+ * imports it straight out of wm-react-loader.js, so the browser reuses the file
34
+ * it already loaded for the page and there is only ever one copy.
35
+ *
36
+ * Adding a package here is half the job -- the name must also go into
37
+ * SHARED_MODULES in the app's config/esbuild.wmx.config.mjs. If it is only
38
+ * listed there, the bundle throws a clear message when it loads.
39
+ */
40
+ export declare const __wmxShared: Record<string, unknown>;
@@ -0,0 +1,33 @@
1
+ import * as React from "react";
2
+ import * as ReactJsxRuntime from "react/jsx-runtime";
3
+ import * as ReactDOM from "react-dom";
4
+ import * as ReactDOMClient from "react-dom/client";
5
+ import * as EmotionReact from "@emotion/react";
6
+ import * as EmotionStyled from "@emotion/styled";
7
+ import * as MuiMaterial from "@mui/material";
8
+ import * as MuiXDatePickers from "@mui/x-date-pickers";
9
+ import * as ReactRedux from "react-redux";
10
+ import * as ReduxToolkit from "@reduxjs/toolkit";
11
+ import * as ReactHookForm from "react-hook-form";
12
+ import * as ReactRouterDom from "react-router-dom";
13
+ import * as DndKitCore from "@dnd-kit/core";
14
+ import * as BaseUiComponents from "@base-ui-components/react";
15
+ const __wmxShared = {
16
+ react: React,
17
+ "react/jsx-runtime": ReactJsxRuntime,
18
+ "react-dom": ReactDOM,
19
+ "react-dom/client": ReactDOMClient,
20
+ "@emotion/react": EmotionReact,
21
+ "@emotion/styled": EmotionStyled,
22
+ "@mui/material": MuiMaterial,
23
+ "@mui/x-date-pickers": MuiXDatePickers,
24
+ "react-redux": ReactRedux,
25
+ "@reduxjs/toolkit": ReduxToolkit,
26
+ "react-hook-form": ReactHookForm,
27
+ "react-router-dom": ReactRouterDom,
28
+ "@dnd-kit/core": DndKitCore,
29
+ "@base-ui-components/react": BaseUiComponents
30
+ };
31
+ export {
32
+ __wmxShared
33
+ };
@@ -1,6 +1,6 @@
1
1
  import { getCurrentPath } from "../core/util/utils";
2
2
  const sanitizeStyleObject = (styleObj) => {
3
- if (!styleObj || typeof styleObj !== "object") {
3
+ if (!styleObj || typeof styleObj !== "object" || Array.isArray(styleObj)) {
4
4
  return {};
5
5
  }
6
6
  const validStyles = {};
@@ -3,4 +3,3 @@ export type WmxComponentModule = Record<string, ComponentType<any>>;
3
3
  export declare const registerWmxComponents: (module: WmxComponentModule) => void;
4
4
  export declare const getWmxModule: () => WmxComponentModule | null;
5
5
  export declare const getWmxComponentName: (widgetName: string) => string | null;
6
- export declare const loadWmxComponent: (componentName: string) => Promise<ComponentType<any> | null>;
@@ -9,33 +9,8 @@ const getWmxComponentName = (widgetName) => {
9
9
  const componentName = (_a = widgetName.split("-")) == null ? void 0 : _a[1];
10
10
  return componentName || null;
11
11
  };
12
- const resolveWmxComponent = (module, componentName) => {
13
- const prefixedComponentName = `Wmx${componentName}`;
14
- const namedExport = module[prefixedComponentName];
15
- return namedExport;
16
- };
17
- const loadWmxComponent = async (componentName) => {
18
- try {
19
- const module = _registeredModule;
20
- if (!module) {
21
- console.warn("wmx modules not found");
22
- const fallbackModule = await import("../components/input/text");
23
- return fallbackModule.default;
24
- }
25
- const component = resolveWmxComponent(module, componentName);
26
- if (!component) {
27
- throw new Error(`WMX component "${componentName}" has no default export.`);
28
- }
29
- return component;
30
- } catch (error) {
31
- console.warn(`WMX component "${componentName}" failed to load, falling back to WmText.`, error);
32
- const fallbackModule = await import("../components/input/text");
33
- return fallbackModule.default;
34
- }
35
- };
36
12
  export {
37
13
  getWmxComponentName,
38
14
  getWmxModule,
39
- loadWmxComponent,
40
15
  registerWmxComponents
41
16
  };
@@ -22,8 +22,18 @@ declare class CrudVariable extends CrudVariable_base {
22
22
  config: CrudVariableConfig;
23
23
  params: any;
24
24
  filters: any;
25
+ /**
26
+ * The by-name params a generated invokeHttp receives. Same field name ServiceVariable uses, so
27
+ * useHttp's call site needs no per-kind chain. NOT `lastInvokedParams`: that name is
28
+ * ServiceVariable's RAW provider snapshot (compared against by invokeOnParamChange), and it is
29
+ * private there — reading it cross-object would also be reading a different thing.
30
+ */
31
+ resolvedParams: any;
25
32
  constructor(config: CrudVariableConfig);
26
33
  setFilterExpValue(filter: any): void;
34
+ lastInvokedOperation: string | undefined;
35
+ private captureLastInvokedParams;
36
+ private resolveParams;
27
37
  invokeOnParamChange(): Promise<this>;
28
38
  listRecords(options?: any, onSuccess?: Function, onError?: Function): any;
29
39
  updateRecord(options?: any, success?: any, error?: any): any;
@@ -9,7 +9,9 @@ import {
9
9
  internalBoundNodeMap
10
10
  } from "@wavemaker-ai/variables";
11
11
  import { VariableEvents, isStaticParamVariable } from "./base-variable";
12
- import { isEqual, isUndefined, isFunction, forEach, isEmpty, isArray, set } from "lodash-es";
12
+ import { isEqual, isUndefined, isFunction, forEach, isEmpty, isArray, set, merge } from "lodash-es";
13
+ import { metadataService } from "./metadata.service";
14
+ import { resolveOperationParams } from "./operation-params";
13
15
  import httpService from "../hooks/useHttp";
14
16
  import { deepCopy } from "../core/util";
15
17
  import Formatters from "../core/formatters";
@@ -63,12 +65,26 @@ class CrudVariable extends _CrudVariable {
63
65
  EventNotifier.ROOT.notify("SERVICE_ERROR", [args.variable, args.data, args.options]);
64
66
  }
65
67
  return config.onError && config.onError(args.variable, args.data, args.options);
66
- }
68
+ },
69
+ // Outside preview mode useHttp's send() calls variable.invokeHttp — without this the
70
+ // generated glue is dropped here and every CRUD call throws "invokeHttp is not a function".
71
+ invokeHttp: (config == null ? void 0 : config.invokeHttp) || void 0
67
72
  };
68
73
  super(variableConfig);
69
74
  this.config = config;
70
75
  __publicField(this, "params", {});
71
76
  __publicField(this, "filters", {});
77
+ /**
78
+ * The by-name params a generated invokeHttp receives. Same field name ServiceVariable uses, so
79
+ * useHttp's call site needs no per-kind chain. NOT `lastInvokedParams`: that name is
80
+ * ServiceVariable's RAW provider snapshot (compared against by invokeOnParamChange), and it is
81
+ * private there — reading it cross-object would also be reading a different thing.
82
+ */
83
+ __publicField(this, "resolvedParams");
84
+ // Which CRUD operation this call is for. A CrudVariable maps to a SET of operations
85
+ // (list/create/update/delete) resolved per call, so a generated invokeHttp has to be told which
86
+ // one to dispatch to — unlike a ServiceVariable, which is always one fixed operation.
87
+ __publicField(this, "lastInvokedOperation");
72
88
  this.dateFormatter = Formatters.get("toDate");
73
89
  this.init();
74
90
  }
@@ -79,6 +95,36 @@ class CrudVariable extends _CrudVariable {
79
95
  r.value = filter[r.target];
80
96
  });
81
97
  }
98
+ captureLastInvokedParams(options, operation) {
99
+ var _a, _b;
100
+ this.lastInvokedOperation = (_a = operation != null ? operation : options == null ? void 0 : options.operation) != null ? _a : "list";
101
+ let inputFields = merge({}, this.config.paramProvider(), this.dataBinding, this.params);
102
+ if (options) {
103
+ const overrides = (_b = options.inputFields) != null ? _b : options;
104
+ inputFields = merge({}, inputFields, overrides);
105
+ }
106
+ this.resolvedParams = this.resolveParams(inputFields, options);
107
+ }
108
+ // CrudVariableManager calls httpCall(requestParams, variable) with NO third argument (unlike
109
+ // Live/ServiceVariable), so a generated invokeHttp never receives this call's values by name.
110
+ // The manager does resolve them — onto operationInfo.parameters[].sampleValue in
111
+ // getMethodInfoForCrud — but keeps that local. Rebuild the same flat map from the same
112
+ // servicedefs entry, using the resolver shared with ServiceVariable.
113
+ resolveParams(inputFields, options) {
114
+ var _a, _b, _c, _d;
115
+ const defs = (_c = (_a = metadataService) == null ? void 0 : _a.getByCrudId) == null ? void 0 : _c.call(
116
+ _a,
117
+ this.config.crudOperationId,
118
+ (_b = this.getPrefabName) == null ? void 0 : _b.call(this)
119
+ );
120
+ const def = (defs || []).find((d) => (d == null ? void 0 : d.operationType) === this.lastInvokedOperation);
121
+ return resolveOperationParams({
122
+ parameters: (_d = def == null ? void 0 : def.wmServiceOperationInfo) == null ? void 0 : _d.parameters,
123
+ inputFields,
124
+ options,
125
+ config: this.config
126
+ });
127
+ }
82
128
  invokeOnParamChange() {
83
129
  const isStatic = isStaticParamVariable(this.config, this);
84
130
  if (isStatic) return isStatic;
@@ -125,21 +171,25 @@ class CrudVariable extends _CrudVariable {
125
171
  options = options || {};
126
172
  options.filterFields = this.filters;
127
173
  this.setFilterExpValue(this.filters);
174
+ this.captureLastInvokedParams(options, "list");
128
175
  return super.listRecords(options, onSuccess, onError);
129
176
  }
130
177
  updateRecord(options, success, error) {
131
178
  this.processBinding(this);
132
179
  this.notify(VariableEvents.BEFORE_INVOKE, [this]);
180
+ this.captureLastInvokedParams(options, "update");
133
181
  return super.updateRecord(options, success, error);
134
182
  }
135
183
  insertRecord(options, success, error) {
136
184
  this.processBinding(this);
137
185
  this.notify(VariableEvents.BEFORE_INVOKE, [this]);
186
+ this.captureLastInvokedParams(options, "create");
138
187
  return super.insertRecord(options, success, error);
139
188
  }
140
189
  deleteRecord(options, success, error) {
141
190
  this.processBinding(this);
142
191
  this.notify(VariableEvents.BEFORE_INVOKE, [this]);
192
+ this.captureLastInvokedParams(options, "delete");
143
193
  return super.deleteRecord(options, success, error);
144
194
  }
145
195
  processBindExp(d, variable) {
@@ -187,6 +237,7 @@ class CrudVariable extends _CrudVariable {
187
237
  }
188
238
  invoke(options, onSuccess, onError) {
189
239
  this.processBinding(this);
240
+ this.captureLastInvokedParams(options);
190
241
  return super.invoke(options, onSuccess, onError);
191
242
  }
192
243
  }
@@ -34,6 +34,7 @@ export interface LiveVariableConfig extends VariableConfig {
34
34
  insertRecord: (options?: any, success?: any, error?: any) => Promise<any>;
35
35
  deleteRecord: (options?: any, success?: any, error?: any) => Promise<any>;
36
36
  notify: (event: VariableEvents, args: any) => void;
37
+ invokeHttp?: Function;
37
38
  }
38
39
  declare enum _LiveVariableEvents {
39
40
  BEFORE_INVOKE = "beforeInvoke"
@@ -66,7 +66,8 @@ class LiveVariable extends _LiveVariable {
66
66
  EventNotifier.ROOT.notify("SERVICE_ERROR", [args.variable, args.data, args.options]);
67
67
  }
68
68
  return config.onError && config.onError(args.variable, args.data, args.options);
69
- }
69
+ },
70
+ invokeHttp: (config == null ? void 0 : config.invokeHttp) || void 0
70
71
  };
71
72
  super(variableConfig);
72
73
  this.config = config;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Port of getEvaluatedOrderBy (not exported from the package root): the options order wins, and a
3
+ * field ordered by both is kept only once.
4
+ */
5
+ export declare function evaluatedOrderBy(varOrder: any, optionsOrder: any): any;
6
+ export interface ResolveParamsInput {
7
+ /** The operation's declared parameters — `wmServiceOperationInfo.parameters`. */
8
+ parameters?: any[];
9
+ /** The values the variable already holds, keyed by param name. */
10
+ inputFields?: any;
11
+ /** The per-call options (`options.page`, `options.size`, `options.orderBy`). */
12
+ options?: any;
13
+ /** The variable's own config, for its defaults. */
14
+ config?: any;
15
+ /**
16
+ * ServiceVariableUtils' `isBodyTypeQueryOrProcedure` — `controller` in
17
+ * {QueryExecution, ProcedureExecution} and `operationType` in {put, post}. Its BODY branch
18
+ * assembles the body from the body param's declared children instead of reading the param's
19
+ * own value.
20
+ */
21
+ isBodyTypeQueryOrProcedure?: boolean;
22
+ /** `wmServiceOperationInfo.definitions` — keyed by a param's `type`, listing its children. */
23
+ definitions?: Record<string, any>;
24
+ }
25
+ /**
26
+ * Returns `inputFields` unchanged when the operation has no declared parameters — there is nothing
27
+ * to resolve against, so passing the raw fields through is strictly better than emptying them.
28
+ */
29
+ export declare function resolveOperationParams({ parameters, inputFields, options, config, isBodyTypeQueryOrProcedure, definitions, }: ResolveParamsInput): any;
@@ -0,0 +1,69 @@
1
+ import { includes, isEmpty, join, map, remove, split, trim } from "lodash-es";
2
+ const PAGINATION_PARAMS = ["page", "size", "sort"];
3
+ function evaluatedOrderBy(varOrder, optionsOrder) {
4
+ if (!optionsOrder || isEmpty(optionsOrder)) {
5
+ return varOrder;
6
+ }
7
+ if (!varOrder) {
8
+ return optionsOrder;
9
+ }
10
+ const varFields = split(varOrder, ",");
11
+ const optionFields = map(split(optionsOrder, ","), (order) => split(trim(order), " ")[0]);
12
+ remove(varFields, (orderBy) => includes(optionFields, split(trim(orderBy), " ")[0]));
13
+ return join(split(optionsOrder, ","), ",") + (varFields.length ? "," + join(varFields, ",") : "");
14
+ }
15
+ function buildQueryProcedureBody(param, inputFields, definitions) {
16
+ const children = definitions == null ? void 0 : definitions[param == null ? void 0 : param.type];
17
+ const wrapped = inputFields == null ? void 0 : inputFields[param == null ? void 0 : param.name];
18
+ const values = wrapped && typeof wrapped === "object" && !Array.isArray(wrapped) ? wrapped : inputFields;
19
+ const declared = (children == null ? void 0 : children.length) ? children.filter((child) => !(child == null ? void 0 : child.readOnly)) : Object.keys(values != null ? values : {}).map((name) => ({ name }));
20
+ const body = {};
21
+ for (const child of declared) {
22
+ const value = values == null ? void 0 : values[child.name];
23
+ if (value !== void 0 && value !== "" && value !== null) {
24
+ body[child.name] = value;
25
+ }
26
+ }
27
+ return body;
28
+ }
29
+ function resolveOperationParams({
30
+ parameters,
31
+ inputFields,
32
+ options,
33
+ config,
34
+ isBodyTypeQueryOrProcedure,
35
+ definitions
36
+ }) {
37
+ var _a, _b;
38
+ if (!(parameters == null ? void 0 : parameters.length)) {
39
+ return inputFields;
40
+ }
41
+ if (isBodyTypeQueryOrProcedure) {
42
+ const bodyParam = parameters.find((p) => (p == null ? void 0 : p.parameterType) === "body");
43
+ if (bodyParam) {
44
+ return buildQueryProcedureBody(bodyParam, inputFields, definitions);
45
+ }
46
+ }
47
+ const resolved = {};
48
+ for (const param of parameters) {
49
+ if (param.readOnly) {
50
+ continue;
51
+ }
52
+ let value = inputFields == null ? void 0 : inputFields[param.name];
53
+ if (includes(PAGINATION_PARAMS, param.name)) {
54
+ if (param.name === "size") {
55
+ value = (options == null ? void 0 : options.size) || value || ((_b = (_a = config == null ? void 0 : config._paginationConfig) == null ? void 0 : _a.input) == null ? void 0 : _b.size) || parseInt(config == null ? void 0 : config.maxResults, 10);
56
+ } else if (param.name === "page") {
57
+ value = (options == null ? void 0 : options.page) || value || 1;
58
+ } else if (param.name === "sort") {
59
+ value = evaluatedOrderBy(config == null ? void 0 : config.orderBy, options == null ? void 0 : options.orderBy) || value || "";
60
+ }
61
+ }
62
+ resolved[param.name] = value;
63
+ }
64
+ return resolved;
65
+ }
66
+ export {
67
+ evaluatedOrderBy,
68
+ resolveOperationParams
69
+ };
@@ -11,6 +11,7 @@ export interface ServiceVariableConfig extends VariableConfig {
11
11
  inFlightBehavior: string;
12
12
  controller: string;
13
13
  getServiceInfo: Function;
14
+ invokeHttp?: Function;
14
15
  }
15
16
  declare enum _ServiceVariableEvents {
16
17
  BEFORE_INVOKE = "beforeInvoke"
@@ -24,6 +25,14 @@ export declare class ServiceVariable extends ServiceVariable_base {
24
25
  private initialized;
25
26
  params: any;
26
27
  private lastInvokedParams;
28
+ /**
29
+ * The by-name params a generated invokeHttp receives — resolved from the operation's declared
30
+ * parameters, so the pagination defaults the manager applies internally are present. Kept
31
+ * separate from lastInvokedParams, which invokeOnParamChange() compares against the RAW provider
32
+ * values: adding `page`/`size` to that snapshot would make every comparison unequal and
33
+ * re-invoke in a loop.
34
+ */
35
+ resolvedParams: any;
27
36
  private dateFormatter;
28
37
  private lastParams;
29
38
  private lastParamProviderValues;