@apptoolkit/harness 1.0.3 → 1.0.4
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/LICENSE +21 -0
- package/README.md +17 -48
- package/harness.js +104 -0
- package/package.json +84 -24
- package/payload/HARNESS.md +21 -0
- package/payload/author-style/README.md +56 -0
- package/payload/author-style/biome-core.json +57 -0
- package/payload/author-style/biome-react.json +9 -0
- package/payload/author-style/biome-sql.json +9 -0
- package/payload/author-style/bun.lock +37 -0
- package/payload/author-style/check.llm.md +17 -0
- package/payload/author-style/check.test.llm.md +17 -0
- package/payload/author-style/check.test.ts +238 -0
- package/payload/author-style/check.ts +181 -0
- package/payload/author-style/member-spacing.test.ts +172 -0
- package/payload/author-style/member-spacing.ts +106 -0
- package/payload/author-style/package.json +18 -0
- package/payload/author-style/plugins/class-member-order.grit +133 -0
- package/payload/author-style/plugins/event-handler-names.grit +110 -0
- package/payload/author-style/plugins/explicit-arrow-body.grit +15 -0
- package/payload/author-style/plugins/explicit-source-constructs.grit +10 -0
- package/payload/author-style/plugins/react-arrow-body.grit +85 -0
- package/payload/author-style/plugins/sql-style.grit +125 -0
- package/payload/author-style/react-module.llm.md +17 -0
- package/payload/author-style/react-module.test.ts +150 -0
- package/payload/author-style/react-module.ts +255 -0
- package/payload/author-style/source-policy.llm.md +17 -0
- package/payload/author-style/source-policy.test.ts +82 -0
- package/payload/author-style/source-policy.ts +238 -0
- package/payload/author-style/spacing.llm.md +17 -0
- package/payload/author-style/spacing.test.ts +174 -0
- package/payload/author-style/spacing.ts +211 -0
- package/payload/harness/POLICY.md +33 -0
- package/payload/harness/PROJECT.md +26 -0
- package/payload/harness/REVIEW.md +17 -0
- package/payload/harness/TEMPLATES.md +20 -0
- package/payload/harness/WORKFLOWS.md +65 -0
- package/payload/harness/runtime/ZOD-LICENSE +21 -0
- package/payload/harness/runtime/harness.mjs +104 -0
- package/payload/harness/services/README.md +26 -0
- package/payload/harness/services/penpot.json +7 -0
- package/payload/harness/services/plane.json +9 -0
- package/payload/harness/workflows/W01.md +13 -0
- package/payload/harness/workflows/W02.md +13 -0
- package/payload/harness/workflows/W03.md +13 -0
- package/payload/harness/workflows/W04.md +13 -0
- package/payload/harness/workflows/W05.md +13 -0
- package/payload/harness/workflows/W06.md +13 -0
- package/payload/harness/workflows/W07.md +13 -0
- package/payload/harness/workflows/W08.md +13 -0
- package/payload/harness/workflows/W09.md +13 -0
- package/payload/harness/workflows/W10.md +13 -0
- package/payload/harness/workflows/W11.md +13 -0
- package/payload/harness/workflows/W12.md +13 -0
- package/payload/harness/workflows/W13.md +13 -0
- package/payload/harness/workflows/W14.md +13 -0
- package/payload/harness/workflows/W15.md +13 -0
- package/payload/harness/workflows/W16.md +13 -0
- package/payload/harness/workflows/W17.md +13 -0
- package/payload/harness/workflows/W18.md +13 -0
- package/payload/harness/workflows/W19.md +13 -0
- package/payload/harness/workflows/W20.md +13 -0
- package/payload/harness/workflows/W21.md +15 -0
- package/payload/harness/workflows/W22.md +13 -0
- package/payload/harness/workflows/W23.md +21 -0
- package/payload/harness/workflows/W24.md +13 -0
- package/payload/harness/workflows/W25.md +13 -0
- package/payload/harness/workflows/W26.md +13 -0
- package/payload/harness/workflows/W27.md +13 -0
- package/payload/harness/workflows/W28.md +13 -0
- package/payload/harness/workflows/W29.md +13 -0
- package/payload/harness/workflows/W30.md +13 -0
- package/payload/harness/workflows/W31.md +13 -0
- package/payload/harness/workflows/W32.md +13 -0
- package/payload/harness/workflows/W33.md +13 -0
- package/payload/harness/workflows/W34.md +13 -0
- package/payload/harness/workflows/W35.md +13 -0
- package/payload/harness/workflows/W36.md +13 -0
- package/payload/harness/workflows/W37.md +13 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
language js(typescript, jsx)
|
|
2
|
+
|
|
3
|
+
pattern implementation() {
|
|
4
|
+
or {
|
|
5
|
+
JsArrowFunctionExpression(),
|
|
6
|
+
JsFunctionExpression(),
|
|
7
|
+
JsCallExpression(callee=$hook, arguments=JsCallArguments(args=[$callback, $dependencies])) where {
|
|
8
|
+
$hook <: or {
|
|
9
|
+
`useCallback`,
|
|
10
|
+
`React.useCallback`
|
|
11
|
+
},
|
|
12
|
+
$callback <: or {
|
|
13
|
+
JsArrowFunctionExpression(),
|
|
14
|
+
JsFunctionExpression()
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pattern local_handler($name) {
|
|
21
|
+
or {
|
|
22
|
+
JsFunctionDeclaration(id=$name, body=JsFunctionBody()),
|
|
23
|
+
JsVariableDeclarator(id=$name, initializer=JsInitializerClause(expression=implementation()))
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pattern call_target($name) { JsCallExpression(callee=JsIdentifierExpression() as $callee) where { $callee <: $name } }
|
|
28
|
+
|
|
29
|
+
pattern adapted_call($name) {
|
|
30
|
+
or {
|
|
31
|
+
call_target($name),
|
|
32
|
+
JsAwaitExpression(argument=call_target($name)),
|
|
33
|
+
JsUnaryExpression(argument=$call) as $unary where {
|
|
34
|
+
$unary <: r"(?s)void\b.*",
|
|
35
|
+
$call <: or {
|
|
36
|
+
call_target($name),
|
|
37
|
+
JsAwaitExpression(argument=call_target($name))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
pattern callback_target($name) {
|
|
44
|
+
or {
|
|
45
|
+
JsIdentifierExpression() as $reference where { $reference <: $name },
|
|
46
|
+
JsArrowFunctionExpression(body=adapted_call($name)),
|
|
47
|
+
JsArrowFunctionExpression(body=JsParenthesizedExpression(expression=adapted_call($name)))
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pattern jsx_reference($name) {
|
|
52
|
+
JsxAttribute(name=$attribute, initializer=JsxAttributeInitializerClause(value=JsxExpressionAttributeValue(expression=$callback))) where {
|
|
53
|
+
$attribute <: r"on[A-Z].*",
|
|
54
|
+
$callback <: or {
|
|
55
|
+
callback_target($name),
|
|
56
|
+
form_reference($name)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
pattern form_reference($name) {
|
|
62
|
+
JsCallExpression(callee=$factory, arguments=JsCallArguments(args=$arguments)) where {
|
|
63
|
+
$factory <: or {
|
|
64
|
+
`handleSubmit`,
|
|
65
|
+
JsStaticMemberExpression(member=$method) where { $method <: r"handleSubmit" }
|
|
66
|
+
},
|
|
67
|
+
$arguments <: or {
|
|
68
|
+
[callback_target($name)],
|
|
69
|
+
[callback_target($name), $invalid],
|
|
70
|
+
[$valid, callback_target($name)]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
pattern native_reference($name, $items) {
|
|
76
|
+
JsCallExpression(callee=$callee, arguments=JsCallArguments(args=$arguments)) where {
|
|
77
|
+
$callee <: r"(?s)(?:window|document)\s*\.\s*addEventListener",
|
|
78
|
+
$arguments <: or {
|
|
79
|
+
[$event, callback_target($name)],
|
|
80
|
+
[$event, callback_target($name), $options]
|
|
81
|
+
},
|
|
82
|
+
not $items <: contains JsIdentifierBinding() as $target where { $target <: r"(?:window|document)" }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
local_handler($name) as $declaration where {
|
|
87
|
+
not $name <: r"handle[A-Z][A-Za-z0-9]*",
|
|
88
|
+
$declaration <: within JsModule(items=$items),
|
|
89
|
+
$items <: contains or {
|
|
90
|
+
jsx_reference($name),
|
|
91
|
+
native_reference($name, $items)
|
|
92
|
+
},
|
|
93
|
+
not $items <: contains JsIdentifierBinding() as $parameter where {
|
|
94
|
+
$parameter <: $name,
|
|
95
|
+
$parameter <: within JsParameters()
|
|
96
|
+
},
|
|
97
|
+
not $items <: contains JsArrowFunctionExpression(parameters=JsIdentifierBinding() as $parameter) where {
|
|
98
|
+
$parameter <: $name
|
|
99
|
+
},
|
|
100
|
+
not $items <: contains JsIdentifierBinding() as $imported where {
|
|
101
|
+
$imported <: $name,
|
|
102
|
+
$imported <: within JsImport()
|
|
103
|
+
},
|
|
104
|
+
not $items <: contains JsIdentifierBinding() as $caught where { $caught <: $name, $caught <: within JsCatchClause() },
|
|
105
|
+
not $items <: contains JsVariableDeclarator(id=$binding, initializer=$initializer) where {
|
|
106
|
+
not $initializer <: JsInitializerClause(expression=implementation()),
|
|
107
|
+
$binding <: contains JsIdentifierBinding() as $forwarded where { $forwarded <: $name }
|
|
108
|
+
},
|
|
109
|
+
register_diagnostic(span=$name, message="Name locally implemented event handlers with a descriptive handle prefix, such as handleDelete.", severity="error")
|
|
110
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
language js(typescript, jsx)
|
|
2
|
+
|
|
3
|
+
JsArrowFunctionExpression(body=$body) where {
|
|
4
|
+
not $body <: or {
|
|
5
|
+
JsFunctionBody(),
|
|
6
|
+
JsxTagExpression(),
|
|
7
|
+
JsParenthesizedExpression(expression=JsxTagExpression())
|
|
8
|
+
},
|
|
9
|
+
$body <: or {
|
|
10
|
+
r"(?s).*\n.*",
|
|
11
|
+
contains JsConditionalExpression(),
|
|
12
|
+
contains JsSequenceExpression()
|
|
13
|
+
},
|
|
14
|
+
register_diagnostic(span=$body, message="Use a block and an explicit return for a multiline or branching arrow body.", severity="error")
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
language js(typescript, jsx)
|
|
2
|
+
|
|
3
|
+
or {
|
|
4
|
+
TsUnknownType() as $type where {
|
|
5
|
+
register_diagnostic(span=$type, message="Use an explicit domain type and validate external values at the boundary.", severity="error")
|
|
6
|
+
},
|
|
7
|
+
or { JsPreUpdateExpression(), JsPostUpdateExpression() } as $expression where {
|
|
8
|
+
register_diagnostic(span=$expression, message="Use an explicit update and preserve the original value if the expression consumes it.", severity="error")
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
language js(typescript, jsx)
|
|
2
|
+
|
|
3
|
+
pattern bare_call() {
|
|
4
|
+
or {
|
|
5
|
+
JsCallExpression(),
|
|
6
|
+
JsParenthesizedExpression(expression=JsCallExpression())
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
pattern void_call() {
|
|
11
|
+
JsUnaryExpression(argument=$argument) as $unary where {
|
|
12
|
+
$unary <: r"(?s)void\b.*",
|
|
13
|
+
$argument <: or {
|
|
14
|
+
bare_call(),
|
|
15
|
+
JsAwaitExpression(argument=bare_call())
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pattern handler_call() {
|
|
21
|
+
or {
|
|
22
|
+
bare_call(),
|
|
23
|
+
JsAwaitExpression(argument=bare_call()),
|
|
24
|
+
void_call(),
|
|
25
|
+
JsParenthesizedExpression(expression=JsAwaitExpression(argument=bare_call())),
|
|
26
|
+
JsParenthesizedExpression(expression=void_call())
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pattern inline_handler() {
|
|
31
|
+
handler_call() as $body where {
|
|
32
|
+
not $body <: contains JsFunctionBody(),
|
|
33
|
+
not $body <: contains JsFunctionExpression(),
|
|
34
|
+
not $body <: contains JsSequenceExpression(),
|
|
35
|
+
not $body <: contains JsAssignmentExpression(),
|
|
36
|
+
not $body <: contains JsPreUpdateExpression(),
|
|
37
|
+
not $body <: contains JsPostUpdateExpression(),
|
|
38
|
+
not $body <: contains JsArrowFunctionExpression(body=JsConditionalExpression()),
|
|
39
|
+
not $body <: contains JsArrowFunctionExpression(body=JsParenthesizedExpression(expression=JsConditionalExpression()))
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
pattern jsx_handler($callback) {
|
|
44
|
+
JsxAttribute(name=$name, initializer=JsxAttributeInitializerClause(value=JsxExpressionAttributeValue(expression=$callback))) where {
|
|
45
|
+
$name <: r"on[A-Z].*"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pattern compact_return($expression) {
|
|
50
|
+
JsFunctionBody(statements=[JsReturnStatement(argument=$expression)]) as $body where {
|
|
51
|
+
$expression <: inline_handler(),
|
|
52
|
+
not $body <: r"(?s).*(?:/\*|//).*"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
or {
|
|
57
|
+
JsArrowFunctionExpression(body=$body) as $arrow where {
|
|
58
|
+
not $body <: JsFunctionBody(),
|
|
59
|
+
not $body <: or {
|
|
60
|
+
JsxTagExpression(),
|
|
61
|
+
JsParenthesizedExpression(expression=JsxTagExpression())
|
|
62
|
+
},
|
|
63
|
+
not and { $body <: handler_call(), $arrow <: within jsx_handler($arrow) },
|
|
64
|
+
$body <: or {
|
|
65
|
+
r"(?s).*\n.*",
|
|
66
|
+
contains JsConditionalExpression(),
|
|
67
|
+
contains JsSequenceExpression()
|
|
68
|
+
},
|
|
69
|
+
register_diagnostic(span=$body, message="Use a block and an explicit return for a multiline or branching arrow body.", severity="error", fix_kind="safe"),
|
|
70
|
+
$body => `{ return $body; }`
|
|
71
|
+
},
|
|
72
|
+
jsx_handler(JsArrowFunctionExpression(body=$body)) where {
|
|
73
|
+
$body <: compact_return($expression),
|
|
74
|
+
register_diagnostic(span=$body, message="Keep an inline JSX handler as one call expression. Extract logic into a named component-level useCallback.", severity="error", fix_kind="safe"),
|
|
75
|
+
$body => `$expression`
|
|
76
|
+
},
|
|
77
|
+
jsx_handler(JsArrowFunctionExpression(body=$body)) where {
|
|
78
|
+
not $body <: inline_handler(),
|
|
79
|
+
not $body <: compact_return(),
|
|
80
|
+
register_diagnostic(span=$body, message="Keep an inline JSX handler as one call expression. Extract logic into a named component-level useCallback.", severity="error")
|
|
81
|
+
},
|
|
82
|
+
jsx_handler(JsFunctionExpression() as $callback) where {
|
|
83
|
+
register_diagnostic(span=$callback, message="Use a named component-level useCallback instead of an inline JSX function.", severity="error")
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
language js(typescript, jsx)
|
|
2
|
+
|
|
3
|
+
pattern sql_template($elements) {
|
|
4
|
+
JsTemplateExpression(tag=$tag, elements=$elements) where {
|
|
5
|
+
$tag <: r"sql",
|
|
6
|
+
not $elements <: some bubble $part where {
|
|
7
|
+
$part <: JsTemplateChunkElement(),
|
|
8
|
+
or {
|
|
9
|
+
not $part <: r"(?s)(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*",
|
|
10
|
+
$part <: r"(?s).*(?:--|/\*).*"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
or {
|
|
17
|
+
sql_template($elements) where {
|
|
18
|
+
$elements <: some bubble $chunk where {
|
|
19
|
+
$chunk <: JsTemplateChunkElement(),
|
|
20
|
+
$chunk <: or {
|
|
21
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:a(?i:ll)|Al(?i:l)|ALl)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
22
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:a(?i:nd)|An(?i:d)|ANd)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
23
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:a(?i:ny)|An(?i:y)|ANy)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
24
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:a(?i:rray)|Ar(?i:ray)|ARr(?i:ay)|ARRa(?i:y)|ARRAy)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
25
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:a(?i:s)|As)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
26
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:a(?i:sc)|As(?i:c)|ASc)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
27
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:b(?i:etween)|Be(?i:tween)|BEt(?i:ween)|BETw(?i:een)|BETWe(?i:en)|BETWEe(?i:n)|BETWEEn)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
28
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:b(?i:y)|By)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
29
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:c(?i:ase)|Ca(?i:se)|CAs(?i:e)|CASe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
30
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:c(?i:onflict)|Co(?i:nflict)|COn(?i:flict)|CONf(?i:lict)|CONFl(?i:ict)|CONFLi(?i:ct)|CONFLIc(?i:t)|CONFLICt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
31
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:c(?i:ross)|Cr(?i:oss)|CRo(?i:ss)|CROs(?i:s)|CROSs)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
32
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:d(?i:elete)|De(?i:lete)|DEl(?i:ete)|DELe(?i:te)|DELEt(?i:e)|DELETe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
33
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:d(?i:esc)|De(?i:sc)|DEs(?i:c)|DESc)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
34
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:d(?i:istinct)|Di(?i:stinct)|DIs(?i:tinct)|DISt(?i:inct)|DISTi(?i:nct)|DISTIn(?i:ct)|DISTINc(?i:t)|DISTINCt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
35
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:d(?i:o)|Do)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
36
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:e(?i:lse)|El(?i:se)|ELs(?i:e)|ELSe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
37
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:e(?i:nd)|En(?i:d)|ENd)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
38
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:e(?i:scape)|Es(?i:cape)|ESc(?i:ape)|ESCa(?i:pe)|ESCAp(?i:e)|ESCAPe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
39
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:e(?i:xcept)|Ex(?i:cept)|EXc(?i:ept)|EXCe(?i:pt)|EXCEp(?i:t)|EXCEPt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
40
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:e(?i:xists)|Ex(?i:ists)|EXi(?i:sts)|EXIs(?i:ts)|EXISt(?i:s)|EXISTs)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
41
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:f(?i:alse)|Fa(?i:lse)|FAl(?i:se)|FALs(?i:e)|FALSe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
42
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:f(?i:or)|Fo(?i:r)|FOr)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
43
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:f(?i:rom)|Fr(?i:om)|FRo(?i:m)|FROm)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
44
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:f(?i:ull)|Fu(?i:ll)|FUl(?i:l)|FULl)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
45
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:g(?i:roup)|Gr(?i:oup)|GRo(?i:up)|GROu(?i:p)|GROUp)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
46
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:h(?i:aving)|Ha(?i:ving)|HAv(?i:ing)|HAVi(?i:ng)|HAVIn(?i:g)|HAVINg)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
47
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:like)|Il(?i:ike)|ILi(?i:ke)|ILIk(?i:e)|ILIKe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
48
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:n)|In)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
49
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:nner)|In(?i:ner)|INn(?i:er)|INNe(?i:r)|INNEr)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
50
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:nsert)|In(?i:sert)|INs(?i:ert)|INSe(?i:rt)|INSEr(?i:t)|INSERt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
51
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:ntersect)|In(?i:tersect)|INt(?i:ersect)|INTe(?i:rsect)|INTEr(?i:sect)|INTERs(?i:ect)|INTERSe(?i:ct)|INTERSEc(?i:t)|INTERSECt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
52
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:nto)|In(?i:to)|INt(?i:o)|INTo)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
53
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:i(?i:s)|Is)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
54
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:j(?i:oin)|Jo(?i:in)|JOi(?i:n)|JOIn)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
55
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:l(?i:eft)|Le(?i:ft)|LEf(?i:t)|LEFt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
56
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:l(?i:ike)|Li(?i:ke)|LIk(?i:e)|LIKe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
57
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:l(?i:imit)|Li(?i:mit)|LIm(?i:it)|LIMi(?i:t)|LIMIt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
58
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:n(?i:atural)|Na(?i:tural)|NAt(?i:ural)|NATu(?i:ral)|NATUr(?i:al)|NATURa(?i:l)|NATURAl)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
59
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:n(?i:ot)|No(?i:t)|NOt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
60
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:n(?i:othing)|No(?i:thing)|NOt(?i:hing)|NOTh(?i:ing)|NOTHi(?i:ng)|NOTHIn(?i:g)|NOTHINg)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
61
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:n(?i:ull)|Nu(?i:ll)|NUl(?i:l)|NULl)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
62
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:o(?i:ffset)|Of(?i:fset)|OFf(?i:set)|OFFs(?i:et)|OFFSe(?i:t)|OFFSEt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
63
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:o(?i:n)|On)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
64
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:o(?i:r)|Or)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
65
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:o(?i:rder)|Or(?i:der)|ORd(?i:er)|ORDe(?i:r)|ORDEr)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
66
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:o(?i:uter)|Ou(?i:ter)|OUt(?i:er)|OUTe(?i:r)|OUTEr)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
67
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:o(?i:ver)|Ov(?i:er)|OVe(?i:r)|OVEr)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
68
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:p(?i:artition)|Pa(?i:rtition)|PAr(?i:tition)|PARt(?i:ition)|PARTi(?i:tion)|PARTIt(?i:ion)|PARTITi(?i:on)|PARTITIo(?i:n)|PARTITIOn)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
69
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:r(?i:ecursive)|Re(?i:cursive)|REc(?i:ursive)|RECu(?i:rsive)|RECUr(?i:sive)|RECURs(?i:ive)|RECURSi(?i:ve)|RECURSIv(?i:e)|RECURSIVe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
70
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:r(?i:eturning)|Re(?i:turning)|REt(?i:urning)|RETu(?i:rning)|RETUr(?i:ning)|RETURn(?i:ing)|RETURNi(?i:ng)|RETURNIn(?i:g)|RETURNINg)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
71
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:r(?i:ight)|Ri(?i:ght)|RIg(?i:ht)|RIGh(?i:t)|RIGHt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
72
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:s(?i:elect)|Se(?i:lect)|SEl(?i:ect)|SELe(?i:ct)|SELEc(?i:t)|SELECt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
73
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:s(?i:et)|Se(?i:t)|SEt)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
74
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:s(?i:ome)|So(?i:me)|SOm(?i:e)|SOMe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
75
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:t(?i:hen)|Th(?i:en)|THe(?i:n)|THEn)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
76
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:t(?i:rue)|Tr(?i:ue)|TRu(?i:e)|TRUe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
77
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:u(?i:nion)|Un(?i:ion)|UNi(?i:on)|UNIo(?i:n)|UNIOn)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
78
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:u(?i:pdate)|Up(?i:date)|UPd(?i:ate)|UPDa(?i:te)|UPDAt(?i:e)|UPDATe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
79
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:u(?i:sing)|Us(?i:ing)|USi(?i:ng)|USIn(?i:g)|USINg)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
80
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:v(?i:alues)|Va(?i:lues)|VAl(?i:ues)|VALu(?i:es)|VALUe(?i:s)|VALUEs)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
81
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:w(?i:hen)|Wh(?i:en)|WHe(?i:n)|WHEn)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
82
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:w(?i:here)|Wh(?i:ere)|WHe(?i:re)|WHEr(?i:e)|WHERe)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*",
|
|
83
|
+
r"(?s)(?:(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-])?(?:w(?i:ith)|Wi(?i:th)|WIt(?i:h)|WITh)(?:[ \t\r\n(),;+*/%<>=!~^|&?@#\[\]-]|$).*"
|
|
84
|
+
},
|
|
85
|
+
register_diagnostic(span=$chunk, message="Use uppercase SQL keywords in the selected tagged SQL.", severity="error")
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
sql_template($elements) where {
|
|
89
|
+
$elements <: some bubble $chunk where {
|
|
90
|
+
$chunk <: JsTemplateChunkElement(),
|
|
91
|
+
$chunk <: or {
|
|
92
|
+
r"(?s)(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*,(?:[^ \t\r\n]|$).*",
|
|
93
|
+
r"(?s)(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*=(?:[^ \t\r\n=>]|$).*",
|
|
94
|
+
r"(?s)(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9)\]])=.*",
|
|
95
|
+
r"(?s)=.*"
|
|
96
|
+
},
|
|
97
|
+
register_diagnostic(span=$chunk, message="Add SQL whitespace after commas and around equals signs.", severity="error")
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
sql_template($elements) as $template where {
|
|
101
|
+
$elements <: [$first, ...],
|
|
102
|
+
$first <: r"(?s)\n( *)(SELECT|UPDATE|INSERT|DELETE) .*"($root_indent, $root_keyword),
|
|
103
|
+
not $template <: r"(?s).*(?:\(\s*(?:SELECT|WITH)|\bUNION\b|\bINTERSECT\b|\bEXCEPT\b).*",
|
|
104
|
+
not $elements <: some $quoted_chunk where {
|
|
105
|
+
$quoted_chunk <: JsTemplateChunkElement(),
|
|
106
|
+
$quoted_chunk <: r"(?s)(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*(?:'(?:[^'\\]|'')*\n(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\n(?:[^\x22\\]|\x22\x22)*\x22)(?:(?:'(?:[^'\\]|'')*'|\x22(?:[^\x22\\]|\x22\x22)*\x22)|[A-Za-z_\x{80}-\x{10ffff}][A-Za-z_0-9$\x{80}-\x{10ffff}]*|[0-9]+|[. :\t\r\n(),;+*/%<>=!~^|&?@#\[\]-])*"
|
|
107
|
+
},
|
|
108
|
+
$indent_size = length($root_indent),
|
|
109
|
+
$keyword_size = length($root_keyword),
|
|
110
|
+
$river = $indent_size + $keyword_size,
|
|
111
|
+
$elements <: some $chunk where {
|
|
112
|
+
$chunk <: JsTemplateChunkElement(),
|
|
113
|
+
$lines = split($chunk, separator=`
|
|
114
|
+
`),
|
|
115
|
+
$lines <: some $line where {
|
|
116
|
+
$line <: r"( *)(FROM|WHERE|SET|GROUP BY|ORDER BY|HAVING|LIMIT|OFFSET|RETURNING|VALUES)(?:[ \t].*|$)"($indent, $clause),
|
|
117
|
+
$line_indent_size = length($indent),
|
|
118
|
+
$clause_size = length($clause),
|
|
119
|
+
$clause_end = $line_indent_size + $clause_size,
|
|
120
|
+
not $clause_end <: $river,
|
|
121
|
+
register_diagnostic(span=$chunk, message="Right-align SQL root clauses with the opening keyword to form a river.", severity="error")
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# React module check map
|
|
2
|
+
|
|
3
|
+
- [Recognized bindings and render expressions](#recognized-bindings-and-render-expressions)
|
|
4
|
+
- [Module checks](#module-checks)
|
|
5
|
+
- [Fixtures and limits](#fixtures-and-limits)
|
|
6
|
+
|
|
7
|
+
## Recognized bindings and render expressions
|
|
8
|
+
|
|
9
|
+
`reactBindings` discovers React imports, `hasReactType` identifies direct `FC` and `FunctionComponent` annotations, and `isReactWrapper` identifies direct `memo` and `forwardRef` calls tied to those imports. `isJsxResult` and `returnsJsx` recognize supported rendered shapes without treating nested callbacks as component returns.
|
|
10
|
+
|
|
11
|
+
## Module checks
|
|
12
|
+
|
|
13
|
+
`findReactModuleIssues` inspects top-level TSX declarations and the export targets resolved by `defaultTargets`. It checks focused named components, direct component typing and default exports. Biome's separate React Grit plugins check inline event callbacks and local handler names.
|
|
14
|
+
|
|
15
|
+
## Fixtures and limits
|
|
16
|
+
|
|
17
|
+
See `react-module.test.ts` for supported syntax and `check.test.ts` for integration with the isolated profile. The check does not follow arbitrary factories, re-exports or cross-file values. Use the React profile on applicable reusable component files. Keep framework entry points and class-based or library-owned components under the project's own review rules.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { findReactModuleIssues } from './react-module.ts';
|
|
5
|
+
|
|
6
|
+
function issues(source: string, fileName = 'Panel.tsx'): string[] {
|
|
7
|
+
return findReactModuleIssues(source, fileName).map((issue) => issue.message);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
test('checks TSX modules only', () => {
|
|
11
|
+
assert.deepEqual(issues('export default function Panel() { return <p />; }', 'Panel.ts'), []);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('accepts a PascalCase const default and equivalent local export', () => {
|
|
15
|
+
assert.deepEqual(issues("import type { FC } from 'react'; const Panel: FC = () => <p />; export default Panel;"), []);
|
|
16
|
+
assert.deepEqual(
|
|
17
|
+
issues(
|
|
18
|
+
"import type { FC } from 'react'; const Panel: FC = function render() { return <p />; }; export { Panel as default };",
|
|
19
|
+
),
|
|
20
|
+
[],
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('requires a directly imported React FC annotation for visible JSX in a named const', () => {
|
|
25
|
+
for (const source of [
|
|
26
|
+
'const Panel = () => <p />; export default Panel;',
|
|
27
|
+
'const Panel = function render() { return <p />; }; export default Panel;',
|
|
28
|
+
"import type { FC } from './local'; const Panel: FC = () => <p />; export default Panel;",
|
|
29
|
+
]) {
|
|
30
|
+
assert.equal(issues(source).length, 1);
|
|
31
|
+
assert.match(issues(source).join('\n'), /Annotate React arrow components/);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('recognizes FC imports and React type namespaces even without visible JSX', () => {
|
|
36
|
+
for (const source of [
|
|
37
|
+
"import type { FC as View } from 'react'; const Panel: View = () => null;",
|
|
38
|
+
"import type * as R from 'react'; const Panel: R.FunctionComponent = () => null;",
|
|
39
|
+
"import { type FC } from 'react'; const Panel: FC = () => null;",
|
|
40
|
+
"import { default as R } from 'react'; const Panel: R.FC = () => null;",
|
|
41
|
+
]) {
|
|
42
|
+
assert.match(issues(source).join('\n'), /named React component as default/);
|
|
43
|
+
assert.deepEqual(issues(`${source} export default Panel;`), []);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('recognizes real React wrapper imports and counts an inline render as one component', () => {
|
|
48
|
+
for (const source of [
|
|
49
|
+
"import React from 'react'; const Panel = React.memo(() => <p />);",
|
|
50
|
+
"import * as R from 'react'; const Panel = R.forwardRef(function Render() { return <p />; });",
|
|
51
|
+
"import { memo as wrap, forwardRef } from 'react'; const Panel = wrap(forwardRef(() => <p />));",
|
|
52
|
+
]) {
|
|
53
|
+
assert.match(issues(source).join('\n'), /named React component as default/);
|
|
54
|
+
assert.deepEqual(issues(`${source} export default Panel;`), []);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('does not infer React wrappers or annotations from other packages or type-only value imports', () => {
|
|
59
|
+
const source = [
|
|
60
|
+
"import { memo, FC } from './local';",
|
|
61
|
+
"import { type forwardRef } from 'react';",
|
|
62
|
+
"import type * as R from 'react';",
|
|
63
|
+
'const Helper = memo(() => <p />);',
|
|
64
|
+
'const Task: FC = () => null;',
|
|
65
|
+
'const External = forwardRef(() => <p />);',
|
|
66
|
+
'const Typed = R.memo(() => <p />);',
|
|
67
|
+
'const Item = Unknown.memo(() => <p />);',
|
|
68
|
+
'export default Helper;',
|
|
69
|
+
].join('\n');
|
|
70
|
+
|
|
71
|
+
assert.deepEqual(issues(source), []);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('requires one module component and a default targeting that component', () => {
|
|
75
|
+
const source = [
|
|
76
|
+
"import type { FC } from 'react';",
|
|
77
|
+
'const Panel: FC = () => <p />;',
|
|
78
|
+
'const Second: FC = () => <div />;',
|
|
79
|
+
'export default Panel;',
|
|
80
|
+
].join('\n');
|
|
81
|
+
const findings = findReactModuleIssues(source, 'Panel.tsx');
|
|
82
|
+
|
|
83
|
+
assert.deepEqual(
|
|
84
|
+
findings.map(({ line, column }) => ({ line, column })),
|
|
85
|
+
[
|
|
86
|
+
{ line: 3, column: 7 },
|
|
87
|
+
{ line: 3, column: 7 },
|
|
88
|
+
],
|
|
89
|
+
);
|
|
90
|
+
assert.match(findings[0]?.message ?? '', /one React component per file/);
|
|
91
|
+
assert.match(findings[1]?.message ?? '', /named React component as default/);
|
|
92
|
+
assert.match(issues('const Panel = () => <p />; export { default } from "./other";').join('\n'), /as default/);
|
|
93
|
+
assert.match(issues('const Panel = () => <p />; export type { Panel as default };').join('\n'), /as default/);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('requires a named PascalCase const for function declarations and inline defaults', () => {
|
|
97
|
+
for (const source of [
|
|
98
|
+
'export default function Panel() { return <p />; }',
|
|
99
|
+
'export default function () { return <p />; }',
|
|
100
|
+
'function Panel() { return <p />; } export default Panel;',
|
|
101
|
+
'export default (() => <p />);',
|
|
102
|
+
"import { memo } from 'react'; export default memo(() => <p />);",
|
|
103
|
+
'let Panel = () => <p />; export default Panel;',
|
|
104
|
+
'const panel = () => <p />; export default panel;',
|
|
105
|
+
'const Panel_Name = () => <p />; export default Panel_Name;',
|
|
106
|
+
]) {
|
|
107
|
+
assert.equal(issues(source).length, 1);
|
|
108
|
+
assert.match(issues(source).join('\n'), /named const component/);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('recognizes visible JSX in branching, array and wrapped expression returns', () => {
|
|
113
|
+
for (const render of [
|
|
114
|
+
'() => condition ? <p /> : null',
|
|
115
|
+
'() => condition && <p />',
|
|
116
|
+
'() => value || <p />',
|
|
117
|
+
'() => value ?? <p />',
|
|
118
|
+
'() => [<p />, <></>]',
|
|
119
|
+
'() => (<p /> satisfies Value)',
|
|
120
|
+
'() => { if (condition) { return <p />; } return null; }',
|
|
121
|
+
]) {
|
|
122
|
+
assert.match(issues(`const Panel = ${render};`).join('\n'), /named React component as default/);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('ignores JSX values, unrelated return shapes, nested helpers and ambient declarations', () => {
|
|
127
|
+
const source = [
|
|
128
|
+
"import type { FC } from 'react';",
|
|
129
|
+
'declare const Ambient: FC;',
|
|
130
|
+
'const { Hidden } = components;',
|
|
131
|
+
'const Literal = <p />;',
|
|
132
|
+
'const State = () => ({ preview: <p /> });',
|
|
133
|
+
'const Truthy = () => <p /> && true;',
|
|
134
|
+
'const RenderedText = () => renderToString(<p />);',
|
|
135
|
+
'const Outer = () => { function Inner() { return <p />; } return Inner; };',
|
|
136
|
+
'const Collector = () => items.map(() => <p />);',
|
|
137
|
+
'class Boundary { render() { return <p />; } }',
|
|
138
|
+
'function renderLabel() { return <p />; }',
|
|
139
|
+
'function build() { const Nested = () => <p />; return Nested; }',
|
|
140
|
+
'const Panel: FC = () => <div />;',
|
|
141
|
+
'export default Panel;',
|
|
142
|
+
].join('\n');
|
|
143
|
+
|
|
144
|
+
assert.deepEqual(issues(source), []);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('does not classify default noncomponent functions or default re-exports', () => {
|
|
148
|
+
assert.deepEqual(issues('export default function load() { return () => <p />; }'), []);
|
|
149
|
+
assert.deepEqual(issues('export { default } from "./Panel";'), []);
|
|
150
|
+
});
|