From 28466c4e6935c09cee166a1a29481ebd459d96cd Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 17:13:35 +0800 Subject: [PATCH 1/8] feat(ui/eslint): add eslint plugin for artalk ui development - Implemented `eslint-plugin-artalk` to enforce Artalk's development conventions. - Added setup script for UI development environment. - Created test cases for Artalk plugin rules. - Configured TypeScript and build settings for the plugin. - Updated documentation with installation and configuration instructions. --- scripts/setup-ui-dev-env.mjs | 29 ++ ui/eslint-plugin-artalk/README.md | 121 ++++++++ ui/eslint-plugin-artalk/package.json | 38 +++ .../src/artalk-plugin.test.ts | 42 +++ ui/eslint-plugin-artalk/src/artalk-plugin.ts | 276 ++++++++++++++++++ ui/eslint-plugin-artalk/src/helper.ts | 6 + ui/eslint-plugin-artalk/src/main.ts | 12 + ui/eslint-plugin-artalk/src/test-helper.ts | 25 ++ ui/eslint-plugin-artalk/tsconfig.json | 7 + ui/eslint-plugin-artalk/tsup.config.ts | 21 ++ 10 files changed, 577 insertions(+) create mode 100644 scripts/setup-ui-dev-env.mjs create mode 100644 ui/eslint-plugin-artalk/README.md create mode 100644 ui/eslint-plugin-artalk/package.json create mode 100644 ui/eslint-plugin-artalk/src/artalk-plugin.test.ts create mode 100644 ui/eslint-plugin-artalk/src/artalk-plugin.ts create mode 100644 ui/eslint-plugin-artalk/src/helper.ts create mode 100644 ui/eslint-plugin-artalk/src/main.ts create mode 100644 ui/eslint-plugin-artalk/src/test-helper.ts create mode 100644 ui/eslint-plugin-artalk/tsconfig.json create mode 100644 ui/eslint-plugin-artalk/tsup.config.ts diff --git a/scripts/setup-ui-dev-env.mjs b/scripts/setup-ui-dev-env.mjs new file mode 100644 index 000000000..94d424acb --- /dev/null +++ b/scripts/setup-ui-dev-env.mjs @@ -0,0 +1,29 @@ +import { exec } from 'child_process' + +function runCommand(command) { + return new Promise((resolve, reject) => { + exec(command, (error, stdout, stderr) => { + if (error) { + reject(stderr || stdout) + } else { + resolve(stdout) + } + }) + }) +} + +async function build() { + try { + // Build Artalk Plugin Kit for plugin development + await runCommand('pnpm build:plugin-kit') + const green = '\x1b[32m' + console.log(green, '[ArtalkDev] build @artalk/plugin-kit success') + // Build Artalk eslint plugin for lint checking + await runCommand('pnpm build:eslint-plugin') + console.log(green, '[ArtalkDev] build eslint-plugin-artalk success') + } catch (error) { + console.error('[ArtalkDev] Artalk UI development environment setup failed:', error) + } +} + +build() diff --git a/ui/eslint-plugin-artalk/README.md b/ui/eslint-plugin-artalk/README.md new file mode 100644 index 000000000..5dabf9373 --- /dev/null +++ b/ui/eslint-plugin-artalk/README.md @@ -0,0 +1,121 @@ +# eslint-plugin-artalk [![npm](https://img.shields.io/npm/v/eslint-plugin-artalk)](https://www.npmjs.com/package/eslint-plugin-artalk) + +The ESLint plugin enforcing Artalk's development conventions. + +It is a part of the [Plugin Development Kit](https://artalk.js.org/develop/plugin.html) for Artalk. + +## Installation + +```bash +pnpm add -D eslint-plugin-artalk +``` + +Since Artalk development is based on TypeScript and the plugin relies on it, you need to install `typescript` and `@typescript-eslint/parser`. For more details, refer to [TypeScript ESLint](https://typescript-eslint.io/getting-started/). + +### Flat Configuration + +Modify the `eslint.config.mjs` file in your project: + + +```js +import eslintJs from '@eslint/js' +import eslintTs from 'typescript-eslint' +import pluginArtalk from 'eslint-plugin-artalk' + +export default eslintTs.config( + eslintJs.configs.recommended, + ...eslintTs.configs.recommended, + { + files: ['**/*.{ts,mts,cts,tsx,js,mjs,cjs}'], + languageOptions: { + parser: eslintTs.parser, + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: __dirname, + sourceType: 'module', + }, + }, + plugins: { + artalk: pluginArtalk, + }, + rules: { + ...pluginArtalk.configs.recommended.rules, + }, + } +) +``` + + + +### Custom Configuration + +You can customize the rules by modifying the `rules` field in the configuration: + +```js +{ + plugins: { + artalk: pluginArtalk, + }, + rules: { + 'artalk/artalk-plugin': 'error', + }, +} +``` + +## Valid and Invalid Examples + +### Rule `artalk-plugin` + +The ESLint rule `artalk/artalk-plugin` enforces the conventions for Artalk plugins. + +The ESLint rule is only enabled when a TypeScript file imports the `ArtalkPlugin` type from the `artalk` package and defines an arrow function variable with the type `ArtalkPlugin`, such as `const TestPlugin: ArtalkPlugin = (ctx) => {}`. The variable type must be `ArtalkPlugin`. + +#### `noLifeCycleEventInNestedBlocks` + +Should not allow life-cycle event listeners to be defined inside nested blocks. + +The life-cycle event listeners are `created`, `mounted`, `updated`, and `destroyed` must be defined in the top-level scope of the ArtalkPlugin arrow function. + +**⚠️ Fail**: + +```ts +import type { ArtalkPlugin } from 'artalk' + +export const TestPlugin: ArtalkPlugin = (ctx) => { + const foo = () => { + const bar = () => { + ctx.on('updated', () => {}) + } + } +} +``` + +**✅ Pass**: + +```ts +import type { ArtalkPlugin } from 'artalk' + +export const TestPlugin: ArtalkPlugin = (ctx) => { + ctx.on('updated', () => {}) +} +``` + +#### `noEventInWatchConf` + +Should not allow event listeners to be defined inside watchConf effect function. + +**⚠️ Fail**: + +```ts +import type { ArtalkPlugin } from 'artalk' + +export const TestPlugin: ArtalkPlugin = (ctx) => { + ctx.watchConf(['el'], (conf) => { + ctx.on('update', () => {}) + }) +} +``` + +## License + +[MIT](https://github.com/ArtalkJS/Artalk/blob/master/LICENSE) diff --git a/ui/eslint-plugin-artalk/package.json b/ui/eslint-plugin-artalk/package.json new file mode 100644 index 000000000..e76d6571b --- /dev/null +++ b/ui/eslint-plugin-artalk/package.json @@ -0,0 +1,38 @@ +{ + "name": "eslint-plugin-artalk", + "version": "1.0.0", + "type": "module", + "license": "MIT", + "homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/eslint-plugin-artalk", + "files": [ + "dist", + "README.md" + ], + "main": "dist/main.js", + "types": "dist/main.d.ts", + "exports": { + ".": { + "require": { + "types": "./dist/main.d.cjs", + "default": "./dist/main.cjs" + }, + "default": { + "types": "./dist/main.d.ts", + "default": "./dist/main.js" + } + } + }, + "scripts": { + "dev": "tsup --watch", + "build": "tsup", + "test": "vitest" + }, + "devDependencies": { + "@typescript-eslint/rule-tester": "^8.8.0", + "tsup": "^8.3.0" + }, + "peerDependencies": { + "@typescript-eslint/utils": ">=8", + "eslint": ">=9" + } +} diff --git a/ui/eslint-plugin-artalk/src/artalk-plugin.test.ts b/ui/eslint-plugin-artalk/src/artalk-plugin.test.ts new file mode 100644 index 000000000..2ddde59f8 --- /dev/null +++ b/ui/eslint-plugin-artalk/src/artalk-plugin.test.ts @@ -0,0 +1,42 @@ +import { artalkPlugin } from './artalk-plugin' +import { setupTest } from './test-helper' + +const { ruleTester } = setupTest() + +const invalid = [ + { + name: 'should not allow life-cycle event functions in nested blocks', + code: ` + import type { ArtalkPlugin } from 'artalk' + + export const TestPlugin: ArtalkPlugin = (ctx) => { + const foo = () => { + const bar = () => { + ctx.on('updated', () => {}) + } + } + } + `, + errorId: 'noLifeCycleEventInNestedBlocks', + }, + { + name: "should not allow 'off' call inside watchConf effect", + code: ` + import type { ArtalkPlugin } from 'artalk' + + export const TestPlugin: ArtalkPlugin = (ctx) => { + ctx.watchConf(['pageVote'], (conf) => { + ctx.off('updated', () => {}) + }) + } + `, + errorId: 'noEventInWatchConf', + }, +] + +for (const { name, code, errorId } of invalid) { + ruleTester.run(name, artalkPlugin as any, { + valid: [], + invalid: [{ code, errors: [{ messageId: errorId }] }], + }) +} diff --git a/ui/eslint-plugin-artalk/src/artalk-plugin.ts b/ui/eslint-plugin-artalk/src/artalk-plugin.ts new file mode 100644 index 000000000..5e8094203 --- /dev/null +++ b/ui/eslint-plugin-artalk/src/artalk-plugin.ts @@ -0,0 +1,276 @@ +import { AST_NODE_TYPES, TSESLint, TSESTree } from '@typescript-eslint/utils' +import type { ContextApi } from '../../artalk/src/types/context' +import { createRule } from './helper' +type _ = ContextApi // for IDE jump-to-definition + +/** Whether the given string is a ArtalkPlugin name */ +function isPluginName(s: string) { + return s === 'ArtalkPlugin' || /Artalk[A-Z0-9].*Plugin/.test(s) +} + +/** The event function names in ContextApi */ +const ctxEventFns = ['off', 'on', 'trigger'] + +/** The life-cycle event names in ContextApi */ +const ctxLifeCycleEvents = ['mounted', 'destroyed', 'updated', 'list-fetched'] + +export const artalkPlugin = createRule({ + name: 'artalk-plugin', + meta: { + type: 'problem', + docs: { + description: + 'Enforce best practices for ArtalkPlugin arrow functions, including ContextApi usage.', + }, + messages: { + noLifeCycleEventInNestedBlocks: + 'The life-cycle event `{{ eventName }}` listeners should only be defined in the top-level scope of the ArtalkPlugin.', + noEventInWatchConf: 'Avoid calling `{{ functionName }}` inside the `ctx.watchConf` effect.', + }, + schema: [], + }, + defaultOptions: [], + create(context) { + // Initialize the TypeScript parser services + const parserServices = context.sourceCode.parserServices + if (!parserServices || !parserServices.program) { + console.error('[eslint-plugin-artalk] Missing typescript parser services.') + return {} + } + const checker = parserServices.program.getTypeChecker() + + // ------------------------------------------------------------------- + // Utility functions + // ------------------------------------------------------------------- + const getTypeName = (node: TSESTree.Node) => { + const tsNode = parserServices?.esTreeNodeToTSNodeMap?.get(node) + const tsType = tsNode ? checker.getTypeAtLocation(tsNode) : null + const typeName = tsType ? checker.typeToString(tsType) : '' + return typeName + } + + const getArrowFunctionType = (node: TSESTree.Node) => { + if (node.type === 'ArrowFunctionExpression') return getTypeName(node) + return '' + } + + const isInsideArtalkPlugin = (node: TSESTree.Node) => { + let curr: TSESTree.Node | undefined = node + while (curr) { + if (isPluginName(getArrowFunctionType(curr))) return true + curr = curr.parent + } + return false + } + + /** + * Get the references to ContextApi in the top scope of the given scope + */ + const getCtxRefNamesInTopScope = (ctxArgName: string, scope: TSESLint.Scope.Scope) => { + const ctxRefs = new Map() + + const getFullMethodName = (node: TSESTree.Node) => { + const methodNameArr: string[] = [] + let curr: TSESTree.Node | undefined = node + while (curr) { + if (curr.type === 'MemberExpression' && curr.property.type === 'Identifier') + methodNameArr.push(curr.property.name) + curr = curr.parent + } + return methodNameArr.join('.') + } + + scope.references.forEach((reference) => { + const identifier = reference.identifier + if (identifier.name !== ctxArgName) return + + const methodName = getFullMethodName(identifier.parent) + if (methodName) ctxRefs.set(identifier.parent, methodName) + }) + + return ctxRefs + } + + /** + * Get the references to ContextApi in the nested scopes of the given + */ + const getCtxRefNamesInNestedScope = ( + ctxArgName: string, + parentScope: TSESLint.Scope.Scope, + keepTop = true, + ) => { + const ctxRefs = new Map() + keepTop && + getCtxRefNamesInTopScope(ctxArgName, parentScope).forEach((v, k) => ctxRefs.set(k, v)) + parentScope.childScopes.forEach((childScope) => { + getCtxRefNamesInNestedScope(ctxArgName, childScope).forEach((v, k) => ctxRefs.set(k, v)) + }) + return ctxRefs + } + + // ------------------------------------------------------------------- + // Checker functions + // ------------------------------------------------------------------- + + /** + * Check the set of all function names in ContextApi + * + * (which is called in the top-level of ArtalkPlugin arrow-function scope) + */ + const checkTopLevelCtxRefs = (m: Map) => { + // console.debug('checkTopLevelCtxFnCalls', m.values()) + // ... + } + + /** + * Check the set of all function names in ContextApi + * + * (which is called in the nested scopes of ArtalkPlugin arrow-function scope) + */ + const checkNestedCtxRefs = (m: Map) => { + // console.debug('checkAllCtxFnCalls', m.values()) + // ... + // TODO: Event Circular trigger Check + } + + /** + * Check the set of all function names in ContextApi + * + * (which is called in the nested scopes of ArtalkPlugin arrow-function scope, excluding the top-level) + */ + const checkNestedCtxRefsNoTop = (m: Map) => { + m.forEach((methodName, node) => { + // Disallow life-cycle events in nested blocks + if (methodName === 'on') { + // Get the call arguments + const parent = node.parent + if (!parent || parent.type !== 'CallExpression') return + if (parent.arguments.length == 0) return + const eventNameArg = parent.arguments[0] + if (eventNameArg.type !== 'Literal') return + const eventName = eventNameArg.value + if (typeof eventName !== 'string') return + if (ctxLifeCycleEvents.includes(eventName)) { + context.report({ + node: parent, + messageId: 'noLifeCycleEventInNestedBlocks', + data: { + eventName, + }, + }) + } + } + }) + } + + /** + * Check the set of all function names in ContextApi + * + * (which is called in the watchConf effect function scope) + */ + const checkWatchConfCalls = (m: Map) => { + const disallowedMethods = [...ctxEventFns] + m.forEach((methodName, node) => { + if (disallowedMethods.includes(methodName)) { + context.report({ + node: node.parent || node, + messageId: 'noEventInWatchConf', + data: { functionName: `ctx.${methodName}` }, + }) + } + }) + } + + /** + * Whether the ArtalkPlugin is imported + * + * (to enable the plugin checker) + */ + let pluginCheckerEnabled = false + + return { + ImportDeclaration(node) { + // Check if contains ArtalkPlugin importing + node.specifiers.forEach((specifier) => { + if (specifier.type !== 'ImportSpecifier') return + if (isPluginName(specifier.imported.name)) { + pluginCheckerEnabled = true + } + }) + }, + + VariableDeclaration(fnNode) { + if (!pluginCheckerEnabled) return + + // Check if the variable declaration is ArtalkPlugin + fnNode.declarations.forEach((decl) => { + if ( + isPluginName(getTypeName(decl)) && + decl.init && + decl.init?.type == 'ArrowFunctionExpression' + ) { + // Is ArtalkPlugin arrow-function + const pluginFn = decl.init + + // Get the first parameter name as the ContextApi reference + if (pluginFn.params.length === 0) return // No ctx reference + const ctxArg = pluginFn.params[0] + if (ctxArg.type !== 'Identifier') return + const ctxArgName = ctxArg.name + + // Visit the top-level scope of the ArtalkPlugin arrow-function + const pluginFnScope = context.sourceCode.getScope(pluginFn.body) + const topLevelCtxRefs = getCtxRefNamesInTopScope(ctxArgName, pluginFnScope) + checkTopLevelCtxRefs(topLevelCtxRefs) + + // Visit all nested scopes (including the top-level) of the ArtalkPlugin arrow-function + const nestedCtxRefsIncludeTop = getCtxRefNamesInNestedScope( + ctxArgName, + pluginFnScope, + true, + ) + checkNestedCtxRefs(nestedCtxRefsIncludeTop) + + // Visit all nested scopes (excluding the top-level) of the ArtalkPlugin arrow-function + const nestedCtxRefsExcludeTop = getCtxRefNamesInNestedScope( + ctxArgName, + pluginFnScope, + false, + ) + checkNestedCtxRefsNoTop(nestedCtxRefsExcludeTop) + + // Visit watchConf effect function scope + const watchConfCalls = new Map() + topLevelCtxRefs.forEach((v, k) => { + if (v === 'watchConf') { + // Get the watchConf call expression + const watchConfCall = k.parent + if (!watchConfCall || watchConfCall.type !== AST_NODE_TYPES.CallExpression) return + + // Get the watchConf effect function + if (watchConfCall.arguments.length < 2) return + const watchConfEffectFn = watchConfCall.arguments[1] + if ( + watchConfEffectFn.type !== 'ArrowFunctionExpression' && + watchConfEffectFn.type !== 'FunctionExpression' + ) + return + + // Get the references to ContextApi in the watchConf effect function top scope + const scope = context.sourceCode.getScope(watchConfEffectFn.body) + getCtxRefNamesInTopScope(ctxArgName, scope).forEach((v, k) => + watchConfCalls.set(k, v), + ) + } + }) + checkWatchConfCalls(watchConfCalls) + } + }) + }, + + Identifier(node) {}, + + CallExpression(node) {}, + } + }, +}) diff --git a/ui/eslint-plugin-artalk/src/helper.ts b/ui/eslint-plugin-artalk/src/helper.ts new file mode 100644 index 000000000..3ffdcd402 --- /dev/null +++ b/ui/eslint-plugin-artalk/src/helper.ts @@ -0,0 +1,6 @@ +import { ESLintUtils } from '@typescript-eslint/utils' + +export const createRule = ESLintUtils.RuleCreator( + (name) => + `https://github.com/ArtalkJS/Artalk/tree/master/ui/eslint-plugin-artalk/README.md#rule-${name}`, +) diff --git a/ui/eslint-plugin-artalk/src/main.ts b/ui/eslint-plugin-artalk/src/main.ts new file mode 100644 index 000000000..4a119df59 --- /dev/null +++ b/ui/eslint-plugin-artalk/src/main.ts @@ -0,0 +1,12 @@ +import { artalkPlugin } from './artalk-plugin' + +export const rules = { + 'artalk-plugin': artalkPlugin, +} + +export default { + rules, + configs: { + recommended: { plugins: ['artalk'], rules: { 'artalk/artalk-plugin': 'warn' } }, + }, +} diff --git a/ui/eslint-plugin-artalk/src/test-helper.ts b/ui/eslint-plugin-artalk/src/test-helper.ts new file mode 100644 index 000000000..99f41c352 --- /dev/null +++ b/ui/eslint-plugin-artalk/src/test-helper.ts @@ -0,0 +1,25 @@ +import * as vitest from 'vitest' +import { RuleTester } from '@typescript-eslint/rule-tester' + +let ruleTester: RuleTester | undefined + +export function setupTest() { + if (ruleTester) return { ruleTester } + + RuleTester.afterAll = vitest.afterAll + RuleTester.it = vitest.it + RuleTester.itOnly = vitest.it.only + RuleTester.describe = vitest.describe + + ruleTester = new RuleTester({ + languageOptions: { + parserOptions: { + projectService: { + allowDefaultProject: ['*.ts*'], + }, + }, + }, + }) + + return { ruleTester } +} diff --git a/ui/eslint-plugin-artalk/tsconfig.json b/ui/eslint-plugin-artalk/tsconfig.json new file mode 100644 index 000000000..122e9c5f0 --- /dev/null +++ b/ui/eslint-plugin-artalk/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "dist" + } +} diff --git a/ui/eslint-plugin-artalk/tsup.config.ts b/ui/eslint-plugin-artalk/tsup.config.ts new file mode 100644 index 000000000..613ab5571 --- /dev/null +++ b/ui/eslint-plugin-artalk/tsup.config.ts @@ -0,0 +1,21 @@ +import { defineConfig, Options } from 'tsup' + +const shared: Options = { + format: ['esm', 'cjs'], + target: 'node14', + platform: 'node', + shims: true, + splitting: false, + bundle: true, + sourcemap: true, + clean: false, + dts: true, +} + +export default defineConfig([ + { + ...shared, + outDir: 'dist', + entry: ['src/main.ts'], + }, +]) From 9298f8034b859c7fbac87138ebce8248214dd974 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 17:18:37 +0800 Subject: [PATCH 2/8] chore: fix deps --- pnpm-lock.yaml | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb684f64a..62001f889 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -292,6 +292,22 @@ importers: specifier: ^2.5.1 version: 2.5.1 + ui/eslint-plugin-artalk: + dependencies: + '@typescript-eslint/utils': + specifier: '>=8' + version: 8.6.0(eslint@9.10.0)(typescript@5.6.2) + eslint: + specifier: '>=9' + version: 9.10.0 + devDependencies: + '@typescript-eslint/rule-tester': + specifier: ^8.8.0 + version: 8.8.0(eslint@9.10.0)(typescript@5.6.2) + tsup: + specifier: ^8.3.0 + version: 8.3.0(@microsoft/api-extractor@7.47.9(@types/node@22.5.5))(@swc/core@1.7.26(@swc/helpers@0.5.13))(postcss@8.4.47)(tsx@4.19.1)(typescript@5.6.2)(yaml@2.5.1) + ui/plugin-auth: dependencies: artalk: @@ -1551,10 +1567,20 @@ packages: typescript: optional: true + '@typescript-eslint/rule-tester@8.8.0': + resolution: {integrity: sha512-Mz41m89RzbOQfdsQ5lYV7gYghL4yumlULV/VBsKSkhZwYckKfNYD/MgkBBMHCTwtFpcPQKUhxHF5q6feyXAKfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/scope-manager@8.6.0': resolution: {integrity: sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.8.0': + resolution: {integrity: sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/type-utils@8.6.0': resolution: {integrity: sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1568,6 +1594,10 @@ packages: resolution: {integrity: sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.8.0': + resolution: {integrity: sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.6.0': resolution: {integrity: sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1577,16 +1607,35 @@ packages: typescript: optional: true + '@typescript-eslint/typescript-estree@8.8.0': + resolution: {integrity: sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/utils@8.6.0': resolution: {integrity: sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/utils@8.8.0': + resolution: {integrity: sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/visitor-keys@8.6.0': resolution: {integrity: sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.8.0': + resolution: {integrity: sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} @@ -6026,11 +6075,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/rule-tester@8.8.0(eslint@9.10.0)(typescript@5.6.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.6.2) + '@typescript-eslint/utils': 8.8.0(eslint@9.10.0)(typescript@5.6.2) + ajv: 6.12.6 + eslint: 9.10.0 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/scope-manager@8.6.0': dependencies: '@typescript-eslint/types': 8.6.0 '@typescript-eslint/visitor-keys': 8.6.0 + '@typescript-eslint/scope-manager@8.8.0': + dependencies: + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/visitor-keys': 8.8.0 + '@typescript-eslint/type-utils@8.6.0(eslint@9.10.0)(typescript@5.6.2)': dependencies: '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.6.2) @@ -6045,6 +6112,8 @@ snapshots: '@typescript-eslint/types@8.6.0': {} + '@typescript-eslint/types@8.8.0': {} + '@typescript-eslint/typescript-estree@8.6.0(typescript@5.6.2)': dependencies: '@typescript-eslint/types': 8.6.0 @@ -6060,6 +6129,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.8.0(typescript@5.6.2)': + dependencies: + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/visitor-keys': 8.8.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.6.0(eslint@9.10.0)(typescript@5.6.2)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) @@ -6071,11 +6155,27 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@8.8.0(eslint@9.10.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@typescript-eslint/scope-manager': 8.8.0 + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.6.2) + eslint: 9.10.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/visitor-keys@8.6.0': dependencies: '@typescript-eslint/types': 8.6.0 eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@8.8.0': + dependencies: + '@typescript-eslint/types': 8.8.0 + eslint-visitor-keys: 3.4.3 + '@ungap/structured-clone@1.2.0': {} '@vitejs/plugin-react-swc@3.7.0(@swc/helpers@0.5.13)(vite@5.4.6(@types/node@22.5.5)(sass@1.79.1)(terser@5.33.0))': From 2459bf02429ee346ee043b80d0ede00ecc86c615 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 17:26:14 +0800 Subject: [PATCH 3/8] add postinstall script in package.json --- eslint.config.mjs | 3 +++ package.json | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 7538f48e1..85f5020b4 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -14,6 +14,7 @@ import pluginVue from 'eslint-plugin-vue' import globals from 'globals' import eslintTs from 'typescript-eslint' import vueParser from 'vue-eslint-parser' +import pluginArtalk from 'eslint-plugin-artalk' const __dirname = path.dirname(url.fileURLToPath(import.meta.url)) const tsProjects = ['./tsconfig.base.json', './ui/*/tsconfig.json', './docs/*/tsconfig.json'] @@ -65,9 +66,11 @@ export default eslintTs.config( plugins: { '@typescript-eslint': pluginTS, 'import-x': pluginImportX, + artalk: pluginArtalk, }, rules: { ...pluginImportX.configs.recommended.rules, + ...pluginArtalk.configs.recommended.rules, '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-unused-vars': 'off', '@typescript-eslint/no-unused-expressions': [ diff --git a/package.json b/package.json index 761714b4b..8fdc31fda 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,17 @@ "build": "pnpm -F artalk build", "build:sidebar": "pnpm -F @artalk/artalk-sidebar build", "build:plugin-kit": "pnpm -F @artalk/plugin-kit build", + "build:eslint-plugin": "pnpm -F eslint-plugin-artalk build", "build:auth": "pnpm -F @artalk/plugin-auth build", - "build:all": "pnpm build && pnpm build:sidebar && pnpm build:plugin-kit", + "build:all": "pnpm build && pnpm build:sidebar", "build:docs": "pnpm build && pnpm -F=docs-landing build && pnpm -F=docs-swagger swagger:build && pnpm -F=docs build:docs && pnpm patch:docs", "patch:docs": "cp -rf docs/landing/dist/* docs/swagger/dist/* docs/docs/.vitepress/dist", "lint:eslint": "eslint .", "lint:prettier": "prettier --check .", "lint": "pnpm lint:eslint && pnpm lint:prettier", "lint:fix": "pnpm lint:eslint --fix && pnpm lint:prettier --write", - "test": "pnpm -F artalk test" + "test": "pnpm -F artalk test", + "postinstall": "node scripts/setup-ui-dev-env.mjs" }, "devDependencies": { "@eslint/compat": "^1.1.1", @@ -33,6 +35,7 @@ "eslint": "^9.10.0", "eslint-config-prettier": "9.1.0", "eslint-import-resolver-typescript": "3.6.3", + "eslint-plugin-artalk": "workspace:^", "eslint-plugin-compat": "^6.0.1", "eslint-plugin-import-x": "^4.2.1", "eslint-plugin-react": "^7.36.1", From da4c0935d5ed11c0ce22add5a1c773469107b1dd Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 17:39:42 +0800 Subject: [PATCH 4/8] update setup-ui-dev-env.mjs --- pnpm-lock.yaml | 3 +++ scripts/setup-ui-dev-env.mjs | 30 +++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62001f889..865cf4eea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: eslint-import-resolver-typescript: specifier: 3.6.3 version: 3.6.3(@typescript-eslint/parser@8.6.0(eslint@9.10.0)(typescript@5.6.2))(eslint-plugin-import-x@4.2.1(eslint@9.10.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0) + eslint-plugin-artalk: + specifier: workspace:^ + version: link:ui/eslint-plugin-artalk eslint-plugin-compat: specifier: ^6.0.1 version: 6.0.1(eslint@9.10.0) diff --git a/scripts/setup-ui-dev-env.mjs b/scripts/setup-ui-dev-env.mjs index 94d424acb..064204f2d 100644 --- a/scripts/setup-ui-dev-env.mjs +++ b/scripts/setup-ui-dev-env.mjs @@ -1,4 +1,9 @@ import { exec } from 'child_process' +import { accessSync } from 'fs' +import { resolve } from 'path' + +const __dirname = new URL('.', import.meta.url).pathname +const forceBuild = process.env.ATK_DEV_TOOLCHAIN_FORCE_BUILD === '1' function runCommand(command) { return new Promise((resolve, reject) => { @@ -12,15 +17,30 @@ function runCommand(command) { }) } +function checkFolderExists(pathname) { + if (forceBuild) return false + try { + accessSync(resolve(__dirname, '../', pathname)) + return true + } catch (error) { + return false + } +} + +const green = '\x1b[32m' + async function build() { try { // Build Artalk Plugin Kit for plugin development - await runCommand('pnpm build:plugin-kit') - const green = '\x1b[32m' - console.log(green, '[ArtalkDev] build @artalk/plugin-kit success') + if (!checkFolderExists('ui/plugin-kit/dist')) { + await runCommand('pnpm build:plugin-kit') + console.log(green, '[ArtalkDev] build @artalk/plugin-kit success') + } // Build Artalk eslint plugin for lint checking - await runCommand('pnpm build:eslint-plugin') - console.log(green, '[ArtalkDev] build eslint-plugin-artalk success') + if (!checkFolderExists('ui/eslint-plugin-artalk/dist')) { + await runCommand('pnpm build:eslint-plugin') + console.log(green, '[ArtalkDev] build eslint-plugin-artalk success') + } } catch (error) { console.error('[ArtalkDev] Artalk UI development environment setup failed:', error) } From 42aa5932557e616cf0e1fb48e4986401692061db Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 19:03:32 +0800 Subject: [PATCH 5/8] update package.json --- ui/plugin-auth/package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ui/plugin-auth/package.json b/ui/plugin-auth/package.json index 5cefe5f96..7c750033d 100644 --- a/ui/plugin-auth/package.json +++ b/ui/plugin-auth/package.json @@ -27,12 +27,9 @@ "build": "vite build", "serve": "vite preview" }, - "dependencies": { - "artalk": "workspace:^" - }, "devDependencies": { + "artalk": "workspace:^", "solid-js": "^1.8.22", - "@artalk/plugin-kit": "workspace:^", "vite-plugin-css-injected-by-js": "^3.5.1", "vite-plugin-solid": "^2.10.2" }, From 700daca1315e16f652ee5485701f35136e770408 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 19:04:12 +0800 Subject: [PATCH 6/8] update package.json --- .github/workflows/test-frontend.yml | 5 +- docs/docs/package.json | 8 +- docs/landing/package.json | 6 +- package.json | 11 +- pnpm-lock.yaml | 144 ++++++++++++++++----------- scripts/setup-ui-dev-env.mjs | 49 --------- test/lightbox/package.json | 2 +- test/vue-test/package.json | 8 +- ui/artalk/package.json | 2 +- ui/eslint-plugin-artalk/package.json | 9 +- ui/plugin-katex/package.json | 6 +- ui/plugin-kit/package.json | 4 +- ui/plugin-lightbox/package.json | 7 +- 13 files changed, 117 insertions(+), 144 deletions(-) delete mode 100644 scripts/setup-ui-dev-env.mjs diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index dac04932b..5d8f224ef 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -45,9 +45,12 @@ jobs: - name: Package Build Test run: pnpm build:all - - name: Unit test + - name: Unit Test run: pnpm test + - name: Plugins Build Test + run: pnpm build:plugins + - name: Lint run: pnpm eslint ui && pnpm prettier --check ui diff --git a/docs/docs/package.json b/docs/docs/package.json index c2c73361f..3525c1cb1 100644 --- a/docs/docs/package.json +++ b/docs/docs/package.json @@ -16,11 +16,9 @@ }, "devDependencies": { "artalk": "workspace:^", - "vitepress": "1.3.4" - }, - "dependencies": { - "@artalk/plugin-katex": "^0.2.3", - "@artalk/plugin-lightbox": "^0.2.3", + "vitepress": "1.3.4", + "@artalk/plugin-katex": "^0.2.4", + "@artalk/plugin-lightbox": "^0.2.4", "katex": "^0.16.11", "lightgallery": "^2.7.2", "vue": "^3.5.6" diff --git a/docs/landing/package.json b/docs/landing/package.json index ed486aefc..cc67daec3 100644 --- a/docs/landing/package.json +++ b/docs/landing/package.json @@ -14,14 +14,12 @@ "preview": "vite preview", "update:readme": "npx tsx ./scripts/update-readme.ts" }, - "dependencies": { + "devDependencies": { "include-media": "^2.0.0", "normalize.css": "^8.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-icons": "5.3.0" - }, - "devDependencies": { + "react-icons": "5.3.0", "@headlessui/react": "^2.1.8", "@types/react": "^18.3.7", "@types/react-dom": "^18.3.0", diff --git a/package.json b/package.json index 8fdc31fda..532ee0d4e 100644 --- a/package.json +++ b/package.json @@ -10,20 +10,21 @@ "dev:landing": "pnpm -F=docs-landing dev", "build": "pnpm -F artalk build", "build:sidebar": "pnpm -F @artalk/artalk-sidebar build", + "build:all": "pnpm build && pnpm build:sidebar", + "build:plugins": "pnpm -F @artalk/plugin-* build", + "build:auth": "pnpm -F @artalk/plugin-auth build", "build:plugin-kit": "pnpm -F @artalk/plugin-kit build", "build:eslint-plugin": "pnpm -F eslint-plugin-artalk build", - "build:auth": "pnpm -F @artalk/plugin-auth build", - "build:all": "pnpm build && pnpm build:sidebar", "build:docs": "pnpm build && pnpm -F=docs-landing build && pnpm -F=docs-swagger swagger:build && pnpm -F=docs build:docs && pnpm patch:docs", "patch:docs": "cp -rf docs/landing/dist/* docs/swagger/dist/* docs/docs/.vitepress/dist", "lint:eslint": "eslint .", "lint:prettier": "prettier --check .", "lint": "pnpm lint:eslint && pnpm lint:prettier", "lint:fix": "pnpm lint:eslint --fix && pnpm lint:prettier --write", - "test": "pnpm -F artalk test", - "postinstall": "node scripts/setup-ui-dev-env.mjs" + "test": "pnpm -F artalk test" }, "devDependencies": { + "@artalk/plugin-kit": "^1.0.6", "@eslint/compat": "^1.1.1", "@eslint/js": "^9.10.0", "@playwright/test": "^1.47.1", @@ -35,7 +36,7 @@ "eslint": "^9.10.0", "eslint-config-prettier": "9.1.0", "eslint-import-resolver-typescript": "3.6.3", - "eslint-plugin-artalk": "workspace:^", + "eslint-plugin-artalk": "^1.0.1", "eslint-plugin-compat": "^6.0.1", "eslint-plugin-import-x": "^4.2.1", "eslint-plugin-react": "^7.36.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 865cf4eea..907260696 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: devDependencies: + '@artalk/plugin-kit': + specifier: ^1.0.6 + version: 1.0.6(@types/node@22.5.5)(artalk@2.9.1(marked@14.1.2))(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0)) '@eslint/compat': specifier: ^1.1.1 version: 1.1.1 @@ -42,8 +45,8 @@ importers: specifier: 3.6.3 version: 3.6.3(@typescript-eslint/parser@8.6.0(eslint@9.10.0)(typescript@5.6.2))(eslint-plugin-import-x@4.2.1(eslint@9.10.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0) eslint-plugin-artalk: - specifier: workspace:^ - version: link:ui/eslint-plugin-artalk + specifier: ^1.0.1 + version: 1.0.1(eslint@9.10.0)(typescript@5.6.2) eslint-plugin-compat: specifier: ^6.0.1 version: 6.0.1(eslint@9.10.0) @@ -112,47 +115,30 @@ importers: version: 9.4.3(eslint@9.10.0) docs/docs: - dependencies: + devDependencies: '@artalk/plugin-katex': specifier: ^0.2.3 version: 0.2.3(@types/katex@0.16.7)(artalk@ui+artalk)(katex@0.16.11) '@artalk/plugin-lightbox': specifier: ^0.2.3 version: 0.2.3(artalk@ui+artalk)(fancybox@3.0.1)(lightbox2@2.11.4)(lightgallery@2.7.2)(photoswipe@5.4.4) + artalk: + specifier: workspace:^ + version: link:../../ui/artalk katex: specifier: ^0.16.11 version: 0.16.11 lightgallery: specifier: ^2.7.2 version: 2.7.2 - vue: - specifier: ^3.5.6 - version: 3.5.6(typescript@5.6.2) - devDependencies: - artalk: - specifier: workspace:^ - version: link:../../ui/artalk vitepress: specifier: 1.3.4 version: 1.3.4(@algolia/client-search@5.4.3)(@types/node@22.5.5)(@types/react@18.3.7)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.79.1)(search-insights@2.17.2)(terser@5.33.0)(typescript@5.6.2) + vue: + specifier: ^3.5.6 + version: 3.5.6(typescript@5.6.2) docs/landing: - dependencies: - include-media: - specifier: ^2.0.0 - version: 2.0.0 - normalize.css: - specifier: ^8.0.1 - version: 8.0.1 - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - react-icons: - specifier: 5.3.0 - version: 5.3.0(react@18.3.1) devDependencies: '@headlessui/react': specifier: ^2.1.8 @@ -172,9 +158,24 @@ importers: i18next-browser-languagedetector: specifier: ^8.0.0 version: 8.0.0 + include-media: + specifier: ^2.0.0 + version: 2.0.0 + normalize.css: + specifier: ^8.0.1 + version: 8.0.1 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^15.0.2 version: 15.0.2(i18next@23.15.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-icons: + specifier: 5.3.0 + version: 5.3.0(react@18.3.1) usehooks-ts: specifier: ^3.1.0 version: 3.1.0(react@18.3.1) @@ -186,7 +187,7 @@ importers: version: 1.25.2(enzyme@3.11.0) test/lightbox: - dependencies: + devDependencies: '@artalk/plugin-lightbox': specifier: workspace:^ version: link:../../ui/plugin-lightbox @@ -210,16 +211,6 @@ importers: version: 5.4.4 test/vue-test: - dependencies: - artalk: - specifier: workspace:* - version: link:../../ui/artalk - vue: - specifier: ^3.5.6 - version: 3.5.6(typescript@5.6.2) - vue-router: - specifier: ^4.4.5 - version: 4.4.5(vue@3.5.6(typescript@5.6.2)) devDependencies: '@tsconfig/node18': specifier: ^18.2.4 @@ -233,6 +224,15 @@ importers: '@vue/tsconfig': specifier: ^0.5.1 version: 0.5.1 + artalk: + specifier: workspace:^ + version: link:../../ui/artalk + vue: + specifier: ^3.5.6 + version: 3.5.6(typescript@5.6.2) + vue-router: + specifier: ^4.4.5 + version: 4.4.5(vue@3.5.6(typescript@5.6.2)) vue-tsc: specifier: ^2.1.6 version: 2.1.6(typescript@5.6.2) @@ -298,8 +298,8 @@ importers: ui/eslint-plugin-artalk: dependencies: '@typescript-eslint/utils': - specifier: '>=8' - version: 8.6.0(eslint@9.10.0)(typescript@5.6.2) + specifier: ^8.8.0 + version: 8.8.0(eslint@9.10.0)(typescript@5.6.2) eslint: specifier: '>=9' version: 9.10.0 @@ -312,14 +312,10 @@ importers: version: 8.3.0(@microsoft/api-extractor@7.47.9(@types/node@22.5.5))(@swc/core@1.7.26(@swc/helpers@0.5.13))(postcss@8.4.47)(tsx@4.19.1)(typescript@5.6.2)(yaml@2.5.1) ui/plugin-auth: - dependencies: + devDependencies: artalk: specifier: workspace:^ version: link:../artalk - devDependencies: - '@artalk/plugin-kit': - specifier: workspace:^ - version: link:../plugin-kit solid-js: specifier: ^1.8.22 version: 1.8.22 @@ -335,16 +331,13 @@ importers: '@types/katex': specifier: ^0.16.7 version: 0.16.7 - artalk: - specifier: workspace:^ - version: link:../artalk katex: specifier: ^0.16.11 version: 0.16.11 devDependencies: - '@artalk/plugin-kit': + artalk: specifier: workspace:^ - version: link:../plugin-kit + version: link:../artalk marked: specifier: ^14.1.2 version: 14.1.2 @@ -354,9 +347,6 @@ importers: '@microsoft/api-extractor': specifier: ^7.47.9 version: 7.47.9(@types/node@22.5.5) - artalk: - specifier: workspace:^ - version: link:../artalk picocolors: specifier: ^1.1.0 version: 1.1.0 @@ -367,6 +357,9 @@ importers: specifier: '*' version: 5.4.2(@types/node@22.5.5)(sass@1.79.1)(terser@5.33.0) devDependencies: + artalk: + specifier: workspace:^ + version: link:../artalk esbuild-plugin-raw: specifier: ^0.1.8 version: 0.1.8(esbuild@0.23.1) @@ -375,14 +368,10 @@ importers: version: 8.3.0(@microsoft/api-extractor@7.47.9(@types/node@22.5.5))(@swc/core@1.7.26(@swc/helpers@0.5.13))(postcss@8.4.47)(tsx@4.19.1)(typescript@5.6.2)(yaml@2.5.1) ui/plugin-lightbox: - dependencies: + devDependencies: artalk: specifier: workspace:^ version: link:../artalk - devDependencies: - '@artalk/plugin-kit': - specifier: workspace:^ - version: link:../plugin-kit fancybox: specifier: ^3.0.1 version: 3.0.1 @@ -497,6 +486,13 @@ packages: artalk: ^2.9.0 katex: ^0.16.11 + '@artalk/plugin-kit@1.0.6': + resolution: {integrity: sha512-ejbzkYmlGFPrHS9kzbMDU612fDXPmx1iN+jzNyF5I44K5B50zr4LcGRD3RevB9ohtdLxPV7C2nMwex33ok0tfA==} + peerDependencies: + artalk: ^2.9.0 + typescript: '*' + vite: '*' + '@artalk/plugin-lightbox@0.2.3': resolution: {integrity: sha512-avmW2pu5rrWnDjRrPj4CM9QrnGJQNMqaY/o5+nH1d/eo7HURlRPiy5/yZFAk7ccbvH6t5c/PtcygGLbRft2M2A==} peerDependencies: @@ -1942,6 +1938,11 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} + artalk@2.9.1: + resolution: {integrity: sha512-IFo9XqWDalsHy8BsmMA5SSB9bozBa/sBhTm/+O5KwA6DnC95lFKv7C6ScMx/Xa4ue5qSQ7VV5vxRgCh/raohkQ==} + peerDependencies: + marked: ^14.1.0 + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -2467,6 +2468,11 @@ packages: eslint-import-resolver-webpack: optional: true + eslint-plugin-artalk@1.0.1: + resolution: {integrity: sha512-mEgJj6kqfgDqHHmHVH6O06s3bhINyBb6TItYkbsASsO3+2WCB8CGHqFxz7vqoyymFH5n6x1GwevfPWlbOg3Kgw==} + peerDependencies: + eslint: '>=9' + eslint-plugin-compat@6.0.1: resolution: {integrity: sha512-0MeIEuoy8kWkOhW38kK8hU4vkb6l/VvyjpuYDymYOXmUY9NvTgyErF16lYuX+HPS5hkmym7lfA+XpYZiWYWmYA==} engines: {node: '>=18.x'} @@ -5057,6 +5063,16 @@ snapshots: artalk: link:ui/artalk katex: 0.16.11 + '@artalk/plugin-kit@1.0.6(@types/node@22.5.5)(artalk@2.9.1(marked@14.1.2))(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0))': + dependencies: + '@microsoft/api-extractor': 7.47.9(@types/node@22.5.5) + artalk: 2.9.1(marked@14.1.2) + picocolors: 1.1.0 + typescript: 5.6.2 + vite: 5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0) + transitivePeerDependencies: + - '@types/node' + '@artalk/plugin-lightbox@0.2.3(artalk@ui+artalk)(fancybox@3.0.1)(lightbox2@2.11.4)(lightgallery@2.7.2)(photoswipe@5.4.4)': dependencies: artalk: link:ui/artalk @@ -6580,6 +6596,10 @@ snapshots: is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 + artalk@2.9.1(marked@14.1.2): + dependencies: + marked: 14.1.2 + assertion-error@2.0.1: {} assignment@2.0.0: {} @@ -7228,6 +7248,14 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-artalk@1.0.1(eslint@9.10.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/utils': 8.8.0(eslint@9.10.0)(typescript@5.6.2) + eslint: 9.10.0 + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-compat@6.0.1(eslint@9.10.0): dependencies: '@mdn/browser-compat-data': 5.6.0 @@ -7242,7 +7270,7 @@ snapshots: eslint-plugin-import-x@4.2.1(eslint@9.10.0)(typescript@5.6.2): dependencies: - '@typescript-eslint/utils': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/utils': 8.8.0(eslint@9.10.0)(typescript@5.6.2) debug: 4.3.7 doctrine: 3.0.0 eslint: 9.10.0 diff --git a/scripts/setup-ui-dev-env.mjs b/scripts/setup-ui-dev-env.mjs deleted file mode 100644 index 064204f2d..000000000 --- a/scripts/setup-ui-dev-env.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import { exec } from 'child_process' -import { accessSync } from 'fs' -import { resolve } from 'path' - -const __dirname = new URL('.', import.meta.url).pathname -const forceBuild = process.env.ATK_DEV_TOOLCHAIN_FORCE_BUILD === '1' - -function runCommand(command) { - return new Promise((resolve, reject) => { - exec(command, (error, stdout, stderr) => { - if (error) { - reject(stderr || stdout) - } else { - resolve(stdout) - } - }) - }) -} - -function checkFolderExists(pathname) { - if (forceBuild) return false - try { - accessSync(resolve(__dirname, '../', pathname)) - return true - } catch (error) { - return false - } -} - -const green = '\x1b[32m' - -async function build() { - try { - // Build Artalk Plugin Kit for plugin development - if (!checkFolderExists('ui/plugin-kit/dist')) { - await runCommand('pnpm build:plugin-kit') - console.log(green, '[ArtalkDev] build @artalk/plugin-kit success') - } - // Build Artalk eslint plugin for lint checking - if (!checkFolderExists('ui/eslint-plugin-artalk/dist')) { - await runCommand('pnpm build:eslint-plugin') - console.log(green, '[ArtalkDev] build eslint-plugin-artalk success') - } - } catch (error) { - console.error('[ArtalkDev] Artalk UI development environment setup failed:', error) - } -} - -build() diff --git a/test/lightbox/package.json b/test/lightbox/package.json index dfc606c49..c5e39914d 100644 --- a/test/lightbox/package.json +++ b/test/lightbox/package.json @@ -8,7 +8,7 @@ "build": "tsc && vite build", "preview": "vite preview" }, - "dependencies": { + "devDependencies": { "jquery": "^3.7.1", "@artalk/plugin-lightbox": "workspace:^", "artalk": "workspace:^", diff --git a/test/vue-test/package.json b/test/vue-test/package.json index ae868aeaf..5d3889739 100644 --- a/test/vue-test/package.json +++ b/test/vue-test/package.json @@ -8,12 +8,10 @@ "build": "vue-tsc && vite build", "preview": "vite preview" }, - "dependencies": { - "artalk": "workspace:*", - "vue": "^3.5.6", - "vue-router": "^4.4.5" - }, "devDependencies": { + "artalk": "workspace:^", + "vue": "^3.5.6", + "vue-router": "^4.4.5", "@tsconfig/node18": "^18.2.4", "@types/node": "^22.5.5", "@vitejs/plugin-vue": "^5.1.4", diff --git a/ui/artalk/package.json b/ui/artalk/package.json index c585b9b20..75f07f6a5 100644 --- a/ui/artalk/package.json +++ b/ui/artalk/package.json @@ -153,6 +153,6 @@ "marked": "^14.1.2" }, "peerDependencies": { - "marked": "^14.1.0" + "marked": "^14.1.2" } } diff --git a/ui/eslint-plugin-artalk/package.json b/ui/eslint-plugin-artalk/package.json index e76d6571b..ac7c06968 100644 --- a/ui/eslint-plugin-artalk/package.json +++ b/ui/eslint-plugin-artalk/package.json @@ -1,12 +1,11 @@ { "name": "eslint-plugin-artalk", - "version": "1.0.0", + "version": "1.0.1", "type": "module", "license": "MIT", "homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/eslint-plugin-artalk", "files": [ - "dist", - "README.md" + "dist" ], "main": "dist/main.js", "types": "dist/main.d.ts", @@ -27,12 +26,14 @@ "build": "tsup", "test": "vitest" }, + "dependencies": { + "@typescript-eslint/utils": "^8.8.0" + }, "devDependencies": { "@typescript-eslint/rule-tester": "^8.8.0", "tsup": "^8.3.0" }, "peerDependencies": { - "@typescript-eslint/utils": ">=8", "eslint": ">=9" } } diff --git a/ui/plugin-katex/package.json b/ui/plugin-katex/package.json index 14dd5663f..7a8a654dc 100644 --- a/ui/plugin-katex/package.json +++ b/ui/plugin-katex/package.json @@ -1,7 +1,6 @@ { "name": "@artalk/plugin-katex", - "version": "0.2.3", - "minAppVersion": "2.8.6", + "version": "0.2.4", "license": "MIT", "description": "The katex plugin for artalk", "type": "module", @@ -18,11 +17,10 @@ }, "dependencies": { "@types/katex": "^0.16.7", - "artalk": "workspace:^", "katex": "^0.16.11" }, "devDependencies": { - "@artalk/plugin-kit": "workspace:^", + "artalk": "workspace:^", "marked": "^14.1.2" }, "peerDependencies": { diff --git a/ui/plugin-kit/package.json b/ui/plugin-kit/package.json index 15f8203ab..7fea4bf45 100644 --- a/ui/plugin-kit/package.json +++ b/ui/plugin-kit/package.json @@ -1,6 +1,6 @@ { "name": "@artalk/plugin-kit", - "version": "1.0.6", + "version": "1.0.7", "description": "The plugin kit for Artalk", "type": "module", "main": "dist/main.js", @@ -27,10 +27,10 @@ "license": "MIT", "dependencies": { "@microsoft/api-extractor": "^7.47.9", - "artalk": "workspace:^", "picocolors": "^1.1.0" }, "devDependencies": { + "artalk": "workspace:^", "esbuild-plugin-raw": "^0.1.8", "tsup": "^8.3.0" }, diff --git a/ui/plugin-lightbox/package.json b/ui/plugin-lightbox/package.json index c242d76c8..4e79cab72 100644 --- a/ui/plugin-lightbox/package.json +++ b/ui/plugin-lightbox/package.json @@ -1,6 +1,6 @@ { "name": "@artalk/plugin-lightbox", - "version": "0.2.3", + "version": "0.2.4", "license": "MIT", "description": "The image lightbox plugin for artalk", "type": "module", @@ -15,11 +15,8 @@ "build": "vite build", "serve": "vite preview" }, - "dependencies": { - "artalk": "workspace:^" - }, "devDependencies": { - "@artalk/plugin-kit": "workspace:^", + "artalk": "workspace:^", "lightgallery": "^2.7.2", "lightbox2": "^2.11.4", "photoswipe": "^5.4.4", From d60752dff199f0d286daec23b474008a4016fa22 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 19:05:31 +0800 Subject: [PATCH 7/8] fix deps --- pnpm-lock.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 907260696..421b0e5f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,11 +117,11 @@ importers: docs/docs: devDependencies: '@artalk/plugin-katex': - specifier: ^0.2.3 - version: 0.2.3(@types/katex@0.16.7)(artalk@ui+artalk)(katex@0.16.11) + specifier: ^0.2.4 + version: 0.2.4(@types/katex@0.16.7)(artalk@ui+artalk)(katex@0.16.11) '@artalk/plugin-lightbox': - specifier: ^0.2.3 - version: 0.2.3(artalk@ui+artalk)(fancybox@3.0.1)(lightbox2@2.11.4)(lightgallery@2.7.2)(photoswipe@5.4.4) + specifier: ^0.2.4 + version: 0.2.4(artalk@ui+artalk)(fancybox@3.0.1)(lightbox2@2.11.4)(lightgallery@2.7.2)(photoswipe@5.4.4) artalk: specifier: workspace:^ version: link:../../ui/artalk @@ -479,11 +479,11 @@ packages: '@antfu/utils@0.7.10': resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} - '@artalk/plugin-katex@0.2.3': - resolution: {integrity: sha512-Xu+f5JBWUTjIiuuyzjrM2p+KOTmy9P5L96fM9Dh+tTmlpVv0cJ/Z6zxkZFt+OooK2QO5syU2Pjw9OcqAtmRCIQ==} + '@artalk/plugin-katex@0.2.4': + resolution: {integrity: sha512-7kNsrg9R77Ly42wVwXdfuLwuwLtIIFYrrITZGrPzqDCqnrm1nYUx0btkyGjWY1/MQLTNZWqczOcjbQ2VN2+o0Q==} peerDependencies: '@types/katex': ^0.16.7 - artalk: ^2.9.0 + artalk: ^2.9.1 katex: ^0.16.11 '@artalk/plugin-kit@1.0.6': @@ -493,10 +493,10 @@ packages: typescript: '*' vite: '*' - '@artalk/plugin-lightbox@0.2.3': - resolution: {integrity: sha512-avmW2pu5rrWnDjRrPj4CM9QrnGJQNMqaY/o5+nH1d/eo7HURlRPiy5/yZFAk7ccbvH6t5c/PtcygGLbRft2M2A==} + '@artalk/plugin-lightbox@0.2.4': + resolution: {integrity: sha512-cYewbb2rkwofDqWq51MrMO/idbN7mcYTrIicsi8xpoRJdr7hwLzqM6ODih9cnbiS25l8+3PVYPTIn3g5WeqkYg==} peerDependencies: - artalk: ^2.9.0 + artalk: ^2.9.1 fancybox: ^3.0.1 lightbox2: ^2.11.4 lightgallery: ^2.7.2 @@ -5057,7 +5057,7 @@ snapshots: '@antfu/utils@0.7.10': {} - '@artalk/plugin-katex@0.2.3(@types/katex@0.16.7)(artalk@ui+artalk)(katex@0.16.11)': + '@artalk/plugin-katex@0.2.4(@types/katex@0.16.7)(artalk@ui+artalk)(katex@0.16.11)': dependencies: '@types/katex': 0.16.7 artalk: link:ui/artalk @@ -5073,7 +5073,7 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@artalk/plugin-lightbox@0.2.3(artalk@ui+artalk)(fancybox@3.0.1)(lightbox2@2.11.4)(lightgallery@2.7.2)(photoswipe@5.4.4)': + '@artalk/plugin-lightbox@0.2.4(artalk@ui+artalk)(fancybox@3.0.1)(lightbox2@2.11.4)(lightgallery@2.7.2)(photoswipe@5.4.4)': dependencies: artalk: link:ui/artalk optionalDependencies: From 04da09c52696cd1f4a1267e786d79474fab06def Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 5 Oct 2024 19:09:55 +0800 Subject: [PATCH 8/8] upgrade @artalk/plugin-kit to v1.0.7 --- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 532ee0d4e..b7c5fcb1b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test": "pnpm -F artalk test" }, "devDependencies": { - "@artalk/plugin-kit": "^1.0.6", + "@artalk/plugin-kit": "^1.0.7", "@eslint/compat": "^1.1.1", "@eslint/js": "^9.10.0", "@playwright/test": "^1.47.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 421b0e5f2..54090b925 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@artalk/plugin-kit': - specifier: ^1.0.6 - version: 1.0.6(@types/node@22.5.5)(artalk@2.9.1(marked@14.1.2))(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0)) + specifier: ^1.0.7 + version: 1.0.7(@types/node@22.5.5)(artalk@2.9.1(marked@14.1.2))(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0)) '@eslint/compat': specifier: ^1.1.1 version: 1.1.1 @@ -486,10 +486,10 @@ packages: artalk: ^2.9.1 katex: ^0.16.11 - '@artalk/plugin-kit@1.0.6': - resolution: {integrity: sha512-ejbzkYmlGFPrHS9kzbMDU612fDXPmx1iN+jzNyF5I44K5B50zr4LcGRD3RevB9ohtdLxPV7C2nMwex33ok0tfA==} + '@artalk/plugin-kit@1.0.7': + resolution: {integrity: sha512-3ggnD0SCQm7b+UpdqOQNzPZdXQjNm5UQLO1iknipSkJ57Nj9E/aLBNSOuW3y6K6djTFY95IKTTJ8wD4ssDV+aQ==} peerDependencies: - artalk: ^2.9.0 + artalk: ^2.9.1 typescript: '*' vite: '*' @@ -5063,7 +5063,7 @@ snapshots: artalk: link:ui/artalk katex: 0.16.11 - '@artalk/plugin-kit@1.0.6(@types/node@22.5.5)(artalk@2.9.1(marked@14.1.2))(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0))': + '@artalk/plugin-kit@1.0.7(@types/node@22.5.5)(artalk@2.9.1(marked@14.1.2))(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)(sass@1.78.0)(terser@5.33.0))': dependencies: '@microsoft/api-extractor': 7.47.9(@types/node@22.5.5) artalk: 2.9.1(marked@14.1.2)