@nocobase/flow-engine 2.0.0-beta.20 → 2.0.0-beta.22

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 (45) hide show
  1. package/lib/JSRunner.js +23 -1
  2. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +3 -3
  3. package/lib/data-source/index.d.ts +7 -27
  4. package/lib/data-source/index.js +67 -46
  5. package/lib/flowContext.d.ts +62 -0
  6. package/lib/flowContext.js +92 -3
  7. package/lib/flowEngine.js +18 -8
  8. package/lib/index.d.ts +4 -1
  9. package/lib/index.js +5 -0
  10. package/lib/resources/sqlResource.d.ts +3 -3
  11. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +12 -2
  12. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +2 -2
  13. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
  14. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
  15. package/lib/runjs-context/contexts/JSItemRunJSContext.js +12 -2
  16. package/lib/runjs-context/contexts/base.js +691 -23
  17. package/lib/runjs-context/contributions.d.ts +33 -0
  18. package/lib/runjs-context/contributions.js +88 -0
  19. package/lib/runjs-context/setup.js +6 -0
  20. package/lib/runjs-context/snippets/index.d.ts +11 -1
  21. package/lib/runjs-context/snippets/index.js +61 -40
  22. package/lib/utils/safeGlobals.js +2 -0
  23. package/package.json +4 -4
  24. package/src/JSRunner.ts +29 -1
  25. package/src/__tests__/JSRunner.test.ts +64 -0
  26. package/src/__tests__/flowContext.test.ts +90 -0
  27. package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
  28. package/src/__tests__/runjsContext.test.ts +4 -1
  29. package/src/__tests__/runjsLocales.test.ts +4 -1
  30. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +3 -3
  31. package/src/data-source/index.ts +71 -105
  32. package/src/flowContext.ts +160 -2
  33. package/src/flowEngine.ts +18 -8
  34. package/src/index.ts +4 -1
  35. package/src/resources/sqlResource.ts +3 -3
  36. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +10 -0
  37. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +6 -2
  38. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
  39. package/src/runjs-context/contexts/JSItemRunJSContext.ts +10 -0
  40. package/src/runjs-context/contexts/base.ts +698 -30
  41. package/src/runjs-context/contributions.ts +88 -0
  42. package/src/runjs-context/setup.ts +6 -0
  43. package/src/runjs-context/snippets/index.ts +75 -41
  44. package/src/utils/__tests__/safeGlobals.test.ts +8 -0
  45. package/src/utils/safeGlobals.ts +3 -1
