@longzai-intelligence-oxlint/stylistic-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/configs/recommended.d.ts +8 -0
- package/dist/configs/recommended.js +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +6 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @longzai-intelligence-oxlint/stylistic-plugin
|
|
2
|
+
|
|
3
|
+
## 意图
|
|
4
|
+
|
|
5
|
+
在静态检查阶段统一代码排版风格,对标 ESLint 生态 @stylistic 插件,避免格式类问题流入代码评审。
|
|
6
|
+
|
|
7
|
+
## 定位
|
|
8
|
+
|
|
9
|
+
Oxlint 生态的 stylistic 规则实现插件,通过 `eslintCompatPlugin` 包装以同时兼容 Oxlint 与 ESLint 运行时。
|
|
10
|
+
|
|
11
|
+
## 职能
|
|
12
|
+
|
|
13
|
+
提供 `multiline-comment-style` 规则约束多行注释风格、`lines-around-comment` 规则约束注释前后空行、`padding-line-between-statements` 规则约束语句间空行;使用 `defineRule` + `createOnce` 实现以获得最佳性能。
|
|
14
|
+
|
|
15
|
+
## 实现情况
|
|
16
|
+
|
|
17
|
+
三条规则均已实现并按规则文件组织,规则集合与插件对象一并导出;当前规则集合聚焦排版维度,处于稳定可用形态。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={"@longzai-intelligence-oxlint/stylistic-plugin/multiline-comment-style":`error`,"@longzai-intelligence-oxlint/stylistic-plugin/lines-around-comment":[`error`,{beforeBlockComment:!0,beforeLineComment:!1,allowBlockStart:!0,allowBlockEnd:!0,allowObjectStart:!0,allowObjectEnd:!0,allowArrayStart:!0,allowArrayEnd:!0,allowClassStart:!0,allowClassEnd:!0,allowInterfaceStart:!0,allowInterfaceEnd:!0,allowTypeStart:!0,allowTypeEnd:!0,allowEnumStart:!0,allowEnumEnd:!0,allowModuleStart:!0,allowModuleEnd:!0}],"@longzai-intelligence-oxlint/stylistic-plugin/padding-line-between-statements":`error`};export{e as recommended};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Rule } from "@oxlint/plugins";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* stylistic 规则集合
|
|
5
|
+
*/
|
|
6
|
+
declare const stylisticRules: Record<string, Rule>;
|
|
7
|
+
/**
|
|
8
|
+
* stylistic 插件
|
|
9
|
+
*/
|
|
10
|
+
declare const stylisticPlugin: import("@oxlint/plugins").Plugin;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { stylisticPlugin as default, stylisticPlugin, stylisticRules };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{defineRule as e,eslintCompatPlugin as t}from"@oxlint/plugins";function n(){return{isBlockStart:!1,isBlockEnd:!1,isObjectStart:!1,isObjectEnd:!1,isArrayStart:!1,isArrayEnd:!1,isClassStart:!1,isClassEnd:!1,isInterfaceStart:!1,isInterfaceEnd:!1,isTypeStart:!1,isTypeEnd:!1,isEnumStart:!1,isEnumEnd:!1,isModuleStart:!1,isModuleEnd:!1,isFunctionStart:!1,isFunctionEnd:!1}}function r(e){return!!(e.includes(`type `)||e.includes(`extends {`)||e.includes(`type{`)||e.includes(`Array<{`)||e.includes(`Promise<{`)||e.includes(`<{`)||e.includes(`| {`)||e.includes(`as {`)||e.includes(`Record<{`)||e.includes(`Partial<{`)||e.includes(`Required<{`)||e.includes(`Pick<{`)||e.includes(`Omit<{`)||e.includes(`& {`))}function i(e,t){for(let n=2;n<=5&&t>n;n++){let r=e[t-n-1];if(r){let e=r.trimEnd();if(e.includes(`Record<{`)||e.includes(`Partial<{`)||e.includes(`Required<{`)||e.includes(`Pick<{`)||e.includes(`Omit<{`)||e.includes(`Array<{`)||e.includes(`Promise<{`)||e.includes(`type `)||e.includes(`interface `))return!0}}return!1}function a(e){return e.endsWith(`) {`)||e.endsWith(`){`)||/\)\s*(?::\s*[^{]+)?\{/.test(e)||e.includes(`=> {`)}function o(e){return!!(e.endsWith(`) {`)||e.endsWith(`){`)||e===`{`||/: [^{]+ \{$/.test(e)||/\)\s*(?::\s*[^{]+)?\{/.test(e)||e.endsWith(`}> {`)||e===`> {`||e.includes(`try {`)||e.includes(`catch {`)||e.includes(`finally {`)||e.includes(`=> {`)||e.includes(`else {`)||/^\w+\s*\{$/.test(e))}function s(e){let t=e.includes(`namespace `)||e.includes(`namespace{`),n=e.startsWith(`declare global`)||e.startsWith(`declare module`);return e.includes(`module `)||e.includes(`module{`)||t||n}function c(e,t){for(let n=2;n<=10&&t>n;n++){let r=e[t-n-1];if(r){let e=r.trim();if(e.includes(`class `)||e.includes(`class{`))return!0}}return!1}function l(e){let t=/\w\(\{$/.test(e),n=e.endsWith(`, {`),r=/=>\s*\(\{$/.test(e),i=e.includes(`export default {`);return e.includes(`: {`)||e.endsWith(`= {`)||t||n||r||i}function u(e,t,n,u){r(t)?e.isTypeStart=!0:t.trim()===`{`?e[i(n,u)?`isTypeStart`:`isBlockStart`]=!0:t.includes(`interface `)||t.includes(`interface{`)?e.isInterfaceStart=!0:t.includes(`enum `)||t.includes(`enum{`)?e.isEnumStart=!0:s(t)?e.isModuleStart=!0:t.includes(`class `)||t.includes(`class{`)||t===`> {`?e.isClassStart=!0:o(t)?(e.isBlockStart=!0,a(t)&&(e.isFunctionStart=!0)):l(t)?e.isObjectStart=!0:t.includes(`: [`)||t.endsWith(`= [`)||t.endsWith(`[`)?e.isArrayStart=!0:c(n,u)&&(e.isClassStart=!0)}function d(e,t,n){if(t<=1)return;let r=t-2;for(;r>=0;){let e=n[r];if(e&&e.trim().length>0)break;r--}if(r<0)return;let i=n[r];if(!i)return;let a=i.trim();a.endsWith(`{`)||/>+\s*\{\s*$/.test(a)?u(e,a,n,t):a.endsWith(`(`)||a.endsWith(`>`)?e.isBlockStart=!0:a.endsWith(`[`)&&(e.isArrayStart=!0)}function f(e,t,n){if(t>=n.length)return;let r=n[t];if(!r)return;let i=r.trimStart();if(i===`}`){e.isBlockEnd=!0,e.isObjectEnd=!0,e.isClassEnd=!0,e.isInterfaceEnd=!0,e.isTypeEnd=!0,e.isEnumEnd=!0,e.isModuleEnd=!0,e.isFunctionEnd=!0;return}if(i===`};`){e.isBlockEnd=!0,e.isObjectEnd=!0,e.isClassEnd=!0,e.isInterfaceEnd=!0,e.isTypeEnd=!0,e.isEnumEnd=!0,e.isModuleEnd=!0,e.isFunctionEnd=!0;return}if(i.startsWith(`];`)){e.isArrayEnd=!0;return}}function p(e,t){let r=n(),i=e.loc.start.line,a=e.loc.end.line;return d(r,i,t),f(r,a,t),r}const m={beforeBlockComment:!0,afterBlockComment:!1,beforeLineComment:!1,afterLineComment:!1,allowBlockStart:!1,allowBlockEnd:!1,allowObjectStart:!1,allowObjectEnd:!1,allowArrayStart:!1,allowArrayEnd:!1,allowClassStart:!1,allowClassEnd:!1,allowInterfaceStart:!1,allowInterfaceEnd:!1,allowTypeStart:!1,allowTypeEnd:!1,allowEnumStart:!1,allowEnumEnd:!1,allowModuleStart:!1,allowModuleEnd:!1,allowFunctionStart:!1,allowFunctionEnd:!1,ignorePattern:void 0,applyDefaultIgnorePatterns:!0};function h(e,t){if(e.loc.start.line<=1)return!1;let n=_(e.loc.start.line,t);return n?/\w+=\{$/.test(n):!1}function g(e,t){if(e.loc.start.line<=1)return!1;let n=_(e.loc.start.line,t);if(!n||!(n===`}`||/^\w+=("[^"]*"|'[^']*')$/.test(n)||/^\w+=\{.+\}$/.test(n)||/^<[A-Z]\w*$/.test(n)||/^\w+:$/.test(n)))return!1;let r=v(e.loc.end.line,t);return r?/^\w+=/.test(r)||/^\/?>$/.test(r)||r.startsWith(`/>`)||r.startsWith(`(`)||r.startsWith(`<`):!1}function _(e,t){let n=e-2;for(;n>=0;){let e=t[n];if(e&&e.trim().length>0)return e.trim();n--}return null}function v(e,t){let n=e;for(;n<t.length;){let e=t[n];if(e&&e.trim().length>0)return e.trim();n++}return null}function y(e,t){let n=t[e.loc.start.line-1];return n?n.slice(0,e.loc.start.column).trim().length>0:!1}function b(e,t){if(t.length===0)return!1;let n=t[t.length-1];return n?n.loc.end.line+1>=e.loc.start.line:!1}const x=[/^eslint/i,/^jshint/i,/^jslint/i,/^istanbul/i,/^global/i,/^exported/i,/^jscs/i];function S(e,t){let n=e.value.trim();if(t.applyDefaultIgnorePatterns!==!1){for(let e of x)if(e.test(n))return!0}return!!(t.ignorePattern&&new RegExp(t.ignorePattern,`u`).test(n))}function C(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function w(e,t,n){let r=t[n];typeof r==`boolean`&&(e[n]=r)}function T(e,t){w(e,t,`beforeBlockComment`),w(e,t,`afterBlockComment`),w(e,t,`beforeLineComment`),w(e,t,`afterLineComment`),w(e,t,`allowBlockStart`),w(e,t,`allowBlockEnd`),w(e,t,`allowObjectStart`),w(e,t,`allowObjectEnd`),w(e,t,`allowArrayStart`),w(e,t,`allowArrayEnd`),w(e,t,`allowClassStart`),w(e,t,`allowClassEnd`),w(e,t,`allowInterfaceStart`),w(e,t,`allowInterfaceEnd`),w(e,t,`allowTypeStart`),w(e,t,`allowTypeEnd`),w(e,t,`allowEnumStart`),w(e,t,`allowEnumEnd`),w(e,t,`allowModuleStart`),w(e,t,`allowModuleEnd`),w(e,t,`allowFunctionStart`),w(e,t,`allowFunctionEnd`),w(e,t,`applyDefaultIgnorePatterns`)}function E(e,t,n){let r=t[n];typeof r==`string`&&(e[n]=r)}function D(e){let t={...m};return C(e)?(T(t,e),E(t,e,`ignorePattern`),t):t}function O(e,t){return e<=1||t[e-2]?.trim()===``}function k(e,t){return e>=t.length||t[e]?.trim()===``}function A(e,t){return e.isBlockStart&&(t.allowBlockStart??!1)||e.isObjectStart&&(t.allowObjectStart??!1)||e.isArrayStart&&(t.allowArrayStart??!1)||e.isClassStart&&(t.allowClassStart??!1)||e.isInterfaceStart&&(t.allowInterfaceStart??!1)||e.isTypeStart&&(t.allowTypeStart??!1)||e.isEnumStart&&(t.allowEnumStart??!1)||e.isModuleStart&&(t.allowModuleStart??!1)||e.isFunctionStart&&(t.allowFunctionStart??!1)}function j(e,t){return e.isBlockEnd&&(t.allowBlockEnd??!1)||e.isObjectEnd&&(t.allowObjectEnd??!1)||e.isArrayEnd&&(t.allowArrayEnd??!1)||e.isClassEnd&&(t.allowClassEnd??!1)||e.isInterfaceEnd&&(t.allowInterfaceEnd??!1)||e.isTypeEnd&&(t.allowTypeEnd??!1)||e.isEnumEnd&&(t.allowEnumEnd??!1)||e.isModuleEnd&&(t.allowModuleEnd??!1)||e.isFunctionEnd&&(t.allowFunctionEnd??!1)}function M(e,t,n,r,i){let a=e.type===`Block`;if(a&&n.beforeBlockComment||!a&&n.beforeLineComment){if(A(i,n))return;let o=e.loc.start.line;O(o,t)||r.report({loc:{start:e.loc.start,end:e.loc.start},message:a?`块注释前需要空行`:`行注释前需要空行`,fix:n=>{let r=0;for(let n=0;n<e.loc.start.line-1;n++)r+=(t[n]?.length??0)+1;return n.insertTextBeforeRange([r,r],`
|
|
2
|
+
`)}})}}function N(e,t,n,r,i){let a=e.type===`Block`;if(a&&n.afterBlockComment||!a&&n.afterLineComment){if(j(i,n))return;let o=e.loc.end.line;k(o,t)||r.report({loc:{start:e.loc.end,end:e.loc.end},message:a?`块注释后需要空行`:`行注释后需要空行`,fix:t=>t.insertTextAfterRange([e.range[1],e.range[1]],`
|
|
3
|
+
`)})}}function P(e,t,n,r,i=[],a=!1,o=!1){if(y(e,t)||S(e,n))return;let s=b(e,i),c=p(e,t),l=h(e,t)||g(e,t);!a&&!s&&!l&&M(e,t,n,r,c),o||N(e,t,n,r,c)}const F=e({meta:{type:`layout`,fixable:`whitespace`,docs:{description:`要求在注释前后有空行`},schema:[{type:`object`,properties:{beforeBlockComment:{type:`boolean`},afterBlockComment:{type:`boolean`},beforeLineComment:{type:`boolean`},afterLineComment:{type:`boolean`},allowBlockStart:{type:`boolean`},allowBlockEnd:{type:`boolean`},allowObjectStart:{type:`boolean`},allowObjectEnd:{type:`boolean`},allowArrayStart:{type:`boolean`},allowArrayEnd:{type:`boolean`},allowClassStart:{type:`boolean`},allowClassEnd:{type:`boolean`},allowInterfaceStart:{type:`boolean`},allowInterfaceEnd:{type:`boolean`},allowTypeStart:{type:`boolean`},allowTypeEnd:{type:`boolean`},allowEnumStart:{type:`boolean`},allowEnumEnd:{type:`boolean`},allowModuleStart:{type:`boolean`},allowModuleEnd:{type:`boolean`},allowFunctionStart:{type:`boolean`},allowFunctionEnd:{type:`boolean`},ignorePattern:{type:`string`},applyDefaultIgnorePatterns:{type:`boolean`}},additionalProperties:!1}]},createOnce(e){let t=[],n=[];return{Program(){let r=D(e.options?.[0]);t=e.sourceCode.text.split(`
|
|
4
|
+
`),n=[];let i=e.sourceCode.getAllComments();for(let a=0;a<i.length;a++){let o=i[a];if(!o)continue;let s=i[a+1],c=s!==void 0&&s.loc.start.line<=o.loc.end.line+1;P(o,t,r,e,n,!1,c),n.push(o)}}}}}),I=e({meta:{type:`layout`,docs:{description:`强制多行注释使用星号块样式`}},createOnce(e){return{Program(t){let n=e.sourceCode.getAllComments();for(let t of n){if(t.type!==`Block`)continue;let n=t.value;if(!n.startsWith(`*`))continue;let r=n.split(`
|
|
5
|
+
`);if(!(r.length<=1))for(let n=1;n<r.length-1;n++){let i=r[n]?.trim();if(i&&!i.startsWith(`*`)){e.report({loc:{start:t.loc.start,end:t.loc.end},message:`多行注释的中间行应以 "*" 开头`});break}}}}}}});function L(e){return e.type===`ExportNamedDeclaration`||e.type===`ExportDefaultDeclaration`||e.type===`ExportAllDeclaration`}function R(e,t,n){if(n-t<=1)return!1;for(let r=t+1;r<n;r++)if(e[r-1]?.trim()===``)return!0;return!1}function z(e){return e.type===`Program`}function B(e,t,n){for(let r=1;r<e.length;r++){let i=e[r-1],a=e[r];if(!(i===void 0||a===void 0)&&L(i)&&L(a)){let e=i.loc.end.line,r=a.loc.start.line;R(t,e,r)||n.report({loc:a.loc.start,message:`export 语句之间需要空行`})}}}const V={"multiline-comment-style":I,"lines-around-comment":F,"padding-line-between-statements":e({meta:{type:`layout`,docs:{description:`要求在 export 语句之间有空行`}},createOnce(e){return{Program(t){let n=e.sourceCode.text.split(`
|
|
6
|
+
`),r=z(t)?t:null;r&&B(r.body,n,e)}}}})},H=t({meta:{name:`@longzai-intelligence-oxlint/stylistic-plugin`},rules:V});export{H as default,H as stylisticPlugin,V as stylisticRules};
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@longzai-intelligence-oxlint/stylistic-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Oxlint stylistic 兼容插件,提供 @stylistic 规则的 Oxlint 实现",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./configs/recommended": {
|
|
18
|
+
"types": "./dist/configs/recommended.d.ts",
|
|
19
|
+
"import": "./dist/configs/recommended.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "lzi-builder",
|
|
24
|
+
"build:prod": "NODE_ENV=production lzi-builder",
|
|
25
|
+
"prepublishOnly": "bun run build:prod",
|
|
26
|
+
"dev": "lzi-builder --watch",
|
|
27
|
+
"clean": "rimraf dist",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:coverage": "vitest run --coverage",
|
|
31
|
+
"lint": "oxlint && oxfmt --check",
|
|
32
|
+
"lint:fix": "oxlint --fix && oxfmt",
|
|
33
|
+
"typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
|
|
34
|
+
"typecheck:app": "tsgo --noEmit -p tsconfig/app.json",
|
|
35
|
+
"typecheck:node": "tsgo --noEmit -p tsconfig/node.json",
|
|
36
|
+
"typecheck:test": "tsgo --noEmit -p tsconfig/test.json"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@longzai-intelligence-oxlint/core": "0.1.0",
|
|
40
|
+
"@longzai-intelligence-logger/node": "^0.1.1",
|
|
41
|
+
"@oxlint/plugins": "^1.74.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
45
|
+
"typescript": "^6.0.3"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"oxlint": ">=1.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|