create-bubbles 0.1.27 → 0.1.28
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/dist/index.js +4 -4
- package/package.json +10 -2
- package/template-pnpm-vp-monorepo/.changeset/README.md +8 -0
- package/template-pnpm-vp-monorepo/.changeset/config.json +11 -0
- package/template-pnpm-vp-monorepo/.gitattributes +5 -0
- package/template-pnpm-vp-monorepo/.github/workflows/ci.yml +33 -0
- package/template-pnpm-vp-monorepo/.github/workflows/docs.yml +55 -0
- package/template-pnpm-vp-monorepo/.github/workflows/release.yml +54 -0
- package/template-pnpm-vp-monorepo/.vite-hooks/commit-msg +1 -0
- package/template-pnpm-vp-monorepo/.vite-hooks/pre-commit +1 -0
- package/template-pnpm-vp-monorepo/.vite-hooks/run.mjs +17 -0
- package/template-pnpm-vp-monorepo/.vscode/settings.json +23 -0
- package/{LICENSE → template-pnpm-vp-monorepo/LICENSE} +2 -2
- package/template-pnpm-vp-monorepo/README.md +93 -0
- package/template-pnpm-vp-monorepo/_gitignore +43 -0
- package/template-pnpm-vp-monorepo/apps/docs/.vitepress/config.mts +69 -0
- package/template-pnpm-vp-monorepo/apps/docs/guide/getting-started.md +70 -0
- package/template-pnpm-vp-monorepo/apps/docs/guide/release.md +73 -0
- package/template-pnpm-vp-monorepo/apps/docs/guide/workspace.md +84 -0
- package/template-pnpm-vp-monorepo/apps/docs/index.md +22 -0
- package/template-pnpm-vp-monorepo/apps/docs/package.json +23 -0
- package/template-pnpm-vp-monorepo/apps/docs/tsconfig.json +7 -0
- package/template-pnpm-vp-monorepo/apps/docs/vite.config.ts +12 -0
- package/template-pnpm-vp-monorepo/apps/playground/index.html +14 -0
- package/template-pnpm-vp-monorepo/apps/playground/package.json +24 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/App.vue +214 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/env.d.ts +6 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/main.ts +6 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/style.css +728 -0
- package/template-pnpm-vp-monorepo/apps/playground/tsconfig.json +10 -0
- package/template-pnpm-vp-monorepo/apps/playground/vite.config.ts +29 -0
- package/template-pnpm-vp-monorepo/commitlint.config.mjs +3 -0
- package/template-pnpm-vp-monorepo/eslint.config.mjs +22 -0
- package/template-pnpm-vp-monorepo/mise.toml +3 -0
- package/template-pnpm-vp-monorepo/package.json +40 -0
- package/template-pnpm-vp-monorepo/packages/utils/LICENSE +21 -0
- package/template-pnpm-vp-monorepo/packages/utils/README.md +26 -0
- package/template-pnpm-vp-monorepo/packages/utils/_gitignore +4 -0
- package/template-pnpm-vp-monorepo/packages/utils/package.json +42 -0
- package/template-pnpm-vp-monorepo/packages/utils/scripts/verify-package.mjs +127 -0
- package/template-pnpm-vp-monorepo/packages/utils/src/index.ts +12 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/consumer/commonjs.cts +20 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/consumer/esm.mts +20 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/consumer/tsconfig.json +10 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/index.test.ts +30 -0
- package/template-pnpm-vp-monorepo/packages/utils/tsconfig.json +4 -0
- package/template-pnpm-vp-monorepo/packages/utils/vite.config.ts +20 -0
- package/template-pnpm-vp-monorepo/pnpm-workspace.yaml +27 -0
- package/template-pnpm-vp-monorepo/tsconfig/base.json +22 -0
- package/template-pnpm-vp-monorepo/tsconfig/node.json +8 -0
- package/template-pnpm-vp-monorepo/tsconfig/vue.json +7 -0
- package/template-pnpm-vp-monorepo/tsconfig.json +4 -0
- package/template-pnpm-vp-monorepo/vite.config.ts +38 -0
- package/template-vp-monorepo-react-nestjs/.spaces/01./344/274/201/344/270/232/347/272/247/351/241/271/347/233/256/347/272/247//346/235/203/351/231/220/344/270/216/350/217/234/345/215/225//346/212/200/346/234/257/345/245/221/347/272/246.md +5 -3
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//344/272/244/344/273/230/350/256/260/345/275/225.md +9 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//345/217/221/345/270/203/350/257/204/344/274/260.md +93 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//345/267/245/345/205/267//350/277/220/350/241/214/346/227/266/345/217/221/345/270/203/346/243/200/346/237/245.mjs +340 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/346/212/245/345/221/212.md +28 -6
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/catalog/en_US.json +4 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/i18n.config.mjs +9 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/report.json +16 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/source/app.ts +2 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/empty-scan/catalog/en_US.json +4 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/empty-scan/i18n.config.mjs +9 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/empty-scan/report.json +19 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/output.json +84 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214//345/275/223/345/211/215/345/244/215/351/252/214.json +86 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214//346/243/200/346/237/245/347/273/223/346/236/234.json +30 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214//346/263/250/351/207/212/345/233/236/345/275/222.json +40 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203/bubblesjs-i18n-core-0.0.0.tgz +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203/bubblesjs-i18n-react-0.0.0.tgz +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203/bubblesjs-i18n-vue-0.0.1.tgz +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203//344/272/247/347/211/251/345/244/215/351/252/214.json +419 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203//346/243/200/346/237/245/347/273/223/346/236/234.json +339 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//350/277/220/350/241/214/346/227/266/345/217/221/345/270/203/346/243/200/346/237/245.json +131 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//350/256/276/350/256/241/346/226/271/346/241/210.md +19 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//351/234/200/346/261/202/346/226/207/346/241/243.md +21 -3
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/274/232/350/257/235/347/256/241/347/220/206//346/212/200/346/234/257/345/245/221/347/272/246.md +5 -2
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/274/232/350/257/235/347/256/241/347/220/206//351/234/200/346/261/202/346/226/207/346/241/243.md +4 -3
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201/PRD.md +2 -1
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//346/212/200/346/234/257/345/245/221/347/272/246.md +3 -2
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//346/265/213/350/257/225/346/212/245/345/221/212.md +15 -12
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//350/201/224/350/260/203/350/256/260/345/275/225.md +6 -5
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//350/256/276/350/256/241/346/226/271/346/241/210.md +2 -1
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//351/234/200/346/261/202/346/226/207/346/241/243.md +4 -3
- package/template-vp-monorepo-react-nestjs/.spaces/README.md +3 -2
- package/template-vp-monorepo-react-nestjs/apps/web/test/{password-actions.spec.ts → password/password-actions.spec.ts} +3 -3
- package/template-vp-monorepo-react-nestjs/apps/web/test/{password-reset-action.spec.ts → password/password-reset-action.spec.ts} +4 -2
- package/template-vp-monorepo-react-nestjs/apps/web/test/{workspaces-password-entry.spec.tsx → password/workspaces-password-entry.spec.tsx} +7 -7
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/README.md +2 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.test.ts +88 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.ts +34 -11
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/command.test.ts +36 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/react/src/use-store.ts +15 -5
- package/template-vp-monorepo-react-nestjs/tsconfig.lib.json +1 -1
- package/template-vp-react/package.json +5 -5
- package/template-vp-vue-eslint-vapor/.vscode/settings.json +53 -0
- package/template-vp-vue-eslint-vapor/package.json +1 -0
- package/template-vp-vue-eslint-vapor/pnpm-workspace.yaml +0 -24
- package/template-vp-vue-eslint-vapor/src/main.ts +2 -3
- package/template-vp-vue-eslint-vapor/vite.config.ts +26 -31
- package/template-vp-react/.vscode/settings.json +0 -18
- /package/{template-vp-vue-eslint-vapor → template-pnpm-vp-monorepo}/.vscode/extensions.json +0 -0
- /package/template-vp-monorepo-react-nestjs/apps/server/test/auth/{password-operations.spec.ts → password/password-operations.spec.ts} +0 -0
- /package/template-vp-monorepo-react-nestjs/apps/server/test/auth/{password.integration.spec.ts → password/password.integration.spec.ts} +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { fileURLToPath, URL } from "node:url";
|
|
2
|
+
|
|
3
|
+
import vue from "@vitejs/plugin-vue";
|
|
4
|
+
import { defineConfig } from "vite-plus";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [vue()],
|
|
8
|
+
resolve: {
|
|
9
|
+
alias: {
|
|
10
|
+
"@bubblesjs/utils": fileURLToPath(
|
|
11
|
+
new URL("../../packages/utils/src/index.ts", import.meta.url),
|
|
12
|
+
),
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
server: {
|
|
16
|
+
port: 5173,
|
|
17
|
+
strictPort: true,
|
|
18
|
+
},
|
|
19
|
+
run: {
|
|
20
|
+
tasks: {
|
|
21
|
+
bundle: {
|
|
22
|
+
command: "vp build",
|
|
23
|
+
cache: {
|
|
24
|
+
env: ["NODE_ENV"],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import antfu from "@antfu/eslint-config";
|
|
2
|
+
|
|
3
|
+
export default antfu(
|
|
4
|
+
{
|
|
5
|
+
formatters: false,
|
|
6
|
+
lessOpinionated: true,
|
|
7
|
+
stylistic: false,
|
|
8
|
+
typescript: true,
|
|
9
|
+
vue: true,
|
|
10
|
+
ignores: ["**/dist/**", "**/coverage/**", "**/.vitepress/cache/**", "**/.vitepress/dist/**"],
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
files: ["**/*.vue"],
|
|
14
|
+
rules: {
|
|
15
|
+
"vue/html-indent": "off",
|
|
16
|
+
"vue/html-self-closing": "off",
|
|
17
|
+
"vue/html-closing-bracket-newline": "off",
|
|
18
|
+
"vue/singleline-html-element-content-newline": "off",
|
|
19
|
+
"vue/multiline-html-element-content-newline": "off",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pnpm-vp-monorepo",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "vp run -r build",
|
|
8
|
+
"changeset": "changeset",
|
|
9
|
+
"check": "vp run quality",
|
|
10
|
+
"ci": "pnpm check && pnpm build && pnpm verify:packages",
|
|
11
|
+
"dev": "vp run playground#dev",
|
|
12
|
+
"docs:build": "vp run docs#build",
|
|
13
|
+
"docs:dev": "vp run docs#dev",
|
|
14
|
+
"docs:preview": "vp run docs#preview",
|
|
15
|
+
"format": "vp fmt --write .",
|
|
16
|
+
"format:check": "vp fmt --check .",
|
|
17
|
+
"hooks:install": "vp config --hooks-dir .vite-hooks --no-agent",
|
|
18
|
+
"lint": "pnpm lint:ox && pnpm lint:vue",
|
|
19
|
+
"lint:ox": "vp lint .",
|
|
20
|
+
"lint:vue": "eslint \"apps/**/*.vue\" \"packages/**/*.vue\" --no-error-on-unmatched-pattern --max-warnings=0",
|
|
21
|
+
"preview": "vp run playground#preview",
|
|
22
|
+
"ready": "pnpm run ci",
|
|
23
|
+
"release": "pnpm ready && changeset publish",
|
|
24
|
+
"test": "vp run -r test",
|
|
25
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && vp run -r typecheck",
|
|
26
|
+
"verify:packages": "vp run -r verify:package",
|
|
27
|
+
"version-packages": "changeset version && pnpm install --lockfile-only --no-frozen-lockfile"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@antfu/eslint-config": "catalog:",
|
|
31
|
+
"@changesets/cli": "catalog:",
|
|
32
|
+
"@commitlint/cli": "catalog:",
|
|
33
|
+
"@commitlint/config-conventional": "catalog:",
|
|
34
|
+
"@types/node": "catalog:",
|
|
35
|
+
"eslint": "catalog:",
|
|
36
|
+
"typescript": "catalog:",
|
|
37
|
+
"vite": "catalog:",
|
|
38
|
+
"vite-plus": "catalog:"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [copyright holder]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @bubblesjs/utils
|
|
2
|
+
|
|
3
|
+
模板中的内部共享 TypeScript 工具包,设置了 `private: true`,不发布到 npm。包名 `@bubblesjs/utils` 保留为工作区内部标识。通过 Vite+ Pack 输出 ESM、CommonJS 和对应的类型声明;应用通过 `workspace:*` 依赖它。
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { clamp } from "@bubblesjs/utils";
|
|
7
|
+
|
|
8
|
+
clamp(125, 0, 100); // 100
|
|
9
|
+
clamp(-20, 0, 100); // 0
|
|
10
|
+
clamp(42, 0, 100); // 42
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`clamp(value, min, max)` 要求参数均为有限数值,且 `min <= max`,否则抛出 `RangeError`。原有 `fn()` 导出保留,返回 `Hello, tsdown!`。
|
|
14
|
+
|
|
15
|
+
在仓库根目录运行:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm --filter @bubblesjs/utils test
|
|
19
|
+
pnpm --filter @bubblesjs/utils build
|
|
20
|
+
pnpm --filter @bubblesjs/utils typecheck
|
|
21
|
+
pnpm --filter @bubblesjs/utils verify:package
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`verify:package` 以及根目录的 `pnpm verify:packages` 仅检查本地 ESM/CJS、类型声明和打包文件,不执行 npm 发布。
|
|
25
|
+
|
|
26
|
+
复制为内部共享包时保留 `private: true`。若将来复制为公开包,例如 `@bubblesjs/math`,须显式移除 `private: true`,设置 `publishConfig.access` 为 `public` 并完善发布元信息。发布到 npm 的账户需拥有 `@bubblesjs` scope 或对应组织的包发布权限。维护 `tests/consumer` 中的双格式消费类型测试和 `scripts/verify-package.mjs` 中的运行验证;仅在更换 scope 时同步替换 `@bubblesjs` 的引用。
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bubblesjs/utils",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Monorepo 模板中的共享 TypeScript 工具包示例。",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"require": {
|
|
24
|
+
"types": "./dist/index.d.cts",
|
|
25
|
+
"default": "./dist/index.cjs"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "vp run bundle",
|
|
32
|
+
"dev": "vp pack --watch",
|
|
33
|
+
"test": "vp test run",
|
|
34
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
35
|
+
"verify:package": "vp pack && tsc -p tests/consumer/tsconfig.json --noEmit && node scripts/verify-package.mjs"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "catalog:",
|
|
39
|
+
"typescript": "catalog:",
|
|
40
|
+
"vite-plus": "catalog:"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { delimiter, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
const packageRoot = fileURLToPath(new URL("../", import.meta.url));
|
|
9
|
+
const manifest = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8"));
|
|
10
|
+
const requiredFiles = new Set(["package.json"]);
|
|
11
|
+
|
|
12
|
+
assert.ok(manifest.name, "Package must have a name");
|
|
13
|
+
|
|
14
|
+
function verifyFile(target, field) {
|
|
15
|
+
assert.equal(typeof target, "string", `${field} must reference a file`);
|
|
16
|
+
const absolutePath = resolve(packageRoot, target);
|
|
17
|
+
const relativePath = relative(packageRoot, absolutePath);
|
|
18
|
+
assert.ok(
|
|
19
|
+
relativePath && !relativePath.startsWith("..") && !isAbsolute(relativePath),
|
|
20
|
+
`${field} must stay inside the package`,
|
|
21
|
+
);
|
|
22
|
+
assert.ok(existsSync(absolutePath), `${field} references a missing file: ${target}`);
|
|
23
|
+
requiredFiles.add(relativePath.replaceAll("\\", "/"));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const field of ["main", "module", "types"]) {
|
|
27
|
+
verifyFile(manifest[field], field);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function verifyExports(value, field = "exports") {
|
|
31
|
+
if (typeof value === "string") {
|
|
32
|
+
verifyFile(value, field);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
assert.ok(value && typeof value === "object", `${field} must define export targets`);
|
|
36
|
+
for (const [condition, target] of Object.entries(value)) {
|
|
37
|
+
verifyExports(target, `${field}.${condition}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
verifyExports(manifest.exports);
|
|
42
|
+
const entry = manifest.exports["."];
|
|
43
|
+
assert.ok(entry?.import?.types?.endsWith(".d.ts"), "ESM exports must declare .d.ts types");
|
|
44
|
+
assert.ok(entry?.require?.types?.endsWith(".d.cts"), "CommonJS exports must declare .d.cts types");
|
|
45
|
+
assert.equal(manifest.type, "module", "ESM .js output requires type: module");
|
|
46
|
+
assert.ok(entry?.import?.default?.endsWith(".js"), "ESM exports must reference .js output");
|
|
47
|
+
assert.ok(entry?.require?.default?.endsWith(".cjs"), "CommonJS exports must reference .cjs output");
|
|
48
|
+
|
|
49
|
+
function verifyRuntime(module, format) {
|
|
50
|
+
assert.equal(module.fn(), "Hello, tsdown!", `${format}: fn()`);
|
|
51
|
+
assert.equal(module.clamp(5, 0, 10), 5, `${format}: value inside bounds`);
|
|
52
|
+
assert.equal(module.clamp(-2, 0, 10), 0, `${format}: lower bound`);
|
|
53
|
+
assert.equal(module.clamp(12, 0, 10), 10, `${format}: upper bound`);
|
|
54
|
+
assert.equal(module.clamp(3, 2, 2), 2, `${format}: equal bounds`);
|
|
55
|
+
for (const args of [
|
|
56
|
+
[NaN, 0, 10],
|
|
57
|
+
[Infinity, 0, 10],
|
|
58
|
+
[1, -Infinity, 10],
|
|
59
|
+
[1, 0, Infinity],
|
|
60
|
+
[1, 10, 0],
|
|
61
|
+
]) {
|
|
62
|
+
assert.throws(() => module.clamp(...args), RangeError, `${format}: invalid bounds or value`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
verifyRuntime(await import(manifest.name), "ESM");
|
|
67
|
+
verifyRuntime(createRequire(import.meta.url)(manifest.name), "CommonJS");
|
|
68
|
+
|
|
69
|
+
// Invoke npm's JavaScript CLI directly when npm is installed as a Windows .cmd
|
|
70
|
+
// wrapper. Passing arguments to Node avoids shell quoting and interpolation.
|
|
71
|
+
function npmCommand() {
|
|
72
|
+
const cliCandidates = [
|
|
73
|
+
process.env.npm_execpath,
|
|
74
|
+
join(dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js"),
|
|
75
|
+
];
|
|
76
|
+
for (const candidate of cliCandidates) {
|
|
77
|
+
if (candidate?.endsWith("npm-cli.js") && existsSync(candidate)) {
|
|
78
|
+
return { command: process.execPath, prefix: [candidate] };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const extensions = process.platform === "win32" ? [".exe", ".cmd", ".bat"] : [""];
|
|
83
|
+
const pathValue = process.env.PATH ?? process.env.Path ?? "";
|
|
84
|
+
for (const directory of pathValue.split(delimiter).filter(Boolean)) {
|
|
85
|
+
for (const extension of extensions) {
|
|
86
|
+
const candidate = join(directory.replace(/^"|"$/g, ""), `npm${extension}`);
|
|
87
|
+
if (!existsSync(candidate)) continue;
|
|
88
|
+
if ([".cmd", ".bat"].includes(extname(candidate).toLowerCase())) {
|
|
89
|
+
const cli = join(dirname(candidate), "node_modules", "npm", "bin", "npm-cli.js");
|
|
90
|
+
if (existsSync(cli)) return { command: process.execPath, prefix: [cli] };
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
return { command: candidate, prefix: [] };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
throw new Error("Cannot locate npm's executable or npm-cli.js; install Node.js with npm first.");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const { command, prefix } = npmCommand();
|
|
100
|
+
const result = spawnSync(command, [...prefix, "pack", "--dry-run", "--json", "--ignore-scripts"], {
|
|
101
|
+
cwd: packageRoot,
|
|
102
|
+
encoding: "utf8",
|
|
103
|
+
shell: false,
|
|
104
|
+
windowsHide: true,
|
|
105
|
+
timeout: 60_000,
|
|
106
|
+
});
|
|
107
|
+
if (result.error) throw result.error;
|
|
108
|
+
assert.equal(result.status, 0, `npm pack failed:\n${result.stderr || result.stdout}`);
|
|
109
|
+
const [packed] = JSON.parse(result.stdout);
|
|
110
|
+
assert.ok(packed?.files?.length, "npm pack must report publishable files");
|
|
111
|
+
const publishedFiles = new Set(packed.files.map(({ path }) => path.replaceAll("\\", "/")));
|
|
112
|
+
for (const target of requiredFiles) {
|
|
113
|
+
assert.ok(publishedFiles.has(target), `Published package is missing ${target}`);
|
|
114
|
+
}
|
|
115
|
+
for (const target of publishedFiles) {
|
|
116
|
+
assert.ok(!/^(src|tests)\//.test(target), `Source or tests must not be published: ${target}`);
|
|
117
|
+
}
|
|
118
|
+
assert.ok(
|
|
119
|
+
[...publishedFiles].some((target) => target.endsWith(".d.ts")),
|
|
120
|
+
"Published package must include ESM declarations",
|
|
121
|
+
);
|
|
122
|
+
assert.ok(
|
|
123
|
+
[...publishedFiles].some((target) => target.endsWith(".d.cts")),
|
|
124
|
+
"Published package must include CommonJS declarations",
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
console.log(`Verified ${manifest.name}: ESM, CommonJS, declarations, and npm package contents.`);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function fn() {
|
|
2
|
+
return "Hello, tsdown!";
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/** 将有限数值限制在闭区间 [min, max] 内。 */
|
|
6
|
+
export function clamp(value: number, min: number, max: number): number {
|
|
7
|
+
if (![value, min, max].every(Number.isFinite) || min > max) {
|
|
8
|
+
throw new RangeError("clamp 需要有限数值,且 min 不能大于 max。");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return Math.min(max, Math.max(min, value));
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import utils = require("@bubblesjs/utils");
|
|
2
|
+
|
|
3
|
+
const message: string = utils.fn();
|
|
4
|
+
const value: number = utils.clamp(5, 0, 10);
|
|
5
|
+
void message;
|
|
6
|
+
void value;
|
|
7
|
+
|
|
8
|
+
// @ts-expect-error Values must be numbers.
|
|
9
|
+
utils.clamp("5", 0, 10);
|
|
10
|
+
// @ts-expect-error Lower bounds must be numbers.
|
|
11
|
+
utils.clamp(5, "0", 10);
|
|
12
|
+
// @ts-expect-error Upper bounds must be numbers.
|
|
13
|
+
utils.clamp(5, 0, "10");
|
|
14
|
+
// @ts-expect-error All three arguments are required.
|
|
15
|
+
utils.clamp(5, 0);
|
|
16
|
+
// @ts-expect-error fn does not accept arguments.
|
|
17
|
+
utils.fn("extra");
|
|
18
|
+
// @ts-expect-error clamp returns a number.
|
|
19
|
+
const wrongResult: string = utils.clamp(5, 0, 10);
|
|
20
|
+
void wrongResult;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { clamp, fn } from "@bubblesjs/utils";
|
|
2
|
+
|
|
3
|
+
const message: string = fn();
|
|
4
|
+
const value: number = clamp(5, 0, 10);
|
|
5
|
+
void message;
|
|
6
|
+
void value;
|
|
7
|
+
|
|
8
|
+
// @ts-expect-error Values must be numbers.
|
|
9
|
+
clamp("5", 0, 10);
|
|
10
|
+
// @ts-expect-error Lower bounds must be numbers.
|
|
11
|
+
clamp(5, "0", 10);
|
|
12
|
+
// @ts-expect-error Upper bounds must be numbers.
|
|
13
|
+
clamp(5, 0, "10");
|
|
14
|
+
// @ts-expect-error All three arguments are required.
|
|
15
|
+
clamp(5, 0);
|
|
16
|
+
// @ts-expect-error fn does not accept arguments.
|
|
17
|
+
fn("extra");
|
|
18
|
+
// @ts-expect-error clamp returns a number.
|
|
19
|
+
const wrongResult: string = clamp(5, 0, 10);
|
|
20
|
+
void wrongResult;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, test } from "vite-plus/test";
|
|
2
|
+
import { clamp, fn } from "../src/index.ts";
|
|
3
|
+
|
|
4
|
+
test("fn", () => {
|
|
5
|
+
expect(fn()).toBe("Hello, tsdown!");
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
describe("clamp", () => {
|
|
9
|
+
test.each([
|
|
10
|
+
[5, 0, 10, 5],
|
|
11
|
+
[-5, 0, 10, 0],
|
|
12
|
+
[15, 0, 10, 10],
|
|
13
|
+
[0, 0, 10, 0],
|
|
14
|
+
[10, 0, 10, 10],
|
|
15
|
+
[8, 3, 3, 3],
|
|
16
|
+
[-2.5, -5, -1, -2.5],
|
|
17
|
+
])("限制 %s 到 [%s, %s] 得到 %s", (value, min, max, expected) => {
|
|
18
|
+
expect(clamp(value, min, max)).toBe(expected);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test.each([
|
|
22
|
+
[5, 10, 0],
|
|
23
|
+
[NaN, 0, 10],
|
|
24
|
+
[Infinity, 0, 10],
|
|
25
|
+
[5, -Infinity, 10],
|
|
26
|
+
[5, 0, Infinity],
|
|
27
|
+
])("拒绝非法输入 (%s, %s, %s)", (value, min, max) => {
|
|
28
|
+
expect(() => clamp(value, min, max)).toThrow(RangeError);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from "vite-plus";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
pack: {
|
|
5
|
+
entry: ["src/index.ts"],
|
|
6
|
+
format: ["esm", "cjs"],
|
|
7
|
+
dts: { generator: "tsc" },
|
|
8
|
+
platform: "neutral",
|
|
9
|
+
sourcemap: true,
|
|
10
|
+
},
|
|
11
|
+
test: {
|
|
12
|
+
include: ["tests/**/*.test.ts"],
|
|
13
|
+
environment: "node",
|
|
14
|
+
},
|
|
15
|
+
run: {
|
|
16
|
+
tasks: {
|
|
17
|
+
bundle: { command: "vp pack", cache: { env: ["NODE_ENV"] } },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
packages:
|
|
2
|
+
- apps/*
|
|
3
|
+
- packages/*
|
|
4
|
+
|
|
5
|
+
catalogMode: prefer
|
|
6
|
+
|
|
7
|
+
catalog:
|
|
8
|
+
"@antfu/eslint-config": ^9.5.1
|
|
9
|
+
"@changesets/cli": ^3.0.3
|
|
10
|
+
"@commitlint/cli": ^21.2.2
|
|
11
|
+
"@commitlint/config-conventional": ^21.2.2
|
|
12
|
+
"@types/node": ^26
|
|
13
|
+
"@vitejs/plugin-vue": ^6.0.9
|
|
14
|
+
eslint: ^10.9.0
|
|
15
|
+
typescript: ^6.0.3
|
|
16
|
+
vite: npm:@voidzero-dev/vite-plus-core@1.1.0
|
|
17
|
+
vite-plus: 1.1.0
|
|
18
|
+
vitepress: 2.0.0-alpha.20
|
|
19
|
+
vue: ^3.5.43
|
|
20
|
+
vue-tsc: ^3.3.12
|
|
21
|
+
overrides:
|
|
22
|
+
vite@*: "catalog:"
|
|
23
|
+
peerDependencyRules:
|
|
24
|
+
allowAny:
|
|
25
|
+
- vite
|
|
26
|
+
allowedVersions:
|
|
27
|
+
vite: "*"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"allowImportingTsExtensions": true,
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"forceConsistentCasingInFileNames": true,
|
|
7
|
+
"isolatedModules": true,
|
|
8
|
+
"lib": ["ES2022"],
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"moduleDetection": "force",
|
|
11
|
+
"moduleResolution": "Bundler",
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"noUncheckedIndexedAccess": true,
|
|
14
|
+
"noUnusedLocals": true,
|
|
15
|
+
"noUnusedParameters": true,
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"strict": true,
|
|
19
|
+
"target": "ES2022",
|
|
20
|
+
"verbatimModuleSyntax": true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { defineConfig } from "vite-plus";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
staged: {
|
|
5
|
+
"*.{js,jsx,ts,tsx,mjs,cjs,mts,cts,json,jsonc,yaml,yml,md,css,scss}": "vp check --fix",
|
|
6
|
+
"*.vue": ["vp fmt --write", "eslint --fix --max-warnings=0"],
|
|
7
|
+
},
|
|
8
|
+
fmt: {
|
|
9
|
+
ignorePatterns: [
|
|
10
|
+
"**/dist/**",
|
|
11
|
+
"**/coverage/**",
|
|
12
|
+
"**/.vitepress/cache/**",
|
|
13
|
+
"**/.vitepress/dist/**",
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
lint: {
|
|
17
|
+
ignorePatterns: [
|
|
18
|
+
"**/dist/**",
|
|
19
|
+
"**/coverage/**",
|
|
20
|
+
"**/.vitepress/cache/**",
|
|
21
|
+
"**/.vitepress/dist/**",
|
|
22
|
+
"**/*.vue",
|
|
23
|
+
"packages/utils/tests/consumer/**",
|
|
24
|
+
],
|
|
25
|
+
jsPlugins: [{ name: "vite-plus", specifier: "vite-plus/oxlint-plugin" }],
|
|
26
|
+
rules: { "vite-plus/prefer-vite-plus-imports": "error" },
|
|
27
|
+
options: { typeAware: true, typeCheck: true },
|
|
28
|
+
},
|
|
29
|
+
run: {
|
|
30
|
+
cache: { scripts: false, tasks: true },
|
|
31
|
+
tasks: {
|
|
32
|
+
quality: {
|
|
33
|
+
command: ["pnpm format:check", "pnpm lint", "pnpm typecheck", "pnpm test"],
|
|
34
|
+
cache: false,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
@@ -197,7 +197,7 @@ interface PermissionTreeResult {
|
|
|
197
197
|
| -------- | -------------------- | --------------------------------------------------- | ------------ | ------------------------------------------- |
|
|
198
198
|
| platform | `platform.home` | `/platform` | 平台工作台 | — |
|
|
199
199
|
| platform | `platform.companies` | `/platform/companies` | 企业管理 | `create*`, `status`, `administrator*` |
|
|
200
|
-
| platform | `platform.accounts` | `/platform/accounts` | 全局账号 | `status`, `roles`
|
|
200
|
+
| platform | `platform.accounts` | `/platform/accounts` | 全局账号 | `status`, `roles`, `reset-password*` |
|
|
201
201
|
| platform | `platform.roles` | `/platform/roles` | 平台角色 | `create`, `update`, `delete`, `permissions` |
|
|
202
202
|
| platform | `platform.menus` | `/platform/menus` | 菜单管理 | `create`, `update`, `delete`, `cleanup*` |
|
|
203
203
|
| platform | `platform.audit` | `/platform/audit` | 平台操作日志 | — |
|
|
@@ -268,6 +268,7 @@ interface AssignPlatformRolesRequest {
|
|
|
268
268
|
| GET `/platform/accounts` | 查询 → `PageResult<AccountRecord>` | `platform.accounts.read` |
|
|
269
269
|
| PATCH `/platform/accounts/:userId/status` | `AccountStatusRequest` → `AccountRecord` | `platform.accounts.status`;禁用最后企业管理员必须是平台内置管理员,最后平台管理员不可禁用 |
|
|
270
270
|
| PUT `/platform/accounts/:userId/roles` | `AssignPlatformRolesRequest` → `AccountRecord` | `platform.accounts.roles`;全量替换该用户平台角色,不触碰企业/项目角色 |
|
|
271
|
+
| POST `/platform/accounts/:userId/reset-password` | `ResetAccountPasswordRequest` → `ResetAccountPasswordResult` | `platform.accounts.reset-password` + 平台内置管理员;只能重置他人,成功撤销目标全部终端会话;详见[修改密码技术契约](../../06.认证与会话/修改密码/技术契约.md) |
|
|
271
272
|
| GET `/companies/:companyId` | → `CompanyDetail` | `company.profile.read` |
|
|
272
273
|
| PATCH `/companies/:companyId` | `UpdateProfileRequest` → `CompanyRecord` | `company.profile.update` |
|
|
273
274
|
| GET `/companies/:companyId/projects` | 查询 → `PageResult<ProjectRecord>` | `company.projects.read`;企业管理员所有项目,其他成员仅本人显式加入的项目,允许看到这些项目的停用状态 |
|
|
@@ -479,7 +480,7 @@ interface AuditQuery extends PageQuery {
|
|
|
479
480
|
|
|
480
481
|
GET `/platform/audit-logs`、`/companies/:companyId/audit-logs`、`/companies/:companyId/projects/:projectId/audit-logs` 返回 `PageResult<AuditRecord>`,分别要求 `platform.audit.read`、`company.audit.read`、`project.audit.read`。日期为 ISO 字符串,`from <= to`;默认不额外限制日期。平台只看 scopeType=platform,企业看本企业 company+project,项目只看本项目。query 搜索 action/objectType/objectId 的公开标识,不提供任意 JSON SQL 筛选。
|
|
481
482
|
|
|
482
|
-
action 使用固定 `company.create/company.status/company.administrator.set/project.create/project.status/project.administrator.set/account.status/member.add/member.status/member.remove/member.roles/role.create/role.update/role.permissions/role.delete/menu.create/menu.update/menu.delete/permission.cleanup`。同一 action 的实际范围从 scope
|
|
483
|
+
action 使用固定 `company.create/company.status/company.administrator.set/project.create/project.status/project.administrator.set/account.status/account.password.reset/member.add/member.status/member.remove/member.roles/role.create/role.update/role.permissions/role.delete/menu.create/menu.update/menu.delete/permission.cleanup`。同一 action 的实际范围从 scope 区分。平台侧企业创建、账号启停、企业管理员设置、管理员重置密码、菜单和清理写平台事件;内部公司/项目变更写自身事件,目标企业 ID 可以进入平台事件的 summary,但不能据此把该事件归入企业审计。`account.password.reset` 仅在成功时写入,`summary` 只含 `{ result: 'success' }`;两种密码操作的成功与失败安全事件见[修改密码技术契约](../../06.认证与会话/修改密码/技术契约.md)。企业邀请审计动作及字段待产品确认,不属于当前固定 action 集合。
|
|
483
484
|
|
|
484
485
|
摘要只记录字段白名单,例如 `changedFields`, `fromStatus`, `toStatus`, `roleIds`, `permissionKeys`, `targetUserId`, `companyId`, `replacedUserId`;不记录完整请求体、密码或令牌。操作者姓名/账号保存当时快照,防止后续变化破坏审计可读性。本期记录成功管理变更,失败交由现有异常/服务日志处理,不增加失败审计产品。
|
|
485
486
|
|
|
@@ -564,10 +565,11 @@ scope CHECK 精确为:platform 两个 ID 均 NULL;company company_id 非 NUL
|
|
|
564
565
|
## 13. 后续扩展与变更记录
|
|
565
566
|
|
|
566
567
|
- 企业邀请只保留已确认的入口定位;邀请对象、载体、流程、状态及技术协议全部待产品确认。当前代码、页面、自动化测试及 `0004_company-member-invitations.sql` 只能作为未确认实现记录,不能替代产品确认或进入现行交付。
|
|
567
|
-
-
|
|
568
|
+
- 平台全局账号的管理员重置密码已在当前工作树实现,`platform.accounts.reset-password` 仅平台内置管理员可用,上文权限表、接口表和固定审计 action 清单已同步。业务错误、全端撤销和安全事件见[修改密码技术契约](../../06.认证与会话/修改密码/技术契约.md),测试边界见[修改密码测试报告](../../06.认证与会话/修改密码/测试报告.md)。
|
|
568
569
|
|
|
569
570
|
| 日期 | 变更摘要 | 原因 | 影响范围 |
|
|
570
571
|
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
572
|
+
| 2026-10-08 | 将管理员重置密码纳入当前平台账号操作、接口和固定审计清单,并链接测试边界 | 当前工作树已实现且完成自动化与隔离存储专项 | 平台账号权限、接口与审计清单 |
|
|
571
573
|
| 2026-10-08 | 关联平台账号管理员重置密码的实施中增量,区分待实施权限与当前权限表 | 修改密码契约已确定新增平台管理员操作 | 平台账号权限、接口与审计清单 |
|
|
572
574
|
| 2026-09-19 | 菜单图标契约由服务端图标名白名单调整为安全 SVG key;Web 自动发现本地图标并统一选择、解析和降级,补充旧图标及空值迁移和新菜单默认图标规则 | 前端资源不能由服务端重复维护清单,且需支持新增 SVG 自动进入选择器 | 共享类型、校验、种子、迁移、菜单管理、导航和兼容测试 |
|
|
573
575
|
| 2026-09-18 | 菜单路由等待态保留旧页面视觉内容并隔离交互,目标路由提交后再替换 | 过早卸载 `RouteTransition` 会丢失旧页面视图快照,导致过渡动画消失 | 前端布局、导航等待态、AC-05 与验证要求 |
|
|
@@ -10,3 +10,12 @@
|
|
|
10
10
|
## 状态
|
|
11
11
|
|
|
12
12
|
已实现并完成构建、测试和 i18n 词条检查。当前语言范围仍为 `zh_CN` 与 `en_US`。
|
|
13
|
+
|
|
14
|
+
独立包发布状态:2026-10-09 复验完成,当前版本仍不宜直接发布。用户修改的 React selector 快照缓存已通过真实渲染检查;本轮仅更新评估、复现工具及证据,未修改业务实现或执行远端发布。剩余发布条件见 [发布评估](./发布评估.md)。
|
|
15
|
+
|
|
16
|
+
## CLI 调用边界注释修复(2026-10-08)
|
|
17
|
+
|
|
18
|
+
- 扫描器允许调用名、左括号和静态字符串后的空白、行注释与块注释,支持 JavaScript 行终止符及准确的源码位置。
|
|
19
|
+
- 保持字符串正文、动态参数过滤和注释内完整调用也会被识别的现有约定,未闭合块注释不会使当前调用匹配成功。
|
|
20
|
+
- 新增扫描与实际 clean 回归,验证仍在使用的词条及既有译文得到保留;CLI 71 个测试、构建与修改文件检查通过,见 [测试报告](./测试报告.md)。
|
|
21
|
+
- 本次仅交付该扫描缺陷修复;完整包发布仍需完成 [发布评估](./发布评估.md) 中的剩余整改。
|