@@ -36,13 +36,214 @@ function defineBaseContextMeta() {
36
36
  label: "RunJS base",
37
37
  properties: {
38
38
  logger: 'Pino logger instance for structured logging. Example: `ctx.logger.info({ foo: 1 }, "message")`',
39
- message: 'Ant Design global message API for displaying temporary messages. Example: `ctx.message.success("Operation completed")`',
40
- notification: 'Ant Design notification API for displaying notification boxes. Example: `ctx.notification.open({ message: "Title", description: "Content" })`',
41
- resource: "Data resource accessible based on current user permissions",
39
+ message: {
40
+ description: "Ant Design global message API for displaying temporary messages.",
41
+ detail: "MessageInstance",
42
+ hidden: /* @__PURE__ */ __name((ctx) => !(ctx == null ? void 0 : ctx.message), "hidden"),
43
+ examples: ['ctx.message.success("Operation completed")'],
44
+ properties: {
45
+ info: {
46
+ type: "function",
47
+ description: "Show an info message.",
48
+ detail: "(content: any, duration?: number) => void",
49
+ completion: { insertText: `ctx.message.info('Info')` }
50
+ },
51
+ success: {
52
+ type: "function",
53
+ description: "Show a success message.",
54
+ detail: "(content: any, duration?: number) => void",
55
+ completion: { insertText: `ctx.message.success('Success')` }
56
+ },
57
+ error: {
58
+ type: "function",
59
+ description: "Show an error message.",
60
+ detail: "(content: any, duration?: number) => void",
61
+ completion: { insertText: `ctx.message.error('Error')` }
62
+ },
63
+ warning: {
64
+ type: "function",
65
+ description: "Show a warning message.",
66
+ detail: "(content: any, duration?: number) => void",
67
+ completion: { insertText: `ctx.message.warning('Warning')` }
68
+ },
69
+ loading: {
70
+ type: "function",
71
+ description: "Show a loading message.",
72
+ detail: "(content: any, duration?: number) => void",
73
+ completion: { insertText: `ctx.message.loading('Loading...')` }
74
+ },
75
+ open: {
76
+ type: "function",
77
+ description: "Open a message with custom config.",
78
+ detail: "(config: any) => void",
79
+ completion: { insertText: `ctx.message.open({ type: 'info', content: 'Hello' })` }
80
+ },
81
+ destroy: {
82
+ type: "function",
83
+ description: "Destroy all messages.",
84
+ detail: "() => void",
85
+ completion: { insertText: `ctx.message.destroy()` }
86
+ }
87
+ }
88
+ },
89
+ notification: {
90
+ description: "Ant Design notification API for displaying notification boxes.",
91
+ detail: "NotificationInstance",
92
+ hidden: /* @__PURE__ */ __name((ctx) => !(ctx == null ? void 0 : ctx.notification), "hidden"),
93
+ examples: ['ctx.notification.open({ message: "Title", description: "Content" })'],
94
+ properties: {
95
+ open: {
96
+ type: "function",
97
+ description: "Open a notification with config.",
98
+ detail: "(config: any) => void",
99
+ completion: { insertText: `ctx.notification.open({ message: 'Title', description: 'Content' })` }
100
+ },
101
+ success: {
102
+ type: "function",
103
+ description: "Open a success notification.",
104
+ detail: "(config: any) => void",
105
+ completion: { insertText: `ctx.notification.success({ message: 'Success' })` }
106
+ },
107
+ info: {
108
+ type: "function",
109
+ description: "Open an info notification.",
110
+ detail: "(config: any) => void",
111
+ completion: { insertText: `ctx.notification.info({ message: 'Info' })` }
112
+ },
113
+ warning: {
114
+ type: "function",
115
+ description: "Open a warning notification.",
116
+ detail: "(config: any) => void",
117
+ completion: { insertText: `ctx.notification.warning({ message: 'Warning' })` }
118
+ },
119
+ error: {
120
+ type: "function",
121
+ description: "Open an error notification.",
122
+ detail: "(config: any) => void",
123
+ completion: { insertText: `ctx.notification.error({ message: 'Error' })` }
124
+ },
125
+ destroy: {
126
+ type: "function",
127
+ description: "Destroy all notifications.",
128
+ detail: "(key?: string) => void",
129
+ completion: { insertText: `ctx.notification.destroy()` }
130
+ }
131
+ }
132
+ },
133
+ modal: {
134
+ description: "Ant Design modal API (HookAPI) for opening modal dialogs.",
135
+ detail: "HookAPI",
136
+ hidden: /* @__PURE__ */ __name((ctx) => !(ctx == null ? void 0 : ctx.modal), "hidden"),
137
+ examples: [`ctx.modal.confirm({ title: 'Confirm', content: 'Are you sure?' })`],
138
+ properties: {
139
+ info: {
140
+ type: "function",
141
+ description: "Open an info modal.",
142
+ detail: "(config: any) => void",
143
+ completion: { insertText: `ctx.modal.info({ title: 'Info', content: '...' })` }
144
+ },
145
+ success: {
146
+ type: "function",
147
+ description: "Open a success modal.",
148
+ detail: "(config: any) => void",
149
+ completion: { insertText: `ctx.modal.success({ title: 'Success', content: '...' })` }
150
+ },
151
+ error: {
152
+ type: "function",
153
+ description: "Open an error modal.",
154
+ detail: "(config: any) => void",
155
+ completion: { insertText: `ctx.modal.error({ title: 'Error', content: '...' })` }
156
+ },
157
+ warning: {
158
+ type: "function",
159
+ description: "Open a warning modal.",
160
+ detail: "(config: any) => void",
161
+ completion: { insertText: `ctx.modal.warning({ title: 'Warning', content: '...' })` }
162
+ },
163
+ confirm: {
164
+ type: "function",
165
+ description: "Open a confirm modal.",
166
+ detail: "(config: any) => void",
167
+ completion: { insertText: `ctx.modal.confirm({ title: 'Confirm', content: '...' })` }
168
+ }
169
+ }
170
+ },
171
+ // TODO: context meta
172
+ resource: {
173
+ description: "FlowResource instance for accessing and manipulating data.",
174
+ detail: "FlowResource",
175
+ examples: [
176
+ "ctx.useResource('MultiRecordResource');",
177
+ "ctx.resource.setResourceName('users');",
178
+ "await ctx.resource.refresh();",
179
+ "const rows = ctx.resource.getData();"
180
+ ],
181
+ properties: {
182
+ // FlowResource
183
+ getData: {
184
+ description: "Get current resource data.",
185
+ detail: "() => any",
186
+ completion: { insertText: "ctx.resource.getData()" }
187
+ },
188
+ setData: {
189
+ description: "Set current resource data (client-side only).",
190
+ detail: "(value: any) => this",
191
+ completion: { insertText: "ctx.resource.setData(value)" }
192
+ },
193
+ refresh: {
194
+ description: "Refresh data from server (available on API-backed resources).",
195
+ detail: "() => Promise<any>",
196
+ completion: { insertText: "await ctx.resource.refresh()" }
197
+ },
198
+ on: {
199
+ description: "Subscribe resource events (e.g., refresh).",
200
+ detail: "(event: string, callback: (...args) => void) => void",
201
+ completion: { insertText: "ctx.resource.on('refresh', () => {})" }
202
+ },
203
+ off: {
204
+ description: "Unsubscribe resource events.",
205
+ detail: "(event: string, callback: (...args) => void) => void",
206
+ completion: { insertText: "ctx.resource.off('refresh', handler)" }
207
+ },
208
+ // BaseRecordResource / SingleRecordResource / MultiRecordResource helpers (common)
209
+ setResourceName: {
210
+ description: 'Set resource name (e.g., "users" or "users.profile").',
211
+ detail: "(resourceName: string) => this",
212
+ completion: { insertText: "ctx.resource.setResourceName('users')" }
213
+ },
214
+ setFilterByTk: {
215
+ description: "Set primary key or filterByTk for record resources.",
216
+ detail: "(filterByTk: any) => this",
217
+ completion: { insertText: "ctx.resource.setFilterByTk(filterByTk)" }
218
+ },
219
+ runAction: {
220
+ description: "Run a resource action (create/update/destroy/custom actions).",
221
+ detail: "(action: string, options: any) => Promise<any>",
222
+ completion: { insertText: "await ctx.resource.runAction('create', { data: {} })" }
223
+ },
224
+ selectedRows: {
225
+ description: "Selected rows in table resources (typically for collection/table actions). Availability depends on resource type.",
226
+ detail: "any[]"
227
+ },
228
+ pagination: {
229
+ description: "Pagination info in list resources. Availability depends on resource type (e.g., MultiRecordResource).",
230
+ detail: "Record<string, any>"
231
+ }
232
+ }
233
+ },
42
234
  urlSearchParams: "URLSearchParams object containing query parameters from the current URL",
43
235
  token: "API authentication token for the current session",
44
236
  role: "Current user role information",
45
- auth: "Authentication context containing locale, role, user, and token information",
237
+ auth: {
238
+ description: "Authentication context containing locale, role, user, and token information.",
239
+ detail: "AuthContext",
240
+ properties: {
241
+ locale: 'Current locale code (e.g., "en-US", "zh-CN").',
242
+ roleName: "Current role name.",
243
+ token: "Current API token.",
244
+ user: "Current user info object (if available)."
245
+ }
246
+ },
46
247
  api: {
47
248
  description: "APIClient instance for making HTTP requests.",
48
249
  detail: "APIClient",
@@ -53,9 +254,82 @@ function defineBaseContextMeta() {
53
254
  completion: {
54
255
  insertText: `await ctx.api.request({ url: '', method: 'get', params: {} })`
55
256
  }
257
+ },
258
+ auth: {
259
+ description: "Authentication info bound to the API client (token/role/locale).",
260
+ detail: "APIClient.auth",
261
+ properties: {
262
+ token: "Current API token.",
263
+ role: "Current role name.",
264
+ locale: "Current locale code."
265
+ }
266
+ }
267
+ }
268
+ },
269
+ viewer: {
270
+ description: "FlowViewer instance providing view helpers (drawer/dialog/popover/embed). ",
271
+ detail: "FlowViewer",
272
+ examples: [
273
+ "await ctx.viewer.drawer({ width: '56%', content: <div>Hello</div> });",
274
+ "await ctx.viewer.dialog({ content: <div>Confirm</div> });"
275
+ ],
276
+ properties: {
277
+ drawer: {
278
+ description: "Open a drawer view. Parameters: (props: ViewProps) => any",
279
+ detail: "(props) => any",
280
+ completion: { insertText: "await ctx.viewer.drawer({ width: '56%', content: <div /> })" }
281
+ },
282
+ dialog: {
283
+ description: "Open a dialog/modal view. Parameters: (props: ViewProps) => any",
284
+ detail: "(props) => any",
285
+ completion: { insertText: "await ctx.viewer.dialog({ content: <div /> })" }
286
+ },
287
+ popover: {
288
+ description: "Open a popover view. Parameters: (props: PopoverProps) => any",
289
+ detail: "(props) => any",
290
+ completion: { insertText: "await ctx.viewer.popover({ target: ctx.element?.__el, content: <div /> })" }
291
+ },
292
+ embed: {
293
+ description: "Open an embed view. Parameters: (props: ViewProps & TargetProps) => any",
294
+ detail: "(props) => any",
295
+ completion: { insertText: "await ctx.viewer.embed({ target: document.body, content: <div /> })" }
56
296
  }
57
297
  }
58
298
  },
299
+ popup: {
300
+ description: 'Popup context when current view is opened as a popup/drawer. Recommended: `const popup = await ctx.getVar("ctx.popup")`.',
301
+ detail: "Promise<PopupContext | undefined>",
302
+ hidden: /* @__PURE__ */ __name(async (ctx) => {
303
+ try {
304
+ const popup = await (ctx == null ? void 0 : ctx.popup);
305
+ return !(popup == null ? void 0 : popup.uid);
306
+ } catch (_) {
307
+ return false;
308
+ }
309
+ }, "hidden"),
310
+ examples: [
311
+ 'const popup = await ctx.getVar("ctx.popup");',
312
+ "const id = popup?.record?.id;",
313
+ "const parentId = popup?.parent?.record?.id;"
314
+ ],
315
+ properties: {
316
+ uid: "Popup view uid (string).",
317
+ record: "Current popup record (object).",
318
+ sourceRecord: "Parent/source record inferred from sourceId/associationName (object).",
319
+ resource: {
320
+ description: "Data source info of the popup record.",
321
+ detail: "PopupResourceInfo",
322
+ properties: {
323
+ dataSourceKey: 'Data source key (e.g., "main").',
324
+ collectionName: "Collection name.",
325
+ associationName: "Association resource name (optional).",
326
+ filterByTk: "Record primary key / filterByTk.",
327
+ sourceId: "Source id (optional)."
328
+ }
329
+ },
330
+ parent: "Parent popup info (object). You can access parent.parent... at runtime if available."
331
+ }
332
+ },
59
333
  i18n: {
60
334
  description: "An instance of i18next for managing internationalization.",
61
335
  detail: "i18next",
@@ -63,26 +337,27 @@ function defineBaseContextMeta() {
63
337
  language: "Current active language code."
64
338
  }
65
339
  },
66
- React: "React namespace providing React library functions and hooks (available in RunJS environment). Recommended access path: `ctx.libs.React`.",
67
- ReactDOM: "ReactDOM client API including createRoot for rendering React components. Also available via `ctx.libs.ReactDOM`.",
68
- antd: "Ant Design component library. Recommended access path: `ctx.libs.antd`.",
69
340
  libs: {
70
- description: "Namespace for third-party and shared libraries. Includes React, ReactDOM, Ant Design, dayjs, lodash, math.js, and formula.js.",
71
- detail: "Libraries namespace",
72
341
  properties: {
73
342
  React: "React namespace (same as ctx.React).",
74
343
  ReactDOM: "ReactDOM client API (same as ctx.ReactDOM).",
75
344
  antd: "Ant Design component library (same as ctx.antd).",
76
345
  dayjs: "dayjs date-time utility library.",
77
346
  antdIcons: "Ant Design icons library. Example: `ctx.libs.antdIcons.PlusOutlined`.",
78
- lodash: 'Lodash utility library. Example: `ctx.libs.lodash.get(obj, "a.b.c")`.',
79
- math: 'Math.js library for mathematical operations. Example: `ctx.libs.math.evaluate("2 + 3 * 4")`.',
80
- formula: "Formula.js library for spreadsheet-like formulas. Example: `ctx.libs.formula.SUM([1, 2, 3])`."
347
+ lodash: 'Lodash utility library. Example: `ctx.libs.lodash.get(obj, "a.b")`.',
348
+ formula: "Formula.js library (spreadsheet-like functions). Example: `ctx.libs.formula.SUM(1, 2, 3)`.",
349
+ math: 'mathjs library. Example: `ctx.libs.math.evaluate("2 + 3")`.'
81
350
  }
82
351
  }
83
352
  },
