@nocobase/flow-engine 2.1.0-beta.9 → 2.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/lib/FlowContextProvider.d.ts +5 -1
  2. package/lib/FlowContextProvider.js +9 -2
  3. package/lib/components/FieldModelRenderer.js +2 -2
  4. package/lib/components/FlowModelRenderer.d.ts +3 -1
  5. package/lib/components/FlowModelRenderer.js +12 -6
  6. package/lib/components/FormItem.d.ts +6 -0
  7. package/lib/components/FormItem.js +11 -3
  8. package/lib/components/MobilePopup.js +6 -5
  9. package/lib/components/dnd/gridDragPlanner.d.ts +59 -2
  10. package/lib/components/dnd/gridDragPlanner.js +607 -19
  11. package/lib/components/dnd/index.d.ts +31 -2
  12. package/lib/components/dnd/index.js +244 -23
  13. package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +2 -1
  14. package/lib/components/settings/wrappers/component/SelectWithTitle.js +14 -12
  15. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +3 -0
  16. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +152 -42
  17. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +23 -43
  18. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +352 -295
  19. package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.d.ts +36 -0
  20. package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +274 -0
  21. package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.d.ts +30 -0
  22. package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +315 -0
  23. package/lib/components/subModel/AddSubModelButton.js +12 -1
  24. package/lib/components/subModel/LazyDropdown.js +301 -52
  25. package/lib/components/subModel/index.d.ts +1 -0
  26. package/lib/components/subModel/index.js +19 -0
  27. package/lib/components/subModel/utils.d.ts +2 -1
  28. package/lib/components/subModel/utils.js +15 -5
  29. package/lib/components/variables/VariableHybridInput.d.ts +27 -0
  30. package/lib/components/variables/VariableHybridInput.js +499 -0
  31. package/lib/components/variables/index.d.ts +2 -0
  32. package/lib/components/variables/index.js +3 -0
  33. package/lib/data-source/index.d.ts +84 -0
  34. package/lib/data-source/index.js +269 -7
  35. package/lib/executor/FlowExecutor.js +6 -3
  36. package/lib/flow-registry/DetachedFlowRegistry.d.ts +21 -0
  37. package/lib/flow-registry/DetachedFlowRegistry.js +80 -0
  38. package/lib/flow-registry/index.d.ts +1 -0
  39. package/lib/flow-registry/index.js +3 -1
  40. package/lib/flowContext.d.ts +9 -1
  41. package/lib/flowContext.js +77 -6
  42. package/lib/flowEngine.d.ts +136 -4
  43. package/lib/flowEngine.js +429 -51
  44. package/lib/flowI18n.js +2 -1
  45. package/lib/flowSettings.d.ts +14 -6
  46. package/lib/flowSettings.js +34 -6
  47. package/lib/index.d.ts +2 -0
  48. package/lib/index.js +7 -0
  49. package/lib/lazy-helper.d.ts +14 -0
  50. package/lib/lazy-helper.js +71 -0
  51. package/lib/locale/en-US.json +1 -0
  52. package/lib/locale/index.d.ts +2 -0
  53. package/lib/locale/zh-CN.json +1 -0
  54. package/lib/models/DisplayItemModel.d.ts +1 -1
  55. package/lib/models/EditableItemModel.d.ts +1 -1
  56. package/lib/models/FilterableItemModel.d.ts +1 -1
  57. package/lib/models/flowModel.d.ts +13 -10
  58. package/lib/models/flowModel.js +126 -34
  59. package/lib/provider.js +38 -23
  60. package/lib/reactive/observer.js +46 -16
  61. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +4 -3
  62. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +4 -15
  63. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +5 -2
  64. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +5 -8
  65. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +4 -3
  66. package/lib/runjs-context/contexts/JSItemRunJSContext.js +4 -3
  67. package/lib/runjs-context/contexts/base.js +464 -29
  68. package/lib/runjs-context/contexts/elementDoc.d.ts +11 -0
  69. package/lib/runjs-context/contexts/elementDoc.js +152 -0
  70. package/lib/runjs-context/setup.js +1 -0
  71. package/lib/runjs-context/snippets/index.js +13 -2
  72. package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.d.ts +11 -0
  73. package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.js +50 -0
  74. package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.d.ts +11 -0
  75. package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.js +54 -0
  76. package/lib/types.d.ts +50 -2
  77. package/lib/types.js +1 -0
  78. package/lib/utils/createCollectionContextMeta.js +6 -2
  79. package/lib/utils/index.d.ts +3 -2
  80. package/lib/utils/index.js +7 -0
  81. package/lib/utils/loadedPageCache.d.ts +24 -0
  82. package/lib/utils/loadedPageCache.js +139 -0
  83. package/lib/utils/parsePathnameToViewParams.d.ts +5 -1
  84. package/lib/utils/parsePathnameToViewParams.js +28 -4
  85. package/lib/utils/randomId.d.ts +39 -0
  86. package/lib/utils/randomId.js +45 -0
  87. package/lib/utils/runjsTemplateCompat.js +1 -1
  88. package/lib/utils/runjsValue.js +41 -11
  89. package/lib/utils/schema-utils.d.ts +7 -1
  90. package/lib/utils/schema-utils.js +19 -0
  91. package/lib/views/FlowView.d.ts +7 -1
  92. package/lib/views/FlowView.js +11 -1
  93. package/lib/views/PageComponent.js +8 -6
  94. package/lib/views/ViewNavigation.d.ts +12 -2
  95. package/lib/views/ViewNavigation.js +28 -9
  96. package/lib/views/createViewMeta.js +114 -50
  97. package/lib/views/inheritLayoutContext.d.ts +10 -0
  98. package/lib/views/inheritLayoutContext.js +50 -0
  99. package/lib/views/runViewBeforeClose.d.ts +10 -0
  100. package/lib/views/runViewBeforeClose.js +45 -0
  101. package/lib/views/useDialog.d.ts +2 -1
  102. package/lib/views/useDialog.js +12 -3
  103. package/lib/views/useDrawer.d.ts +2 -1
  104. package/lib/views/useDrawer.js +12 -3
  105. package/lib/views/usePage.d.ts +5 -11
  106. package/lib/views/usePage.js +304 -144
  107. package/package.json +5 -4
  108. package/src/FlowContextProvider.tsx +9 -1
  109. package/src/__tests__/createViewMeta.popup.test.ts +115 -1
  110. package/src/__tests__/flow-engine.test.ts +166 -0
  111. package/src/__tests__/flowContext.test.ts +105 -1
  112. package/src/__tests__/flowEngine.modelLoaders.test.ts +245 -0
  113. package/src/__tests__/flowEngine.moveModel.test.ts +81 -1
  114. package/src/__tests__/flowEngine.removeModel.test.ts +47 -3
  115. package/src/__tests__/flowSettings.test.ts +94 -15
  116. package/src/__tests__/objectVariable.test.ts +24 -0
  117. package/src/__tests__/provider.test.tsx +24 -2
  118. package/src/__tests__/renderHiddenInConfig.test.tsx +6 -6
  119. package/src/__tests__/runjsContext.test.ts +21 -0
  120. package/src/__tests__/runjsContextImplementations.test.ts +9 -2
  121. package/src/__tests__/runjsContextRuntime.test.ts +2 -0
  122. package/src/__tests__/runjsLocales.test.ts +6 -5
  123. package/src/__tests__/runjsSnippets.test.ts +21 -0
  124. package/src/__tests__/viewScopedFlowEngine.test.ts +136 -3
  125. package/src/components/FieldModelRenderer.tsx +2 -1
  126. package/src/components/FlowModelRenderer.tsx +18 -6
  127. package/src/components/FormItem.tsx +7 -1
  128. package/src/components/MobilePopup.tsx +4 -2
  129. package/src/components/__tests__/FlowModelRenderer.test.tsx +65 -2
  130. package/src/components/__tests__/FormItem.test.tsx +25 -0
  131. package/src/components/__tests__/dnd.test.ts +44 -0
  132. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +20 -10
  133. package/src/components/__tests__/gridDragPlanner.test.ts +472 -5
  134. package/src/components/dnd/__tests__/DndProvider.test.tsx +98 -0
  135. package/src/components/dnd/gridDragPlanner.ts +750 -17
  136. package/src/components/dnd/index.tsx +305 -28
  137. package/src/components/settings/wrappers/component/SelectWithTitle.tsx +21 -9
  138. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +178 -48
  139. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +487 -440
  140. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +344 -8
  141. package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +778 -0
  142. package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +360 -0
  143. package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +361 -0
  144. package/src/components/subModel/AddSubModelButton.tsx +16 -2
  145. package/src/components/subModel/LazyDropdown.tsx +341 -56
  146. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +524 -38
  147. package/src/components/subModel/__tests__/utils.test.ts +24 -0
  148. package/src/components/subModel/index.ts +1 -0
  149. package/src/components/subModel/utils.ts +13 -2
  150. package/src/components/variables/VariableHybridInput.tsx +531 -0
  151. package/src/components/variables/index.ts +2 -0
  152. package/src/data-source/__tests__/collection.test.ts +41 -2
  153. package/src/data-source/__tests__/index.test.ts +69 -2
  154. package/src/data-source/index.ts +332 -8
  155. package/src/executor/FlowExecutor.ts +6 -3
  156. package/src/executor/__tests__/flowExecutor.test.ts +57 -0
  157. package/src/flow-registry/DetachedFlowRegistry.ts +46 -0
  158. package/src/flow-registry/__tests__/detachedFlowRegistry.test.ts +47 -0
  159. package/src/flow-registry/index.ts +1 -0
  160. package/src/flowContext.ts +85 -6
  161. package/src/flowEngine.ts +484 -45
  162. package/src/flowI18n.ts +2 -1
  163. package/src/flowSettings.ts +40 -6
  164. package/src/index.ts +2 -0
  165. package/src/lazy-helper.tsx +57 -0
  166. package/src/locale/en-US.json +1 -0
  167. package/src/locale/zh-CN.json +1 -0
  168. package/src/models/DisplayItemModel.tsx +1 -1
  169. package/src/models/EditableItemModel.tsx +1 -1
  170. package/src/models/FilterableItemModel.tsx +1 -1
  171. package/src/models/__tests__/flowEngine.resolveUse.test.ts +0 -15
  172. package/src/models/__tests__/flowModel.test.ts +65 -37
  173. package/src/models/flowModel.tsx +184 -65
  174. package/src/provider.tsx +41 -25
  175. package/src/reactive/__tests__/observer.test.tsx +82 -0
  176. package/src/reactive/observer.tsx +87 -25
  177. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +4 -3
  178. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +4 -15
  179. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +4 -2
  180. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +5 -9
  181. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +4 -3
  182. package/src/runjs-context/contexts/JSItemRunJSContext.ts +4 -3
  183. package/src/runjs-context/contexts/base.ts +467 -31
  184. package/src/runjs-context/contexts/elementDoc.ts +130 -0
  185. package/src/runjs-context/setup.ts +1 -0
  186. package/src/runjs-context/snippets/index.ts +12 -1
  187. package/src/runjs-context/snippets/scene/detail/set-field-style.snippet.ts +30 -0
  188. package/src/runjs-context/snippets/scene/table/set-cell-style.snippet.ts +34 -0
  189. package/src/types.ts +62 -0
  190. package/src/utils/__tests__/createCollectionContextMeta.test.ts +48 -0
  191. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +21 -0
  192. package/src/utils/__tests__/runjsValue.test.ts +11 -0
  193. package/src/utils/__tests__/utils.test.ts +62 -0
  194. package/src/utils/createCollectionContextMeta.ts +6 -2
  195. package/src/utils/index.ts +5 -1
  196. package/src/utils/loadedPageCache.ts +147 -0
  197. package/src/utils/parsePathnameToViewParams.ts +45 -5
  198. package/src/utils/randomId.ts +48 -0
  199. package/src/utils/runjsTemplateCompat.ts +1 -1
  200. package/src/utils/runjsValue.ts +50 -11
  201. package/src/utils/schema-utils.ts +30 -1
  202. package/src/views/FlowView.tsx +22 -2
  203. package/src/views/PageComponent.tsx +7 -4
  204. package/src/views/ViewNavigation.ts +46 -9
  205. package/src/views/__tests__/FlowView.usePage.test.tsx +243 -3
  206. package/src/views/__tests__/ViewNavigation.test.ts +52 -0
  207. package/src/views/__tests__/inheritLayoutContext.test.ts +53 -0
  208. package/src/views/__tests__/runViewBeforeClose.test.ts +30 -0
  209. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +12 -12
  210. package/src/views/createViewMeta.ts +106 -34
  211. package/src/views/inheritLayoutContext.ts +26 -0
  212. package/src/views/runViewBeforeClose.ts +19 -0
  213. package/src/views/useDialog.tsx +13 -3
  214. package/src/views/useDrawer.tsx +13 -3
  215. package/src/views/usePage.tsx +367 -180
