create-windy 0.3.19 → 0.4.1
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 -13
- package/dist/cli.js +788 -280
- package/package.json +1 -1
- package/template/.agents/skills/windy-business-module/SKILL.md +34 -10
- package/template/.windy-template.json +2 -2
- package/template/AGENTS.md +18 -8
- package/template/README.md +32 -22
- package/template/apps/server/Dockerfile +1 -0
- package/template/apps/server/package.json +1 -0
- package/template/apps/server/scripts/validate-module-composition-once.ts +4 -0
- package/template/apps/server/scripts/validate-module-composition.ts +28 -0
- package/template/apps/server/src/agent/data-scope-routes.test.ts +20 -5
- package/template/apps/server/src/agent/routes.test.ts +20 -7
- package/template/apps/server/src/agent/routes.ts +14 -0
- package/template/apps/server/src/agent/runtime-bootstrap.ts +22 -6
- package/template/apps/server/src/agent/sandbox-worker.ts +2 -2
- package/template/apps/server/src/agent/unavailable-routes.ts +33 -0
- package/template/apps/server/src/app/server-composition.ts +56 -0
- package/template/apps/server/src/application-services.ts +2 -0
- package/template/apps/server/src/bulk-data/service.ts +14 -0
- package/template/apps/server/src/data-governance/export/authorization-port.ts +1 -1
- package/template/apps/server/src/data-governance/export/postgres-api-fixture.ts +18 -2
- package/template/apps/server/src/data-governance/export/postgres-recovery.integration.test.ts +10 -9
- package/template/apps/server/src/data-governance/export/routes-test-fixture.ts +6 -8
- package/template/apps/server/src/data-governance/user-plaintext-routes.test.ts +4 -2
- package/template/apps/server/src/feature/routes.authorization.test.ts +26 -1
- package/template/apps/server/src/feature/routes.ts +33 -15
- package/template/apps/server/src/foundation-activation.test.ts +60 -0
- package/template/apps/server/src/foundation.ts +64 -5
- package/template/apps/server/src/guards.test.ts +23 -0
- package/template/apps/server/src/guards.ts +12 -0
- package/template/apps/server/src/index.ts +28 -34
- package/template/apps/server/src/installed-business-modules.ts +13 -24
- package/template/apps/server/src/jobs/legacy-adapter.integration.test.ts +1 -0
- package/template/apps/server/src/jobs/legacy-adapter.test.ts +106 -0
- package/template/apps/server/src/jobs/legacy-service-runtime.ts +40 -0
- package/template/apps/server/src/license/activation.test.ts +30 -0
- package/template/apps/server/src/license/activation.ts +26 -0
- package/template/apps/server/src/license/restriction.test.ts +16 -0
- package/template/apps/server/src/license/routes-offline-code.test.ts +6 -2
- package/template/apps/server/src/license/routes.ts +20 -4
- package/template/apps/server/src/license/runtime-service.test.ts +10 -2
- package/template/apps/server/src/module-bootstrap.ts +14 -23
- package/template/apps/server/src/module-composition.test.ts +43 -2
- package/template/apps/server/src/module-composition.ts +29 -0
- package/template/apps/server/src/module-host/durable-context-guard.test.ts +172 -0
- package/template/apps/server/src/module-host/durable-context-unavailable.test.ts +50 -1
- package/template/apps/server/src/module-host/durable-context.test.ts +42 -25
- package/template/apps/server/src/module-host/durable-context.ts +42 -2
- package/template/apps/server/src/module-host/durable-handler-registration.ts +96 -5
- package/template/apps/server/src/module-host/implementation-completeness.test.ts +185 -0
- package/template/apps/server/src/module-host/implementation-completeness.ts +132 -0
- package/template/apps/server/src/module-host/initialize-contracts.ts +14 -0
- package/template/apps/server/src/module-host/initialize.test.ts +78 -2
- package/template/apps/server/src/module-host/initialize.ts +15 -4
- package/template/apps/server/src/module-host/project-attachments.test.ts +92 -0
- package/template/apps/server/src/module-host/project-attachments.ts +58 -0
- package/template/apps/server/src/module-host/project-composition-package.test.ts +186 -0
- package/template/apps/server/src/module-host/project-composition.test.ts +260 -0
- package/template/apps/server/src/module-host/project-composition.ts +311 -0
- package/template/apps/server/src/module-host/request-context.ts +3 -0
- package/template/apps/server/src/module-host/route-declaration.ts +15 -6
- package/template/apps/server/src/module-host/route-installer.test.ts +15 -2
- package/template/apps/server/src/module-host/route-installer.ts +12 -2
- package/template/apps/server/src/module-host/route-registration.test.ts +13 -4
- package/template/apps/server/src/module-host/runtime-composition-compatibility.test.ts +63 -0
- package/template/apps/server/src/module-host/runtime-composition-compatibility.ts +46 -0
- package/template/apps/server/src/module-host/runtime-composition.ts +34 -0
- package/template/apps/server/src/module-host/search-provider-registration.test.ts +64 -0
- package/template/apps/server/src/module-host/search-provider-registration.ts +35 -0
- package/template/apps/server/src/module-host/static-route-authorization.test.ts +99 -0
- package/template/apps/server/src/module-host/static-route-authorization.ts +90 -0
- package/template/apps/server/src/module-host/task-definitions.ts +1 -0
- package/template/apps/server/src/module-host/user-directory-composition.test.ts +4 -1
- package/template/apps/server/src/module-host.test.ts +2 -0
- package/template/apps/server/src/module-preflight.test.ts +289 -0
- package/template/apps/server/src/module-preflight.ts +96 -0
- package/template/apps/server/src/module-runtime-validation.ts +1 -0
- package/template/apps/server/src/platform-app-bootstrap.ts +50 -0
- package/template/apps/server/src/platform-http-runtime.ts +32 -7
- package/template/apps/server/src/route-guards.test.ts +22 -0
- package/template/apps/server/src/route-guards.ts +10 -3
- package/template/apps/server/src/runtime-audit-query.ts +50 -0
- package/template/apps/server/src/runtime-feature.test.ts +46 -0
- package/template/apps/server/src/runtime-feature.ts +5 -0
- package/template/apps/server/src/runtime.ts +10 -49
- package/template/apps/server/src/scheduler/audit-action.test.ts +49 -0
- package/template/apps/server/src/scheduler/audit.ts +1 -1
- package/template/apps/server/src/scheduler/execution-recorder.ts +10 -5
- package/template/apps/server/src/scheduler/recovery-service.test.ts +4 -3
- package/template/apps/server/src/scheduler/service-idle.test.ts +4 -3
- package/template/apps/server/src/scheduler/service.test.ts +1 -0
- package/template/apps/server/src/scheduler/service.ts +18 -21
- package/template/apps/server/src/scheduler/types.ts +5 -1
- package/template/apps/server/src/settings/drizzle-watermark-repository.integration.test.ts +4 -0
- package/template/apps/server/src/settings/drizzle-watermark-repository.ts +11 -3
- package/template/apps/server/src/settings/watermark-routes.test.ts +54 -1
- package/template/apps/server/src/settings/watermark-routes.ts +29 -1
- package/template/apps/server/src/startup-composition-validation.test.ts +35 -0
- package/template/apps/server/src/startup-composition-validation.ts +54 -0
- package/template/apps/server/src/startup-preflight.test.ts +36 -0
- package/template/apps/server/src/startup-preflight.ts +37 -0
- package/template/apps/server/src/system/audit-routes.test.ts +9 -3
- package/template/apps/server/src/system/department-routes.test.ts +5 -3
- package/template/apps/server/src/system/feature-routes.test.ts +4 -3
- package/template/apps/server/src/system/interface-catalog.test.ts +5 -3
- package/template/apps/server/src/system/interface-catalog.ts +3 -0
- package/template/apps/server/src/system/menu-routes.test.ts +5 -3
- package/template/apps/server/src/system/route-test-runtime.ts +24 -0
- package/template/apps/server/src/system/routes-validation.test.ts +7 -3
- package/template/apps/server/src/system/routes.test.ts +21 -11
- package/template/apps/server/src/system/routes.ts +11 -2
- package/template/apps/server/src/work-order/foundation-modules.test.ts +6 -4
- package/template/apps/server/src/work-order/routes.test.ts +8 -0
- package/template/apps/server/src/work-order/task.test.ts +6 -1
- package/template/apps/web/Dockerfile +5 -0
- package/template/apps/web/package.json +1 -0
- package/template/apps/web/scripts/validate-admin-ui-composition.ts +106 -0
- package/template/apps/web/src/app/web-composition.ts +24 -0
- package/template/apps/web/src/app/web-composition.webtest.ts +15 -0
- package/template/apps/web/src/composables/useWatermarkSettings.webtest.ts +14 -0
- package/template/apps/web/src/composables/watermark-settings.ts +40 -11
- package/template/apps/web/src/composables/watermark-settings.webtest.ts +19 -6
- package/template/apps/web/src/layout/AppSidebar.vue +8 -1
- package/template/apps/web/src/layout/GlobalWatermark.layering.webtest.ts +2 -0
- package/template/apps/web/src/layout/GlobalWatermark.vue +4 -8
- package/template/apps/web/src/layout/GlobalWatermark.webtest.ts +12 -5
- package/template/apps/web/src/layout/NavigationSearchDialog.vue +8 -1
- package/template/apps/web/src/layout/navigation.ts +29 -4
- package/template/apps/web/src/layout/navigation.webtest.ts +51 -0
- package/template/apps/web/src/pages/dashboard/dashboard-presenter.ts +6 -1
- package/template/apps/web/src/pages/settings/WatermarkPreview.vue +72 -0
- package/template/apps/web/src/pages/settings/WatermarkPreview.webtest.ts +55 -0
- package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +80 -24
- package/template/apps/web/src/pages/settings/WatermarkSettingsSection.webtest.ts +115 -0
- package/template/apps/web/src/pages/work-orders/WorkOrderListPage.vue +202 -0
- package/template/apps/web/src/pages/work-orders/WorkOrderListPage.webtest.ts +51 -0
- package/template/apps/web/src/router/admin-extension-loader.ts +44 -0
- package/template/apps/web/src/router/admin-extension-loader.webtest.ts +49 -0
- package/template/apps/web/src/router/admin-ui-composition-plugin.ts +33 -0
- package/template/apps/web/src/router/admin-ui-composition-plugin.webtest.ts +20 -0
- package/template/apps/web/src/router/admin-ui-composition.ts +313 -0
- package/template/apps/web/src/router/admin-ui-composition.webtest.ts +225 -0
- package/template/apps/web/src/router/admin-ui-module-registry-plugin.ts +55 -0
- package/template/apps/web/src/router/admin-ui-module-registry-plugin.webtest.ts +46 -0
- package/template/apps/web/src/router/business-routes.ts +32 -45
- package/template/apps/web/src/router/business-routes.webtest.ts +40 -44
- package/template/apps/web/src/router/index.ts +64 -54
- package/template/apps/web/src/router/manifest-routes.ts +27 -7
- package/template/apps/web/src/router/manifest-routes.webtest.ts +10 -2
- package/template/apps/web/src/router/platform-admin-route-bindings.ts +58 -0
- package/template/apps/web/src/router/reserved-route-paths.ts +14 -0
- package/template/apps/web/src/router/shared-scaffold-neutrality.webtest.ts +10 -4
- package/template/apps/web/src/router/web-composition-host.ts +20 -0
- package/template/apps/web/src/services/work-order-api.ts +16 -0
- package/template/apps/web/src/services/work-order-api.webtest.ts +21 -0
- package/template/apps/web/src/virtual-admin-ui-modules.d.ts +5 -0
- package/template/apps/web/vite.config.ts +22 -1
- package/template/docs/architecture/migration-bundle.md +10 -7
- package/template/docs/architecture/module-manifest-composition.md +85 -3
- package/template/docs/architecture/search-provider-protocol.md +6 -1
- package/template/docs/architecture/server-module-interface.md +70 -7
- package/template/docs/development/business-web-routes.md +53 -50
- package/template/docs/development/module-lifecycle.md +48 -54
- package/template/docs/platform/navigation-registry.md +5 -4
- package/template/docs/platform/platform-shell-settings.md +15 -10
- package/template/docs/platform/web-system-crud.md +1 -1
- package/template/package.json +1 -1
- package/template/packages/config/package.json +1 -1
- package/template/packages/database/drizzle/0044_sweet_tarantula.sql +6 -0
- package/template/packages/database/drizzle/meta/0044_snapshot.json +8349 -0
- package/template/packages/database/drizzle/meta/_journal.json +7 -0
- package/template/packages/database/package.json +1 -1
- package/template/packages/database/src/schema/platform-settings.ts +3 -0
- package/template/packages/example-work-order/package.json +6 -0
- package/template/packages/example-work-order/src/admin-page.ts +78 -0
- package/template/packages/example-work-order/src/admin.ts +35 -0
- package/template/packages/example-work-order/src/manifest.test.ts +62 -5
- package/template/packages/example-work-order/src/manifest.ts +54 -7
- package/template/packages/example-work-order/src/migration-bundle.ts +8 -0
- package/template/packages/example-work-order/src/server-module.ts +2 -2
- package/template/packages/jobs/package.json +1 -1
- package/template/packages/modules/index.ts +4 -0
- package/template/packages/modules/package.json +3 -2
- package/template/packages/modules/src/admin-ui-entry.ts +8 -0
- package/template/packages/modules/src/admin-ui-manifest.test.ts +52 -0
- package/template/packages/modules/src/admin-ui-manifest.ts +53 -0
- package/template/packages/modules/src/capability-audit-validation.test.ts +127 -0
- package/template/packages/modules/src/capability-audit-validation.ts +38 -0
- package/template/packages/modules/src/capability-guard-validation.ts +148 -0
- package/template/packages/modules/src/capability-key-validation.test.ts +150 -0
- package/template/packages/modules/src/composition-fixtures.test-support.ts +7 -5
- package/template/packages/modules/src/composition.test.ts +74 -9
- package/template/packages/modules/src/composition.ts +8 -0
- package/template/packages/modules/src/manifest.ts +1 -0
- package/template/packages/modules/src/migration-bundle-validation.test.ts +23 -0
- package/template/packages/modules/src/module-host-range.test.ts +57 -0
- package/template/packages/modules/src/module-host-range.ts +125 -0
- package/template/packages/modules/src/project-module-assembly.test.ts +133 -0
- package/template/packages/modules/src/project-module-assembly.ts +126 -0
- package/template/packages/modules/src/system-admin-routes.ts +6 -5
- package/template/packages/modules/src/system-admin-ui-catalog.ts +72 -0
- package/template/packages/modules/src/system-agent-tools.ts +2 -2
- package/template/packages/modules/src/system-api-binding.ts +43 -9
- package/template/packages/modules/src/system-api-control-plane.ts +202 -0
- package/template/packages/modules/src/system-api-data-governance.ts +4 -2
- package/template/packages/modules/src/system-api-operational.ts +57 -8
- package/template/packages/modules/src/system-api-permissions.ts +115 -21
- package/template/packages/modules/src/system-api-watermark.ts +3 -0
- package/template/packages/modules/src/system-audit-actions.ts +7 -0
- package/template/packages/modules/src/system-data-governance.ts +5 -2
- package/template/packages/modules/src/system-features.ts +31 -0
- package/template/packages/modules/src/system-governed-export-bindings.ts +8 -4
- package/template/packages/modules/src/system-module-catalog.test.ts +39 -4
- package/template/packages/modules/src/system-module-catalog.ts +68 -7
- package/template/packages/modules/src/system-module-tasks.ts +8 -1
- package/template/packages/modules/src/system-modules-access.test.ts +4 -0
- package/template/packages/modules/src/system-modules.test.ts +10 -2
- package/template/packages/modules/src/system-modules.ts +6 -5
- package/template/packages/modules/src/system-permissions.ts +4 -0
- package/template/packages/modules/user/module.ts +19 -2
- package/template/packages/server-sdk/index.ts +8 -0
- package/template/packages/server-sdk/package.json +2 -1
- package/template/packages/server-sdk/src/durable-handler.ts +16 -1
- package/template/packages/server-sdk/src/module-adapter.test.ts +44 -0
- package/template/packages/server-sdk/src/module-adapter.ts +59 -0
- package/template/packages/server-sdk/src/route-definition.ts +3 -2
- package/template/packages/shared/package.json +1 -1
- package/template/packages/shared/src/audit.test.ts +7 -0
- package/template/packages/shared/src/audit.ts +16 -0
- package/template/packages/shared/src/migration-bundle-validation.ts +9 -11
- package/template/packages/shared/src/platform-settings.ts +17 -0
- package/template/packages/shared/src/rbac.ts +2 -0
- package/template/apps/web/src/app/business-routes.ts +0 -22
|
@@ -2,15 +2,17 @@ import type { MenuNode } from "@southwind-ai/shared";
|
|
|
2
2
|
import type { ModuleFactory, ModuleManifest } from "./manifest.js";
|
|
3
3
|
import { systemFoundationModule } from "./system-modules.js";
|
|
4
4
|
|
|
5
|
-
interface SystemModuleDefinition {
|
|
5
|
+
export interface SystemModuleDefinition {
|
|
6
6
|
name: string;
|
|
7
7
|
version: string;
|
|
8
8
|
label: string;
|
|
9
9
|
description: string;
|
|
10
|
+
dependencies?: readonly string[];
|
|
10
11
|
resources: readonly string[];
|
|
11
12
|
permissionKeys?: readonly string[];
|
|
12
13
|
excludedPermissionKeys?: readonly string[];
|
|
13
14
|
featureKeys: readonly string[];
|
|
15
|
+
runtimeActivation?: "physical-only";
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export const systemModuleDefinitions = [
|
|
@@ -19,14 +21,21 @@ export const systemModuleDefinitions = [
|
|
|
19
21
|
version: "0.1.0",
|
|
20
22
|
label: "系统核心",
|
|
21
23
|
description: "管理面准入、Feature 治理、数据库基线与审计动作目录。",
|
|
22
|
-
resources: ["admin", "feature"],
|
|
23
|
-
featureKeys: [
|
|
24
|
+
resources: ["admin", "runtime", "auth", "feature"],
|
|
25
|
+
featureKeys: [
|
|
26
|
+
"system.admin",
|
|
27
|
+
"system.runtime",
|
|
28
|
+
"system.auth",
|
|
29
|
+
"system.feature",
|
|
30
|
+
"system.ruoyi-compat",
|
|
31
|
+
],
|
|
24
32
|
},
|
|
25
33
|
{
|
|
26
34
|
name: "system.identity",
|
|
27
35
|
version: "0.1.0",
|
|
28
36
|
label: "身份与权限",
|
|
29
37
|
description: "用户、角色、部门、菜单、字典、个人资料和数据范围。",
|
|
38
|
+
dependencies: ["system"],
|
|
30
39
|
resources: [
|
|
31
40
|
"user",
|
|
32
41
|
"user-directory",
|
|
@@ -37,7 +46,16 @@ export const systemModuleDefinitions = [
|
|
|
37
46
|
"profile",
|
|
38
47
|
],
|
|
39
48
|
excludedPermissionKeys: ["system.user.reveal", "system.user.export"],
|
|
40
|
-
featureKeys: [
|
|
49
|
+
featureKeys: [
|
|
50
|
+
"system.rbac",
|
|
51
|
+
"system.user",
|
|
52
|
+
"system.role",
|
|
53
|
+
"system.department",
|
|
54
|
+
"system.menu",
|
|
55
|
+
"system.dict",
|
|
56
|
+
"system.user-directory",
|
|
57
|
+
"system.profile",
|
|
58
|
+
],
|
|
41
59
|
},
|
|
42
60
|
// @windy-module system.settings begin
|
|
43
61
|
{
|
|
@@ -45,8 +63,10 @@ export const systemModuleDefinitions = [
|
|
|
45
63
|
version: "0.1.0",
|
|
46
64
|
label: "平台设置",
|
|
47
65
|
description: "品牌设置、Logo 与页面水印。",
|
|
66
|
+
dependencies: ["system"],
|
|
48
67
|
resources: ["settings", "watermark"],
|
|
49
68
|
featureKeys: ["system.settings", "system.watermark"],
|
|
69
|
+
runtimeActivation: "physical-only",
|
|
50
70
|
},
|
|
51
71
|
// @windy-module system.settings end
|
|
52
72
|
// @windy-module system.configuration begin
|
|
@@ -55,6 +75,7 @@ export const systemModuleDefinitions = [
|
|
|
55
75
|
version: "0.1.0",
|
|
56
76
|
label: "配置版本",
|
|
57
77
|
description: "类型化模块配置、版本、差异、应用与回滚。",
|
|
78
|
+
dependencies: ["system"],
|
|
58
79
|
resources: ["config"],
|
|
59
80
|
featureKeys: ["system.config"],
|
|
60
81
|
},
|
|
@@ -65,6 +86,7 @@ export const systemModuleDefinitions = [
|
|
|
65
86
|
version: "0.1.0",
|
|
66
87
|
label: "License",
|
|
67
88
|
description: "License 安装、验签、到期限制与版本授权。",
|
|
89
|
+
dependencies: ["system"],
|
|
68
90
|
resources: ["license"],
|
|
69
91
|
featureKeys: ["system.license"],
|
|
70
92
|
},
|
|
@@ -75,6 +97,7 @@ export const systemModuleDefinitions = [
|
|
|
75
97
|
version: "0.1.0",
|
|
76
98
|
label: "审计日志",
|
|
77
99
|
description: "关键操作、权限拒绝和系统异常的安全追溯。",
|
|
100
|
+
dependencies: ["system"],
|
|
78
101
|
resources: ["audit"],
|
|
79
102
|
featureKeys: ["system.audit"],
|
|
80
103
|
},
|
|
@@ -85,8 +108,10 @@ export const systemModuleDefinitions = [
|
|
|
85
108
|
version: "0.1.0",
|
|
86
109
|
label: "文件存储",
|
|
87
110
|
description: "上传、续传、下载与对象生命周期管理。",
|
|
111
|
+
dependencies: ["system", "system.settings"],
|
|
88
112
|
resources: ["storage"],
|
|
89
113
|
featureKeys: ["system.storage"],
|
|
114
|
+
runtimeActivation: "physical-only",
|
|
90
115
|
},
|
|
91
116
|
// @windy-module system.storage end
|
|
92
117
|
// @windy-module system.agent begin
|
|
@@ -95,6 +120,13 @@ export const systemModuleDefinitions = [
|
|
|
95
120
|
version: "0.1.0",
|
|
96
121
|
label: "Agent Tool",
|
|
97
122
|
description: "受 Feature、RBAC 和审计保护的 Agent 工具调用。",
|
|
123
|
+
dependencies: [
|
|
124
|
+
"system",
|
|
125
|
+
"system.audit",
|
|
126
|
+
"system.storage",
|
|
127
|
+
"system.scheduler",
|
|
128
|
+
"system.workflow",
|
|
129
|
+
],
|
|
98
130
|
resources: ["agent"],
|
|
99
131
|
featureKeys: ["system.agent"],
|
|
100
132
|
},
|
|
@@ -105,6 +137,7 @@ export const systemModuleDefinitions = [
|
|
|
105
137
|
version: "0.1.0",
|
|
106
138
|
label: "运维与调度",
|
|
107
139
|
description: "服务、数据库、缓存、磁盘与在线会话监控。",
|
|
140
|
+
dependencies: ["system", "system.configuration"],
|
|
108
141
|
resources: ["ops"],
|
|
109
142
|
featureKeys: ["system.ops"],
|
|
110
143
|
},
|
|
@@ -115,6 +148,7 @@ export const systemModuleDefinitions = [
|
|
|
115
148
|
version: "0.1.0",
|
|
116
149
|
label: "任务调度",
|
|
117
150
|
description: "定时任务注册、执行、重试、历史与恢复。",
|
|
151
|
+
dependencies: ["system", "system.audit"],
|
|
118
152
|
resources: ["scheduler"],
|
|
119
153
|
featureKeys: ["system.scheduler"],
|
|
120
154
|
},
|
|
@@ -126,6 +160,7 @@ export const systemModuleDefinitions = [
|
|
|
126
160
|
label: "站内通知",
|
|
127
161
|
description:
|
|
128
162
|
"通知定向与定时发布、用户偏好、外部渠道投递、修改历史、阅读、收藏和归档。",
|
|
163
|
+
dependencies: ["system", "system.identity", "system.scheduler"],
|
|
129
164
|
resources: ["notification"],
|
|
130
165
|
featureKeys: ["system.notification"],
|
|
131
166
|
},
|
|
@@ -136,6 +171,12 @@ export const systemModuleDefinitions = [
|
|
|
136
171
|
version: "0.1.0",
|
|
137
172
|
label: "审批工作流",
|
|
138
173
|
description: "审批领取、转交、决定、取消与超时补偿。",
|
|
174
|
+
dependencies: [
|
|
175
|
+
"system",
|
|
176
|
+
"system.identity",
|
|
177
|
+
"system.notification",
|
|
178
|
+
"system.scheduler",
|
|
179
|
+
],
|
|
139
180
|
resources: ["workflow"],
|
|
140
181
|
featureKeys: ["system.workflow"],
|
|
141
182
|
},
|
|
@@ -146,6 +187,7 @@ export const systemModuleDefinitions = [
|
|
|
146
187
|
version: "0.1.0",
|
|
147
188
|
label: "批量数据",
|
|
148
189
|
description: "批量导入导出、失败明细、结果留存与清理。",
|
|
190
|
+
dependencies: ["system", "system.storage", "system.scheduler"],
|
|
149
191
|
resources: ["bulk-data"],
|
|
150
192
|
featureKeys: ["system.bulk-data"],
|
|
151
193
|
},
|
|
@@ -156,6 +198,7 @@ export const systemModuleDefinitions = [
|
|
|
156
198
|
version: "0.1.0",
|
|
157
199
|
label: "平台搜索",
|
|
158
200
|
description: "权限感知的功能搜索与业务 SearchProvider 聚合。",
|
|
201
|
+
dependencies: ["system"],
|
|
159
202
|
resources: ["search"],
|
|
160
203
|
featureKeys: ["system.search"],
|
|
161
204
|
},
|
|
@@ -166,9 +209,18 @@ export const systemModuleDefinitions = [
|
|
|
166
209
|
version: "0.1.0",
|
|
167
210
|
label: "数据治理",
|
|
168
211
|
description: "敏感字段投影、明文访问与受治理导出。",
|
|
212
|
+
dependencies: [
|
|
213
|
+
"system",
|
|
214
|
+
"system.identity",
|
|
215
|
+
"system.audit",
|
|
216
|
+
"system.storage",
|
|
217
|
+
"system.workflow",
|
|
218
|
+
"system.scheduler",
|
|
219
|
+
],
|
|
169
220
|
resources: [],
|
|
170
221
|
permissionKeys: ["system.user.reveal", "system.user.export"],
|
|
171
222
|
featureKeys: [],
|
|
223
|
+
runtimeActivation: "physical-only",
|
|
172
224
|
},
|
|
173
225
|
// @windy-module system.data-governance end
|
|
174
226
|
] as const satisfies readonly SystemModuleDefinition[];
|
|
@@ -211,9 +263,13 @@ function createSystemCapabilityModule(
|
|
|
211
263
|
version: definition.version,
|
|
212
264
|
label: definition.label,
|
|
213
265
|
description: definition.description,
|
|
214
|
-
dependencies: isCore ? [] : ["system"],
|
|
266
|
+
dependencies: [...(definition.dependencies ?? (isCore ? [] : ["system"]))],
|
|
215
267
|
menus: selectMenus(aggregate.menus, ownsGuard),
|
|
216
|
-
adminRoutes: aggregate.adminRoutes.filter(
|
|
268
|
+
adminRoutes: aggregate.adminRoutes.filter((route) =>
|
|
269
|
+
route.key === "system.settings"
|
|
270
|
+
? definition.name === "system.settings"
|
|
271
|
+
: ownsGuard(route),
|
|
272
|
+
),
|
|
217
273
|
permissions: aggregate.permissions
|
|
218
274
|
.filter(({ key }) => ownsPermission(key))
|
|
219
275
|
.map((permission) => ({
|
|
@@ -245,7 +301,12 @@ function createSystemCapabilityModule(
|
|
|
245
301
|
auditActionKey(action) === "system.user-directory.query",
|
|
246
302
|
)
|
|
247
303
|
: [],
|
|
248
|
-
metadata: {
|
|
304
|
+
metadata: {
|
|
305
|
+
kind: "platform-capability",
|
|
306
|
+
...(definition.runtimeActivation
|
|
307
|
+
? { runtimeActivation: definition.runtimeActivation }
|
|
308
|
+
: {}),
|
|
309
|
+
},
|
|
249
310
|
};
|
|
250
311
|
}
|
|
251
312
|
|
|
@@ -8,6 +8,7 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
8
8
|
description: "周期验证调度、Guard、执行历史和重试链路可用。",
|
|
9
9
|
permissionKey: "system.scheduler.manage",
|
|
10
10
|
featureKey: "system.scheduler",
|
|
11
|
+
auditAction: "task.execute",
|
|
11
12
|
intervalSeconds: 300,
|
|
12
13
|
maxAttempts: 3,
|
|
13
14
|
retryDelaySeconds: 30,
|
|
@@ -20,6 +21,7 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
20
21
|
description: "发布到期通知并领取持久投递队列,执行渠道重试。",
|
|
21
22
|
permissionKey: "system.notification.manage",
|
|
22
23
|
featureKey: "system.notification",
|
|
24
|
+
auditAction: "notification.publish",
|
|
23
25
|
intervalSeconds: 5,
|
|
24
26
|
maxAttempts: 3,
|
|
25
27
|
retryDelaySeconds: 30,
|
|
@@ -32,6 +34,7 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
32
34
|
description: "领取一个已排队或到期重试的批量导入导出任务。",
|
|
33
35
|
permissionKey: "system.bulk-data.manage",
|
|
34
36
|
featureKey: "system.bulk-data",
|
|
37
|
+
auditAction: "task.execute",
|
|
35
38
|
intervalSeconds: 5,
|
|
36
39
|
maxAttempts: 3,
|
|
37
40
|
retryDelaySeconds: 30,
|
|
@@ -42,6 +45,7 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
42
45
|
description: "清理超过留存期限的源文件、结果和失败明细。",
|
|
43
46
|
permissionKey: "system.bulk-data.manage",
|
|
44
47
|
featureKey: "system.bulk-data",
|
|
48
|
+
auditAction: "task.execute",
|
|
45
49
|
intervalSeconds: 3_600,
|
|
46
50
|
maxAttempts: 3,
|
|
47
51
|
retryDelaySeconds: 60,
|
|
@@ -54,6 +58,7 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
54
58
|
description: "清理过期上传、文件、临时分片和超过宽限期的孤儿对象。",
|
|
55
59
|
permissionKey: "system.storage.manage",
|
|
56
60
|
featureKey: "system.storage",
|
|
61
|
+
auditAction: "task.execute",
|
|
57
62
|
intervalSeconds: 3_600,
|
|
58
63
|
maxAttempts: 3,
|
|
59
64
|
retryDelaySeconds: 60,
|
|
@@ -66,6 +71,7 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
66
71
|
description: "补偿登记并执行一个到期审批任务,进程重启后继续处理。",
|
|
67
72
|
permissionKey: "system.workflow.manage",
|
|
68
73
|
featureKey: "system.workflow",
|
|
74
|
+
auditAction: "workflow.timeout",
|
|
69
75
|
intervalSeconds: 5,
|
|
70
76
|
maxAttempts: 3,
|
|
71
77
|
retryDelaySeconds: 30,
|
|
@@ -77,7 +83,8 @@ export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
|
77
83
|
label: "受治理导出派发",
|
|
78
84
|
description: "领取并执行一个已批准的敏感数据导出任务。",
|
|
79
85
|
permissionKey: "system.user.export",
|
|
80
|
-
featureKey: "system.
|
|
86
|
+
featureKey: "system.user",
|
|
87
|
+
auditAction: "data.governed-export.generate",
|
|
81
88
|
intervalSeconds: 5,
|
|
82
89
|
maxAttempts: 3,
|
|
83
90
|
retryDelaySeconds: 30,
|
|
@@ -22,6 +22,7 @@ describe("系统模块管理面与 MCP 注册", () => {
|
|
|
22
22
|
path: "/api/admin/bootstrap",
|
|
23
23
|
permissionKey: "system.admin.access",
|
|
24
24
|
featureKey: "system.admin",
|
|
25
|
+
auditAction: "data.read",
|
|
25
26
|
anonymous: undefined,
|
|
26
27
|
});
|
|
27
28
|
});
|
|
@@ -38,6 +39,7 @@ describe("系统模块管理面与 MCP 注册", () => {
|
|
|
38
39
|
path: MCP_API_PATH,
|
|
39
40
|
permissionKey: "system.agent.read",
|
|
40
41
|
featureKey: "system.agent",
|
|
42
|
+
auditAction: "agent.mcp.access",
|
|
41
43
|
anonymous: undefined,
|
|
42
44
|
},
|
|
43
45
|
{
|
|
@@ -45,6 +47,7 @@ describe("系统模块管理面与 MCP 注册", () => {
|
|
|
45
47
|
path: MCP_API_PATH,
|
|
46
48
|
permissionKey: "system.agent.read",
|
|
47
49
|
featureKey: "system.agent",
|
|
50
|
+
auditAction: "agent.mcp.access",
|
|
48
51
|
anonymous: undefined,
|
|
49
52
|
},
|
|
50
53
|
{
|
|
@@ -52,6 +55,7 @@ describe("系统模块管理面与 MCP 注册", () => {
|
|
|
52
55
|
path: MCP_API_PATH,
|
|
53
56
|
permissionKey: "system.agent.read",
|
|
54
57
|
featureKey: "system.agent",
|
|
58
|
+
auditAction: "agent.mcp.access",
|
|
55
59
|
anonymous: undefined,
|
|
56
60
|
},
|
|
57
61
|
]);
|
|
@@ -189,6 +189,7 @@ describe("系统模块能力注册", () => {
|
|
|
189
189
|
path: "/api/search/providers",
|
|
190
190
|
permissionKey: "system.search.read",
|
|
191
191
|
featureKey: "system.search",
|
|
192
|
+
auditAction: "data.read",
|
|
192
193
|
anonymous: undefined,
|
|
193
194
|
},
|
|
194
195
|
{
|
|
@@ -196,6 +197,7 @@ describe("系统模块能力注册", () => {
|
|
|
196
197
|
path: "/api/search",
|
|
197
198
|
permissionKey: "system.search.read",
|
|
198
199
|
featureKey: "system.search",
|
|
200
|
+
auditAction: "search.query",
|
|
199
201
|
anonymous: undefined,
|
|
200
202
|
},
|
|
201
203
|
]),
|
|
@@ -231,14 +233,16 @@ describe("系统模块能力注册", () => {
|
|
|
231
233
|
method: "POST",
|
|
232
234
|
path: "/api/system/departments/quick",
|
|
233
235
|
permissionKey: "system.department.create",
|
|
234
|
-
featureKey: "system.
|
|
236
|
+
featureKey: "system.department",
|
|
237
|
+
auditAction: "crud.create",
|
|
235
238
|
anonymous: undefined,
|
|
236
239
|
});
|
|
237
240
|
expect(manifest.apiPermissions).toContainEqual({
|
|
238
241
|
method: "POST",
|
|
239
242
|
path: "/api/system/departments/:id/transition",
|
|
240
243
|
permissionKey: "system.department.manage",
|
|
241
|
-
featureKey: "system.
|
|
244
|
+
featureKey: "system.department",
|
|
245
|
+
auditAction: "organization.department.transition",
|
|
242
246
|
anonymous: undefined,
|
|
243
247
|
});
|
|
244
248
|
expect(manifest.auditActions).toContainEqual(
|
|
@@ -291,6 +295,7 @@ describe("系统模块能力注册", () => {
|
|
|
291
295
|
path: "/api/system/configurations",
|
|
292
296
|
permissionKey: "system.config.read",
|
|
293
297
|
featureKey: "system.config",
|
|
298
|
+
auditAction: "data.read",
|
|
294
299
|
anonymous: undefined,
|
|
295
300
|
},
|
|
296
301
|
{
|
|
@@ -298,6 +303,7 @@ describe("系统模块能力注册", () => {
|
|
|
298
303
|
path: "/api/system/configurations/:moduleKey/versions",
|
|
299
304
|
permissionKey: "system.config.read",
|
|
300
305
|
featureKey: "system.config",
|
|
306
|
+
auditAction: "data.read",
|
|
301
307
|
anonymous: undefined,
|
|
302
308
|
},
|
|
303
309
|
{
|
|
@@ -305,6 +311,7 @@ describe("系统模块能力注册", () => {
|
|
|
305
311
|
path: "/api/system/configurations/:moduleKey/versions",
|
|
306
312
|
permissionKey: "system.config.manage",
|
|
307
313
|
featureKey: "system.config",
|
|
314
|
+
auditAction: "config.update",
|
|
308
315
|
anonymous: undefined,
|
|
309
316
|
},
|
|
310
317
|
{
|
|
@@ -312,6 +319,7 @@ describe("系统模块能力注册", () => {
|
|
|
312
319
|
path: "/api/system/configurations/:moduleKey/versions/:version/rollback",
|
|
313
320
|
permissionKey: "system.config.manage",
|
|
314
321
|
featureKey: "system.config",
|
|
322
|
+
auditAction: "config.rollback",
|
|
315
323
|
anonymous: undefined,
|
|
316
324
|
},
|
|
317
325
|
]);
|
|
@@ -50,7 +50,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
50
50
|
path: "/admin/system/users",
|
|
51
51
|
icon: "users",
|
|
52
52
|
permissionKey: "system.user.read",
|
|
53
|
-
featureKey: "system.
|
|
53
|
+
featureKey: "system.user",
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
key: "system.role",
|
|
@@ -61,7 +61,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
61
61
|
path: "/admin/system/roles",
|
|
62
62
|
icon: "shield-check",
|
|
63
63
|
permissionKey: "system.role.read",
|
|
64
|
-
featureKey: "system.
|
|
64
|
+
featureKey: "system.role",
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
key: "system.department",
|
|
@@ -72,7 +72,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
72
72
|
path: "/admin/system/departments",
|
|
73
73
|
icon: "building-2",
|
|
74
74
|
permissionKey: "system.department.read",
|
|
75
|
-
featureKey: "system.
|
|
75
|
+
featureKey: "system.department",
|
|
76
76
|
},
|
|
77
77
|
],
|
|
78
78
|
},
|
|
@@ -119,7 +119,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
119
119
|
path: "/admin/system/menus",
|
|
120
120
|
icon: "panel-left",
|
|
121
121
|
permissionKey: "system.menu.read",
|
|
122
|
-
featureKey: "system.
|
|
122
|
+
featureKey: "system.menu",
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
key: "system.dictionary",
|
|
@@ -130,7 +130,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
130
130
|
path: "/admin/system/dictionaries",
|
|
131
131
|
icon: "book-open",
|
|
132
132
|
permissionKey: "system.dict.read",
|
|
133
|
-
featureKey: "system.
|
|
133
|
+
featureKey: "system.dict",
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
key: "system.feature",
|
|
@@ -141,6 +141,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
141
141
|
path: "/admin/system/features",
|
|
142
142
|
icon: "flag",
|
|
143
143
|
permissionKey: "system.feature.read",
|
|
144
|
+
featureKey: "system.feature",
|
|
144
145
|
},
|
|
145
146
|
// @windy-module system.notification begin
|
|
146
147
|
{
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { ModuleManifest } from "./manifest.js";
|
|
2
2
|
|
|
3
3
|
const systemResourceLabels = {
|
|
4
|
+
auth: "认证恢复",
|
|
4
5
|
admin: "管理面准入",
|
|
6
|
+
runtime: "运行状态",
|
|
5
7
|
user: "用户管理",
|
|
6
8
|
"user-directory": "业务用户目录",
|
|
7
9
|
role: "角色与权限",
|
|
@@ -72,7 +74,9 @@ function permission(
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
export const systemPermissions: ModuleManifest["permissions"] = [
|
|
77
|
+
permission("auth", "access"),
|
|
75
78
|
permission("admin", "access"),
|
|
79
|
+
permission("runtime", "read"),
|
|
76
80
|
permission("user", "read"),
|
|
77
81
|
// @windy-module system.data-governance begin
|
|
78
82
|
permission("user", "reveal", "sensitive-disclosure"),
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { ModuleManifest } from "../index.js";
|
|
2
|
+
import { featureKey } from "@southwind-ai/shared";
|
|
3
|
+
|
|
4
|
+
const USER_ACCOUNT_FEATURE = featureKey("user.account");
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* Example user module manifest.
|
|
@@ -23,6 +26,7 @@ export default function userModule(): ModuleManifest {
|
|
|
23
26
|
path: "/users",
|
|
24
27
|
icon: "users",
|
|
25
28
|
permissionKey: "user.account.read",
|
|
29
|
+
featureKey: USER_ACCOUNT_FEATURE,
|
|
26
30
|
},
|
|
27
31
|
],
|
|
28
32
|
adminRoutes: [
|
|
@@ -32,6 +36,7 @@ export default function userModule(): ModuleManifest {
|
|
|
32
36
|
title: "用户管理",
|
|
33
37
|
surface: "sidebar",
|
|
34
38
|
permissionKey: "user.account.read",
|
|
39
|
+
featureKey: USER_ACCOUNT_FEATURE,
|
|
35
40
|
},
|
|
36
41
|
],
|
|
37
42
|
permissions: [
|
|
@@ -59,14 +64,26 @@ export default function userModule(): ModuleManifest {
|
|
|
59
64
|
method: "GET",
|
|
60
65
|
path: "/api/users",
|
|
61
66
|
permissionKey: "user.account.read",
|
|
67
|
+
featureKey: USER_ACCOUNT_FEATURE,
|
|
68
|
+
auditAction: "data.read",
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
features: [
|
|
72
|
+
{
|
|
73
|
+
key: USER_ACCOUNT_FEATURE,
|
|
74
|
+
label: "用户账号",
|
|
75
|
+
module: "user",
|
|
76
|
+
description: "用户账号列表、授权和基础资料管理。",
|
|
77
|
+
visible: "visible",
|
|
78
|
+
enabled: true,
|
|
79
|
+
stage: "stable",
|
|
62
80
|
},
|
|
63
81
|
],
|
|
64
|
-
features: [],
|
|
65
82
|
migrations: [],
|
|
66
83
|
schemaExports: [],
|
|
67
84
|
tasks: [],
|
|
68
85
|
tools: [],
|
|
69
86
|
providers: [],
|
|
70
|
-
auditActions: ["crud.create", "crud.update", "crud.delete"],
|
|
87
|
+
auditActions: ["crud.create", "crud.update", "crud.delete", "data.read"],
|
|
71
88
|
};
|
|
72
89
|
}
|
|
@@ -36,6 +36,7 @@ export type {
|
|
|
36
36
|
} from "./src/jobs-port.js";
|
|
37
37
|
export { ModuleJobControlError } from "./src/jobs-port.js";
|
|
38
38
|
export type {
|
|
39
|
+
ModuleDurableHandlerCapability,
|
|
39
40
|
ModuleDurableHandlerContext,
|
|
40
41
|
ModuleDurableHandlerDefinition,
|
|
41
42
|
ModuleDurableStoragePort,
|
|
@@ -58,6 +59,13 @@ export type {
|
|
|
58
59
|
ModuleInitializer,
|
|
59
60
|
ModuleUploadPolicy,
|
|
60
61
|
} from "./src/module-host.js";
|
|
62
|
+
export {
|
|
63
|
+
defineWindyServerComposition,
|
|
64
|
+
defineWindyServerModule,
|
|
65
|
+
type WindyServerCompositionDeclaration,
|
|
66
|
+
type WindyServerModuleAttachment,
|
|
67
|
+
type WindyServerModuleAdapter,
|
|
68
|
+
} from "./src/module-adapter.js";
|
|
61
69
|
export { requireModuleNamespace } from "./src/namespace.js";
|
|
62
70
|
export type { ModuleRequestContext } from "./src/request-context.js";
|
|
63
71
|
export type { ModuleRolePreset } from "./src/role-preset.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@southwind-ai/server-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"src/durable-handler.ts",
|
|
19
19
|
"src/jobs-port.ts",
|
|
20
20
|
"src/module-host.ts",
|
|
21
|
+
"src/module-adapter.ts",
|
|
21
22
|
"src/namespace.ts",
|
|
22
23
|
"src/request-context.ts",
|
|
23
24
|
"src/role-preset.ts",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DurableHandlerContext, PayloadParser } from "@southwind-ai/jobs";
|
|
2
|
+
import type { AuditActionType } from "@southwind-ai/shared";
|
|
2
3
|
import type { ModuleActor } from "./actor.js";
|
|
3
4
|
import type { ModuleBackgroundAiPort } from "./background-ai-port.js";
|
|
4
5
|
import type {
|
|
@@ -19,7 +20,21 @@ export interface ModuleDurableHandlerContext extends DurableHandlerContext {
|
|
|
19
20
|
readonly ai: ModuleBackgroundAiPort;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Durable Handler 必须绑定当前模块 Manifest 已注册的能力三元组。
|
|
25
|
+
*
|
|
26
|
+
* Worker 每次领取任务(包括重试与恢复)都使用这份绑定重新执行
|
|
27
|
+
* License、Feature 与 Permission Guard,不能依赖提交时的授权结果。
|
|
28
|
+
*/
|
|
29
|
+
export interface ModuleDurableHandlerCapability {
|
|
30
|
+
readonly featureKey: string;
|
|
31
|
+
readonly permissionKey: string;
|
|
32
|
+
readonly auditAction: AuditActionType;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ModuleDurableHandlerDefinition<
|
|
36
|
+
T,
|
|
37
|
+
> extends ModuleDurableHandlerCapability {
|
|
23
38
|
readonly key: string;
|
|
24
39
|
readonly payload: PayloadParser<T>;
|
|
25
40
|
execute(
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
import {
|
|
3
|
+
defineWindyServerComposition,
|
|
4
|
+
defineWindyServerModule,
|
|
5
|
+
type InstallableServerModule,
|
|
6
|
+
} from "../index.js";
|
|
7
|
+
|
|
8
|
+
test("defineWindyServerModule 保留标准 Adapter 声明", async () => {
|
|
9
|
+
const module: InstallableServerModule<{ name: string }> = {
|
|
10
|
+
manifest: { name: "case" },
|
|
11
|
+
setup() {},
|
|
12
|
+
};
|
|
13
|
+
const adapter = defineWindyServerModule({
|
|
14
|
+
name: "case",
|
|
15
|
+
hostRange: "^0.1.0",
|
|
16
|
+
runtimeMode: "self-contained",
|
|
17
|
+
create: (config) => {
|
|
18
|
+
expect(config).toEqual({ tenant: "demo" });
|
|
19
|
+
return module;
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(adapter.name).toBe("case");
|
|
24
|
+
expect(adapter.runtimeMode).toBe("self-contained");
|
|
25
|
+
expect(await adapter.create({ tenant: "demo" })).toBe(module);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("defineWindyServerComposition 保留项目装配与显式运行时挂载", () => {
|
|
29
|
+
const attachment = {
|
|
30
|
+
name: "case",
|
|
31
|
+
attach(runtime: { readonly database: string }) {
|
|
32
|
+
expect(runtime.database).toBe("customer");
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const declaration = defineWindyServerComposition({
|
|
36
|
+
assembly: { schemaVersion: 1 as const, modules: [] },
|
|
37
|
+
adapters: [],
|
|
38
|
+
attachments: [attachment],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
expect(declaration.assembly.schemaVersion).toBe(1);
|
|
42
|
+
expect(declaration.attachments).toEqual([attachment]);
|
|
43
|
+
declaration.attachments?.[0]?.attach({ database: "customer" });
|
|
44
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { InstallableServerModule } from "./module-host.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 模块 package 提供给 Windy Server Host 的标准入口。
|
|
5
|
+
*
|
|
6
|
+
* package 根导出使用固定名称 `windyServerModule`;Host 在执行 create 前校验
|
|
7
|
+
* name 与 hostRange,并把项目装配清单中的模块配置作为只读数据传入。
|
|
8
|
+
*/
|
|
9
|
+
export interface WindyServerModuleAdapter<TManifest> {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly hostRange: string;
|
|
12
|
+
/**
|
|
13
|
+
* `self-contained` 可从 package 动态加载;`project-attachment` 只用于项目
|
|
14
|
+
* Composition Root,并且必须声明同名 attachment。
|
|
15
|
+
*/
|
|
16
|
+
readonly runtimeMode: "self-contained" | "project-attachment";
|
|
17
|
+
create(
|
|
18
|
+
config: Readonly<Record<string, unknown>>,
|
|
19
|
+
):
|
|
20
|
+
| InstallableServerModule<TManifest>
|
|
21
|
+
| Promise<InstallableServerModule<TManifest>>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 项目拥有的 Server 组合声明。
|
|
26
|
+
*
|
|
27
|
+
* `attachments` 只存在于项目 Composition Root,用于把客户 Repository 等运行时
|
|
28
|
+
* 依赖交给本地 Adapter。Host 从 package 动态加载的模块不会获得这些依赖。
|
|
29
|
+
*/
|
|
30
|
+
export interface WindyServerModuleAttachment<TRuntime> {
|
|
31
|
+
readonly name: string;
|
|
32
|
+
attach(runtime: TRuntime): Promise<void> | void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WindyServerCompositionDeclaration<
|
|
36
|
+
TManifest,
|
|
37
|
+
TAssembly,
|
|
38
|
+
TRuntime = never,
|
|
39
|
+
> {
|
|
40
|
+
readonly assembly: TAssembly;
|
|
41
|
+
readonly adapters: readonly WindyServerModuleAdapter<TManifest>[];
|
|
42
|
+
readonly attachments?: readonly WindyServerModuleAttachment<TRuntime>[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function defineWindyServerModule<TManifest>(
|
|
46
|
+
adapter: WindyServerModuleAdapter<TManifest>,
|
|
47
|
+
): WindyServerModuleAdapter<TManifest> {
|
|
48
|
+
return adapter;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function defineWindyServerComposition<TManifest, TAssembly, TRuntime>(
|
|
52
|
+
declaration: WindyServerCompositionDeclaration<
|
|
53
|
+
TManifest,
|
|
54
|
+
TAssembly,
|
|
55
|
+
TRuntime
|
|
56
|
+
>,
|
|
57
|
+
): WindyServerCompositionDeclaration<TManifest, TAssembly, TRuntime> {
|
|
58
|
+
return declaration;
|
|
59
|
+
}
|