无用代码去除
This commit is contained in:
parent
ed9536f6ab
commit
badc8c1cf4
|
|
@ -1,4 +0,0 @@
|
||||||
> 1%
|
|
||||||
last 2 versions
|
|
||||||
not dead
|
|
||||||
not ie 11
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# Changesets
|
|
||||||
|
|
||||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
||||||
|
|
||||||
We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
|
||||||
"changelog": [
|
|
||||||
"@changesets/changelog-github",
|
|
||||||
{ "repo": "aiflowy/aiflowy" }
|
|
||||||
],
|
|
||||||
"commit": false,
|
|
||||||
"fixed": [["@aiflowy-core/*", "@aiflowy/*"]],
|
|
||||||
"snapshot": {
|
|
||||||
"prereleaseTemplate": "{tag}-{datetime}"
|
|
||||||
},
|
|
||||||
"privatePackages": { "version": true, "tag": true },
|
|
||||||
"linked": [],
|
|
||||||
"access": "public",
|
|
||||||
"baseBranch": "main",
|
|
||||||
"updateInternalDependencies": "patch",
|
|
||||||
"ignore": []
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export { default } from '@aiflowy/commitlint-config';
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
node_modules
|
|
||||||
.git
|
|
||||||
.gitignore
|
|
||||||
*.md
|
|
||||||
dist
|
|
||||||
.turbo
|
|
||||||
dist.zip
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset=utf-8
|
|
||||||
end_of_line=lf
|
|
||||||
insert_final_newline=true
|
|
||||||
indent_style=space
|
|
||||||
indent_size=2
|
|
||||||
max_line_length = 100
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
quote_type = single
|
|
||||||
|
|
||||||
[*.{yml,yaml,json}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
# https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
|
||||||
|
|
||||||
# Automatically normalize line endings (to LF) for all text-based files.
|
|
||||||
* text=auto eol=lf
|
|
||||||
|
|
||||||
# Declare files that will always have CRLF line endings on checkout.
|
|
||||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
|
||||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
|
||||||
|
|
||||||
# Denote all files that are truly binary and should not be modified.
|
|
||||||
*.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[core]
|
|
||||||
ignorecase = false
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
node_modules
|
|
||||||
.DS_Store
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
dist.zip
|
|
||||||
dist.tar
|
|
||||||
dist.war
|
|
||||||
.nitro
|
|
||||||
.output
|
|
||||||
*-dist.zip
|
|
||||||
*-dist.tar
|
|
||||||
*-dist.war
|
|
||||||
coverage
|
|
||||||
*.local
|
|
||||||
**/.vitepress/cache
|
|
||||||
.cache
|
|
||||||
.turbo
|
|
||||||
.temp
|
|
||||||
dev-dist
|
|
||||||
.stylelintcache
|
|
||||||
yarn.lock
|
|
||||||
package-lock.json
|
|
||||||
.VSCodeCounter
|
|
||||||
**/backend-mock/data
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
vite.config.mts.*
|
|
||||||
vite.config.mjs.*
|
|
||||||
vite.config.js.*
|
|
||||||
vite.config.ts.*
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.idea
|
|
||||||
# .vscode
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
.history
|
|
||||||
.cursor
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
ports:
|
|
||||||
- port: 5555
|
|
||||||
onOpen: open-preview
|
|
||||||
tasks:
|
|
||||||
- init: npm i -g corepack && pnpm install
|
|
||||||
command: pnpm run dev:play
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
22.1.0
|
|
||||||
13
.npmrc
13
.npmrc
|
|
@ -1,13 +0,0 @@
|
||||||
registry=https://registry.npmmirror.com
|
|
||||||
public-hoist-pattern[]=lefthook
|
|
||||||
public-hoist-pattern[]=eslint
|
|
||||||
public-hoist-pattern[]=prettier
|
|
||||||
public-hoist-pattern[]=prettier-plugin-tailwindcss
|
|
||||||
public-hoist-pattern[]=stylelint
|
|
||||||
public-hoist-pattern[]=*postcss*
|
|
||||||
public-hoist-pattern[]=@commitlint/*
|
|
||||||
public-hoist-pattern[]=czg
|
|
||||||
|
|
||||||
strict-peer-dependencies=false
|
|
||||||
auto-install-peers=true
|
|
||||||
dedupe-peer-dependents=true
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
dist
|
|
||||||
dev-dist
|
|
||||||
.local
|
|
||||||
.output.js
|
|
||||||
node_modules
|
|
||||||
.nvmrc
|
|
||||||
coverage
|
|
||||||
CODEOWNERS
|
|
||||||
.nitro
|
|
||||||
.output
|
|
||||||
|
|
||||||
|
|
||||||
**/*.svg
|
|
||||||
**/*.sh
|
|
||||||
|
|
||||||
public
|
|
||||||
.npmrc
|
|
||||||
*-lock.yaml
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export { default } from '@aiflowy/prettier-config';
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
dist
|
|
||||||
public
|
|
||||||
__tests__
|
|
||||||
coverage
|
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
{
|
|
||||||
"folders": [
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/app",
|
|
||||||
"path": "app",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/commitlint-config",
|
|
||||||
"path": "internal/lint-configs/commitlint-config",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/eslint-config",
|
|
||||||
"path": "internal/lint-configs/eslint-config",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/prettier-config",
|
|
||||||
"path": "internal/lint-configs/prettier-config",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/stylelint-config",
|
|
||||||
"path": "internal/lint-configs/stylelint-config",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/node-utils",
|
|
||||||
"path": "internal/node-utils",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/tailwind-config",
|
|
||||||
"path": "internal/tailwind-config",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/tsconfig",
|
|
||||||
"path": "internal/tsconfig",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/vite-config",
|
|
||||||
"path": "internal/vite-config",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/design",
|
|
||||||
"path": "packages/@core/base/design",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/icons",
|
|
||||||
"path": "packages/@core/base/icons",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/shared",
|
|
||||||
"path": "packages/@core/base/shared",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/typings",
|
|
||||||
"path": "packages/@core/base/typings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/composables",
|
|
||||||
"path": "packages/@core/composables",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/preferences",
|
|
||||||
"path": "packages/@core/preferences",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/form-ui",
|
|
||||||
"path": "packages/@core/ui-kit/form-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/layout-ui",
|
|
||||||
"path": "packages/@core/ui-kit/layout-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/menu-ui",
|
|
||||||
"path": "packages/@core/ui-kit/menu-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/popup-ui",
|
|
||||||
"path": "packages/@core/ui-kit/popup-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/shadcn-ui",
|
|
||||||
"path": "packages/@core/ui-kit/shadcn-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy-core/tabs-ui",
|
|
||||||
"path": "packages/@core/ui-kit/tabs-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/constants",
|
|
||||||
"path": "packages/constants",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/access",
|
|
||||||
"path": "packages/effects/access",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/common-ui",
|
|
||||||
"path": "packages/effects/common-ui",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/hooks",
|
|
||||||
"path": "packages/effects/hooks",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/layouts",
|
|
||||||
"path": "packages/effects/layouts",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/plugins",
|
|
||||||
"path": "packages/effects/plugins",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/request",
|
|
||||||
"path": "packages/effects/request",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/icons",
|
|
||||||
"path": "packages/icons",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/locales",
|
|
||||||
"path": "packages/locales",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/preferences",
|
|
||||||
"path": "packages/preferences",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/stores",
|
|
||||||
"path": "packages/stores",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/styles",
|
|
||||||
"path": "packages/styles",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/types",
|
|
||||||
"path": "packages/types",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/utils",
|
|
||||||
"path": "packages/utils",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/turbo-run",
|
|
||||||
"path": "scripts/turbo-run",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "@aiflowy/vsh",
|
|
||||||
"path": "scripts/vsh",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/app",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homepage": "https://aiflowy.tech",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "app"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"build": "pnpm vite build --mode production",
|
|
||||||
"build:analyze": "pnpm vite build --mode analyze",
|
|
||||||
"dev": "pnpm vite --mode development",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"typecheck": "vue-tsc --noEmit --skipLibCheck"
|
|
||||||
},
|
|
||||||
"imports": {
|
|
||||||
"#/*": "./src/*"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@aiflowy-core/shadcn-ui": "workspace:*",
|
|
||||||
"@aiflowy/access": "workspace:*",
|
|
||||||
"@aiflowy/common-ui": "workspace:*",
|
|
||||||
"@aiflowy/constants": "workspace:*",
|
|
||||||
"@aiflowy/hooks": "workspace:*",
|
|
||||||
"@aiflowy/icons": "workspace:*",
|
|
||||||
"@aiflowy/layouts": "workspace:*",
|
|
||||||
"@aiflowy/locales": "workspace:*",
|
|
||||||
"@aiflowy/plugins": "workspace:*",
|
|
||||||
"@aiflowy/preferences": "workspace:*",
|
|
||||||
"@aiflowy/request": "workspace:*",
|
|
||||||
"@aiflowy/stores": "workspace:*",
|
|
||||||
"@aiflowy/styles": "workspace:*",
|
|
||||||
"@aiflowy/types": "workspace:*",
|
|
||||||
"@aiflowy/utils": "workspace:*",
|
|
||||||
"@element-plus/icons-vue": "^2.3.2",
|
|
||||||
"@tinyflow-ai/vue": "^1.1.10",
|
|
||||||
"@vueuse/core": "catalog:",
|
|
||||||
"dayjs": "catalog:",
|
|
||||||
"dompurify": "^3.3.1",
|
|
||||||
"element-plus": "catalog:",
|
|
||||||
"fetch-event-stream": "^0.1.6",
|
|
||||||
"highlight.js": "^11.11.1",
|
|
||||||
"markdown-it": "^14.1.0",
|
|
||||||
"pinia": "catalog:",
|
|
||||||
"radash": "^12.1.1",
|
|
||||||
"vue": "catalog:",
|
|
||||||
"vue-cropper": "^1.1.4",
|
|
||||||
"vue-element-plus-x": "^1.3.7",
|
|
||||||
"vue-router": "catalog:",
|
|
||||||
"vue3-json-viewer": "^2.4.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"cssnano": "catalog:",
|
|
||||||
"unplugin-element-plus": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
69
cspell.json
69
cspell.json
|
|
@ -1,69 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
|
|
||||||
"version": "0.2",
|
|
||||||
"language": "en,en-US",
|
|
||||||
"allowCompoundWords": true,
|
|
||||||
"words": [
|
|
||||||
"acmr",
|
|
||||||
"antd",
|
|
||||||
"antdv",
|
|
||||||
"astro",
|
|
||||||
"brotli",
|
|
||||||
"clsx",
|
|
||||||
"defu",
|
|
||||||
"demi",
|
|
||||||
"echarts",
|
|
||||||
"ependencies",
|
|
||||||
"esno",
|
|
||||||
"etag",
|
|
||||||
"execa",
|
|
||||||
"iconify",
|
|
||||||
"iconoir",
|
|
||||||
"intlify",
|
|
||||||
"lockb",
|
|
||||||
"lucide",
|
|
||||||
"minh",
|
|
||||||
"minw",
|
|
||||||
"mkdist",
|
|
||||||
"mockjs",
|
|
||||||
"naiveui",
|
|
||||||
"nocheck",
|
|
||||||
"noopener",
|
|
||||||
"noreferrer",
|
|
||||||
"nprogress",
|
|
||||||
"nuxt",
|
|
||||||
"pinia",
|
|
||||||
"prefixs",
|
|
||||||
"publint",
|
|
||||||
"qrcode",
|
|
||||||
"reka",
|
|
||||||
"shadcn",
|
|
||||||
"sonner",
|
|
||||||
"sortablejs",
|
|
||||||
"styl",
|
|
||||||
"taze",
|
|
||||||
"ui-kit",
|
|
||||||
"uicons",
|
|
||||||
"unplugin",
|
|
||||||
"unref",
|
|
||||||
"aiflowy",
|
|
||||||
"aiflowy",
|
|
||||||
"vite",
|
|
||||||
"vitejs",
|
|
||||||
"vitepress",
|
|
||||||
"vnode",
|
|
||||||
"vueuse",
|
|
||||||
"yxxx"
|
|
||||||
],
|
|
||||||
"ignorePaths": [
|
|
||||||
"**/node_modules/**",
|
|
||||||
"**/dist/**",
|
|
||||||
"**/*-dist/**",
|
|
||||||
"**/icons/**",
|
|
||||||
"pnpm-lock.yaml",
|
|
||||||
"**/*.log",
|
|
||||||
"**/*.test.ts",
|
|
||||||
"**/*.spec.ts",
|
|
||||||
"**/__tests__/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
import { defineConfig } from '@aiflowy/eslint-config';
|
|
||||||
|
|
||||||
export default defineConfig();
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
import { execSync } from 'node:child_process';
|
|
||||||
|
|
||||||
import { getPackagesSync } from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
const { packages } = getPackagesSync();
|
|
||||||
|
|
||||||
const allowedScopes = [
|
|
||||||
...packages.map((pkg) => pkg.packageJson.name),
|
|
||||||
'project',
|
|
||||||
'style',
|
|
||||||
'lint',
|
|
||||||
'ci',
|
|
||||||
'dev',
|
|
||||||
'deploy',
|
|
||||||
'other',
|
|
||||||
];
|
|
||||||
|
|
||||||
// precomputed scope
|
|
||||||
const scopeComplete = execSync('git status --porcelain || true')
|
|
||||||
.toString()
|
|
||||||
.trim()
|
|
||||||
.split('\n')
|
|
||||||
.find((r) => ~r.indexOf('M src'))
|
|
||||||
?.replace(/(\/)/g, '%%')
|
|
||||||
?.match(/src%%((\w|-)*)/)?.[1]
|
|
||||||
?.replace(/s$/, '');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {import('cz-git').UserConfig}
|
|
||||||
*/
|
|
||||||
const userConfig = {
|
|
||||||
extends: ['@commitlint/config-conventional'],
|
|
||||||
plugins: ['commitlint-plugin-function-rules'],
|
|
||||||
prompt: {
|
|
||||||
/** @use `pnpm commit :f` */
|
|
||||||
alias: {
|
|
||||||
b: 'build: bump dependencies',
|
|
||||||
c: 'chore: update config',
|
|
||||||
f: 'docs: fix typos',
|
|
||||||
r: 'docs: update README',
|
|
||||||
s: 'style: update code format',
|
|
||||||
},
|
|
||||||
allowCustomIssuePrefixs: false,
|
|
||||||
// scopes: [...scopes, 'mock'],
|
|
||||||
allowEmptyIssuePrefixs: false,
|
|
||||||
customScopesAlign: scopeComplete ? 'bottom' : 'top',
|
|
||||||
defaultScope: scopeComplete,
|
|
||||||
// English
|
|
||||||
typesAppend: [
|
|
||||||
{ name: 'workflow: workflow improvements', value: 'workflow' },
|
|
||||||
{ name: 'types: type definition file changes', value: 'types' },
|
|
||||||
],
|
|
||||||
|
|
||||||
// 中英文对照版
|
|
||||||
// messages: {
|
|
||||||
// type: '选择你要提交的类型 :',
|
|
||||||
// scope: '选择一个提交范围 (可选):',
|
|
||||||
// customScope: '请输入自定义的提交范围 :',
|
|
||||||
// subject: '填写简短精炼的变更描述 :\n',
|
|
||||||
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
|
|
||||||
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
|
|
||||||
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
|
|
||||||
// customFooterPrefixs: '输入自定义issue前缀 :',
|
|
||||||
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
|
|
||||||
// confirmCommit: '是否提交或修改commit ?',
|
|
||||||
// },
|
|
||||||
// types: [
|
|
||||||
// { value: 'feat', name: 'feat: 新增功能' },
|
|
||||||
// { value: 'fix', name: 'fix: 修复缺陷' },
|
|
||||||
// { value: 'docs', name: 'docs: 文档变更' },
|
|
||||||
// { value: 'style', name: 'style: 代码格式' },
|
|
||||||
// { value: 'refactor', name: 'refactor: 代码重构' },
|
|
||||||
// { value: 'perf', name: 'perf: 性能优化' },
|
|
||||||
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
|
|
||||||
// { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' },
|
|
||||||
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
|
|
||||||
// { value: 'revert', name: 'revert: 回滚 commit' },
|
|
||||||
// { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' },
|
|
||||||
// { value: 'wip', name: 'wip: 正在开发中' },
|
|
||||||
// { value: 'workflow', name: 'workflow: 工作流程改进' },
|
|
||||||
// { value: 'types', name: 'types: 类型定义文件修改' },
|
|
||||||
// ],
|
|
||||||
// emptyScopesAlias: 'empty: 不填写',
|
|
||||||
// customScopesAlias: 'custom: 自定义',
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
/**
|
|
||||||
* type[scope]: [function] description
|
|
||||||
*
|
|
||||||
* ^^^^^^^^^^^^^^ empty line.
|
|
||||||
* - Something here
|
|
||||||
*/
|
|
||||||
'body-leading-blank': [2, 'always'],
|
|
||||||
/**
|
|
||||||
* type[scope]: [function] description
|
|
||||||
*
|
|
||||||
* - something here
|
|
||||||
*
|
|
||||||
* ^^^^^^^^^^^^^^
|
|
||||||
*/
|
|
||||||
'footer-leading-blank': [1, 'always'],
|
|
||||||
/**
|
|
||||||
* type[scope]: [function] description
|
|
||||||
* ^^^^^
|
|
||||||
*/
|
|
||||||
'function-rules/scope-enum': [
|
|
||||||
2, // level: error
|
|
||||||
'always',
|
|
||||||
(parsed) => {
|
|
||||||
if (!parsed.scope || allowedScopes.includes(parsed.scope)) {
|
|
||||||
return [true];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [false, `scope must be one of ${allowedScopes.join(', ')}`];
|
|
||||||
},
|
|
||||||
],
|
|
||||||
/**
|
|
||||||
* type[scope]: [function] description [No more than 108 characters]
|
|
||||||
* ^^^^^
|
|
||||||
*/
|
|
||||||
'header-max-length': [2, 'always', 108],
|
|
||||||
|
|
||||||
'scope-enum': [0],
|
|
||||||
'subject-case': [0],
|
|
||||||
'subject-empty': [2, 'never'],
|
|
||||||
'type-empty': [2, 'never'],
|
|
||||||
/**
|
|
||||||
* type[scope]: [function] description
|
|
||||||
* ^^^^
|
|
||||||
*/
|
|
||||||
'type-enum': [
|
|
||||||
2,
|
|
||||||
'always',
|
|
||||||
[
|
|
||||||
'feat',
|
|
||||||
'fix',
|
|
||||||
'perf',
|
|
||||||
'style',
|
|
||||||
'docs',
|
|
||||||
'test',
|
|
||||||
'refactor',
|
|
||||||
'build',
|
|
||||||
'ci',
|
|
||||||
'chore',
|
|
||||||
'revert',
|
|
||||||
'types',
|
|
||||||
'release',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default userConfig;
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/commitlint-config",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/lint-configs/commitlint-config"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./index.mjs",
|
|
||||||
"module": "./index.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": "./index.mjs",
|
|
||||||
"default": "./index.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@commitlint/cli": "catalog:",
|
|
||||||
"@commitlint/config-conventional": "catalog:",
|
|
||||||
"@aiflowy/node-utils": "workspace:*",
|
|
||||||
"commitlint-plugin-function-rules": "catalog:",
|
|
||||||
"cz-git": "catalog:",
|
|
||||||
"czg": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import { defineBuildConfig } from 'unbuild';
|
|
||||||
|
|
||||||
export default defineBuildConfig({
|
|
||||||
clean: true,
|
|
||||||
declaration: true,
|
|
||||||
entries: ['src/index'],
|
|
||||||
});
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/eslint-config",
|
|
||||||
"version": "5.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/lint-configs/eslint-config"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"stub": "pnpm unbuild --stub"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./dist/index.mjs",
|
|
||||||
"module": "./dist/index.mjs",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"import": "./dist/index.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"eslint-config-turbo": "catalog:",
|
|
||||||
"eslint-plugin-command": "catalog:",
|
|
||||||
"eslint-plugin-import-x": "catalog:"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@eslint/js": "catalog:",
|
|
||||||
"@types/eslint": "catalog:",
|
|
||||||
"@typescript-eslint/eslint-plugin": "catalog:",
|
|
||||||
"@typescript-eslint/parser": "catalog:",
|
|
||||||
"eslint": "catalog:",
|
|
||||||
"eslint-plugin-eslint-comments": "catalog:",
|
|
||||||
"eslint-plugin-jsdoc": "catalog:",
|
|
||||||
"eslint-plugin-jsonc": "catalog:",
|
|
||||||
"eslint-plugin-n": "catalog:",
|
|
||||||
"eslint-plugin-no-only-tests": "catalog:",
|
|
||||||
"eslint-plugin-perfectionist": "catalog:",
|
|
||||||
"eslint-plugin-prettier": "catalog:",
|
|
||||||
"eslint-plugin-regexp": "catalog:",
|
|
||||||
"eslint-plugin-unicorn": "catalog:",
|
|
||||||
"eslint-plugin-unused-imports": "catalog:",
|
|
||||||
"eslint-plugin-vitest": "catalog:",
|
|
||||||
"eslint-plugin-vue": "catalog:",
|
|
||||||
"globals": "catalog:",
|
|
||||||
"jsonc-eslint-parser": "catalog:",
|
|
||||||
"vue-eslint-parser": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import createCommand from 'eslint-plugin-command/config';
|
|
||||||
|
|
||||||
export async function command() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
// @ts-expect-error - no types
|
|
||||||
...createCommand(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function comments(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginComments] = await Promise.all([
|
|
||||||
// @ts-expect-error - no types
|
|
||||||
interopDefault(import('eslint-plugin-eslint-comments')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
'eslint-comments': pluginComments,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'eslint-comments/no-aggregating-enable': 'error',
|
|
||||||
'eslint-comments/no-duplicate-disable': 'error',
|
|
||||||
'eslint-comments/no-unlimited-disable': 'error',
|
|
||||||
'eslint-comments/no-unused-enable': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
export async function disableds(): Promise<Linter.Config[]> {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
files: ['**/__tests__/**/*.?([cm])[jt]s?(x)'],
|
|
||||||
name: 'disables/test',
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/ban-ts-comment': 'off',
|
|
||||||
'no-console': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/*.d.ts'],
|
|
||||||
name: 'disables/dts',
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/triple-slash-reference': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/*.js', '**/*.mjs', '**/*.cjs'],
|
|
||||||
name: 'disables/js',
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
export async function ignores(): Promise<Linter.Config[]> {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
ignores: [
|
|
||||||
'**/node_modules',
|
|
||||||
'**/dist',
|
|
||||||
'**/dist-*',
|
|
||||||
'**/*-dist',
|
|
||||||
'**/.husky',
|
|
||||||
'**/.nitro',
|
|
||||||
'**/.output',
|
|
||||||
'**/Dockerfile',
|
|
||||||
'**/package-lock.json',
|
|
||||||
'**/yarn.lock',
|
|
||||||
'**/pnpm-lock.yaml',
|
|
||||||
'**/bun.lockb',
|
|
||||||
'**/output',
|
|
||||||
'**/coverage',
|
|
||||||
'**/temp',
|
|
||||||
'**/.temp',
|
|
||||||
'**/tmp',
|
|
||||||
'**/.tmp',
|
|
||||||
'**/.history',
|
|
||||||
'**/.turbo',
|
|
||||||
'**/.nuxt',
|
|
||||||
'**/.next',
|
|
||||||
'**/.vercel',
|
|
||||||
'**/.changeset',
|
|
||||||
'**/.idea',
|
|
||||||
'**/.cache',
|
|
||||||
'**/.output',
|
|
||||||
'**/.vite-inspect',
|
|
||||||
|
|
||||||
'**/CHANGELOG*.md',
|
|
||||||
'**/*.min.*',
|
|
||||||
'**/LICENSE*',
|
|
||||||
'**/__snapshots__',
|
|
||||||
'**/*.snap',
|
|
||||||
'**/fixtures/**',
|
|
||||||
'**/.vitepress/cache/**',
|
|
||||||
'**/auto-import?(s).d.ts',
|
|
||||||
'**/components.d.ts',
|
|
||||||
'**/vite.config.mts.*',
|
|
||||||
'**/*.sh',
|
|
||||||
'**/*.ttf',
|
|
||||||
'**/*.woff',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import * as pluginImport from 'eslint-plugin-import-x';
|
|
||||||
|
|
||||||
export async function importPluginConfig(): Promise<Linter.Config[]> {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
// @ts-expect-error - This is a dynamic import
|
|
||||||
import: pluginImport,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
|
||||||
'import/first': 'error',
|
|
||||||
'import/newline-after-import': 'error',
|
|
||||||
'import/no-duplicates': 'error',
|
|
||||||
'import/no-mutable-exports': 'error',
|
|
||||||
'import/no-named-default': 'error',
|
|
||||||
'import/no-self-import': 'error',
|
|
||||||
'import/no-unresolved': 'off',
|
|
||||||
'import/no-webpack-loader-syntax': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
export * from './command';
|
|
||||||
export * from './comments';
|
|
||||||
export * from './disableds';
|
|
||||||
export * from './ignores';
|
|
||||||
export * from './import';
|
|
||||||
export * from './javascript';
|
|
||||||
export * from './jsdoc';
|
|
||||||
export * from './jsonc';
|
|
||||||
export * from './node';
|
|
||||||
export * from './perfectionist';
|
|
||||||
export * from './prettier';
|
|
||||||
export * from './regexp';
|
|
||||||
export * from './test';
|
|
||||||
export * from './turbo';
|
|
||||||
export * from './typescript';
|
|
||||||
export * from './unicorn';
|
|
||||||
export * from './vue';
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import js from '@eslint/js';
|
|
||||||
import pluginUnusedImports from 'eslint-plugin-unused-imports';
|
|
||||||
import globals from 'globals';
|
|
||||||
|
|
||||||
export async function javascript(): Promise<Linter.Config[]> {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
globals: {
|
|
||||||
...globals.browser,
|
|
||||||
...globals.es2021,
|
|
||||||
...globals.node,
|
|
||||||
document: 'readonly',
|
|
||||||
navigator: 'readonly',
|
|
||||||
window: 'readonly',
|
|
||||||
},
|
|
||||||
parserOptions: {
|
|
||||||
ecmaFeatures: {
|
|
||||||
jsx: true,
|
|
||||||
},
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
linterOptions: {
|
|
||||||
reportUnusedDisableDirectives: true,
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
'unused-imports': pluginUnusedImports,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...js.configs.recommended.rules,
|
|
||||||
'accessor-pairs': [
|
|
||||||
'error',
|
|
||||||
{ enforceForClassMembers: true, setWithoutGet: true },
|
|
||||||
],
|
|
||||||
'array-callback-return': 'error',
|
|
||||||
'block-scoped-var': 'error',
|
|
||||||
'constructor-super': 'error',
|
|
||||||
'default-case-last': 'error',
|
|
||||||
'dot-notation': ['error', { allowKeywords: true }],
|
|
||||||
eqeqeq: ['error', 'always'],
|
|
||||||
'keyword-spacing': 'off',
|
|
||||||
|
|
||||||
'new-cap': [
|
|
||||||
'error',
|
|
||||||
{ capIsNew: false, newIsCap: true, properties: true },
|
|
||||||
],
|
|
||||||
'no-alert': 'error',
|
|
||||||
'no-array-constructor': 'error',
|
|
||||||
'no-async-promise-executor': 'error',
|
|
||||||
'no-caller': 'error',
|
|
||||||
'no-case-declarations': 'error',
|
|
||||||
'no-class-assign': 'error',
|
|
||||||
'no-compare-neg-zero': 'error',
|
|
||||||
'no-cond-assign': ['error', 'always'],
|
|
||||||
'no-console': ['error', { allow: ['warn', 'error'] }],
|
|
||||||
'no-const-assign': 'error',
|
|
||||||
'no-control-regex': 'error',
|
|
||||||
'no-debugger': 'error',
|
|
||||||
'no-delete-var': 'error',
|
|
||||||
'no-dupe-args': 'error',
|
|
||||||
'no-dupe-class-members': 'error',
|
|
||||||
'no-dupe-keys': 'error',
|
|
||||||
'no-duplicate-case': 'error',
|
|
||||||
'no-empty': ['error', { allowEmptyCatch: true }],
|
|
||||||
'no-empty-character-class': 'error',
|
|
||||||
'no-empty-function': 'off',
|
|
||||||
'no-empty-pattern': 'error',
|
|
||||||
'no-eval': 'error',
|
|
||||||
'no-ex-assign': 'error',
|
|
||||||
'no-extend-native': 'error',
|
|
||||||
'no-extra-bind': 'error',
|
|
||||||
'no-extra-boolean-cast': 'error',
|
|
||||||
'no-fallthrough': 'error',
|
|
||||||
'no-func-assign': 'error',
|
|
||||||
'no-global-assign': 'error',
|
|
||||||
'no-implied-eval': 'error',
|
|
||||||
'no-import-assign': 'error',
|
|
||||||
'no-invalid-regexp': 'error',
|
|
||||||
'no-irregular-whitespace': 'error',
|
|
||||||
'no-iterator': 'error',
|
|
||||||
'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
|
|
||||||
'no-lone-blocks': 'error',
|
|
||||||
'no-loss-of-precision': 'error',
|
|
||||||
'no-misleading-character-class': 'error',
|
|
||||||
'no-multi-str': 'error',
|
|
||||||
'no-new': 'error',
|
|
||||||
'no-new-func': 'error',
|
|
||||||
'no-new-object': 'error',
|
|
||||||
'no-new-symbol': 'error',
|
|
||||||
'no-new-wrappers': 'error',
|
|
||||||
'no-obj-calls': 'error',
|
|
||||||
'no-octal': 'error',
|
|
||||||
'no-octal-escape': 'error',
|
|
||||||
'no-proto': 'error',
|
|
||||||
'no-prototype-builtins': 'error',
|
|
||||||
'no-redeclare': ['error', { builtinGlobals: false }],
|
|
||||||
'no-regex-spaces': 'error',
|
|
||||||
'no-restricted-globals': [
|
|
||||||
'error',
|
|
||||||
{ message: 'Use `globalThis` instead.', name: 'global' },
|
|
||||||
{ message: 'Use `globalThis` instead.', name: 'self' },
|
|
||||||
],
|
|
||||||
'no-restricted-properties': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
message:
|
|
||||||
'Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.',
|
|
||||||
property: '__proto__',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: 'Use `Object.defineProperty` instead.',
|
|
||||||
property: '__defineGetter__',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: 'Use `Object.defineProperty` instead.',
|
|
||||||
property: '__defineSetter__',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: 'Use `Object.getOwnPropertyDescriptor` instead.',
|
|
||||||
property: '__lookupGetter__',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: 'Use `Object.getOwnPropertyDescriptor` instead.',
|
|
||||||
property: '__lookupSetter__',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-restricted-syntax': [
|
|
||||||
'error',
|
|
||||||
'DebuggerStatement',
|
|
||||||
'LabeledStatement',
|
|
||||||
'WithStatement',
|
|
||||||
'TSEnumDeclaration[const=true]',
|
|
||||||
'TSExportAssignment',
|
|
||||||
],
|
|
||||||
'no-self-assign': ['error', { props: true }],
|
|
||||||
'no-self-compare': 'error',
|
|
||||||
'no-sequences': 'error',
|
|
||||||
'no-shadow-restricted-names': 'error',
|
|
||||||
'no-sparse-arrays': 'error',
|
|
||||||
'no-template-curly-in-string': 'error',
|
|
||||||
'no-this-before-super': 'error',
|
|
||||||
'no-throw-literal': 'error',
|
|
||||||
'no-undef': 'off',
|
|
||||||
'no-undef-init': 'error',
|
|
||||||
'no-unexpected-multiline': 'error',
|
|
||||||
'no-unmodified-loop-condition': 'error',
|
|
||||||
'no-unneeded-ternary': ['error', { defaultAssignment: false }],
|
|
||||||
'no-unreachable': 'error',
|
|
||||||
'no-unreachable-loop': 'error',
|
|
||||||
'no-unsafe-finally': 'error',
|
|
||||||
'no-unsafe-negation': 'error',
|
|
||||||
'no-unused-expressions': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
allowShortCircuit: true,
|
|
||||||
allowTaggedTemplates: true,
|
|
||||||
allowTernary: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-unused-vars': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
args: 'none',
|
|
||||||
caughtErrors: 'none',
|
|
||||||
ignoreRestSiblings: true,
|
|
||||||
vars: 'all',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-use-before-define': [
|
|
||||||
'error',
|
|
||||||
{ classes: false, functions: false, variables: false },
|
|
||||||
],
|
|
||||||
'no-useless-backreference': 'error',
|
|
||||||
'no-useless-call': 'error',
|
|
||||||
'no-useless-catch': 'error',
|
|
||||||
'no-useless-computed-key': 'error',
|
|
||||||
'no-useless-constructor': 'error',
|
|
||||||
'no-useless-rename': 'error',
|
|
||||||
'no-useless-return': 'error',
|
|
||||||
'no-var': 'error',
|
|
||||||
'no-with': 'error',
|
|
||||||
'object-shorthand': [
|
|
||||||
'error',
|
|
||||||
'always',
|
|
||||||
{ avoidQuotes: true, ignoreConstructors: false },
|
|
||||||
],
|
|
||||||
'one-var': ['error', { initialized: 'never' }],
|
|
||||||
'prefer-arrow-callback': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
allowNamedFunctions: false,
|
|
||||||
allowUnboundThis: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'prefer-const': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
destructuring: 'all',
|
|
||||||
ignoreReadBeforeAssign: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'prefer-exponentiation-operator': 'error',
|
|
||||||
|
|
||||||
'prefer-promise-reject-errors': 'error',
|
|
||||||
'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
|
|
||||||
'prefer-rest-params': 'error',
|
|
||||||
'prefer-spread': 'error',
|
|
||||||
'prefer-template': 'error',
|
|
||||||
'space-before-function-paren': 'off',
|
|
||||||
'spaced-comment': 'error',
|
|
||||||
'symbol-description': 'error',
|
|
||||||
'unicode-bom': ['error', 'never'],
|
|
||||||
|
|
||||||
'unused-imports/no-unused-imports': 'error',
|
|
||||||
'unused-imports/no-unused-vars': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
args: 'after-used',
|
|
||||||
argsIgnorePattern: '^_',
|
|
||||||
vars: 'all',
|
|
||||||
varsIgnorePattern: '^_',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'use-isnan': [
|
|
||||||
'error',
|
|
||||||
{ enforceForIndexOf: true, enforceForSwitchCase: true },
|
|
||||||
],
|
|
||||||
'valid-typeof': ['error', { requireStringLiterals: true }],
|
|
||||||
|
|
||||||
'vars-on-top': 'error',
|
|
||||||
yoda: ['error', 'never'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function jsdoc(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginJsdoc] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-jsdoc')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
jsdoc: pluginJsdoc,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'jsdoc/check-access': 'warn',
|
|
||||||
'jsdoc/check-param-names': 'warn',
|
|
||||||
'jsdoc/check-property-names': 'warn',
|
|
||||||
'jsdoc/check-types': 'warn',
|
|
||||||
'jsdoc/empty-tags': 'warn',
|
|
||||||
'jsdoc/implements-on-classes': 'warn',
|
|
||||||
'jsdoc/no-defaults': 'warn',
|
|
||||||
'jsdoc/no-multi-asterisks': 'warn',
|
|
||||||
'jsdoc/require-param-name': 'warn',
|
|
||||||
'jsdoc/require-property': 'warn',
|
|
||||||
'jsdoc/require-property-description': 'warn',
|
|
||||||
'jsdoc/require-property-name': 'warn',
|
|
||||||
'jsdoc/require-returns-check': 'warn',
|
|
||||||
'jsdoc/require-returns-description': 'warn',
|
|
||||||
'jsdoc/require-yields-check': 'warn',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,258 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function jsonc(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginJsonc, parserJsonc] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-jsonc')),
|
|
||||||
interopDefault(import('jsonc-eslint-parser')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
files: ['**/*.json', '**/*.json5', '**/*.jsonc', '*.code-workspace'],
|
|
||||||
languageOptions: {
|
|
||||||
parser: parserJsonc as any,
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
jsonc: pluginJsonc as any,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'jsonc/no-bigint-literals': 'error',
|
|
||||||
'jsonc/no-binary-expression': 'error',
|
|
||||||
'jsonc/no-binary-numeric-literals': 'error',
|
|
||||||
'jsonc/no-dupe-keys': 'error',
|
|
||||||
'jsonc/no-escape-sequence-in-identifier': 'error',
|
|
||||||
'jsonc/no-floating-decimal': 'error',
|
|
||||||
'jsonc/no-hexadecimal-numeric-literals': 'error',
|
|
||||||
'jsonc/no-infinity': 'error',
|
|
||||||
'jsonc/no-multi-str': 'error',
|
|
||||||
'jsonc/no-nan': 'error',
|
|
||||||
'jsonc/no-number-props': 'error',
|
|
||||||
'jsonc/no-numeric-separators': 'error',
|
|
||||||
'jsonc/no-octal': 'error',
|
|
||||||
'jsonc/no-octal-escape': 'error',
|
|
||||||
'jsonc/no-octal-numeric-literals': 'error',
|
|
||||||
'jsonc/no-parenthesized': 'error',
|
|
||||||
'jsonc/no-plus-sign': 'error',
|
|
||||||
'jsonc/no-regexp-literals': 'error',
|
|
||||||
'jsonc/no-sparse-arrays': 'error',
|
|
||||||
'jsonc/no-template-literals': 'error',
|
|
||||||
'jsonc/no-undefined-value': 'error',
|
|
||||||
'jsonc/no-unicode-codepoint-escapes': 'error',
|
|
||||||
'jsonc/no-useless-escape': 'error',
|
|
||||||
'jsonc/space-unary-ops': 'error',
|
|
||||||
'jsonc/valid-json-number': 'error',
|
|
||||||
'jsonc/vue-custom-block/no-parsing-error': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
sortTsconfig(),
|
|
||||||
sortPackageJson(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortPackageJson(): Linter.Config {
|
|
||||||
return {
|
|
||||||
files: ['**/package.json'],
|
|
||||||
rules: {
|
|
||||||
'jsonc/sort-array-values': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: { type: 'asc' },
|
|
||||||
pathPattern: '^files$|^pnpm.neverBuiltDependencies$',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'jsonc/sort-keys': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: [
|
|
||||||
'name',
|
|
||||||
'version',
|
|
||||||
'description',
|
|
||||||
'private',
|
|
||||||
'keywords',
|
|
||||||
'homepage',
|
|
||||||
'bugs',
|
|
||||||
'repository',
|
|
||||||
'license',
|
|
||||||
'author',
|
|
||||||
'contributors',
|
|
||||||
'categories',
|
|
||||||
'funding',
|
|
||||||
'type',
|
|
||||||
'scripts',
|
|
||||||
'files',
|
|
||||||
'sideEffects',
|
|
||||||
'bin',
|
|
||||||
'main',
|
|
||||||
'module',
|
|
||||||
'unpkg',
|
|
||||||
'jsdelivr',
|
|
||||||
'types',
|
|
||||||
'typesVersions',
|
|
||||||
'imports',
|
|
||||||
'exports',
|
|
||||||
'publishConfig',
|
|
||||||
'icon',
|
|
||||||
'activationEvents',
|
|
||||||
'contributes',
|
|
||||||
'peerDependencies',
|
|
||||||
'peerDependenciesMeta',
|
|
||||||
'dependencies',
|
|
||||||
'optionalDependencies',
|
|
||||||
'devDependencies',
|
|
||||||
'engines',
|
|
||||||
'packageManager',
|
|
||||||
'pnpm',
|
|
||||||
'overrides',
|
|
||||||
'resolutions',
|
|
||||||
'husky',
|
|
||||||
'simple-git-hooks',
|
|
||||||
'lint-staged',
|
|
||||||
'eslintConfig',
|
|
||||||
],
|
|
||||||
pathPattern: '^$',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: { type: 'asc' },
|
|
||||||
pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: { type: 'asc' },
|
|
||||||
pathPattern: '^(?:resolutions|overrides|pnpm.overrides)$',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: ['types', 'import', 'require', 'default'],
|
|
||||||
pathPattern: '^exports.*$',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortTsconfig(): Linter.Config {
|
|
||||||
return {
|
|
||||||
files: [
|
|
||||||
'**/tsconfig.json',
|
|
||||||
'**/tsconfig.*.json',
|
|
||||||
'internal/tsconfig/*.json',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'jsonc/sort-keys': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: [
|
|
||||||
'extends',
|
|
||||||
'compilerOptions',
|
|
||||||
'references',
|
|
||||||
'files',
|
|
||||||
'include',
|
|
||||||
'exclude',
|
|
||||||
],
|
|
||||||
pathPattern: '^$',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: [
|
|
||||||
/* Projects */
|
|
||||||
'incremental',
|
|
||||||
'composite',
|
|
||||||
'tsBuildInfoFile',
|
|
||||||
'disableSourceOfProjectReferenceRedirect',
|
|
||||||
'disableSolutionSearching',
|
|
||||||
'disableReferencedProjectLoad',
|
|
||||||
/* Language and Environment */
|
|
||||||
'target',
|
|
||||||
'jsx',
|
|
||||||
'jsxFactory',
|
|
||||||
'jsxFragmentFactory',
|
|
||||||
'jsxImportSource',
|
|
||||||
'lib',
|
|
||||||
'moduleDetection',
|
|
||||||
'noLib',
|
|
||||||
'reactNamespace',
|
|
||||||
'useDefineForClassFields',
|
|
||||||
'emitDecoratorMetadata',
|
|
||||||
'experimentalDecorators',
|
|
||||||
/* Modules */
|
|
||||||
'baseUrl',
|
|
||||||
'rootDir',
|
|
||||||
'rootDirs',
|
|
||||||
'customConditions',
|
|
||||||
'module',
|
|
||||||
'moduleResolution',
|
|
||||||
'moduleSuffixes',
|
|
||||||
'noResolve',
|
|
||||||
'paths',
|
|
||||||
'resolveJsonModule',
|
|
||||||
'resolvePackageJsonExports',
|
|
||||||
'resolvePackageJsonImports',
|
|
||||||
'typeRoots',
|
|
||||||
'types',
|
|
||||||
'allowArbitraryExtensions',
|
|
||||||
'allowImportingTsExtensions',
|
|
||||||
'allowUmdGlobalAccess',
|
|
||||||
/* JavaScript Support */
|
|
||||||
'allowJs',
|
|
||||||
'checkJs',
|
|
||||||
'maxNodeModuleJsDepth',
|
|
||||||
/* Type Checking */
|
|
||||||
'strict',
|
|
||||||
'strictBindCallApply',
|
|
||||||
'strictFunctionTypes',
|
|
||||||
'strictNullChecks',
|
|
||||||
'strictPropertyInitialization',
|
|
||||||
'allowUnreachableCode',
|
|
||||||
'allowUnusedLabels',
|
|
||||||
'alwaysStrict',
|
|
||||||
'exactOptionalPropertyTypes',
|
|
||||||
'noFallthroughCasesInSwitch',
|
|
||||||
'noImplicitAny',
|
|
||||||
'noImplicitOverride',
|
|
||||||
'noImplicitReturns',
|
|
||||||
'noImplicitThis',
|
|
||||||
'noPropertyAccessFromIndexSignature',
|
|
||||||
'noUncheckedIndexedAccess',
|
|
||||||
'noUnusedLocals',
|
|
||||||
'noUnusedParameters',
|
|
||||||
'useUnknownInCatchVariables',
|
|
||||||
/* Emit */
|
|
||||||
'declaration',
|
|
||||||
'declarationDir',
|
|
||||||
'declarationMap',
|
|
||||||
'downlevelIteration',
|
|
||||||
'emitBOM',
|
|
||||||
'emitDeclarationOnly',
|
|
||||||
'importHelpers',
|
|
||||||
'importsNotUsedAsValues',
|
|
||||||
'inlineSourceMap',
|
|
||||||
'inlineSources',
|
|
||||||
'mapRoot',
|
|
||||||
'newLine',
|
|
||||||
'noEmit',
|
|
||||||
'noEmitHelpers',
|
|
||||||
'noEmitOnError',
|
|
||||||
'outDir',
|
|
||||||
'outFile',
|
|
||||||
'preserveConstEnums',
|
|
||||||
'preserveValueImports',
|
|
||||||
'removeComments',
|
|
||||||
'sourceMap',
|
|
||||||
'sourceRoot',
|
|
||||||
'stripInternal',
|
|
||||||
/* Interop Constraints */
|
|
||||||
'allowSyntheticDefaultImports',
|
|
||||||
'esModuleInterop',
|
|
||||||
'forceConsistentCasingInFileNames',
|
|
||||||
'isolatedModules',
|
|
||||||
'preserveSymlinks',
|
|
||||||
'verbatimModuleSyntax',
|
|
||||||
/* Completeness */
|
|
||||||
'skipDefaultLibCheck',
|
|
||||||
'skipLibCheck',
|
|
||||||
],
|
|
||||||
pathPattern: '^compilerOptions$',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function node(): Promise<Linter.Config[]> {
|
|
||||||
const pluginNode = await interopDefault(import('eslint-plugin-n'));
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
n: pluginNode,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'n/handle-callback-err': ['error', '^(err|error)$'],
|
|
||||||
'n/no-deprecated-api': 'error',
|
|
||||||
'n/no-exports-assign': 'error',
|
|
||||||
'n/no-extraneous-import': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
allowModules: [
|
|
||||||
'unbuild',
|
|
||||||
'@aiflowy/vite-config',
|
|
||||||
'vitest',
|
|
||||||
'vite',
|
|
||||||
'@vue/test-utils',
|
|
||||||
'@aiflowy/tailwind-config',
|
|
||||||
'@playwright/test',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'n/no-new-require': 'error',
|
|
||||||
'n/no-path-concat': 'error',
|
|
||||||
// 'n/no-unpublished-import': 'off',
|
|
||||||
'n/no-unsupported-features/es-syntax': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignores: [],
|
|
||||||
version: '>=18.0.0',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'n/prefer-global/buffer': ['error', 'never'],
|
|
||||||
// 'n/no-missing-import': 'off',
|
|
||||||
'n/prefer-global/process': ['error', 'never'],
|
|
||||||
'n/process-exit-as-throw': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'scripts/**/*.?([cm])[jt]s?(x)',
|
|
||||||
'internal/**/*.?([cm])[jt]s?(x)',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'n/prefer-global/process': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function perfectionist(): Promise<Linter.Config[]> {
|
|
||||||
const perfectionistPlugin = await interopDefault(
|
|
||||||
// @ts-expect-error - no types
|
|
||||||
import('eslint-plugin-perfectionist'),
|
|
||||||
);
|
|
||||||
|
|
||||||
return [
|
|
||||||
perfectionistPlugin.configs['recommended-natural'],
|
|
||||||
{
|
|
||||||
rules: {
|
|
||||||
'perfectionist/sort-exports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: 'asc',
|
|
||||||
type: 'natural',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'perfectionist/sort-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
customGroups: {
|
|
||||||
type: {
|
|
||||||
'aiflowy-core-type': ['^@aiflowy-core/.+'],
|
|
||||||
'aiflowy-type': ['^@aiflowy/.+'],
|
|
||||||
'vue-type': ['^vue$', '^vue-.+', '^@vue/.+'],
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
aiflowy: ['^@aiflowy/.+'],
|
|
||||||
'aiflowy-core': ['^@aiflowy-core/.+'],
|
|
||||||
vue: ['^vue$', '^vue-.+', '^@vue/.+'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
environment: 'node',
|
|
||||||
groups: [
|
|
||||||
['external-type', 'builtin-type', 'type'],
|
|
||||||
'vue-type',
|
|
||||||
'aiflowy-type',
|
|
||||||
'aiflowy-core-type',
|
|
||||||
['parent-type', 'sibling-type', 'index-type'],
|
|
||||||
['internal-type'],
|
|
||||||
'builtin',
|
|
||||||
'vue',
|
|
||||||
'aiflowy',
|
|
||||||
'aiflowy-core',
|
|
||||||
'external',
|
|
||||||
'internal',
|
|
||||||
['parent', 'sibling', 'index'],
|
|
||||||
'side-effect',
|
|
||||||
'side-effect-style',
|
|
||||||
'style',
|
|
||||||
'object',
|
|
||||||
'unknown',
|
|
||||||
],
|
|
||||||
internalPattern: ['^#/.+'],
|
|
||||||
newlinesBetween: 'always',
|
|
||||||
order: 'asc',
|
|
||||||
type: 'natural',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'perfectionist/sort-modules': 'off',
|
|
||||||
'perfectionist/sort-named-exports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: 'asc',
|
|
||||||
type: 'natural',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'perfectionist/sort-objects': [
|
|
||||||
'off',
|
|
||||||
{
|
|
||||||
customGroups: {
|
|
||||||
items: 'items',
|
|
||||||
list: 'list',
|
|
||||||
children: 'children',
|
|
||||||
},
|
|
||||||
groups: ['unknown', 'items', 'list', 'children'],
|
|
||||||
ignorePattern: ['children'],
|
|
||||||
order: 'asc',
|
|
||||||
type: 'natural',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function prettier(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginPrettier] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-prettier')),
|
|
||||||
] as const);
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
prettier: pluginPrettier,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'prettier/prettier': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function regexp(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginRegexp] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-regexp')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
regexp: pluginRegexp,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...pluginRegexp.configs.recommended.rules,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function test(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginTest, pluginNoOnlyTests] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-vitest')),
|
|
||||||
// @ts-expect-error - no types
|
|
||||||
interopDefault(import('eslint-plugin-no-only-tests')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
`**/__tests__/**/*.?([cm])[jt]s?(x)`,
|
|
||||||
`**/*.spec.?([cm])[jt]s?(x)`,
|
|
||||||
`**/*.test.?([cm])[jt]s?(x)`,
|
|
||||||
`**/*.bench.?([cm])[jt]s?(x)`,
|
|
||||||
`**/*.benchmark.?([cm])[jt]s?(x)`,
|
|
||||||
],
|
|
||||||
plugins: {
|
|
||||||
test: {
|
|
||||||
...pluginTest,
|
|
||||||
rules: {
|
|
||||||
...pluginTest.rules,
|
|
||||||
...pluginNoOnlyTests.rules,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'no-console': 'off',
|
|
||||||
'node/prefer-global/process': 'off',
|
|
||||||
'test/consistent-test-it': [
|
|
||||||
'error',
|
|
||||||
{ fn: 'it', withinDescribe: 'it' },
|
|
||||||
],
|
|
||||||
'test/no-identical-title': 'error',
|
|
||||||
'test/no-import-node-test': 'error',
|
|
||||||
'test/no-only-tests': 'error',
|
|
||||||
'test/prefer-hooks-in-order': 'error',
|
|
||||||
'test/prefer-lowercase-title': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function turbo(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginTurbo] = await Promise.all([
|
|
||||||
// @ts-expect-error - no types
|
|
||||||
interopDefault(import('eslint-config-turbo')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
turbo: pluginTurbo,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function typescript(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginTs, parserTs] = await Promise.all([
|
|
||||||
interopDefault(import('@typescript-eslint/eslint-plugin')),
|
|
||||||
// @ts-expect-error missing types
|
|
||||||
interopDefault(import('@typescript-eslint/parser')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
files: ['**/*.?([cm])[jt]s?(x)'],
|
|
||||||
languageOptions: {
|
|
||||||
parser: parserTs,
|
|
||||||
parserOptions: {
|
|
||||||
createDefaultProgram: false,
|
|
||||||
ecmaFeatures: {
|
|
||||||
jsx: true,
|
|
||||||
},
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
extraFileExtensions: ['.vue'],
|
|
||||||
jsxPragma: 'React',
|
|
||||||
project: './tsconfig.*.json',
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
'@typescript-eslint': pluginTs,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...pluginTs.configs['eslint-recommended'].overrides?.[0].rules,
|
|
||||||
...pluginTs.configs.strict.rules,
|
|
||||||
'@typescript-eslint/ban-ts-comment': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
'ts-check': false,
|
|
||||||
'ts-expect-error': 'allow-with-description',
|
|
||||||
'ts-ignore': 'allow-with-description',
|
|
||||||
'ts-nocheck': 'allow-with-description',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
// '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
|
|
||||||
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-empty-function': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
allow: ['arrowFunctions', 'functions', 'methods'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-namespace': 'off',
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
||||||
'@typescript-eslint/no-unused-expressions': 'off',
|
|
||||||
'@typescript-eslint/no-unused-vars': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
argsIgnorePattern: '^_',
|
|
||||||
varsIgnorePattern: '^_',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@typescript-eslint/no-use-before-define': 'off',
|
|
||||||
'@typescript-eslint/no-var-requires': 'error',
|
|
||||||
'unused-imports/no-unused-vars': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function unicorn(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginUnicorn] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-unicorn')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
plugins: {
|
|
||||||
unicorn: pluginUnicorn,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...pluginUnicorn.configs.recommended.rules,
|
|
||||||
|
|
||||||
'unicorn/better-regex': 'off',
|
|
||||||
'unicorn/consistent-destructuring': 'off',
|
|
||||||
'unicorn/consistent-function-scoping': 'off',
|
|
||||||
'unicorn/expiring-todo-comments': 'off',
|
|
||||||
'unicorn/filename-case': 'off',
|
|
||||||
'unicorn/import-style': 'off',
|
|
||||||
'unicorn/no-array-for-each': 'off',
|
|
||||||
'unicorn/no-null': 'off',
|
|
||||||
'unicorn/no-useless-undefined': 'off',
|
|
||||||
'unicorn/prefer-at': 'off',
|
|
||||||
'unicorn/prefer-dom-node-text-content': 'off',
|
|
||||||
'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
|
|
||||||
'unicorn/prefer-global-this': 'off',
|
|
||||||
'unicorn/prefer-top-level-await': 'off',
|
|
||||||
'unicorn/prevent-abbreviations': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'scripts/**/*.?([cm])[jt]s?(x)',
|
|
||||||
'internal/**/*.?([cm])[jt]s?(x)',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'unicorn/no-process-exit': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import { interopDefault } from '../util';
|
|
||||||
|
|
||||||
export async function vue(): Promise<Linter.Config[]> {
|
|
||||||
const [pluginVue, parserVue, parserTs] = await Promise.all([
|
|
||||||
interopDefault(import('eslint-plugin-vue')),
|
|
||||||
interopDefault(import('vue-eslint-parser')),
|
|
||||||
// @ts-expect-error missing types
|
|
||||||
interopDefault(import('@typescript-eslint/parser')),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
const flatEssential = pluginVue.configs?.['flat/essential'] || [];
|
|
||||||
const flatStronglyRecommended =
|
|
||||||
pluginVue.configs?.['flat/strongly-recommended'] || [];
|
|
||||||
const flatRecommended = pluginVue.configs?.['flat/recommended'] || [];
|
|
||||||
|
|
||||||
return [
|
|
||||||
...flatEssential,
|
|
||||||
...flatStronglyRecommended,
|
|
||||||
...flatRecommended,
|
|
||||||
{
|
|
||||||
files: ['**/*.vue'],
|
|
||||||
languageOptions: {
|
|
||||||
// globals: {
|
|
||||||
// computed: 'readonly',
|
|
||||||
// defineEmits: 'readonly',
|
|
||||||
// defineExpose: 'readonly',
|
|
||||||
// defineProps: 'readonly',
|
|
||||||
// onMounted: 'readonly',
|
|
||||||
// onUnmounted: 'readonly',
|
|
||||||
// reactive: 'readonly',
|
|
||||||
// ref: 'readonly',
|
|
||||||
// shallowReactive: 'readonly',
|
|
||||||
// shallowRef: 'readonly',
|
|
||||||
// toRef: 'readonly',
|
|
||||||
// toRefs: 'readonly',
|
|
||||||
// watch: 'readonly',
|
|
||||||
// watchEffect: 'readonly',
|
|
||||||
// },
|
|
||||||
parser: parserVue,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaFeatures: {
|
|
||||||
jsx: true,
|
|
||||||
},
|
|
||||||
extraFileExtensions: ['.vue'],
|
|
||||||
parser: parserTs,
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
vue: pluginVue,
|
|
||||||
},
|
|
||||||
processor: pluginVue.processors?.['.vue'],
|
|
||||||
rules: {
|
|
||||||
...pluginVue.configs?.base?.rules,
|
|
||||||
|
|
||||||
'vue/attribute-hyphenation': [
|
|
||||||
'error',
|
|
||||||
'always',
|
|
||||||
{
|
|
||||||
ignore: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'vue/attributes-order': 'off',
|
|
||||||
'vue/block-order': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: ['script', 'template', 'style'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
|
|
||||||
'vue/component-options-name-casing': ['error', 'PascalCase'],
|
|
||||||
'vue/custom-event-name-casing': ['error', 'camelCase'],
|
|
||||||
'vue/define-macros-order': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
order: [
|
|
||||||
'defineOptions',
|
|
||||||
'defineProps',
|
|
||||||
'defineEmits',
|
|
||||||
'defineSlots',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'vue/dot-location': ['error', 'property'],
|
|
||||||
'vue/dot-notation': ['error', { allowKeywords: true }],
|
|
||||||
'vue/eqeqeq': ['error', 'smart'],
|
|
||||||
'vue/html-closing-bracket-newline': 'error',
|
|
||||||
'vue/html-indent': 'off',
|
|
||||||
// 'vue/html-indent': ['error', 2],
|
|
||||||
'vue/html-quotes': ['error', 'double'],
|
|
||||||
'vue/html-self-closing': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
html: {
|
|
||||||
component: 'always',
|
|
||||||
normal: 'never',
|
|
||||||
void: 'always',
|
|
||||||
},
|
|
||||||
math: 'always',
|
|
||||||
svg: 'always',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'vue/max-attributes-per-line': 'off',
|
|
||||||
'vue/multi-word-component-names': 'off',
|
|
||||||
'vue/multiline-html-element-content-newline': 'error',
|
|
||||||
'vue/no-empty-pattern': 'error',
|
|
||||||
'vue/no-extra-parens': ['error', 'functions'],
|
|
||||||
'vue/no-irregular-whitespace': 'error',
|
|
||||||
'vue/no-loss-of-precision': 'error',
|
|
||||||
'vue/no-reserved-component-names': 'off',
|
|
||||||
'vue/no-restricted-syntax': [
|
|
||||||
'error',
|
|
||||||
'DebuggerStatement',
|
|
||||||
'LabeledStatement',
|
|
||||||
'WithStatement',
|
|
||||||
],
|
|
||||||
'vue/no-restricted-v-bind': ['error', '/^v-/'],
|
|
||||||
'vue/no-sparse-arrays': 'error',
|
|
||||||
'vue/no-unused-refs': 'error',
|
|
||||||
'vue/no-useless-v-bind': 'error',
|
|
||||||
'vue/object-shorthand': [
|
|
||||||
'error',
|
|
||||||
'always',
|
|
||||||
{
|
|
||||||
avoidQuotes: true,
|
|
||||||
ignoreConstructors: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'vue/one-component-per-file': 'error',
|
|
||||||
'vue/prefer-import-from-vue': 'error',
|
|
||||||
'vue/prefer-separate-static-class': 'error',
|
|
||||||
'vue/prefer-template': 'error',
|
|
||||||
'vue/prop-name-casing': ['error', 'camelCase'],
|
|
||||||
'vue/require-default-prop': 'error',
|
|
||||||
'vue/require-explicit-emits': 'error',
|
|
||||||
'vue/require-prop-types': 'off',
|
|
||||||
'vue/singleline-html-element-content-newline': 'off',
|
|
||||||
'vue/space-infix-ops': 'error',
|
|
||||||
'vue/space-unary-ops': ['error', { nonwords: false, words: true }],
|
|
||||||
'vue/v-on-event-hyphenation': [
|
|
||||||
'error',
|
|
||||||
'always',
|
|
||||||
{
|
|
||||||
autofix: true,
|
|
||||||
ignore: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
const restrictedImportIgnores = [
|
|
||||||
'**/vite.config.mts',
|
|
||||||
'**/tailwind.config.mjs',
|
|
||||||
'**/postcss.config.mjs',
|
|
||||||
];
|
|
||||||
|
|
||||||
const customConfig: Linter.Config[] = [
|
|
||||||
// shadcn-ui 内部组件是自动生成的,不做太多限制
|
|
||||||
{
|
|
||||||
files: ['packages/@core/ui-kit/shadcn-ui/**/**'],
|
|
||||||
rules: {
|
|
||||||
'vue/require-default-prop': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'app/**',
|
|
||||||
'packages/effects/**/**',
|
|
||||||
'packages/utils/**/**',
|
|
||||||
'packages/types/**/**',
|
|
||||||
'packages/locales/**/**',
|
|
||||||
],
|
|
||||||
ignores: restrictedImportIgnores,
|
|
||||||
rules: {
|
|
||||||
'perfectionist/sort-interfaces': 'off',
|
|
||||||
'perfectionist/sort-objects': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/**.vue'],
|
|
||||||
ignores: restrictedImportIgnores,
|
|
||||||
rules: {
|
|
||||||
'perfectionist/sort-objects': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// apps内部的一些基础规则
|
|
||||||
files: ['app/**'],
|
|
||||||
ignores: restrictedImportIgnores,
|
|
||||||
rules: {
|
|
||||||
'no-restricted-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
patterns: [
|
|
||||||
{
|
|
||||||
group: ['#/api/*'],
|
|
||||||
message:
|
|
||||||
'The #/api package cannot be imported, please use the @core package itself',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
group: ['#/layouts/*'],
|
|
||||||
message:
|
|
||||||
'The #/layouts package cannot be imported, please use the @core package itself',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
group: ['#/locales/*'],
|
|
||||||
message:
|
|
||||||
'The #/locales package cannot be imported, please use the @core package itself',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
group: ['#/stores/*'],
|
|
||||||
message:
|
|
||||||
'The #/stores package cannot be imported, please use the @core package itself',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'perfectionist/sort-interfaces': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// @core内部组件,不能引入@aiflowy/* 里面的包
|
|
||||||
files: ['packages/@core/**/**'],
|
|
||||||
ignores: restrictedImportIgnores,
|
|
||||||
rules: {
|
|
||||||
'no-restricted-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
patterns: [
|
|
||||||
{
|
|
||||||
group: ['@aiflowy/*'],
|
|
||||||
message:
|
|
||||||
'The @core package cannot import the @aiflowy package, please use the @core package itself',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// @core/shared内部组件,不能引入@aiflowy/* 或者 @aiflowy-core/* 里面的包
|
|
||||||
files: ['packages/@core/base/**/**'],
|
|
||||||
ignores: restrictedImportIgnores,
|
|
||||||
rules: {
|
|
||||||
'no-restricted-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
patterns: [
|
|
||||||
{
|
|
||||||
group: ['@aiflowy/*', '@aiflowy-core/*'],
|
|
||||||
message:
|
|
||||||
'The @aiflowy-core/shared package cannot import the @aiflowy package, please use the @core/shared package itself',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
// 不能引入@aiflowy/*里面的包
|
|
||||||
files: [
|
|
||||||
'packages/types/**/**',
|
|
||||||
'packages/utils/**/**',
|
|
||||||
'packages/icons/**/**',
|
|
||||||
'packages/constants/**/**',
|
|
||||||
'packages/styles/**/**',
|
|
||||||
'packages/stores/**/**',
|
|
||||||
'packages/preferences/**/**',
|
|
||||||
'packages/locales/**/**',
|
|
||||||
],
|
|
||||||
ignores: restrictedImportIgnores,
|
|
||||||
rules: {
|
|
||||||
'no-restricted-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
patterns: [
|
|
||||||
{
|
|
||||||
group: ['@aiflowy/*'],
|
|
||||||
message:
|
|
||||||
'The @aiflowy package cannot be imported, please use the @core package itself',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/**/playwright.config.ts'],
|
|
||||||
rules: {
|
|
||||||
'n/prefer-global/buffer': 'off',
|
|
||||||
'n/prefer-global/process': 'off',
|
|
||||||
'no-console': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['internal/**/**', 'scripts/**/**'],
|
|
||||||
rules: {
|
|
||||||
'no-console': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export { customConfig };
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
import type { Linter } from 'eslint';
|
|
||||||
|
|
||||||
import {
|
|
||||||
command,
|
|
||||||
comments,
|
|
||||||
disableds,
|
|
||||||
ignores,
|
|
||||||
importPluginConfig,
|
|
||||||
javascript,
|
|
||||||
jsdoc,
|
|
||||||
jsonc,
|
|
||||||
node,
|
|
||||||
perfectionist,
|
|
||||||
prettier,
|
|
||||||
regexp,
|
|
||||||
test,
|
|
||||||
turbo,
|
|
||||||
typescript,
|
|
||||||
unicorn,
|
|
||||||
vue,
|
|
||||||
} from './configs';
|
|
||||||
import { customConfig } from './custom-config';
|
|
||||||
|
|
||||||
type FlatConfig = Linter.Config;
|
|
||||||
|
|
||||||
type FlatConfigPromise =
|
|
||||||
| FlatConfig
|
|
||||||
| FlatConfig[]
|
|
||||||
| Promise<FlatConfig>
|
|
||||||
| Promise<FlatConfig[]>;
|
|
||||||
|
|
||||||
async function defineConfig(config: FlatConfig[] = []) {
|
|
||||||
const configs: FlatConfigPromise[] = [
|
|
||||||
vue(),
|
|
||||||
javascript(),
|
|
||||||
ignores(),
|
|
||||||
prettier(),
|
|
||||||
typescript(),
|
|
||||||
jsonc(),
|
|
||||||
disableds(),
|
|
||||||
importPluginConfig(),
|
|
||||||
node(),
|
|
||||||
perfectionist(),
|
|
||||||
comments(),
|
|
||||||
jsdoc(),
|
|
||||||
unicorn(),
|
|
||||||
test(),
|
|
||||||
regexp(),
|
|
||||||
command(),
|
|
||||||
turbo(),
|
|
||||||
...customConfig,
|
|
||||||
...config,
|
|
||||||
];
|
|
||||||
|
|
||||||
const resolved = await Promise.all(configs);
|
|
||||||
|
|
||||||
return resolved.flat();
|
|
||||||
}
|
|
||||||
|
|
||||||
export { defineConfig };
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
export type Awaitable<T> = Promise<T> | T;
|
|
||||||
|
|
||||||
export async function interopDefault<T>(
|
|
||||||
m: Awaitable<T>,
|
|
||||||
): Promise<T extends { default: infer U } ? U : T> {
|
|
||||||
const resolved = await m;
|
|
||||||
return (resolved as any).default || resolved;
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"extends": "@aiflowy/tsconfig/node.json",
|
|
||||||
"include": ["src"],
|
|
||||||
"exclude": ["node_modules"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
export default {
|
|
||||||
endOfLine: 'auto',
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json5'],
|
|
||||||
options: {
|
|
||||||
quoteProps: 'preserve',
|
|
||||||
singleQuote: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
plugins: ['prettier-plugin-tailwindcss'],
|
|
||||||
printWidth: 80,
|
|
||||||
proseWrap: 'never',
|
|
||||||
semi: true,
|
|
||||||
singleQuote: true,
|
|
||||||
trailingComma: 'all',
|
|
||||||
};
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/prettier-config",
|
|
||||||
"version": "5.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/lint-configs/prettier-config"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./index.mjs",
|
|
||||||
"module": "./index.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"default": "./index.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"prettier": "catalog:",
|
|
||||||
"prettier-plugin-tailwindcss": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,141 +0,0 @@
|
||||||
export default {
|
|
||||||
extends: ['stylelint-config-standard', 'stylelint-config-recess-order'],
|
|
||||||
ignoreFiles: [
|
|
||||||
'**/*.js',
|
|
||||||
'**/*.jsx',
|
|
||||||
'**/*.tsx',
|
|
||||||
'**/*.ts',
|
|
||||||
'**/*.json',
|
|
||||||
'**/*.md',
|
|
||||||
],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
customSyntax: 'postcss-html',
|
|
||||||
files: ['*.(html|vue)', '**/*.(html|vue)'],
|
|
||||||
rules: {
|
|
||||||
'selector-pseudo-class-no-unknown': [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
ignorePseudoClasses: ['global', 'deep'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'selector-pseudo-element-no-unknown': [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
customSyntax: 'postcss-scss',
|
|
||||||
extends: [
|
|
||||||
'stylelint-config-recommended-scss',
|
|
||||||
'stylelint-config-recommended-vue/scss',
|
|
||||||
],
|
|
||||||
files: ['*.scss', '**/*.scss'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
'stylelint-order',
|
|
||||||
'@stylistic/stylelint-plugin',
|
|
||||||
'stylelint-prettier',
|
|
||||||
'stylelint-scss',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'at-rule-no-deprecated': null,
|
|
||||||
'at-rule-no-unknown': [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
ignoreAtRules: [
|
|
||||||
'extends',
|
|
||||||
'ignores',
|
|
||||||
'include',
|
|
||||||
'mixin',
|
|
||||||
'if',
|
|
||||||
'else',
|
|
||||||
'media',
|
|
||||||
'for',
|
|
||||||
'at-root',
|
|
||||||
'tailwind',
|
|
||||||
'apply',
|
|
||||||
'variants',
|
|
||||||
'responsive',
|
|
||||||
'screen',
|
|
||||||
'function',
|
|
||||||
'each',
|
|
||||||
'use',
|
|
||||||
'forward',
|
|
||||||
'return',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'font-family-no-missing-generic-family-keyword': null,
|
|
||||||
'function-no-unknown': null,
|
|
||||||
'import-notation': null,
|
|
||||||
'media-feature-range-notation': null,
|
|
||||||
'named-grid-areas-no-invalid': null,
|
|
||||||
'no-descending-specificity': null,
|
|
||||||
'no-empty-source': null,
|
|
||||||
'order/order': [
|
|
||||||
[
|
|
||||||
'dollar-variables',
|
|
||||||
'custom-properties',
|
|
||||||
'at-rules',
|
|
||||||
'declarations',
|
|
||||||
{
|
|
||||||
name: 'supports',
|
|
||||||
type: 'at-rule',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'media',
|
|
||||||
type: 'at-rule',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'include',
|
|
||||||
type: 'at-rule',
|
|
||||||
},
|
|
||||||
'rules',
|
|
||||||
],
|
|
||||||
{ severity: 'error' },
|
|
||||||
],
|
|
||||||
'prettier/prettier': true,
|
|
||||||
'rule-empty-line-before': [
|
|
||||||
'always',
|
|
||||||
{
|
|
||||||
ignore: ['after-comment', 'first-nested'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'scss/at-rule-no-unknown': [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
ignoreAtRules: [
|
|
||||||
'extends',
|
|
||||||
'ignores',
|
|
||||||
'include',
|
|
||||||
'mixin',
|
|
||||||
'if',
|
|
||||||
'else',
|
|
||||||
'media',
|
|
||||||
'for',
|
|
||||||
'at-root',
|
|
||||||
'tailwind',
|
|
||||||
'apply',
|
|
||||||
'variants',
|
|
||||||
'responsive',
|
|
||||||
'screen',
|
|
||||||
'function',
|
|
||||||
'each',
|
|
||||||
'use',
|
|
||||||
'forward',
|
|
||||||
'return',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'scss/operator-no-newline-after': null,
|
|
||||||
'selector-class-pattern':
|
|
||||||
'^(?:(?:o|c|u|t|s|is|has|_|js|qa)-)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:[.+])?$',
|
|
||||||
|
|
||||||
'selector-not-notation': null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/stylelint-config",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/lint-configs/stylelint-config"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./index.mjs",
|
|
||||||
"module": "./index.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": "./index.mjs",
|
|
||||||
"default": "./index.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@stylistic/stylelint-plugin": "catalog:",
|
|
||||||
"stylelint-config-recess-order": "catalog:",
|
|
||||||
"stylelint-scss": "catalog:"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"postcss": "catalog:",
|
|
||||||
"postcss-html": "catalog:",
|
|
||||||
"postcss-scss": "catalog:",
|
|
||||||
"prettier": "catalog:",
|
|
||||||
"stylelint": "catalog:",
|
|
||||||
"stylelint-config-recommended": "catalog:",
|
|
||||||
"stylelint-config-recommended-scss": "catalog:",
|
|
||||||
"stylelint-config-recommended-vue": "catalog:",
|
|
||||||
"stylelint-config-standard": "catalog:",
|
|
||||||
"stylelint-order": "catalog:",
|
|
||||||
"stylelint-prettier": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import { defineBuildConfig } from 'unbuild';
|
|
||||||
|
|
||||||
export default defineBuildConfig({
|
|
||||||
clean: true,
|
|
||||||
declaration: true,
|
|
||||||
entries: ['src/index'],
|
|
||||||
});
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/node-utils",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/node-utils"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"stub": "pnpm unbuild --stub"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./dist/index.mjs",
|
|
||||||
"module": "./dist/index.mjs",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./src/index.ts",
|
|
||||||
"import": "./dist/index.mjs",
|
|
||||||
"default": "./dist/index.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@changesets/git": "catalog:",
|
|
||||||
"@manypkg/get-packages": "catalog:",
|
|
||||||
"chalk": "catalog:",
|
|
||||||
"consola": "catalog:",
|
|
||||||
"dayjs": "catalog:",
|
|
||||||
"execa": "catalog:",
|
|
||||||
"find-up": "catalog:",
|
|
||||||
"ora": "catalog:",
|
|
||||||
"pkg-types": "catalog:",
|
|
||||||
"prettier": "catalog:",
|
|
||||||
"rimraf": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
import { createHash } from 'node:crypto';
|
|
||||||
|
|
||||||
import { describe, expect, it } from 'vitest';
|
|
||||||
|
|
||||||
import { generatorContentHash } from '../hash';
|
|
||||||
|
|
||||||
describe('generatorContentHash', () => {
|
|
||||||
it('should generate an MD5 hash for the content', () => {
|
|
||||||
const content = 'example content';
|
|
||||||
const expectedHash = createHash('md5')
|
|
||||||
.update(content, 'utf8')
|
|
||||||
.digest('hex');
|
|
||||||
const actualHash = generatorContentHash(content);
|
|
||||||
expect(actualHash).toBe(expectedHash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should generate an MD5 hash with specified length', () => {
|
|
||||||
const content = 'example content';
|
|
||||||
const hashLength = 10;
|
|
||||||
const generatedHash = generatorContentHash(content, hashLength);
|
|
||||||
expect(generatedHash).toHaveLength(hashLength);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly generate the hash with specified length', () => {
|
|
||||||
const content = 'example content';
|
|
||||||
const hashLength = 8;
|
|
||||||
const expectedHash = createHash('md5')
|
|
||||||
.update(content, 'utf8')
|
|
||||||
.digest('hex')
|
|
||||||
.slice(0, hashLength);
|
|
||||||
const generatedHash = generatorContentHash(content, hashLength);
|
|
||||||
expect(generatedHash).toBe(expectedHash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return full hash if hash length parameter is not provided', () => {
|
|
||||||
const content = 'example content';
|
|
||||||
const expectedHash = createHash('md5')
|
|
||||||
.update(content, 'utf8')
|
|
||||||
.digest('hex');
|
|
||||||
const actualHash = generatorContentHash(content);
|
|
||||||
expect(actualHash).toBe(expectedHash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle empty content', () => {
|
|
||||||
const content = '';
|
|
||||||
const expectedHash = createHash('md5')
|
|
||||||
.update(content, 'utf8')
|
|
||||||
.digest('hex');
|
|
||||||
const actualHash = generatorContentHash(content);
|
|
||||||
expect(actualHash).toBe(expectedHash);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
// pathUtils.test.ts
|
|
||||||
|
|
||||||
import { describe, expect, it } from 'vitest';
|
|
||||||
|
|
||||||
import { toPosixPath } from '../path';
|
|
||||||
|
|
||||||
describe('toPosixPath', () => {
|
|
||||||
// 测试 Windows 风格路径到 POSIX 风格路径的转换
|
|
||||||
it('converts Windows-style paths to POSIX paths', () => {
|
|
||||||
const windowsPath = String.raw`C:\Users\Example\file.txt`;
|
|
||||||
const expectedPosixPath = 'C:/Users/Example/file.txt';
|
|
||||||
expect(toPosixPath(windowsPath)).toBe(expectedPosixPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 确认 POSIX 风格路径不会被改变
|
|
||||||
it('leaves POSIX-style paths unchanged', () => {
|
|
||||||
const posixPath = '/home/user/file.txt';
|
|
||||||
expect(toPosixPath(posixPath)).toBe(posixPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试带有多个分隔符的路径
|
|
||||||
it('converts paths with mixed separators', () => {
|
|
||||||
const mixedPath = String.raw`C:/Users\Example\file.txt`;
|
|
||||||
const expectedPosixPath = 'C:/Users/Example/file.txt';
|
|
||||||
expect(toPosixPath(mixedPath)).toBe(expectedPosixPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试空字符串
|
|
||||||
it('handles empty strings', () => {
|
|
||||||
const emptyPath = '';
|
|
||||||
expect(toPosixPath(emptyPath)).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试仅包含分隔符的路径
|
|
||||||
it('handles path with only separators', () => {
|
|
||||||
const separatorsPath = '\\\\\\';
|
|
||||||
const expectedPosixPath = '///';
|
|
||||||
expect(toPosixPath(separatorsPath)).toBe(expectedPosixPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试不包含任何分隔符的路径
|
|
||||||
it('handles path without separators', () => {
|
|
||||||
const noSeparatorPath = 'file.txt';
|
|
||||||
expect(toPosixPath(noSeparatorPath)).toBe('file.txt');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试以分隔符结尾的路径
|
|
||||||
it('handles path ending with a separator', () => {
|
|
||||||
const endingSeparatorPath = 'C:\\Users\\Example\\';
|
|
||||||
const expectedPosixPath = 'C:/Users/Example/';
|
|
||||||
expect(toPosixPath(endingSeparatorPath)).toBe(expectedPosixPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试以分隔符开头的路径
|
|
||||||
it('handles path starting with a separator', () => {
|
|
||||||
const startingSeparatorPath = String.raw`\Users\Example`;
|
|
||||||
const expectedPosixPath = '/Users/Example';
|
|
||||||
expect(toPosixPath(startingSeparatorPath)).toBe(expectedPosixPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 测试包含非法字符的路径
|
|
||||||
it('handles path with invalid characters', () => {
|
|
||||||
const invalidCharsPath = String.raw`C:\Us*?ers\Ex<ample>|file.txt`;
|
|
||||||
const expectedPosixPath = 'C:/Us*?ers/Ex<ample>|file.txt';
|
|
||||||
expect(toPosixPath(invalidCharsPath)).toBe(expectedPosixPath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
enum UNICODE {
|
|
||||||
FAILURE = '\u2716', // ✖
|
|
||||||
SUCCESS = '\u2714', // ✔
|
|
||||||
}
|
|
||||||
|
|
||||||
export { UNICODE };
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import timezone from 'dayjs/plugin/timezone';
|
|
||||||
import utc from 'dayjs/plugin/utc';
|
|
||||||
|
|
||||||
dayjs.extend(utc);
|
|
||||||
dayjs.extend(timezone);
|
|
||||||
|
|
||||||
dayjs.tz.setDefault('Asia/Shanghai');
|
|
||||||
|
|
||||||
const dateUtil = dayjs;
|
|
||||||
|
|
||||||
export { dateUtil };
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
import { promises as fs } from 'node:fs';
|
|
||||||
import { dirname } from 'node:path';
|
|
||||||
|
|
||||||
export async function outputJSON(
|
|
||||||
filePath: string,
|
|
||||||
data: any,
|
|
||||||
spaces: number = 2,
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const dir = dirname(filePath);
|
|
||||||
await fs.mkdir(dir, { recursive: true });
|
|
||||||
const jsonData = JSON.stringify(data, null, spaces);
|
|
||||||
await fs.writeFile(filePath, jsonData, 'utf8');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error writing JSON file:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function ensureFile(filePath: string) {
|
|
||||||
try {
|
|
||||||
const dir = dirname(filePath);
|
|
||||||
await fs.mkdir(dir, { recursive: true });
|
|
||||||
await fs.writeFile(filePath, '', { flag: 'a' });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error ensuring file:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function readJSON(filePath: string) {
|
|
||||||
try {
|
|
||||||
const data = await fs.readFile(filePath, 'utf8');
|
|
||||||
return JSON.parse(data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error reading JSON file:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import path from 'node:path';
|
|
||||||
|
|
||||||
import { execa } from 'execa';
|
|
||||||
|
|
||||||
export * from '@changesets/git';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取暂存区文件
|
|
||||||
*/
|
|
||||||
async function getStagedFiles(): Promise<string[]> {
|
|
||||||
try {
|
|
||||||
const { stdout } = await execa('git', [
|
|
||||||
'-c',
|
|
||||||
'submodule.recurse=false',
|
|
||||||
'diff',
|
|
||||||
'--staged',
|
|
||||||
'--diff-filter=ACMR',
|
|
||||||
'--name-only',
|
|
||||||
'--ignore-submodules',
|
|
||||||
'-z',
|
|
||||||
]);
|
|
||||||
|
|
||||||
let changedList = stdout ? stdout.replace(/\0$/, '').split('\0') : [];
|
|
||||||
changedList = changedList.map((item) => path.resolve(process.cwd(), item));
|
|
||||||
const changedSet = new Set(changedList);
|
|
||||||
changedSet.delete('');
|
|
||||||
return [...changedSet];
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to get staged files:', error);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { getStagedFiles };
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { createHash } from 'node:crypto';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生产基于内容的 hash,可自定义长度
|
|
||||||
* @param content
|
|
||||||
* @param hashLSize
|
|
||||||
*/
|
|
||||||
function generatorContentHash(content: string, hashLSize?: number) {
|
|
||||||
const hash = createHash('md5').update(content, 'utf8').digest('hex');
|
|
||||||
|
|
||||||
if (hashLSize) {
|
|
||||||
return hash.slice(0, hashLSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { generatorContentHash };
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
export * from './constants';
|
|
||||||
export * from './date';
|
|
||||||
export * from './fs';
|
|
||||||
export * from './git';
|
|
||||||
export { getStagedFiles, add as gitAdd } from './git';
|
|
||||||
export { generatorContentHash } from './hash';
|
|
||||||
export * from './monorepo';
|
|
||||||
export { toPosixPath } from './path';
|
|
||||||
export { prettierFormat } from './prettier';
|
|
||||||
export * from './spinner';
|
|
||||||
export type { Package } from '@manypkg/get-packages';
|
|
||||||
export { default as colors } from 'chalk';
|
|
||||||
export { consola } from 'consola';
|
|
||||||
export * from 'execa';
|
|
||||||
|
|
||||||
export { default as fs } from 'node:fs/promises';
|
|
||||||
|
|
||||||
export { type PackageJson, readPackageJSON } from 'pkg-types';
|
|
||||||
export { rimraf } from 'rimraf';
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
import { dirname } from 'node:path';
|
|
||||||
|
|
||||||
import {
|
|
||||||
getPackages as getPackagesFunc,
|
|
||||||
getPackagesSync as getPackagesSyncFunc,
|
|
||||||
} from '@manypkg/get-packages';
|
|
||||||
import { findUpSync } from 'find-up';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找大仓的根目录
|
|
||||||
* @param cwd
|
|
||||||
*/
|
|
||||||
function findMonorepoRoot(cwd: string = process.cwd()) {
|
|
||||||
const lockFile = findUpSync('pnpm-lock.yaml', {
|
|
||||||
cwd,
|
|
||||||
type: 'file',
|
|
||||||
});
|
|
||||||
return dirname(lockFile || '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取大仓的所有包
|
|
||||||
*/
|
|
||||||
function getPackagesSync() {
|
|
||||||
const root = findMonorepoRoot();
|
|
||||||
return getPackagesSyncFunc(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取大仓的所有包
|
|
||||||
*/
|
|
||||||
async function getPackages() {
|
|
||||||
const root = findMonorepoRoot();
|
|
||||||
|
|
||||||
return await getPackagesFunc(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取大仓指定的包
|
|
||||||
*/
|
|
||||||
async function getPackage(pkgName: string) {
|
|
||||||
const { packages } = await getPackages();
|
|
||||||
return packages.find((pkg) => pkg.packageJson.name === pkgName);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { findMonorepoRoot, getPackage, getPackages, getPackagesSync };
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
import { posix } from 'node:path';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将给定的文件路径转换为 POSIX 风格。
|
|
||||||
* @param {string} pathname - 原始文件路径。
|
|
||||||
*/
|
|
||||||
function toPosixPath(pathname: string) {
|
|
||||||
return pathname.split(`\\`).join(posix.sep);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { toPosixPath };
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import fs from 'node:fs/promises';
|
|
||||||
|
|
||||||
import { format, getFileInfo, resolveConfig } from 'prettier';
|
|
||||||
|
|
||||||
async function prettierFormat(filepath: string) {
|
|
||||||
const prettierOptions = await resolveConfig(filepath, {});
|
|
||||||
|
|
||||||
const fileInfo = await getFileInfo(filepath);
|
|
||||||
|
|
||||||
const input = await fs.readFile(filepath, 'utf8');
|
|
||||||
const output = await format(input, {
|
|
||||||
...prettierOptions,
|
|
||||||
parser: fileInfo.inferredParser as any,
|
|
||||||
});
|
|
||||||
if (output !== input) {
|
|
||||||
await fs.writeFile(filepath, output, 'utf8');
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { prettierFormat };
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
import type { Ora } from 'ora';
|
|
||||||
|
|
||||||
import ora from 'ora';
|
|
||||||
|
|
||||||
interface SpinnerOptions {
|
|
||||||
failedText?: string;
|
|
||||||
successText?: string;
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
export async function spinner<T>(
|
|
||||||
{ failedText, successText, title }: SpinnerOptions,
|
|
||||||
callback: () => Promise<T>,
|
|
||||||
): Promise<T> {
|
|
||||||
const loading: Ora = ora(title).start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await callback();
|
|
||||||
loading.succeed(successText || 'Success!');
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
loading.fail(failedText || 'Failed!');
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
loading.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"extends": "@aiflowy/tsconfig/node.json",
|
|
||||||
"include": ["src"],
|
|
||||||
"exclude": ["node_modules"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import { defineBuildConfig } from 'unbuild';
|
|
||||||
|
|
||||||
export default defineBuildConfig({
|
|
||||||
clean: true,
|
|
||||||
declaration: true,
|
|
||||||
entries: ['src/index', './src/postcss.config'],
|
|
||||||
rollup: {
|
|
||||||
emitCJS: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/tailwind-config",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/tailwind-config"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"stub": "pnpm unbuild --stub"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./dist/index.mjs",
|
|
||||||
"module": "./dist/index.mjs",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"typesVersions": {
|
|
||||||
"*": {
|
|
||||||
"*": [
|
|
||||||
"./dist/*",
|
|
||||||
"./*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./src/index.ts",
|
|
||||||
"import": "./dist/index.mjs",
|
|
||||||
"require": "./dist/index.cjs"
|
|
||||||
},
|
|
||||||
"./postcss": {
|
|
||||||
"types": "./src/postcss.config.ts",
|
|
||||||
"import": "./dist/postcss.config.mjs",
|
|
||||||
"require": "./dist/postcss.config.cjs",
|
|
||||||
"default": "./dist/postcss.config.mjs"
|
|
||||||
},
|
|
||||||
"./*": "./*"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"tailwindcss": "^3.4.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@iconify/json": "catalog:",
|
|
||||||
"@iconify/tailwind": "catalog:",
|
|
||||||
"@manypkg/get-packages": "catalog:",
|
|
||||||
"@tailwindcss/nesting": "catalog:",
|
|
||||||
"@tailwindcss/typography": "catalog:",
|
|
||||||
"autoprefixer": "catalog:",
|
|
||||||
"cssnano": "catalog:",
|
|
||||||
"postcss": "catalog:",
|
|
||||||
"postcss-antd-fixes": "catalog:",
|
|
||||||
"postcss-import": "catalog:",
|
|
||||||
"postcss-preset-env": "catalog:",
|
|
||||||
"tailwindcss": "catalog:",
|
|
||||||
"tailwindcss-animate": "catalog:"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/postcss-import": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,266 +0,0 @@
|
||||||
import type { Config } from 'tailwindcss';
|
|
||||||
|
|
||||||
import path from 'node:path';
|
|
||||||
|
|
||||||
import { addDynamicIconSelectors } from '@iconify/tailwind';
|
|
||||||
import { getPackagesSync } from '@manypkg/get-packages';
|
|
||||||
import typographyPlugin from '@tailwindcss/typography';
|
|
||||||
import animate from 'tailwindcss-animate';
|
|
||||||
|
|
||||||
import { enterAnimationPlugin } from './plugins/entry';
|
|
||||||
|
|
||||||
// import defaultTheme from 'tailwindcss/defaultTheme';
|
|
||||||
|
|
||||||
const { packages } = getPackagesSync(process.cwd());
|
|
||||||
|
|
||||||
const tailwindPackages: string[] = [];
|
|
||||||
|
|
||||||
packages.forEach((pkg) => {
|
|
||||||
// apps目录下和 @aiflowy-core/tailwind-ui 包需要使用到 tailwindcss ui
|
|
||||||
// if (fs.existsSync(path.join(pkg.dir, 'tailwind.config.mjs'))) {
|
|
||||||
tailwindPackages.push(pkg.dir);
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
|
|
||||||
const shadcnUiColors = {
|
|
||||||
accent: {
|
|
||||||
DEFAULT: 'hsl(var(--accent))',
|
|
||||||
foreground: 'hsl(var(--accent-foreground))',
|
|
||||||
hover: 'hsl(var(--accent-hover))',
|
|
||||||
lighter: 'has(val(--accent-lighter))',
|
|
||||||
},
|
|
||||||
background: {
|
|
||||||
deep: 'hsl(var(--background-deep))',
|
|
||||||
DEFAULT: 'hsl(var(--background))',
|
|
||||||
},
|
|
||||||
border: {
|
|
||||||
DEFAULT: 'hsl(var(--border))',
|
|
||||||
},
|
|
||||||
card: {
|
|
||||||
DEFAULT: 'hsl(var(--card))',
|
|
||||||
foreground: 'hsl(var(--card-foreground))',
|
|
||||||
},
|
|
||||||
destructive: {
|
|
||||||
...createColorsPalette('destructive'),
|
|
||||||
DEFAULT: 'hsl(var(--destructive))',
|
|
||||||
},
|
|
||||||
|
|
||||||
foreground: {
|
|
||||||
DEFAULT: 'hsl(var(--foreground))',
|
|
||||||
},
|
|
||||||
|
|
||||||
input: {
|
|
||||||
background: 'hsl(var(--input-background))',
|
|
||||||
DEFAULT: 'hsl(var(--input))',
|
|
||||||
},
|
|
||||||
muted: {
|
|
||||||
DEFAULT: 'hsl(var(--muted))',
|
|
||||||
foreground: 'hsl(var(--muted-foreground))',
|
|
||||||
},
|
|
||||||
popover: {
|
|
||||||
DEFAULT: 'hsl(var(--popover))',
|
|
||||||
foreground: 'hsl(var(--popover-foreground))',
|
|
||||||
},
|
|
||||||
primary: {
|
|
||||||
...createColorsPalette('primary'),
|
|
||||||
DEFAULT: 'hsl(var(--primary))',
|
|
||||||
},
|
|
||||||
|
|
||||||
ring: 'hsl(var(--ring))',
|
|
||||||
secondary: {
|
|
||||||
DEFAULT: 'hsl(var(--secondary))',
|
|
||||||
desc: 'hsl(var(--secondary-desc))',
|
|
||||||
foreground: 'hsl(var(--secondary-foreground))',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const customColors = {
|
|
||||||
green: {
|
|
||||||
...createColorsPalette('green'),
|
|
||||||
foreground: 'hsl(var(--success-foreground))',
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
DEFAULT: 'hsl(var(--header))',
|
|
||||||
},
|
|
||||||
heavy: {
|
|
||||||
DEFAULT: 'hsl(var(--heavy))',
|
|
||||||
foreground: 'hsl(var(--heavy-foreground))',
|
|
||||||
},
|
|
||||||
main: {
|
|
||||||
DEFAULT: 'hsl(var(--main))',
|
|
||||||
},
|
|
||||||
overlay: {
|
|
||||||
content: 'hsl(var(--overlay-content))',
|
|
||||||
DEFAULT: 'hsl(var(--overlay))',
|
|
||||||
},
|
|
||||||
red: {
|
|
||||||
...createColorsPalette('red'),
|
|
||||||
foreground: 'hsl(var(--destructive-foreground))',
|
|
||||||
},
|
|
||||||
sidebar: {
|
|
||||||
deep: 'hsl(var(--sidebar-deep))',
|
|
||||||
DEFAULT: 'hsl(var(--sidebar))',
|
|
||||||
},
|
|
||||||
success: {
|
|
||||||
...createColorsPalette('success'),
|
|
||||||
DEFAULT: 'hsl(var(--success))',
|
|
||||||
},
|
|
||||||
warning: {
|
|
||||||
...createColorsPalette('warning'),
|
|
||||||
DEFAULT: 'hsl(var(--warning))',
|
|
||||||
},
|
|
||||||
yellow: {
|
|
||||||
...createColorsPalette('yellow'),
|
|
||||||
foreground: 'hsl(var(--warning-foreground))',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
content: [
|
|
||||||
'./index.html',
|
|
||||||
...tailwindPackages.map((item) =>
|
|
||||||
path.join(item, 'src/**/*.{vue,js,ts,jsx,tsx,svelte,astro,html}'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
darkMode: 'selector',
|
|
||||||
plugins: [
|
|
||||||
animate,
|
|
||||||
typographyPlugin,
|
|
||||||
addDynamicIconSelectors(),
|
|
||||||
enterAnimationPlugin,
|
|
||||||
],
|
|
||||||
prefix: '',
|
|
||||||
theme: {
|
|
||||||
container: {
|
|
||||||
center: true,
|
|
||||||
padding: '2rem',
|
|
||||||
screens: {
|
|
||||||
'2xl': '1400px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extend: {
|
|
||||||
animation: {
|
|
||||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
|
||||||
'accordion-up': 'accordion-up 0.2s ease-out',
|
|
||||||
'collapsible-down': 'collapsible-down 0.2s ease-in-out',
|
|
||||||
'collapsible-up': 'collapsible-up 0.2s ease-in-out',
|
|
||||||
float: 'float 5s linear 0ms infinite',
|
|
||||||
},
|
|
||||||
|
|
||||||
animationDuration: {
|
|
||||||
'2000': '2000ms',
|
|
||||||
'3000': '3000ms',
|
|
||||||
},
|
|
||||||
borderRadius: {
|
|
||||||
lg: 'var(--radius)',
|
|
||||||
md: 'calc(var(--radius) - 2px)',
|
|
||||||
sm: 'calc(var(--radius) - 4px)',
|
|
||||||
xl: 'calc(var(--radius) + 4px)',
|
|
||||||
},
|
|
||||||
boxShadow: {
|
|
||||||
float: `0 6px 16px 0 rgb(0 0 0 / 8%),
|
|
||||||
0 3px 6px -4px rgb(0 0 0 / 12%),
|
|
||||||
0 9px 28px 8px rgb(0 0 0 / 5%)`,
|
|
||||||
},
|
|
||||||
colors: {
|
|
||||||
...customColors,
|
|
||||||
...shadcnUiColors,
|
|
||||||
},
|
|
||||||
fontFamily: {
|
|
||||||
sans: [
|
|
||||||
'var(--font-family)',
|
|
||||||
// ...defaultTheme.fontFamily.sans
|
|
||||||
],
|
|
||||||
},
|
|
||||||
keyframes: {
|
|
||||||
'accordion-down': {
|
|
||||||
from: { height: '0' },
|
|
||||||
to: { height: 'var(--reka-accordion-content-height)' },
|
|
||||||
},
|
|
||||||
'accordion-up': {
|
|
||||||
from: { height: 'var(--reka-accordion-content-height)' },
|
|
||||||
to: { height: '0' },
|
|
||||||
},
|
|
||||||
'collapsible-down': {
|
|
||||||
from: { height: '0' },
|
|
||||||
to: { height: 'var(--reka-collapsible-content-height)' },
|
|
||||||
},
|
|
||||||
'collapsible-up': {
|
|
||||||
from: { height: 'var(--reka-collapsible-content-height)' },
|
|
||||||
to: { height: '0' },
|
|
||||||
},
|
|
||||||
float: {
|
|
||||||
'0%': { transform: 'translateY(0)' },
|
|
||||||
'50%': { transform: 'translateY(-20px)' },
|
|
||||||
'100%': { transform: 'translateY(0)' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
zIndex: {
|
|
||||||
'100': '100',
|
|
||||||
'1000': '1000',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
safelist: ['dark'],
|
|
||||||
} as Config;
|
|
||||||
|
|
||||||
function createColorsPalette(name: string) {
|
|
||||||
// backgroundLightest: '#EFF6FF', // Tailwind CSS 默认的 `blue-50`
|
|
||||||
// backgroundLighter: '#DBEAFE', // Tailwind CSS 默认的 `blue-100`
|
|
||||||
// backgroundLight: '#BFDBFE', // Tailwind CSS 默认的 `blue-200`
|
|
||||||
// borderLight: '#93C5FD', // Tailwind CSS 默认的 `blue-300`
|
|
||||||
// border: '#60A5FA', // Tailwind CSS 默认的 `blue-400`
|
|
||||||
// main: '#3B82F6', // Tailwind CSS 默认的 `blue-500`
|
|
||||||
// hover: '#2563EB', // Tailwind CSS 默认的 `blue-600`
|
|
||||||
// active: '#1D4ED8', // Tailwind CSS 默认的 `blue-700`
|
|
||||||
// backgroundDark: '#1E40AF', // Tailwind CSS 默认的 `blue-800`
|
|
||||||
// backgroundDarker: '#1E3A8A', // Tailwind CSS 默认的 `blue-900`
|
|
||||||
// backgroundDarkest: '#172554', // Tailwind CSS 默认的 `blue-950`
|
|
||||||
|
|
||||||
// • backgroundLightest (#EFF6FF): 适用于最浅的背景色,可能用于非常轻微的阴影或卡片的背景。
|
|
||||||
// • backgroundLighter (#DBEAFE): 适用于略浅的背景色,通常用于次要背景或略浅的区域。
|
|
||||||
// • backgroundLight (#BFDBFE): 适用于浅色背景,可能用于输入框或表单区域的背景。
|
|
||||||
// • borderLight (#93C5FD): 适用于浅色边框,可能用于输入框或卡片的边框。
|
|
||||||
// • border (#60A5FA): 适用于普通边框,可能用于按钮或卡片的边框。
|
|
||||||
// • main (#3B82F6): 适用于主要的主题色,通常用于按钮、链接或主要的强调色。
|
|
||||||
// • hover (#2563EB): 适用于鼠标悬停状态下的颜色,例如按钮悬停时的背景色或边框色。
|
|
||||||
// • active (#1D4ED8): 适用于激活状态下的颜色,例如按钮按下时的背景色或边框色。
|
|
||||||
// • backgroundDark (#1E40AF): 适用于深色背景,可能用于主要按钮或深色卡片背景。
|
|
||||||
// • backgroundDarker (#1E3A8A): 适用于更深的背景,通常用于头部导航栏或页脚。
|
|
||||||
// • backgroundDarkest (#172554): 适用于最深的背景,可能用于非常深色的区域或极端对比色。
|
|
||||||
|
|
||||||
return {
|
|
||||||
50: `hsl(var(--${name}-50))`,
|
|
||||||
100: `hsl(var(--${name}-100))`,
|
|
||||||
200: `hsl(var(--${name}-200))`,
|
|
||||||
300: `hsl(var(--${name}-300))`,
|
|
||||||
400: `hsl(var(--${name}-400))`,
|
|
||||||
500: `hsl(var(--${name}-500))`,
|
|
||||||
600: `hsl(var(--${name}-600))`,
|
|
||||||
700: `hsl(var(--${name}-700))`,
|
|
||||||
// 800: `hsl(var(--${name}-800))`,
|
|
||||||
// 900: `hsl(var(--${name}-900))`,
|
|
||||||
// 950: `hsl(var(--${name}-950))`,
|
|
||||||
// 激活状态下的颜色,适用于按钮按下时的背景色或边框色。
|
|
||||||
active: `hsl(var(--${name}-700))`,
|
|
||||||
// 浅色背景,适用于输入框或表单区域的背景。
|
|
||||||
'background-light': `hsl(var(--${name}-200))`,
|
|
||||||
// 适用于略浅的背景色,通常用于次要背景或略浅的区域。
|
|
||||||
'background-lighter': `hsl(var(--${name}-100))`,
|
|
||||||
// 最浅的背景色,适用于非常轻微的阴影或卡片的背景。
|
|
||||||
'background-lightest': `hsl(var(--${name}-50))`,
|
|
||||||
// 适用于普通边框,可能用于按钮或卡片的边框。
|
|
||||||
border: `hsl(var(--${name}-400))`,
|
|
||||||
// 浅色边框,适用于输入框或卡片的边框。
|
|
||||||
'border-light': `hsl(var(--${name}-300))`,
|
|
||||||
foreground: `hsl(var(--${name}-foreground))`,
|
|
||||||
// 鼠标悬停状态下的颜色,适用于按钮悬停时的背景色或边框色。
|
|
||||||
hover: `hsl(var(--${name}-600))`,
|
|
||||||
// 主色文本
|
|
||||||
text: `hsl(var(--${name}-500))`,
|
|
||||||
// 主色文本激活态
|
|
||||||
'text-active': `hsl(var(--${name}-700))`,
|
|
||||||
// 主色文本悬浮态
|
|
||||||
'text-hover': `hsl(var(--${name}-600))`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
declare module '@tailwindcss/nesting' {
|
|
||||||
export default any;
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
import plugin from 'tailwindcss/plugin.js';
|
|
||||||
|
|
||||||
const enterAnimationPlugin = plugin(({ addUtilities }) => {
|
|
||||||
const maxChild = 5;
|
|
||||||
const utilities: Record<string, any> = {};
|
|
||||||
for (let i = 1; i <= maxChild; i++) {
|
|
||||||
const baseDelay = 0.1;
|
|
||||||
const delay = `${baseDelay * i}s`;
|
|
||||||
|
|
||||||
utilities[`.enter-x:nth-child(${i})`] = {
|
|
||||||
animation: `enter-x-animation 0.3s ease-in-out ${delay} forwards`,
|
|
||||||
opacity: '0',
|
|
||||||
transform: `translateX(50px)`,
|
|
||||||
};
|
|
||||||
|
|
||||||
utilities[`.enter-y:nth-child(${i})`] = {
|
|
||||||
animation: `enter-y-animation 0.3s ease-in-out ${delay} forwards`,
|
|
||||||
opacity: '0',
|
|
||||||
transform: `translateY(50px)`,
|
|
||||||
};
|
|
||||||
|
|
||||||
utilities[`.-enter-x:nth-child(${i})`] = {
|
|
||||||
animation: `enter-x-animation 0.3s ease-in-out ${delay} forwards`,
|
|
||||||
opacity: '0',
|
|
||||||
transform: `translateX(-50px)`,
|
|
||||||
};
|
|
||||||
|
|
||||||
utilities[`.-enter-y:nth-child(${i})`] = {
|
|
||||||
animation: `enter-y-animation 0.3s ease-in-out ${delay} forwards`,
|
|
||||||
opacity: '0',
|
|
||||||
transform: `translateY(-50px)`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加动画关键帧
|
|
||||||
addUtilities(utilities);
|
|
||||||
addUtilities({
|
|
||||||
'@keyframes enter-x-animation': {
|
|
||||||
to: {
|
|
||||||
opacity: '1',
|
|
||||||
transform: 'translateX(0)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'@keyframes enter-y-animation': {
|
|
||||||
to: {
|
|
||||||
opacity: '1',
|
|
||||||
transform: 'translateY(0)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
export { enterAnimationPlugin };
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import config from '.';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
plugins: {
|
|
||||||
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}),
|
|
||||||
// Specifying the config is not necessary in most cases, but it is included
|
|
||||||
autoprefixer: {},
|
|
||||||
// 修复 element-plus 和 ant-design-vue 的样式和tailwindcss冲突问题
|
|
||||||
'postcss-antd-fixes': { prefixes: ['ant', 'el'] },
|
|
||||||
'postcss-import': {},
|
|
||||||
'postcss-preset-env': {},
|
|
||||||
tailwindcss: { config },
|
|
||||||
'tailwindcss/nesting': {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"extends": "@aiflowy/tsconfig/node.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"moduleResolution": "bundler"
|
|
||||||
},
|
|
||||||
"include": ["src"],
|
|
||||||
"exclude": ["node_modules"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Base",
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": false,
|
|
||||||
"target": "ESNext",
|
|
||||||
|
|
||||||
"moduleDetection": "force",
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
|
|
||||||
"baseUrl": ".",
|
|
||||||
"module": "ESNext",
|
|
||||||
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
|
|
||||||
"strict": true,
|
|
||||||
"strictNullChecks": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"noImplicitOverride": true,
|
|
||||||
"noImplicitThis": true,
|
|
||||||
"noUncheckedIndexedAccess": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
|
|
||||||
"inlineSources": false,
|
|
||||||
"noEmit": true,
|
|
||||||
"removeComments": true,
|
|
||||||
"sourceMap": false,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"verbatimModuleSyntax": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"preserveWatchOutput": true
|
|
||||||
},
|
|
||||||
"exclude": ["**/node_modules/**", "**/dist/**", "**/.turbo/**"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Web Application",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"jsx": "preserve",
|
|
||||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"declaration": true,
|
|
||||||
"noEmit": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Node Config",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": false,
|
|
||||||
"lib": ["ESNext"],
|
|
||||||
"baseUrl": "./",
|
|
||||||
"types": ["node"],
|
|
||||||
"noImplicitAny": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/tsconfig",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/tsconfig"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"files": [
|
|
||||||
"base.json",
|
|
||||||
"library.json",
|
|
||||||
"node.json",
|
|
||||||
"web-app.json",
|
|
||||||
"web.json"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"@aiflowy/types": "workspace:*",
|
|
||||||
"vite": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Web Application",
|
|
||||||
"extends": "./web.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"types": ["vite/client", "@aiflowy/types/global"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Web Package",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"jsx": "preserve",
|
|
||||||
"jsxImportSource": "vue",
|
|
||||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"types": ["vite/client"],
|
|
||||||
"declaration": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import { defineBuildConfig } from 'unbuild';
|
|
||||||
|
|
||||||
export default defineBuildConfig({
|
|
||||||
clean: true,
|
|
||||||
declaration: true,
|
|
||||||
entries: ['src/index'],
|
|
||||||
});
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@aiflowy/vite-config",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"homepage": "https://github.com/aiflowy/aiflowy",
|
|
||||||
"bugs": "https://github.com/aiflowy/aiflowy/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/aiflowy/aiflowy.git",
|
|
||||||
"directory": "internal/vite-config"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"stub": "pnpm unbuild --stub"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"main": "./dist/index.mjs",
|
|
||||||
"module": "./dist/index.mjs",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./src/index.ts",
|
|
||||||
"default": "./dist/index.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@intlify/unplugin-vue-i18n": "catalog:",
|
|
||||||
"@jspm/generator": "catalog:",
|
|
||||||
"archiver": "catalog:",
|
|
||||||
"cheerio": "catalog:",
|
|
||||||
"get-port": "catalog:",
|
|
||||||
"html-minifier-terser": "catalog:",
|
|
||||||
"nitropack": "catalog:",
|
|
||||||
"resolve.exports": "catalog:",
|
|
||||||
"vite-plugin-pwa": "catalog:",
|
|
||||||
"vite-plugin-vue-devtools": "catalog:"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@pnpm/workspace.read-manifest": "catalog:",
|
|
||||||
"@types/archiver": "catalog:",
|
|
||||||
"@types/html-minifier-terser": "catalog:",
|
|
||||||
"@aiflowy/node-utils": "workspace:*",
|
|
||||||
"@vitejs/plugin-vue": "catalog:",
|
|
||||||
"@vitejs/plugin-vue-jsx": "catalog:",
|
|
||||||
"dayjs": "catalog:",
|
|
||||||
"dotenv": "catalog:",
|
|
||||||
"rollup": "catalog:",
|
|
||||||
"rollup-plugin-visualizer": "catalog:",
|
|
||||||
"sass": "catalog:",
|
|
||||||
"vite": "catalog:",
|
|
||||||
"vite-plugin-compression": "catalog:",
|
|
||||||
"vite-plugin-dts": "catalog:",
|
|
||||||
"vite-plugin-html": "catalog:",
|
|
||||||
"vite-plugin-lazy-import": "catalog:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
import type { CSSOptions, UserConfig } from 'vite';
|
|
||||||
|
|
||||||
import type { DefineApplicationOptions } from '../typing';
|
|
||||||
|
|
||||||
import path, { relative } from 'node:path';
|
|
||||||
|
|
||||||
import { findMonorepoRoot } from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
import { NodePackageImporter } from 'sass';
|
|
||||||
import { defineConfig, loadEnv, mergeConfig } from 'vite';
|
|
||||||
|
|
||||||
import { defaultImportmapOptions, getDefaultPwaOptions } from '../options';
|
|
||||||
import { loadApplicationPlugins } from '../plugins';
|
|
||||||
import { loadAndConvertEnv } from '../utils/env';
|
|
||||||
import { getCommonConfig } from './common';
|
|
||||||
|
|
||||||
function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) {
|
|
||||||
return defineConfig(async (config) => {
|
|
||||||
const options = await userConfigPromise?.(config);
|
|
||||||
const { appTitle, base, port, ...envConfig } = await loadAndConvertEnv();
|
|
||||||
const { command, mode } = config;
|
|
||||||
const { application = {}, vite = {} } = options || {};
|
|
||||||
const root = process.cwd();
|
|
||||||
const isBuild = command === 'build';
|
|
||||||
const env = loadEnv(mode, root);
|
|
||||||
|
|
||||||
const plugins = await loadApplicationPlugins({
|
|
||||||
archiver: true,
|
|
||||||
archiverPluginOptions: {},
|
|
||||||
compress: false,
|
|
||||||
compressTypes: ['brotli', 'gzip'],
|
|
||||||
devtools: true,
|
|
||||||
env,
|
|
||||||
extraAppConfig: true,
|
|
||||||
html: true,
|
|
||||||
i18n: true,
|
|
||||||
importmapOptions: defaultImportmapOptions,
|
|
||||||
injectAppLoading: true,
|
|
||||||
injectMetadata: true,
|
|
||||||
isBuild,
|
|
||||||
license: true,
|
|
||||||
mode,
|
|
||||||
nitroMock: !isBuild,
|
|
||||||
nitroMockOptions: {},
|
|
||||||
print: !isBuild,
|
|
||||||
printInfoMap: {
|
|
||||||
'AIFlowy Docs': 'https://aiflowy.tech',
|
|
||||||
},
|
|
||||||
pwa: true,
|
|
||||||
pwaOptions: getDefaultPwaOptions(appTitle),
|
|
||||||
vxeTableLazyImport: true,
|
|
||||||
...envConfig,
|
|
||||||
...application,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { injectGlobalScss = true } = application;
|
|
||||||
|
|
||||||
const applicationConfig: UserConfig = {
|
|
||||||
base,
|
|
||||||
build: {
|
|
||||||
rollupOptions: {
|
|
||||||
output: {
|
|
||||||
assetFileNames: '[ext]/[name]-[hash].[ext]',
|
|
||||||
chunkFileNames: 'js/[name]-[hash].js',
|
|
||||||
entryFileNames: 'jse/index-[name]-[hash].js',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
target: 'es2015',
|
|
||||||
},
|
|
||||||
css: createCssOptions(injectGlobalScss),
|
|
||||||
esbuild: {
|
|
||||||
drop: isBuild
|
|
||||||
? [
|
|
||||||
// 'console',
|
|
||||||
'debugger',
|
|
||||||
]
|
|
||||||
: [],
|
|
||||||
legalComments: 'none',
|
|
||||||
},
|
|
||||||
plugins,
|
|
||||||
server: {
|
|
||||||
host: true,
|
|
||||||
port,
|
|
||||||
warmup: {
|
|
||||||
// 预热文件
|
|
||||||
clientFiles: [
|
|
||||||
'./index.html',
|
|
||||||
'./src/bootstrap.ts',
|
|
||||||
'./src/{views,layouts,router,store,api,adapter}/*',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mergedCommonConfig = mergeConfig(
|
|
||||||
await getCommonConfig(),
|
|
||||||
applicationConfig,
|
|
||||||
);
|
|
||||||
return mergeConfig(mergedCommonConfig, vite);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function createCssOptions(injectGlobalScss = true): CSSOptions {
|
|
||||||
const root = findMonorepoRoot();
|
|
||||||
return {
|
|
||||||
preprocessorOptions: injectGlobalScss
|
|
||||||
? {
|
|
||||||
scss: {
|
|
||||||
additionalData: (content: string, filepath: string) => {
|
|
||||||
const relativePath = relative(root, filepath);
|
|
||||||
// apps下的包注入全局样式
|
|
||||||
if (relativePath.startsWith(`apps${path.sep}`)) {
|
|
||||||
return `@use "@aiflowy/styles/global" as *;\n${content}`;
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
},
|
|
||||||
api: 'modern',
|
|
||||||
importers: [new NodePackageImporter()],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export { defineApplicationConfig };
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
import type { UserConfig } from 'vite';
|
|
||||||
|
|
||||||
async function getCommonConfig(): Promise<UserConfig> {
|
|
||||||
return {
|
|
||||||
build: {
|
|
||||||
chunkSizeWarningLimit: 2000,
|
|
||||||
reportCompressedSize: false,
|
|
||||||
sourcemap: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export { getCommonConfig };
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import type { DefineConfig } from '../typing';
|
|
||||||
|
|
||||||
import { existsSync } from 'node:fs';
|
|
||||||
import { join } from 'node:path';
|
|
||||||
|
|
||||||
import { defineApplicationConfig } from './application';
|
|
||||||
import { defineLibraryConfig } from './library';
|
|
||||||
|
|
||||||
export * from './application';
|
|
||||||
export * from './library';
|
|
||||||
|
|
||||||
function defineConfig(
|
|
||||||
userConfigPromise?: DefineConfig,
|
|
||||||
type: 'application' | 'auto' | 'library' = 'auto',
|
|
||||||
) {
|
|
||||||
let projectType = type;
|
|
||||||
|
|
||||||
// 根据包是否存在 index.html,自动判断类型
|
|
||||||
if (projectType === 'auto') {
|
|
||||||
const htmlPath = join(process.cwd(), 'index.html');
|
|
||||||
projectType = existsSync(htmlPath) ? 'application' : 'library';
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (projectType) {
|
|
||||||
case 'application': {
|
|
||||||
return defineApplicationConfig(userConfigPromise);
|
|
||||||
}
|
|
||||||
case 'library': {
|
|
||||||
return defineLibraryConfig(userConfigPromise);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw new Error(`Unsupported project type: ${projectType}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { defineConfig };
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
import type { ConfigEnv, UserConfig } from 'vite';
|
|
||||||
|
|
||||||
import type { DefineLibraryOptions } from '../typing';
|
|
||||||
|
|
||||||
import { readPackageJSON } from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
import { defineConfig, mergeConfig } from 'vite';
|
|
||||||
|
|
||||||
import { loadLibraryPlugins } from '../plugins';
|
|
||||||
import { getCommonConfig } from './common';
|
|
||||||
|
|
||||||
function defineLibraryConfig(userConfigPromise?: DefineLibraryOptions) {
|
|
||||||
return defineConfig(async (config: ConfigEnv) => {
|
|
||||||
const options = await userConfigPromise?.(config);
|
|
||||||
const { command, mode } = config;
|
|
||||||
const { library = {}, vite = {} } = options || {};
|
|
||||||
const root = process.cwd();
|
|
||||||
const isBuild = command === 'build';
|
|
||||||
|
|
||||||
const plugins = await loadLibraryPlugins({
|
|
||||||
dts: false,
|
|
||||||
injectMetadata: true,
|
|
||||||
isBuild,
|
|
||||||
mode,
|
|
||||||
...library,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { dependencies = {}, peerDependencies = {} } =
|
|
||||||
await readPackageJSON(root);
|
|
||||||
|
|
||||||
const externalPackages = [
|
|
||||||
...Object.keys(dependencies),
|
|
||||||
...Object.keys(peerDependencies),
|
|
||||||
];
|
|
||||||
|
|
||||||
const packageConfig: UserConfig = {
|
|
||||||
build: {
|
|
||||||
lib: {
|
|
||||||
entry: 'src/index.ts',
|
|
||||||
fileName: () => 'index.mjs',
|
|
||||||
formats: ['es'],
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: (id) => {
|
|
||||||
return externalPackages.some(
|
|
||||||
(pkg) => id === pkg || id.startsWith(`${pkg}/`),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins,
|
|
||||||
};
|
|
||||||
const commonConfig = await getCommonConfig();
|
|
||||||
const mergedConmonConfig = mergeConfig(commonConfig, packageConfig);
|
|
||||||
return mergeConfig(mergedConmonConfig, vite);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export { defineLibraryConfig };
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
export * from './config';
|
|
||||||
export * from './options';
|
|
||||||
export * from './plugins';
|
|
||||||
export { loadAndConvertEnv } from './utils/env';
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
import type { Options as PwaPluginOptions } from 'vite-plugin-pwa';
|
|
||||||
|
|
||||||
import type { ImportmapPluginOptions } from './typing';
|
|
||||||
|
|
||||||
const isDevelopment = process.env.NODE_ENV === 'development';
|
|
||||||
|
|
||||||
const getDefaultPwaOptions = (name: string): Partial<PwaPluginOptions> => ({
|
|
||||||
manifest: {
|
|
||||||
description:
|
|
||||||
'AIFlowy Admin is a modern admin dashboard template based on Vue 3. ',
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
sizes: '192x192',
|
|
||||||
src: 'https://unpkg.com/@aiflowy/static-source@0.1.7/source/pwa-icon-192.png',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sizes: '512x512',
|
|
||||||
src: 'https://unpkg.com/@aiflowy/static-source@0.1.7/source/pwa-icon-512.png',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
name: `${name}${isDevelopment ? ' dev' : ''}`,
|
|
||||||
short_name: `${name}${isDevelopment ? ' dev' : ''}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* importmap CDN 暂时不开启,因为有些包不支持,且网络不稳定
|
|
||||||
*/
|
|
||||||
const defaultImportmapOptions: ImportmapPluginOptions = {
|
|
||||||
// 通过 Importmap CDN 方式引入,
|
|
||||||
// 目前只有esm.sh源兼容性好一点,jspm.io对于 esm 入口要求高
|
|
||||||
defaultProvider: 'esm.sh',
|
|
||||||
importmap: [
|
|
||||||
{ name: 'vue' },
|
|
||||||
{ name: 'pinia' },
|
|
||||||
{ name: 'vue-router' },
|
|
||||||
// { name: 'vue-i18n' },
|
|
||||||
{ name: 'dayjs' },
|
|
||||||
{ name: 'vue-demi' },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export { defaultImportmapOptions, getDefaultPwaOptions };
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
|
|
||||||
import type { ArchiverPluginOptions } from '../typing';
|
|
||||||
|
|
||||||
import fs from 'node:fs';
|
|
||||||
import fsp from 'node:fs/promises';
|
|
||||||
import { join } from 'node:path';
|
|
||||||
|
|
||||||
import archiver from 'archiver';
|
|
||||||
|
|
||||||
export const viteArchiverPlugin = (
|
|
||||||
options: ArchiverPluginOptions = {},
|
|
||||||
): PluginOption => {
|
|
||||||
return {
|
|
||||||
apply: 'build',
|
|
||||||
closeBundle: {
|
|
||||||
handler() {
|
|
||||||
const { name = 'dist', outputDir = '.' } = options;
|
|
||||||
|
|
||||||
setTimeout(async () => {
|
|
||||||
const folderToZip = 'dist';
|
|
||||||
|
|
||||||
const zipOutputDir = join(process.cwd(), outputDir);
|
|
||||||
const zipOutputPath = join(zipOutputDir, `${name}.zip`);
|
|
||||||
try {
|
|
||||||
await fsp.mkdir(zipOutputDir, { recursive: true });
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await zipFolder(folderToZip, zipOutputPath);
|
|
||||||
console.log(`Folder has been zipped to: ${zipOutputPath}`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error zipping folder:', error);
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
},
|
|
||||||
order: 'post',
|
|
||||||
},
|
|
||||||
enforce: 'post',
|
|
||||||
name: 'vite:archiver',
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
async function zipFolder(
|
|
||||||
folderPath: string,
|
|
||||||
outputPath: string,
|
|
||||||
): Promise<void> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const output = fs.createWriteStream(outputPath);
|
|
||||||
const archive = archiver('zip', {
|
|
||||||
zlib: { level: 9 }, // 设置压缩级别为 9 以实现最高压缩率
|
|
||||||
});
|
|
||||||
|
|
||||||
output.on('close', () => {
|
|
||||||
console.log(
|
|
||||||
`ZIP file created: ${outputPath} (${archive.pointer()} total bytes)`,
|
|
||||||
);
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
archive.on('error', (err) => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
archive.pipe(output);
|
|
||||||
|
|
||||||
// 使用 directory 方法以流的方式压缩文件夹,减少内存消耗
|
|
||||||
archive.directory(folderPath, false);
|
|
||||||
|
|
||||||
// 流式处理完成
|
|
||||||
archive.finalize();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
|
|
||||||
import {
|
|
||||||
colors,
|
|
||||||
generatorContentHash,
|
|
||||||
readPackageJSON,
|
|
||||||
} from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
import { loadEnv } from '../utils/env';
|
|
||||||
|
|
||||||
interface PluginOptions {
|
|
||||||
isBuild: boolean;
|
|
||||||
root: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const GLOBAL_CONFIG_FILE_NAME = '_app.config.js';
|
|
||||||
const APP_ADMIN_PRO_APP_CONF = '_APP_ADMIN_PRO_APP_CONF_';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于将配置文件抽离出来并注入到项目中
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
|
|
||||||
async function viteExtraAppConfigPlugin({
|
|
||||||
isBuild,
|
|
||||||
root,
|
|
||||||
}: PluginOptions): Promise<PluginOption | undefined> {
|
|
||||||
let publicPath: string;
|
|
||||||
let source: string;
|
|
||||||
|
|
||||||
if (!isBuild) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { version = '' } = await readPackageJSON(root);
|
|
||||||
|
|
||||||
return {
|
|
||||||
async configResolved(config) {
|
|
||||||
publicPath = ensureTrailingSlash(config.base);
|
|
||||||
source = await getConfigSource();
|
|
||||||
},
|
|
||||||
async generateBundle() {
|
|
||||||
try {
|
|
||||||
this.emitFile({
|
|
||||||
fileName: GLOBAL_CONFIG_FILE_NAME,
|
|
||||||
source,
|
|
||||||
type: 'asset',
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(colors.cyan(`✨configuration file is build successfully!`));
|
|
||||||
} catch (error) {
|
|
||||||
console.log(
|
|
||||||
colors.red(
|
|
||||||
`configuration file configuration file failed to package:\n${error}`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: 'vite:extra-app-config',
|
|
||||||
async transformIndexHtml(html) {
|
|
||||||
const hash = `v=${version}-${generatorContentHash(source, 8)}`;
|
|
||||||
|
|
||||||
const appConfigSrc = `${publicPath}${GLOBAL_CONFIG_FILE_NAME}?${hash}`;
|
|
||||||
|
|
||||||
return {
|
|
||||||
html,
|
|
||||||
tags: [{ attrs: { src: appConfigSrc }, tag: 'script' }],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getConfigSource() {
|
|
||||||
const config = await loadEnv();
|
|
||||||
const windowVariable = `window.${APP_ADMIN_PRO_APP_CONF}`;
|
|
||||||
// 确保变量不会被修改
|
|
||||||
let source = `${windowVariable}=${JSON.stringify(config)};`;
|
|
||||||
source += `
|
|
||||||
Object.freeze(${windowVariable});
|
|
||||||
Object.defineProperty(window, "${APP_ADMIN_PRO_APP_CONF}", {
|
|
||||||
configurable: false,
|
|
||||||
writable: false,
|
|
||||||
});
|
|
||||||
`.replaceAll(/\s/g, '');
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureTrailingSlash(path: string) {
|
|
||||||
return path.endsWith('/') ? path : `${path}/`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { viteExtraAppConfigPlugin };
|
|
||||||
|
|
@ -1,245 +0,0 @@
|
||||||
/**
|
|
||||||
* 参考 https://github.com/jspm/vite-plugin-jspm,调整为需要的功能
|
|
||||||
*/
|
|
||||||
import type { GeneratorOptions } from '@jspm/generator';
|
|
||||||
import type { Plugin } from 'vite';
|
|
||||||
|
|
||||||
import { Generator } from '@jspm/generator';
|
|
||||||
import { load } from 'cheerio';
|
|
||||||
import { minify } from 'html-minifier-terser';
|
|
||||||
|
|
||||||
const DEFAULT_PROVIDER = 'jspm.io';
|
|
||||||
|
|
||||||
type pluginOptions = GeneratorOptions & {
|
|
||||||
debug?: boolean;
|
|
||||||
defaultProvider?: 'esm.sh' | 'jsdelivr' | 'jspm.io';
|
|
||||||
importmap?: Array<{ name: string; range?: string }>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// async function getLatestVersionOfShims() {
|
|
||||||
// const result = await fetch('https://ga.jspm.io/npm:es-module-shims');
|
|
||||||
// const version = result.text();
|
|
||||||
// return version;
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function getShimsUrl(provide: string) {
|
|
||||||
// const version = await getLatestVersionOfShims();
|
|
||||||
const version = '1.10.0';
|
|
||||||
|
|
||||||
const shimsSubpath = `dist/es-module-shims.js`;
|
|
||||||
const providerShimsMap: Record<string, string> = {
|
|
||||||
'esm.sh': `https://esm.sh/es-module-shims@${version}/${shimsSubpath}`,
|
|
||||||
// unpkg: `https://unpkg.com/es-module-shims@${version}/${shimsSubpath}`,
|
|
||||||
jsdelivr: `https://cdn.jsdelivr.net/npm/es-module-shims@${version}/${shimsSubpath}`,
|
|
||||||
|
|
||||||
// 下面两个CDN不稳定,暂时不用
|
|
||||||
'jspm.io': `https://ga.jspm.io/npm:es-module-shims@${version}/${shimsSubpath}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
return providerShimsMap[provide] || providerShimsMap[DEFAULT_PROVIDER];
|
|
||||||
}
|
|
||||||
|
|
||||||
let generator: Generator;
|
|
||||||
|
|
||||||
async function viteImportMapPlugin(
|
|
||||||
pluginOptions?: pluginOptions,
|
|
||||||
): Promise<Plugin[]> {
|
|
||||||
const { importmap } = pluginOptions || {};
|
|
||||||
|
|
||||||
let isSSR = false;
|
|
||||||
let isBuild = false;
|
|
||||||
let installed = false;
|
|
||||||
let installError: Error | null = null;
|
|
||||||
|
|
||||||
const options: pluginOptions = Object.assign(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
debug: false,
|
|
||||||
defaultProvider: 'jspm.io',
|
|
||||||
env: ['production', 'browser', 'module'],
|
|
||||||
importmap: [],
|
|
||||||
},
|
|
||||||
pluginOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
generator = new Generator({
|
|
||||||
...options,
|
|
||||||
baseUrl: process.cwd(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (options?.debug) {
|
|
||||||
(async () => {
|
|
||||||
for await (const { message, type } of generator.logStream()) {
|
|
||||||
console.log(`${type}: ${message}`);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
const imports = options.inputMap?.imports ?? {};
|
|
||||||
const scopes = options.inputMap?.scopes ?? {};
|
|
||||||
const firstLayerKeys = Object.keys(scopes);
|
|
||||||
const inputMapScopes: string[] = [];
|
|
||||||
firstLayerKeys.forEach((key) => {
|
|
||||||
inputMapScopes.push(...Object.keys(scopes[key] || {}));
|
|
||||||
});
|
|
||||||
const inputMapImports = Object.keys(imports);
|
|
||||||
|
|
||||||
const allDepNames: string[] = [
|
|
||||||
...(importmap?.map((item) => item.name) || []),
|
|
||||||
...inputMapImports,
|
|
||||||
...inputMapScopes,
|
|
||||||
];
|
|
||||||
const depNames = new Set<string>(allDepNames);
|
|
||||||
|
|
||||||
const installDeps = importmap?.map((item) => ({
|
|
||||||
range: item.range,
|
|
||||||
target: item.name,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
async config(_, { command, isSsrBuild }) {
|
|
||||||
isBuild = command === 'build';
|
|
||||||
isSSR = !!isSsrBuild;
|
|
||||||
},
|
|
||||||
enforce: 'pre',
|
|
||||||
name: 'importmap:external',
|
|
||||||
resolveId(id) {
|
|
||||||
if (isSSR || !isBuild) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!depNames.has(id)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return { external: true, id };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enforce: 'post',
|
|
||||||
name: 'importmap:install',
|
|
||||||
async resolveId() {
|
|
||||||
if (isSSR || !isBuild || installed) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
installed = true;
|
|
||||||
await Promise.allSettled(
|
|
||||||
(installDeps || []).map((dep) => generator.install(dep)),
|
|
||||||
);
|
|
||||||
} catch (error: any) {
|
|
||||||
installError = error;
|
|
||||||
installed = false;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
buildEnd() {
|
|
||||||
// 未生成importmap时,抛出错误,防止被turbo缓存
|
|
||||||
if (!installed && !isSSR) {
|
|
||||||
installError && console.error(installError);
|
|
||||||
throw new Error('Importmap installation failed.');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
enforce: 'post',
|
|
||||||
name: 'importmap:html',
|
|
||||||
transformIndexHtml: {
|
|
||||||
async handler(html) {
|
|
||||||
if (isSSR || !isBuild) {
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
const importmapJson = generator.getMap();
|
|
||||||
|
|
||||||
if (!importmapJson) {
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
const esModuleShimsSrc = await getShimsUrl(
|
|
||||||
options.defaultProvider || DEFAULT_PROVIDER,
|
|
||||||
);
|
|
||||||
|
|
||||||
const resultHtml = await injectShimsToHtml(
|
|
||||||
html,
|
|
||||||
esModuleShimsSrc || '',
|
|
||||||
);
|
|
||||||
html = await minify(resultHtml || html, {
|
|
||||||
collapseWhitespace: true,
|
|
||||||
minifyCSS: true,
|
|
||||||
minifyJS: true,
|
|
||||||
removeComments: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
html,
|
|
||||||
tags: [
|
|
||||||
{
|
|
||||||
attrs: {
|
|
||||||
type: 'importmap',
|
|
||||||
},
|
|
||||||
injectTo: 'head-prepend',
|
|
||||||
tag: 'script',
|
|
||||||
children: `${JSON.stringify(importmapJson)}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
order: 'post',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function injectShimsToHtml(html: string, esModuleShimUrl: string) {
|
|
||||||
const $ = load(html);
|
|
||||||
|
|
||||||
const $script = $(`script[type='module']`);
|
|
||||||
|
|
||||||
if (!$script) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entry = $script.attr('src');
|
|
||||||
|
|
||||||
$script.removeAttr('type');
|
|
||||||
$script.removeAttr('crossorigin');
|
|
||||||
$script.removeAttr('src');
|
|
||||||
$script.html(`
|
|
||||||
if (!HTMLScriptElement.supports || !HTMLScriptElement.supports('importmap')) {
|
|
||||||
self.importShim = function () {
|
|
||||||
const promise = new Promise((resolve, reject) => {
|
|
||||||
document.head.appendChild(
|
|
||||||
Object.assign(document.createElement('script'), {
|
|
||||||
src: '${esModuleShimUrl}',
|
|
||||||
crossorigin: 'anonymous',
|
|
||||||
async: true,
|
|
||||||
onload() {
|
|
||||||
if (!importShim.$proxy) {
|
|
||||||
resolve(importShim);
|
|
||||||
} else {
|
|
||||||
reject(new Error('No globalThis.importShim found:' + esModuleShimUrl));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onerror(error) {
|
|
||||||
reject(error);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
importShim.$proxy = true;
|
|
||||||
return promise.then((importShim) => importShim(...arguments));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var modules = ['${entry}'];
|
|
||||||
typeof importShim === 'function'
|
|
||||||
? modules.forEach((moduleName) => importShim(moduleName))
|
|
||||||
: modules.forEach((moduleName) => import(moduleName));
|
|
||||||
`);
|
|
||||||
$('body').after($script);
|
|
||||||
$('head').remove(`script[type='module']`);
|
|
||||||
return $.html();
|
|
||||||
}
|
|
||||||
|
|
||||||
export { viteImportMapPlugin };
|
|
||||||
|
|
@ -1,247 +0,0 @@
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
|
|
||||||
import type {
|
|
||||||
ApplicationPluginOptions,
|
|
||||||
CommonPluginOptions,
|
|
||||||
ConditionPlugin,
|
|
||||||
LibraryPluginOptions,
|
|
||||||
} from '../typing';
|
|
||||||
|
|
||||||
import viteVueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
|
|
||||||
import viteVue from '@vitejs/plugin-vue';
|
|
||||||
import viteVueJsx from '@vitejs/plugin-vue-jsx';
|
|
||||||
import { visualizer as viteVisualizerPlugin } from 'rollup-plugin-visualizer';
|
|
||||||
import viteCompressPlugin from 'vite-plugin-compression';
|
|
||||||
import viteDtsPlugin from 'vite-plugin-dts';
|
|
||||||
import { createHtmlPlugin as viteHtmlPlugin } from 'vite-plugin-html';
|
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
|
||||||
import viteVueDevTools from 'vite-plugin-vue-devtools';
|
|
||||||
|
|
||||||
import { viteArchiverPlugin } from './archiver';
|
|
||||||
import { viteExtraAppConfigPlugin } from './extra-app-config';
|
|
||||||
import { viteImportMapPlugin } from './importmap';
|
|
||||||
import { viteInjectAppLoadingPlugin } from './inject-app-loading';
|
|
||||||
import { viteMetadataPlugin } from './inject-metadata';
|
|
||||||
import { viteLicensePlugin } from './license';
|
|
||||||
import { viteNitroMockPlugin } from './nitro-mock';
|
|
||||||
import { vitePrintPlugin } from './print';
|
|
||||||
import { viteVxeTableImportsPlugin } from './vxe-table';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取条件成立的 vite 插件
|
|
||||||
* @param conditionPlugins
|
|
||||||
*/
|
|
||||||
async function loadConditionPlugins(conditionPlugins: ConditionPlugin[]) {
|
|
||||||
const plugins: PluginOption[] = [];
|
|
||||||
for (const conditionPlugin of conditionPlugins) {
|
|
||||||
if (conditionPlugin.condition) {
|
|
||||||
const realPlugins = await conditionPlugin.plugins();
|
|
||||||
plugins.push(...realPlugins);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return plugins.flat();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件获取通用的vite插件
|
|
||||||
*/
|
|
||||||
async function loadCommonPlugins(
|
|
||||||
options: CommonPluginOptions,
|
|
||||||
): Promise<ConditionPlugin[]> {
|
|
||||||
const { devtools, injectMetadata, isBuild, visualizer } = options;
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
condition: true,
|
|
||||||
plugins: () => [
|
|
||||||
viteVue({
|
|
||||||
script: {
|
|
||||||
defineModel: true,
|
|
||||||
// propsDestructure: true,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
viteVueJsx(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
condition: !isBuild && devtools,
|
|
||||||
plugins: () => [viteVueDevTools()],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: injectMetadata,
|
|
||||||
plugins: async () => [await viteMetadataPlugin()],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: isBuild && !!visualizer,
|
|
||||||
plugins: () => [<PluginOption>viteVisualizerPlugin({
|
|
||||||
filename: './node_modules/.cache/visualizer/stats.html',
|
|
||||||
gzipSize: true,
|
|
||||||
open: true,
|
|
||||||
})],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件获取应用类型的vite插件
|
|
||||||
*/
|
|
||||||
async function loadApplicationPlugins(
|
|
||||||
options: ApplicationPluginOptions,
|
|
||||||
): Promise<PluginOption[]> {
|
|
||||||
// 单独取,否则commonOptions拿不到
|
|
||||||
const isBuild = options.isBuild;
|
|
||||||
const env = options.env;
|
|
||||||
|
|
||||||
const {
|
|
||||||
archiver,
|
|
||||||
archiverPluginOptions,
|
|
||||||
compress,
|
|
||||||
compressTypes,
|
|
||||||
extraAppConfig,
|
|
||||||
html,
|
|
||||||
i18n,
|
|
||||||
importmap,
|
|
||||||
importmapOptions,
|
|
||||||
injectAppLoading,
|
|
||||||
license,
|
|
||||||
nitroMock,
|
|
||||||
nitroMockOptions,
|
|
||||||
print,
|
|
||||||
printInfoMap,
|
|
||||||
pwa,
|
|
||||||
pwaOptions,
|
|
||||||
vxeTableLazyImport,
|
|
||||||
...commonOptions
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
const commonPlugins = await loadCommonPlugins(commonOptions);
|
|
||||||
|
|
||||||
return await loadConditionPlugins([
|
|
||||||
...commonPlugins,
|
|
||||||
{
|
|
||||||
condition: i18n,
|
|
||||||
plugins: async () => {
|
|
||||||
return [
|
|
||||||
viteVueI18nPlugin({
|
|
||||||
compositionOnly: true,
|
|
||||||
fullInstall: true,
|
|
||||||
runtimeOnly: true,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: print,
|
|
||||||
plugins: async () => {
|
|
||||||
return [await vitePrintPlugin({ infoMap: printInfoMap })];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: vxeTableLazyImport,
|
|
||||||
plugins: async () => {
|
|
||||||
return [await viteVxeTableImportsPlugin()];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: nitroMock,
|
|
||||||
plugins: async () => {
|
|
||||||
return [await viteNitroMockPlugin(nitroMockOptions)];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
condition: injectAppLoading,
|
|
||||||
plugins: async () => [await viteInjectAppLoadingPlugin(!!isBuild, env)],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: license,
|
|
||||||
plugins: async () => [await viteLicensePlugin()],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: pwa,
|
|
||||||
plugins: () =>
|
|
||||||
VitePWA({
|
|
||||||
injectRegister: false,
|
|
||||||
workbox: {
|
|
||||||
globPatterns: [],
|
|
||||||
},
|
|
||||||
...pwaOptions,
|
|
||||||
manifest: {
|
|
||||||
display: 'standalone',
|
|
||||||
start_url: '/',
|
|
||||||
theme_color: '#ffffff',
|
|
||||||
...pwaOptions?.manifest,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: isBuild && !!compress,
|
|
||||||
plugins: () => {
|
|
||||||
const compressPlugins: PluginOption[] = [];
|
|
||||||
if (compressTypes?.includes('brotli')) {
|
|
||||||
compressPlugins.push(
|
|
||||||
viteCompressPlugin({ deleteOriginFile: false, ext: '.br' }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (compressTypes?.includes('gzip')) {
|
|
||||||
compressPlugins.push(
|
|
||||||
viteCompressPlugin({ deleteOriginFile: false, ext: '.gz' }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return compressPlugins;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: !!html,
|
|
||||||
plugins: () => [viteHtmlPlugin({ minify: true })],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: isBuild && importmap,
|
|
||||||
plugins: () => {
|
|
||||||
return [viteImportMapPlugin(importmapOptions)];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: isBuild && extraAppConfig,
|
|
||||||
plugins: async () => [
|
|
||||||
await viteExtraAppConfigPlugin({ isBuild: true, root: process.cwd() }),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: archiver,
|
|
||||||
plugins: async () => {
|
|
||||||
return [await viteArchiverPlugin(archiverPluginOptions)];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件获取库类型的vite插件
|
|
||||||
*/
|
|
||||||
async function loadLibraryPlugins(
|
|
||||||
options: LibraryPluginOptions,
|
|
||||||
): Promise<PluginOption[]> {
|
|
||||||
// 单独取,否则commonOptions拿不到
|
|
||||||
const isBuild = options.isBuild;
|
|
||||||
const { dts, ...commonOptions } = options;
|
|
||||||
const commonPlugins = await loadCommonPlugins(commonOptions);
|
|
||||||
return await loadConditionPlugins([
|
|
||||||
...commonPlugins,
|
|
||||||
{
|
|
||||||
condition: isBuild && !!dts,
|
|
||||||
plugins: () => [viteDtsPlugin({ logLevel: 'error' })],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
loadApplicationPlugins,
|
|
||||||
loadLibraryPlugins,
|
|
||||||
viteArchiverPlugin,
|
|
||||||
viteCompressPlugin,
|
|
||||||
viteDtsPlugin,
|
|
||||||
viteHtmlPlugin,
|
|
||||||
viteVisualizerPlugin,
|
|
||||||
viteVxeTableImportsPlugin,
|
|
||||||
};
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# inject-app-loading
|
|
||||||
|
|
||||||
用于在应用加载时显示加载动画的插件,可自行选择加载动画的样式。
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
<style data-app-loading="inject-css">
|
|
||||||
html {
|
|
||||||
/* same as ant-design-vue/dist/reset.css setting, avoid the title line-height changed */
|
|
||||||
line-height: 1.15;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark .loading {
|
|
||||||
background-color: #0d0d10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark .loading .title {
|
|
||||||
color: rgb(255 255 255 / 85%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
pointer-events: none;
|
|
||||||
background-color: #f4f7f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading.hidden {
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.6s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading .title {
|
|
||||||
margin-top: 36px;
|
|
||||||
font-size: 30px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: rgb(0 0 0 / 85%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: inline-block;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
margin-top: 30px;
|
|
||||||
font-size: 32px;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
animation: rotate-ani 1.2s infinite linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot i {
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
background-color: hsl(var(--primary, 210 100% 50%));
|
|
||||||
border-radius: 100%;
|
|
||||||
opacity: 0.3;
|
|
||||||
transform: scale(0.75);
|
|
||||||
transform-origin: 50% 50%;
|
|
||||||
animation: spin-move-ani 1s infinite linear alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot i:nth-child(1) {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot i:nth-child(2) {
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
animation-delay: 0.4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot i:nth-child(3) {
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
animation-delay: 0.8s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot i:nth-child(4) {
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
animation-delay: 1.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate-ani {
|
|
||||||
to {
|
|
||||||
transform: rotate(405deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin-move-ani {
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="loading" id="__app-loading__">
|
|
||||||
<span class="dot"><i></i><i></i><i></i><i></i></span>
|
|
||||||
<div class="title"><%= VITE_APP_TITLE %></div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
<style data-app-loading="inject-css">
|
|
||||||
html {
|
|
||||||
/* same as ant-design-vue/dist/reset.css setting, avoid the title line-height changed */
|
|
||||||
line-height: 1.15;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #f4f7f9;
|
|
||||||
|
|
||||||
/* transition: all 0.8s ease-out; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading.hidden {
|
|
||||||
pointer-events: none;
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.8s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark .loading {
|
|
||||||
background: #0d0d10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-top: 66px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: rgb(0 0 0 / 85%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark .title {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
position: relative;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader::before {
|
|
||||||
position: absolute;
|
|
||||||
top: 60px;
|
|
||||||
left: 0;
|
|
||||||
width: 48px;
|
|
||||||
height: 5px;
|
|
||||||
content: '';
|
|
||||||
background: hsl(var(--primary, 210 100% 50%) / 50%);
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: shadow-ani 0.5s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader::after {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
content: '';
|
|
||||||
background: hsl(var(--primary, 210 100% 50%));
|
|
||||||
border-radius: 4px;
|
|
||||||
animation: jump-ani 0.5s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes jump-ani {
|
|
||||||
15% {
|
|
||||||
border-bottom-right-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
25% {
|
|
||||||
transform: translateY(9px) rotate(22.5deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
border-bottom-right-radius: 40px;
|
|
||||||
transform: translateY(18px) scale(1, 0.9) rotate(45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
75% {
|
|
||||||
transform: translateY(9px) rotate(67.5deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translateY(0) rotate(90deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes shadow-ani {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
transform: scale(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: scale(1.2, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="loading" id="__app-loading__">
|
|
||||||
<div class="loader"></div>
|
|
||||||
<div class="title"><%= VITE_APP_TITLE %></div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
|
|
||||||
import fs from 'node:fs';
|
|
||||||
import fsp from 'node:fs/promises';
|
|
||||||
import { join } from 'node:path';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
import { readPackageJSON } from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于生成将loading样式注入到项目中
|
|
||||||
* 为多app提供loading样式,无需在每个 app -> index.html单独引入
|
|
||||||
*/
|
|
||||||
async function viteInjectAppLoadingPlugin(
|
|
||||||
isBuild: boolean,
|
|
||||||
env: Record<string, any> = {},
|
|
||||||
loadingTemplate = 'loading.html',
|
|
||||||
): Promise<PluginOption | undefined> {
|
|
||||||
const loadingHtml = await getLoadingRawByHtmlTemplate(loadingTemplate);
|
|
||||||
const { version } = await readPackageJSON(process.cwd());
|
|
||||||
const envRaw = isBuild ? 'prod' : 'dev';
|
|
||||||
const cacheName = `'${env.VITE_APP_NAMESPACE}-${version}-${envRaw}-preferences-theme'`;
|
|
||||||
|
|
||||||
// 获取缓存的主题
|
|
||||||
// 保证黑暗主题下,刷新页面时,loading也是黑暗主题
|
|
||||||
const injectScript = `
|
|
||||||
<script data-app-loading="inject-js">
|
|
||||||
var theme = localStorage.getItem(${cacheName});
|
|
||||||
document.documentElement.classList.toggle('dark', /dark/.test(theme));
|
|
||||||
</script>
|
|
||||||
`;
|
|
||||||
|
|
||||||
if (!loadingHtml) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
enforce: 'pre',
|
|
||||||
name: 'vite:inject-app-loading',
|
|
||||||
transformIndexHtml: {
|
|
||||||
handler(html) {
|
|
||||||
const re = /<body\s*>/;
|
|
||||||
html = html.replace(re, `<body>${injectScript}${loadingHtml}`);
|
|
||||||
return html;
|
|
||||||
},
|
|
||||||
order: 'pre',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于获取loading的html模板
|
|
||||||
*/
|
|
||||||
async function getLoadingRawByHtmlTemplate(loadingTemplate: string) {
|
|
||||||
// 支持在app内自定义loading模板,模版参考default-loading.html即可
|
|
||||||
let appLoadingPath = join(process.cwd(), loadingTemplate);
|
|
||||||
|
|
||||||
if (!fs.existsSync(appLoadingPath)) {
|
|
||||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
||||||
appLoadingPath = join(__dirname, './default-loading.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fsp.readFile(appLoadingPath, 'utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
export { viteInjectAppLoadingPlugin };
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
|
|
||||||
import {
|
|
||||||
dateUtil,
|
|
||||||
findMonorepoRoot,
|
|
||||||
getPackages,
|
|
||||||
readPackageJSON,
|
|
||||||
} from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
import { readWorkspaceManifest } from '@pnpm/workspace.read-manifest';
|
|
||||||
|
|
||||||
function resolvePackageVersion(
|
|
||||||
pkgsMeta: Record<string, string>,
|
|
||||||
name: string,
|
|
||||||
value: string,
|
|
||||||
catalog: Record<string, string>,
|
|
||||||
) {
|
|
||||||
if (value.includes('catalog:')) {
|
|
||||||
return catalog[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('workspace')) {
|
|
||||||
return pkgsMeta[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function resolveMonorepoDependencies() {
|
|
||||||
const { packages } = await getPackages();
|
|
||||||
const manifest = await readWorkspaceManifest(findMonorepoRoot());
|
|
||||||
const catalog = manifest?.catalog || {};
|
|
||||||
|
|
||||||
const resultDevDependencies: Record<string, string | undefined> = {};
|
|
||||||
const resultDependencies: Record<string, string | undefined> = {};
|
|
||||||
const pkgsMeta: Record<string, string> = {};
|
|
||||||
|
|
||||||
for (const { packageJson } of packages) {
|
|
||||||
pkgsMeta[packageJson.name] = packageJson.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const { packageJson } of packages) {
|
|
||||||
const { dependencies = {}, devDependencies = {} } = packageJson;
|
|
||||||
for (const [key, value] of Object.entries(dependencies)) {
|
|
||||||
resultDependencies[key] = resolvePackageVersion(
|
|
||||||
pkgsMeta,
|
|
||||||
key,
|
|
||||||
value,
|
|
||||||
catalog,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (const [key, value] of Object.entries(devDependencies)) {
|
|
||||||
resultDevDependencies[key] = resolvePackageVersion(
|
|
||||||
pkgsMeta,
|
|
||||||
key,
|
|
||||||
value,
|
|
||||||
catalog,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
dependencies: resultDependencies,
|
|
||||||
devDependencies: resultDevDependencies,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于注入项目信息
|
|
||||||
*/
|
|
||||||
async function viteMetadataPlugin(
|
|
||||||
root = process.cwd(),
|
|
||||||
): Promise<PluginOption | undefined> {
|
|
||||||
const { author, description, homepage, license, version } =
|
|
||||||
await readPackageJSON(root);
|
|
||||||
|
|
||||||
const buildTime = dateUtil().format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
|
|
||||||
return {
|
|
||||||
async config() {
|
|
||||||
const { dependencies, devDependencies } =
|
|
||||||
await resolveMonorepoDependencies();
|
|
||||||
|
|
||||||
const isAuthorObject = typeof author === 'object';
|
|
||||||
const authorName = isAuthorObject ? author.name : author;
|
|
||||||
const authorEmail = isAuthorObject ? author.email : null;
|
|
||||||
const authorUrl = isAuthorObject ? author.url : null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
define: {
|
|
||||||
__APP_ADMIN_METADATA__: JSON.stringify({
|
|
||||||
authorEmail,
|
|
||||||
authorName,
|
|
||||||
authorUrl,
|
|
||||||
buildTime,
|
|
||||||
dependencies,
|
|
||||||
description,
|
|
||||||
devDependencies,
|
|
||||||
homepage,
|
|
||||||
license,
|
|
||||||
version,
|
|
||||||
}),
|
|
||||||
'import.meta.env.VITE_APP_VERSION': JSON.stringify(version),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
enforce: 'post',
|
|
||||||
name: 'vite:inject-metadata',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export { viteMetadataPlugin };
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
import type {
|
|
||||||
NormalizedOutputOptions,
|
|
||||||
OutputBundle,
|
|
||||||
OutputChunk,
|
|
||||||
} from 'rollup';
|
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
|
|
||||||
import { EOL } from 'node:os';
|
|
||||||
|
|
||||||
import { dateUtil, readPackageJSON } from '@aiflowy/node-utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于注入版权信息
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
|
|
||||||
async function viteLicensePlugin(
|
|
||||||
root = process.cwd(),
|
|
||||||
): Promise<PluginOption | undefined> {
|
|
||||||
const {
|
|
||||||
description = '',
|
|
||||||
homepage = '',
|
|
||||||
version = '',
|
|
||||||
} = await readPackageJSON(root);
|
|
||||||
|
|
||||||
return {
|
|
||||||
apply: 'build',
|
|
||||||
enforce: 'post',
|
|
||||||
generateBundle: {
|
|
||||||
handler: (_options: NormalizedOutputOptions, bundle: OutputBundle) => {
|
|
||||||
const date = dateUtil().format('YYYY-MM-DD ');
|
|
||||||
const copyrightText = `/*!
|
|
||||||
* AIFlowy Admin
|
|
||||||
* Version: ${version}
|
|
||||||
* Author: aiflowy
|
|
||||||
* Copyright (C) 2026 AIFlowy
|
|
||||||
* License: MIT License
|
|
||||||
* Description: ${description}
|
|
||||||
* Date Created: ${date}
|
|
||||||
* Homepage: ${homepage}
|
|
||||||
* Contact: fuhai999@gmail.com
|
|
||||||
*/
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
for (const [, fileContent] of Object.entries(bundle)) {
|
|
||||||
if (fileContent.type === 'chunk' && fileContent.isEntry) {
|
|
||||||
const chunkContent = fileContent as OutputChunk;
|
|
||||||
// 插入版权信息
|
|
||||||
const content = chunkContent.code;
|
|
||||||
const updatedContent = `${copyrightText}${EOL}${content}`;
|
|
||||||
|
|
||||||
// 更新bundle
|
|
||||||
(fileContent as OutputChunk).code = updatedContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
order: 'post',
|
|
||||||
},
|
|
||||||
name: 'vite:license',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export { viteLicensePlugin };
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue