@lowdefy/engine 4.5.1 → 4.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 (37) hide show
  1. package/dist/Actions.js +53 -20
  2. package/dist/Areas.js +4 -2
  3. package/dist/Block.js +20 -3
  4. package/dist/Events.js +1 -1
  5. package/dist/Requests.js +7 -3
  6. package/dist/State.js +1 -1
  7. package/dist/actions/createCallAPI.js +1 -1
  8. package/dist/actions/createCallMethod.js +3 -3
  9. package/dist/actions/createDisplayMessage.js +1 -1
  10. package/dist/actions/createGetActions.js +1 -1
  11. package/dist/actions/createGetBlockId.js +1 -1
  12. package/dist/actions/createGetEvent.js +1 -1
  13. package/dist/actions/createGetGlobal.js +1 -1
  14. package/dist/actions/createGetInput.js +1 -1
  15. package/dist/actions/createGetPageId.js +1 -1
  16. package/dist/actions/createGetRequestDetails.js +1 -1
  17. package/dist/actions/createGetState.js +1 -1
  18. package/dist/actions/createGetUrlQuery.js +2 -2
  19. package/dist/actions/createGetUser.js +1 -1
  20. package/dist/actions/createLink.js +1 -1
  21. package/dist/actions/createLogin.js +1 -1
  22. package/dist/actions/createLogout.js +1 -1
  23. package/dist/actions/createRequest.js +3 -2
  24. package/dist/actions/createReset.js +1 -1
  25. package/dist/actions/createResetValidation.js +1 -1
  26. package/dist/actions/createSetGlobal.js +1 -1
  27. package/dist/actions/createSetState.js +1 -1
  28. package/dist/actions/createUpdateSession.js +1 -1
  29. package/dist/actions/createValidate.js +4 -4
  30. package/dist/actions/getActionMethods.js +1 -1
  31. package/dist/actions/getFromObject.js +3 -3
  32. package/dist/callAPIHandler.js +1 -1
  33. package/dist/createLink.js +2 -2
  34. package/dist/getBlockMatcher.js +1 -1
  35. package/dist/getContext.js +16 -3
  36. package/dist/index.js +1 -1
  37. package/package.json +8 -7
package/dist/Actions.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -12,9 +12,29 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ import { type } from '@lowdefy/helpers';
15
+ */ import { ActionError, ConfigError, UserError } from '@lowdefy/errors';
16
+ import { type } from '@lowdefy/helpers';
16
17
  import getActionMethods from './actions/getActionMethods.js';
17
18
  let Actions = class Actions {
19
+ logActionError({ error, action }) {
20
+ const handleError = this.context._internal.lowdefy._internal.handleError;
21
+ const actionId = action?.id || '';
22
+ // Deduplicate by error message + action id
23
+ const errorKey = `${error?.message || ''}:${actionId}`;
24
+ if (this.loggedActionErrors.has(errorKey)) {
25
+ return;
26
+ }
27
+ this.loggedActionErrors.add(errorKey);
28
+ // User-facing errors log to browser console only, never to terminal
29
+ if (error instanceof UserError) {
30
+ this.context._internal.lowdefy._internal.logger.error(error);
31
+ return;
32
+ }
33
+ // Lowdefy errors - use handleError (-> terminal)
34
+ if (handleError) {
35
+ handleError(error);
36
+ }
37
+ }
18
38
  async callAsyncAction({ action, arrayIndices, block, event, index, responses }) {
19
39
  try {
20
40
  const response = await this.callAction({
@@ -26,9 +46,10 @@ let Actions = class Actions {
26
46
  responses
27
47
  });
28
48
  responses[action.id] = response;
29
- } catch (error) {
30
- responses[action.id] = error;
31
- console.error(error);
49
+ } catch (err) {
50
+ // err is already {error, action, index} from callAction
51
+ responses[action.id] = err;
52
+ this.logActionError(err);
32
53
  }
33
54
  }
34
55
  async callActionLoop({ actions, arrayIndices, block, event, progress, responses }) {
@@ -56,12 +77,10 @@ let Actions = class Actions {
56
77
  });
57
78
  responses[action.id] = response;
58
79
  }
59
- } catch (error) {
60
- responses[action.id] = error;
61
- throw {
62
- error,
63
- action
64
- };
80
+ } catch (err) {
81
+ // err is already {error, action, index} from callAction
82
+ responses[action.id] = err;
83
+ throw err;
65
84
  }