@@ -13,7 +13,42 @@ export function defineBaseContextMeta() {
13
13
  FlowRunJSContext.define({
14
14
  label: 'RunJS base',
15
15
  properties: {
16
- logger: 'Pino logger instance for structured logging. Example: `ctx.logger.info({ foo: 1 }, "message")`',
16
+ logger: {
17
+ description: 'Pino logger instance for structured logging. Example: `ctx.logger.info({ foo: 1 }, "message")`',
18
+ detail: 'Logger',
19
+ properties: {
20
+ info: {
21
+ type: 'function',
22
+ description: 'Write an info-level log.',
23
+ detail: '(...args: any[]) => void',
24
+ completion: { insertText: `ctx.logger.info({ foo: 1 }, 'message')` },
25
+ },
26
+ warn: {
27
+ type: 'function',
28
+ description: 'Write a warn-level log.',
29
+ detail: '(...args: any[]) => void',
30
+ completion: { insertText: `ctx.logger.warn({ foo: 1 }, 'message')` },
31
+ },
32
+ error: {
33
+ type: 'function',
34
+ description: 'Write an error-level log.',
35
+ detail: '(...args: any[]) => void',
36
+ completion: { insertText: `ctx.logger.error({ err }, 'message')` },
37
+ },
38
+ debug: {
39
+ type: 'function',
40
+ description: 'Write a debug-level log.',
41
+ detail: '(...args: any[]) => void',
42
+ completion: { insertText: `ctx.logger.debug({ foo: 1 }, 'message')` },
43
+ },
44
+ child: {
45
+ type: 'function',
46
+ description: 'Create a child logger with bindings.',
47
+ detail: '(bindings: object) => Logger',
48
+ completion: { insertText: `ctx.logger.child({ module: 'runjs' })` },
49
+ },
50
+ },
51
+ },
17
52
  message: {
18
53
  description: 'Ant Design global message API for displaying temporary messages.',
19
54
  detail: 'MessageInstance',
@@ -241,12 +276,18 @@ export function defineBaseContextMeta() {
241
276
  popover: {
242
277
  description: 'Open a popover view. Parameters: (props: PopoverProps) => any',
243
278
  detail: '(props) => any',
244
- completion: { insertText: 'await ctx.viewer.popover({ target: ctx.element?.__el, content: <div /> })' },
279
+ completion: {
280
+ insertText: 'await ctx.viewer.popover({ target: ctx.element?.__el, content: <div /> })',
281
+ requires: ['element'],
282
+ },
245
283
  },
246
284
  embed: {
247
285
  description: 'Open an embed view. Parameters: (props: ViewProps & TargetProps) => any',
248
286
  detail: '(props) => any',
249
- completion: { insertText: 'await ctx.viewer.embed({ target: document.body, content: <div /> })' },
287
+ completion: {
288
+ insertText: 'await ctx.viewer.embed({ target: ctx.element?.__el, content: <div /> })',
289
+ requires: ['element'],
290
+ },
250
291
  },
251
292
  },
252
293
  },
@@ -293,16 +334,165 @@ export function defineBaseContextMeta() {
293
334
  language: 'Current active language code.',
294
335
  },
295
336
  },
337
+ sql: {
338
+ description: 'SQL helper (FlowSQLRepository).',
339
+ detail: 'FlowSQLRepository',
340
+ properties: {
341
+ run: {
342
+ type: 'function',
343
+ description: 'Run ad-hoc SQL with optional bind/result options.',
344
+ detail: '(sql: string, options?: SQLRunOptions) => Promise<any>',
345
+ completion: { insertText: `await ctx.sql.run('SELECT 1', { type: 'selectRows' })` },
346
+ },
347
+ save: {
348
+ type: 'function',
349
+ description: 'Save a SQL template.',
350
+ detail: '(data: { uid: string; sql: string; dataSourceKey?: string }) => Promise<void>',
351
+ completion: { insertText: `await ctx.sql.save({ uid: 'sql-uid', sql: 'SELECT 1' })` },
352
+ },
353
+ runById: {
354
+ type: 'function',
355
+ description: 'Run a saved SQL template by uid.',
356
+ detail: '(uid: string, options?: SQLRunOptions) => Promise<any>',
357
+ completion: { insertText: `await ctx.sql.runById('sql-uid', { type: 'selectRows' })` },
358
+ },
359
+ destroy: {
360
+ type: 'function',
361
+ description: 'Delete a saved SQL template by uid.',
362
+ detail: '(uid: string) => Promise<void>',
363
+ completion: { insertText: `await ctx.sql.destroy('sql-uid')` },
364
+ },
365
+ },
366
+ },
296
367
  libs: {
297
368
  properties: {
298
- React: 'React namespace (same as ctx.React).',
299
- ReactDOM: 'ReactDOM client API (same as ctx.ReactDOM).',
300
- antd: 'Ant Design component library (same as ctx.antd).',
301
- dayjs: 'dayjs date-time utility library.',
369
+ React: {
370
+ description: 'React namespace (same as ctx.React).',
371
+ properties: {
372
+ createElement: {
373
+ type: 'function',
374
+ description: 'Create a React element.',
375
+ detail: 'React.createElement',
376
+ completion: { insertText: `ctx.libs.React.createElement('div', null, 'Hello')` },
377
+ },
378
+ useState: {
379
+ type: 'function',
380
+ description: 'React state hook.',
381
+ detail: 'React.useState',
382
+ completion: { insertText: 'ctx.libs.React.useState(initialValue)' },
383
+ },
384
+ useEffect: {
385
+ type: 'function',
386
+ description: 'React effect hook.',
387
+ detail: 'React.useEffect',
388
+ completion: { insertText: 'ctx.libs.React.useEffect(() => {}, [])' },
389
+ },
390
+ useMemo: {
391
+ type: 'function',
392
+ description: 'React memo hook.',
393
+ detail: 'React.useMemo',
394
+ completion: { insertText: 'ctx.libs.React.useMemo(() => value, [])' },
395
+ },
396
+ useCallback: {
397
+ type: 'function',
398
+ description: 'React callback hook.',
399
+ detail: 'React.useCallback',
400
+ completion: { insertText: 'ctx.libs.React.useCallback(() => {}, [])' },
401
+ },
402
+ },
403
+ },
404
+ ReactDOM: {
405
+ description: 'ReactDOM client API (same as ctx.ReactDOM).',
406
+ properties: {
407
+ createRoot: {
408
+ type: 'function',
409
+ description: 'Create a React root.',
410
+ detail: 'ReactDOM.createRoot',
411
+ completion: { insertText: 'ctx.libs.ReactDOM.createRoot(ctx.element.__el)', requires: ['element'] },
412
+ },
413
+ },
414
+ },
415
+ antd: {
416
+ description: 'Ant Design component library (same as ctx.antd).',
417
+ properties: {
418
+ Button: 'Ant Design Button component.',
419
+ Table: 'Ant Design Table component.',
420
+ Form: 'Ant Design Form component.',
421
+ Input: 'Ant Design Input component.',
422
+ Select: 'Ant Design Select component.',
423
+ Modal: 'Ant Design Modal API/component.',
424
+ },
425
+ },
426
+ dayjs: {
427
+ type: 'function',
428
+ description: 'dayjs date-time utility library.',
429
+ detail: 'dayjs',
430
+ completion: { insertText: 'ctx.libs.dayjs()' },
431
+ },
302
432
  antdIcons: 'Ant Design icons library. Example: `ctx.libs.antdIcons.PlusOutlined`.',
303
- lodash: 'Lodash utility library. Example: `ctx.libs.lodash.get(obj, "a.b")`.',
304
- formula: 'Formula.js library (spreadsheet-like functions). Example: `ctx.libs.formula.SUM(1, 2, 3)`.',
305
- math: 'mathjs library. Example: `ctx.libs.math.evaluate("2 + 3")`.',
433
+ lodash: {
434
+ description: 'Lodash utility library. Example: `ctx.libs.lodash.get(obj, "a.b")`.',
435
+ properties: {
436
+ get: {
437
+ type: 'function',
438
+ description: 'Read a nested value by path.',
439
+ detail: 'lodash.get',
440
+ completion: { insertText: `ctx.libs.lodash.get(obj, 'a.b')` },
441
+ },
442
+ set: {
443
+ type: 'function',
444
+ description: 'Set a nested value by path.',
445
+ detail: 'lodash.set',
446
+ completion: { insertText: `ctx.libs.lodash.set(obj, 'a.b', value)` },
447
+ },
448
+ debounce: {
449
+ type: 'function',
450
+ description: 'Create a debounced function.',
451
+ detail: 'lodash.debounce',
452
+ completion: { insertText: 'ctx.libs.lodash.debounce(() => {}, 300)' },
453
+ },
454
+ cloneDeep: {
455
+ type: 'function',
456
+ description: 'Deep clone a value.',
457
+ detail: 'lodash.cloneDeep',
458
+ completion: { insertText: 'ctx.libs.lodash.cloneDeep(value)' },
459
+ },
460
+ },
461
+ },
462
+ formula: {
463
+ description: 'Formula.js library (spreadsheet-like functions). Example: `ctx.libs.formula.SUM(1, 2, 3)`.',
464
+ properties: {
465
+ SUM: {
466
+ type: 'function',
467
+ description: 'Sum values.',
468
+ detail: 'formula.SUM',
469
+ completion: { insertText: 'ctx.libs.formula.SUM(1, 2, 3)' },
470
+ },
471
+ AVERAGE: {
472
+ type: 'function',
473
+ description: 'Average values.',
474
+ detail: 'formula.AVERAGE',
475
+ completion: { insertText: 'ctx.libs.formula.AVERAGE(1, 2, 3)' },
476
+ },
477
+ },
478
+ },
479
+ math: {
480
+ description: 'mathjs library. Example: `ctx.libs.math.evaluate("2 + 3")`.',
481
+ properties: {
482
+ evaluate: {
483
+ type: 'function',
484
+ description: 'Evaluate a math expression.',
485
+ detail: 'math.evaluate',
486
+ completion: { insertText: `ctx.libs.math.evaluate('2 + 3')` },
487
+ },
488
+ round: {
489
+ type: 'function',
490
+ description: 'Round a number.',
491
+ detail: 'math.round',
492
+ completion: { insertText: 'ctx.libs.math.round(value, 2)' },
493
+ },
494
+ },
495
+ },
306
496
  },
307
497
  },
308
498
  },
@@ -333,7 +523,13 @@ export function defineBaseContextMeta() {
333
523
  returns: { type: 'FlowModel | undefined' },
334
524
  examples: ["const model = ctx.getModel('block-uid-xxx');"],
335
525
  },
336
- t: 'Internationalization function for translating text. Parameters: (key: string, variables?: object) => string. Example: `ctx.t("Hello {{name}}", { name: "World" })`',
526
+ t: {
527
+ description:
528
+ 'Internationalization function for translating text. Parameters: (key: string, variables?: object) => string.',
529
+ detail: '(key: string, variables?: object) => string',
530
+ completion: { insertText: `ctx.t('Hello')` },
531
+ examples: [`ctx.t("Hello {{name}}", { name: "World" })`],
532
+ },
337
533
  initResource: {
338
534
  description:
339
535
  'Initialize ctx.resource as a FlowResource instance by class name. Common values: "MultiRecordResource", "SingleRecordResource", "SQLResource".',
@@ -354,12 +550,35 @@ export function defineBaseContextMeta() {
354
550
  detail: 'ReactDOM Root',
355
551
  completion: {
356
552
  insertText: `ctx.render(<div />)`,
553
+ requires: ['element'],
357
554
  },
358
555
  },
359
- requireAsync:
360
- 'Load UMD/AMD/global scripts or CSS asynchronously from URL. Accepts shorthand like "echarts@5/dist/echarts.min.js" (resolved via ESM CDN with ?raw) or full URLs, and returns a Promise of the loaded library.',
361
- importAsync:
362
- 'Dynamically import ESM modules or CSS by URL. Accepts shorthand like "vue@3.4.0" or "dayjs@1/plugin/relativeTime.js" (resolved via configured ESM CDN) or full URLs, and returns a Promise of the module namespace.',
556
+ requireAsync: {
557
+ description:
558
+ 'Load UMD/AMD/global scripts or CSS asynchronously from URL. Accepts shorthand like "echarts@5/dist/echarts.min.js" (resolved via ESM CDN with ?raw) or full URLs, and returns a Promise of the loaded library.',
559
+ detail: '(url: string) => Promise<any>',
560
+ completion: { insertText: `const lib = await ctx.requireAsync('https://cdn.example.com/lib.umd.js')` },
561
+ },
562
+ importAsync: {
563
+ description:
564
+ 'Dynamically import ESM modules or CSS by URL. Accepts shorthand like "vue@3.4.0" or "dayjs@1/plugin/relativeTime.js" (resolved via configured ESM CDN) or full URLs, and returns a Promise of the module namespace.',
565
+ detail: '(url: string) => Promise<any>',
566
+ completion: { insertText: `const mod = await ctx.importAsync('lodash-es')` },
567
+ },
568
+ resolveJsonTemplate: {
569
+ description: 'Resolve a JSON template containing {{ }} variable expressions.',
570
+ detail: '(template: any) => Promise<any>',
571
+ params: [
572
+ {
573
+ name: 'template',
574
+ type: 'any',
575
+ description: 'JSON-compatible value containing {{ ctx.* }} expressions.',
576
+ },
577
+ ],
578
+ returns: { type: 'Promise<any>' },
579
+ completion: { insertText: `await ctx.resolveJsonTemplate({ value: '{{ctx.record.id}}' })` },
580
+ examples: ["const data = await ctx.resolveJsonTemplate({ id: '{{ctx.record.id}}' });"],
581
+ },
363
582
  getVar: {
364
583
  description: 'Resolve a ctx expression value by path string (expression starts with "ctx.").',
365
584
  detail: '(path: string) => Promise<any>',
@@ -447,7 +666,42 @@ export function defineBaseContextMeta() {
447
666
  {
448
667
  label: 'RunJS 基础',
449
668
  properties: {
450
- logger: 'Pino 日志实例(结构化日志)。示例:`ctx.logger.info({ foo: 1 }, "message")`',
669
+ logger: {
670
+ description: 'Pino 日志实例(结构化日志)。示例:`ctx.logger.info({ foo: 1 }, "message")`',
671
+ detail: 'Logger',
672
+ properties: {
673
+ info: {
674
+ type: 'function',
675
+ description: '写入 info 级别日志。',
676
+ detail: '(...args: any[]) => void',
677
+ completion: { insertText: `ctx.logger.info({ foo: 1 }, 'message')` },
678
+ },
679
+ warn: {
680
+ type: 'function',
681
+ description: '写入 warn 级别日志。',
682
+ detail: '(...args: any[]) => void',
683
+ completion: { insertText: `ctx.logger.warn({ foo: 1 }, 'message')` },
684
+ },
685
+ error: {
686
+ type: 'function',
687
+ description: '写入 error 级别日志。',
688
+ detail: '(...args: any[]) => void',
689
+ completion: { insertText: `ctx.logger.error({ err }, 'message')` },
690
+ },
691
+ debug: {
692
+ type: 'function',
693
+ description: '写入 debug 级别日志。',
694
+ detail: '(...args: any[]) => void',
695
+ completion: { insertText: `ctx.logger.debug({ foo: 1 }, 'message')` },
696
+ },
697
+ child: {
698
+ type: 'function',
699
+ description: '创建带绑定字段的子 logger。',
700
+ detail: '(bindings: object) => Logger',
701
+ completion: { insertText: `ctx.logger.child({ module: 'runjs' })` },
702
+ },
703
+ },
704
+ },
451
705
  message: {
452
706
  description: 'Ant Design 全局消息 API,用于显示临时提示。',
453
707
  detail: 'MessageInstance',
@@ -670,12 +924,18 @@ export function defineBaseContextMeta() {
670
924
  popover: {
671
925
  description: '打开气泡卡片视图。参数:(props: PopoverProps) => any',
672
926
  detail: '(props) => any',
673
- completion: { insertText: 'await ctx.viewer.popover({ target: ctx.element?.__el, content: <div /> })' },
927
+ completion: {
928
+ insertText: 'await ctx.viewer.popover({ target: ctx.element?.__el, content: <div /> })',
929
+ requires: ['element'],
930
+ },
674
931
  },
675
932
  embed: {
676
933
  description: '打开内嵌视图。参数:(props: ViewProps & TargetProps) => any',
677
934
  detail: '(props) => any',
678
- completion: { insertText: 'await ctx.viewer.embed({ target: document.body, content: <div /> })' },
935
+ completion: {
936
+ insertText: 'await ctx.viewer.embed({ target: ctx.element?.__el, content: <div /> })',
937
+ requires: ['element'],
938
+ },
679
939
  },
680
940
  },
681
941
  },
@@ -713,6 +973,36 @@ export function defineBaseContextMeta() {
713
973
  language: '当前激活的语言代码',
714
974
  },
715
975
  },
976
+ sql: {
977
+ description: 'SQL 执行助手(FlowSQLRepository)。',
978
+ detail: 'FlowSQLRepository',
979
+ properties: {
980
+ run: {
981
+ type: 'function',
982
+ description: '执行临时 SQL,可传绑定参数与结果类型。',
983
+ detail: '(sql: string, options?: SQLRunOptions) => Promise<any>',
984
+ completion: { insertText: `await ctx.sql.run('SELECT 1', { type: 'selectRows' })` },
985
+ },
986
+ save: {
987
+ type: 'function',
988
+ description: '保存 SQL 模板。',
989
+ detail: '(data: { uid: string; sql: string; dataSourceKey?: string }) => Promise<void>',
990
+ completion: { insertText: `await ctx.sql.save({ uid: 'sql-uid', sql: 'SELECT 1' })` },
991
+ },
992
+ runById: {
993
+ type: 'function',
994
+ description: '按 uid 执行已保存 SQL 模板。',
995
+ detail: '(uid: string, options?: SQLRunOptions) => Promise<any>',
996
+ completion: { insertText: `await ctx.sql.runById('sql-uid', { type: 'selectRows' })` },
997
+ },
998
+ destroy: {
999
+ type: 'function',
1000
+ description: '按 uid 删除已保存 SQL 模板。',
1001
+ detail: '(uid: string) => Promise<void>',
1002
+ completion: { insertText: `await ctx.sql.destroy('sql-uid')` },
1003
+ },
1004
+ },
1005
+ },
716
1006
  dayjs: {
717
1007
  type: 'function',
718
1008
  description: 'dayjs 日期时间工具库(可调用)。',
@@ -728,14 +1018,133 @@ export function defineBaseContextMeta() {
728
1018
  '第三方/通用库的统一命名空间,包含 React、ReactDOM、Ant Design、dayjs、icons 等,并可扩展更多工具库(如 lodash、formula、math)。后续新增库会优先挂在此处。',
729
1019
  detail: '通用库命名空间',
730
1020
  properties: {
731
- React: 'React 命名空间(等价于 ctx.React)。',
732
- ReactDOM: 'ReactDOM 客户端 API(等价于 ctx.ReactDOM)。',
733
- antd: 'Ant Design 组件库(等价于 ctx.antd)。',
734
- dayjs: 'dayjs 日期时间工具库。',
1021
+ React: {
1022
+ description: 'React 命名空间(等价于 ctx.React)。',
1023
+ properties: {
1024
+ createElement: {
1025
+ type: 'function',
1026
+ description: '创建 React 元素。',
1027
+ detail: 'React.createElement',
1028
+ completion: { insertText: `ctx.libs.React.createElement('div', null, 'Hello')` },
1029
+ },
1030
+ useState: {
1031
+ type: 'function',
1032
+ description: 'React state hook。',
1033
+ detail: 'React.useState',
1034
+ completion: { insertText: 'ctx.libs.React.useState(initialValue)' },
1035
+ },
1036
+ useEffect: {
1037
+ type: 'function',
1038
+ description: 'React effect hook。',
1039
+ detail: 'React.useEffect',
1040
+ completion: { insertText: 'ctx.libs.React.useEffect(() => {}, [])' },
1041
+ },
1042
+ useMemo: {
1043
+ type: 'function',
1044
+ description: 'React memo hook。',
1045
+ detail: 'React.useMemo',
1046
+ completion: { insertText: 'ctx.libs.React.useMemo(() => value, [])' },
1047
+ },
1048
+ useCallback: {
1049
+ type: 'function',
1050
+ description: 'React callback hook。',
1051
+ detail: 'React.useCallback',
1052
+ completion: { insertText: 'ctx.libs.React.useCallback(() => {}, [])' },
1053
+ },
1054
+ },
1055
+ },
1056
+ ReactDOM: {
1057
+ description: 'ReactDOM 客户端 API(等价于 ctx.ReactDOM)。',
1058
+ properties: {
1059
+ createRoot: {
1060
+ type: 'function',
1061
+ description: '创建 React 根。',
1062
+ detail: 'ReactDOM.createRoot',
1063
+ completion: { insertText: 'ctx.libs.ReactDOM.createRoot(ctx.element.__el)', requires: ['element'] },
1064
+ },
1065
+ },
1066
+ },
1067
+ antd: {
1068
+ description: 'Ant Design 组件库(等价于 ctx.antd)。',
1069
+ properties: {
1070
+ Button: 'Ant Design Button 组件。',
1071
+ Table: 'Ant Design Table 组件。',
1072
+ Form: 'Ant Design Form 组件。',
1073
+ Input: 'Ant Design Input 组件。',
1074
+ Select: 'Ant Design Select 组件。',
1075
+ Modal: 'Ant Design Modal API/组件。',
1076
+ },
1077
+ },
1078
+ dayjs: {
1079
+ type: 'function',
1080
+ description: 'dayjs 日期时间工具库。',
1081
+ detail: 'dayjs',
1082
+ completion: { insertText: 'ctx.libs.dayjs()' },
1083
+ },
735
1084
  antdIcons: 'Ant Design 图标库。 例如:`ctx.libs.antdIcons.PlusOutlined`。',
736
- lodash: 'Lodash 工具库。示例:`ctx.libs.lodash.get(obj, "a.b")`。',
737
- formula: 'Formula.js 公式库(类表格函数)。示例:`ctx.libs.formula.SUM(1, 2, 3)`。',
738
- math: 'mathjs 数学库。示例:`ctx.libs.math.evaluate("2 + 3")`。',
1085
+ lodash: {
1086
+ description: 'Lodash 工具库。示例:`ctx.libs.lodash.get(obj, "a.b")`。',
1087
+ properties: {
1088
+ get: {
1089
+ type: 'function',
1090
+ description: '按路径读取嵌套值。',
1091
+ detail: 'lodash.get',
1092
+ completion: { insertText: `ctx.libs.lodash.get(obj, 'a.b')` },
1093
+ },
1094
+ set: {
1095
+ type: 'function',
1096
+ description: '按路径设置嵌套值。',
1097
+ detail: 'lodash.set',
1098
+ completion: { insertText: `ctx.libs.lodash.set(obj, 'a.b', value)` },
1099
+ },
1100
+ debounce: {
1101
+ type: 'function',
1102
+ description: '创建防抖函数。',
1103
+ detail: 'lodash.debounce',
1104
+ completion: { insertText: 'ctx.libs.lodash.debounce(() => {}, 300)' },
1105
+ },
1106
+ cloneDeep: {
1107
+ type: 'function',
1108
+ description: '深拷贝值。',
1109
+ detail: 'lodash.cloneDeep',
1110
+ completion: { insertText: 'ctx.libs.lodash.cloneDeep(value)' },
1111
+ },
1112
+ },
1113
+ },
1114
+ formula: {
1115
+ description: 'Formula.js 公式库(类表格函数)。示例:`ctx.libs.formula.SUM(1, 2, 3)`。',
1116
+ properties: {
1117
+ SUM: {
1118
+ type: 'function',
1119
+ description: '求和。',
1120
+ detail: 'formula.SUM',
1121
+ completion: { insertText: 'ctx.libs.formula.SUM(1, 2, 3)' },
1122
+ },
1123
+ AVERAGE: {
1124
+ type: 'function',
1125
+ description: '求平均值。',
1126
+ detail: 'formula.AVERAGE',
1127
+ completion: { insertText: 'ctx.libs.formula.AVERAGE(1, 2, 3)' },
1128
+ },
1129
+ },
1130
+ },
1131
+ math: {
1132
+ description: 'mathjs 数学库。示例:`ctx.libs.math.evaluate("2 + 3")`。',
1133
+ properties: {
1134
+ evaluate: {
1135
+ type: 'function',
1136
+ description: '计算数学表达式。',
1137
+ detail: 'math.evaluate',
1138
+ completion: { insertText: `ctx.libs.math.evaluate('2 + 3')` },
1139
+ },
1140
+ round: {
1141
+ type: 'function',
1142
+ description: '四舍五入。',
1143
+ detail: 'math.round',
1144
+ completion: { insertText: 'ctx.libs.math.round(value, 2)' },
1145
+ },
1146
+ },
1147
+ },
739
1148
  },
740
1149
  },
741
1150
  },
@@ -765,7 +1174,12 @@ export function defineBaseContextMeta() {
765
1174
  returns: { type: 'FlowModel | undefined' },
766
1175
  examples: ["const model = ctx.getModel('block-uid-xxx');"],
767
1176
  },
768
- t: '国际化函数,用于翻译文案。参数:(key: string, variables?: object) => string。示例:`ctx.t("你好 {{name}}", { name: "世界" })`',
1177
+ t: {
1178
+ description: '国际化函数,用于翻译文案。参数:(key: string, variables?: object) => string。',
1179
+ detail: '(key: string, variables?: object) => string',
1180
+ completion: { insertText: `ctx.t('你好')` },
1181
+ examples: [`ctx.t("你好 {{name}}", { name: "世界" })`],
1182
+ },
769
1183
  initResource: {
770
1184
  description:
771
1185
  '初始化当前上下文的资源:若尚未存在 ctx.resource,则按资源类名创建并绑定;若已存在则直接复用。常用值:"MultiRecordResource"、"SingleRecordResource"、"SQLResource"。',
@@ -786,12 +1200,21 @@ export function defineBaseContextMeta() {
786
1200
  detail: 'ReactDOM Root',
787
1201
  completion: {
788
1202
  insertText: `ctx.render(<div />)`,
1203
+ requires: ['element'],
789
1204
  },
790
1205
  },
791
- requireAsync:
792
- '按 URL 异步加载 UMD/AMD 或挂到全局的脚本,也可加载 CSS。支持简写路径(如 "echarts@5/dist/echarts.min.js",会经由 ESM CDN 加 ?raw 获取原始文件)和完整 URL,返回加载后的库对象或样式注入结果。',
793
- importAsync:
794
- ' URL 动态加载 ESM 模块或 CSS。支持简写(如 "vue@3.4.0"、"dayjs@1/plugin/relativeTime.js",会按配置拼接 ESM CDN 前缀)和完整 URL,返回模块命名空间或样式注入结果。',
1206
+ requireAsync: {
1207
+ description:
1208
+ '按 URL 异步加载 UMD/AMD 或挂到全局的脚本,也可加载 CSS。支持简写路径(如 "echarts@5/dist/echarts.min.js",会经由 ESM CDN 加 ?raw 获取原始文件)和完整 URL,返回加载后的库对象或样式注入结果。',
1209
+ detail: '(url: string) => Promise<any>',
1210
+ completion: { insertText: `const lib = await ctx.requireAsync('https://cdn.example.com/lib.umd.js')` },
1211
+ },
1212
+ importAsync: {
1213
+ description:
1214
+ '按 URL 动态加载 ESM 模块或 CSS。支持简写(如 "vue@3.4.0"、"dayjs@1/plugin/relativeTime.js",会按配置拼接 ESM CDN 前缀)和完整 URL,返回模块命名空间或样式注入结果。',
1215
+ detail: '(url: string) => Promise<any>',
1216
+ completion: { insertText: `const mod = await ctx.importAsync('lodash-es')` },
1217
+ },
795
1218
  getVar: {
796
1219
  description: '通过表达式路径字符串获取 ctx 的运行时值(以 "ctx." 开头)。',
797
1220
  detail: '(path: string) => Promise<any>',
@@ -843,7 +1266,20 @@ export function defineBaseContextMeta() {
843
1266
  returns: { type: 'Promise<Record<string, any>>' },
844
1267
  examples: ['const envs = await ctx.getEnvInfos();'],
845
1268
  },
846
- resolveJsonTemplate: '解析含 {{ }} 变量表达式的 JSON 模板。参数:(template: any, context?: object) => any',
1269
+ resolveJsonTemplate: {
1270
+ description: '解析含 {{ }} 变量表达式的 JSON 模板。',
1271
+ detail: '(template: any) => Promise<any>',
1272
+ params: [
1273
+ {
1274
+ name: 'template',
1275
+ type: 'any',
1276
+ description: '包含 {{ ctx.* }} 表达式的 JSON 兼容值。',
1277
+ },
1278
+ ],
1279
+ returns: { type: 'Promise<any>' },
1280
+ completion: { insertText: `await ctx.resolveJsonTemplate({ value: '{{ctx.record.id}}' })` },
1281
+ examples: ["const data = await ctx.resolveJsonTemplate({ id: '{{ctx.record.id}}' });"],
1282
+ },
847
1283
  runAction: {
848
1284
  description:
849
1285
  '对当前资源执行数据动作。参数:(actionName: string, params: object) => Promise<any>。示例:`await ctx.runAction("create", { values: { name: "test" } })`',