create-windy 0.2.7 → 0.2.9
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 -0
- package/dist/cli.js +181 -87
- package/package.json +1 -1
- package/template/.windy-template.json +2 -2
- package/template/apps/server/Dockerfile +2 -0
- package/template/apps/server/package.json +10 -8
- package/template/apps/server/src/access-guards.ts +1 -1
- package/template/apps/server/src/admin/routes.test.ts +10 -0
- package/template/apps/server/src/admin/routes.ts +4 -2
- package/template/apps/server/src/agent/routes.test.ts +1 -1
- package/template/apps/server/src/agent/routes.ts +2 -2
- package/template/apps/server/src/application-services.ts +3 -0
- package/template/apps/server/src/audit/drizzle-log-store.ts +2 -2
- package/template/apps/server/src/audit/policy.ts +1 -1
- package/template/apps/server/src/audit/recovery-queue.test.ts +1 -1
- package/template/apps/server/src/audit/recovery-queue.ts +1 -1
- package/template/apps/server/src/audit/redaction.ts +1 -1
- package/template/apps/server/src/audit/reliable-writer.test.ts +1 -1
- package/template/apps/server/src/audit/reliable-writer.ts +1 -1
- package/template/apps/server/src/audit/search-summary.ts +1 -1
- package/template/apps/server/src/auth/authentication-provider.test.ts +1 -1
- package/template/apps/server/src/auth/credential-service.ts +1 -1
- package/template/apps/server/src/auth/drizzle-repository.ts +2 -2
- package/template/apps/server/src/auth/drizzle-session-operations.ts +1 -1
- package/template/apps/server/src/auth/own-session-routes.test.ts +1 -1
- package/template/apps/server/src/auth/password.ts +2 -2
- package/template/apps/server/src/auth/repository.ts +1 -1
- package/template/apps/server/src/auth/routes.test.ts +1 -1
- package/template/apps/server/src/auth/service.ts +1 -1
- package/template/apps/server/src/bulk-data/artifact-store.ts +1 -1
- package/template/apps/server/src/bulk-data/dictionary-handler.ts +1 -1
- package/template/apps/server/src/bulk-data/drizzle-repository.ts +3 -3
- package/template/apps/server/src/bulk-data/repository.ts +1 -1
- package/template/apps/server/src/bulk-data/routes.test.ts +1 -1
- package/template/apps/server/src/bulk-data/routes.ts +1 -1
- package/template/apps/server/src/bulk-data/service.test.ts +1 -1
- package/template/apps/server/src/bulk-data/service.ts +1 -1
- package/template/apps/server/src/bulk-data/types.ts +1 -1
- package/template/apps/server/src/configuration/bootstrap.ts +2 -2
- package/template/apps/server/src/configuration/definition.ts +2 -2
- package/template/apps/server/src/configuration/drizzle-repository.ts +2 -2
- package/template/apps/server/src/configuration/repository.ts +1 -1
- package/template/apps/server/src/configuration/routes.ts +1 -1
- package/template/apps/server/src/configuration/service.ts +1 -1
- package/template/apps/server/src/data-access/context.ts +2 -2
- package/template/apps/server/src/data-access/query-specification.test.ts +1 -1
- package/template/apps/server/src/data-access/scoped-repository.integration.test.ts +1 -1
- package/template/apps/server/src/data-access/scoped-repository.ts +1 -1
- package/template/apps/server/src/data-access/scoped-resource.test.ts +1 -1
- package/template/apps/server/src/data-access/scoped-resource.ts +1 -1
- package/template/apps/server/src/data-governance/export/approval-port.ts +1 -1
- package/template/apps/server/src/data-governance/export/drizzle-repository.ts +1 -1
- package/template/apps/server/src/data-governance/export/job-runtime.test.ts +2 -2
- package/template/apps/server/src/data-governance/export/job-runtime.ts +2 -3
- package/template/apps/server/src/data-governance/export/postgres-api-fixture.ts +2 -2
- package/template/apps/server/src/data-governance/export/postgres-api.integration.test.ts +1 -1
- package/template/apps/server/src/data-governance/export/routes-test-fixture.ts +3 -3
- package/template/apps/server/src/data-governance/export/routes.ts +1 -1
- package/template/apps/server/src/data-governance/export/scope-snapshot.ts +1 -1
- package/template/apps/server/src/data-governance/export/service.ts +2 -2
- package/template/apps/server/src/data-governance/export/source.ts +1 -1
- package/template/apps/server/src/data-governance/export/types.ts +1 -1
- package/template/apps/server/src/data-governance/plaintext-access.test.ts +1 -1
- package/template/apps/server/src/data-governance/plaintext-access.ts +1 -1
- package/template/apps/server/src/data-governance/plaintext-postgres.integration.test.ts +1 -1
- package/template/apps/server/src/data-governance/user-plaintext-routes.ts +1 -1
- package/template/apps/server/src/data-governance/user-projection.ts +2 -2
- package/template/apps/server/src/example-modules.ts +25 -1
- package/template/apps/server/src/feature/manifest-feature-repository.test.ts +1 -1
- package/template/apps/server/src/feature/manifest-feature-repository.ts +1 -1
- package/template/apps/server/src/feature/routes.ts +3 -6
- package/template/apps/server/src/foundation-access.test.ts +1 -1
- package/template/apps/server/src/foundation-access.ts +1 -1
- package/template/apps/server/src/foundation.ts +21 -7
- package/template/apps/server/src/guards.test.ts +1 -1
- package/template/apps/server/src/guards.ts +3 -3
- package/template/apps/server/src/index.ts +28 -3
- package/template/{packages/modules → apps/server}/src/installed-business-modules.ts +2 -2
- package/template/apps/server/src/jobs/artifact-service.test.ts +1 -1
- package/template/apps/server/src/jobs/artifact-service.ts +2 -2
- package/template/apps/server/src/jobs/drizzle-artifact.ts +2 -2
- package/template/apps/server/src/jobs/drizzle-claim.ts +1 -1
- package/template/apps/server/src/jobs/drizzle-execution-repository.ts +2 -2
- package/template/apps/server/src/jobs/drizzle-execution.integration.test.ts +1 -1
- package/template/apps/server/src/jobs/drizzle-lease.ts +2 -2
- package/template/apps/server/src/jobs/drizzle-mappers.ts +3 -3
- package/template/apps/server/src/jobs/drizzle-recovery-repository.ts +1 -1
- package/template/apps/server/src/jobs/drizzle-repository.integration.test.ts +1 -1
- package/template/apps/server/src/jobs/drizzle-repository.ts +3 -3
- package/template/apps/server/src/jobs/execution-repository.ts +1 -1
- package/template/apps/server/src/jobs/execution.test.ts +2 -2
- package/template/apps/server/src/jobs/in-memory-claim.ts +1 -1
- package/template/apps/server/src/jobs/in-memory-execution.ts +1 -1
- package/template/apps/server/src/jobs/in-memory-lease.ts +1 -1
- package/template/apps/server/src/jobs/legacy-adapter.integration.test.ts +1 -1
- package/template/apps/server/src/jobs/legacy-adapter.test.ts +1 -1
- package/template/apps/server/src/jobs/legacy-adapter.ts +1 -1
- package/template/apps/server/src/jobs/legacy-service-runtime.ts +4 -2
- package/template/apps/server/src/jobs/repository.ts +2 -2
- package/template/apps/server/src/jobs/service.ts +2 -2
- package/template/apps/server/src/jobs/worker.ts +3 -2
- package/template/apps/server/src/license/legacy-license-resolver.ts +1 -1
- package/template/apps/server/src/license/license-resolver.test.ts +1 -1
- package/template/apps/server/src/license/license-resolver.ts +3 -3
- package/template/apps/server/src/license/routes-offline-code.test.ts +2 -2
- package/template/apps/server/src/license/routes.ts +1 -1
- package/template/apps/server/src/license/runtime-audit-reliability.test.ts +2 -2
- package/template/apps/server/src/license/runtime-reminder.test.ts +2 -2
- package/template/apps/server/src/license/runtime-service.test.ts +2 -2
- package/template/apps/server/src/license/runtime-service.ts +2 -2
- package/template/apps/server/src/module-composition.test.ts +1 -1
- package/template/apps/server/src/module-composition.ts +1 -1
- package/template/apps/server/src/module-host.test.ts +145 -0
- package/template/apps/server/src/module-host.ts +110 -0
- package/template/apps/server/src/notification/drizzle-repository.ts +2 -2
- package/template/apps/server/src/notification/repository.ts +1 -1
- package/template/apps/server/src/notification/routes.ts +1 -1
- package/template/apps/server/src/pagination.ts +1 -1
- package/template/apps/server/src/persistence.integration.test.ts +1 -1
- package/template/apps/server/src/persistence.ts +1 -1
- package/template/apps/server/src/profile/routes.ts +1 -1
- package/template/apps/server/src/route-guards.test.ts +1 -1
- package/template/apps/server/src/route-guards.ts +1 -1
- package/template/apps/server/src/runtime-feature.ts +125 -0
- package/template/apps/server/src/runtime-license.ts +1 -1
- package/template/apps/server/src/runtime.test.ts +48 -1
- package/template/apps/server/src/runtime.ts +17 -64
- package/template/apps/server/src/scheduler/audit.ts +1 -1
- package/template/apps/server/src/scheduler/definitions.test.ts +1 -1
- package/template/apps/server/src/scheduler/definitions.ts +2 -2
- package/template/apps/server/src/scheduler/drizzle-durable-links.ts +1 -1
- package/template/apps/server/src/scheduler/drizzle-mappers.ts +1 -1
- package/template/apps/server/src/scheduler/drizzle-repository.ts +1 -1
- package/template/apps/server/src/scheduler/execution-recorder.ts +1 -1
- package/template/apps/server/src/scheduler/history.ts +1 -1
- package/template/apps/server/src/scheduler/overview.ts +1 -1
- package/template/apps/server/src/scheduler/recovery-service.test.ts +1 -1
- package/template/apps/server/src/scheduler/recovery-service.ts +1 -1
- package/template/apps/server/src/scheduler/repository.ts +1 -1
- package/template/apps/server/src/scheduler/routes.ts +1 -1
- package/template/apps/server/src/scheduler/service-idle.test.ts +1 -1
- package/template/apps/server/src/scheduler/service.test.ts +1 -1
- package/template/apps/server/src/scheduler/service.ts +1 -1
- package/template/apps/server/src/scheduler/types.ts +1 -1
- package/template/apps/server/src/search/contracts.ts +2 -2
- package/template/apps/server/src/search/host.ts +1 -1
- package/template/apps/server/src/search/registry.ts +1 -1
- package/template/apps/server/src/search/routes.test.ts +1 -1
- package/template/apps/server/src/search/routes.ts +1 -1
- package/template/apps/server/src/search/service.ts +2 -2
- package/template/apps/server/src/search/test-support.ts +2 -2
- package/template/apps/server/src/session/routes.ts +1 -1
- package/template/apps/server/src/settings/drizzle-repository.ts +2 -2
- package/template/apps/server/src/settings/repository.ts +1 -1
- package/template/apps/server/src/settings/routes.test.ts +1 -1
- package/template/apps/server/src/settings/routes.ts +1 -1
- package/template/apps/server/src/settings/runtime.ts +1 -1
- package/template/apps/server/src/storage/blob-reference-registry.test.ts +1 -1
- package/template/apps/server/src/storage/blob-reference-registry.ts +1 -1
- package/template/apps/server/src/storage/drizzle-upload-repository.integration.test.ts +1 -1
- package/template/apps/server/src/storage/drizzle-upload-repository.ts +2 -2
- package/template/apps/server/src/storage/route-support.ts +1 -1
- package/template/apps/server/src/storage/routes.test.ts +1 -1
- package/template/apps/server/src/storage/routes.ts +2 -2
- package/template/apps/server/src/storage/runtime.ts +6 -4
- package/template/apps/server/src/system/audit-routes.ts +1 -1
- package/template/apps/server/src/system/department-routes.ts +1 -1
- package/template/apps/server/src/system/drizzle-repository.ts +1 -1
- package/template/apps/server/src/system/drizzle-scoped-repository.ts +1 -1
- package/template/apps/server/src/system/drizzle-system.ts +1 -1
- package/template/apps/server/src/system/entities.ts +1 -1
- package/template/apps/server/src/system/identity-route-config.ts +1 -1
- package/template/apps/server/src/system/interface-catalog.test.ts +3 -3
- package/template/apps/server/src/system/interface-catalog.ts +2 -2
- package/template/apps/server/src/system/menu-registry.ts +1 -1
- package/template/apps/server/src/system/menu-routes.ts +1 -1
- package/template/apps/server/src/system/operations.test.ts +1 -1
- package/template/apps/server/src/system/operations.ts +1 -1
- package/template/apps/server/src/system/redis-health.ts +1 -1
- package/template/apps/server/src/system/repository.ts +1 -1
- package/template/apps/server/src/system/resource-route-support.ts +1 -1
- package/template/apps/server/src/system/route-helpers.ts +1 -1
- package/template/apps/server/src/system/route-types.ts +1 -1
- package/template/apps/server/src/system/routes.test.ts +1 -1
- package/template/apps/server/src/system/routes.ts +1 -1
- package/template/apps/server/src/system/user-projection.ts +1 -1
- package/template/apps/server/src/work-order/data-scope.integration.test.ts +1 -1
- package/template/apps/server/src/work-order/drizzle-repository.integration.test.ts +1 -1
- package/template/apps/server/src/work-order/drizzle-repository.ts +2 -2
- package/template/apps/server/src/work-order/foundation-modules.test.ts +15 -5
- package/template/apps/server/src/work-order/repository.ts +1 -1
- package/template/apps/server/src/work-order/routes.test.ts +2 -2
- package/template/apps/server/src/work-order/routes.ts +2 -2
- package/template/apps/server/src/work-order/search-api.test.ts +3 -3
- package/template/apps/server/src/work-order/search-provider.test.ts +3 -3
- package/template/apps/server/src/work-order/service.ts +1 -1
- package/template/apps/server/src/work-order/task.test.ts +1 -1
- package/template/apps/server/src/work-order/task.ts +2 -2
- package/template/apps/server/src/workflow/drizzle-repository.integration.test.ts +2 -2
- package/template/apps/server/src/workflow/drizzle-repository.ts +3 -3
- package/template/apps/server/src/workflow/effects.test.ts +1 -1
- package/template/apps/server/src/workflow/effects.ts +1 -1
- package/template/apps/server/src/workflow/repository.ts +2 -2
- package/template/apps/server/src/workflow/routes.ts +3 -3
- package/template/apps/server/src/workflow/service.ts +1 -1
- package/template/apps/server/src/workflow/timeout-runtime.test.ts +1 -1
- package/template/apps/server/src/workflow/timeout-runtime.ts +2 -2
- package/template/apps/web/Dockerfile +2 -0
- package/template/apps/web/package.json +4 -4
- package/template/apps/web/runtime-server.ts +1 -1
- package/template/apps/web/src/app/layouts/AppLayout.vue +6 -0
- package/template/apps/web/src/components/auth/PasswordChangeForm.vue +1 -1
- package/template/apps/web/src/components/common/DataPagination.vue +1 -1
- package/template/apps/web/src/components/license/LicenseActivationCodeForm.vue +1 -1
- package/template/apps/web/src/components/license/LicenseFlow.webtest.ts +2 -2
- package/template/apps/web/src/composables/useModuleConfigurations.ts +1 -1
- package/template/apps/web/src/composables/useWatermarkSettings.ts +1 -0
- package/template/apps/web/src/composables/watermark-settings.ts +6 -0
- package/template/apps/web/src/composables/watermark-settings.webtest.ts +27 -1
- package/template/apps/web/src/layout/AppSidebar.vue +12 -3
- package/template/apps/web/src/layout/AppSidebar.webtest.ts +11 -0
- package/template/apps/web/src/layout/GlobalWatermark.vue +25 -8
- package/template/apps/web/src/layout/GlobalWatermark.webtest.ts +109 -0
- package/template/apps/web/src/layout/NavigationSearchDialog.vue +1 -1
- package/template/apps/web/src/layout/NotificationMenu.vue +1 -1
- package/template/apps/web/src/layout/navigation.ts +5 -1
- package/template/apps/web/src/layout/navigation.webtest.ts +1 -1
- package/template/apps/web/src/pages/configuration/components/ModuleConfigRollbackDialog.vue +1 -1
- package/template/apps/web/src/pages/configuration/components/ModuleConfigVersionList.vue +1 -1
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.vue +1 -1
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.webtest.ts +1 -1
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationWorkbench.vue +1 -1
- package/template/apps/web/src/pages/dashboard/dashboard-presenter.webtest.ts +1 -1
- package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +21 -0
- package/template/apps/web/src/pages/system/SystemNotificationsPage.vue +2 -2
- package/template/apps/web/src/pages/system/components/AuditActionCell.vue +7 -2
- package/template/apps/web/src/pages/system/components/AuditLogFilters.vue +7 -2
- package/template/apps/web/src/pages/system/components/NotificationPublishForm.vue +1 -1
- package/template/apps/web/src/pages/system/components/SchedulerOperationsPanel.vue +1 -1
- package/template/apps/web/src/pages/system/components/SchedulerOperationsPanel.webtest.ts +1 -1
- package/template/apps/web/src/pages/system/components/SchedulerRunTable.vue +1 -1
- package/template/apps/web/src/pages/system/components/SchedulerRunTable.webtest.ts +1 -1
- package/template/apps/web/src/pages/system/components/SchedulerStaleRecoveryForm.vue +1 -1
- package/template/apps/web/src/pages/system/components/SchedulerStaleRecoveryForm.webtest.ts +1 -1
- package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +1 -1
- package/template/apps/web/src/pages/system/components/SystemResourceTable.vue +10 -3
- package/template/apps/web/src/pages/system/components/role-policy/RolePermissionTree.vue +1 -1
- package/template/apps/web/src/pages/system/components/role-policy/RolePermissionTree.webtest.ts +1 -1
- package/template/apps/web/src/pages/system/components/role-policy/RolePolicyForm.vue +1 -1
- package/template/apps/web/src/pages/system/components/role-policy/permission-tree.ts +1 -1
- package/template/apps/web/src/pages/system/components/role-policy/permission-tree.webtest.ts +1 -1
- package/template/apps/web/src/pages/system/composables/useSchedulerOperations.ts +2 -2
- package/template/apps/web/src/pages/system/composables/useSchedulerOperations.webtest.ts +1 -1
- package/template/apps/web/src/pages/system/composables/useSystemResource.ts +1 -1
- package/template/apps/web/src/router/manifest-routes.ts +1 -1
- package/template/apps/web/src/router/manifest-routes.webtest.ts +1 -1
- package/template/apps/web/src/services/access-api.ts +10 -1
- package/template/apps/web/src/services/configuration-api.ts +1 -1
- package/template/apps/web/src/services/license-api.ts +1 -1
- package/template/apps/web/src/services/notification-api.ts +2 -2
- package/template/apps/web/src/services/operations-api.ts +1 -1
- package/template/apps/web/src/services/platform-settings-api.ts +2 -2
- package/template/apps/web/src/services/profile-api.ts +2 -2
- package/template/docs/architecture/durable-jobs.md +5 -0
- package/template/docs/architecture/module-manifest-composition.md +14 -7
- package/template/docs/architecture/object-storage.md +1 -1
- package/template/docs/development/crud-generator.md +4 -1
- package/template/docs/platform/audit-reliability.md +1 -1
- package/template/package.json +2 -1
- package/template/packages/config/package.json +15 -4
- package/template/packages/config/src/platform.ts +1 -1
- package/template/packages/crud-generator/package.json +1 -1
- package/template/packages/crud-generator/src/generator.test.ts +16 -0
- package/template/packages/crud-generator/src/templates/domain.ts +1 -1
- package/template/packages/crud-generator/src/templates/manifest.ts +2 -2
- package/template/packages/crud-generator/src/templates/project.ts +3 -3
- package/template/packages/crud-generator/src/templates/repository.ts +1 -1
- package/template/packages/crud-generator/src/templates/routes.ts +2 -2
- package/template/packages/crud-generator/src/validation.ts +22 -1
- package/template/packages/database/package.json +15 -5
- package/template/packages/database/src/bundle-validation.ts +218 -0
- package/template/packages/database/src/dialects.ts +1 -1
- package/template/packages/database/src/runner.test.ts +160 -13
- package/template/packages/database/src/runner.ts +95 -77
- package/template/packages/database/src/schema/governed-exports.ts +1 -1
- package/template/packages/database/src/schema/identity.ts +1 -1
- package/template/packages/database/src/schema/license-v1.ts +1 -1
- package/template/packages/database/src/schema/notifications.ts +1 -1
- package/template/packages/database/src/schema/platform-settings.ts +1 -1
- package/template/packages/database/src/schema/workflow.ts +1 -1
- package/template/packages/database/src/sql-store.ts +1 -1
- package/template/packages/database/src/store.ts +1 -1
- package/template/packages/example-work-order/index.ts +1 -0
- package/template/packages/example-work-order/package.json +4 -3
- package/template/packages/example-work-order/src/contract.ts +1 -1
- package/template/packages/example-work-order/src/manifest.ts +8 -3
- package/template/packages/example-work-order/src/migration-bundle.test.ts +43 -0
- package/template/packages/example-work-order/src/migration-bundle.ts +64 -0
- package/template/packages/jobs/index.ts +2 -0
- package/template/packages/jobs/package.json +29 -0
- package/template/packages/jobs/src/handlers.test.ts +72 -0
- package/template/{apps/server/src/jobs/handler-registry.ts → packages/jobs/src/handlers.ts} +4 -4
- package/template/{apps/server/src/jobs → packages/jobs/src}/types.ts +7 -1
- package/template/packages/{license-sdk → jobs}/tsconfig.json +0 -1
- package/template/packages/modules/index.ts +1 -1
- package/template/packages/modules/package.json +15 -5
- package/template/packages/modules/src/ai-operation-composition.test.ts +195 -0
- package/template/packages/modules/src/ai-operation-composition.ts +145 -0
- package/template/packages/modules/src/catalog-validation.ts +123 -0
- package/template/packages/modules/src/composition.test.ts +75 -2
- package/template/packages/modules/src/composition.ts +23 -39
- package/template/packages/modules/src/implementation-bindings.ts +70 -0
- package/template/packages/modules/src/manifest.ts +43 -12
- package/template/packages/modules/src/menu-composition.ts +1 -1
- package/template/packages/modules/src/system-api-binding.ts +1 -1
- package/template/packages/modules/src/system-api-data-governance.ts +1 -1
- package/template/packages/modules/src/system-api-permissions.ts +1 -1
- package/template/packages/modules/src/system-data-governance.ts +1 -1
- package/template/packages/modules/src/system-features.ts +1 -1
- package/template/packages/modules/src/system-governed-export-bindings.ts +1 -1
- package/template/packages/modules/src/system-module-catalog.ts +1 -1
- package/template/packages/server-sdk/index.ts +5 -0
- package/template/packages/server-sdk/package.json +25 -0
- package/template/packages/server-sdk/src/module-host.ts +29 -0
- package/template/packages/server-sdk/tsconfig.json +16 -0
- package/template/packages/shared/index.ts +2 -0
- package/template/packages/shared/package.json +14 -3
- package/template/packages/shared/src/audit.ts +22 -1
- package/template/packages/shared/src/license-catalog.test.ts +17 -0
- package/template/packages/shared/src/license-catalog.ts +33 -0
- package/template/packages/shared/src/migration.ts +39 -0
- package/template/packages/storage/package.json +14 -3
- package/template/packages/license-sdk/index.ts +0 -13
- package/template/packages/license-sdk/package.json +0 -18
- package/template/packages/license-sdk/src/bounded-json-body.test.ts +0 -65
- package/template/packages/license-sdk/src/bounded-json-body.ts +0 -135
- package/template/packages/license-sdk/src/canonical-json.test.ts +0 -28
- package/template/packages/license-sdk/src/canonical-json.ts +0 -104
- package/template/packages/license-sdk/src/client.test.ts +0 -82
- package/template/packages/license-sdk/src/client.ts +0 -86
- package/template/packages/license-sdk/src/device.ts +0 -46
- package/template/packages/license-sdk/src/file-storage.test.ts +0 -80
- package/template/packages/license-sdk/src/file-storage.ts +0 -77
- package/template/packages/license-sdk/src/installation.test.ts +0 -241
- package/template/packages/license-sdk/src/installation.ts +0 -150
- package/template/packages/license-sdk/src/license-parser.ts +0 -56
- package/template/packages/license-sdk/src/offline-code-base32.ts +0 -57
- package/template/packages/license-sdk/src/offline-code-decompression.ts +0 -55
- package/template/packages/license-sdk/src/offline-code-limits.ts +0 -10
- package/template/packages/license-sdk/src/offline-code-wire.ts +0 -72
- package/template/packages/license-sdk/src/offline-code.test.ts +0 -172
- package/template/packages/license-sdk/src/offline-code.ts +0 -319
- package/template/packages/license-sdk/src/payload.test.ts +0 -72
- package/template/packages/license-sdk/src/payload.ts +0 -201
- package/template/packages/license-sdk/src/storage.ts +0 -64
- package/template/packages/license-sdk/src/test-fixtures.ts +0 -59
- package/template/packages/license-sdk/src/v1-test-vector.ts +0 -49
- package/template/packages/license-sdk/src/validation.test.ts +0 -62
- package/template/packages/license-sdk/src/validation.ts +0 -143
- package/template/packages/license-sdk/src/verification.test.ts +0 -97
- package/template/packages/license-sdk/src/verification.ts +0 -199
package/README.md
CHANGED
|
@@ -66,6 +66,12 @@ npx create-windy@latest my-dashboard \
|
|
|
66
66
|
法律许可证与离线 `system.license` 是两项独立选择:前者决定项目代码授权,后者
|
|
67
67
|
为离线部署提供运行时验签与限制态。
|
|
68
68
|
|
|
69
|
+
选择 `system.license` 时,Server 与 Web 通过 npm 依赖
|
|
70
|
+
`@southwind-ai/license@^0.1.1` 使用运行时能力;生成项目及 `create-windy` 模板快照都不包含
|
|
71
|
+
`packages/license-sdk` 源码。公网 npm 已发布兼容的 `@southwind-ai/license@0.1.1`;
|
|
72
|
+
发布包含该模块的新版创建器前,必须先确认目标 registry 中存在兼容版本,并完成真实
|
|
73
|
+
安装回归。
|
|
74
|
+
|
|
69
75
|
未选择的模块会从 package、源码、依赖、Composition、Manifest、schema、migration
|
|
70
76
|
和模块文档中物理排除,而不是只隐藏菜单或关闭 Feature。模块依赖会自动补齐;未知
|
|
71
77
|
模块和不闭合组合会在写入前拒绝。
|
package/dist/cli.js
CHANGED
|
@@ -359,7 +359,8 @@ var optionalModuleManifests = [
|
|
|
359
359
|
"system",
|
|
360
360
|
"system.identity",
|
|
361
361
|
"system.search",
|
|
362
|
-
"system.scheduler"
|
|
362
|
+
"system.scheduler",
|
|
363
|
+
"system.storage"
|
|
363
364
|
]),
|
|
364
365
|
packages: ["packages/example-work-order"],
|
|
365
366
|
fileRoots: [
|
|
@@ -383,6 +384,7 @@ function module(name, label, description, dependencies) {
|
|
|
383
384
|
dependencies,
|
|
384
385
|
conflicts: [],
|
|
385
386
|
packages: [],
|
|
387
|
+
registryDependencies: [],
|
|
386
388
|
fileRoots: [],
|
|
387
389
|
documentation: [],
|
|
388
390
|
schemaFiles: [],
|
|
@@ -435,7 +437,13 @@ var platformModules = [
|
|
|
435
437
|
},
|
|
436
438
|
{
|
|
437
439
|
...module2("system.license", "离线 License", "离线验签、安装和限制态。", "optional", ["system"]),
|
|
438
|
-
|
|
440
|
+
registryDependencies: [
|
|
441
|
+
{
|
|
442
|
+
sourceName: "@southwind-ai/license",
|
|
443
|
+
name: "@southwind-ai/license",
|
|
444
|
+
version: "^0.1.1"
|
|
445
|
+
}
|
|
446
|
+
],
|
|
439
447
|
fileRoots: [
|
|
440
448
|
"apps/server/src/license",
|
|
441
449
|
"apps/web/src/components/license",
|
|
@@ -582,6 +590,7 @@ function module2(name, label, description, selection, dependencies = []) {
|
|
|
582
590
|
dependencies,
|
|
583
591
|
conflicts: [],
|
|
584
592
|
packages: [],
|
|
593
|
+
registryDependencies: [],
|
|
585
594
|
fileRoots: [],
|
|
586
595
|
documentation: [],
|
|
587
596
|
schemaFiles: [],
|
|
@@ -711,7 +720,7 @@ var helpText = `create-windy <项目名> [选项]
|
|
|
711
720
|
`;
|
|
712
721
|
|
|
713
722
|
// src/create-project.ts
|
|
714
|
-
import { mkdir as mkdir4, readdir as
|
|
723
|
+
import { mkdir as mkdir4, readdir as readdir5, rm as rm4 } from "node:fs/promises";
|
|
715
724
|
|
|
716
725
|
// src/commands.ts
|
|
717
726
|
import { spawn } from "node:child_process";
|
|
@@ -902,14 +911,14 @@ function isAlreadyExists(error) {
|
|
|
902
911
|
// src/generator.ts
|
|
903
912
|
import {
|
|
904
913
|
copyFile,
|
|
905
|
-
lstat as
|
|
914
|
+
lstat as lstat4,
|
|
906
915
|
mkdir as mkdir3,
|
|
907
|
-
readFile as
|
|
908
|
-
readdir as
|
|
916
|
+
readFile as readFile9,
|
|
917
|
+
readdir as readdir4,
|
|
909
918
|
rm as rm3,
|
|
910
|
-
writeFile as
|
|
919
|
+
writeFile as writeFile8
|
|
911
920
|
} from "node:fs/promises";
|
|
912
|
-
import { basename as
|
|
921
|
+
import { basename as basename3, extname as extname3, join as join9 } from "node:path";
|
|
913
922
|
|
|
914
923
|
// src/customer-docker.ts
|
|
915
924
|
import { readFile as readFile2, writeFile } from "node:fs/promises";
|
|
@@ -919,6 +928,7 @@ var supplierWorkspaceCopies = [
|
|
|
919
928
|
"COPY apps/signing-service/package.json apps/signing-service/package.json",
|
|
920
929
|
"COPY packages/create-windy/package.json packages/create-windy/package.json"
|
|
921
930
|
];
|
|
931
|
+
var supplierWorkspacePaths = ["packages/license-sdk"];
|
|
922
932
|
async function prepareCustomerDockerfiles(root) {
|
|
923
933
|
await Promise.all(["apps/server/Dockerfile", "apps/web/Dockerfile"].map(async (path) => {
|
|
924
934
|
const absolutePath = join2(root, path);
|
|
@@ -929,7 +939,7 @@ async function prepareCustomerDockerfiles(root) {
|
|
|
929
939
|
function rewriteCustomerDockerfile(source) {
|
|
930
940
|
const lines = source.split(`
|
|
931
941
|
`).filter((line) => {
|
|
932
|
-
return !supplierWorkspaceCopies.includes(line) && !line.includes("deploy/production/server-entrypoint.sh");
|
|
942
|
+
return !supplierWorkspaceCopies.includes(line) && !supplierWorkspacePaths.some((path) => line.includes(path)) && !line.includes("deploy/production/server-entrypoint.sh");
|
|
933
943
|
});
|
|
934
944
|
return lines.join(`
|
|
935
945
|
`).replace("COPY package.json bun.lock ./", "COPY package.json ./").replace("RUN bun install --frozen-lockfile", "RUN bun install");
|
|
@@ -1131,6 +1141,10 @@ async function materializeSelectedModules(targetDirectory, selectedNames) {
|
|
|
1131
1141
|
const selected = new Set(selectedNames);
|
|
1132
1142
|
const removed = moduleDistributionCatalog.filter(({ name }) => !selected.has(name));
|
|
1133
1143
|
const removedPackageNames = await readRemovedPackageNames(targetDirectory, removed.flatMap(({ packages }) => packages));
|
|
1144
|
+
for (const dependency of removed.flatMap(({ registryDependencies }) => registryDependencies)) {
|
|
1145
|
+
removedPackageNames.add(dependency.sourceName);
|
|
1146
|
+
removedPackageNames.add(dependency.name);
|
|
1147
|
+
}
|
|
1134
1148
|
await stripModuleBlocks(targetDirectory, selected);
|
|
1135
1149
|
await pruneDatabaseArtifacts(targetDirectory, removed.flatMap(({ databaseTables, transientDatabaseTables }) => [
|
|
1136
1150
|
...databaseTables,
|
|
@@ -1380,7 +1394,7 @@ License 签发中心、独立签名服务、Vault、发布治理、内部任务
|
|
|
1380
1394
|
|
|
1381
1395
|
- 架构:从 [Module Manifest 组合](./architecture/module-manifest-composition.md) 开始。
|
|
1382
1396
|
- 平台开发:从 [系统 CRUD API](./platform/system-crud-api.md) 和 [CRUD 生成器](./development/crud-generator.md) 开始。
|
|
1383
|
-
${includeOfflineLicense ? "- License 消费端:[离线激活与安装协议](./license/license-offline-activation-code.md)
|
|
1397
|
+
${includeOfflineLicense ? "- License 消费端:[离线激活与安装协议](./license/license-offline-activation-code.md);运行时能力由 npm 依赖 `@southwind-ai/license` 提供。" : ""}
|
|
1384
1398
|
- 运维:[可观测性](./operations/observability.md) 与 [运维总览](./platform/operations-overview.md)。
|
|
1385
1399
|
- 兼容:[RuoYi-Vue Adapter](./adapters/ruoyi-vue-compatibility.md)。
|
|
1386
1400
|
`;
|
|
@@ -1571,7 +1585,8 @@ function createStarterPackage(source, projectName, includeOxc = true, projectLic
|
|
|
1571
1585
|
typecheck: [
|
|
1572
1586
|
"bun run --cwd apps/web typecheck",
|
|
1573
1587
|
"bun run --cwd apps/server typecheck",
|
|
1574
|
-
|
|
1588
|
+
"bun run --cwd packages/jobs typecheck",
|
|
1589
|
+
"bun run --cwd packages/server-sdk typecheck",
|
|
1575
1590
|
...selectedModules.includes("system.storage") ? ["bun run --cwd packages/storage typecheck"] : [],
|
|
1576
1591
|
"bun run --cwd packages/database typecheck",
|
|
1577
1592
|
"bun run --cwd packages/crud-generator typecheck"
|
|
@@ -1612,8 +1627,9 @@ var templateDirectories = [
|
|
|
1612
1627
|
"packages/crud-generator",
|
|
1613
1628
|
"packages/database",
|
|
1614
1629
|
"packages/example-work-order",
|
|
1615
|
-
"packages/
|
|
1630
|
+
"packages/jobs",
|
|
1616
1631
|
"packages/modules",
|
|
1632
|
+
"packages/server-sdk",
|
|
1617
1633
|
"packages/shared",
|
|
1618
1634
|
"packages/storage"
|
|
1619
1635
|
];
|
|
@@ -1749,6 +1765,81 @@ function isModuleVersion(value) {
|
|
|
1749
1765
|
return typeof module3.name === "string" && module3.name.length > 0 && typeof module3.version === "string" && module3.version.length > 0;
|
|
1750
1766
|
}
|
|
1751
1767
|
|
|
1768
|
+
// src/registry-dependencies.ts
|
|
1769
|
+
import { lstat as lstat3, readFile as readFile8, readdir as readdir3, writeFile as writeFile7 } from "node:fs/promises";
|
|
1770
|
+
import { basename as basename2, extname as extname2, join as join8 } from "node:path";
|
|
1771
|
+
var dependencySections = [
|
|
1772
|
+
"dependencies",
|
|
1773
|
+
"devDependencies",
|
|
1774
|
+
"optionalDependencies",
|
|
1775
|
+
"peerDependencies"
|
|
1776
|
+
];
|
|
1777
|
+
var replaceableExtensions = new Set([
|
|
1778
|
+
".css",
|
|
1779
|
+
".html",
|
|
1780
|
+
".js",
|
|
1781
|
+
".json",
|
|
1782
|
+
".md",
|
|
1783
|
+
".mjs",
|
|
1784
|
+
".ts",
|
|
1785
|
+
".tsx",
|
|
1786
|
+
".vue"
|
|
1787
|
+
]);
|
|
1788
|
+
async function materializeRegistryDependencies(root, dependencies) {
|
|
1789
|
+
if (!dependencies.length)
|
|
1790
|
+
return;
|
|
1791
|
+
for (const path of await collectFiles3(root)) {
|
|
1792
|
+
if (!replaceableExtensions.has(extname2(path)))
|
|
1793
|
+
continue;
|
|
1794
|
+
if (basename2(path) === "package.json") {
|
|
1795
|
+
await rewritePackageJson(path, dependencies);
|
|
1796
|
+
continue;
|
|
1797
|
+
}
|
|
1798
|
+
const source = await readFile8(path, "utf8");
|
|
1799
|
+
const output = dependencies.reduce((value, dependency) => value.replaceAll(dependency.sourceName, dependency.name), source);
|
|
1800
|
+
if (output !== source)
|
|
1801
|
+
await writeFile7(path, output);
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
async function rewritePackageJson(path, registryDependencies) {
|
|
1805
|
+
const value = JSON.parse(await readFile8(path, "utf8"));
|
|
1806
|
+
let changed = false;
|
|
1807
|
+
for (const section of dependencySections) {
|
|
1808
|
+
const dependencies = value[section];
|
|
1809
|
+
if (!dependencies)
|
|
1810
|
+
continue;
|
|
1811
|
+
for (const dependency of registryDependencies) {
|
|
1812
|
+
if (!(dependency.sourceName in dependencies))
|
|
1813
|
+
continue;
|
|
1814
|
+
delete dependencies[dependency.sourceName];
|
|
1815
|
+
dependencies[dependency.name] = dependency.version;
|
|
1816
|
+
changed = true;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
if (changed)
|
|
1820
|
+
await writeFile7(path, `${JSON.stringify(value, null, 2)}
|
|
1821
|
+
`);
|
|
1822
|
+
}
|
|
1823
|
+
async function collectFiles3(root) {
|
|
1824
|
+
const files = [];
|
|
1825
|
+
await visit(root);
|
|
1826
|
+
return files.sort();
|
|
1827
|
+
async function visit(directory) {
|
|
1828
|
+
for (const name of (await readdir3(directory)).sort()) {
|
|
1829
|
+
if ([".git", "node_modules", "dist"].includes(name))
|
|
1830
|
+
continue;
|
|
1831
|
+
const path = join8(directory, name);
|
|
1832
|
+
const metadata = await lstat3(path);
|
|
1833
|
+
if (metadata.isSymbolicLink())
|
|
1834
|
+
continue;
|
|
1835
|
+
if (metadata.isDirectory())
|
|
1836
|
+
await visit(path);
|
|
1837
|
+
else
|
|
1838
|
+
files.push(path);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1752
1843
|
// src/generator.ts
|
|
1753
1844
|
async function generateProject(input) {
|
|
1754
1845
|
validateProjectName(input.projectName);
|
|
@@ -1760,29 +1851,30 @@ async function generateProject(input) {
|
|
|
1760
1851
|
const templateMetadata = await readTemplateMetadata(input.sourceRoot);
|
|
1761
1852
|
const selectedModules = input.selectedModules ?? templateMetadata.modules.filter(({ name }) => includeExample || name !== "work-order").map(({ name }) => name);
|
|
1762
1853
|
for (const relativePath2 of generationTemplatePaths(true, includeOxc)) {
|
|
1763
|
-
await copyTree(await resolveTemplateSource(input.sourceRoot, relativePath2),
|
|
1854
|
+
await copyTree(await resolveTemplateSource(input.sourceRoot, relativePath2), join9(input.targetDirectory, relativePath2));
|
|
1764
1855
|
}
|
|
1765
1856
|
await materializeSelectedModules(input.targetDirectory, selectedModules);
|
|
1766
|
-
|
|
1767
|
-
const
|
|
1768
|
-
|
|
1857
|
+
await materializeRegistryDependencies(input.targetDirectory, selectedModuleManifests(selectedModules).flatMap(({ registryDependencies }) => registryDependencies));
|
|
1858
|
+
const packagePath = join9(input.targetDirectory, "package.json");
|
|
1859
|
+
const packageJson = JSON.parse(await readFile9(packagePath, "utf8"));
|
|
1860
|
+
await writeFile8(packagePath, `${JSON.stringify(createStarterPackage(packageJson, input.projectName, includeOxc, projectLicense, selectedModules, templateMetadata.generatorVersion), null, 2)}
|
|
1769
1861
|
`);
|
|
1770
|
-
await
|
|
1771
|
-
await
|
|
1772
|
-
await
|
|
1773
|
-
await
|
|
1862
|
+
await writeFile8(join9(input.targetDirectory, "docker-compose.yml"), starterCompose);
|
|
1863
|
+
await writeFile8(join9(input.targetDirectory, ".env.example"), environmentExample(includeExample));
|
|
1864
|
+
await writeFile8(join9(input.targetDirectory, "README.md"), starterReadme(input.projectName, includeExample, includeOxc, projectLicense, selectedModules));
|
|
1865
|
+
await writeFile8(join9(input.targetDirectory, "docs/README.md"), starterDocsReadme(selectedModules.includes("system.license")));
|
|
1774
1866
|
await reflectCodeQualityChoice(input.targetDirectory, includeOxc);
|
|
1775
1867
|
await applyWindyBaseLicense(input.targetDirectory);
|
|
1776
1868
|
await applyProjectLicense(input.targetDirectory, projectLicense, input.licenseHolder);
|
|
1777
1869
|
await prepareCustomerDockerfiles(input.targetDirectory);
|
|
1778
1870
|
await writeGenerationProvenance(input.targetDirectory, templateMetadata, input.profile ?? starterProfile.key, selectedModules, includeOxc, projectLicense);
|
|
1779
|
-
await rm3(
|
|
1871
|
+
await rm3(join9(input.targetDirectory, "bun.lock"), { force: true });
|
|
1780
1872
|
await writeManagedFilesManifest(input.targetDirectory, templateMetadata.generatorVersion);
|
|
1781
1873
|
}
|
|
1782
1874
|
async function resolveTemplateSource(sourceRoot, relativePath2) {
|
|
1783
|
-
const source =
|
|
1875
|
+
const source = join9(sourceRoot, relativePath2);
|
|
1784
1876
|
try {
|
|
1785
|
-
await
|
|
1877
|
+
await lstat4(source);
|
|
1786
1878
|
return source;
|
|
1787
1879
|
} catch (error) {
|
|
1788
1880
|
if (!isMissing2(error))
|
|
@@ -1791,13 +1883,13 @@ async function resolveTemplateSource(sourceRoot, relativePath2) {
|
|
|
1791
1883
|
const alias = npmTemplateAliases[relativePath2];
|
|
1792
1884
|
if (!alias)
|
|
1793
1885
|
return source;
|
|
1794
|
-
return
|
|
1886
|
+
return join9(sourceRoot, alias);
|
|
1795
1887
|
}
|
|
1796
1888
|
async function assertGeneratedProjectIsClean(targetDirectory) {
|
|
1797
1889
|
const violations = [];
|
|
1798
1890
|
await walk(targetDirectory, async (path) => {
|
|
1799
|
-
const name =
|
|
1800
|
-
const extension =
|
|
1891
|
+
const name = basename3(path);
|
|
1892
|
+
const extension = extname3(name).toLowerCase();
|
|
1801
1893
|
if (excludedNames.has(name) || excludedRuntimeFiles.has(name) || [".key", ".pem", ".p12", ".pfx"].includes(extension)) {
|
|
1802
1894
|
violations.push(path.slice(targetDirectory.length + 1));
|
|
1803
1895
|
}
|
|
@@ -1816,7 +1908,7 @@ function validateProjectName(projectName) {
|
|
|
1816
1908
|
}
|
|
1817
1909
|
async function assertTargetAvailable(targetDirectory) {
|
|
1818
1910
|
try {
|
|
1819
|
-
const entries = await
|
|
1911
|
+
const entries = await readdir4(targetDirectory);
|
|
1820
1912
|
if (entries.length)
|
|
1821
1913
|
throw new Error("目标目录不是空目录");
|
|
1822
1914
|
} catch (error) {
|
|
@@ -1826,28 +1918,28 @@ async function assertTargetAvailable(targetDirectory) {
|
|
|
1826
1918
|
}
|
|
1827
1919
|
}
|
|
1828
1920
|
async function copyTree(source, target) {
|
|
1829
|
-
const metadata = await
|
|
1830
|
-
const name =
|
|
1921
|
+
const metadata = await lstat4(source);
|
|
1922
|
+
const name = basename3(source);
|
|
1831
1923
|
if (shouldExclude(name) || metadata.isSymbolicLink())
|
|
1832
1924
|
return;
|
|
1833
1925
|
if (metadata.isDirectory()) {
|
|
1834
1926
|
await mkdir3(target, { recursive: true });
|
|
1835
|
-
for (const child of await
|
|
1836
|
-
await copyTree(
|
|
1927
|
+
for (const child of await readdir4(source)) {
|
|
1928
|
+
await copyTree(join9(source, child), join9(target, child));
|
|
1837
1929
|
}
|
|
1838
1930
|
return;
|
|
1839
1931
|
}
|
|
1840
|
-
await mkdir3(
|
|
1932
|
+
await mkdir3(join9(target, ".."), { recursive: true });
|
|
1841
1933
|
await copyFile(source, target);
|
|
1842
1934
|
}
|
|
1843
1935
|
function shouldExclude(name) {
|
|
1844
1936
|
return excludedNames.has(name) || excludedRuntimeFiles.has(name);
|
|
1845
1937
|
}
|
|
1846
1938
|
async function walk(directory, visit) {
|
|
1847
|
-
for (const name of await
|
|
1848
|
-
const path =
|
|
1939
|
+
for (const name of await readdir4(directory)) {
|
|
1940
|
+
const path = join9(directory, name);
|
|
1849
1941
|
await visit(path);
|
|
1850
|
-
if ((await
|
|
1942
|
+
if ((await lstat4(path)).isDirectory())
|
|
1851
1943
|
await walk(path, visit);
|
|
1852
1944
|
}
|
|
1853
1945
|
}
|
|
@@ -1924,7 +2016,7 @@ async function createProject(options, dependencies = {}) {
|
|
|
1924
2016
|
}
|
|
1925
2017
|
async function inspectTarget(path) {
|
|
1926
2018
|
try {
|
|
1927
|
-
return (await
|
|
2019
|
+
return (await readdir5(path)).length === 0 ? "empty" : "non-empty";
|
|
1928
2020
|
} catch (error) {
|
|
1929
2021
|
if (isMissing3(error))
|
|
1930
2022
|
return "missing";
|
|
@@ -3696,8 +3788,8 @@ import { rm as rm8 } from "node:fs/promises";
|
|
|
3696
3788
|
import { resolve as resolve4 } from "node:path";
|
|
3697
3789
|
|
|
3698
3790
|
// src/update/doctor.ts
|
|
3699
|
-
import { readFile as
|
|
3700
|
-
import { join as
|
|
3791
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
3792
|
+
import { join as join11 } from "node:path";
|
|
3701
3793
|
|
|
3702
3794
|
// src/update/process.ts
|
|
3703
3795
|
import { spawn as spawn3 } from "node:child_process";
|
|
@@ -3729,11 +3821,11 @@ import {
|
|
|
3729
3821
|
access as access2,
|
|
3730
3822
|
copyFile as copyFile2,
|
|
3731
3823
|
mkdir as mkdir5,
|
|
3732
|
-
readFile as
|
|
3824
|
+
readFile as readFile10,
|
|
3733
3825
|
rm as rm5,
|
|
3734
|
-
writeFile as
|
|
3826
|
+
writeFile as writeFile9
|
|
3735
3827
|
} from "node:fs/promises";
|
|
3736
|
-
import { dirname as dirname3, join as
|
|
3828
|
+
import { dirname as dirname3, join as join10 } from "node:path";
|
|
3737
3829
|
var updateStatePath = ".windy/update-state.json";
|
|
3738
3830
|
async function applyTransaction(plan) {
|
|
3739
3831
|
if (plan.conflicts.length) {
|
|
@@ -3742,7 +3834,7 @@ async function applyTransaction(plan) {
|
|
|
3742
3834
|
const changed = plan.files.filter(({ action }) => action === "create" || action === "update" || action === "delete");
|
|
3743
3835
|
for (const file of changed)
|
|
3744
3836
|
assertSafePath(file.path);
|
|
3745
|
-
const backupDirectory =
|
|
3837
|
+
const backupDirectory = join10(plan.projectDirectory, ".windy/backups", plan.id);
|
|
3746
3838
|
const protectedPaths = new Set([
|
|
3747
3839
|
...changed.map(({ path: path2 }) => path2),
|
|
3748
3840
|
".windy/generation.json",
|
|
@@ -3751,12 +3843,12 @@ async function applyTransaction(plan) {
|
|
|
3751
3843
|
]);
|
|
3752
3844
|
const backupEntries = [];
|
|
3753
3845
|
for (const path2 of protectedPaths) {
|
|
3754
|
-
const source =
|
|
3846
|
+
const source = join10(plan.projectDirectory, path2);
|
|
3755
3847
|
const existed = await exists(source);
|
|
3756
3848
|
backupEntries.push({ path: path2, existed });
|
|
3757
3849
|
if (!existed)
|
|
3758
3850
|
continue;
|
|
3759
|
-
const target =
|
|
3851
|
+
const target = join10(backupDirectory, "files", path2);
|
|
3760
3852
|
await mkdir5(dirname3(target), { recursive: true });
|
|
3761
3853
|
await copyFile2(source, target);
|
|
3762
3854
|
}
|
|
@@ -3769,7 +3861,7 @@ async function applyTransaction(plan) {
|
|
|
3769
3861
|
await writeState(plan.projectDirectory, state);
|
|
3770
3862
|
try {
|
|
3771
3863
|
for (const file of changed) {
|
|
3772
|
-
const target =
|
|
3864
|
+
const target = join10(plan.projectDirectory, file.path);
|
|
3773
3865
|
if (file.action === "delete") {
|
|
3774
3866
|
await rm5(target, { force: true });
|
|
3775
3867
|
continue;
|
|
@@ -3777,7 +3869,7 @@ async function applyTransaction(plan) {
|
|
|
3777
3869
|
if (!file.content)
|
|
3778
3870
|
throw new Error(`更新计划缺少文件内容:${file.path}`);
|
|
3779
3871
|
await mkdir5(dirname3(target), { recursive: true });
|
|
3780
|
-
await
|
|
3872
|
+
await writeFile9(target, file.content);
|
|
3781
3873
|
}
|
|
3782
3874
|
} catch (error) {
|
|
3783
3875
|
await restoreUpdateState(plan.projectDirectory, state);
|
|
@@ -3792,7 +3884,7 @@ async function applyTransaction(plan) {
|
|
|
3792
3884
|
}
|
|
3793
3885
|
async function readUpdateState(projectDirectory) {
|
|
3794
3886
|
try {
|
|
3795
|
-
const parsed = JSON.parse(await
|
|
3887
|
+
const parsed = JSON.parse(await readFile10(join10(projectDirectory, updateStatePath), "utf8"));
|
|
3796
3888
|
if (!isUpdateState(parsed))
|
|
3797
3889
|
throw new Error("更新恢复状态无效,请人工检查 .windy 目录");
|
|
3798
3890
|
return parsed;
|
|
@@ -3805,25 +3897,25 @@ async function readUpdateState(projectDirectory) {
|
|
|
3805
3897
|
async function restoreUpdateState(projectDirectory, state) {
|
|
3806
3898
|
for (const entry of state.entries) {
|
|
3807
3899
|
assertSafePath(entry.path);
|
|
3808
|
-
const target =
|
|
3900
|
+
const target = join10(projectDirectory, entry.path);
|
|
3809
3901
|
if (!entry.existed) {
|
|
3810
3902
|
await rm5(target, { force: true });
|
|
3811
3903
|
continue;
|
|
3812
3904
|
}
|
|
3813
|
-
const backup =
|
|
3905
|
+
const backup = join10(state.backupDirectory, "files", entry.path);
|
|
3814
3906
|
await mkdir5(dirname3(target), { recursive: true });
|
|
3815
3907
|
await copyFile2(backup, target);
|
|
3816
3908
|
}
|
|
3817
|
-
await rm5(
|
|
3909
|
+
await rm5(join10(projectDirectory, updateStatePath), { force: true });
|
|
3818
3910
|
await rm5(state.backupDirectory, { recursive: true, force: true });
|
|
3819
3911
|
}
|
|
3820
3912
|
async function clearUpdateState(projectDirectory) {
|
|
3821
|
-
await rm5(
|
|
3913
|
+
await rm5(join10(projectDirectory, updateStatePath), { force: true });
|
|
3822
3914
|
}
|
|
3823
3915
|
async function writeState(projectDirectory, state) {
|
|
3824
|
-
const path2 =
|
|
3916
|
+
const path2 = join10(projectDirectory, updateStatePath);
|
|
3825
3917
|
await mkdir5(dirname3(path2), { recursive: true });
|
|
3826
|
-
await
|
|
3918
|
+
await writeFile9(path2, `${JSON.stringify(state, null, 2)}
|
|
3827
3919
|
`);
|
|
3828
3920
|
}
|
|
3829
3921
|
async function exists(path2) {
|
|
@@ -3871,7 +3963,7 @@ async function diagnoseProject(projectDirectory, repair = false) {
|
|
|
3871
3963
|
if (file.ownership === "project-owned")
|
|
3872
3964
|
continue;
|
|
3873
3965
|
try {
|
|
3874
|
-
const changed = hashContent(await
|
|
3966
|
+
const changed = hashContent(await readFile11(join11(projectDirectory, file.path))) !== file.hash;
|
|
3875
3967
|
if (!changed)
|
|
3876
3968
|
continue;
|
|
3877
3969
|
modifiedManagedFiles.push(file.path);
|
|
@@ -3908,7 +4000,9 @@ var recipes = [
|
|
|
3908
4000
|
{ id: "starter-0.2.3-to-0.2.4", from: "0.2.3", to: "0.2.4" },
|
|
3909
4001
|
{ id: "starter-0.2.4-to-0.2.5", from: "0.2.4", to: "0.2.5" },
|
|
3910
4002
|
{ id: "starter-0.2.5-to-0.2.6", from: "0.2.5", to: "0.2.6" },
|
|
3911
|
-
{ id: "starter-0.2.6-to-0.2.7", from: "0.2.6", to: "0.2.7" }
|
|
4003
|
+
{ id: "starter-0.2.6-to-0.2.7", from: "0.2.6", to: "0.2.7" },
|
|
4004
|
+
{ id: "starter-0.2.7-to-0.2.8", from: "0.2.7", to: "0.2.8" },
|
|
4005
|
+
{ id: "starter-0.2.8-to-0.2.9", from: "0.2.8", to: "0.2.9" }
|
|
3912
4006
|
];
|
|
3913
4007
|
function resolveRecipeChain(sourceVersion, targetVersion) {
|
|
3914
4008
|
if (sourceVersion === targetVersion)
|
|
@@ -3933,19 +4027,19 @@ function resolveRecipeChain(sourceVersion, targetVersion) {
|
|
|
3933
4027
|
}
|
|
3934
4028
|
|
|
3935
4029
|
// src/update/updater.ts
|
|
3936
|
-
import { mkdir as mkdir7, readFile as
|
|
3937
|
-
import { dirname as dirname4, join as
|
|
4030
|
+
import { mkdir as mkdir7, readFile as readFile14, rm as rm7, writeFile as writeFile11 } from "node:fs/promises";
|
|
4031
|
+
import { dirname as dirname4, join as join15 } from "node:path";
|
|
3938
4032
|
|
|
3939
4033
|
// src/update/artifacts.ts
|
|
3940
|
-
import { mkdir as mkdir6, mkdtemp, readFile as
|
|
4034
|
+
import { mkdir as mkdir6, mkdtemp, readFile as readFile12 } from "node:fs/promises";
|
|
3941
4035
|
import { tmpdir } from "node:os";
|
|
3942
|
-
import { basename as
|
|
4036
|
+
import { basename as basename4, join as join12 } from "node:path";
|
|
3943
4037
|
class PublishedArtifactProvider {
|
|
3944
4038
|
async prepare(projectDirectory, provenance) {
|
|
3945
|
-
const temporaryRoot = await mkdtemp(
|
|
4039
|
+
const temporaryRoot = await mkdtemp(join12(tmpdir(), "windy-update-"));
|
|
3946
4040
|
const projectName = await readProjectName2(projectDirectory);
|
|
3947
|
-
const baseDirectory =
|
|
3948
|
-
const targetDirectory =
|
|
4041
|
+
const baseDirectory = join12(temporaryRoot, "base", projectName);
|
|
4042
|
+
const targetDirectory = join12(temporaryRoot, "target", projectName);
|
|
3949
4043
|
await generatePublishedBase(temporaryRoot, projectName, provenance, baseDirectory);
|
|
3950
4044
|
await generateProject({
|
|
3951
4045
|
sourceRoot: await resolveTemplateRoot(),
|
|
@@ -3961,7 +4055,7 @@ class PublishedArtifactProvider {
|
|
|
3961
4055
|
}
|
|
3962
4056
|
}
|
|
3963
4057
|
async function generatePublishedBase(temporaryRoot, projectName, provenance, expectedDirectory) {
|
|
3964
|
-
const parent =
|
|
4058
|
+
const parent = join12(temporaryRoot, "base");
|
|
3965
4059
|
await mkdir6(parent, { recursive: true });
|
|
3966
4060
|
const args = [
|
|
3967
4061
|
"--bun",
|
|
@@ -3985,33 +4079,33 @@ async function generatePublishedBase(temporaryRoot, projectName, provenance, exp
|
|
|
3985
4079
|
}
|
|
3986
4080
|
}
|
|
3987
4081
|
await assertProcess("bunx", args, parent);
|
|
3988
|
-
if (
|
|
4082
|
+
if (join12(parent, projectName) !== expectedDirectory) {
|
|
3989
4083
|
throw new Error("历史 artifact 生成目录异常");
|
|
3990
4084
|
}
|
|
3991
4085
|
}
|
|
3992
4086
|
async function readProjectName2(projectDirectory) {
|
|
3993
|
-
const source = JSON.parse(await
|
|
3994
|
-
return source.name ||
|
|
4087
|
+
const source = JSON.parse(await readFile12(join12(projectDirectory, "package.json"), "utf8"));
|
|
4088
|
+
return source.name || basename4(projectDirectory);
|
|
3995
4089
|
}
|
|
3996
4090
|
|
|
3997
4091
|
// src/update/planner.ts
|
|
3998
|
-
import { access as access3, readFile as
|
|
3999
|
-
import { join as
|
|
4092
|
+
import { access as access3, readFile as readFile13 } from "node:fs/promises";
|
|
4093
|
+
import { join as join14 } from "node:path";
|
|
4000
4094
|
|
|
4001
4095
|
// src/update/merge.ts
|
|
4002
|
-
import { mkdtemp as mkdtemp2, rm as rm6, writeFile as
|
|
4096
|
+
import { mkdtemp as mkdtemp2, rm as rm6, writeFile as writeFile10 } from "node:fs/promises";
|
|
4003
4097
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
4004
|
-
import { join as
|
|
4098
|
+
import { join as join13 } from "node:path";
|
|
4005
4099
|
async function mergeTextFile(base, ours, theirs) {
|
|
4006
|
-
const root = await mkdtemp2(
|
|
4100
|
+
const root = await mkdtemp2(join13(tmpdir2(), "windy-merge-"));
|
|
4007
4101
|
try {
|
|
4008
|
-
const oursPath =
|
|
4009
|
-
const basePath =
|
|
4010
|
-
const theirsPath =
|
|
4102
|
+
const oursPath = join13(root, "ours");
|
|
4103
|
+
const basePath = join13(root, "base");
|
|
4104
|
+
const theirsPath = join13(root, "theirs");
|
|
4011
4105
|
await Promise.all([
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4106
|
+
writeFile10(oursPath, ours),
|
|
4107
|
+
writeFile10(basePath, base),
|
|
4108
|
+
writeFile10(theirsPath, theirs)
|
|
4015
4109
|
]);
|
|
4016
4110
|
const result = await captureProcess("git", ["merge-file", "-p", "--diff3", oursPath, basePath, theirsPath], root);
|
|
4017
4111
|
if (result.code === 0) {
|
|
@@ -4129,9 +4223,9 @@ async function createUpdatePlan(request, artifacts) {
|
|
|
4129
4223
|
}
|
|
4130
4224
|
async function planFile(path2, project, baseRoot, targetRoot, source, target) {
|
|
4131
4225
|
const [ours, base, theirs] = await Promise.all([
|
|
4132
|
-
readOptional(
|
|
4133
|
-
readOptional(
|
|
4134
|
-
readOptional(
|
|
4226
|
+
readOptional(join14(project, path2)),
|
|
4227
|
+
readOptional(join14(baseRoot, path2)),
|
|
4228
|
+
readOptional(join14(targetRoot, path2))
|
|
4135
4229
|
]);
|
|
4136
4230
|
const ownership = target?.ownership || source?.ownership || classifyOwnership(path2);
|
|
4137
4231
|
if (path2.startsWith("packages/database/drizzle/") && path2.endsWith(".sql")) {
|
|
@@ -4199,7 +4293,7 @@ function conflict(path2, ownership, reason) {
|
|
|
4199
4293
|
}
|
|
4200
4294
|
async function readOptional(path2) {
|
|
4201
4295
|
try {
|
|
4202
|
-
return await
|
|
4296
|
+
return await readFile13(path2);
|
|
4203
4297
|
} catch (error) {
|
|
4204
4298
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
4205
4299
|
return;
|
|
@@ -4215,7 +4309,7 @@ async function assertGitClean(projectDirectory) {
|
|
|
4215
4309
|
}
|
|
4216
4310
|
async function assertNoPendingUpdate(projectDirectory) {
|
|
4217
4311
|
try {
|
|
4218
|
-
await access3(
|
|
4312
|
+
await access3(join14(projectDirectory, ".windy/update-state.json"));
|
|
4219
4313
|
throw new Error("检测到未完成更新,请先运行 bun run windy doctor --repair");
|
|
4220
4314
|
} catch (error) {
|
|
4221
4315
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
@@ -4251,7 +4345,7 @@ class DefaultStarterUpdater {
|
|
|
4251
4345
|
try {
|
|
4252
4346
|
await this.#execute("bun", ["install", "--force"], result.plan.projectDirectory);
|
|
4253
4347
|
steps.push({ name: "bun install --force", status: "passed" });
|
|
4254
|
-
const packageJson = JSON.parse(await
|
|
4348
|
+
const packageJson = JSON.parse(await readFile14(join15(result.plan.projectDirectory, "package.json"), "utf8"));
|
|
4255
4349
|
for (const name of ["lint", "typecheck", "test", "build"]) {
|
|
4256
4350
|
if (!packageJson.scripts?.[name]) {
|
|
4257
4351
|
steps.push({ name: `bun run ${name}`, status: "skipped" });
|
|
@@ -4280,13 +4374,13 @@ class DefaultStarterUpdater {
|
|
|
4280
4374
|
}
|
|
4281
4375
|
async function finalize(result) {
|
|
4282
4376
|
const root = result.plan.projectDirectory;
|
|
4283
|
-
await
|
|
4377
|
+
await writeFile11(join15(root, ".windy/generation.json"), `${JSON.stringify(result.plan.targetProvenance, null, 2)}
|
|
4284
4378
|
`);
|
|
4285
|
-
await
|
|
4379
|
+
await writeFile11(join15(root, ".windy/files.json"), `${JSON.stringify(result.plan.targetManifest, null, 2)}
|
|
4286
4380
|
`);
|
|
4287
4381
|
}
|
|
4288
4382
|
async function writeReport(result, steps, relativePath2) {
|
|
4289
|
-
const path2 =
|
|
4383
|
+
const path2 = join15(result.plan.projectDirectory, relativePath2);
|
|
4290
4384
|
await mkdir7(dirname4(path2), { recursive: true });
|
|
4291
4385
|
const lines = [
|
|
4292
4386
|
`# Windy 更新报告 ${result.plan.id}`,
|
|
@@ -4304,7 +4398,7 @@ async function writeReport(result, steps, relativePath2) {
|
|
|
4304
4398
|
`备份保留在 \`.windy/backups/${result.plan.id}\`,确认稳定后可人工删除。`,
|
|
4305
4399
|
""
|
|
4306
4400
|
];
|
|
4307
|
-
await
|
|
4401
|
+
await writeFile11(path2, lines.join(`
|
|
4308
4402
|
`));
|
|
4309
4403
|
}
|
|
4310
4404
|
|
package/package.json
CHANGED
|
@@ -13,8 +13,10 @@ COPY packages/create-windy/package.json packages/create-windy/package.json
|
|
|
13
13
|
COPY packages/crud-generator/package.json packages/crud-generator/package.json
|
|
14
14
|
COPY packages/database/package.json packages/database/package.json
|
|
15
15
|
COPY packages/example-work-order/package.json packages/example-work-order/package.json
|
|
16
|
+
COPY packages/jobs/package.json packages/jobs/package.json
|
|
16
17
|
COPY packages/license-sdk/package.json packages/license-sdk/package.json
|
|
17
18
|
COPY packages/modules/package.json packages/modules/package.json
|
|
19
|
+
COPY packages/server-sdk/package.json packages/server-sdk/package.json
|
|
18
20
|
COPY packages/shared/package.json packages/shared/package.json
|
|
19
21
|
COPY packages/storage/package.json packages/storage/package.json
|
|
20
22
|
RUN bun install --frozen-lockfile
|