84
353
  methods: {
85
- t: 'Internationalization function for translating text. Parameters: (key: string, variables?: object) => string. Example: `ctx.t("Hello {name}", { name: "World" })`',
354
+ t: 'Internationalization function for translating text. Parameters: (key: string, variables?: object) => string. Example: `ctx.t("Hello {{name}}", { name: "World" })`',
355
+ useResource: {
356
+ description: 'Define ctx.resource as a FlowResource instance by class name. Common values: "MultiRecordResource", "SingleRecordResource", "SQLResource".',
357
+ detail: "(className) => void",
358
+ completion: { insertText: "ctx.useResource('MultiRecordResource')" },
359
+ examples: ["ctx.useResource('MultiRecordResource'); ctx.resource.setResourceName('users');"]
360
+ },
86
361
  render: {
87
362
  description: 'Render into container. Accepts ReactElement, DOM Node/Fragment, or HTML string. Parameters: (vnode: ReactElement | Node | DocumentFragment | string, container?: HTMLElement|ElementProxy) => Root|null. Example: `ctx.render(<div>Hello</div>)` or `ctx.render("<b>hi</b>")`',
88
363
  detail: "ReactDOM Root",
@@ -92,7 +367,65 @@ function defineBaseContextMeta() {
92
367
  },
93
368
  requireAsync: 'Asynchronously load external libraries from URL. Parameters: (url: string) => Promise<any>. Example: `const lodash = await ctx.requireAsync("https://cdn.jsdelivr.net/npm/lodash")`',
94
369
  importAsync: 'Dynamically import ESM module by URL. Parameters: (url: string) => Promise<Module>. Example: `const mod = await ctx.importAsync("https://cdn.jsdelivr.net/npm/lit-html@2/+esm")`',
95
- resolveJsonTemplate: "Resolve JSON templates containing variable expressions with {{ }} syntax. Parameters: (template: any, context?: object) => any",
370
+ loadCSS: {
371
+ description: "Load a CSS file by URL (browser only).",
372
+ detail: "(url: string) => Promise<void>",
373
+ completion: { insertText: "await ctx.loadCSS('https://example.com/style.css')" },
374
+ params: [{ name: "url", type: "string", description: "CSS URL." }],
375
+ returns: { type: "Promise<void>" },
376
+ examples: ["await ctx.loadCSS('https://example.com/style.css');"]
377
+ },
378
+ getVar: {
379
+ description: 'Resolve a ctx expression value by path string (expression starts with "ctx.").',
380
+ detail: "(path: string) => Promise<any>",
381
+ completion: { insertText: "await ctx.getVar('ctx.record.id')" },
382
+ params: [
383
+ {
384
+ name: "path",
385
+ type: "string",
386
+ description: 'Expression path starts with "ctx." (e.g. "ctx.record.id", "ctx.record.roles[0].id").'
387
+ }
388
+ ],
389
+ returns: { type: "Promise<any>" },
390
+ examples: ["const id = await ctx.getVar('ctx.record.id');"]
391
+ },
392
+ getApiInfos: {
393
+ description: "All available APIs under context namespace",
394
+ detail: "(options?: { version?: string }) => Promise<Record<string, any>>",
395
+ completion: { insertText: "await ctx.getApiInfos()" },
396
+ params: [
397
+ {
398
+ name: "options",
399
+ type: "{ version?: string }",
400
+ optional: true,
401
+ description: "Options (e.g. version)."
402
+ }
403
+ ],
404
+ returns: { type: "Promise<Record<string, any>>" },
405
+ examples: ["const apis = await ctx.getApiInfos();"]
406
+ },
407
+ getVarInfos: {
408
+ description: "All available variables could be used to get deeper data.",
409
+ detail: "(options?: { path?: string|string[]; maxDepth?: number }) => Promise<Record<string, any>>",
410
+ completion: { insertText: "await ctx.getVarInfos({ path: 'record', maxDepth: 3 })" },
411
+ params: [
412
+ {
413
+ name: "options",
414
+ type: "{ path?: string|string[]; maxDepth?: number }",
415
+ optional: true,
416
+ description: "Options for path trimming and maxDepth expansion."
417
+ }
418
+ ],
419
+ returns: { type: "Promise<Record<string, any>>" },
420
+ examples: ["const vars = await ctx.getVarInfos({ path: 'record', maxDepth: 3 });"]
421
+ },
422
+ getEnvInfos: {
423
+ description: "current runtime environment",
424
+ detail: "() => Promise<Record<string, any>>",
425
+ completion: { insertText: "await ctx.getEnvInfos()" },
426
+ returns: { type: "Promise<Record<string, any>>" },
427
+ examples: ["const envs = await ctx.getEnvInfos();"]
428
+ },
96
429
  runAction: {
97
430
  description: 'Execute a data action on the current resource. Parameters: (actionName: string, params: object) => Promise<any>. Example: `await ctx.runAction("create", { values: { name: "test" } })`',
98
431
  detail: "Promise<any>",
@@ -128,13 +461,211 @@ function defineBaseContextMeta() {
128
461
  label: "RunJS \u57FA\u7840",
129
462
  properties: {
130
463
  logger: 'Pino \u65E5\u5FD7\u5B9E\u4F8B\uFF08\u7ED3\u6784\u5316\u65E5\u5FD7\uFF09\u3002\u793A\u4F8B\uFF1A`ctx.logger.info({ foo: 1 }, "message")`',
131
- message: 'Ant Design \u5168\u5C40\u6D88\u606F API\uFF0C\u7528\u4E8E\u663E\u793A\u4E34\u65F6\u63D0\u793A\u3002\u793A\u4F8B\uFF1A`ctx.message.success("\u64CD\u4F5C\u6210\u529F")`',
132
- notification: 'Ant Design \u901A\u77E5 API\uFF0C\u7528\u4E8E\u663E\u793A\u901A\u77E5\u6846\u3002\u793A\u4F8B\uFF1A`ctx.notification.open({ message: "\u6807\u9898", description: "\u5185\u5BB9" })`',
133
- resource: "\u57FA\u4E8E\u5F53\u524D\u7528\u6237\u6743\u9650\u53EF\u8BBF\u95EE\u7684\u6570\u636E\u8D44\u6E90",
464
+ message: {
465
+ description: "Ant Design \u5168\u5C40\u6D88\u606F API\uFF0C\u7528\u4E8E\u663E\u793A\u4E34\u65F6\u63D0\u793A\u3002",
466
+ detail: "MessageInstance",
467
+ hidden: /* @__PURE__ */ __name((ctx) => !(ctx == null ? void 0 : ctx.message), "hidden"),
468
+ examples: ['ctx.message.success("\u64CD\u4F5C\u6210\u529F")'],
469
+ properties: {
470
+ info: {
471
+ type: "function",
472
+ description: "\u663E\u793A\u4FE1\u606F\u63D0\u793A\u3002",
473
+ detail: "(content: any, duration?: number) => void",
474
+ completion: { insertText: `ctx.message.info('\u63D0\u793A')` }
475
+ },
476
+ success: {
477
+ type: "function",
478
+ description: "\u663E\u793A\u6210\u529F\u63D0\u793A\u3002",
479
+ detail: "(content: any, duration?: number) => void",
480
+ completion: { insertText: `ctx.message.success('\u6210\u529F')` }
481
+ },
482
+ error: {
483
+ type: "function",
484
+ description: "\u663E\u793A\u9519\u8BEF\u63D0\u793A\u3002",
485
+ detail: "(content: any, duration?: number) => void",
486
+ completion: { insertText: `ctx.message.error('\u9519\u8BEF')` }
487
+ },
488
+ warning: {
489
+ type: "function",
490
+ description: "\u663E\u793A\u8B66\u544A\u63D0\u793A\u3002",
491
+ detail: "(content: any, duration?: number) => void",
492
+ completion: { insertText: `ctx.message.warning('\u8B66\u544A')` }
493
+ },
494
+ loading: {
495
+ type: "function",
496
+ description: "\u663E\u793A\u52A0\u8F7D\u63D0\u793A\u3002",
497
+ detail: "(content: any, duration?: number) => void",
498
+ completion: { insertText: `ctx.message.loading('\u52A0\u8F7D\u4E2D...')` }
499
+ },
500
+ open: {
501
+ type: "function",
502
+ description: "\u4F7F\u7528\u81EA\u5B9A\u4E49\u914D\u7F6E\u6253\u5F00\u6D88\u606F\u3002",
503
+ detail: "(config: any) => void",
504
+ completion: { insertText: `ctx.message.open({ type: 'info', content: 'Hello' })` }
505
+ },
506
+ destroy: {
507
+ type: "function",
508
+ description: "\u9500\u6BC1\u6240\u6709\u6D88\u606F\u3002",
509
+ detail: "() => void",
510
+ completion: { insertText: `ctx.message.destroy()` }
511
+ }
512
+ }
513
+ },
514
+ notification: {
515
+ description: "Ant Design \u901A\u77E5 API\uFF0C\u7528\u4E8E\u663E\u793A\u901A\u77E5\u6846\u3002",
516
+ detail: "NotificationInstance",
517
+ hidden: /* @__PURE__ */ __name((ctx) => !(ctx == null ? void 0 : ctx.notification), "hidden"),
518
+ examples: ['ctx.notification.open({ message: "\u6807\u9898", description: "\u5185\u5BB9" })'],
519
+ properties: {
520
+ open: {
521
+ type: "function",
522
+ description: "\u6253\u5F00\u901A\u77E5\u3002",
523
+ detail: "(config: any) => void",
524
+ completion: { insertText: `ctx.notification.open({ message: '\u6807\u9898', description: '\u5185\u5BB9' })` }
525
+ },
526
+ success: {
527
+ type: "function",
528
+ description: "\u6253\u5F00\u6210\u529F\u901A\u77E5\u3002",
529
+ detail: "(config: any) => void",
530
+ completion: { insertText: `ctx.notification.success({ message: '\u6210\u529F' })` }
531
+ },
532
+ info: {
533
+ type: "function",
534
+ description: "\u6253\u5F00\u4FE1\u606F\u901A\u77E5\u3002",
535
+ detail: "(config: any) => void",
536
+ completion: { insertText: `ctx.notification.info({ message: '\u63D0\u793A' })` }
537
+ },
538
+ warning: {
539
+ type: "function",
540
+ description: "\u6253\u5F00\u8B66\u544A\u901A\u77E5\u3002",
541
+ detail: "(config: any) => void",
542
+ completion: { insertText: `ctx.notification.warning({ message: '\u8B66\u544A' })` }
543
+ },
544
+ error: {
545
+ type: "function",
546
+ description: "\u6253\u5F00\u9519\u8BEF\u901A\u77E5\u3002",
547
+ detail: "(config: any) => void",
548
+ completion: { insertText: `ctx.notification.error({ message: '\u9519\u8BEF' })` }
549
+ },
550
+ destroy: {
551
+ type: "function",
552
+ description: "\u9500\u6BC1\u901A\u77E5\u3002",
553
+ detail: "(key?: string) => void",
554
+ completion: { insertText: `ctx.notification.destroy()` }
555
+ }
556
+ }
557
+ },
558
+ modal: {
559
+ description: "Ant Design modal API\uFF08HookAPI\uFF09\uFF0C\u7528\u4E8E\u6253\u5F00\u5BF9\u8BDD\u6846\u3002",
560
+ detail: "HookAPI",
561
+ hidden: /* @__PURE__ */ __name((ctx) => !(ctx == null ? void 0 : ctx.modal), "hidden"),
562
+ examples: [`ctx.modal.confirm({ title: '\u786E\u8BA4', content: '\u786E\u5B9A\u7EE7\u7EED\uFF1F' })`],
563
+ properties: {
564
+ info: {
565
+ type: "function",
566
+ description: "\u6253\u5F00\u4FE1\u606F\u5BF9\u8BDD\u6846\u3002",
567
+ detail: "(config: any) => void",
568
+ completion: { insertText: `ctx.modal.info({ title: '\u63D0\u793A', content: '...' })` }
569
+ },
570
+ success: {
571
+ type: "function",
572
+ description: "\u6253\u5F00\u6210\u529F\u5BF9\u8BDD\u6846\u3002",
573
+ detail: "(config: any) => void",
574
+ completion: { insertText: `ctx.modal.success({ title: '\u6210\u529F', content: '...' })` }
575
+ },
576
+ error: {
577
+ type: "function",
578
+ description: "\u6253\u5F00\u9519\u8BEF\u5BF9\u8BDD\u6846\u3002",
579
+ detail: "(config: any) => void",
580
+ completion: { insertText: `ctx.modal.error({ title: '\u9519\u8BEF', content: '...' })` }
581
+ },
582
+ warning: {
583
+ type: "function",
584
+ description: "\u6253\u5F00\u8B66\u544A\u5BF9\u8BDD\u6846\u3002",
585
+ detail: "(config: any) => void",
586
+ completion: { insertText: `ctx.modal.warning({ title: '\u8B66\u544A', content: '...' })` }
587
+ },
588
+ confirm: {
589
+ type: "function",
590
+ description: "\u6253\u5F00\u786E\u8BA4\u5BF9\u8BDD\u6846\u3002",
591
+ detail: "(config: any) => void",
592
+ completion: { insertText: `ctx.modal.confirm({ title: '\u786E\u8BA4', content: '...' })` }
593
+ }
594
+ }
595
+ },
596
+ resource: {
597
+ description: "\u6570\u636E\u8D44\u6E90\uFF08FlowResource\uFF09\u3002\u591A\u6570\u573A\u666F\u9700\u8981\u5148\u8C03\u7528 ctx.useResource(...) \u521B\u5EFA ctx.resource\u3002",
598
+ detail: "FlowResource",
599
+ examples: [
600
+ "ctx.useResource('MultiRecordResource');",
601
+ "ctx.resource.setResourceName('users');",
602
+ "await ctx.resource.refresh();",
603
+ "const rows = ctx.resource.getData();"
604
+ ],
605
+ properties: {
606
+ getData: {
607
+ description: "\u83B7\u53D6\u8D44\u6E90\u5F53\u524D\u6570\u636E\u3002",
608
+ detail: "() => any",
609
+ completion: { insertText: "ctx.resource.getData()" }
610
+ },
611
+ setData: {
612
+ description: "\u8BBE\u7F6E\u8D44\u6E90\u5F53\u524D\u6570\u636E\uFF08\u4EC5\u524D\u7AEF\uFF09\u3002",
613
+ detail: "(value: any) => this",
614
+ completion: { insertText: "ctx.resource.setData(value)" }
615
+ },
616
+ refresh: {
617
+ description: "\u4ECE\u540E\u7AEF\u5237\u65B0\u6570\u636E\uFF08APIResource/RecordResource \u7B49\u53EF\u7528\uFF09\u3002",
618
+ detail: "() => Promise<any>",
619
+ completion: { insertText: "await ctx.resource.refresh()" }
620
+ },
621
+ on: {
622
+ description: "\u8BA2\u9605\u8D44\u6E90\u4E8B\u4EF6\uFF08\u4F8B\u5982 refresh\uFF09\u3002",
623
+ detail: "(event: string, callback: (...args) => void) => void",
624
+ completion: { insertText: "ctx.resource.on('refresh', () => {})" }
625
+ },
626
+ off: {
627
+ description: "\u53D6\u6D88\u8BA2\u9605\u8D44\u6E90\u4E8B\u4EF6\u3002",
628
+ detail: "(event: string, callback: (...args) => void) => void",
629
+ completion: { insertText: "ctx.resource.off('refresh', handler)" }
630
+ },
631
+ setResourceName: {
632
+ description: '\u8BBE\u7F6E\u8D44\u6E90\u540D\u79F0\uFF08\u4F8B\u5982 "users" \u6216 "users.profile"\uFF09\u3002',
633
+ detail: "(resourceName: string) => this",
634
+ completion: { insertText: "ctx.resource.setResourceName('users')" }
635
+ },
636
+ setFilterByTk: {
637
+ description: "\u8BBE\u7F6E\u4E3B\u952E/\u8FC7\u6EE4\u952E filterByTk\uFF08\u8BB0\u5F55\u8D44\u6E90\u5E38\u7528\uFF09\u3002",
638
+ detail: "(filterByTk: any) => this",
639
+ completion: { insertText: "ctx.resource.setFilterByTk(filterByTk)" }
640
+ },
641
+ runAction: {
642
+ description: "\u6267\u884C\u8D44\u6E90\u52A8\u4F5C\uFF08create/update/destroy/\u81EA\u5B9A\u4E49 action\uFF09\u3002",
643
+ detail: "(action: string, options: any) => Promise<any>",
644
+ completion: { insertText: "await ctx.resource.runAction('create', { data: {} })" }
645
+ },
646
+ selectedRows: {
647
+ description: "\u5217\u8868\u8D44\u6E90\u7684\u9009\u4E2D\u884C\uFF08\u901A\u5E38\u7528\u4E8E\u8868\u683C\u52A8\u4F5C\uFF1B\u662F\u5426\u5B58\u5728\u53D6\u51B3\u4E8E\u8D44\u6E90\u7C7B\u578B\uFF09\u3002",
648
+ detail: "any[]"
649
+ },
650
+ pagination: {
651
+ description: "\u5217\u8868\u8D44\u6E90\u7684\u5206\u9875\u4FE1\u606F\uFF08\u662F\u5426\u5B58\u5728\u53D6\u51B3\u4E8E\u8D44\u6E90\u7C7B\u578B\uFF09\u3002",
652
+ detail: "Record<string, any>"
653
+ }
654
+ }
655
+ },
134
656
  urlSearchParams: "\u5F53\u524D URL \u7684\u67E5\u8BE2\u53C2\u6570\uFF08URLSearchParams \u5BF9\u8C61\uFF09",
135
657
  token: "\u5F53\u524D\u4F1A\u8BDD\u7684 API \u8BA4\u8BC1 token",
136
658
  role: "\u5F53\u524D\u7528\u6237\u89D2\u8272\u4FE1\u606F",
137
- auth: "\u8BA4\u8BC1\u4E0A\u4E0B\u6587\uFF0C\u5305\u542B locale\u3001role\u3001user\u3001token \u7B49\u4FE1\u606F",
659
+ auth: {
660
+ description: "\u8BA4\u8BC1\u4E0A\u4E0B\u6587\uFF0C\u5305\u542B locale\u3001role\u3001user\u3001token \u7B49\u4FE1\u606F",
661
+ detail: "AuthContext",
662
+ properties: {
663
+ locale: '\u5F53\u524D locale\uFF08\u4F8B\u5982 "en-US"\u3001"zh-CN"\uFF09\u3002',
664
+ roleName: "\u5F53\u524D\u89D2\u8272\u540D\u3002",
665
+ token: "\u5F53\u524D API token\u3002",
666
+ user: "\u5F53\u524D\u7528\u6237\u4FE1\u606F\u5BF9\u8C61\uFF08\u82E5\u53EF\u7528\uFF09\u3002"
667
+ }
668
+ },
138
669
  api: {
139
670
  description: "\u7528\u4E8E\u53D1\u8D77 HTTP \u8BF7\u6C42\u7684 APIClient \u5B9E\u4F8B",
140
671
  detail: "APIClient",
@@ -145,9 +676,74 @@ function defineBaseContextMeta() {
145
676
  completion: {
146
677
  insertText: `await ctx.api.request({ url: '', method: 'get', params: {} })`
147
678
  }
679
+ },
680
+ auth: {
681
+ description: "APIClient \u4E0A\u7684\u8BA4\u8BC1\u4FE1\u606F\uFF08token/role/locale\uFF09\u3002",
682
+ detail: "APIClient.auth",
683
+ properties: {
684
+ token: "\u5F53\u524D API token\u3002",
685
+ role: "\u5F53\u524D\u89D2\u8272\u540D\u3002",
686
+ locale: "\u5F53\u524D locale\u3002"
687
+ }
688
+ }
689
+ }
690
+ },
691
+ viewer: {
692
+ description: "\u89C6\u56FE\u63A7\u5236\u5668\uFF08FlowViewer\uFF09\uFF0C\u63D0\u4F9B drawer/dialog/popover/embed \u7B49\u4EA4\u4E92\u80FD\u529B\u3002",
693
+ detail: "FlowViewer",
694
+ examples: [
695
+ "await ctx.viewer.drawer({ width: '56%', content: <div /> });",
696
+ "await ctx.viewer.dialog({ content: <div /> });"
697
+ ],
698
+ properties: {
699
+ drawer: {
700
+ description: "\u6253\u5F00\u62BD\u5C49\u89C6\u56FE\u3002\u53C2\u6570\uFF1A(props: ViewProps) => any",
701
+ detail: "(props) => any",
702
+ completion: { insertText: "await ctx.viewer.drawer({ width: '56%', content: <div /> })" }
703
+ },
704
+ dialog: {
705
+ description: "\u6253\u5F00\u5BF9\u8BDD\u6846\u89C6\u56FE\u3002\u53C2\u6570\uFF1A(props: ViewProps) => any",
706
+ detail: "(props) => any",
707
+ completion: { insertText: "await ctx.viewer.dialog({ content: <div /> })" }
708
+ },
709
+ popover: {
710
+ description: "\u6253\u5F00\u6C14\u6CE1\u5361\u7247\u89C6\u56FE\u3002\u53C2\u6570\uFF1A(props: PopoverProps) => any",
711
+ detail: "(props) => any",
712
+ completion: { insertText: "await ctx.viewer.popover({ target: ctx.element?.__el, content: <div /> })" }
713
+ },
714
+ embed: {
715
+ description: "\u6253\u5F00\u5185\u5D4C\u89C6\u56FE\u3002\u53C2\u6570\uFF1A(props: ViewProps & TargetProps) => any",
716
+ detail: "(props) => any",
717
+ completion: { insertText: "await ctx.viewer.embed({ target: document.body, content: <div /> })" }
148
718
  }
149
719
  }
150
720
  },
721
+ popup: {
722
+ description: '\u5F39\u7A97\u4E0A\u4E0B\u6587\uFF08\u5728\u5F53\u524D\u89C6\u56FE\u4EE5\u5F39\u7A97/\u62BD\u5C49\u6253\u5F00\u65F6\u53EF\u7528\uFF09\u3002\u63A8\u8350\uFF1A`const popup = await ctx.getVar("ctx.popup")`\u3002',
723
+ detail: "Promise<PopupContext | undefined>",
724
+ examples: [
725
+ 'const popup = await ctx.getVar("ctx.popup");',
726
+ "const id = popup?.record?.id;",
727
+ "const parentId = popup?.parent?.record?.id;"
728
+ ],
729
+ properties: {
730
+ uid: "\u5F39\u7A97 view uid\uFF08string\uFF09",
731
+ record: "\u5F53\u524D\u5F39\u7A97\u8BB0\u5F55\uFF08object\uFF09",
732
+ sourceRecord: "\u6839\u636E sourceId/associationName \u63A8\u65AD\u7684\u4E0A\u7EA7\u8BB0\u5F55\uFF08object\uFF09",
733
+ resource: {
734
+ description: "\u5F39\u7A97\u8BB0\u5F55\u7684\u6570\u636E\u6E90\u4FE1\u606F\u3002",
735
+ detail: "PopupResourceInfo",
736
+ properties: {
737
+ dataSourceKey: '\u6570\u636E\u6E90 key\uFF08\u4F8B\u5982 "main"\uFF09\u3002',
738
+ collectionName: "\u96C6\u5408\u540D\u79F0\u3002",
739
+ associationName: "\u5173\u8054\u8D44\u6E90\u540D\uFF08\u53EF\u9009\uFF09\u3002",
740
+ filterByTk: "\u8BB0\u5F55\u4E3B\u952E/\u8FC7\u6EE4\u952E filterByTk\u3002",
741
+ sourceId: "sourceId\uFF08\u53EF\u9009\uFF09\u3002"
742
+ }
743
+ },
744
+ parent: "\u4E0A\u7EA7\u5F39\u7A97\u4FE1\u606F\uFF08object\uFF09\u3002\u8FD0\u884C\u65F6\u82E5\u5B58\u5728\u53EF\u8BBF\u95EE parent.parent... \u94FE\u3002"
745
+ }
746
+ },
151
747
  i18n: {
152
748
  description: "i18next \u5B9E\u4F8B\uFF0C\u53EF\u7528\u4E8E\u7BA1\u7406\u56FD\u9645\u5316",
153
749
  detail: "i18next",
@@ -155,11 +751,18 @@ function defineBaseContextMeta() {
155
751
  language: "\u5F53\u524D\u6FC0\u6D3B\u7684\u8BED\u8A00\u4EE3\u7801"
156
752
  }
157
753
  },
754
+ dayjs: {
755
+ type: "function",
756
+ description: "dayjs \u65E5\u671F\u65F6\u95F4\u5DE5\u5177\u5E93\uFF08\u53EF\u8C03\u7528\uFF09\u3002",
757
+ detail: "dayjs",
758
+ completion: { insertText: "ctx.dayjs()" },
759
+ examples: ["const now = ctx.dayjs().format('YYYY-MM-DD HH:mm:ss');"]
760
+ },
158
761
  React: "React \u547D\u540D\u7A7A\u95F4\uFF0C\u63D0\u4F9B React \u51FD\u6570\u4E0E hooks\uFF08RunJS \u73AF\u5883\u4E2D\u53EF\u7528\uFF09\u3002\u63A8\u8350\u4F7F\u7528 `ctx.libs.React` \u8BBF\u95EE\u3002",
159
762
  ReactDOM: "ReactDOM \u5BA2\u6237\u7AEF API\uFF0C\u542B createRoot \u7B49\u6E32\u67D3\u65B9\u6CD5\u3002\u63A8\u8350\u901A\u8FC7 `ctx.libs.ReactDOM` \u8BBF\u95EE\u3002",
160
763
  antd: "Ant Design \u7EC4\u4EF6\u5E93\uFF08RunJS \u73AF\u5883\u4E2D\u53EF\u7528\uFF09\u3002\u63A8\u8350\u4F7F\u7528 `ctx.libs.antd` \u8BBF\u95EE\u3002",
161
764
  libs: {
162
- description: "\u7B2C\u4E09\u65B9/\u901A\u7528\u5E93\u7684\u7EDF\u4E00\u547D\u540D\u7A7A\u95F4\uFF0C\u5305\u542B React\u3001ReactDOM\u3001Ant Design\u3001dayjs\u3001lodash\u3001math.js\u3001formula.js \u7B49\u3002\u540E\u7EED\u65B0\u589E\u5E93\u4F1A\u4F18\u5148\u6302\u5728\u6B64\u5904\u3002",
765
+ description: "\u7B2C\u4E09\u65B9/\u901A\u7528\u5E93\u7684\u7EDF\u4E00\u547D\u540D\u7A7A\u95F4\uFF0C\u5305\u542B React\u3001ReactDOM\u3001Ant Design\u3001dayjs\u3001icons \u7B49\uFF0C\u5E76\u53EF\u6269\u5C55\u66F4\u591A\u5DE5\u5177\u5E93\uFF08\u5982 lodash\u3001formula\u3001math\uFF09\u3002\u540E\u7EED\u65B0\u589E\u5E93\u4F1A\u4F18\u5148\u6302\u5728\u6B64\u5904\u3002",
163
766
  detail: "\u901A\u7528\u5E93\u547D\u540D\u7A7A\u95F4",
164
767
  properties: {
165
768
  React: "React \u547D\u540D\u7A7A\u95F4\uFF08\u7B49\u4EF7\u4E8E ctx.React\uFF09\u3002",
@@ -167,14 +770,20 @@ function defineBaseContextMeta() {
167
770
  antd: "Ant Design \u7EC4\u4EF6\u5E93\uFF08\u7B49\u4EF7\u4E8E ctx.antd\uFF09\u3002",
168
771
  dayjs: "dayjs \u65E5\u671F\u65F6\u95F4\u5DE5\u5177\u5E93\u3002",
169
772
  antdIcons: "Ant Design \u56FE\u6807\u5E93\u3002 \u4F8B\u5982\uFF1A`ctx.libs.antdIcons.PlusOutlined`\u3002",
170
- lodash: 'Lodash \u5DE5\u5177\u5E93\u3002\u4F8B\u5982\uFF1A`ctx.libs.lodash.get(obj, "a.b.c")`\u3002',
171
- math: 'Math.js \u6570\u5B66\u8FD0\u7B97\u5E93\u3002\u4F8B\u5982\uFF1A`ctx.libs.math.evaluate("2 + 3 * 4")`\u3002',
172
- formula: "Formula.js \u7535\u5B50\u8868\u683C\u516C\u5F0F\u5E93\u3002\u4F8B\u5982\uFF1A`ctx.libs.formula.SUM([1, 2, 3])`\u3002"
773
+ lodash: 'Lodash \u5DE5\u5177\u5E93\u3002\u793A\u4F8B\uFF1A`ctx.libs.lodash.get(obj, "a.b")`\u3002',
774
+ formula: "Formula.js \u516C\u5F0F\u5E93\uFF08\u7C7B\u8868\u683C\u51FD\u6570\uFF09\u3002\u793A\u4F8B\uFF1A`ctx.libs.formula.SUM(1, 2, 3)`\u3002",
775
+ math: 'mathjs \u6570\u5B66\u5E93\u3002\u793A\u4F8B\uFF1A`ctx.libs.math.evaluate("2 + 3")`\u3002'
173
776
  }
174
777
  }
175
778
  },
176
779
  methods: {
177
- t: '\u56FD\u9645\u5316\u51FD\u6570\uFF0C\u7528\u4E8E\u7FFB\u8BD1\u6587\u6848\u3002\u53C2\u6570\uFF1A(key: string, variables?: object) => string\u3002\u793A\u4F8B\uFF1A`ctx.t("\u4F60\u597D {name}", { name: "\u4E16\u754C" })`',
780
+ t: '\u56FD\u9645\u5316\u51FD\u6570\uFF0C\u7528\u4E8E\u7FFB\u8BD1\u6587\u6848\u3002\u53C2\u6570\uFF1A(key: string, variables?: object) => string\u3002\u793A\u4F8B\uFF1A`ctx.t("\u4F60\u597D {{name}}", { name: "\u4E16\u754C" })`',
781
+ useResource: {
782
+ description: '\u901A\u8FC7\u8D44\u6E90\u7C7B\u540D\u521B\u5EFA ctx.resource\u3002\u5E38\u7528\u503C\uFF1A"MultiRecordResource"\u3001"SingleRecordResource"\u3001"SQLResource"\u3002',
783
+ detail: "(className) => void",
784
+ completion: { insertText: "ctx.useResource('MultiRecordResource')" },
785
+ examples: ["ctx.useResource('MultiRecordResource'); ctx.resource.setResourceName('users');"]
786
+ },
178
787
  render: {
179
788
  description: '\u6E32\u67D3\u5230\u5BB9\u5668\u3002vnode \u652F\u6301 ReactElement\u3001DOM \u8282\u70B9/\u7247\u6BB5\u3001\u6216 HTML \u5B57\u7B26\u4E32\u3002\u53C2\u6570\uFF1A(vnode: ReactElement | Node | DocumentFragment | string, container?: HTMLElement|ElementProxy) => Root|null\u3002\u793A\u4F8B\uFF1A`ctx.render(<div />)` \u6216 `ctx.render("<b>hi</b>")`',
180
789
  detail: "ReactDOM Root",
@@ -184,6 +793,65 @@ function defineBaseContextMeta() {
184
793
  },
185
794
  requireAsync: '\u6309 URL \u5F02\u6B65\u52A0\u8F7D\u5916\u90E8\u5E93\u3002\u53C2\u6570\uFF1A(url: string) => Promise<any>\u3002\u793A\u4F8B\uFF1A`const lodash = await ctx.requireAsync("https://cdn.jsdelivr.net/npm/lodash")`',
186
795
  importAsync: '\u6309 URL \u52A8\u6001\u5BFC\u5165 ESM \u6A21\u5757\uFF08\u5F00\u53D1/\u751F\u4EA7\u5747\u53EF\u7528\uFF09\u3002\u53C2\u6570\uFF1A(url: string) => Promise<Module>\u3002\u793A\u4F8B\uFF1A`const mod = await ctx.importAsync("https://cdn.jsdelivr.net/npm/lit-html@2/+esm")`',
796
+ loadCSS: {
797
+ description: "\u6309 URL \u52A0\u8F7D CSS\uFF08\u4EC5\u6D4F\u89C8\u5668\u73AF\u5883\uFF09\u3002",
798
+ detail: "(url: string) => Promise<void>",
799
+ completion: { insertText: "await ctx.loadCSS('https://example.com/style.css')" },
800
+ params: [{ name: "url", type: "string", description: "CSS \u5730\u5740\u3002" }],
801
+ returns: { type: "Promise<void>" },
802
+ examples: ["await ctx.loadCSS('https://example.com/style.css');"]
803
+ },
804
+ getVar: {
805
+ description: '\u901A\u8FC7\u8868\u8FBE\u5F0F\u8DEF\u5F84\u5B57\u7B26\u4E32\u83B7\u53D6 ctx \u7684\u8FD0\u884C\u65F6\u503C\uFF08\u4EE5 "ctx." \u5F00\u5934\uFF09\u3002',
806
+ detail: "(path: string) => Promise<any>",
807
+ completion: { insertText: "await ctx.getVar('ctx.record.id')" },
808
+ params: [
809
+ {
810
+ name: "path",
811
+ type: "string",
812
+ description: '\u4EE5 "ctx." \u5F00\u5934\u7684\u8868\u8FBE\u5F0F\u8DEF\u5F84\uFF08\u4F8B\u5982 "ctx.record.id" / "ctx.record.roles[0].id"\uFF09\u3002'
813
+ }
814
+ ],
815
+ returns: { type: "Promise<any>" },
816
+ examples: ["const id = await ctx.getVar('ctx.record.id');"]
817
+ },
818
+ getApiInfos: {
819
+ description: "\u4E0A\u4E0B\u6587\u547D\u540D\u7A7A\u95F4\u4E0B\u7684\u6240\u6709\u53EF\u7528 API",
820
+ detail: "(options?: { version?: string }) => Promise<Record<string, any>>",
821
+ completion: { insertText: "await ctx.getApiInfos()" },
822
+ params: [
823
+ {
824
+ name: "options",
825
+ type: "{ version?: string }",
826
+ optional: true,
827
+ description: "\u53EF\u9009\u53C2\u6570\uFF08\u4F8B\u5982 version\uFF09\u3002"
828
+ }
829
+ ],
830
+ returns: { type: "Promise<Record<string, any>>" },
831
+ examples: ["const apis = await ctx.getApiInfos();"]
832
+ },
833
+ getVarInfos: {
834
+ description: "\u6240\u6709\u53EF\u7528\u53D8\u91CF\uFF0C\u53EF\u7528\u4E8E\u83B7\u53D6\u66F4\u6DF1\u5C42\u6570\u636E\u3002",
835
+ detail: "(options?: { path?: string|string[]; maxDepth?: number }) => Promise<Record<string, any>>",
836
+ completion: { insertText: "await ctx.getVarInfos({ path: 'record', maxDepth: 3 })" },
837
+ params: [
838
+ {
839
+ name: "options",
840
+ type: "{ path?: string|string[]; maxDepth?: number }",
841
+ optional: true,
842
+ description: "path \u526A\u88C1\u4E0E maxDepth \u5C55\u5F00\u53C2\u6570\u3002"
843
+ }
844
+ ],
845
+ returns: { type: "Promise<Record<string, any>>" },
846
+ examples: ["const vars = await ctx.getVarInfos({ path: 'record', maxDepth: 3 });"]
847
+ },
848
+ getEnvInfos: {
849
+ description: "\u5F53\u524D\u8FD0\u884C\u65F6\u73AF\u5883",
850
+ detail: "() => Promise<Record<string, any>>",
851
+ completion: { insertText: "await ctx.getEnvInfos()" },
852
+ returns: { type: "Promise<Record<string, any>>" },
853
+ examples: ["const envs = await ctx.getEnvInfos();"]
854
+ },
187
855
  resolveJsonTemplate: "\u89E3\u6790\u542B {{ }} \u53D8\u91CF\u8868\u8FBE\u5F0F\u7684 JSON \u6A21\u677F\u3002\u53C2\u6570\uFF1A(template: any, context?: object) => any",
188
856
  runAction: {
189
857
  description: '\u5BF9\u5F53\u524D\u8D44\u6E90\u6267\u884C\u6570\u636E\u52A8\u4F5C\u3002\u53C2\u6570\uFF1A(actionName: string, params: object) => Promise<any>\u3002\u793A\u4F8B\uFF1A`await ctx.runAction("create", { values: { name: "test" } })`',