@sinemacula/coding-standards 1.12.0 → 1.12.2
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 +4 -6
- package/js/biome.json +0 -1
- package/js/eslint/index.js +0 -1
- package/js/eslint/plugin.js +0 -2
- package/package.json +1 -1
- package/js/eslint/rules/pad-block-start.js +0 -85
package/README.md
CHANGED
|
@@ -285,7 +285,6 @@ type-checked layer.
|
|
|
285
285
|
| `@sinemacula/no-base-error` | Throw a domain-specific `Error` subclass, never the base `Error`; test code exempt. |
|
|
286
286
|
| `@sinemacula/require-copyright` | Every file must carry a documentation comment with `@copyright` and `@author`. |
|
|
287
287
|
| `@sinemacula/align-doc-tags` | `@author` and `@copyright` values line up at a single column; autofixable. |
|
|
288
|
-
| `@sinemacula/pad-block-start` | An interface, class or enum body opens with a blank line; autofixable. |
|
|
289
288
|
| `@sinemacula/single-line-property-doc` | A data member's documentation comment sits on one line; autofixable. |
|
|
290
289
|
| `@sinemacula/multiline-function-doc` | A method's documentation comment spans multiple lines; autofixable. |
|
|
291
290
|
|
|
@@ -293,11 +292,10 @@ type-checked layer.
|
|
|
293
292
|
to widen the accepted vocabulary from a consumer config. `max-methods-per-class` takes `max`, `no-base-error` takes
|
|
294
293
|
`allow`, and `require-copyright` takes `tags` to adjust their defaults. `align-doc-tags` takes `tags` and `column`,
|
|
295
294
|
the column counting from the `@`, so the default of 14 gives `@author` six spaces and `@copyright` three.
|
|
296
|
-
`
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
where present; a free function keeps the freedom of either shape.
|
|
295
|
+
Together `single-line-property-doc` and `multiline-function-doc` set a member's comment shape by its kind: data
|
|
296
|
+
members (interface property signatures, enum members and data class fields) take one line, while methods, interface
|
|
297
|
+
method signatures and class fields holding a function take several. A data comment is never required, only held to
|
|
298
|
+
one line where present; a free function keeps the freedom of either shape.
|
|
301
299
|
|
|
302
300
|
The base layer also switches on a set of built-in rules: `@typescript-eslint/no-explicit-any`, `max-lines-per-function`
|
|
303
301
|
(50 lines, test code exempt) and `max-depth` (4), plus `eslint-plugin-jsdoc` rules that require a documentation comment
|
package/js/biome.json
CHANGED
package/js/eslint/index.js
CHANGED
|
@@ -50,7 +50,6 @@ export default [
|
|
|
50
50
|
'@sinemacula/no-base-error': 'error',
|
|
51
51
|
'@sinemacula/require-copyright': 'error',
|
|
52
52
|
'@sinemacula/align-doc-tags': 'error',
|
|
53
|
-
'@sinemacula/pad-block-start': 'error',
|
|
54
53
|
'@sinemacula/single-line-property-doc': 'error',
|
|
55
54
|
'@sinemacula/multiline-function-doc': 'error',
|
|
56
55
|
|
package/js/eslint/plugin.js
CHANGED
|
@@ -5,7 +5,6 @@ import multilineFunctionDoc from './rules/multiline-function-doc.js';
|
|
|
5
5
|
import noBaseError from './rules/no-base-error.js';
|
|
6
6
|
import noInterfacePrefix from './rules/no-interface-prefix.js';
|
|
7
7
|
import noMutableStatic from './rules/no-mutable-static.js';
|
|
8
|
-
import padBlockStart from './rules/pad-block-start.js';
|
|
9
8
|
import requireCopyright from './rules/require-copyright.js';
|
|
10
9
|
import requireReadonlyPublicProperty from './rules/require-readonly-public-property.js';
|
|
11
10
|
import singleLinePropertyDoc from './rules/single-line-property-doc.js';
|
|
@@ -35,7 +34,6 @@ export default {
|
|
|
35
34
|
'no-base-error': noBaseError,
|
|
36
35
|
'require-copyright': requireCopyright,
|
|
37
36
|
'align-doc-tags': alignDocTags,
|
|
38
|
-
'pad-block-start': padBlockStart,
|
|
39
37
|
'single-line-property-doc': singleLinePropertyDoc,
|
|
40
38
|
'multiline-function-doc': multilineFunctionDoc,
|
|
41
39
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinemacula/coding-standards",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.2",
|
|
4
4
|
"description": "Centralized coding standards, static analysis configurations, and code quality tooling for all Sine Macula repositories.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Ben Carey <bdmc@sinemacula.co.uk>",
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { createRule } from './lib.js';
|
|
2
|
-
|
|
3
|
-
/** The member-carrying bodies whose first line is held clear of the brace. */
|
|
4
|
-
const BODY_TYPES = new Set(['TSInterfaceBody', 'ClassBody', 'TSEnumBody']);
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Require a blank line after the opening brace of an interface, class or enum
|
|
8
|
-
* body.
|
|
9
|
-
*
|
|
10
|
-
* The first member then stands off from the declaration the way every later
|
|
11
|
-
* member stands off from the one above it, so a body reads as an evenly spaced
|
|
12
|
-
* list rather than crowding its opening line. Only the opening brace is
|
|
13
|
-
* governed; the closing brace is left to sit against the final member.
|
|
14
|
-
*
|
|
15
|
-
* An empty body and a body written entirely on one line carry no member to
|
|
16
|
-
* separate and are left alone. Where the first member opens with a
|
|
17
|
-
* documentation comment the blank line falls above the comment, so the comment
|
|
18
|
-
* stays attached to what it documents.
|
|
19
|
-
*
|
|
20
|
-
* @author Ben Carey <bdmc@sinemacula.co.uk>
|
|
21
|
-
* @copyright 2026 Sine Macula Limited
|
|
22
|
-
*/
|
|
23
|
-
export default createRule({
|
|
24
|
-
name: 'pad-block-start',
|
|
25
|
-
meta: {
|
|
26
|
-
type: 'layout',
|
|
27
|
-
fixable: 'whitespace',
|
|
28
|
-
docs: {
|
|
29
|
-
description: 'Require a blank line after the opening brace of an interface, class or enum body.',
|
|
30
|
-
},
|
|
31
|
-
schema: [],
|
|
32
|
-
messages: {
|
|
33
|
-
missing: 'A body must begin with a blank line after its opening brace.',
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
defaultOptions: [],
|
|
37
|
-
create(context) {
|
|
38
|
-
const { sourceCode } = context;
|
|
39
|
-
|
|
40
|
-
/** Hold the first member of a body clear of the opening brace. */
|
|
41
|
-
function inspect(node) {
|
|
42
|
-
const brace = sourceCode.getFirstToken(node);
|
|
43
|
-
const close = sourceCode.getLastToken(node);
|
|
44
|
-
|
|
45
|
-
// A one-line body has no member to separate from the brace.
|
|
46
|
-
if (!brace || !close || brace.loc.end.line === close.loc.start.line) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const first = sourceCode.getTokenAfter(brace, { includeComments: true });
|
|
51
|
-
|
|
52
|
-
// An empty body carries nothing to stand off from the brace.
|
|
53
|
-
if (!first || first === close) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const blanks = first.loc.start.line - brace.loc.end.line - 1;
|
|
58
|
-
|
|
59
|
-
if (blanks === 1) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const onOwnLine = first.loc.start.line > brace.loc.end.line;
|
|
64
|
-
|
|
65
|
-
context.report({
|
|
66
|
-
loc: brace.loc,
|
|
67
|
-
messageId: 'missing',
|
|
68
|
-
fix: onOwnLine
|
|
69
|
-
? fixer => fixer.replaceTextRange(
|
|
70
|
-
[brace.range[1], first.range[0]],
|
|
71
|
-
`\n\n${' '.repeat(first.loc.start.column)}`,
|
|
72
|
-
)
|
|
73
|
-
: null,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const visitor = {};
|
|
78
|
-
|
|
79
|
-
for (const type of BODY_TYPES) {
|
|
80
|
-
visitor[type] = inspect;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return visitor;
|
|
84
|
-
},
|
|
85
|
-
});
|