@forinda/kickjs-lint 5.1.0 → 5.2.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 +5 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +7 -2
- package/dist/index.mjs.map +1 -1
- package/dist/rules.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,11 +32,11 @@ if (result.violations.length > 0) console.error(formatViolations(result.violatio
|
|
|
32
32
|
|
|
33
33
|
## Rules
|
|
34
34
|
|
|
35
|
-
| Rule
|
|
36
|
-
|
|
|
37
|
-
| `di-token-symbol`
|
|
38
|
-
| `token-kick-prefix`
|
|
39
|
-
| `token-reserved-prefix`
|
|
35
|
+
| Rule | Default | Description |
|
|
36
|
+
| ----------------------- | ------- | ----------------------------------------------------------------------------- |
|
|
37
|
+
| `di-token-symbol` | `error` | DI tokens must use `createToken<T>()` instead of `Symbol(...)` in token files |
|
|
38
|
+
| `token-kick-prefix` | `error` | First-party tokens must start with the reserved `kick/` prefix |
|
|
39
|
+
| `token-reserved-prefix` | `warn` | Third-party tokens must not squat the reserved `kick/` prefix |
|
|
40
40
|
|
|
41
41
|
Inline-disable a rule on a single line:
|
|
42
42
|
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;AA8EA;;;;cAhDa,gBAAA,EAAgB,GAAA;AAAA,UA2BZ,WAAA;EAuBf;EArBA,GAAA;EAqBY;AAQd;;;;EAvBE,UAAA;EAuBgD;;;;;EAjBhD,KAAA;EAiBwD;EAfxD,KAAA,YAAiB,IAAA;EAeiD;EAblE,SAAA,GAAY,WAAA;AAAA;AAAA,UAGG,UAAA;EACf,UAAA,EAAY,SAAA;EACZ,YAAA;AAAA;;;;;;iBAQoB,OAAA,CAAQ,IAAA,EAAM,WAAA,GAAc,OAAA,CAAQ,UAAA;;;;;;iBAkD1C,gBAAA,CAAiB,UAAA,WAAqB,SAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-lint v5.
|
|
2
|
+
* @forinda/kickjs-lint v5.2.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -49,7 +49,12 @@ const SKIP_DIRS = new Set([
|
|
|
49
49
|
"node_modules",
|
|
50
50
|
"dist",
|
|
51
51
|
"__tests__",
|
|
52
|
-
".kickjs"
|
|
52
|
+
".kickjs",
|
|
53
|
+
"public",
|
|
54
|
+
".vitepress",
|
|
55
|
+
".turbo",
|
|
56
|
+
".wireit",
|
|
57
|
+
"coverage"
|
|
53
58
|
]);
|
|
54
59
|
/**
|
|
55
60
|
* Walk `cwd` (constrained to `scope` directories), apply every rule to
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defaultRules"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Programmatic entry point for `@forinda/kickjs-lint`.\n *\n * Walks a directory tree, applies every enabled rule from\n * {@link ./rules} to each file that matches the token-bearing filename\n * heuristic, and returns the aggregated violations.\n *\n * The CLI binary (`bin.mjs`) wraps this with a process-exit translation\n * layer; downstream tools (devtools, editor extensions) call this\n * directly.\n *\n * @module @forinda/kickjs-lint\n */\n\nimport { readdir, readFile } from 'node:fs/promises'\nimport { join, relative } from 'node:path'\nimport { rules as defaultRules, type Rule, type Violation } from './rules'\n\nexport type { LintContext, Rule, Violation } from './rules'\nexport { diTokenSymbol, tokenKickPrefix, tokenReservedPrefix, rules as defaultRules } from './rules'\n\n/**\n * Filenames that historically declare DI tokens. Lint runs only on\n * these to keep false positives out of unrelated files (e.g. a class\n * named `Symbol` in a math library).\n *\n * `database.ts`, `interfaces.ts`, `client.ts` were added after a\n * regression where `TENANT_DB = Symbol(...)` slipped past the rule by\n * living in `database.ts` rather than `tokens.ts` / `constants.ts`.\n */\nexport const TOKEN_FILE_NAMES = new Set([\n 'types.ts',\n 'tokens.ts',\n 'constants.ts',\n 'service.ts',\n 'adapter.ts',\n 'database.ts',\n 'interfaces.ts',\n 'client.ts',\n])\n\n/** Directories the walker skips wholesale. */\nconst SKIP_DIRS = new Set(['node_modules'
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defaultRules"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Programmatic entry point for `@forinda/kickjs-lint`.\n *\n * Walks a directory tree, applies every enabled rule from\n * {@link ./rules} to each file that matches the token-bearing filename\n * heuristic, and returns the aggregated violations.\n *\n * The CLI binary (`bin.mjs`) wraps this with a process-exit translation\n * layer; downstream tools (devtools, editor extensions) call this\n * directly.\n *\n * @module @forinda/kickjs-lint\n */\n\nimport { readdir, readFile } from 'node:fs/promises'\nimport { join, relative } from 'node:path'\nimport { rules as defaultRules, type Rule, type Violation } from './rules'\n\nexport type { LintContext, Rule, Violation } from './rules'\nexport { diTokenSymbol, tokenKickPrefix, tokenReservedPrefix, rules as defaultRules } from './rules'\n\n/**\n * Filenames that historically declare DI tokens. Lint runs only on\n * these to keep false positives out of unrelated files (e.g. a class\n * named `Symbol` in a math library).\n *\n * `database.ts`, `interfaces.ts`, `client.ts` were added after a\n * regression where `TENANT_DB = Symbol(...)` slipped past the rule by\n * living in `database.ts` rather than `tokens.ts` / `constants.ts`.\n */\nexport const TOKEN_FILE_NAMES = new Set([\n 'types.ts',\n 'tokens.ts',\n 'constants.ts',\n 'service.ts',\n 'adapter.ts',\n 'database.ts',\n 'interfaces.ts',\n 'client.ts',\n])\n\n/** Directories the walker skips wholesale. */\nconst SKIP_DIRS = new Set([\n 'node_modules',\n 'dist',\n '__tests__',\n '.kickjs',\n // Built static assets (e.g. devtools SPA bundle) live under `public/`\n // and ship as-is to npm — no token literals to lint there.\n 'public',\n // VitePress / Vite build outputs that adopters sometimes commit.\n '.vitepress',\n '.turbo',\n '.wireit',\n 'coverage',\n])\n\nexport interface LintOptions {\n /** Root directory to walk. Required. */\n cwd: string\n /**\n * Whether the project being linted is a first-party `@forinda/kickjs-*`\n * package (enables `token-kick-prefix`, disables `token-reserved-prefix`).\n * Defaults to `false` so adopter projects use the friendlier ruleset.\n */\n firstParty?: boolean\n /**\n * Only lint files inside these subdirectories (relative to `cwd`).\n * Defaults to `['packages']` for first-party use; pass `['src']` or\n * `['.']` for adopter projects.\n */\n scope?: readonly string[]\n /** Override the rule set. Defaults to every rule shipped by the package. */\n rules?: readonly Rule[]\n /** Filenames to lint (defaults to {@link TOKEN_FILE_NAMES}). */\n filenames?: ReadonlySet<string>\n}\n\nexport interface LintResult {\n violations: Violation[]\n filesScanned: number\n}\n\n/**\n * Walk `cwd` (constrained to `scope` directories), apply every rule to\n * each token-bearing file, and return the aggregated violations + the\n * number of files actually checked.\n */\nexport async function runLint(opts: LintOptions): Promise<LintResult> {\n const cwd = opts.cwd\n const firstParty = opts.firstParty ?? false\n const scope = opts.scope ?? ['packages']\n const ruleset = opts.rules ?? defaultRules\n const filenames = opts.filenames ?? TOKEN_FILE_NAMES\n\n const violations: Violation[] = []\n let filesScanned = 0\n\n for (const root of scope) {\n const start = join(cwd, root)\n await walk(start, async (file) => {\n const base = file.slice(file.lastIndexOf('/') + 1)\n if (!filenames.has(base)) return\n const source = await readFile(file, 'utf-8')\n const rel = relative(cwd, file)\n filesScanned++\n for (const rule of ruleset) {\n violations.push(...rule.check({ source, file: rel, firstParty }))\n }\n })\n }\n\n return { violations, filesScanned }\n}\n\nasync function walk(dir: string, visit: (file: string) => Promise<void>): Promise<void> {\n let entries\n try {\n entries = await readdir(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) continue\n await walk(full, visit)\n } else if (entry.isFile()) {\n await visit(full)\n }\n }\n}\n\n/**\n * Format a violation list for terminal output. One block per violation,\n * trailing summary line. Returns `''` when there are no violations so\n * callers can branch on truthiness.\n */\nexport function formatViolations(violations: readonly Violation[]): string {\n if (violations.length === 0) return ''\n const lines: string[] = []\n for (const v of violations) {\n const tag = v.severity === 'error' ? 'error' : 'warn'\n lines.push(` [${tag}] ${v.file}:${v.line} ${v.ruleId}`)\n lines.push(` ${v.message}`)\n if (v.suggestion) lines.push(` -> ${v.suggestion}`)\n lines.push('')\n }\n const errors = violations.filter((v) => v.severity === 'error').length\n const warnings = violations.length - errors\n lines.push(`${violations.length} violation(s): ${errors} error, ${warnings} warn`)\n return lines.join('\\n')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,mBAAmB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;AAGF,MAAM,YAAY,IAAI,IAAI;CACxB;CACA;CACA;CACA;CAGA;CAEA;CACA;CACA;CACA;CACD,CAAC;;;;;;AAiCF,eAAsB,QAAQ,MAAwC;CACpE,MAAM,MAAM,KAAK;CACjB,MAAM,aAAa,KAAK,cAAc;CACtC,MAAM,QAAQ,KAAK,SAAS,CAAC,WAAW;CACxC,MAAM,UAAU,KAAK,SAASA;CAC9B,MAAM,YAAY,KAAK,aAAa;CAEpC,MAAM,aAA0B,EAAE;CAClC,IAAI,eAAe;AAEnB,MAAK,MAAM,QAAQ,MAEjB,OAAM,KADQ,KAAK,KAAK,KAAK,EACX,OAAO,SAAS;EAChC,MAAM,OAAO,KAAK,MAAM,KAAK,YAAY,IAAI,GAAG,EAAE;AAClD,MAAI,CAAC,UAAU,IAAI,KAAK,CAAE;EAC1B,MAAM,SAAS,MAAM,SAAS,MAAM,QAAQ;EAC5C,MAAM,MAAM,SAAS,KAAK,KAAK;AAC/B;AACA,OAAK,MAAM,QAAQ,QACjB,YAAW,KAAK,GAAG,KAAK,MAAM;GAAE;GAAQ,MAAM;GAAK;GAAY,CAAC,CAAC;GAEnE;AAGJ,QAAO;EAAE;EAAY;EAAc;;AAGrC,eAAe,KAAK,KAAa,OAAuD;CACtF,IAAI;AACJ,KAAI;AACF,YAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,MAAM,CAAC;SAC/C;AACN;;AAEF,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,OAAO,KAAK,KAAK,MAAM,KAAK;AAClC,MAAI,MAAM,aAAa,EAAE;AACvB,OAAI,UAAU,IAAI,MAAM,KAAK,CAAE;AAC/B,SAAM,KAAK,MAAM,MAAM;aACd,MAAM,QAAQ,CACvB,OAAM,MAAM,KAAK;;;;;;;;AAUvB,SAAgB,iBAAiB,YAA0C;AACzE,KAAI,WAAW,WAAW,EAAG,QAAO;CACpC,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,KAAK,YAAY;EAC1B,MAAM,MAAM,EAAE,aAAa,UAAU,UAAU;AAC/C,QAAM,KAAK,MAAM,IAAI,IAAI,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI,EAAE,SAAS;AACzD,QAAM,KAAK,OAAO,EAAE,UAAU;AAC9B,MAAI,EAAE,WAAY,OAAM,KAAK,UAAU,EAAE,aAAa;AACtD,QAAM,KAAK,GAAG;;CAEhB,MAAM,SAAS,WAAW,QAAQ,MAAM,EAAE,aAAa,QAAQ,CAAC;CAChE,MAAM,WAAW,WAAW,SAAS;AACrC,OAAM,KAAK,GAAG,WAAW,OAAO,iBAAiB,OAAO,UAAU,SAAS,OAAO;AAClF,QAAO,MAAM,KAAK,KAAK"}
|
package/dist/rules.mjs
CHANGED