openxiangda 1.0.86 → 1.0.88
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 +30 -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 +109 -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 +72 -4
- package/package.json +1 -1
- package/packages/sdk/dist/runtime/index.cjs +3624 -3394
- 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 +3083 -2855
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/react.cjs +2826 -121
- package/packages/sdk/dist/runtime/react.cjs.map +1 -1
- package/packages/sdk/dist/runtime/react.d.mts +1400 -2
- package/packages/sdk/dist/runtime/react.d.ts +1400 -2
- package/packages/sdk/dist/runtime/react.mjs +2782 -89
- 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,113 @@ 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": { "scenario": "score-link" }
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Tickets are single-use by default. Set policy `ticketConfig.singleUse: false` only when the link is intentionally reusable.
|
|
271
|
+
|
|
272
|
+
### POST `/apps/:appType/public/session`
|
|
273
|
+
|
|
274
|
+
Does not require an existing login. Creates a scoped public guest session.
|
|
275
|
+
|
|
276
|
+
Body:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"policyCode": "public_register",
|
|
281
|
+
"routeCode": "public.register",
|
|
282
|
+
"path": "/view/APP_XXX/public/register",
|
|
283
|
+
"ticket": "optional-ticket",
|
|
284
|
+
"guestIdentifier": "public:APP_XXX:browser-id",
|
|
285
|
+
"domain": "example.com",
|
|
286
|
+
"userAgent": "browser"
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The response returns a scoped bearer token. New React SPA apps must use `PublicAccessGate` or `createPublicAccessClient` so follow-up runtime/bootstrap, dataView, function, and connector calls include `Authorization: Bearer <token>`. Do not depend on auth cookies for public sessions.
|
|
291
|
+
|
|
292
|
+
Returns the normal guest token payload plus `extra.publicAccess`.
|
|
187
293
|
|
|
188
294
|
### GET `/apps/:appType/menus`
|
|
189
295
|
|
|
@@ -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
|
+
`PublicAccessGate` stores the returned bearer token in the runtime provider and injects it into follow-up SDK requests. If you call `createPublicAccessClient` directly outside the provider, pass the returned `accessToken` as `Authorization: Bearer <token>` for follow-up APIs. 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,74 @@ 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, "singleUse": true },
|
|
161
|
+
"grants": {
|
|
162
|
+
"dataViews": ["public_score_lookup"]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Ticket 默认单次使用,首次换取 public session 后立即失效;只有明确配置 `ticketConfig.singleUse: false` 的业务场景才允许复用。
|
|
168
|
+
|
|
169
|
+
`grants.forms` 可以写本地 `formCode`,CLI 发布时会解析为真实 `formUuid`。
|
|
170
|
+
|
|
171
|
+
## 3. Connector — `src/resources/connectors/<code>.json`
|
|
105
172
|
|
|
106
173
|
```json
|
|
107
174
|
{
|
|
@@ -140,7 +207,7 @@ const data = await sdk.connector.call("crm.getCustomer", { body: { keyword } });
|
|
|
140
207
|
|
|
141
208
|
不要把 `authConfig` 里的真实 secret 写进 manifest;用 placeholder,由平台管理员在后台覆盖。完整字段见 [`connector-resources.md`](connector-resources.md)。
|
|
142
209
|
|
|
143
|
-
##
|
|
210
|
+
## 4. Data View — `src/resources/data-views/<code>.json`
|
|
144
211
|
|
|
145
212
|
选择规则:
|
|
146
213
|
|
|
@@ -488,11 +555,12 @@ export default async function (ctx) {
|
|
|
488
555
|
{ "fields": ["customerCode"], "unique": true },
|
|
489
556
|
{ "fields": ["status", "ownerDept"] }
|
|
490
557
|
],
|
|
491
|
-
"dataManagement": { "enabled": true, "default": "list" }
|
|
492
|
-
"publicAccess": { "enabled": false }
|
|
558
|
+
"dataManagement": { "enabled": true, "default": "list" }
|
|
493
559
|
}
|
|
494
560
|
```
|
|
495
561
|
|
|
562
|
+
`publicAccess` 表单 setting 只用于旧 `sy-lowcode-view` 兼容。新 React SPA 公开页面必须使用 `src/resources/routes/` + `src/resources/public-access/` + `PublicAccessGate`。
|
|
563
|
+
|
|
496
564
|
## 12. Menu — `src/resources/menus/<code>.json`
|
|
497
565
|
|
|
498
566
|
```json
|