openxiangda 1.0.19 → 1.0.20
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.
- package/openxiangda-skills/SKILL.md +2 -0
- package/openxiangda-skills/references/automation-v3.md +42 -2
- package/openxiangda-skills/references/workflow-v3.md +39 -1
- package/openxiangda-skills/skills/openxiangda-workflow-automation/SKILL.md +11 -2
- package/package.json +1 -1
- package/packages/sdk/dist/runtime/index.d.mts +11 -1
- package/packages/sdk/dist/runtime/index.d.ts +11 -1
- package/packages/sdk/src/build-source/scripts/utils/register-payload.mjs +1 -0
- package/packages/sdk/src/build-source/scripts/utils/register-payload.test.ts +54 -5
- package/templates/sy-lowcode-app-workspace/src/types/app-workspace.types.ts +36 -0
|
@@ -74,6 +74,8 @@ When the user provides a root domain such as `https://yida.wisejob.cn/`, use it
|
|
|
74
74
|
- Before publishing to another platform, verify the workspace is bound for that profile. Resource IDs from one profile must not be reused for another profile.
|
|
75
75
|
- Use `openxiangda app snapshot <APP_XXX> --profile <name> --json` for diagnosis before changing an existing app.
|
|
76
76
|
- Run write commands that update `.openxiangda/state.json` sequentially within the same workspace. Read-only commands can run in parallel.
|
|
77
|
+
- JS_CODE is backend-executed workflow/automation logic, not frontend page code. Use it when logic must run after a backend trigger such as fixed cron schedules, form date-field schedules, form submit/update/delete/field-change events, or workflow approval/process events.
|
|
78
|
+
- Use JS_CODE for cross-form data queries, create/update/batch update operations, process termination, platform API calls, external HTTP calls, and complex orchestration that the frontend cannot handle reliably. Do not use it for simple UI interactions, ordinary form validation, or display-only page behavior.
|
|
77
79
|
- For workflow/automation JS_CODE nodes, prefer V2 `runtimeMode: "trusted_node"`. AI-authored source must be TypeScript under `sy-lowcode-app-workspace/src/js-code-nodes/<scriptCode>/index.ts`. `pnpm build-js-code --script <scriptCode>` runs TypeScript validation before bundling, and `sourceFile.localPath` should point to the TS source; the CLI builds, uploads, and replaces it with snapshot metadata during validate/create.
|
|
78
80
|
|
|
79
81
|
## Subskills
|
|
@@ -7,6 +7,8 @@ Automations have two files:
|
|
|
7
7
|
|
|
8
8
|
## Trigger Config
|
|
9
9
|
|
|
10
|
+
Automation can run from form events, workflow events, fixed cron schedules, or a form date field reaching a configured time. Pair these triggers with JS_CODE when the action must execute on the backend and cannot be handled reliably by a frontend page.
|
|
11
|
+
|
|
10
12
|
Form submit trigger:
|
|
11
13
|
|
|
12
14
|
```json
|
|
@@ -96,7 +98,7 @@ Supported node types:
|
|
|
96
98
|
|
|
97
99
|
## JS_CODE V2
|
|
98
100
|
|
|
99
|
-
Use trusted Node JS_CODE nodes for AI/admin automation logic
|
|
101
|
+
Use trusted Node JS_CODE nodes for AI/admin automation logic that runs after an automation trigger. Typical cases include scheduled data cleanup, date-field reminders, cross-form synchronization after submit/update/delete, workflow-completed follow-up writes, calling internal platform APIs, calling external HTTP services, and other backend-only orchestration.
|
|
100
102
|
|
|
101
103
|
```json
|
|
102
104
|
{
|
|
@@ -117,7 +119,45 @@ Use trusted Node JS_CODE nodes for AI/admin automation logic:
|
|
|
117
119
|
|
|
118
120
|
Author source in `sy-lowcode-app-workspace/src/js-code-nodes/<scriptCode>/index.ts`. AI-authored source must be TypeScript. Build with `pnpm build-js-code --script <scriptCode>`; the command runs TypeScript validation before bundling. During validate/create, the CLI uploads the generated bundle, replaces `sourceFile.localPath` with `{ bucketName, objectName, sha256, ... }`, and the backend verifies sha256 before execution.
|
|
119
121
|
|
|
120
|
-
Scripts may use `module.exports = async (ctx) => {}`, `require`, `process`, `Buffer`,
|
|
122
|
+
The backend runs the snapshot in the trusted Node runtime, applies the node timeout (`30000` ms by default), stores execution logs, and writes the returned value to the node output and `variables.node_<nodeId>`. Scripts may use `export default async function (ctx) {}`, `module.exports = async (ctx) => {}`, `require`, `process`, `Buffer`, arbitrary HTTP, and `platform.api` for `/openxiangda-api/v1`.
|
|
123
|
+
|
|
124
|
+
Runtime context includes `ctx.triggerEvent`, `ctx.formData`, `ctx.workflowData`, `ctx.operator`, `ctx.app`, `ctx.variables`, and `ctx.node`. Data/process bridge methods include `ctx.methods.queryOneData`, `queryManyData`, `updateOneData`, `updateDataByFormInstanceId`, `updateManyData`, `createOneData`, `terminateProcess`, and `getAllParentDepartments`.
|
|
125
|
+
|
|
126
|
+
Example `src/js-code-nodes/scheduled_reconcile/index.ts`:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
export default async function scheduledReconcile(ctx) {
|
|
130
|
+
const appType = ctx.app.appType;
|
|
131
|
+
const current = ctx.formData?.current || {};
|
|
132
|
+
const formInstanceId =
|
|
133
|
+
ctx.triggerEvent?.data?.formInstanceId ||
|
|
134
|
+
current.formInstanceId ||
|
|
135
|
+
current.formInstId;
|
|
136
|
+
|
|
137
|
+
const pendingRows = await ctx.methods.queryManyData(appType, "FORM_ORDER", {
|
|
138
|
+
status: "pending",
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
if (formInstanceId) {
|
|
142
|
+
await ctx.methods.updateDataByFormInstanceId(
|
|
143
|
+
appType,
|
|
144
|
+
"FORM_ORDER",
|
|
145
|
+
formInstanceId,
|
|
146
|
+
{ last_checked_at: new Date().toISOString() }
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const log = await ctx.methods.createOneData(appType, "FORM_JOB_LOG", {
|
|
151
|
+
trigger_type: ctx.triggerEvent?.type || "scheduled",
|
|
152
|
+
processed_count: Array.isArray(pendingRows) ? pendingRows.length : 0,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
processedCount: pendingRows?.length || 0,
|
|
157
|
+
logId: log?.formInstanceId || log?.id,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
```
|
|
121
161
|
|
|
122
162
|
Validation rules:
|
|
123
163
|
|
|
@@ -52,6 +52,8 @@ Supported node types:
|
|
|
52
52
|
|
|
53
53
|
## JS_CODE V2
|
|
54
54
|
|
|
55
|
+
Workflow JS_CODE runs on the backend when the process reaches the `js_code` node. Use it before or after approval nodes, in branches, or before ending a process when the workflow needs server-side side effects such as cross-form synchronization, audit record creation, external API calls, or terminating a related process. Do not use it for frontend-only behavior.
|
|
56
|
+
|
|
55
57
|
Inline:
|
|
56
58
|
|
|
57
59
|
```json
|
|
@@ -87,7 +89,43 @@ File snapshot:
|
|
|
87
89
|
}
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
AI-authored JS_CODE source must be TypeScript under `sy-lowcode-app-workspace/src/js-code-nodes/<scriptCode>/index.ts`. When validating or creating, the CLI runs `pnpm build-js-code --script <scriptCode>`, which runs TypeScript validation first, bundles to `dist/js-code-nodes/<scriptCode>/index.cjs`, uploads the bundle, and replaces `sourceFile.localPath` with immutable snapshot metadata.
|
|
92
|
+
AI-authored JS_CODE source must be TypeScript under `sy-lowcode-app-workspace/src/js-code-nodes/<scriptCode>/index.ts`. When validating or creating, the CLI runs `pnpm build-js-code --script <scriptCode>`, which runs TypeScript validation first, bundles to `dist/js-code-nodes/<scriptCode>/index.cjs`, uploads the bundle, and replaces `sourceFile.localPath` with immutable snapshot metadata. The backend verifies snapshot `sha256`, runs it in the trusted Node runtime, applies the node timeout (`30000` ms by default), stores execution logs, and writes the returned value to the node output and `variables.node_<nodeId>`.
|
|
93
|
+
|
|
94
|
+
Scripts can export `export default async function (ctx) {}` or `module.exports = async (ctx) => {}`. The runtime exposes `ctx.triggerEvent`, `ctx.formData`, `ctx.workflowData`, `ctx.operator`, `ctx.app`, `ctx.variables`, `ctx.methods.*`, `ctx.platform.api.*`, `ctx.utils`, `require`, `process`, and `Buffer`. Use `ctx.methods.queryOneData/queryManyData/updateOneData/updateDataByFormInstanceId/updateManyData/createOneData/terminateProcess/getAllParentDepartments` for platform-side data and process operations.
|
|
95
|
+
|
|
96
|
+
Example `src/js-code-nodes/sync_customer/index.ts`:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
export default async function syncCustomer(ctx) {
|
|
100
|
+
const current = ctx.formData?.current || {};
|
|
101
|
+
const appType = ctx.app.appType;
|
|
102
|
+
const customerNo = current.customer_no;
|
|
103
|
+
|
|
104
|
+
const customer = await ctx.methods.queryOneData(appType, "FORM_CUSTOMER", {
|
|
105
|
+
customer_no: customerNo,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (customer) {
|
|
109
|
+
await ctx.methods.updateOneData(
|
|
110
|
+
appType,
|
|
111
|
+
"FORM_CUSTOMER",
|
|
112
|
+
{ customer_no: customerNo },
|
|
113
|
+
{ last_approved_at: new Date().toISOString() }
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const log = await ctx.methods.createOneData(appType, "FORM_SYNC_LOG", {
|
|
118
|
+
source: "workflow",
|
|
119
|
+
customer_no: customerNo,
|
|
120
|
+
result: customer ? "updated" : "missing",
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
customerFound: Boolean(customer),
|
|
125
|
+
logId: log?.formInstanceId || log?.id,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
```
|
|
91
129
|
|
|
92
130
|
Field permission config lives in `flowConfig` by node ID:
|
|
93
131
|
|
|
@@ -44,7 +44,9 @@ Use `workflow pull` to inspect the live definition. Use logical workflow codes l
|
|
|
44
44
|
|
|
45
45
|
## JS_CODE V2
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
JS_CODE is the backend execution escape hatch for workflow and automation. Use it when the logic must run on the server after a backend trigger, such as a fixed cron schedule, a form date-field schedule, a form submit/update/delete/field-change event, or a workflow approval/process event. It is appropriate for cross-form data queries, create/update/batch update operations, process termination, platform API calls, external HTTP calls, and complex orchestration that the frontend cannot handle reliably.
|
|
48
|
+
|
|
49
|
+
Do not use JS_CODE for simple UI interactions, ordinary form validation, display-only page behavior, or logic that belongs in a normal React code page. For non-trivial backend logic, prefer JS_CODE V2 trusted Node scripts over large inline snippets. AI-authored JS_CODE source must be TypeScript:
|
|
48
50
|
|
|
49
51
|
1. Put source in `sy-lowcode-app-workspace/src/js-code-nodes/<scriptCode>/index.ts`.
|
|
50
52
|
2. Run `pnpm build-js-code --script <scriptCode>`. This command runs TypeScript validation first and only bundles after `tsc` passes.
|
|
@@ -68,7 +70,14 @@ For non-trivial logic, prefer JS_CODE V2 trusted Node scripts over large inline
|
|
|
68
70
|
|
|
69
71
|
The CLI requires `sourceFile.localPath` to point to `src/js-code-nodes/<scriptCode>/index.ts`. During validate/create it runs `pnpm build-js-code --script <scriptCode>`, uploads the generated `dist/js-code-nodes/<scriptCode>/index.cjs` to `/file/js-code-snapshot/upload`, verifies the server snapshot metadata, and replaces it with `{ bucketName, objectName, sha256, ... }`.
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
The backend verifies the uploaded snapshot sha256 before execution, runs it in the trusted Node runtime, applies the node timeout (`30000` ms by default), stores console/runtime logs in the execution record, and writes the returned value to the node output and `variables.node_<nodeId>`.
|
|
74
|
+
|
|
75
|
+
Inside the TypeScript script, prefer `export default async function (ctx) {}` or `module.exports = async (ctx) => {}`. The runtime exposes:
|
|
76
|
+
|
|
77
|
+
- Context: `ctx.triggerEvent`, `ctx.formData`, `ctx.workflowData`, `ctx.operator`, `ctx.app`, `ctx.variables`, and `ctx.node`.
|
|
78
|
+
- Data/process methods: `ctx.methods.queryOneData`, `queryManyData`, `updateOneData`, `updateDataByFormInstanceId`, `updateManyData`, `createOneData`, `terminateProcess`, and `getAllParentDepartments`.
|
|
79
|
+
- Platform API bridge: `ctx.platform.api.get/post/put/patch/delete/request` for `/openxiangda-api/v1`.
|
|
80
|
+
- Node runtime helpers: `require`, `process`, `Buffer`, `ctx.utils`, `ctx.utils.http`, and `ctx.console`.
|
|
72
81
|
|
|
73
82
|
## Automation Flow
|
|
74
83
|
|
package/package.json
CHANGED
|
@@ -127,6 +127,13 @@ interface PageDataSourceDescriptor {
|
|
|
127
127
|
defaultFilter?: SearchExpression | string;
|
|
128
128
|
[key: string]: unknown;
|
|
129
129
|
}
|
|
130
|
+
type CustomPageEntryMode = "app-shell" | "plain-page";
|
|
131
|
+
interface CustomPageEntryConfig {
|
|
132
|
+
mode?: CustomPageEntryMode | string;
|
|
133
|
+
hidePlatformNav?: boolean;
|
|
134
|
+
defaultRoute?: string;
|
|
135
|
+
[key: string]: unknown;
|
|
136
|
+
}
|
|
130
137
|
interface PageInfo {
|
|
131
138
|
id: string;
|
|
132
139
|
code: string;
|
|
@@ -138,6 +145,7 @@ interface PageInfo {
|
|
|
138
145
|
status: string;
|
|
139
146
|
props: Record<string, unknown>;
|
|
140
147
|
route: Record<string, unknown> | object;
|
|
148
|
+
entry?: CustomPageEntryConfig;
|
|
141
149
|
dataSources: PageDataSourceDescriptor[];
|
|
142
150
|
capabilities: Record<string, unknown>;
|
|
143
151
|
version?: string;
|
|
@@ -164,6 +172,8 @@ interface PageNavigationApi {
|
|
|
164
172
|
*/
|
|
165
173
|
pushPage(pageKey: string, query?: Record<string, unknown>): void;
|
|
166
174
|
replacePage(pageKey: string, query?: Record<string, unknown>): void;
|
|
175
|
+
pushRoute(route: string, query?: Record<string, unknown>): void;
|
|
176
|
+
replaceRoute(route: string, query?: Record<string, unknown>): void;
|
|
167
177
|
updateQuery(query: Record<string, unknown>): void;
|
|
168
178
|
setHash(hash: string): void;
|
|
169
179
|
back(): void;
|
|
@@ -856,4 +866,4 @@ declare const usePageRoute: () => PageRouteInfo;
|
|
|
856
866
|
|
|
857
867
|
declare const usePageSdk: () => PageSdk;
|
|
858
868
|
|
|
859
|
-
export { type ApiPermissionListParams, type ApproveTaskParams, type AssignPermissionsParams, type AssignRolesParams, type BatchAddUsersToRoleParams, type BatchSendNotificationByTypeParams, type ChangeUserRoleParams, type ConnectorCallParams, type ConnectorInvokeParams, type ConnectorInvokeResult, type ConnectorRequestBodyType, type ConnectorResponseType, type CreateApiPermissionParams, type CreateFormPermissionGroupDto, type CreatePagePermissionGroupDto, type CreateRoleParams, type CreateUiPermissionParams, type CreateUserParams, type CurrentUserDepartmentParents, type DataManagementConfigParams, type DataManagementFilterState, type DataPermissionConditionDto, type DataPermissionDto, type DataPermissionRuleDto, type FieldPermissionDto, type FormAdvancedSearchParams, type FormChangeRecordParams, type FormCreateParams, type FormExportParams, type FormGetDetailParams, type FormImportParams, type FormPermissionGroup, type FormRemoveParams, type FormSearchParams, type FormUpdateParams, type GetParentDepartmentsOptions, type GetProcessInstanceParams, type GetUserRolesParams, type ImportExportRecordDownloadParams, type ImportExportRecordQuery, type InstanceStatus, type NotificationChannel, type NotificationMessageRecord, type PageApiPermissionRecord, type PageApiResponse, type PageAppInfo, type PageBinaryResponse, type PageBridgeApi, type PageContext, type PageDataManagementConfig, type PageDataSourceDescriptor, type PageDepartmentInfo, type PageDepartmentRecord, type PageHttpMethod, type PageInfo, type PageListResult, type PageMessageApi, type PageModalApi, type PageNavigationApi, type PageOffsetListResult, type PagePermissionGroup, type PagePermissionInfo, PageProvider, type PageQueryValue, type PageRequestOptions, type PageRoleRecord, type PageRouteInfo, type PageScope, type PageSdk, type PageSdkError, type PageSdkMeta, type PageTransportDownloadPayload, type PageTransportRequestPayload, type PageUiPermissionRecord, type PageUiPermissionType, type PageUserInfo, type PageUserRecord, type PageUserType, type ProcessApproveAction, type QueryFormPermissionGroupDto, type QueryPagePermissionGroupDto, type RoleListParams, type RoleUsersParams, type SaveDataManagementConfigParams, type SearchComponentName, type SearchExpression, type SearchFieldKey, type SearchGroup, type SearchLogic, type SearchOperator, type SearchRule, type SearchSortItem, type SearchSystemField, type SendNotificationByTypeParams, type SendNotificationResult, type SubFormRule, type SwitchAppRoleParams, type SwitchPlatformRoleParams, type TerminateProcessInstanceParams, type TriggerCallbackTaskParams, type UiPermissionListParams, type UpdateApiPermissionParams, type UpdateFormPermissionGroupDto, type UpdatePagePermissionGroupDto, type UpdateRoleParams, type UpdateUiPermissionParams, type UpdateUserParams, type UserListParams, type UserMenuPermissionsResponse, type ValidateUserParams, type ViewFieldPermissionValue, type ViewOperationPermission, type ViewPermissionSummary, createPageSdk, createReactPage, useCurrentUser, useDataSource, useFormViewPermissions, useMessage, useModal, useNavigation, usePageContext, usePageProps, usePageRoute, usePageSdk };
|
|
869
|
+
export { type ApiPermissionListParams, type ApproveTaskParams, type AssignPermissionsParams, type AssignRolesParams, type BatchAddUsersToRoleParams, type BatchSendNotificationByTypeParams, type ChangeUserRoleParams, type ConnectorCallParams, type ConnectorInvokeParams, type ConnectorInvokeResult, type ConnectorRequestBodyType, type ConnectorResponseType, type CreateApiPermissionParams, type CreateFormPermissionGroupDto, type CreatePagePermissionGroupDto, type CreateRoleParams, type CreateUiPermissionParams, type CreateUserParams, type CurrentUserDepartmentParents, type CustomPageEntryConfig, type CustomPageEntryMode, type DataManagementConfigParams, type DataManagementFilterState, type DataPermissionConditionDto, type DataPermissionDto, type DataPermissionRuleDto, type FieldPermissionDto, type FormAdvancedSearchParams, type FormChangeRecordParams, type FormCreateParams, type FormExportParams, type FormGetDetailParams, type FormImportParams, type FormPermissionGroup, type FormRemoveParams, type FormSearchParams, type FormUpdateParams, type GetParentDepartmentsOptions, type GetProcessInstanceParams, type GetUserRolesParams, type ImportExportRecordDownloadParams, type ImportExportRecordQuery, type InstanceStatus, type NotificationChannel, type NotificationMessageRecord, type PageApiPermissionRecord, type PageApiResponse, type PageAppInfo, type PageBinaryResponse, type PageBridgeApi, type PageContext, type PageDataManagementConfig, type PageDataSourceDescriptor, type PageDepartmentInfo, type PageDepartmentRecord, type PageHttpMethod, type PageInfo, type PageListResult, type PageMessageApi, type PageModalApi, type PageNavigationApi, type PageOffsetListResult, type PagePermissionGroup, type PagePermissionInfo, PageProvider, type PageQueryValue, type PageRequestOptions, type PageRoleRecord, type PageRouteInfo, type PageScope, type PageSdk, type PageSdkError, type PageSdkMeta, type PageTransportDownloadPayload, type PageTransportRequestPayload, type PageUiPermissionRecord, type PageUiPermissionType, type PageUserInfo, type PageUserRecord, type PageUserType, type ProcessApproveAction, type QueryFormPermissionGroupDto, type QueryPagePermissionGroupDto, type RoleListParams, type RoleUsersParams, type SaveDataManagementConfigParams, type SearchComponentName, type SearchExpression, type SearchFieldKey, type SearchGroup, type SearchLogic, type SearchOperator, type SearchRule, type SearchSortItem, type SearchSystemField, type SendNotificationByTypeParams, type SendNotificationResult, type SubFormRule, type SwitchAppRoleParams, type SwitchPlatformRoleParams, type TerminateProcessInstanceParams, type TriggerCallbackTaskParams, type UiPermissionListParams, type UpdateApiPermissionParams, type UpdateFormPermissionGroupDto, type UpdatePagePermissionGroupDto, type UpdateRoleParams, type UpdateUiPermissionParams, type UpdateUserParams, type UserListParams, type UserMenuPermissionsResponse, type ValidateUserParams, type ViewFieldPermissionValue, type ViewOperationPermission, type ViewPermissionSummary, createPageSdk, createReactPage, useCurrentUser, useDataSource, useFormViewPermissions, useMessage, useModal, useNavigation, usePageContext, usePageProps, usePageRoute, usePageSdk };
|
|
@@ -127,6 +127,13 @@ interface PageDataSourceDescriptor {
|
|
|
127
127
|
defaultFilter?: SearchExpression | string;
|
|
128
128
|
[key: string]: unknown;
|
|
129
129
|
}
|
|
130
|
+
type CustomPageEntryMode = "app-shell" | "plain-page";
|
|
131
|
+
interface CustomPageEntryConfig {
|
|
132
|
+
mode?: CustomPageEntryMode | string;
|
|
133
|
+
hidePlatformNav?: boolean;
|
|
134
|
+
defaultRoute?: string;
|
|
135
|
+
[key: string]: unknown;
|
|
136
|
+
}
|
|
130
137
|
interface PageInfo {
|
|
131
138
|
id: string;
|
|
132
139
|
code: string;
|
|
@@ -138,6 +145,7 @@ interface PageInfo {
|
|
|
138
145
|
status: string;
|
|
139
146
|
props: Record<string, unknown>;
|
|
140
147
|
route: Record<string, unknown> | object;
|
|
148
|
+
entry?: CustomPageEntryConfig;
|
|
141
149
|
dataSources: PageDataSourceDescriptor[];
|
|
142
150
|
capabilities: Record<string, unknown>;
|
|
143
151
|
version?: string;
|
|
@@ -164,6 +172,8 @@ interface PageNavigationApi {
|
|
|
164
172
|
*/
|
|
165
173
|
pushPage(pageKey: string, query?: Record<string, unknown>): void;
|
|
166
174
|
replacePage(pageKey: string, query?: Record<string, unknown>): void;
|
|
175
|
+
pushRoute(route: string, query?: Record<string, unknown>): void;
|
|
176
|
+
replaceRoute(route: string, query?: Record<string, unknown>): void;
|
|
167
177
|
updateQuery(query: Record<string, unknown>): void;
|
|
168
178
|
setHash(hash: string): void;
|
|
169
179
|
back(): void;
|
|
@@ -856,4 +866,4 @@ declare const usePageRoute: () => PageRouteInfo;
|
|
|
856
866
|
|
|
857
867
|
declare const usePageSdk: () => PageSdk;
|
|
858
868
|
|
|
859
|
-
export { type ApiPermissionListParams, type ApproveTaskParams, type AssignPermissionsParams, type AssignRolesParams, type BatchAddUsersToRoleParams, type BatchSendNotificationByTypeParams, type ChangeUserRoleParams, type ConnectorCallParams, type ConnectorInvokeParams, type ConnectorInvokeResult, type ConnectorRequestBodyType, type ConnectorResponseType, type CreateApiPermissionParams, type CreateFormPermissionGroupDto, type CreatePagePermissionGroupDto, type CreateRoleParams, type CreateUiPermissionParams, type CreateUserParams, type CurrentUserDepartmentParents, type DataManagementConfigParams, type DataManagementFilterState, type DataPermissionConditionDto, type DataPermissionDto, type DataPermissionRuleDto, type FieldPermissionDto, type FormAdvancedSearchParams, type FormChangeRecordParams, type FormCreateParams, type FormExportParams, type FormGetDetailParams, type FormImportParams, type FormPermissionGroup, type FormRemoveParams, type FormSearchParams, type FormUpdateParams, type GetParentDepartmentsOptions, type GetProcessInstanceParams, type GetUserRolesParams, type ImportExportRecordDownloadParams, type ImportExportRecordQuery, type InstanceStatus, type NotificationChannel, type NotificationMessageRecord, type PageApiPermissionRecord, type PageApiResponse, type PageAppInfo, type PageBinaryResponse, type PageBridgeApi, type PageContext, type PageDataManagementConfig, type PageDataSourceDescriptor, type PageDepartmentInfo, type PageDepartmentRecord, type PageHttpMethod, type PageInfo, type PageListResult, type PageMessageApi, type PageModalApi, type PageNavigationApi, type PageOffsetListResult, type PagePermissionGroup, type PagePermissionInfo, PageProvider, type PageQueryValue, type PageRequestOptions, type PageRoleRecord, type PageRouteInfo, type PageScope, type PageSdk, type PageSdkError, type PageSdkMeta, type PageTransportDownloadPayload, type PageTransportRequestPayload, type PageUiPermissionRecord, type PageUiPermissionType, type PageUserInfo, type PageUserRecord, type PageUserType, type ProcessApproveAction, type QueryFormPermissionGroupDto, type QueryPagePermissionGroupDto, type RoleListParams, type RoleUsersParams, type SaveDataManagementConfigParams, type SearchComponentName, type SearchExpression, type SearchFieldKey, type SearchGroup, type SearchLogic, type SearchOperator, type SearchRule, type SearchSortItem, type SearchSystemField, type SendNotificationByTypeParams, type SendNotificationResult, type SubFormRule, type SwitchAppRoleParams, type SwitchPlatformRoleParams, type TerminateProcessInstanceParams, type TriggerCallbackTaskParams, type UiPermissionListParams, type UpdateApiPermissionParams, type UpdateFormPermissionGroupDto, type UpdatePagePermissionGroupDto, type UpdateRoleParams, type UpdateUiPermissionParams, type UpdateUserParams, type UserListParams, type UserMenuPermissionsResponse, type ValidateUserParams, type ViewFieldPermissionValue, type ViewOperationPermission, type ViewPermissionSummary, createPageSdk, createReactPage, useCurrentUser, useDataSource, useFormViewPermissions, useMessage, useModal, useNavigation, usePageContext, usePageProps, usePageRoute, usePageSdk };
|
|
869
|
+
export { type ApiPermissionListParams, type ApproveTaskParams, type AssignPermissionsParams, type AssignRolesParams, type BatchAddUsersToRoleParams, type BatchSendNotificationByTypeParams, type ChangeUserRoleParams, type ConnectorCallParams, type ConnectorInvokeParams, type ConnectorInvokeResult, type ConnectorRequestBodyType, type ConnectorResponseType, type CreateApiPermissionParams, type CreateFormPermissionGroupDto, type CreatePagePermissionGroupDto, type CreateRoleParams, type CreateUiPermissionParams, type CreateUserParams, type CurrentUserDepartmentParents, type CustomPageEntryConfig, type CustomPageEntryMode, type DataManagementConfigParams, type DataManagementFilterState, type DataPermissionConditionDto, type DataPermissionDto, type DataPermissionRuleDto, type FieldPermissionDto, type FormAdvancedSearchParams, type FormChangeRecordParams, type FormCreateParams, type FormExportParams, type FormGetDetailParams, type FormImportParams, type FormPermissionGroup, type FormRemoveParams, type FormSearchParams, type FormUpdateParams, type GetParentDepartmentsOptions, type GetProcessInstanceParams, type GetUserRolesParams, type ImportExportRecordDownloadParams, type ImportExportRecordQuery, type InstanceStatus, type NotificationChannel, type NotificationMessageRecord, type PageApiPermissionRecord, type PageApiResponse, type PageAppInfo, type PageBinaryResponse, type PageBridgeApi, type PageContext, type PageDataManagementConfig, type PageDataSourceDescriptor, type PageDepartmentInfo, type PageDepartmentRecord, type PageHttpMethod, type PageInfo, type PageListResult, type PageMessageApi, type PageModalApi, type PageNavigationApi, type PageOffsetListResult, type PagePermissionGroup, type PagePermissionInfo, PageProvider, type PageQueryValue, type PageRequestOptions, type PageRoleRecord, type PageRouteInfo, type PageScope, type PageSdk, type PageSdkError, type PageSdkMeta, type PageTransportDownloadPayload, type PageTransportRequestPayload, type PageUiPermissionRecord, type PageUiPermissionType, type PageUserInfo, type PageUserRecord, type PageUserType, type ProcessApproveAction, type QueryFormPermissionGroupDto, type QueryPagePermissionGroupDto, type RoleListParams, type RoleUsersParams, type SaveDataManagementConfigParams, type SearchComponentName, type SearchExpression, type SearchFieldKey, type SearchGroup, type SearchLogic, type SearchOperator, type SearchRule, type SearchSortItem, type SearchSystemField, type SendNotificationByTypeParams, type SendNotificationResult, type SubFormRule, type SwitchAppRoleParams, type SwitchPlatformRoleParams, type TerminateProcessInstanceParams, type TriggerCallbackTaskParams, type UiPermissionListParams, type UpdateApiPermissionParams, type UpdateFormPermissionGroupDto, type UpdatePagePermissionGroupDto, type UpdateRoleParams, type UpdateUiPermissionParams, type UpdateUserParams, type UserListParams, type UserMenuPermissionsResponse, type ValidateUserParams, type ViewFieldPermissionValue, type ViewOperationPermission, type ViewPermissionSummary, createPageSdk, createReactPage, useCurrentUser, useDataSource, useFormViewPermissions, useMessage, useModal, useNavigation, usePageContext, usePageProps, usePageRoute, usePageSdk };
|
|
@@ -66,6 +66,7 @@ export function buildDirectPagePublishPayload(config, pages) {
|
|
|
66
66
|
code: page.config.code,
|
|
67
67
|
name: page.config.name,
|
|
68
68
|
description: page.config.description || "",
|
|
69
|
+
entry: page.config.entry || {},
|
|
69
70
|
route: page.config.route,
|
|
70
71
|
props: page.config.props || {},
|
|
71
72
|
dataSources: page.config.dataSources || [],
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
5
|
|
|
3
6
|
import { getFormBundleUrl, getPageAssetUrl } from "./load-config.mjs";
|
|
4
|
-
import { discoverPages } from "./pages.mjs";
|
|
5
7
|
import { buildDirectPagePublishPayload } from "./register-payload.mjs";
|
|
6
8
|
|
|
7
9
|
const config = {
|
|
@@ -25,10 +27,47 @@ const config = {
|
|
|
25
27
|
|
|
26
28
|
describe("register payload helpers", () => {
|
|
27
29
|
it("discovers publishable code pages", async () => {
|
|
28
|
-
const
|
|
30
|
+
const workspaceRoot = await mkdtemp(
|
|
31
|
+
join(process.cwd(), ".tmp-openxiangda-pages-test-"),
|
|
32
|
+
);
|
|
33
|
+
const previousWorkspaceRoot = process.env.LOWCODE_WORKSPACE_ROOT;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const pageDir = join(workspaceRoot, "src/pages/customer-dashboard");
|
|
37
|
+
await mkdir(pageDir, { recursive: true });
|
|
38
|
+
await writeFile(join(pageDir, "index.tsx"), "export {};\n", "utf8");
|
|
39
|
+
await writeFile(
|
|
40
|
+
join(pageDir, "App.tsx"),
|
|
41
|
+
"export default function App() { return null; }\n",
|
|
42
|
+
"utf8",
|
|
43
|
+
);
|
|
44
|
+
await writeFile(
|
|
45
|
+
join(pageDir, "page.config.ts"),
|
|
46
|
+
`export default {
|
|
47
|
+
code: "customer-dashboard",
|
|
48
|
+
name: "客户经营看板",
|
|
49
|
+
route: { pathKey: "customer-dashboard" },
|
|
50
|
+
};
|
|
51
|
+
`,
|
|
52
|
+
"utf8",
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
process.env.LOWCODE_WORKSPACE_ROOT = workspaceRoot;
|
|
56
|
+
vi.resetModules();
|
|
57
|
+
const { discoverPages } = await import("./pages.mjs");
|
|
58
|
+
const pages = await discoverPages("customer-dashboard");
|
|
29
59
|
|
|
30
|
-
|
|
31
|
-
|
|
60
|
+
expect(pages).toHaveLength(1);
|
|
61
|
+
expect(pages[0].config.code).toBe("customer-dashboard");
|
|
62
|
+
} finally {
|
|
63
|
+
if (previousWorkspaceRoot === undefined) {
|
|
64
|
+
delete process.env.LOWCODE_WORKSPACE_ROOT;
|
|
65
|
+
} else {
|
|
66
|
+
process.env.LOWCODE_WORKSPACE_ROOT = previousWorkspaceRoot;
|
|
67
|
+
}
|
|
68
|
+
vi.resetModules();
|
|
69
|
+
await rm(workspaceRoot, { recursive: true, force: true });
|
|
70
|
+
}
|
|
32
71
|
});
|
|
33
72
|
|
|
34
73
|
it("builds stable form and page asset URLs from one build id", () => {
|
|
@@ -46,6 +85,11 @@ describe("register payload helpers", () => {
|
|
|
46
85
|
config: {
|
|
47
86
|
code: "customer-dashboard",
|
|
48
87
|
name: "客户经营看板",
|
|
88
|
+
entry: {
|
|
89
|
+
mode: "app-shell",
|
|
90
|
+
hidePlatformNav: true,
|
|
91
|
+
defaultRoute: "home",
|
|
92
|
+
},
|
|
49
93
|
route: { pathKey: "customer-dashboard" },
|
|
50
94
|
props: { title: "客户经营看板" },
|
|
51
95
|
dataSources: [],
|
|
@@ -56,6 +100,11 @@ describe("register payload helpers", () => {
|
|
|
56
100
|
expect(payload.pages[0].runtime.entryUrl).toBe(
|
|
57
101
|
"https://bucket.oss-cn-hangzhou.aliyuncs.com/lowcode/app-workspace/dev/1.2.3/BUILD_001/pages/customer-dashboard/index.js",
|
|
58
102
|
);
|
|
103
|
+
expect(payload.pages[0].entry).toEqual({
|
|
104
|
+
mode: "app-shell",
|
|
105
|
+
hidePlatformNav: true,
|
|
106
|
+
defaultRoute: "home",
|
|
107
|
+
});
|
|
59
108
|
expect(JSON.stringify(payload)).not.toMatch(/manifest/i);
|
|
60
109
|
});
|
|
61
110
|
|
|
@@ -26,6 +26,42 @@ export interface AppWorkspaceConfig {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export type CustomPageEntryMode = "app-shell" | "plain-page";
|
|
30
|
+
|
|
31
|
+
export interface CustomPageEntryConfig {
|
|
32
|
+
mode?: CustomPageEntryMode | string;
|
|
33
|
+
hidePlatformNav?: boolean;
|
|
34
|
+
defaultRoute?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface CustomPageConfig {
|
|
38
|
+
code: string;
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
publish?: boolean;
|
|
42
|
+
route?: {
|
|
43
|
+
pathKey?: string;
|
|
44
|
+
allowQueryKeys?: string[];
|
|
45
|
+
allowHash?: boolean;
|
|
46
|
+
subRouteMode?: "hash" | "memory" | string;
|
|
47
|
+
defaultQuery?: Record<string, unknown>;
|
|
48
|
+
};
|
|
49
|
+
entry?: CustomPageEntryConfig;
|
|
50
|
+
props?: Record<string, unknown>;
|
|
51
|
+
dataSources?: Array<Record<string, unknown>>;
|
|
52
|
+
menu?: {
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
name?: string;
|
|
55
|
+
parentId?: string | null;
|
|
56
|
+
icon?: string | null;
|
|
57
|
+
};
|
|
58
|
+
cssIsolation?: "namespace" | "shadow" | "none";
|
|
59
|
+
}
|
|
60
|
+
|
|
29
61
|
export function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {
|
|
30
62
|
return config;
|
|
31
63
|
}
|
|
64
|
+
|
|
65
|
+
export function definePageConfig<T extends CustomPageConfig>(config: T): T {
|
|
66
|
+
return config;
|
|
67
|
+
}
|