openxiangda-cli 2.0.0-alpha.18 → 2.0.0-alpha.182
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 +6 -14
- package/bin/run.js +79 -1
- package/dist/base.d.ts +60 -5
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +197 -10
- package/dist/base.js.map +1 -1
- package/dist/commands/accept.d.ts +28 -0
- package/dist/commands/accept.d.ts.map +1 -0
- package/dist/commands/accept.js +21 -0
- package/dist/commands/accept.js.map +1 -0
- package/dist/commands/admin.d.ts +32 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +25 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/cancel.d.ts +19 -1
- package/dist/commands/cancel.d.ts.map +1 -1
- package/dist/commands/cancel.js +1 -1
- package/dist/commands/cancel.js.map +1 -1
- package/dist/commands/check.d.ts +23 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +21 -4
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/context.d.ts +27 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +10 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/create.d.ts +39 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +457 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/deploy.d.ts +28 -8
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +30 -18
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +23 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +28 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts +30 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +20 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/login.d.ts +29 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/{auth/login.js → login.js} +27 -9
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +22 -2
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +9 -5
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/retry.d.ts +19 -1
- package/dist/commands/retry.d.ts.map +1 -1
- package/dist/commands/retry.js +5 -2
- package/dist/commands/retry.js.map +1 -1
- package/dist/commands/rollback.d.ts +23 -4
- package/dist/commands/rollback.d.ts.map +1 -1
- package/dist/commands/rollback.js +18 -5
- package/dist/commands/rollback.js.map +1 -1
- package/dist/commands/skill.d.ts +32 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +50 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/spec.d.ts +42 -0
- package/dist/commands/spec.d.ts.map +1 -0
- package/dist/commands/spec.js +123 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/commands/start.d.ts +28 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +18 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +20 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +11 -4
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/stop.d.ts +28 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +18 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/create-workspace.d.ts +67 -0
- package/dist/create-workspace.d.ts.map +1 -0
- package/dist/create-workspace.js +631 -0
- package/dist/create-workspace.js.map +1 -0
- package/dist/studio-events.d.ts +9 -0
- package/dist/studio-events.d.ts.map +1 -0
- package/dist/studio-events.js +30 -0
- package/dist/studio-events.js.map +1 -0
- package/dist/toolchain-capsule.d.ts +4 -0
- package/dist/toolchain-capsule.d.ts.map +1 -0
- package/dist/toolchain-capsule.js +116 -0
- package/dist/toolchain-capsule.js.map +1 -0
- package/package.json +17 -10
- package/template/.dockerignore +23 -0
- package/template/.env.example +3 -0
- package/template/AGENTS.md +26 -0
- package/template/README.md +45 -0
- package/template/_gitignore +14 -0
- package/template/apps/web/data-api-live.e2e.html +15 -0
- package/template/apps/web/e2e/client-fixture.ts +5 -0
- package/template/apps/web/e2e/component-defaults-fixture.css +15 -0
- package/template/apps/web/e2e/data-api-live-fixture.tsx +162 -0
- package/template/apps/web/e2e/data-api-live.spec.ts +144 -0
- package/template/apps/web/e2e/field-protocol-fixture.tsx +387 -0
- package/template/apps/web/e2e/field-protocol.spec.ts +285 -0
- package/template/apps/web/e2e/mobile-files.spec.ts +96 -0
- package/template/apps/web/e2e/mobile-reference-fixture.tsx +314 -0
- package/template/apps/web/e2e/mobile-reference.spec.ts +360 -0
- package/template/apps/web/e2e/mobile-selection.spec.ts +199 -0
- package/template/apps/web/e2e/resource-experience-fixture.tsx +491 -0
- package/template/apps/web/e2e/resource-platform-mock.ts +202 -0
- package/template/apps/web/e2e/resources.spec.ts +488 -0
- package/template/apps/web/e2e/standard-admin.spec.ts +511 -0
- package/template/apps/web/e2e/workflow-entry-fixture.tsx +107 -0
- package/template/apps/web/e2e/workflow-entry.spec.ts +556 -0
- package/template/apps/web/e2e/workflow-experience-fixture.tsx +338 -0
- package/template/apps/web/e2e/workflow.spec.ts +1265 -0
- package/template/apps/web/field-protocol.e2e.html +22 -0
- package/template/apps/web/index.html +12 -0
- package/template/apps/web/mobile-reference.e2e.html +27 -0
- package/template/apps/web/package.json +34 -0
- package/template/apps/web/playwright.config.ts +47 -0
- package/template/apps/web/resource-experience.e2e.html +16 -0
- package/template/apps/web/scripts/check.mjs +43 -0
- package/template/apps/web/scripts/verify-build.mjs +6 -0
- package/template/apps/web/src/document.css +5 -0
- package/template/apps/web/src/main.tsx +66 -0
- package/template/apps/web/src/user-end/tailwind.css +5 -0
- package/template/apps/web/test/contracts.test.ts +163 -0
- package/template/apps/web/test/loopback.test.ts +68 -0
- package/template/apps/web/test/standard-user-surfaces.typecheck.tsx +27 -0
- package/template/apps/web/tsconfig.json +12 -0
- package/template/apps/web/vite.config.ts +43 -0
- package/template/apps/web/workflow-entry.e2e.html +15 -0
- package/template/apps/web/workflow-experience.e2e.html +15 -0
- package/template/appspec/app.md +52 -0
- package/template/openxiangda.config.ts +55 -0
- package/template/package.json +28 -0
- package/template/packages/contracts/package.json +23 -0
- package/template/packages/contracts/src/generated.ts +265 -0
- package/template/packages/contracts/src/index.ts +1 -0
- package/template/packages/contracts/tsconfig.json +9 -0
- package/template/pnpm-workspace.yaml +7 -0
- package/template/tsconfig.base.json +13 -0
- package/dist/commands/app/create.d.ts +0 -15
- package/dist/commands/app/create.d.ts.map +0 -1
- package/dist/commands/app/create.js +0 -42
- package/dist/commands/app/create.js.map +0 -1
- package/dist/commands/app/info.d.ts +0 -9
- package/dist/commands/app/info.d.ts.map +0 -1
- package/dist/commands/app/info.js +0 -10
- package/dist/commands/app/info.js.map +0 -1
- package/dist/commands/app/link.d.ts +0 -10
- package/dist/commands/app/link.d.ts.map +0 -1
- package/dist/commands/app/link.js +0 -16
- package/dist/commands/app/link.js.map +0 -1
- package/dist/commands/app/provision.d.ts +0 -9
- package/dist/commands/app/provision.d.ts.map +0 -1
- package/dist/commands/app/provision.js +0 -10
- package/dist/commands/app/provision.js.map +0 -1
- package/dist/commands/auth/login.d.ts +0 -11
- package/dist/commands/auth/login.d.ts.map +0 -1
- package/dist/commands/auth/login.js.map +0 -1
- package/dist/commands/auth/logout.d.ts +0 -6
- package/dist/commands/auth/logout.d.ts.map +0 -1
- package/dist/commands/auth/logout.js +0 -30
- package/dist/commands/auth/logout.js.map +0 -1
- package/dist/commands/auth/status.d.ts +0 -6
- package/dist/commands/auth/status.d.ts.map +0 -1
- package/dist/commands/auth/status.js +0 -60
- package/dist/commands/auth/status.js.map +0 -1
- package/dist/commands/build.d.ts +0 -11
- package/dist/commands/build.d.ts.map +0 -1
- package/dist/commands/build.js +0 -23
- package/dist/commands/build.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -9
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js +0 -7
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/event/delivery/list.d.ts +0 -10
- package/dist/commands/event/delivery/list.d.ts.map +0 -1
- package/dist/commands/event/delivery/list.js +0 -14
- package/dist/commands/event/delivery/list.js.map +0 -1
- package/dist/commands/event/delivery/replay.d.ts +0 -13
- package/dist/commands/event/delivery/replay.d.ts.map +0 -1
- package/dist/commands/event/delivery/replay.js +0 -16
- package/dist/commands/event/delivery/replay.js.map +0 -1
- package/dist/commands/event/subscription/list.d.ts +0 -9
- package/dist/commands/event/subscription/list.d.ts.map +0 -1
- package/dist/commands/event/subscription/list.js +0 -10
- package/dist/commands/event/subscription/list.js.map +0 -1
- package/dist/commands/event/subscription/rotate-secret.d.ts +0 -15
- package/dist/commands/event/subscription/rotate-secret.d.ts.map +0 -1
- package/dist/commands/event/subscription/rotate-secret.js +0 -33
- package/dist/commands/event/subscription/rotate-secret.js.map +0 -1
- package/dist/commands/event/subscription/status.d.ts +0 -14
- package/dist/commands/event/subscription/status.d.ts.map +0 -1
- package/dist/commands/event/subscription/status.js +0 -19
- package/dist/commands/event/subscription/status.js.map +0 -1
- package/dist/commands/event/timer/list.d.ts +0 -9
- package/dist/commands/event/timer/list.d.ts.map +0 -1
- package/dist/commands/event/timer/list.js +0 -10
- package/dist/commands/event/timer/list.js.map +0 -1
- package/dist/commands/event/timer/status.d.ts +0 -14
- package/dist/commands/event/timer/status.d.ts.map +0 -1
- package/dist/commands/event/timer/status.js +0 -19
- package/dist/commands/event/timer/status.js.map +0 -1
- package/dist/commands/generate.d.ts +0 -10
- package/dist/commands/generate.d.ts.map +0 -1
- package/dist/commands/generate.js +0 -8
- package/dist/commands/generate.js.map +0 -1
- package/dist/commands/oauth/audit/list.d.ts +0 -12
- package/dist/commands/oauth/audit/list.d.ts.map +0 -1
- package/dist/commands/oauth/audit/list.js +0 -20
- package/dist/commands/oauth/audit/list.js.map +0 -1
- package/dist/commands/oauth/client/create.d.ts +0 -13
- package/dist/commands/oauth/client/create.d.ts.map +0 -1
- package/dist/commands/oauth/client/create.js +0 -34
- package/dist/commands/oauth/client/create.js.map +0 -1
- package/dist/commands/oauth/client/list.d.ts +0 -9
- package/dist/commands/oauth/client/list.d.ts.map +0 -1
- package/dist/commands/oauth/client/list.js +0 -10
- package/dist/commands/oauth/client/list.js.map +0 -1
- package/dist/commands/oauth/client/revoke.d.ts +0 -12
- package/dist/commands/oauth/client/revoke.d.ts.map +0 -1
- package/dist/commands/oauth/client/revoke.js +0 -12
- package/dist/commands/oauth/client/revoke.js.map +0 -1
- package/dist/commands/oauth/client/rotate.d.ts +0 -13
- package/dist/commands/oauth/client/rotate.d.ts.map +0 -1
- package/dist/commands/oauth/client/rotate.js +0 -20
- package/dist/commands/oauth/client/rotate.js.map +0 -1
- package/dist/commands/oauth/client/update.d.ts +0 -15
- package/dist/commands/oauth/client/update.d.ts.map +0 -1
- package/dist/commands/oauth/client/update.js +0 -23
- package/dist/commands/oauth/client/update.js.map +0 -1
- package/dist/commands/oauth/runtime/rotate.d.ts +0 -12
- package/dist/commands/oauth/runtime/rotate.d.ts.map +0 -1
- package/dist/commands/oauth/runtime/rotate.js +0 -31
- package/dist/commands/oauth/runtime/rotate.js.map +0 -1
- package/dist/commands/oauth/runtime/status.d.ts +0 -10
- package/dist/commands/oauth/runtime/status.d.ts.map +0 -1
- package/dist/commands/oauth/runtime/status.js +0 -17
- package/dist/commands/oauth/runtime/status.js.map +0 -1
- package/dist/commands/promote.d.ts +0 -13
- package/dist/commands/promote.d.ts.map +0 -1
- package/dist/commands/promote.js +0 -9
- package/dist/commands/promote.js.map +0 -1
- package/dist/commands/secret/audit/list.d.ts +0 -14
- package/dist/commands/secret/audit/list.d.ts.map +0 -1
- package/dist/commands/secret/audit/list.js +0 -16
- package/dist/commands/secret/audit/list.js.map +0 -1
- package/dist/commands/secret/create.d.ts +0 -18
- package/dist/commands/secret/create.d.ts.map +0 -1
- package/dist/commands/secret/create.js +0 -33
- package/dist/commands/secret/create.js.map +0 -1
- package/dist/commands/secret/delete.d.ts +0 -15
- package/dist/commands/secret/delete.d.ts.map +0 -1
- package/dist/commands/secret/delete.js +0 -20
- package/dist/commands/secret/delete.js.map +0 -1
- package/dist/commands/secret/list.d.ts +0 -10
- package/dist/commands/secret/list.d.ts.map +0 -1
- package/dist/commands/secret/list.js +0 -14
- package/dist/commands/secret/list.js.map +0 -1
- package/dist/commands/secret/rotate.d.ts +0 -18
- package/dist/commands/secret/rotate.d.ts.map +0 -1
- package/dist/commands/secret/rotate.js +0 -30
- package/dist/commands/secret/rotate.js.map +0 -1
- package/dist/commands/secret/update.d.ts +0 -17
- package/dist/commands/secret/update.d.ts.map +0 -1
- package/dist/commands/secret/update.js +0 -37
- package/dist/commands/secret/update.js.map +0 -1
- package/dist/commands/skill/install.d.ts +0 -11
- package/dist/commands/skill/install.d.ts.map +0 -1
- package/dist/commands/skill/install.js +0 -52
- package/dist/commands/skill/install.js.map +0 -1
- package/dist/commands/skill/validate.d.ts +0 -9
- package/dist/commands/skill/validate.d.ts.map +0 -1
- package/dist/commands/skill/validate.js +0 -32
- package/dist/commands/skill/validate.js.map +0 -1
- package/dist/commands/test.d.ts +0 -9
- package/dist/commands/test.d.ts.map +0 -1
- package/dist/commands/test.js +0 -7
- package/dist/commands/test.js.map +0 -1
- package/dist/commands/workflow/provider/list.d.ts +0 -10
- package/dist/commands/workflow/provider/list.d.ts.map +0 -1
- package/dist/commands/workflow/provider/list.js +0 -14
- package/dist/commands/workflow/provider/list.js.map +0 -1
- package/dist/commands/workflow/provider/rotate.d.ts +0 -15
- package/dist/commands/workflow/provider/rotate.d.ts.map +0 -1
- package/dist/commands/workflow/provider/rotate.js +0 -24
- package/dist/commands/workflow/provider/rotate.js.map +0 -1
- package/dist/secret-value.d.ts +0 -5
- package/dist/secret-value.d.ts.map +0 -1
- package/dist/secret-value.js +0 -15
- package/dist/secret-value.js.map +0 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="openxiangda-runtime-base" content="/" />
|
|
7
|
+
<meta name="openxiangda-app-code" content="field-protocol-fixture" />
|
|
8
|
+
<meta name="openxiangda-environment" content="preproduction" />
|
|
9
|
+
<title>Field protocol acceptance</title>
|
|
10
|
+
<style>
|
|
11
|
+
html { background-color: rgb(248, 249, 250); }
|
|
12
|
+
body { color: rgb(31, 32, 33); font-size: 17px; font-family: monospace; }
|
|
13
|
+
a { color: rgb(101, 42, 140); }
|
|
14
|
+
output[data-saved-values] { display: block; overflow-wrap: anywhere; }
|
|
15
|
+
</style>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<a id="outside-mobile" href="#root">页面外部链接</a>
|
|
19
|
+
<div id="root"></div>
|
|
20
|
+
<script type="module" src="/e2e/field-protocol-fixture.tsx"></script>
|
|
21
|
+
</body>
|
|
22
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>OpenXiangda 应用</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="openxiangda-runtime-base" content="/" />
|
|
7
|
+
<meta name="openxiangda-app-code" content="field-protocol-fixture" />
|
|
8
|
+
<meta name="openxiangda-environment" content="preproduction" />
|
|
9
|
+
<title>移动表单组件</title>
|
|
10
|
+
<style>
|
|
11
|
+
body { margin: 0; }
|
|
12
|
+
.reference-form { min-height: 100dvh; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
|
|
13
|
+
.reference-form .oxa-mobile-header { position: sticky; top: 0; z-index: 5; }
|
|
14
|
+
.reference-form .reference-group { margin: 0 12px 16px; padding: 0 16px; background: white; border-radius: 10px; }
|
|
15
|
+
.reference-form .reference-group > div:last-child .oxa-mobile-field { border-bottom: 0; }
|
|
16
|
+
.reference-form .reference-group-title { font-size: 14px; font-weight: 400; color: #888; padding: 0 24px; margin: 20px 0 10px; }
|
|
17
|
+
.reference-form .reference-content { padding-bottom: 86px; }
|
|
18
|
+
.reference-form [data-field-code] { scroll-margin-top: 82px; }
|
|
19
|
+
.reference-form output { display: none; }
|
|
20
|
+
.reference-form .reference-notice { padding: 8px 24px; color: #1677ff; }
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<div id="root"></div>
|
|
25
|
+
<script type="module" src="/e2e/mobile-reference-fixture.tsx"></script>
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@app/web",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"check": "tsc -p tsconfig.json --noEmit && node scripts/check.mjs",
|
|
9
|
+
"test": "tsx --test test/*.test.ts",
|
|
10
|
+
"test:e2e": "playwright test",
|
|
11
|
+
"build": "tsc -p tsconfig.json --noEmit && vite build && node scripts/verify-build.mjs"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@ant-design/icons": "6.2.3",
|
|
15
|
+
"@refinedev/core": "5.0.12",
|
|
16
|
+
"antd": "6.4.3",
|
|
17
|
+
"openxiangda": "2.0.0-alpha.109",
|
|
18
|
+
"react": "19.2.8",
|
|
19
|
+
"react-dom": "19.2.8",
|
|
20
|
+
"react-router-dom": "7.8.2"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@playwright/test": "1.62.1",
|
|
24
|
+
"@tailwindcss/vite": "4.3.3",
|
|
25
|
+
"@types/node": "24.13.3",
|
|
26
|
+
"@types/react": "19.2.14",
|
|
27
|
+
"@types/react-dom": "19.2.3",
|
|
28
|
+
"@vitejs/plugin-react": "4.7.0",
|
|
29
|
+
"tailwindcss": "4.3.3",
|
|
30
|
+
"tsx": "4.23.12",
|
|
31
|
+
"typescript": "5.9.3",
|
|
32
|
+
"vite": "7.1.3"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineConfig } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
const e2ePort = resolveE2ePort();
|
|
4
|
+
const baseURL =
|
|
5
|
+
process.env.OPENXIANGDA_E2E_BASE_URL || `http://127.0.0.1:${e2ePort}`;
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
testDir: './e2e',
|
|
9
|
+
// The development server owns one mutable dependency-optimizer generation.
|
|
10
|
+
// Serial browser entrypoints prevent a second HTML graph from invalidating
|
|
11
|
+
// an in-flight transformed module during release acceptance.
|
|
12
|
+
workers: 1,
|
|
13
|
+
use: { baseURL, trace: 'retain-on-failure' },
|
|
14
|
+
webServer: process.env.OPENXIANGDA_E2E_BASE_URL
|
|
15
|
+
? undefined
|
|
16
|
+
: {
|
|
17
|
+
command: 'pnpm dev',
|
|
18
|
+
url: baseURL,
|
|
19
|
+
reuseExistingServer: false,
|
|
20
|
+
env: {
|
|
21
|
+
OPENXIANGDA_WEB_PORT: String(e2ePort),
|
|
22
|
+
OPENXIANGDA_ENVIRONMENT_KEY: 'production',
|
|
23
|
+
OPENXIANGDA_DEV_PROXY:
|
|
24
|
+
process.env.OPENXIANGDA_E2E_PLATFORM_URL ||
|
|
25
|
+
'http://127.0.0.1:7001',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function resolveE2ePort() {
|
|
31
|
+
const configured = process.env.OPENXIANGDA_E2E_PORT;
|
|
32
|
+
if (configured !== undefined) {
|
|
33
|
+
const port = Number(configured);
|
|
34
|
+
if (!Number.isInteger(port) || port < 1024 || port > 65535) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
'OPENXIANGDA_E2E_PORT must be an integer between 1024 and 65535'
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return port;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let hash = 2166136261;
|
|
43
|
+
for (const character of process.cwd()) {
|
|
44
|
+
hash = Math.imul(hash ^ character.charCodeAt(0), 16777619);
|
|
45
|
+
}
|
|
46
|
+
return 30_000 + ((hash >>> 0) % 30_000);
|
|
47
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="openxiangda-runtime-base" content="/" />
|
|
7
|
+
<meta name="openxiangda-app-code" content="openxiangda-application" />
|
|
8
|
+
<meta name="openxiangda-environment" content="preproduction" />
|
|
9
|
+
<title>Resource experience acceptance</title>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="outside-ui" style="height:0;overflow:hidden;font-family:monospace;color:rgb(31,32,33);background:rgb(248,249,250)">宿主页面</div>
|
|
13
|
+
<div id="root"></div>
|
|
14
|
+
<script type="module" src="/e2e/resource-experience-fixture.tsx"></script>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
const root = resolve(import.meta.dirname, '..');
|
|
5
|
+
const files = [];
|
|
6
|
+
function visit(directory) {
|
|
7
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
8
|
+
const path = join(directory, entry.name);
|
|
9
|
+
if (entry.isDirectory() && !['.umi', '.umi-production', '.turbopack'].includes(entry.name)) visit(path);
|
|
10
|
+
else if (/\.(?:ts|tsx)$/.test(entry.name)) files.push(path);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
visit(join(root, 'src'));
|
|
14
|
+
const lines = files.reduce((total, file) => total + readFileSync(file, 'utf8').split(/\r?\n/).length, 0);
|
|
15
|
+
// The shared Surface renderer is deliberately counted as application source;
|
|
16
|
+
// keep its small budget explicit instead of hiding it in generated output.
|
|
17
|
+
// Field Kit families are separate modules so a semantic field does not add a
|
|
18
|
+
// branch to one universal renderer. Keep explicit ceilings while allowing the
|
|
19
|
+
// complete 30-field standard kit to remain decomposed.
|
|
20
|
+
if (files.length > 36) throw new Error(`WEB_SOURCE_FILE_BUDGET_EXCEEDED:${files.length}>36`);
|
|
21
|
+
if (lines > 10_000) throw new Error(`WEB_BUSINESS_LOC_BUDGET_EXCEEDED:${lines}>10000`);
|
|
22
|
+
const source = files.map((file) => readFileSync(file, 'utf8')).join('\n');
|
|
23
|
+
for (const marker of [
|
|
24
|
+
'@umijs/',
|
|
25
|
+
'openxiangda-' + 'admin',
|
|
26
|
+
'openxiangda-' + 'user',
|
|
27
|
+
'instrument_query',
|
|
28
|
+
'instrument_save',
|
|
29
|
+
'function.invoke',
|
|
30
|
+
'authorization' + '-mode',
|
|
31
|
+
'focused' + '_role',
|
|
32
|
+
'/native/current' + '-user',
|
|
33
|
+
'college-' + 'am',
|
|
34
|
+
'user-' + 'wang',
|
|
35
|
+
'dept-' + 'am-test',
|
|
36
|
+
]) {
|
|
37
|
+
if (source.includes(marker)) throw new Error(`WEB_FORBIDDEN_MARKER:${marker}`);
|
|
38
|
+
}
|
|
39
|
+
const playwright = readFileSync(join(root, 'playwright.config.ts'), 'utf8');
|
|
40
|
+
if (!playwright.includes('reuseExistingServer: false')) {
|
|
41
|
+
throw new Error('WEB_E2E_MUST_NOT_REUSE_UNKNOWN_SERVER');
|
|
42
|
+
}
|
|
43
|
+
process.stdout.write(`Verified Vite/Refine web source: ${files.length} files, ${lines} LOC.\n`);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { verifyOpenXiangdaWebBuild } from 'openxiangda/testing';
|
|
2
|
+
|
|
3
|
+
const result = verifyOpenXiangdaWebBuild(new URL('../dist', import.meta.url));
|
|
4
|
+
process.stdout.write(
|
|
5
|
+
`Verified Vite build: ${result.totalBytes} bytes, ${result.totalJavaScriptGzipBytes} total gzip bytes, ${result.initialJavaScriptGzipBytes} initial gzip bytes.\n`
|
|
6
|
+
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom/client';
|
|
3
|
+
import {
|
|
4
|
+
defineApplicationContributions,
|
|
5
|
+
DefaultDesktopApplicationLoginSurface,
|
|
6
|
+
DefaultMobileApplicationLoginSurface,
|
|
7
|
+
OpenXiangdaApplication,
|
|
8
|
+
type ApplicationLoginSurfaceProps,
|
|
9
|
+
} from 'openxiangda/react';
|
|
10
|
+
import {
|
|
11
|
+
appCode,
|
|
12
|
+
appName,
|
|
13
|
+
appPerspectives,
|
|
14
|
+
appRoutes,
|
|
15
|
+
routeManifest,
|
|
16
|
+
authenticationSurfaces,
|
|
17
|
+
anonymousPublicAccess,
|
|
18
|
+
adminNavigation,
|
|
19
|
+
adminAccess,
|
|
20
|
+
adminPages,
|
|
21
|
+
resourceDefinitions,
|
|
22
|
+
workflowDefinitions,
|
|
23
|
+
} from '../../../packages/contracts/src/generated.js';
|
|
24
|
+
import './document.css';
|
|
25
|
+
import './user-end/tailwind.css';
|
|
26
|
+
import 'openxiangda/react/styles.css';
|
|
27
|
+
|
|
28
|
+
const ApplicationHome = () => <main>OpenXiangda 应用</main>;
|
|
29
|
+
const ApplicationHomeMobile = () => <main>OpenXiangda 移动应用</main>;
|
|
30
|
+
const BrandedDesktopLogin = (props: ApplicationLoginSurfaceProps) => (
|
|
31
|
+
<DefaultDesktopApplicationLoginSurface {...props} />
|
|
32
|
+
);
|
|
33
|
+
const BrandedMobileLogin = (props: ApplicationLoginSurfaceProps) => (
|
|
34
|
+
<DefaultMobileApplicationLoginSurface {...props} />
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const applicationContributions = defineApplicationContributions(
|
|
38
|
+
{ routes: appRoutes, authenticationSurfaces },
|
|
39
|
+
{
|
|
40
|
+
pages: {
|
|
41
|
+
applicationHome: ApplicationHome,
|
|
42
|
+
applicationHomeMobile: ApplicationHomeMobile,
|
|
43
|
+
},
|
|
44
|
+
authentication: {
|
|
45
|
+
applicationLogin: BrandedDesktopLogin,
|
|
46
|
+
applicationLoginMobile: BrandedMobileLogin,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
51
|
+
<React.StrictMode>
|
|
52
|
+
<OpenXiangdaApplication
|
|
53
|
+
appCode={appCode}
|
|
54
|
+
appName={appName}
|
|
55
|
+
adminAccess={adminAccess}
|
|
56
|
+
adminNavigation={adminNavigation}
|
|
57
|
+
adminPages={adminPages}
|
|
58
|
+
routeManifest={routeManifest}
|
|
59
|
+
contributions={applicationContributions}
|
|
60
|
+
publicAccess={anonymousPublicAccess}
|
|
61
|
+
perspectives={appPerspectives}
|
|
62
|
+
resourceDefinitions={resourceDefinitions}
|
|
63
|
+
workflows={workflowDefinitions}
|
|
64
|
+
/>
|
|
65
|
+
</React.StrictMode>,
|
|
66
|
+
);
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
3
|
+
import test from 'node:test';
|
|
4
|
+
import { readRuntimeMount, resolveApplicationBasename } from 'openxiangda/core';
|
|
5
|
+
import {
|
|
6
|
+
notificationTemplateCodes,
|
|
7
|
+
platformAuthManifest,
|
|
8
|
+
resourceCodes,
|
|
9
|
+
resourceDefinitions,
|
|
10
|
+
} from '../../../packages/contracts/src/generated.js';
|
|
11
|
+
|
|
12
|
+
test('clean template contains application declarations, document reset and one React entry', () => {
|
|
13
|
+
const config = readFileSync(
|
|
14
|
+
new URL('../../../openxiangda.config.ts', import.meta.url),
|
|
15
|
+
'utf8'
|
|
16
|
+
);
|
|
17
|
+
const source = readFileSync(new URL('../src/main.tsx', import.meta.url), 'utf8');
|
|
18
|
+
const productionSources = readdirSync(new URL('../src', import.meta.url), {
|
|
19
|
+
withFileTypes: true,
|
|
20
|
+
})
|
|
21
|
+
.filter(entry => entry.isFile())
|
|
22
|
+
.map(entry => entry.name)
|
|
23
|
+
.sort();
|
|
24
|
+
assert.deepEqual(productionSources, ['document.css', 'main.tsx']);
|
|
25
|
+
assert.deepEqual(Object.keys(resourceDefinitions).sort(), [...resourceCodes].sort());
|
|
26
|
+
assert.equal(
|
|
27
|
+
notificationTemplateCodes.applicationInformational,
|
|
28
|
+
'application.informational.standard'
|
|
29
|
+
);
|
|
30
|
+
assert.equal(platformAuthManifest?.protectedUserRouteCount, 2);
|
|
31
|
+
assert.equal(platformAuthManifest?.surfaces.length, 2);
|
|
32
|
+
assert.match(config, /defineOpenXiangdaApp/);
|
|
33
|
+
assert.match(source, /OpenXiangdaApplication/);
|
|
34
|
+
assert.match(source, /routes: appRoutes, authenticationSurfaces/);
|
|
35
|
+
assert.match(source, /DefaultDesktopApplicationLoginSurface/);
|
|
36
|
+
assert.match(source, /DefaultMobileApplicationLoginSurface/);
|
|
37
|
+
assert.match(source, /contributions=\{applicationContributions\}/);
|
|
38
|
+
assert.match(source, /publicAccess=\{anonymousPublicAccess\}/);
|
|
39
|
+
assert.match(source, /from 'openxiangda\/react'/);
|
|
40
|
+
assert.match(source, /openxiangda\/react\/styles\.css/);
|
|
41
|
+
const legacyMarkers = [
|
|
42
|
+
'instruments',
|
|
43
|
+
'colleges',
|
|
44
|
+
'仪器' + '资源管理',
|
|
45
|
+
'学院' + '字典',
|
|
46
|
+
'HGY',
|
|
47
|
+
'Instrument',
|
|
48
|
+
];
|
|
49
|
+
assert.doesNotMatch(`${config}\n${source}`, new RegExp(legacyMarkers.join('|')));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('application manifests expose one direct OpenXiangda dependency', () => {
|
|
53
|
+
for (const relative of [
|
|
54
|
+
'../../../package.json',
|
|
55
|
+
'../package.json',
|
|
56
|
+
...(existsSync(new URL('../../server/package.json', import.meta.url)) ? ['../../server/package.json'] : []),
|
|
57
|
+
]) {
|
|
58
|
+
const manifest = JSON.parse(
|
|
59
|
+
readFileSync(new URL(relative, import.meta.url), 'utf8')
|
|
60
|
+
) as Record<string, Record<string, string>>;
|
|
61
|
+
const dependencies = Object.entries({
|
|
62
|
+
...(manifest.dependencies || {}),
|
|
63
|
+
...(manifest.devDependencies || {}),
|
|
64
|
+
...(manifest.peerDependencies || {}),
|
|
65
|
+
}).filter(([name]) =>
|
|
66
|
+
name === 'openxiangda' || name.startsWith('openxiangda-')
|
|
67
|
+
);
|
|
68
|
+
assert.deepEqual(
|
|
69
|
+
dependencies.map(([name]) => name),
|
|
70
|
+
dependencies.length ? ['openxiangda'] : []
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('runtime metadata stays mount-scoped', () => {
|
|
76
|
+
const mount = readRuntimeMount(
|
|
77
|
+
name =>
|
|
78
|
+
({
|
|
79
|
+
'openxiangda-runtime-base': '/view/example-app/',
|
|
80
|
+
'openxiangda-app-code': 'example-app',
|
|
81
|
+
'openxiangda-environment': 'preproduction',
|
|
82
|
+
})[name]
|
|
83
|
+
);
|
|
84
|
+
assert.equal(resolveApplicationBasename(mount), '/view/example-app');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('resource E2E harness owns the standard export download response', () => {
|
|
88
|
+
const source = readFileSync(
|
|
89
|
+
new URL('../e2e/resource-platform-mock.ts', import.meta.url),
|
|
90
|
+
'utf8'
|
|
91
|
+
);
|
|
92
|
+
assert.match(source, /\/native\\\/data\\\/\(\[\^\/\]\+\)\\\/export\$/);
|
|
93
|
+
assert.match(source, /content-disposition/);
|
|
94
|
+
assert.match(source, /text\/csv/);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('published E2E harnesses do not write evidence into the platform source repository', () => {
|
|
98
|
+
const workflowSource = readFileSync(
|
|
99
|
+
new URL('../e2e/workflow.spec.ts', import.meta.url),
|
|
100
|
+
'utf8'
|
|
101
|
+
);
|
|
102
|
+
assert.doesNotMatch(workflowSource, /docs\/architecture|evidenceDirectory/);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('E2E experience fixtures explicitly own every tested route', () => {
|
|
106
|
+
const resourceFixture = readFileSync(
|
|
107
|
+
new URL('../e2e/resource-experience-fixture.tsx', import.meta.url),
|
|
108
|
+
'utf8'
|
|
109
|
+
);
|
|
110
|
+
for (let index = 1; index <= 12; index += 1) {
|
|
111
|
+
const code = `resource-${String(index).padStart(2, '0')}`;
|
|
112
|
+
const pageCode = `resource:${code}:list`;
|
|
113
|
+
assert.match(resourceFixture, new RegExp(`pageCode: '${pageCode}'`));
|
|
114
|
+
assert.match(resourceFixture, new RegExp(`code: '${pageCode}'`));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const workflowFixture = readFileSync(
|
|
118
|
+
new URL('../e2e/workflow-experience-fixture.tsx', import.meta.url),
|
|
119
|
+
'utf8'
|
|
120
|
+
);
|
|
121
|
+
assert.match(workflowFixture, /code: 'workflow:work-center'/);
|
|
122
|
+
assert.match(workflowFixture, /code: 'workflow:task'/);
|
|
123
|
+
assert.match(workflowFixture, /code: 'workflow:instance'/);
|
|
124
|
+
assert.match(workflowFixture, /path: '\/work-center'/);
|
|
125
|
+
assert.match(workflowFixture, /path: '\/tasks\/:taskId'/);
|
|
126
|
+
assert.match(workflowFixture, /path: '\/workflows\/:instanceId'/);
|
|
127
|
+
assert.doesNotMatch(
|
|
128
|
+
workflowFixture,
|
|
129
|
+
/path: '\/(?:m\/)?admin\/(?:todos|work-center|tasks|workflows)/
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('browser acceptance serializes the prewarmed Vite HTML entrypoints', () => {
|
|
134
|
+
const viteConfig = readFileSync(new URL('../vite.config.ts', import.meta.url), 'utf8');
|
|
135
|
+
const playwrightConfig = readFileSync(
|
|
136
|
+
new URL('../playwright.config.ts', import.meta.url),
|
|
137
|
+
'utf8'
|
|
138
|
+
);
|
|
139
|
+
const htmlEntries = readdirSync(new URL('..', import.meta.url))
|
|
140
|
+
.filter(name => name.endsWith('.e2e.html'))
|
|
141
|
+
.sort();
|
|
142
|
+
assert.deepEqual(htmlEntries, [
|
|
143
|
+
'data-api-live.e2e.html',
|
|
144
|
+
'field-protocol.e2e.html',
|
|
145
|
+
'mobile-reference.e2e.html',
|
|
146
|
+
'resource-experience.e2e.html',
|
|
147
|
+
'workflow-entry.e2e.html',
|
|
148
|
+
'workflow-experience.e2e.html',
|
|
149
|
+
]);
|
|
150
|
+
for (const entry of htmlEntries) {
|
|
151
|
+
assert.ok(viteConfig.includes(`'${entry}'`), `missing optimizeDeps entry ${entry}`);
|
|
152
|
+
}
|
|
153
|
+
assert.match(playwrightConfig, /workers:\s*1/);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('the platform package owns Web build verification policy', () => {
|
|
157
|
+
const verifier = readFileSync(
|
|
158
|
+
new URL('../scripts/verify-build.mjs', import.meta.url),
|
|
159
|
+
'utf8'
|
|
160
|
+
);
|
|
161
|
+
assert.match(verifier, /verifyOpenXiangdaWebBuild/);
|
|
162
|
+
assert.doesNotMatch(verifier, /2_650_000|800_000|600_000/);
|
|
163
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { createServer } from 'node:net';
|
|
5
|
+
import { networkInterfaces } from 'node:os';
|
|
6
|
+
import { dirname, join, resolve } from 'node:path';
|
|
7
|
+
import test from 'node:test';
|
|
8
|
+
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
|
|
11
|
+
test('Vite is reachable on loopback and not on a LAN interface', async t => {
|
|
12
|
+
const port = await freePort();
|
|
13
|
+
const root = resolve(import.meta.dirname, '..');
|
|
14
|
+
const vitePackagePath = require.resolve('vite/package.json');
|
|
15
|
+
const vitePackage = require(vitePackagePath) as { bin: { vite: string } };
|
|
16
|
+
const viteBin = join(dirname(vitePackagePath), vitePackage.bin.vite);
|
|
17
|
+
const child = spawn(process.execPath, [viteBin, '--port', String(port), '--strictPort'], {
|
|
18
|
+
cwd: root,
|
|
19
|
+
stdio: 'ignore',
|
|
20
|
+
env: {
|
|
21
|
+
...process.env,
|
|
22
|
+
OPENXIANGDA_WEB_PORT: String(port),
|
|
23
|
+
OPENXIANGDA_DEV_PROXY: 'http://127.0.0.1:7001',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
await waitFor(`http://127.0.0.1:${port}`);
|
|
28
|
+
const lan = Object.values(networkInterfaces())
|
|
29
|
+
.flat()
|
|
30
|
+
.find(address => address?.family === 'IPv4' && !address.internal)?.address;
|
|
31
|
+
if (!lan) {
|
|
32
|
+
t.diagnostic('No non-loopback IPv4 interface; loopback reachability verified.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
await assert.rejects(
|
|
36
|
+
fetch(`http://${lan}:${port}`, {
|
|
37
|
+
signal: AbortSignal.timeout(500),
|
|
38
|
+
})
|
|
39
|
+
);
|
|
40
|
+
} finally {
|
|
41
|
+
child.kill('SIGTERM');
|
|
42
|
+
await new Promise(resolve => child.once('exit', resolve));
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
async function freePort() {
|
|
47
|
+
return await new Promise<number>((resolve, reject) => {
|
|
48
|
+
const server = createServer();
|
|
49
|
+
server.once('error', reject);
|
|
50
|
+
server.listen({ host: '127.0.0.1', port: 0 }, () => {
|
|
51
|
+
const address = server.address();
|
|
52
|
+
const port = typeof address === 'object' && address ? address.port : 0;
|
|
53
|
+
server.close(error => (error ? reject(error) : resolve(port)));
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function waitFor(url: string) {
|
|
59
|
+
const deadline = Date.now() + 10_000;
|
|
60
|
+
while (Date.now() < deadline) {
|
|
61
|
+
try {
|
|
62
|
+
const response = await fetch(url);
|
|
63
|
+
if (response.ok) return;
|
|
64
|
+
} catch {}
|
|
65
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`VITE_READINESS_TIMEOUT:${url}`);
|
|
68
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineApplicationContributions,
|
|
3
|
+
type StandardApplicationTodoCenterProps,
|
|
4
|
+
type StandardUserPageFrameProps,
|
|
5
|
+
type StandardUserSurfaceContributions,
|
|
6
|
+
} from 'openxiangda/react';
|
|
7
|
+
|
|
8
|
+
function Frame({ children }: StandardUserPageFrameProps) {
|
|
9
|
+
return <>{children}</>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function Todo({ items }: StandardApplicationTodoCenterProps) {
|
|
13
|
+
return <>{items.length}</>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const standardUserSurfaces = {
|
|
17
|
+
frame: { desktop: Frame, mobile: Frame },
|
|
18
|
+
applicationTodoCenter: { desktop: Todo, mobile: Todo },
|
|
19
|
+
} satisfies StandardUserSurfaceContributions;
|
|
20
|
+
|
|
21
|
+
const contributions = defineApplicationContributions({}, {
|
|
22
|
+
pages: {},
|
|
23
|
+
standardUserSurfaces,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const exportedFrame = contributions.standardUserSurfaces?.frame.desktop;
|
|
27
|
+
void exportedFrame;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"exactOptionalPropertyTypes": false,
|
|
9
|
+
"types": ["vite/client", "node"]
|
|
10
|
+
},
|
|
11
|
+
"include": ["src", "test", "vite.config.ts", "playwright.config.ts"]
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import react from '@vitejs/plugin-react';
|
|
2
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
3
|
+
import { defineConfig } from 'vite';
|
|
4
|
+
|
|
5
|
+
const connectedProxy =
|
|
6
|
+
process.env.OPENXIANGDA_DEV_PROXY?.trim() || 'http://127.0.0.1:7001';
|
|
7
|
+
const port = Number(process.env.OPENXIANGDA_WEB_PORT || 5173);
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
plugins: [react(), tailwindcss()],
|
|
11
|
+
base: './',
|
|
12
|
+
optimizeDeps: {
|
|
13
|
+
entries: [
|
|
14
|
+
'index.html',
|
|
15
|
+
'data-api-live.e2e.html',
|
|
16
|
+
'field-protocol.e2e.html',
|
|
17
|
+
'mobile-reference.e2e.html',
|
|
18
|
+
'resource-experience.e2e.html',
|
|
19
|
+
'workflow-experience.e2e.html',
|
|
20
|
+
'workflow-entry.e2e.html',
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
server: {
|
|
24
|
+
host: '127.0.0.1',
|
|
25
|
+
port,
|
|
26
|
+
strictPort: true,
|
|
27
|
+
proxy: {
|
|
28
|
+
'/service': { target: connectedProxy, changeOrigin: false },
|
|
29
|
+
'/api': { target: connectedProxy, changeOrigin: false },
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
build: {
|
|
33
|
+
sourcemap: false,
|
|
34
|
+
rollupOptions: {
|
|
35
|
+
output: {
|
|
36
|
+
manualChunks: {
|
|
37
|
+
react: ['react', 'react-dom', 'react-router-dom'],
|
|
38
|
+
refine: ['@refinedev/core'],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="openxiangda-runtime-base" content="/" />
|
|
7
|
+
<meta name="openxiangda-app-code" content="openxiangda-application" />
|
|
8
|
+
<meta name="openxiangda-environment" content="preproduction" />
|
|
9
|
+
<title>Workflow entry acceptance</title>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
<script type="module" src="/e2e/workflow-entry-fixture.tsx"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="openxiangda-runtime-base" content="/" />
|
|
7
|
+
<meta name="openxiangda-app-code" content="openxiangda-application" />
|
|
8
|
+
<meta name="openxiangda-environment" content="preproduction" />
|
|
9
|
+
<title>Workflow experience acceptance</title>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
<script type="module" src="/e2e/workflow-experience-fixture.tsx"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|