66
85
  }
67
86
  }
@@ -78,7 +97,7 @@ let Actions = class Actions {
78
97
  progress
79
98
  });
80
99
  } catch (error) {
81
- console.error(error);
100
+ this.logActionError(error);
82
101
  try {
83
102
  await this.callActionLoop({
84
103
  actions: catchActions,
@@ -89,7 +108,7 @@ let Actions = class Actions {
89
108
  progress
90
109
  });
91
110
  } catch (errorCatch) {
92
- console.error(errorCatch);
111
+ this.logActionError(errorCatch);
93
112
  return {
94
113
  blockId: block.blockId,
95
114
  bounced: false,
@@ -128,9 +147,12 @@ let Actions = class Actions {
128
147
  }
129
148
  async callAction({ action, arrayIndices, block, event, index, progress, responses }) {
130
149
  if (!this.actions[action.type]) {
150
+ const error = new ConfigError(`Invalid action type "${action.type}" at "${block.blockId}".`, {
151
+ configKey: action['~k']
152
+ });
131
153
  throw {
132
- error: new Error(`Invalid action type "${action.type}" at "${block.blockId}".`),
133
- type: action.type,
154
+ error,
155
+ action,
134
156
  index
135
157
  };
136
158
  }
@@ -142,9 +164,10 @@ let Actions = class Actions {
142
164
  location: block.blockId
143
165
  });
144
166
  if (parserErrors.length > 0) {
167
+ // Parser errors already have configKey from operator
145
168
  throw {
146
169
  error: parserErrors[0],
147
- type: action.type,
170
+ action,
148
171
  index
149
172
  };
150
173
  }
@@ -167,6 +190,7 @@ let Actions = class Actions {
167
190
  response = await this.actions[action.type]({
168
191
  globals: this.context._internal.lowdefy._internal.globals,
169
192
  methods: getActionMethods({
193
+ actionId: action.id,
170
194
  actions: responses,
171
195
  arrayIndices,
172
196
  blockId: block.blockId,
@@ -178,7 +202,14 @@ let Actions = class Actions {
178
202
  if (progress) {
179
203
  progress();
180
204
  }
181
- } catch (error) {
205
+ } catch (err) {
206
+ const error = err.isLowdefyError ? err : new ActionError(err.message, {
207
+ cause: err,
208
+ typeName: action.type,
209
+ received: parsedAction.params,
210
+ location: block.blockId,
211
+ configKey: action['~k']
212
+ });
182
213
  responses[action.id] = {
183
214
  error,
184
215
  index,
@@ -195,21 +226,21 @@ let Actions = class Actions {
195
226
  // this condition is very unlikely since parser errors usually occur in the first parse.
196
227
  throw {
197
228
  error: parserErrors[0],
198
- type: action.type,
229
+ action,
199
230
  index
200
231
  };
201
232
  }
202
233
  closeLoading();
203
234
  this.displayMessage({
204
- defaultMessage: error.message,
235
+ defaultMessage: err.message,
205
236
  duration: 6,
206
237
  hideExplicitly: true,
207
238
  message: (parsedMessages || {}).error,
208
239
  status: 'error'
209
240
  });
210
241
  throw {
211
- type: action.type,
212
242
  error,
243
+ action,
213
244
  index
214
245
  };
215
246
  }
@@ -242,7 +273,9 @@ let Actions = class Actions {
242
273
  this.callActionLoop = this.callActionLoop.bind(this);
243
274
  this.callActions = this.callActions.bind(this);
244
275
  this.displayMessage = this.displayMessage.bind(this);
276
+ this.logActionError = this.logActionError.bind(this);
245
277
  this.actions = context._internal.lowdefy._internal.actions;
278
+ this.loggedActionErrors = new Set();
246
279
  }
247
280
  };
248
281
  export default Actions;
package/dist/Areas.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-param-reassign */ /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -40,7 +40,9 @@ let Areas = class Areas {
40
40
  _define_property(this, "initAreaBlocks", ()=>{
41
41
  if (type.isObject(this.areas)) {
42
42
  Object.values(this.areas).forEach((area)=>{
43
- const blocks = area.blocks.map((areaBlock)=>new Block(this, areaBlock));
43
+ // Handle areas with no blocks - render as empty
44
+ const blocksConfig = area.blocks ?? [];
45
+ const blocks = blocksConfig.map((areaBlock)=>new Block(this, areaBlock));
44
46
  area.blocks = blocks;
45
47
  });
46
48
  }
package/dist/Block.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import { applyArrayIndices, get, serializer, swap, type } from '@lowdefy/helpers
29
29
  import Events from './Events.js';
30
30
  import Areas from './Areas.js';
31
31
  let Block = class Block {
32
- constructor({ context, arrayIndices }, { id, blockId, events, layout, loading, properties, required, skeleton, style, validate, visible, type: blockType, areas }){
32
+ constructor({ context, arrayIndices }, blockConfig){
33
33
  _define_property(this, "_initInput", ()=>{
34
34
  this.setValue = (value)=>{
35
35
  this.value = type.enforceType(this.meta.valueType, value);
@@ -356,9 +356,22 @@ let Block = class Block {
356
356
  _define_property(this, "render", ()=>{
357
357
  if (!this.update) return;
358
358
  this.update = false;
359
+ // Collect parse errors from all eval results
360
+ const parseErrors = [
361
+ ...this.propertiesEval.errors || [],
362
+ ...this.styleEval.errors || [],
363
+ ...this.layoutEval.errors || [],
364
+ ...this.visibleEval.errors || [],
365
+ ...this.loadingEval.errors || [],
366
+ ...this.requiredEval.errors || [],
367
+ ...this.skeletonEval.errors || [],
368
+ ...this.areasLayoutEval.errors || []
369
+ ];
359
370
  this.eval = {
360
371
  areas: this.areasLayoutEval.output,
372
+ configKey: this.configKey,
361
373
  events: type.isNone(this.Events.events) ? null : this.Events.events,
374
+ parseErrors: parseErrors.length > 0 ? parseErrors : null,
362
375
  properties: this.propertiesEval.output,
363
376
  loading: this.loadingEval.output,
364
377
  skeleton: this.skeletonEval.output,
@@ -374,8 +387,10 @@ let Block = class Block {
374
387
  };
375
388
  this.context._internal.lowdefy._internal.updateBlock(this.id);
376
389
  });
390
+ const { id, blockId, events, layout, loading, properties, required, skeleton, style, validate, visible, type: blockType, areas } = blockConfig;
377
391
  this.context = context;
378
392
  this.arrayIndices = arrayIndices;
393
+ this.configKey = blockConfig['~k'];
379
394
  this.idPattern = id;
380
395
  this.blockIdPattern = blockId;
381
396
  this.id = applyArrayIndices(this.arrayIndices, this.idPattern);
@@ -403,7 +418,9 @@ let Block = class Block {
403
418
  try {
404
419
  this.meta = this.context._internal.lowdefy._internal.blockComponents[this.type].meta;
405
420
  } catch (error) {
406
- throw new Error(`Block type ${this.type} not found at ${this.blockId}. Check your plugins to make sure the block is installed. For more info, see https://docs.lowdefy.com/plugins.`);
421
+ throw new Error(`Block type ${this.type} not found at ${this.blockId}. Check your plugins to make sure the block is installed. For more info, see https://docs.lowdefy.com/plugins.`, {
422
+ cause: error
423
+ });
407
424
  }
408
425
  if (!this.isContainer() && !this.isDisplay() && !this.isInput() && !this.isList()) {
409
426
  throw new Error(`Block type ${this.type}.meta.category must be either "container", "display", "input", "list", or "input-container".`);
package/dist/Events.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/dist/Requests.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -14,9 +14,10 @@
14
14
  limitations under the License.
15
15
  */ import { get, serializer, type } from '@lowdefy/helpers';
16
16
  let Requests = class Requests {
17
- callRequests({ actions, arrayIndices, blockId, event, params } = {}) {
17
+ callRequests({ actionId, actions, arrayIndices, blockId, event, params } = {}) {
18
18
  if (type.isObject(params) && params.all === true) {
19
19
  return Promise.all(Object.keys(this.requestConfig).map((requestId)=>this.callRequest({
20
+ actionId,
20
21
  arrayIndices,
21
22
  blockId,
22
23
  event,
@@ -29,6 +30,7 @@ let Requests = class Requests {
29
30
  ];
30
31
  if (type.isArray(params)) requestIds = params;
31
32
  const requests = requestIds.map((requestId)=>this.callRequest({
33
+ actionId,
32
34
  actions,
33
35
  requestId,
34
36
  blockId,
@@ -38,7 +40,7 @@ let Requests = class Requests {
38
40
  this.context._internal.update(); // update to render request reset
39
41
  return Promise.all(requests);
40
42
  }
41
- async callRequest({ actions, arrayIndices, blockId, event, requestId }) {
43
+ async callRequest({ actionId, actions, arrayIndices, blockId, event, requestId }) {
42
44
  const requestConfig = this.requestConfig[requestId];
43
45
  if (!this.context.requests[requestId]) {
44
46
  this.context.requests[requestId] = [];
@@ -66,6 +68,7 @@ let Requests = class Requests {
66
68
  throw parserErrors[0];
67
69
  }
68
70
  const request = {
71
+ actionId,
69
72
  blockId,
70
73
  loading: true,
71
74
  payload,
@@ -80,6 +83,7 @@ let Requests = class Requests {
80
83
  const startTime = Date.now();
81
84
  try {
82
85
  const response = await this.context._internal.lowdefy._internal.callRequest({
86
+ actionId: request.actionId,
83
87
  blockId: request.blockId,
84
88
  pageId: this.context.pageId,
85
89
  payload: serializer.serialize(request.payload),
package/dist/State.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -18,10 +18,10 @@ function createCallMethod({ arrayIndices, context }) {
18
18
  const { blockId, method, args = [] } = params;
19
19
  const blockMethod = context._internal.RootAreas.map[applyArrayIndices(arrayIndices, blockId)].methods[method];
20
20
  if (!type.isArray(args)) {
21
- throw new Error(`Failed to call method "${method}" on block "${blockId}": "args" should be an array. Received "${JSON.stringify(params)}".`);
21
+ throw new Error(`Failed to call method "${method}" on block "${blockId}": "args" should be an array.`);
22
22
  }
23
23
  if (!type.isFunction(blockMethod)) {
24
- throw new Error(`Failed to call method "${method}" on block "${blockId}". Check if "${method}" is a valid block method for block "${blockId}". Received "${JSON.stringify(params)}".`);
24
+ throw new Error(`Failed to call method "${method}" on block "${blockId}". Check if "${method}" is a valid block method for block "${blockId}".`);
25
25
  }
26
26
  return blockMethod(...args);
27
27
  };
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ function createGetUrlQuery({ arrayIndices, blockId, context }) {
18
18
  return function getUrlQuery(params) {
19
19
  const { window } = context._internal.lowdefy._internal.globals;
20
20
  if (!window?.location) {
21
- throw new Error(`Browser window.location not available for getUrlQuery. Received: ${JSON.stringify(params)} on blockId: ${blockId}.`);
21
+ throw new Error(`Browser window.location not available for getUrlQuery on blockId: ${blockId}.`);
22
22
  }
23
23
  return getFromObject({
24
24
  arrayIndices,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -12,9 +12,10 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ function createRequest({ actions, arrayIndices, blockId, context, event }) {
15
+ */ function createRequest({ actionId, actions, arrayIndices, blockId, context, event }) {
16
16
  return function request(params) {
17
17
  return context._internal.Requests.callRequests({
18
+ actionId,
18
19
  actions,
19
20
  arrayIndices,
20
21
  blockId,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -12,13 +12,13 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ import getBlockMatcher from '../getBlockMatcher.js';
15
+ */ import { UserError } from '@lowdefy/errors';
16
+ import getBlockMatcher from '../getBlockMatcher.js';
16
17
  function createValidate({ context }) {
17
18
  return function validate(params) {
18
19
  const validationErrors = context._internal.RootAreas.validate(getBlockMatcher(params));
19
20
  if (validationErrors.length > 0) {
20
- const error = new Error(`Your input has ${validationErrors.length} validation error${validationErrors.length !== 1 ? 's' : ''}.`);
21
- throw error;
21
+ throw new UserError(`Your input has ${validationErrors.length} validation error${validationErrors.length !== 1 ? 's' : ''}.`);
22
22
  }
23
23
  };
24
24
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ const getFromObject = ({ arrayIndices, location, method, object, params })=>{
21
21
  key: params
22
22
  };
23
23
  if (!type.isObject(params)) {
24
- throw new Error(`Method Error: ${method} params must be of type string, integer, boolean or object. Received: ${JSON.stringify(params)} at ${location}.`);
24
+ throw new Error(`Method Error: ${method} params must be of type string, integer, boolean or object at ${location}.`);
25
25
  }
26
26
  if (params.key === null) return get(params, 'default', {
27
27
  default: null,
@@ -29,7 +29,7 @@ const getFromObject = ({ arrayIndices, location, method, object, params })=>{
29
29
  });
30
30
  if (params.all === true) return serializer.copy(object);
31
31
  if (!type.isString(params.key) && !type.isInt(params.key)) {
32
- throw new Error(`Method Error: ${method} params.key must be of type string or integer. Received: ${JSON.stringify(params)} at ${location}.`);
32
+ throw new Error(`Method Error: ${method} params.key must be of type string or integer at ${location}.`);
33
33
  }
34
34
  return get(object, applyArrayIndices(arrayIndices, params.key), {
35
35
  default: get(params, 'default', {
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ function createLink({ backLink, disabledLink, lowdefy, newOriginLink, noLink, sa
25
25
  !props.href,
26
26
  !props.url
27
27
  ].filter((v)=>!v).length > 1) {
28
- throw Error(`Invalid Link: To avoid ambiguity, only one of 'back', 'home', 'href', 'pageId' or 'url' can be defined.`);
28
+ throw new Error(`Invalid Link: To avoid ambiguity, only one of 'back', 'home', 'href', 'pageId' or 'url' can be defined.`);
29
29
  }
30
30
  if (props.back === true) {
31
31
  // Cannot set input or urlQuery on back
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -17,7 +17,9 @@ import Actions from './Actions.js';
17
17
  import Areas from './Areas.js';
18
18
  import Requests from './Requests.js';
19
19
  import State from './State.js';
20
- const blockData = ({ areas, blockId, blocks, events, field, id, layout, pageId, properties, requests, required, style, type, validate, visible })=>({
20
+ const blockData = (config)=>{
21
+ const { areas, blockId, blocks, events, field, id, layout, pageId, properties, requests, required, style, type, validate, visible } = config;
22
+ const result = {
21
23
  areas,
22
24
  blockId,
23
25
  blocks,
@@ -33,7 +35,18 @@ const blockData = ({ areas, blockId, blocks, events, field, id, layout, pageId,
33
35
  type,
34
36
  validate,
35
37
  visible
36
- });
38
+ };
39
+ // Preserve ~k (configKey) for error tracing - it's non-enumerable so must be copied explicitly
40
+ if (config['~k']) {
41
+ Object.defineProperty(result, '~k', {
42
+ value: config['~k'],
43
+ enumerable: false,
44
+ writable: true,
45
+ configurable: true
46
+ });
47
+ }
48
+ return result;
49
+ };
37
50
  function getContext({ config, jsMap = {}, lowdefy, resetContext = {
38
51
  reset: false,
39
52
  setReset: ()=>undefined
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2024 Lowdefy, Inc
2
+ Copyright 2020-2026 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/engine",
3
- "version": "4.5.1",
3
+ "version": "4.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -30,15 +30,16 @@
30
30
  "dist/*"
31
31
  ],
32
32
  "dependencies": {
33
- "@lowdefy/helpers": "4.5.1",
34
- "@lowdefy/operators": "4.5.1"
33
+ "@lowdefy/errors": "4.6.0",
34
+ "@lowdefy/helpers": "4.6.0",
35
+ "@lowdefy/operators": "4.6.0"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@jest/globals": "28.1.3",
38
- "@lowdefy/actions-core": "4.5.1",
39
- "@lowdefy/build": "4.5.1",
40
- "@lowdefy/operators-js": "4.5.1",
41
- "@lowdefy/operators-mql": "4.5.1",
39
+ "@lowdefy/actions-core": "4.6.0",
40
+ "@lowdefy/build": "4.6.0",
41
+ "@lowdefy/operators-js": "4.6.0",
42
+ "@lowdefy/operators-mql": "4.6.0",
42
43
  "@swc/cli": "0.1.63",
43
44
  "@swc/core": "1.3.99",
44
45
  "@swc/jest": "0.2.29",