@oj-module/cli 0.2.18 → 0.2.20
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/devkit/README.md +4 -4
- package/devkit/SKILL.md +41 -37
- package/devkit/framework-dev.md +6 -5
- package/devkit/manual.md +259 -161
- package/devkit/menu-rules.md +3 -3
- package/devkit/module-dev-and-cdn-playground.md +31 -22
- package/devkit/sql-builder-missing-capabilities-pr.md +11 -6
- package/package.json +2 -2
- package/shell-dist/assets/runtime.js +2 -2
- package/shell-dist/index.html +2 -2
- package/shell-dist/versions.json +3 -3
- package/src/__tests__/build-backend.test.ts +54 -0
- package/src/__tests__/layout.test.ts +176 -0
- package/src/__tests__/module-list.test.ts +66 -0
- package/src/__tests__/oj-caps.test.ts +114 -0
- package/src/alias-paths.ts +102 -0
- package/src/build.ts +41 -9
- package/src/bundle.ts +25 -13
- package/src/config.ts +82 -9
- package/src/contract/__tests__/market-client.integration.test.ts +2 -2
- package/src/contract/check.ts +56 -28
- package/src/contract/emit-stub.ts +21 -9
- package/src/contract/handler-scan.ts +19 -10
- package/src/contract/run.ts +14 -4
- package/src/dev.ts +22 -7
- package/src/index.ts +1 -1
- package/src/info.ts +20 -3
- package/src/init.ts +91 -21
- package/src/layout.ts +282 -24
- package/src/lifecycle/__tests__/bundle.test.ts +16 -1
- package/src/lifecycle/__tests__/manifest-contract.test.ts +2 -2
- package/src/market/__tests__/bootstrap.test.ts +17 -9
- package/src/market/bootstrap.ts +30 -17
- package/src/oj-caps.ts +133 -0
- package/src/oj.ts +27 -4
- package/src/preview-config.ts +1 -1
- package/src/preview.ts +2 -1
- package/src/site.ts +2 -2
- package/src/usage.ts +6 -6
- package/src/vendor.ts +5 -1
- package/templates/{api/config.yaml → config.yaml} +13 -8
- package/templates/global.d.ts +7 -6
- package/templates/init.include.yaml +41 -36
- package/templates/package.json +1 -1
- package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/installer.ts +4 -0
- package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/smoke.ts +21 -2
- package/templates/{api/src/_platform → src/_platform/api}/market/api.ts +25 -15
- package/templates/{api/src/_platform → src/_platform/api}/solutions/api.ts +7 -3
- package/templates/{api/src/auth → src/auth/api}/_shared/login-throttle.ts +2 -2
- package/templates/{api/src/auth → src/auth/api}/_shared/session.ts +2 -2
- package/templates/{api/src/auth → src/auth/api}/api.ts +1 -1
- package/templates/{api/src/auth → src/auth/api}/ldap-login/api.ts +1 -1
- package/templates/src/auth/api/manifest.yaml +6 -0
- package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/InstallDialog.test.tsx +53 -1
- package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/marketClient.fake.ts +6 -0
- package/templates/{web/src/oj-market → src/oj-market/web}/api/client.ts +5 -0
- package/templates/{web/src/oj-market → src/oj-market/web}/api/defaultClient.ts +7 -1
- package/templates/{web/src/oj-market → src/oj-market/web}/components/InstallDialog.tsx +80 -5
- package/templates/{web/src/oj-market → src/oj-market/web}/hooks/useMarket.ts +6 -1
- package/templates/{web/src/oj-market → src/oj-market/web}/locales/en-US.json +10 -1
- package/templates/{web/src/oj-market → src/oj-market/web}/locales/zh-CN.json +10 -1
- package/templates/{web/src/oj-market → src/oj-market/web}/types.ts +15 -2
- package/templates/{api/src/system → src/system/api}/login-methods/api.ts +2 -2
- package/templates/src/system/api/manifest.yaml +6 -0
- package/templates/{api/src/system → src/system/api}/oplog/api.ts +4 -4
- package/templates/{api/src/system → src/system/api}/permissions/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/roles/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/roles/bindings/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/settings/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/users/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/users/forbidden/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/users/password/api.ts +3 -3
- package/templates/{api/src/system → src/system/api}/users/roles/api.ts +3 -3
- package/templates/src/tsconfig.json +16 -0
- package/templates/{api/tests → tests}/auth-ldap.spec.ts +2 -2
- package/templates/{api/tests → tests}/auth-session.spec.ts +3 -3
- package/templates/{api/tests → tests}/auth-throttle.spec.ts +1 -1
- package/templates/tests/fixture.ts +434 -0
- package/templates/{api/tests → tests}/guard.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/atomic-state.spec.ts +3 -3
- package/templates/{api/tests → tests}/lifecycle/bootstrap.spec.ts +8 -4
- package/templates/{api/tests → tests}/lifecycle/deploy-smoke.spec.ts +31 -8
- package/templates/{api/tests → tests}/lifecycle/installer.spec.ts +15 -15
- package/templates/{api/tests → tests}/lifecycle/market-api.spec.ts +30 -29
- package/templates/{api/tests → tests}/lifecycle/migrate.spec.ts +6 -6
- package/templates/{api/tests → tests}/lifecycle/preflight.spec.ts +4 -4
- package/templates/{api/tests → tests}/lifecycle/register.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/semver.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/sha384.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/sig-fixtures.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/solutions-api.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/steps-fs.spec.ts +12 -12
- package/templates/{api/tests → tests}/lifecycle/text-edit.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/tgz-guard.spec.ts +1 -1
- package/templates/{api/tests → tests}/lifecycle/trust.spec.ts +5 -5
- package/templates/{api/tests → tests}/lifecycle/uninstall.spec.ts +7 -7
- package/templates/{api/tests → tests}/lifecycle/verify-checks.spec.ts +9 -6
- package/templates/{api/tests → tests}/lifecycle/verify-report.spec.ts +7 -5
- package/templates/{api/tests → tests}/query-utils.spec.ts +1 -1
- package/templates/{api/tests → tests}/rbac-audit.spec.ts +1 -1
- package/templates/{api/tests → tests}/rbac-contacts.spec.ts +2 -2
- package/templates/{api/tests → tests}/rbac-guard.spec.ts +1 -1
- package/templates/{api/tests → tests}/rbac-roles.spec.ts +2 -2
- package/templates/{api/tests → tests}/rbac-seed.spec.ts +1 -1
- package/templates/{api/tests → tests}/rbac-settings.spec.ts +2 -2
- package/templates/{api/tests → tests}/rbac-solution-perms.spec.ts +1 -1
- package/templates/{api/tests → tests}/rbac-users.spec.ts +3 -3
- package/templates/tsconfig.json +5 -1
- package/templates/tsconfig.paths.json +19 -0
- package/templates/types/oj-modules.d.ts +17 -0
- package/templates/vitest.config.ts +22 -0
- package/templates/web.config.ts +23 -13
- package/vendor/host-versions.json +3 -3
- package/templates/api/src/auth/manifest.yaml +0 -5
- package/templates/api/src/system/manifest.yaml +0 -5
- package/templates/api/tests/fixture.ts +0 -58
- package/templates/api/tsconfig.json +0 -8
- package/templates/api/vitest.config.ts +0 -12
- package/templates/logs/task-events.jsonl +0 -0
- /package/templates/{api/.ojm-api-exempt.json → .ojm-api-exempt.json} +0 -0
- /package/templates/{api/seed.mysql.sql → seed.mysql.sql} +0 -0
- /package/templates/{api/seed.pg.sql → seed.pg.sql} +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/README.md +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/atomic.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/history.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/lock.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/semver.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/sha384.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/state.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/deploy-web.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/download.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/extract.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/migrate.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/preflight.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/register.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/reload.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/verify.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/tasks.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/text-edit.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/tgz-guard.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/trust.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/types.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/uninstall.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/verify-checks.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/verify-report.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/respond.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/contacts.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/roles.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/settings.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/solution-perms.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/users.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/access.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/audit.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/guard.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/oplog.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/query.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/rate.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/_shared/site-facade.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/contacts/api.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/contacts/detail/api.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/fixtures/l1-test-user.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/manifest.yaml +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/market/bootstrap.ts +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0001__create_users.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0001__create_users.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0001__create_users.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0002__add_users_avatar_base64.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0002__add_users_avatar_base64.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0003__users_source_display_name.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0003__users_source_display_name.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0004__sys_rbac.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0004__sys_rbac.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0004__sys_rbac.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0005__users_must_change.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0005__users_must_change.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0006__users_is_forbidden.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0006__users_is_forbidden.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0007__users_email.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0008__sys_refresh_token.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0008__sys_refresh_token.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0008__sys_refresh_token.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0009__sys_throttle.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0009__sys_throttle.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0009__sys_throttle.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0010__sys_solution_route.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0010__sys_solution_route.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0010__sys_solution_route.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0011__sys_setting_group_label.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0011__sys_setting_group_label.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0012__market_history.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0012__market_history.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0012__market_history.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/migrations/0013__users_profile.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/schema.yaml +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/seed.mysql.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/seed.pg.sql +0 -0
- /package/templates/{api/src/_platform → src/_platform/api}/seed.sql +0 -0
- /package/templates/{web/src/_platform → src/_platform/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/_platform → src/_platform/web}/__client/api.ts +0 -0
- /package/templates/{web/src/about → src/about/web}/entry.ts +0 -0
- /package/templates/{web/src/about → src/about/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/about → src/about/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/about → src/about/web}/pages/constants.ts +0 -0
- /package/templates/{web/src/about → src/about/web}/pages/index.tsx +0 -0
- /package/templates/{web/src/access → src/access/web}/entry.ts +0 -0
- /package/templates/{web/src/access → src/access/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/access → src/access/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/access → src/access/web}/pages/access-mode/index.tsx +0 -0
- /package/templates/{web/src/access → src/access/web}/pages/admin-visible/index.tsx +0 -0
- /package/templates/{web/src/access → src/access/web}/pages/button-control/index.tsx +0 -0
- /package/templates/{web/src/access → src/access/web}/pages/common-visible/index.tsx +0 -0
- /package/templates/{web/src/access → src/access/web}/pages/page-control/index.tsx +0 -0
- /package/templates/{api/src/auth → src/auth/api}/_shared/ldap-login.ts +0 -0
- /package/templates/{api/src/auth → src/auth/api}/_shared/ldap.ts +0 -0
- /package/templates/{web/src/auth → src/auth/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/auth → src/auth/web}/__client/api.ts +0 -0
- /package/templates/{api/src/demo → src/demo/api}/manifest.yaml +0 -0
- /package/templates/{api/src/demo → src/demo/api}/migrations/0001__create_todos.sql +0 -0
- /package/templates/{api/src/demo → src/demo/api}/schema.yaml +0 -0
- /package/templates/{api/src/demo → src/demo/api}/seed.sql +0 -0
- /package/templates/{api/src/demo → src/demo/api}/todos/api.ts +0 -0
- /package/templates/{web/src/demo → src/demo/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/demo → src/demo/web}/__client/api.ts +0 -0
- /package/templates/{web/src/demo → src/demo/web}/entry.ts +0 -0
- /package/templates/{web/src/demo → src/demo/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/demo → src/demo/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/demo → src/demo/web}/pages/index.tsx +0 -0
- /package/templates/{web/src/exception → src/exception/web}/entry.ts +0 -0
- /package/templates/{web/src/exception → src/exception/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/exception → src/exception/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/exception → src/exception/web}/pages/403/index.tsx +0 -0
- /package/templates/{web/src/exception → src/exception/web}/pages/404/index.tsx +0 -0
- /package/templates/{web/src/exception → src/exception/web}/pages/500/index.tsx +0 -0
- /package/templates/{web/src/exception → src/exception/web}/pages/unknown-component/index.tsx +0 -0
- /package/templates/{api/src/home → src/home/api}/line/api.ts +0 -0
- /package/templates/{api/src/home → src/home/api}/manifest.yaml +0 -0
- /package/templates/{api/src/home → src/home/api}/migrations/0001__create_home_tables.sql +0 -0
- /package/templates/{api/src/home → src/home/api}/pie/api.ts +0 -0
- /package/templates/{api/src/home → src/home/api}/schema.yaml +0 -0
- /package/templates/{api/src/home → src/home/api}/seed.sql +0 -0
- /package/templates/{web/src/home → src/home/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/home → src/home/web}/__client/api.ts +0 -0
- /package/templates/{web/src/home → src/home/web}/entry.ts +0 -0
- /package/templates/{web/src/home → src/home/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/home → src/home/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/home → src/home/web}/pages/components/bar-chart.tsx +0 -0
- /package/templates/{web/src/home → src/home/web}/pages/components/card-list.tsx +0 -0
- /package/templates/{web/src/home → src/home/web}/pages/components/line-chart.tsx +0 -0
- /package/templates/{web/src/home → src/home/web}/pages/components/pie-chart.tsx +0 -0
- /package/templates/{web/src/home → src/home/web}/pages/index.tsx +0 -0
- /package/templates/{web/src/login → src/login/web}/entry.ts +0 -0
- /package/templates/{web/src/login → src/login/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/login → src/login/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/login → src/login/web}/pages/change-password.tsx +0 -0
- /package/templates/{web/src/login → src/login/web}/pages/login.tsx +0 -0
- /package/templates/{api/src/notification → src/notification/api}/_shared/notify.ts +0 -0
- /package/templates/{api/src/notification → src/notification/api}/api.ts +0 -0
- /package/templates/{api/src/notification → src/notification/api}/del/api.ts +0 -0
- /package/templates/{api/src/notification → src/notification/api}/manifest.yaml +0 -0
- /package/templates/{api/src/notification → src/notification/api}/migrations/0001__create_notifications.sql +0 -0
- /package/templates/{api/src/notification → src/notification/api}/migrations/0002__notifications_user.sql +0 -0
- /package/templates/{api/src/notification → src/notification/api}/migrations/0003__notifications_broadcast.sql +0 -0
- /package/templates/{api/src/notification → src/notification/api}/migrations/0004__notifications_broadcast_hidden.sql +0 -0
- /package/templates/{api/src/notification → src/notification/api}/schema.yaml +0 -0
- /package/templates/{api/src/notification → src/notification/api}/seed.sql +0 -0
- /package/templates/{web/src/notification → src/notification/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/notification → src/notification/web}/__client/api.ts +0 -0
- /package/templates/{web/src/notification → src/notification/web}/entry.ts +0 -0
- /package/templates/{web/src/notification → src/notification/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/notification → src/notification/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/notification → src/notification/web}/pages/center/index.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/CardGrid.test.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/HistoryDrawer.test.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/RollbackDialog.test.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/UninstallConfirm.test.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/poll.test.ts +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/render.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/runtime-stub.ts +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/semver.test.ts +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/api/MarketClientProvider.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/api/context.ts +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/components/CardGrid.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/components/CardItem.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/components/DetailDrawer.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/components/HistoryDrawer.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/components/RollbackDialog.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/components/UninstallConfirm.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/entry.ts +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/pages/MarketApp.tsx +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/utils/poll.ts +0 -0
- /package/templates/{web/src/oj-market → src/oj-market/web}/utils/semver.ts +0 -0
- /package/templates/{web/src/outside → src/outside/web}/entry.ts +0 -0
- /package/templates/{web/src/outside → src/outside/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/outside → src/outside/web}/locales/zh-CN.json +0 -0
- /package/templates/{api/src/personal-center → src/personal-center/api}/manifest.yaml +0 -0
- /package/templates/{api/src/personal-center → src/personal-center/api}/profile/api.ts +0 -0
- /package/templates/{api/src/personal-center → src/personal-center/api}/upload/api.ts +0 -0
- /package/templates/{web/src/personal-center → src/personal-center/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/personal-center → src/personal-center/web}/__client/api.ts +0 -0
- /package/templates/{web/src/personal-center → src/personal-center/web}/entry.ts +0 -0
- /package/templates/{web/src/personal-center → src/personal-center/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/personal-center → src/personal-center/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/personal-center → src/personal-center/web}/pages/my-profile/index.tsx +0 -0
- /package/templates/{web/src/route-nest → src/route-nest/web}/entry.ts +0 -0
- /package/templates/{web/src/route-nest → src/route-nest/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/route-nest → src/route-nest/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/route-nest → src/route-nest/web}/pages/menu1/menu1-1/index.tsx +0 -0
- /package/templates/{web/src/route-nest → src/route-nest/web}/pages/menu1/menu1-2/index.tsx +0 -0
- /package/templates/{web/src/route-nest → src/route-nest/web}/pages/menu2/index.tsx +0 -0
- /package/templates/{web/src → src}/styles.css +0 -0
- /package/templates/{web/src/system → src/system/web}/__client/api.schemas.ts +0 -0
- /package/templates/{web/src/system → src/system/web}/__client/api.ts +0 -0
- /package/templates/{web/src/system → src/system/web}/entry.ts +0 -0
- /package/templates/{web/src/system → src/system/web}/locales/en-US.json +0 -0
- /package/templates/{web/src/system → src/system/web}/locales/zh-CN.json +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/errors.ts +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/forbidden.tsx +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/login-methods/index.tsx +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/oplog/index.tsx +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/roles/index.tsx +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/settings/index.tsx +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/users/index.tsx +0 -0
- /package/templates/{web/src/system → src/system/web}/pages/users/roles.tsx +0 -0
- /package/templates/{api/src/web → src/web/api}/get-async-routes/api.ts +0 -0
- /package/templates/{api/src/web → src/web/api}/hello/api.ts +0 -0
- /package/templates/{api/src/web → src/web/api}/manifest.yaml +0 -0
- /package/templates/{api/src/web → src/web/api}/user-info/api.ts +0 -0
- /package/templates/{web/src → src/web}/web/__client/api.schemas.ts +0 -0
- /package/templates/{web/src → src/web}/web/__client/api.ts +0 -0
- /package/templates/{api/tests → tests}/l1-builder.test.ts +0 -0
- /package/templates/{api/tests → tests}/rbac-tables.spec.ts +0 -0
|
@@ -8,19 +8,19 @@
|
|
|
8
8
|
// 快照逐数组 ⊇ 声明,少 = 注册丢失判失败)collect-all 全败齐报。
|
|
9
9
|
// entry 浏览器加载不在安装器验(Node import 必假绿——设计 §4.1),注释钉口径。
|
|
10
10
|
// fetch/sha384/query/reload 面经 ctx 注入 stub(同 steps-fs 范式),fs 为 globalThis.fs 面。
|
|
11
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
12
|
-
import type { StateStore } from "../../src/_platform/_lifecycle/state";
|
|
13
|
-
import type { DeployWebContext, ModuleEntry } from "../../src/_platform/_lifecycle/steps/deploy-web";
|
|
14
|
-
import type { ReloadContext, ReloadFace, ReloadResult } from "../../src/_platform/_lifecycle/steps/reload";
|
|
15
|
-
import type { SmokeContext } from "../../src/_platform/_lifecycle/steps/smoke";
|
|
11
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
12
|
+
import type { StateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
13
|
+
import type { DeployWebContext, ModuleEntry } from "../../src/_platform/api/_lifecycle/steps/deploy-web";
|
|
14
|
+
import type { ReloadContext, ReloadFace, ReloadResult } from "../../src/_platform/api/_lifecycle/steps/reload";
|
|
15
|
+
import type { SmokeContext } from "../../src/_platform/api/_lifecycle/steps/smoke";
|
|
16
16
|
import { createHash } from "node:crypto";
|
|
17
17
|
import * as fsp from "node:fs/promises";
|
|
18
18
|
import { tmpdir } from "node:os";
|
|
19
19
|
import { join } from "node:path";
|
|
20
20
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
21
|
-
import { deployWeb, posixPath, upsertModulesJson } from "../../src/_platform/_lifecycle/steps/deploy-web";
|
|
22
|
-
import { reloadAndAssert } from "../../src/_platform/_lifecycle/steps/reload";
|
|
23
|
-
import { probeUrlOf, smoke } from "../../src/_platform/_lifecycle/steps/smoke";
|
|
21
|
+
import { deployWeb, posixPath, upsertModulesJson } from "../../src/_platform/api/_lifecycle/steps/deploy-web";
|
|
22
|
+
import { reloadAndAssert } from "../../src/_platform/api/_lifecycle/steps/reload";
|
|
23
|
+
import { probeUrlOf, smoke } from "../../src/_platform/api/_lifecycle/steps/smoke";
|
|
24
24
|
|
|
25
25
|
const g = globalThis as any;
|
|
26
26
|
|
|
@@ -326,6 +326,29 @@ describe("smoke 探活(D14/Q-A:health 不强制)", () => {
|
|
|
326
326
|
expect(r.ok).toBe(true);
|
|
327
327
|
});
|
|
328
328
|
|
|
329
|
+
it("health 401 且路径属本次新增 anonymous(restart_pending)→ 判通过 + 落待重启提示", async () => {
|
|
330
|
+
await seedDeployed();
|
|
331
|
+
const r = await smoke(smCtx({
|
|
332
|
+
manifest: solManifest({ health: "/demo-solution/ping" }),
|
|
333
|
+
fetch: async () => ({ ok: false, status: 401 }),
|
|
334
|
+
deferredAnonymous: ["/demo-solution/ping"],
|
|
335
|
+
}));
|
|
336
|
+
expect(r.ok).toBe(true);
|
|
337
|
+
expect(r.message).toContain("restart_pending");
|
|
338
|
+
expect(r.message).toContain("重启宿主后生效");
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it("health 401 但路径不是本次新增(已在配置里)→ 仍判失败(不放宽真失败)", async () => {
|
|
342
|
+
await seedDeployed();
|
|
343
|
+
const r = await smoke(smCtx({
|
|
344
|
+
manifest: solManifest({ health: "/demo-solution/ping" }),
|
|
345
|
+
fetch: async () => ({ ok: false, status: 401 }),
|
|
346
|
+
deferredAnonymous: ["/demo-solution/other"],
|
|
347
|
+
}));
|
|
348
|
+
expect(r.ok).toBe(false);
|
|
349
|
+
expect(r.message).toContain("401");
|
|
350
|
+
});
|
|
351
|
+
|
|
329
352
|
it("health 非 2xx → 探活失败", async () => {
|
|
330
353
|
await seedDeployed();
|
|
331
354
|
const r = await smoke(smCtx({
|
|
@@ -12,22 +12,22 @@
|
|
|
12
12
|
// 过期(30min)可接管。setEnabled 四处同写(D12/AC-P1-6):锁摘除/恢复 + sidecar + route + modules。
|
|
13
13
|
// 步骤面全 stub 注入(DIP):fetch/exec/tar/reload 不真跑;register/smoke/audit 走真实内存库夹具。
|
|
14
14
|
/* eslint-disable test/prefer-lowercase-title -- 任务/AC 编号是验收锚点,保留大写(register.spec 同约定) */
|
|
15
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
16
|
-
import type { InstallRequest } from "../../src/_platform/_lifecycle/installer";
|
|
17
|
-
import type { StateStore } from "../../src/_platform/_lifecycle/state";
|
|
18
|
-
import type { ExecFace } from "../../src/_platform/_lifecycle/steps/extract";
|
|
15
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
16
|
+
import type { InstallRequest } from "../../src/_platform/api/_lifecycle/installer";
|
|
17
|
+
import type { StateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
18
|
+
import type { ExecFace } from "../../src/_platform/api/_lifecycle/steps/extract";
|
|
19
19
|
import { createHash } from "node:crypto";
|
|
20
20
|
import * as fsp from "node:fs/promises";
|
|
21
21
|
import { tmpdir } from "node:os";
|
|
22
22
|
import { join } from "node:path";
|
|
23
23
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
24
|
-
import { defaultTestKey, nodeVerifyEd25519, signedArchiveFor } from "
|
|
25
|
-
import { atomicWriteText } from "../../src/_platform/_lifecycle/atomic";
|
|
26
|
-
import { gcVersions, reconcile, runInstall, setEnabled, STAGES } from "../../src/_platform/_lifecycle/installer";
|
|
27
|
-
import { acquireTaskLock, commitLockEntry, parseLock, readLock, serializeLock, writeLock } from "../../src/_platform/_lifecycle/lock";
|
|
28
|
-
import { createStateStore } from "../../src/_platform/_lifecycle/state";
|
|
29
|
-
import { getTask, readTasks, redact, sweepTimedOut, writeTask } from "../../src/_platform/_lifecycle/tasks";
|
|
30
|
-
import { createTrustStore } from "../../src/_platform/_lifecycle/trust";
|
|
24
|
+
import { defaultTestKey, nodeVerifyEd25519, signedArchiveFor } from "../../../src/lifecycle/__tests__/helpers";
|
|
25
|
+
import { atomicWriteText } from "../../src/_platform/api/_lifecycle/atomic";
|
|
26
|
+
import { gcVersions, reconcile, runInstall, setEnabled, STAGES } from "../../src/_platform/api/_lifecycle/installer";
|
|
27
|
+
import { acquireTaskLock, commitLockEntry, parseLock, readLock, serializeLock, writeLock } from "../../src/_platform/api/_lifecycle/lock";
|
|
28
|
+
import { createStateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
29
|
+
import { getTask, readTasks, redact, sweepTimedOut, writeTask } from "../../src/_platform/api/_lifecycle/tasks";
|
|
30
|
+
import { createTrustStore } from "../../src/_platform/api/_lifecycle/trust";
|
|
31
31
|
import { installDb } from "../fixture";
|
|
32
32
|
|
|
33
33
|
const g = globalThis as any;
|
|
@@ -532,8 +532,8 @@ describe("U5 取消安装(P3-8):cancel token → h.kill + staging 清场 +
|
|
|
532
532
|
|
|
533
533
|
describe("第五终态 needs_trust(P2-3,G3 TOFU:未知 key_id 待确认,staging 不清场)", () => {
|
|
534
534
|
it("未知 key 装 → needs_trust + trust 三元组 + unknown_key 指引;锁/库表/sidecar/审计零改动,staging 留存", async () => {
|
|
535
|
-
const { generateKeyPair } = await import("
|
|
536
|
-
const { signedArchiveFor: signFor } = await import("
|
|
535
|
+
const { generateKeyPair } = await import("../../../src/lifecycle/keygen");
|
|
536
|
+
const { signedArchiveFor: signFor } = await import("../../../src/lifecycle/__tests__/helpers");
|
|
537
537
|
const stranger = signFor(ARCHIVE, "demo-solution", "0.1.0", { keyPair: generateKeyPair(), keyId: "stranger.pub" });
|
|
538
538
|
const m = manifestFixture("0.1.0");
|
|
539
539
|
m.archive = { ...m.archive, signature: stranger.sig };
|
|
@@ -562,8 +562,8 @@ describe("第五终态 needs_trust(P2-3,G3 TOFU:未知 key_id 待确认,
|
|
|
562
562
|
});
|
|
563
563
|
|
|
564
564
|
it("TOFU 全链:确认入信任库(端点同路径 store.add)后原样重试 → done", async () => {
|
|
565
|
-
const { generateKeyPair } = await import("
|
|
566
|
-
const { signedArchiveFor: signFor } = await import("
|
|
565
|
+
const { generateKeyPair } = await import("../../../src/lifecycle/keygen");
|
|
566
|
+
const { signedArchiveFor: signFor } = await import("../../../src/lifecycle/__tests__/helpers");
|
|
567
567
|
const stranger = signFor(ARCHIVE, "demo-solution", "0.1.0", { keyPair: generateKeyPair(), keyId: "stranger.pub" });
|
|
568
568
|
const m = manifestFixture("0.1.0");
|
|
569
569
|
m.archive = { ...m.archive, signature: stranger.sig };
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
// 简报 `task/:id` 段参数形态在模板 http 面无先例(contacts/detail?id= 同款 query 惯例),备案于任务报告。
|
|
8
8
|
// 步骤面全 stub 注入(DIP):fetch/exec/reload 不真跑;register/smoke/audit 走真实内存库夹具。
|
|
9
9
|
/* eslint-disable test/prefer-lowercase-title -- 端点动词/路径是验收锚点,保留大写(installer.spec 同约定) */
|
|
10
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
11
|
-
import type { FetchFace } from "../../src/_platform/_lifecycle/steps/download";
|
|
12
|
-
import type { ExecFace } from "../../src/_platform/_lifecycle/steps/extract";
|
|
13
|
-
import type { ReloadFace } from "../../src/_platform/_lifecycle/steps/reload";
|
|
14
|
-
import type { MarketEnv } from "../../src/_platform/market/api";
|
|
10
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
11
|
+
import type { FetchFace } from "../../src/_platform/api/_lifecycle/steps/download";
|
|
12
|
+
import type { ExecFace } from "../../src/_platform/api/_lifecycle/steps/extract";
|
|
13
|
+
import type { ReloadFace } from "../../src/_platform/api/_lifecycle/steps/reload";
|
|
14
|
+
import type { MarketEnv } from "../../src/_platform/api/market/api";
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
16
|
import { readFileSync } from "node:fs";
|
|
17
17
|
import * as fsp from "node:fs/promises";
|
|
@@ -20,14 +20,14 @@ import { dirname, join } from "node:path";
|
|
|
20
20
|
import { fileURLToPath } from "node:url";
|
|
21
21
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
22
22
|
import { parse } from "yaml";
|
|
23
|
-
import { defaultTestKey, nodeVerifyEd25519, signedArchiveFor } from "
|
|
24
|
-
import { signIndex } from "
|
|
25
|
-
import { readLock, writeLock } from "../../src/_platform/_lifecycle/lock";
|
|
26
|
-
import { createStateStore } from "../../src/_platform/_lifecycle/state";
|
|
27
|
-
import { getTask, writeTask } from "../../src/_platform/_lifecycle/tasks";
|
|
28
|
-
import { createTrustStore } from "../../src/_platform/_lifecycle/trust";
|
|
29
|
-
import { invalidateAllUsers } from "../../src/_platform/_shared/service/infra/access";
|
|
30
|
-
import { createMarketApi, marketEnv, parseVersionsJson, versionsJsonPathOf } from "../../src/_platform/market/api";
|
|
23
|
+
import { defaultTestKey, nodeVerifyEd25519, signedArchiveFor } from "../../../src/lifecycle/__tests__/helpers";
|
|
24
|
+
import { signIndex } from "../../../src/publish";
|
|
25
|
+
import { readLock, writeLock } from "../../src/_platform/api/_lifecycle/lock";
|
|
26
|
+
import { createStateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
27
|
+
import { getTask, writeTask } from "../../src/_platform/api/_lifecycle/tasks";
|
|
28
|
+
import { createTrustStore } from "../../src/_platform/api/_lifecycle/trust";
|
|
29
|
+
import { invalidateAllUsers } from "../../src/_platform/api/_shared/service/infra/access";
|
|
30
|
+
import { createMarketApi, marketEnv, parseVersionsJson, versionsJsonPathOf } from "../../src/_platform/api/market/api";
|
|
31
31
|
import { installDb } from "../fixture";
|
|
32
32
|
|
|
33
33
|
function hexToBytes(hex: string): Uint8Array {
|
|
@@ -274,7 +274,7 @@ describe("权限门(R9:市场编排 superadmin 独占,meta 登录即可)
|
|
|
274
274
|
it("pair-pin:meta apiVersion === _platform/manifest.yaml version(手工镜像漂移防护,P2-9)", async () => {
|
|
275
275
|
// API_VERSION(market/api.ts)与 _platform/manifest.yaml version 为手工同步的双真源;
|
|
276
276
|
// 本测试经 meta 端点间接钉住 API_VERSION,漂移即红(peerPlatform 预检口径失真)。
|
|
277
|
-
const manifestPath = join(dirname(fileURLToPath(import.meta.url)), "../../src/_platform/manifest.yaml");
|
|
277
|
+
const manifestPath = join(dirname(fileURLToPath(import.meta.url)), "../../src/_platform/api/manifest.yaml");
|
|
278
278
|
const manifestVersion = (parse(readFileSync(manifestPath, "utf8")) as { version: string }).version;
|
|
279
279
|
const api = createMarketApi(makeEnv());
|
|
280
280
|
g.http = { user: { id: 1 } };
|
|
@@ -503,7 +503,7 @@ describe("POST /market/trust {task_id}(P2-3 TOFU 确认:混淆代理防线
|
|
|
503
503
|
|
|
504
504
|
it("确认成功:任务 needs_trust → 指纹复算一致 → 入信任库 added", async () => {
|
|
505
505
|
const api = createMarketApi(makeEnv());
|
|
506
|
-
const { generateKeyPair } = await import("
|
|
506
|
+
const { generateKeyPair } = await import("../../../src/lifecycle/keygen");
|
|
507
507
|
const kp = generateKeyPair();
|
|
508
508
|
const id = await seedNeedsTrust("stranger.pub", kp.publicKeyHex);
|
|
509
509
|
g.http = { user: { id: 1 }, body: { task_id: id } };
|
|
@@ -539,7 +539,7 @@ describe("POST /market/trust {task_id}(P2-3 TOFU 确认:混淆代理防线
|
|
|
539
539
|
|
|
540
540
|
it("混淆代理:任务记录指纹与公钥不符 → 409 拒,信任库零变化", async () => {
|
|
541
541
|
const api = createMarketApi(makeEnv());
|
|
542
|
-
const { generateKeyPair } = await import("
|
|
542
|
+
const { generateKeyPair } = await import("../../../src/lifecycle/keygen");
|
|
543
543
|
const kp = generateKeyPair();
|
|
544
544
|
const id = await seedNeedsTrust("stranger.pub", kp.publicKeyHex, "f".repeat(64)); // 指纹造假
|
|
545
545
|
g.http = { user: { id: 1 }, body: { task_id: id } };
|
|
@@ -552,7 +552,7 @@ describe("POST /market/trust {task_id}(P2-3 TOFU 确认:混淆代理防线
|
|
|
552
552
|
|
|
553
553
|
it("撞绑定:key_id 已绑其他公钥 → 409 trust_bound_mismatch,库内不动", async () => {
|
|
554
554
|
const api = createMarketApi(makeEnv());
|
|
555
|
-
const { generateKeyPair } = await import("
|
|
555
|
+
const { generateKeyPair } = await import("../../../src/lifecycle/keygen");
|
|
556
556
|
const kp = generateKeyPair();
|
|
557
557
|
const id = await seedNeedsTrust("test.publisher", kp.publicKeyHex); // 已播种的 key_id
|
|
558
558
|
g.http = { user: { id: 1 }, body: { task_id: id } };
|
|
@@ -815,10 +815,11 @@ describe("P3-7 索引签名校验(G4 fail-closed:署名相符采用 / 篡改
|
|
|
815
815
|
});
|
|
816
816
|
|
|
817
817
|
describe("hostVersions 缺省接线(B-11:C2-09 比对真源 = <dist>/versions.json,ojm 宿主构建产物)", () => {
|
|
818
|
-
it("versionsJsonPathOf 布局推导:
|
|
819
|
-
expect(versionsJsonPathOf("dist
|
|
820
|
-
expect(versionsJsonPathOf("/site/dist
|
|
821
|
-
expect(versionsJsonPathOf("
|
|
818
|
+
it("versionsJsonPathOf 布局推导:release 根下的 versions.json(相对/绝对/尾斜杠同构)", () => {
|
|
819
|
+
expect(versionsJsonPathOf("api/dist")).toBe("api/dist/versions.json");
|
|
820
|
+
expect(versionsJsonPathOf("/site/api/dist")).toBe("/site/api/dist/versions.json");
|
|
821
|
+
expect(versionsJsonPathOf("api/dist/")).toBe("api/dist/versions.json");
|
|
822
|
+
expect(versionsJsonPathOf("")).toBe("versions.json");
|
|
822
823
|
});
|
|
823
824
|
|
|
824
825
|
it("parseVersionsJson:{packageName: version} 全字符串表 → 解析;任何违约(非对象/值非字符串/坏 JSON)→ undefined(fail-closed 不猜)", () => {
|
|
@@ -829,9 +830,9 @@ describe("hostVersions 缺省接线(B-11:C2-09 比对真源 = <dist>/version
|
|
|
829
830
|
}
|
|
830
831
|
});
|
|
831
832
|
|
|
832
|
-
it("集成:env 未注入 hostVersions +
|
|
833
|
-
await fsp.mkdir(
|
|
834
|
-
await fsp.writeFile(join(
|
|
833
|
+
it("集成:env 未注入 hostVersions + <release 根>/versions.json 在盘 → install 全链 done(C2-09 比对走缺省真源)", async () => {
|
|
834
|
+
await fsp.mkdir(sharedRoot, { recursive: true });
|
|
835
|
+
await fsp.writeFile(join(sharedRoot, "versions.json"), JSON.stringify({ "@oj-module/runtime": "0.1.77" }));
|
|
835
836
|
const env = makeEnv();
|
|
836
837
|
delete (env as Partial<MarketEnv>).hostVersions;
|
|
837
838
|
const api = createMarketApi(env);
|
|
@@ -857,12 +858,12 @@ describe("hostVersions 缺省接线(B-11:C2-09 比对真源 = <dist>/version
|
|
|
857
858
|
});
|
|
858
859
|
|
|
859
860
|
describe("P1-16 接线:marketEnv 生产口径 / exec opts 转发 / operator 通道 / 账本真源 / index 即对账入口", () => {
|
|
860
|
-
it("marketEnv() 缺省 =
|
|
861
|
+
it("marketEnv() 缺省 = 布局 v2 生产口径:版本目录与 versions.json 在 release 根 api/dist,站点 modules 在 web/dist;暂存/任务/sidecar 留 jail 根", () => {
|
|
861
862
|
const env = marketEnv();
|
|
862
|
-
expect(env.sharedRoot).toBe("dist");
|
|
863
|
-
expect(env.siteModulesDir).toBe("dist/modules");
|
|
864
|
-
expect(env.modulesJsonPath).toBe("dist/modules.json");
|
|
865
|
-
expect(versionsJsonPathOf(env.
|
|
863
|
+
expect(env.sharedRoot).toBe("api/dist");
|
|
864
|
+
expect(env.siteModulesDir).toBe("web/dist/modules");
|
|
865
|
+
expect(env.modulesJsonPath).toBe("web/dist/modules.json");
|
|
866
|
+
expect(versionsJsonPathOf(env.sharedRoot)).toBe("api/dist/versions.json");
|
|
866
867
|
expect(env.staging).toBe("modules/.staging");
|
|
867
868
|
expect(env.taskDir).toBe("modules/.install-tasks");
|
|
868
869
|
expect(env.statePath).toBe("modules/.solutions/state.yaml");
|
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
// rollbackGuard 纯函数:目标产物 max seq < 账本 head = 降版部署,禁止(OJ-9/M003 同源红线);
|
|
8
8
|
// seq 为数值非版本号,直接数值比较(semver.ts 不适用)。
|
|
9
9
|
// exec/fs 面注入 stub(同 steps-fs 范式),不真跑 oj/sqlite。
|
|
10
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
11
|
-
import type { StateStore } from "../../src/_platform/_lifecycle/state";
|
|
12
|
-
import type { ExecFace } from "../../src/_platform/_lifecycle/steps/extract";
|
|
13
|
-
import type { MigrateContext } from "../../src/_platform/_lifecycle/steps/migrate";
|
|
10
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
11
|
+
import type { StateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
12
|
+
import type { ExecFace } from "../../src/_platform/api/_lifecycle/steps/extract";
|
|
13
|
+
import type { MigrateContext } from "../../src/_platform/api/_lifecycle/steps/migrate";
|
|
14
14
|
import * as fsp from "node:fs/promises";
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
18
|
-
import { parseLock } from "../../src/_platform/_lifecycle/lock";
|
|
19
|
-
import { buildMigrateCmd, maxAppliedSeq, migrate, migrateSvcDirOf, parseMigrateOutput, rollbackGuard } from "../../src/_platform/_lifecycle/steps/migrate";
|
|
18
|
+
import { parseLock } from "../../src/_platform/api/_lifecycle/lock";
|
|
19
|
+
import { buildMigrateCmd, maxAppliedSeq, migrate, migrateSvcDirOf, parseMigrateOutput, rollbackGuard } from "../../src/_platform/api/_lifecycle/steps/migrate";
|
|
20
20
|
|
|
21
21
|
const g = globalThis as any;
|
|
22
22
|
const DB_BYTES = new TextEncoder().encode("sqlite-header-bytes\n");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { SolutionState, StateStore } from "../../src/_platform/_lifecycle/state";
|
|
2
|
-
import type { InstallContext } from "../../src/_platform/_lifecycle/steps/preflight";
|
|
1
|
+
import type { SolutionState, StateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
2
|
+
import type { InstallContext } from "../../src/_platform/api/_lifecycle/steps/preflight";
|
|
3
3
|
// BDD:安装预检规则引擎(P1-5,R7/R8/R9/R24,十阶段状态机 stage 1)。
|
|
4
4
|
// 规则真源:docs/prd/solution/202610171254-lifecycle-manifest-contract.md(C2-01~33 安装列);
|
|
5
5
|
// 期望真源:packages/cli/src/lifecycle/__tests__/fixtures/(fixture-valid 零违规、fixture-invalid 七码齐报)。
|
|
@@ -12,9 +12,9 @@ import { fileURLToPath } from "node:url";
|
|
|
12
12
|
|
|
13
13
|
import { describe, expect, it } from "vitest";
|
|
14
14
|
import { parse } from "yaml";
|
|
15
|
-
import { preflight } from "../../src/_platform/_lifecycle/steps/preflight";
|
|
15
|
+
import { preflight } from "../../src/_platform/api/_lifecycle/steps/preflight";
|
|
16
16
|
|
|
17
|
-
const FIXTURES = join(dirname(fileURLToPath(import.meta.url)), "
|
|
17
|
+
const FIXTURES = join(dirname(fileURLToPath(import.meta.url)), "../../../src/lifecycle/__tests__/fixtures");
|
|
18
18
|
const VALID = parse(readFileSync(join(FIXTURES, "fixture-valid/manifest.yaml"), "utf8")) as any;
|
|
19
19
|
|
|
20
20
|
/** 宿主 versions.json 假数据(C2-09 真源键:@oj-module/runtime,shell/src/manifest.ts P7.6) */
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
/* eslint-disable test/prefer-lowercase-title -- 任务/AC 编号是验收锚点,保留大写(DB/P1-5) */
|
|
9
9
|
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
10
10
|
|
|
11
|
-
import { checkOccupancy, queryAllRegistered, queryRegistered, registerSolution } from "../../src/_platform/_lifecycle/steps/register";
|
|
11
|
+
import { checkOccupancy, queryAllRegistered, queryRegistered, registerSolution } from "../../src/_platform/api/_lifecycle/steps/register";
|
|
12
12
|
import { installDb } from "../fixture";
|
|
13
13
|
|
|
14
14
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// 无 prerelease > 有 prerelease;「1.0」「1.0.0」「1.0.0.0」视为相等(安装器容错口径)。
|
|
4
4
|
import { describe, expect, it } from "vitest";
|
|
5
5
|
|
|
6
|
-
import { compareVersions } from "../../src/_platform/_lifecycle/semver";
|
|
6
|
+
import { compareVersions } from "../../src/_platform/api/_lifecycle/semver";
|
|
7
7
|
|
|
8
8
|
const cases: Array<[a: string, b: string, expected: -1 | 0 | 1]> = [
|
|
9
9
|
// 主版本数值比较(非字典序)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import { describe, expect, it } from "vitest";
|
|
7
|
-
import { bytesToBase64, sha384B64, sha384Bytes } from "../../src/_platform/_lifecycle/sha384";
|
|
7
|
+
import { bytesToBase64, sha384B64, sha384Bytes } from "../../src/_platform/api/_lifecycle/sha384";
|
|
8
8
|
|
|
9
9
|
const hex = (bytes: Uint8Array): string => Array.from(bytes, b => b.toString(16).padStart(2, "0")).join("");
|
|
10
10
|
|
|
@@ -10,7 +10,7 @@ import { fileURLToPath } from "node:url";
|
|
|
10
10
|
import { describe, expect, it } from "vitest";
|
|
11
11
|
|
|
12
12
|
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
const SIG_DIR = path.resolve(HERE, "
|
|
13
|
+
const SIG_DIR = path.resolve(HERE, "../../../src/lifecycle/__tests__/fixtures/sig");
|
|
14
14
|
const GEN = path.join(SIG_DIR, "gen-signed-fixtures.mjs");
|
|
15
15
|
|
|
16
16
|
const HEX64 = /^[0-9a-f]{64}$/;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/* eslint-disable test/prefer-lowercase-title -- 端点路径是验收锚点 */
|
|
6
6
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
7
7
|
|
|
8
|
-
import api from "../../src/_platform/solutions/api";
|
|
8
|
+
import api from "../../src/_platform/api/solutions/api";
|
|
9
9
|
import { installDb } from "../fixture";
|
|
10
10
|
|
|
11
11
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
// 命令构造为纯函数,argv 逐字断言(与平台 exec 白名单逐字对齐,S1-2 基座);
|
|
7
7
|
// exec/fetch/sha256 面经 ctx 注入 stub,不真跑网络;合法夹具集成用例的 exec stub 落到真实系统 tar
|
|
8
8
|
// (与生产同路径:isolate 不内嵌解压,exec.run 系统 tar)。
|
|
9
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
10
|
-
import type { StateStore } from "../../src/_platform/_lifecycle/state";
|
|
11
|
-
import type { DownloadContext } from "../../src/_platform/_lifecycle/steps/download";
|
|
12
|
-
import type { ExecFace, ExtractContext } from "../../src/_platform/_lifecycle/steps/extract";
|
|
13
|
-
import type { VerifyContext } from "../../src/_platform/_lifecycle/steps/verify";
|
|
9
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
10
|
+
import type { StateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
11
|
+
import type { DownloadContext } from "../../src/_platform/api/_lifecycle/steps/download";
|
|
12
|
+
import type { ExecFace, ExtractContext } from "../../src/_platform/api/_lifecycle/steps/extract";
|
|
13
|
+
import type { VerifyContext } from "../../src/_platform/api/_lifecycle/steps/verify";
|
|
14
14
|
import { execFile as execFileCb } from "node:child_process";
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
16
|
import * as fsp from "node:fs/promises";
|
|
@@ -18,11 +18,11 @@ import { tmpdir } from "node:os";
|
|
|
18
18
|
import { join } from "node:path";
|
|
19
19
|
import { promisify } from "node:util";
|
|
20
20
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
21
|
-
import { defaultTestKey, nodeVerifyEd25519, signedArchiveFor } from "
|
|
22
|
-
import { archiveFileOf, download } from "../../src/_platform/_lifecycle/steps/download";
|
|
23
|
-
import { buildExtractCmd, buildListCmd, checkModuleManifest, extract } from "../../src/_platform/_lifecycle/steps/extract";
|
|
24
|
-
import { verify } from "../../src/_platform/_lifecycle/steps/verify";
|
|
25
|
-
import { createTrustStore } from "../../src/_platform/_lifecycle/trust";
|
|
21
|
+
import { defaultTestKey, nodeVerifyEd25519, signedArchiveFor } from "../../../src/lifecycle/__tests__/helpers";
|
|
22
|
+
import { archiveFileOf, download } from "../../src/_platform/api/_lifecycle/steps/download";
|
|
23
|
+
import { buildExtractCmd, buildListCmd, checkModuleManifest, extract } from "../../src/_platform/api/_lifecycle/steps/extract";
|
|
24
|
+
import { verify } from "../../src/_platform/api/_lifecycle/steps/verify";
|
|
25
|
+
import { createTrustStore } from "../../src/_platform/api/_lifecycle/trust";
|
|
26
26
|
|
|
27
27
|
const execFileP = promisify(execFileCb);
|
|
28
28
|
const g = globalThis as any;
|
|
@@ -352,8 +352,8 @@ describe("verify(stage=verifying,C2-29 sha256 fail-closed + P2-3 六码验
|
|
|
352
352
|
it("sig_key:已信任 key_id 但包内公钥与库绑定不一致(首次绑定不可改族)", async () => {
|
|
353
353
|
await seed();
|
|
354
354
|
// 另一把私钥冒用已信任 key_id(trusted key_id + 异公钥 = 绑定不一致)
|
|
355
|
-
const { signedArchiveFor: signFor } = await import("
|
|
356
|
-
const { generateKeyPair } = await import("
|
|
355
|
+
const { signedArchiveFor: signFor } = await import("../../../src/lifecycle/__tests__/helpers");
|
|
356
|
+
const { generateKeyPair } = await import("../../../src/lifecycle/keygen");
|
|
357
357
|
const impostor = signFor(BYTES, "demo-solution", "0.1.0", { keyPair: generateKeyPair(), keyId: "test.publisher" });
|
|
358
358
|
const r = await verify(vfCtx({ manifest: manifest({ ...manifest().archive, signature: impostor.sig }) }));
|
|
359
359
|
expect(r).toMatchObject({ ok: false, code: "sig_key" });
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as fsp from "node:fs/promises";
|
|
6
6
|
import { describe, expect, it } from "vitest";
|
|
7
7
|
|
|
8
|
-
import { appendAnonymousPaths, bumpInstallSeq, ensureReloadApi, hasAnchor, insertAnchor } from "../../src/_platform/_lifecycle/text-edit";
|
|
8
|
+
import { appendAnonymousPaths, bumpInstallSeq, ensureReloadApi, hasAnchor, insertAnchor } from "../../src/_platform/api/_lifecycle/text-edit";
|
|
9
9
|
|
|
10
10
|
describe("insertAnchor(R18)", () => {
|
|
11
11
|
it("带注释的 config.yaml 插入后注释/缩进/空行/键序逐字保留", () => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// 拒绝:绝对路径、任何 `..` 段、l/h 条目、空成员名、反斜杠路径;`./` 前缀相对合法。
|
|
5
5
|
import { describe, expect, it } from "vitest";
|
|
6
6
|
|
|
7
|
-
import { validateTarListing } from "../../src/_platform/_lifecycle/tgz-guard";
|
|
7
|
+
import { validateTarListing } from "../../src/_platform/api/_lifecycle/tgz-guard";
|
|
8
8
|
|
|
9
9
|
describe("validateTarListing(R1)", () => {
|
|
10
10
|
it("正常成员列表通过", () => {
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
// store 层:空库/幂等/首次绑定不可改/多 key/吊销/损坏 fail-closed/.bak 回落/并发读不见半截/审计。
|
|
3
3
|
// 端点层:GET /market/trust、POST /market/trust/key、DELETE /market/trust/key?key_id=(del 动词 + query,system/roles 同款先例)。
|
|
4
4
|
/* eslint-disable test/prefer-lowercase-title -- 端点动词/路径是验收锚点,保留大写(market-api.spec 同约定) */
|
|
5
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
6
|
-
import type { MarketEnv } from "../../src/_platform/market/api";
|
|
5
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
6
|
+
import type { MarketEnv } from "../../src/_platform/api/market/api";
|
|
7
7
|
import { Buffer } from "node:buffer";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import * as fsp from "node:fs/promises";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
13
|
-
import { createTrustStore, isValidKeyId } from "../../src/_platform/_lifecycle/trust";
|
|
14
|
-
import { invalidateAllUsers } from "../../src/_platform/_shared/service/infra/access";
|
|
15
|
-
import { createMarketApi, marketEnv } from "../../src/_platform/market/api";
|
|
13
|
+
import { createTrustStore, isValidKeyId } from "../../src/_platform/api/_lifecycle/trust";
|
|
14
|
+
import { invalidateAllUsers } from "../../src/_platform/api/_shared/service/infra/access";
|
|
15
|
+
import { createMarketApi, marketEnv } from "../../src/_platform/api/market/api";
|
|
16
16
|
import { installDb } from "../fixture";
|
|
17
17
|
|
|
18
18
|
const g = globalThis as any;
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
// 夹具:本仓范式(node:sqlite 真实迁移建表 + 真实 fs 面 g.fs);market_history 表由平台迁移
|
|
6
6
|
// 0012(IF NOT EXISTS)随 installDb 重放建立,守卫语义(表不存在静默跳过)单列一例。
|
|
7
7
|
/* eslint-disable test/prefer-lowercase-title -- 端点动词/路径是验收锚点,保留大写(market-api.spec 同约定) */
|
|
8
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
9
|
-
import type { MarketEnv } from "../../src/_platform/market/api";
|
|
8
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
9
|
+
import type { MarketEnv } from "../../src/_platform/api/market/api";
|
|
10
10
|
import * as fsp from "node:fs/promises";
|
|
11
11
|
import { tmpdir } from "node:os";
|
|
12
12
|
import { dirname, join } from "node:path";
|
|
13
13
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
14
|
-
import { readLock, writeLock } from "../../src/_platform/_lifecycle/lock";
|
|
15
|
-
import { createStateStore } from "../../src/_platform/_lifecycle/state";
|
|
16
|
-
import { collectRetainedTables, moduleTablePrefix } from "../../src/_platform/_lifecycle/uninstall";
|
|
17
|
-
import { invalidateAllUsers } from "../../src/_platform/_shared/service/infra/access";
|
|
18
|
-
import { createMarketApi } from "../../src/_platform/market/api";
|
|
14
|
+
import { readLock, writeLock } from "../../src/_platform/api/_lifecycle/lock";
|
|
15
|
+
import { createStateStore } from "../../src/_platform/api/_lifecycle/state";
|
|
16
|
+
import { collectRetainedTables, moduleTablePrefix } from "../../src/_platform/api/_lifecycle/uninstall";
|
|
17
|
+
import { invalidateAllUsers } from "../../src/_platform/api/_shared/service/infra/access";
|
|
18
|
+
import { createMarketApi } from "../../src/_platform/api/market/api";
|
|
19
19
|
import { installDb } from "../fixture";
|
|
20
20
|
|
|
21
21
|
const g = globalThis as any;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// BDD:深检后端四项 + 端点(P2-7,C2-42)+ SSRF 三钉。
|
|
2
2
|
// 纯 diff 函数 / 探针分类 / SSRF 钉(出站拦截 / header 清洗 / 不跟随重定向)+ 端点门(401/403/404)+ 编排。
|
|
3
3
|
/* eslint-disable test/prefer-lowercase-title -- 端点动词/路径是验收锚点,保留大写(market-api.spec 同约定) */
|
|
4
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
5
|
-
import type { SolutionRouteRow } from "../../src/_platform/_lifecycle/verify-checks";
|
|
4
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
5
|
+
import type { SolutionRouteRow } from "../../src/_platform/api/_lifecycle/verify-checks";
|
|
6
6
|
import * as fsp from "node:fs/promises";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
@@ -18,9 +18,9 @@ import {
|
|
|
18
18
|
sha384B64,
|
|
19
19
|
|
|
20
20
|
verifyRouteReachability,
|
|
21
|
-
} from "../../src/_platform/_lifecycle/verify-checks";
|
|
22
|
-
import { siteOrigin } from "../../src/_platform/market/api";
|
|
23
|
-
import { createSolutionsApi, solutionsEnv } from "../../src/_platform/solutions/api";
|
|
21
|
+
} from "../../src/_platform/api/_lifecycle/verify-checks";
|
|
22
|
+
import { siteOrigin } from "../../src/_platform/api/market/api";
|
|
23
|
+
import { createSolutionsApi, solutionsEnv } from "../../src/_platform/api/solutions/api";
|
|
24
24
|
import { installDb } from "../fixture";
|
|
25
25
|
|
|
26
26
|
const g = globalThis as any;
|
|
@@ -278,7 +278,10 @@ function setHttp(over: Record<string, unknown>) {
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
function makeEnv() {
|
|
281
|
-
|
|
281
|
+
// modulesJsonPath 钉进临时目录(readFile 失败 → 不打 web 项):默认值 `web/dist/modules.json`
|
|
282
|
+
// 是相对 cwd 的,会把模板本机构建产物卷进用例,全绿用例随「模板 build 过没有」摇摆。
|
|
283
|
+
// P4-2 两条 integrity 用例显式覆盖它。
|
|
284
|
+
return { ...solutionsEnv(), sharedRoot: root, statePath: join(root, "state.yaml"), modulesJsonPath: join(root, "modules.json") };
|
|
282
285
|
}
|
|
283
286
|
|
|
284
287
|
describe("深检端点门(admin 域)", () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// BDD:P2-8 深检报告结构 + 留存 N=10 + 可信性项(trust_state)+ i18n 降级项 + 设值不进报告。
|
|
2
2
|
// 纯模块单测(verify-report.ts)+ 端点编排(persist-on-POST / GET verify/last / 降级项 / secret 不泄漏)。
|
|
3
3
|
/* eslint-disable test/prefer-lowercase-title -- 端点动词/路径是验收锚点,保留大写(verify-checks.spec 同约定) */
|
|
4
|
-
import type { FsFace } from "../../src/_platform/_lifecycle/atomic";
|
|
5
|
-
import type { VerifyReport } from "../../src/_platform/_lifecycle/verify-report";
|
|
4
|
+
import type { FsFace } from "../../src/_platform/api/_lifecycle/atomic";
|
|
5
|
+
import type { VerifyReport } from "../../src/_platform/api/_lifecycle/verify-report";
|
|
6
6
|
import * as fsp from "node:fs/promises";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
persistReport,
|
|
13
13
|
VERIFY_REPORTS_KEEP,
|
|
14
14
|
verifyReportsDirOf,
|
|
15
|
-
} from "../../src/_platform/_lifecycle/verify-report";
|
|
16
|
-
import { createSolutionsApi, solutionsEnv } from "../../src/_platform/solutions/api";
|
|
15
|
+
} from "../../src/_platform/api/_lifecycle/verify-report";
|
|
16
|
+
import { createSolutionsApi, solutionsEnv } from "../../src/_platform/api/solutions/api";
|
|
17
17
|
import { installDb } from "../fixture";
|
|
18
18
|
|
|
19
19
|
const g = globalThis as any;
|
|
@@ -127,7 +127,9 @@ function setHttp(over: Record<string, unknown> = {}) {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
function makeEnv() {
|
|
130
|
-
|
|
130
|
+
// modulesJsonPath 同 verify-checks.spec:钉进临时目录(缺文件 → 跳过 web 项),
|
|
131
|
+
// 不吃模板本机 `web/dist/modules.json`。
|
|
132
|
+
return { ...solutionsEnv(), sharedRoot: root, statePath: join(root, "state.yaml"), modulesJsonPath: join(root, "modules.json"), verifyReportsDir: reportsDir };
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
async function insertRoute(perm: string | null) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/* eslint-disable test/prefer-lowercase-title -- AC 编号是验收锚点,保留大写 */
|
|
4
4
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
5
5
|
|
|
6
|
-
import { likePattern, paged, pagedFactory } from "../src/_platform/_shared/service/infra/query";
|
|
6
|
+
import { likePattern, paged, pagedFactory } from "../src/_platform/api/_shared/service/infra/query";
|
|
7
7
|
import { installDb } from "./fixture";
|
|
8
8
|
|
|
9
9
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/* eslint-disable test/prefer-lowercase-title -- AC 编号是验收锚点,保留大写 */
|
|
4
4
|
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
5
5
|
|
|
6
|
-
import { auditDeny, auditOp, recordOp, resetDenyAudit } from "../src/_platform/_shared/service/infra/audit";
|
|
6
|
+
import { auditDeny, auditOp, recordOp, resetDenyAudit } from "../src/_platform/api/_shared/service/infra/audit";
|
|
7
7
|
import { installDb } from "./fixture";
|
|
8
8
|
|
|
9
9
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/* eslint-disable test/prefer-lowercase-title -- AC 编号是验收锚点,保留大写 */
|
|
5
5
|
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
6
6
|
|
|
7
|
-
import { contactDetail, searchContacts } from "../src/_platform/_shared/service/domain/contacts";
|
|
7
|
+
import { contactDetail, searchContacts } from "../src/_platform/api/_shared/service/domain/contacts";
|
|
8
8
|
import { installDb } from "./fixture";
|
|
9
9
|
|
|
10
10
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -74,7 +74,7 @@ describe("详情与限速", () => {
|
|
|
74
74
|
it("接口级限速:同用户突发超限 → 429", async () => {
|
|
75
75
|
const uid = mkUser("c_rate");
|
|
76
76
|
g.http = { user: { id: uid } };
|
|
77
|
-
const { rateLimit } = await import("../src/_platform/_shared/service/infra/rate");
|
|
77
|
+
const { rateLimit } = await import("../src/_platform/api/_shared/service/infra/rate");
|
|
78
78
|
// 窗口 60s / 限额 3(测试参数;生产端点各自定额)
|
|
79
79
|
for (let i = 0; i < 3; i++)
|
|
80
80
|
await rateLimit(`contacts:${uid}`, 3, 60_000);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/* eslint-disable test/prefer-lowercase-title -- AC 编号是验收锚点,保留大写 */
|
|
5
5
|
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
6
6
|
|
|
7
|
-
import { assertPermission, assertSuperAdmin, assertSystemAdmin, invalidateUser } from "../src/_platform/_shared/service/infra/access";
|
|
7
|
+
import { assertPermission, assertSuperAdmin, assertSystemAdmin, invalidateUser } from "../src/_platform/api/_shared/service/infra/access";
|
|
8
8
|
import { installDb } from "./fixture";
|
|
9
9
|
|
|
10
10
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
/* eslint-disable test/prefer-lowercase-title -- AC 编号是验收锚点,保留大写 */
|
|
5
5
|
import { afterEach, beforeAll, describe, expect, it } from "vitest";
|
|
6
6
|
|
|
7
|
-
import { createRole, deleteRole, listPermissions, listRoles, updateBindings } from "../src/_platform/_shared/service/domain/roles";
|
|
8
|
-
import { assertPermission } from "../src/_platform/_shared/service/infra/access";
|
|
7
|
+
import { createRole, deleteRole, listPermissions, listRoles, updateBindings } from "../src/_platform/api/_shared/service/domain/roles";
|
|
8
|
+
import { assertPermission } from "../src/_platform/api/_shared/service/infra/access";
|
|
9
9
|
import { installDb } from "./fixture";
|
|
10
10
|
|
|
11
11
|
let dbo: ReturnType<typeof installDb>;
|
|
@@ -7,7 +7,7 @@ import { beforeAll, describe, expect, it } from "vitest";
|
|
|
7
7
|
|
|
8
8
|
import { installDb } from "./fixture";
|
|
9
9
|
|
|
10
|
-
const SEED = join(dirname(fileURLToPath(import.meta.url)), "..", "src", "_platform", "seed.sql");
|
|
10
|
+
const SEED = join(dirname(fileURLToPath(import.meta.url)), "..", "src", "_platform", "api", "seed.sql");
|
|
11
11
|
let dbo: ReturnType<typeof installDb>;
|
|
12
12
|
|
|
13
13
|
beforeAll(() => {
|