@limenet-ch/baseline 2.12.0 → 2.12.1

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 CHANGED
@@ -124,7 +124,7 @@ State lives in `.baseline.json` at the project root (a JS project has no `config
124
124
  | `hasCiJobs` | same GitLab CI templates, without the `php` job |
125
125
  | `hasTrivyConfig` | identical, canonical config included: its `vendor/**`, `storage/logs/` and `.ddev/` skips are inert in a JS project |
126
126
  | `ciSetsNodeVersion` | **npm-only**: the Laravel runner does not register it |
127
- | `isCiLintComplete` | asserts the JS toolchain in the npm script, not pint/phpstan in a composer script: `tsc` plus whichever linter is installed (`biome` for `@biomejs/biome`, `eslint` for `eslint`), failing if neither is |
127
+ | `isCiLintComplete` | asserts the JS toolchain in the npm script, not pint/phpstan in a composer script: whichever linter is installed (`biome` for `@biomejs/biome`, `eslint` for `eslint`), failing if neither is, plus `tsc` once the project has a `.ts`/`.tsx`/`.mts`/`.cts` file outside `node_modules` and dot-directories |
128
128
  | `callsBaseline` | hooks the `ci-lint` npm script, since npm has no `post-update-cmd` |
129
129
  | `doesNotExcludeUnknownChecks` | identical, against this runner's smaller registry: a name only the Laravel runner knows is as dead here as one that exists nowhere |
130
130
  | `usesReleaseIt` | **inverted**: fails if `@release-it/bumper` is configured, because `package.json` is already release-it's source of truth |
@@ -5,7 +5,8 @@ import { Check, type CheckResult } from './check.js';
5
5
  * just be installed.
6
6
  *
7
7
  * Which linter is the project's choice: every one it installs has to run, and it
8
- * has to install at least one.
8
+ * has to install at least one. The type checker is only required once there is
9
+ * TypeScript for it to check.
9
10
  */
10
11
  export declare class IsCiLintCompleteCheck extends Check {
11
12
  static readonly checkName = "isCiLintComplete";
@@ -6,7 +6,8 @@ import { Check } from './check.js';
6
6
  * just be installed.
7
7
  *
8
8
  * Which linter is the project's choice: every one it installs has to run, and it
9
- * has to install at least one.
9
+ * has to install at least one. The type checker is only required once there is
10
+ * TypeScript for it to check.
10
11
  */
11
12
  export class IsCiLintCompleteCheck extends Check {
12
13
  static checkName = 'isCiLintComplete';
@@ -28,6 +29,9 @@ export class IsCiLintCompleteCheck extends Check {
28
29
  ...installed.map((name) => linters[name]),
29
30
  ...policy().strings('ciLint.required.js'),
30
31
  ];
32
+ if (this.project.containsFileWithExtension(policy().strings('ciLint.typeChecker.js.extensions'))) {
33
+ required.push(policy().string('ciLint.typeChecker.js.command'));
34
+ }
31
35
  for (const command of required) {
32
36
  if (!script.includes(command)) {
33
37
  this.comment(`Incomplete ci-lint script in package.json: it must run "${command}"`);
@@ -1 +1 @@
1
- {"version":3,"file":"is-ci-lint-complete-check.js","sourceRoot":"","sources":["../../src/checks/is-ci-lint-complete-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,KAAK,EAAoB,MAAM,YAAY,CAAA;AAQpD;;;;;;;GAOG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC5C,MAAM,CAAmB,SAAS,GAAG,kBAAkB,CAAA;IAEvD,KAAK;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAc,cAAc,CAAC,CAAA;QACtE,MAAM,MAAM,GAAG,WAAW,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,CAAA;QAEhD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,0EAA0E,CAAC,CAAA;YAExF,OAAO,MAAM,CAAA;QACjB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;QACvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CACzC,CAAC,IAAI,EAAE,EAAE,CACL,WAAW,EAAE,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS;YAC/C,WAAW,EAAE,eAAe,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,CACzD,CAAA;QAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CACR,6CAA6C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAClH,CAAA;YAED,OAAO,MAAM,CAAA;QACjB,CAAC;QAED,MAAM,QAAQ,GAAG;YACb,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAW,CAAC;YACnD,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,oBAAoB,CAAC;SAC5C,CAAA;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,2DAA2D,OAAO,GAAG,CAAC,CAAA;gBAEnF,OAAO,MAAM,CAAA;YACjB,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAA;IACjB,CAAC;CACJ"}
1
+ {"version":3,"file":"is-ci-lint-complete-check.js","sourceRoot":"","sources":["../../src/checks/is-ci-lint-complete-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,KAAK,EAAoB,MAAM,YAAY,CAAA;AAQpD;;;;;;;;GAQG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC5C,MAAM,CAAmB,SAAS,GAAG,kBAAkB,CAAA;IAEvD,KAAK;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAc,cAAc,CAAC,CAAA;QACtE,MAAM,MAAM,GAAG,WAAW,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,CAAA;QAEhD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,0EAA0E,CAAC,CAAA;YAExF,OAAO,MAAM,CAAA;QACjB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;QACvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CACzC,CAAC,IAAI,EAAE,EAAE,CACL,WAAW,EAAE,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS;YAC/C,WAAW,EAAE,eAAe,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,CACzD,CAAA;QAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CACR,6CAA6C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAClH,CAAA;YAED,OAAO,MAAM,CAAA;QACjB,CAAC;QAED,MAAM,QAAQ,GAAG;YACb,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAW,CAAC;YACnD,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,oBAAoB,CAAC;SAC5C,CAAA;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,EAAE,CAAC;YAC/F,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAA;QACnE,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,2DAA2D,OAAO,GAAG,CAAC,CAAA;gBAEnF,OAAO,MAAM,CAAA;YACjB,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAA;IACjB,CAAC;CACJ"}
@@ -23,4 +23,10 @@ export declare class Project {
23
23
  */
24
24
  writeJson(relative: string, data: unknown): void;
25
25
  remove(relative: string): void;
26
+ /**
27
+ * Whether any file in the project ends in one of the extensions. node_modules
28
+ * and dot-directories (.git, .claude, .ddev, …) are not the project's own
29
+ * source, and symlinks are not followed; the walk stops at the first match.
30
+ */
31
+ containsFileWithExtension(extensions: string[], directory?: string): boolean;
26
32
  }
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, join, resolve } from 'node:path';
3
3
  /**
4
4
  * The project under inspection. Every file access a check makes goes through
@@ -60,5 +60,24 @@ export class Project {
60
60
  remove(relative) {
61
61
  rmSync(this.path(relative), { recursive: true, force: true });
62
62
  }
63
+ /**
64
+ * Whether any file in the project ends in one of the extensions. node_modules
65
+ * and dot-directories (.git, .claude, .ddev, …) are not the project's own
66
+ * source, and symlinks are not followed; the walk stops at the first match.
67
+ */
68
+ containsFileWithExtension(extensions, directory = '') {
69
+ for (const entry of readdirSync(this.path(directory), { withFileTypes: true })) {
70
+ if (entry.isFile() && extensions.some((extension) => entry.name.endsWith(extension))) {
71
+ return true;
72
+ }
73
+ if (entry.isDirectory() &&
74
+ entry.name !== 'node_modules' &&
75
+ !entry.name.startsWith('.') &&
76
+ this.containsFileWithExtension(extensions, join(directory, entry.name))) {
77
+ return true;
78
+ }
79
+ }
80
+ return false;
81
+ }
63
82
  }
64
83
  //# sourceMappingURL=project.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC9F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAElD;;;;;;;GAOG;AACH,MAAM,OAAO,OAAO;IACK,QAAQ;IAA7B,YAAqB,QAAgB;wBAAhB,QAAQ;IAAW,CAAC;IAEzC,MAAM,CAAC,EAAE,CAAC,QAAQ,GAAW,OAAO,CAAC,GAAG,EAAE;QACtC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;IACzC,CAAC;IAED,IAAI,CAAC,QAAgB;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,CAAC,QAAgB;QACnB,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,WAAW,CAAC,QAAgB;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAEhC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IAC3D,CAAC;IAED,IAAI,CAAC,QAAgB;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnF,CAAC;IAED,QAAQ,CAA8B,QAAgB;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAEpC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAA;QACf,CAAC;QAED,4EAA4E;QAC5E,0EAA0E;QAC1E,0EAA0E;QAC1E,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAM,CAAA;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACX,GAAG,QAAQ,uBAAuB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CACrF,CAAA;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAgB,EAAE,QAAgB;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAEhC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7C,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACjC,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,QAAgB,EAAE,IAAa;QACrC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,CAAC,QAAgB;QACnB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACjE,CAAC;CACJ"}
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limenet-ch/baseline",
3
- "version": "2.12.0",
3
+ "version": "2.12.1",
4
4
  "description": "A highly opinionated baseline for JS/TS projects.",
5
5
  "keywords": [
6
6
  "baseline",
@@ -107,7 +107,7 @@
107
107
  "ciLint": {
108
108
  "required": {
109
109
  "php": ["pint --parallel", "phpstan"],
110
- "js": ["tsc"]
110
+ "js": []
111
111
  },
112
112
  "linters": {
113
113
  "js": {
@@ -115,6 +115,12 @@
115
115
  "eslint": "eslint"
116
116
  }
117
117
  },
118
+ "typeChecker": {
119
+ "js": {
120
+ "command": "tsc",
121
+ "extensions": [".ts", ".tsx", ".mts", ".cts"]
122
+ }
123
+ },
118
124
  "baselineCommand": {
119
125
  "js": "baseline check"
120
126
  }
@@ -212,7 +212,7 @@
212
212
  "ciLint": {
213
213
  "type": "object",
214
214
  "additionalProperties": false,
215
- "required": ["required", "linters", "baselineCommand"],
215
+ "required": ["required", "linters", "typeChecker", "baselineCommand"],
216
216
  "properties": {
217
217
  "required": {
218
218
  "type": "object",
@@ -237,6 +237,27 @@
237
237
  }
238
238
  }
239
239
  },
240
+ "typeChecker": {
241
+ "type": "object",
242
+ "additionalProperties": false,
243
+ "required": ["js"],
244
+ "description": "The command ci-lint must run once the project contains a file with one of these extensions, outside node_modules and dot-directories. A plain JS project has nothing for it to check.",
245
+ "properties": {
246
+ "js": {
247
+ "type": "object",
248
+ "additionalProperties": false,
249
+ "required": ["command", "extensions"],
250
+ "properties": {
251
+ "command": { "type": "string" },
252
+ "extensions": {
253
+ "type": "array",
254
+ "items": { "type": "string" },
255
+ "minItems": 1
256
+ }
257
+ }
258
+ }
259
+ }
260
+ },
240
261
  "baselineCommand": {
241
262
  "type": "object",
242
263
  "additionalProperties": false,