openxiangda 1.0.86 → 1.0.87
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/README.md +28 -0
- package/lib/cli.js +391 -0
- package/openxiangda-skills/SKILL.md +5 -1
- package/openxiangda-skills/references/architecture-design.md +29 -0
- package/openxiangda-skills/references/openxiangda-api.md +105 -3
- package/openxiangda-skills/references/pages/page-sdk.md +35 -0
- package/openxiangda-skills/references/permissions-settings.md +39 -2
- package/openxiangda-skills/references/resource-manifest-cheatsheet.md +70 -4
- package/package.json +1 -1
- package/packages/sdk/dist/runtime/index.cjs +3590 -3388
- package/packages/sdk/dist/runtime/index.cjs.map +1 -1
- package/packages/sdk/dist/runtime/index.d.mts +4 -1001
- package/packages/sdk/dist/runtime/index.d.ts +4 -1001
- package/packages/sdk/dist/runtime/index.mjs +3049 -2849
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/react.cjs +2793 -116
- package/packages/sdk/dist/runtime/react.cjs.map +1 -1
- package/packages/sdk/dist/runtime/react.d.mts +1394 -2
- package/packages/sdk/dist/runtime/react.d.ts +1394 -2
- package/packages/sdk/dist/runtime/react.mjs +2749 -84
- package/packages/sdk/dist/runtime/react.mjs.map +1 -1
- package/templates/openxiangda-react-spa/AGENTS.md +29 -0
- package/templates/openxiangda-react-spa/src/app/router.tsx +21 -1
- package/templates/openxiangda-react-spa/src/pages/public/PublicRegisterPage.tsx +15 -0
- package/templates/openxiangda-react-spa/src/resources/permissions/page-groups/public-visitor.json +8 -0
- package/templates/openxiangda-react-spa/src/resources/public-access/public-register.json +14 -0
- package/templates/openxiangda-react-spa/src/resources/routes/public-register.json +8 -0
- package/templates/openxiangda-react-spa/tsconfig.app.json +1 -1
- package/templates/openxiangda-react-spa/vite.config.ts +1 -1
- package/packages/sdk/dist/openxiangdaProvider-CaXMpsnK.d.mts +0 -328
- package/packages/sdk/dist/openxiangdaProvider-CaXMpsnK.d.ts +0 -328
|
@@ -166,11 +166,11 @@ Body:
|
|
|
166
166
|
|
|
167
167
|
### GET `/apps/:appType/forms/:formUuid/public-access`
|
|
168
168
|
|
|
169
|
-
Requires Bearer token. Returns public/guest access config for the form.
|
|
169
|
+
Requires Bearer token. Returns legacy public/guest access config for the form. This endpoint is only for old `sy-lowcode-view` compatibility.
|
|
170
170
|
|
|
171
171
|
### PUT `/apps/:appType/forms/:formUuid/public-access`
|
|
172
172
|
|
|
173
|
-
Requires Bearer token. Creates or updates public/guest access config.
|
|
173
|
+
Requires Bearer token. Creates or updates legacy public/guest access config.
|
|
174
174
|
|
|
175
175
|
Body:
|
|
176
176
|
|
|
@@ -183,7 +183,109 @@ Body:
|
|
|
183
183
|
|
|
184
184
|
### DELETE `/apps/:appType/forms/:formUuid/public-access`
|
|
185
185
|
|
|
186
|
-
Requires Bearer token. Deletes public/guest access config for the form.
|
|
186
|
+
Requires Bearer token. Deletes legacy public/guest access config for the form.
|
|
187
|
+
|
|
188
|
+
## React SPA Public Access
|
|
189
|
+
|
|
190
|
+
New React SPA apps use `/view/:appType/public/*`, route resources, public access policies, and a scoped public session. Do not use `?publicAccess=guest` for new apps.
|
|
191
|
+
|
|
192
|
+
### GET `/apps/:appType/routes`
|
|
193
|
+
|
|
194
|
+
Requires Bearer token. Lists route resources.
|
|
195
|
+
|
|
196
|
+
### POST `/apps/:appType/routes`
|
|
197
|
+
|
|
198
|
+
Requires Bearer token. Creates a route resource.
|
|
199
|
+
|
|
200
|
+
Body:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"code": "public.register",
|
|
205
|
+
"title": "公开报名",
|
|
206
|
+
"kind": "page",
|
|
207
|
+
"pathPattern": "/view/:appType/public/register",
|
|
208
|
+
"publicAccess": "guest",
|
|
209
|
+
"publicPolicyCode": "public_register"
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### PUT `/apps/:appType/routes/:code`
|
|
214
|
+
|
|
215
|
+
Requires Bearer token. Updates a route resource.
|
|
216
|
+
|
|
217
|
+
### DELETE `/apps/:appType/routes/:code`
|
|
218
|
+
|
|
219
|
+
Requires Bearer token. Deletes a route resource.
|
|
220
|
+
|
|
221
|
+
### GET `/apps/:appType/public-access/policies`
|
|
222
|
+
|
|
223
|
+
Requires Bearer token. Lists public access policies.
|
|
224
|
+
|
|
225
|
+
### POST `/apps/:appType/public-access/policies`
|
|
226
|
+
|
|
227
|
+
Requires Bearer token. Creates a public access policy.
|
|
228
|
+
|
|
229
|
+
Body:
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"code": "public_register",
|
|
234
|
+
"name": "公开报名入口",
|
|
235
|
+
"enabled": true,
|
|
236
|
+
"mode": "guest",
|
|
237
|
+
"routeCode": "public.register",
|
|
238
|
+
"pathPattern": "/view/:appType/public/register",
|
|
239
|
+
"externalRoleCodes": ["external_visitor"],
|
|
240
|
+
"grants": {
|
|
241
|
+
"forms": ["FORM_UUID"],
|
|
242
|
+
"dataViews": ["public_registration_lookup"],
|
|
243
|
+
"functions": ["submit_public_registration"],
|
|
244
|
+
"connectors": ["sms.sendCode"]
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### PUT `/apps/:appType/public-access/policies/:code`
|
|
250
|
+
|
|
251
|
+
Requires Bearer token. Updates a public access policy.
|
|
252
|
+
|
|
253
|
+
### DELETE `/apps/:appType/public-access/policies/:code`
|
|
254
|
+
|
|
255
|
+
Requires Bearer token. Deletes a public access policy.
|
|
256
|
+
|
|
257
|
+
### POST `/apps/:appType/public-access/policies/:code/tickets`
|
|
258
|
+
|
|
259
|
+
Requires Bearer token. Creates a ticket for a `mode: "ticket"` policy.
|
|
260
|
+
|
|
261
|
+
Body:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"expiresAt": "2026-06-18T12:00:00.000Z",
|
|
266
|
+
"subject": { "usage": "single-use" }
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### POST `/apps/:appType/public/session`
|
|
271
|
+
|
|
272
|
+
Does not require an existing login. Creates a scoped public guest session.
|
|
273
|
+
|
|
274
|
+
Body:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"policyCode": "public_register",
|
|
279
|
+
"routeCode": "public.register",
|
|
280
|
+
"path": "/view/APP_XXX/public/register",
|
|
281
|
+
"ticket": "optional-ticket",
|
|
282
|
+
"guestIdentifier": "public:APP_XXX:browser-id",
|
|
283
|
+
"domain": "example.com",
|
|
284
|
+
"userAgent": "browser"
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Returns the normal guest token payload plus `extra.publicAccess`.
|
|
187
289
|
|
|
188
290
|
### GET `/apps/:appType/menus`
|
|
189
291
|
|
|
@@ -15,6 +15,7 @@ Guidelines:
|
|
|
15
15
|
- Use `sdk.connector.invoke`, `sdk.connector.call("connector.api")`, or `sdk.connector.download` for external services. The SDK calls the platform runtime connector endpoint; it must not call third-party domains directly.
|
|
16
16
|
- Use `sdk.notification.sendByType` and `batchSendByType` for reusable business messages. Custom notification types must be declared in `src/resources/notifications/` and published with `openxiangda resource publish`.
|
|
17
17
|
- Use `createAuthClient` from `openxiangda/runtime` or `LoginPage` / `useAuth` from `openxiangda/runtime/react` for application login pages. Auth provider App Functions return identity assertions only; platform auth owns create/bind/reject/token decisions.
|
|
18
|
+
- Use `PublicAccessGate` from `openxiangda/runtime/react` or `createPublicAccessClient` from `openxiangda/runtime` for React SPA public pages under `/view/:appType/public/*`. Do not append old `?publicAccess=guest` links in new apps.
|
|
18
19
|
- For the current user's department hierarchy, use `sdk.department.getCurrentUserParentDepartments()`; do not hardcode `GET /department/:id/parentDepartments` in page code.
|
|
19
20
|
- Use `sdk.auth.logoutAndRedirect({ loginUrl })` for user logout when the page should return after login. It calls the platform logout endpoint, appends the current page URL as `callback`, and redirects to the login URL. Use `sdk.auth.logout()` only when the page wants to handle redirect itself.
|
|
20
21
|
- Use `sdk.role.getMyRoles()`, `sdk.role.getCurrentRole()`, and `sdk.role.switchAppRole()` for current-user app role switching. Pass `roleId: ""` to switch back to all app roles.
|
|
@@ -141,6 +142,40 @@ const result = await auth.phoneCodeLogin({
|
|
|
141
142
|
|
|
142
143
|
For phone-code auth, the App Function provider receives `event`, `appType`, `method`, `credential`, `requestId`, `request`, and `challenge`. It may return `{ ok, providerState }` for send and `{ ok, identity }` for verify. It must not return `token`, `accessToken`, `refreshToken`, cookies, or mutate platform account tables.
|
|
143
144
|
|
|
145
|
+
Public access route:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { PublicAccessGate } from "openxiangda/runtime/react";
|
|
149
|
+
|
|
150
|
+
export function PublicRegisterRoute() {
|
|
151
|
+
return (
|
|
152
|
+
<PublicAccessGate
|
|
153
|
+
policyCode="public_register"
|
|
154
|
+
routeCode="public.register"
|
|
155
|
+
>
|
|
156
|
+
<PublicRegisterPage />
|
|
157
|
+
</PublicAccessGate>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Standalone public session client:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { createPublicAccessClient } from "openxiangda/runtime";
|
|
166
|
+
|
|
167
|
+
const publicAccess = createPublicAccessClient({ appType, servicePrefix: "/service" });
|
|
168
|
+
|
|
169
|
+
await publicAccess.startSession({
|
|
170
|
+
policyCode: "public_register",
|
|
171
|
+
routeCode: "public.register",
|
|
172
|
+
path: window.location.pathname,
|
|
173
|
+
ticket: new URLSearchParams(window.location.search).get("ticket") || undefined,
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The matching resources must exist under `src/resources/routes/` and `src/resources/public-access/`. Public guest access to forms, data views, functions, and connectors is denied unless the policy `grants` explicitly names that resource.
|
|
178
|
+
|
|
144
179
|
Logout and current-user role switching:
|
|
145
180
|
|
|
146
181
|
```ts
|
|
@@ -185,7 +185,44 @@ Data management config is stored as an opaque JSON object by the platform. Keep
|
|
|
185
185
|
}
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
-
Public
|
|
188
|
+
## Public Access
|
|
189
|
+
|
|
190
|
+
新 React SPA 应用的公开访问使用应用路由和公开策略资源:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"code": "public.register",
|
|
195
|
+
"pathPattern": "/view/:appType/public/register",
|
|
196
|
+
"publicAccess": "guest",
|
|
197
|
+
"publicPolicyCode": "public_register"
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"code": "public_register",
|
|
204
|
+
"mode": "guest",
|
|
205
|
+
"routeCode": "public.register",
|
|
206
|
+
"externalRoleCodes": ["external_visitor"],
|
|
207
|
+
"grants": {
|
|
208
|
+
"forms": ["registration_form"],
|
|
209
|
+
"dataViews": ["public_registration_lookup"],
|
|
210
|
+
"functions": ["submit_public_registration"],
|
|
211
|
+
"connectors": ["sms.sendCode"]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Rules:
|
|
217
|
+
|
|
218
|
+
- Public routes live under `/view/:appType/public/*`.
|
|
219
|
+
- Public users get a scoped `publicAccess` claim, not a normal app role assignment.
|
|
220
|
+
- Use virtual external role codes, such as `external_visitor`, in page/form/dataView permission groups.
|
|
221
|
+
- Form/dataView/function/connector access is denied unless the policy explicitly grants it.
|
|
222
|
+
- `mode: "ticket"` requires a valid ticket for sensitive links.
|
|
223
|
+
- Do not use `?publicAccess=guest` for new React SPA apps.
|
|
224
|
+
|
|
225
|
+
Legacy form public access config:
|
|
189
226
|
|
|
190
227
|
```json
|
|
191
228
|
{
|
|
@@ -194,4 +231,4 @@ Public access config:
|
|
|
194
231
|
}
|
|
195
232
|
```
|
|
196
233
|
|
|
197
|
-
|
|
234
|
+
This old form-level setting is resolved by `appType + formUuid` and exists only for old `sy-lowcode-view` compatibility.
|
|
@@ -101,7 +101,72 @@ await auth.phoneCodeLogin({ phone, code, challengeId: sent.challengeId });
|
|
|
101
101
|
|
|
102
102
|
设计前必须确认启用方式、注册策略、身份匹配键、provider 边界、默认权限、安全参数、第三方配置归属。
|
|
103
103
|
|
|
104
|
-
## 1.
|
|
104
|
+
## 1. Public Route — `src/resources/routes/<code>.json`
|
|
105
|
+
|
|
106
|
+
新 React SPA 公开页使用 `/view/:appType/public/*`,不要再使用旧 `?publicAccess=guest`。
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"code": "public.register",
|
|
111
|
+
"title": "公开报名",
|
|
112
|
+
"kind": "page",
|
|
113
|
+
"pathPattern": "/view/:appType/public/register",
|
|
114
|
+
"publicAccess": "guest",
|
|
115
|
+
"publicPolicyCode": "public_register"
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
React Router 中用 `PublicAccessGate` 创建 scoped public session:
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { PublicAccessGate } from "openxiangda/runtime/react";
|
|
123
|
+
|
|
124
|
+
<PublicAccessGate policyCode="public_register" routeCode="public.register">
|
|
125
|
+
<PublicRegisterPage />
|
|
126
|
+
</PublicAccessGate>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 2. Public Access Policy — `src/resources/public-access/<code>.json`
|
|
130
|
+
|
|
131
|
+
公开策略声明外部角色和可访问资源。未显式 grant 的 form/dataView/function/connector 默认拒绝;grant 后仍受对应后端权限组控制。
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"code": "public_register",
|
|
136
|
+
"name": "公开报名入口",
|
|
137
|
+
"mode": "guest",
|
|
138
|
+
"routeCode": "public.register",
|
|
139
|
+
"pathPattern": "/view/:appType/public/register",
|
|
140
|
+
"externalRoleCodes": ["external_visitor"],
|
|
141
|
+
"grants": {
|
|
142
|
+
"forms": ["registration_form"],
|
|
143
|
+
"dataViews": ["public_registration_lookup"],
|
|
144
|
+
"functions": ["submit_public_registration"],
|
|
145
|
+
"connectors": ["sms.sendCode"]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Ticket 模式:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"code": "public_score_lookup",
|
|
155
|
+
"name": "公开成绩查询",
|
|
156
|
+
"mode": "ticket",
|
|
157
|
+
"routeCode": "public.scoreLookup",
|
|
158
|
+
"pathPattern": "/view/:appType/public/score",
|
|
159
|
+
"externalRoleCodes": ["external_ticket_holder"],
|
|
160
|
+
"ticketConfig": { "ttlSeconds": 1800 },
|
|
161
|
+
"grants": {
|
|
162
|
+
"dataViews": ["public_score_lookup"]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`grants.forms` 可以写本地 `formCode`,CLI 发布时会解析为真实 `formUuid`。
|
|
168
|
+
|
|
169
|
+
## 3. Connector — `src/resources/connectors/<code>.json`
|
|
105
170
|
|
|
106
171
|
```json
|
|
107
172
|
{
|
|
@@ -140,7 +205,7 @@ const data = await sdk.connector.call("crm.getCustomer", { body: { keyword } });
|
|
|
140
205
|
|
|
141
206
|
不要把 `authConfig` 里的真实 secret 写进 manifest;用 placeholder,由平台管理员在后台覆盖。完整字段见 [`connector-resources.md`](connector-resources.md)。
|
|
142
207
|
|
|
143
|
-
##
|
|
208
|
+
## 4. Data View — `src/resources/data-views/<code>.json`
|
|
144
209
|
|
|
145
210
|
选择规则:
|
|
146
211
|
|
|
@@ -488,11 +553,12 @@ export default async function (ctx) {
|
|
|
488
553
|
{ "fields": ["customerCode"], "unique": true },
|
|
489
554
|
{ "fields": ["status", "ownerDept"] }
|
|
490
555
|
],
|
|
491
|
-
"dataManagement": { "enabled": true, "default": "list" }
|
|
492
|
-
"publicAccess": { "enabled": false }
|
|
556
|
+
"dataManagement": { "enabled": true, "default": "list" }
|
|
493
557
|
}
|
|
494
558
|
```
|
|
495
559
|
|
|
560
|
+
`publicAccess` 表单 setting 只用于旧 `sy-lowcode-view` 兼容。新 React SPA 公开页面必须使用 `src/resources/routes/` + `src/resources/public-access/` + `PublicAccessGate`。
|
|
561
|
+
|
|
496
562
|
## 12. Menu — `src/resources/menus/<code>.json`
|
|
497
563
|
|
|
498
564
|
```json
|