@foldkit/oxlint-plugin 0.5.0 → 0.6.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/all.json CHANGED
@@ -19,6 +19,7 @@
19
19
  "foldkit/no-child-message-construction-in-root": "error",
20
20
  "foldkit/no-disabling-dev-guardrails": "error",
21
21
  "foldkit/no-duplicate-onmount-per-element": "error",
22
+ "foldkit/no-empty-children-array": "error",
22
23
  "foldkit/no-empty-object-tagged-call": "error",
23
24
  "foldkit/no-hand-rolled-command-struct": "error",
24
25
  "foldkit/no-hardcoded-route-strings": "error",
@@ -51,6 +52,7 @@
51
52
  "foldkit/no-child-message-construction-in-root": "off",
52
53
  "foldkit/no-disabling-dev-guardrails": "off",
53
54
  "foldkit/no-duplicate-onmount-per-element": "off",
55
+ "foldkit/no-empty-children-array": "off",
54
56
  "foldkit/no-empty-object-tagged-call": "off",
55
57
  "foldkit/no-hand-rolled-command-struct": "off",
56
58
  "foldkit/no-hardcoded-route-strings": "off",
package/dist/index.js CHANGED
@@ -11038,6 +11038,297 @@ var noDuplicateOnmountPerElement = Rule_exports.define({
11038
11038
  }
11039
11039
  });
11040
11040
 
11041
+ // src/elementBuilderNames.ts
11042
+ var ELEMENT_BUILDER_NAMES = /* @__PURE__ */ new Set([
11043
+ // HTML
11044
+ "a",
11045
+ "abbr",
11046
+ "address",
11047
+ "area",
11048
+ "article",
11049
+ "aside",
11050
+ "audio",
11051
+ "b",
11052
+ "base",
11053
+ "bdi",
11054
+ "bdo",
11055
+ "blockquote",
11056
+ "body",
11057
+ "br",
11058
+ "button",
11059
+ "canvas",
11060
+ "caption",
11061
+ "cite",
11062
+ "code",
11063
+ "col",
11064
+ "colgroup",
11065
+ "data",
11066
+ "datalist",
11067
+ "dd",
11068
+ "del",
11069
+ "details",
11070
+ "dfn",
11071
+ "dialog",
11072
+ "div",
11073
+ "dl",
11074
+ "dt",
11075
+ "em",
11076
+ "embed",
11077
+ "fieldset",
11078
+ "figcaption",
11079
+ "figure",
11080
+ "footer",
11081
+ "form",
11082
+ "h1",
11083
+ "h2",
11084
+ "h3",
11085
+ "h4",
11086
+ "h5",
11087
+ "h6",
11088
+ "head",
11089
+ "header",
11090
+ "hgroup",
11091
+ "hr",
11092
+ "html",
11093
+ "i",
11094
+ "iframe",
11095
+ "img",
11096
+ "input",
11097
+ "ins",
11098
+ "kbd",
11099
+ "label",
11100
+ "legend",
11101
+ "li",
11102
+ "link",
11103
+ "main",
11104
+ "map",
11105
+ "mark",
11106
+ "menu",
11107
+ "meta",
11108
+ "meter",
11109
+ "nav",
11110
+ "noscript",
11111
+ "object",
11112
+ "ol",
11113
+ "optgroup",
11114
+ "option",
11115
+ "output",
11116
+ "p",
11117
+ "picture",
11118
+ "portal",
11119
+ "pre",
11120
+ "progress",
11121
+ "q",
11122
+ "rp",
11123
+ "rt",
11124
+ "ruby",
11125
+ "s",
11126
+ "samp",
11127
+ "script",
11128
+ "search",
11129
+ "section",
11130
+ "select",
11131
+ "slot",
11132
+ "small",
11133
+ "source",
11134
+ "span",
11135
+ "strong",
11136
+ "style",
11137
+ "sub",
11138
+ "summary",
11139
+ "sup",
11140
+ "table",
11141
+ "tbody",
11142
+ "td",
11143
+ "template",
11144
+ "textarea",
11145
+ "tfoot",
11146
+ "th",
11147
+ "thead",
11148
+ "time",
11149
+ "title",
11150
+ "tr",
11151
+ "track",
11152
+ "u",
11153
+ "ul",
11154
+ "var",
11155
+ "video",
11156
+ "wbr",
11157
+ // SVG
11158
+ "svg",
11159
+ "animate",
11160
+ "animateMotion",
11161
+ "animateTransform",
11162
+ "circle",
11163
+ "clipPath",
11164
+ "defs",
11165
+ "desc",
11166
+ "ellipse",
11167
+ "feBlend",
11168
+ "feColorMatrix",
11169
+ "feComponentTransfer",
11170
+ "feComposite",
11171
+ "feConvolveMatrix",
11172
+ "feDiffuseLighting",
11173
+ "feDisplacementMap",
11174
+ "feDistantLight",
11175
+ "feDropShadow",
11176
+ "feFlood",
11177
+ "feFuncA",
11178
+ "feFuncB",
11179
+ "feFuncG",
11180
+ "feFuncR",
11181
+ "feGaussianBlur",
11182
+ "feImage",
11183
+ "feMerge",
11184
+ "feMergeNode",
11185
+ "feMorphology",
11186
+ "feOffset",
11187
+ "fePointLight",
11188
+ "feSpecularLighting",
11189
+ "feSpotLight",
11190
+ "feTile",
11191
+ "feTurbulence",
11192
+ "filter",
11193
+ "foreignObject",
11194
+ "g",
11195
+ "image",
11196
+ "line",
11197
+ "linearGradient",
11198
+ "marker",
11199
+ "mask",
11200
+ "metadata",
11201
+ "mpath",
11202
+ "path",
11203
+ "pattern",
11204
+ "polygon",
11205
+ "polyline",
11206
+ "radialGradient",
11207
+ "rect",
11208
+ "set",
11209
+ "stop",
11210
+ "switch",
11211
+ "symbol",
11212
+ "text",
11213
+ "textPath",
11214
+ "tspan",
11215
+ "use",
11216
+ "view",
11217
+ // MathML
11218
+ "math",
11219
+ "annotation",
11220
+ "maction",
11221
+ "menclose",
11222
+ "merror",
11223
+ "mfenced",
11224
+ "mfrac",
11225
+ "mglyph",
11226
+ "mi",
11227
+ "mlabeledtr",
11228
+ "mlongdiv",
11229
+ "mmultiscripts",
11230
+ "mn",
11231
+ "mo",
11232
+ "mover",
11233
+ "mpadded",
11234
+ "mphantom",
11235
+ "mprescripts",
11236
+ "mroot",
11237
+ "mrow",
11238
+ "ms",
11239
+ "mscarries",
11240
+ "mscarry",
11241
+ "msgroup",
11242
+ "msline",
11243
+ "mspace",
11244
+ "msqrt",
11245
+ "msrow",
11246
+ "mstack",
11247
+ "mstyle",
11248
+ "msub",
11249
+ "msubsup",
11250
+ "msup",
11251
+ "mtable",
11252
+ "mtd",
11253
+ "mtext",
11254
+ "mtr",
11255
+ "munder",
11256
+ "munderover",
11257
+ "semantics"
11258
+ ]);
11259
+
11260
+ // src/rules/no-empty-children-array.ts
11261
+ var BUILDER_BINDINGS = /* @__PURE__ */ new Set(["h", "ih", "inertHtml"]);
11262
+ var KEYED_PROPERTY = "keyed";
11263
+ var builderCallee = (callee) => {
11264
+ if (!isMemberExpression(callee) || callee.computed === true) {
11265
+ return Option_exports.none();
11266
+ }
11267
+ if (!isIdentifier(callee.object) || !BUILDER_BINDINGS.has(callee.object.name) || !isIdentifier(callee.property)) {
11268
+ return Option_exports.none();
11269
+ }
11270
+ return Option_exports.some({
11271
+ binding: callee.object.name,
11272
+ property: callee.property.name
11273
+ });
11274
+ };
11275
+ var elementCallTarget = (node) => node.arguments.length === 2 ? builderCallee(node.callee).pipe(
11276
+ Option_exports.filter(({ property }) => ELEMENT_BUILDER_NAMES.has(property)),
11277
+ Option_exports.map(({ binding, property }) => `${binding}.${property}([...])`)
11278
+ ) : Option_exports.none();
11279
+ var keyedCallTarget = (node) => {
11280
+ if (node.arguments.length !== 3 || !isCallExpression(node.callee)) {
11281
+ return Option_exports.none();
11282
+ }
11283
+ return builderCallee(node.callee.callee).pipe(
11284
+ Option_exports.filter(({ property }) => property === KEYED_PROPERTY),
11285
+ Option_exports.map(
11286
+ ({ binding }) => `${binding}.${KEYED_PROPERTY}(tag)(key, [...])`
11287
+ )
11288
+ );
11289
+ };
11290
+ var childrenArgument = (node) => Array_exports.last(node.arguments);
11291
+ var emptyChildrenMessage = (target) => `Omit the children argument when an element has none. Write ${target} instead of passing a trailing []. The builder defaults children to an empty array, so the two build the same vnode and the [] carries no information.`;
11292
+ var noEmptyChildrenArray = Rule_exports.define({
11293
+ name: "no-empty-children-array",
11294
+ meta: Rule_exports.meta({
11295
+ type: "suggestion",
11296
+ description: "Omit the children argument on elements that have no children."
11297
+ }),
11298
+ create: function* () {
11299
+ const ctx = yield* RuleContext;
11300
+ return {
11301
+ CallExpression: (node) => {
11302
+ if (!isCallExpression(node)) {
11303
+ return Effect_exports.void;
11304
+ }
11305
+ const maybeTarget = Option_exports.orElse(
11306
+ elementCallTarget(node),
11307
+ () => keyedCallTarget(node)
11308
+ );
11309
+ if (Option_exports.isNone(maybeTarget)) {
11310
+ return Effect_exports.void;
11311
+ }
11312
+ const maybeChildren = childrenArgument(node);
11313
+ if (Option_exports.isNone(maybeChildren) || !isArrayExpression(maybeChildren.value) || Array_exports.isReadonlyArrayNonEmpty(maybeChildren.value.elements)) {
11314
+ return Effect_exports.void;
11315
+ }
11316
+ if (Array_exports.isReadonlyArrayNonEmpty(
11317
+ ctx.sourceCode.getCommentsInside(maybeChildren.value)
11318
+ )) {
11319
+ return Effect_exports.void;
11320
+ }
11321
+ return ctx.report(
11322
+ Diagnostic_exports.make({
11323
+ node: maybeChildren.value,
11324
+ message: emptyChildrenMessage(maybeTarget.value)
11325
+ })
11326
+ );
11327
+ }
11328
+ };
11329
+ }
11330
+ });
11331
+
11041
11332
  // src/rules/no-empty-object-tagged-call.ts
11042
11333
  var noEmptyObjectTaggedCall = Rule_exports.define({
11043
11334
  name: "no-empty-object-tagged-call",
@@ -11961,6 +12252,7 @@ var basePlugin = Plugin_exports.define({
11961
12252
  "no-child-message-construction-in-root": noChildMessageConstructionInRoot,
11962
12253
  "no-disabling-dev-guardrails": noDisablingDevGuardrails,
11963
12254
  "no-duplicate-onmount-per-element": noDuplicateOnmountPerElement,
12255
+ "no-empty-children-array": noEmptyChildrenArray,
11964
12256
  "no-empty-object-tagged-call": noEmptyObjectTaggedCall,
11965
12257
  "no-hand-rolled-command-struct": noHandRolledCommandStruct,
11966
12258
  "no-hardcoded-route-strings": noHardcodedRouteStrings,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/oxlint-plugin",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Oxlint rules for Foldkit applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/recommended.json CHANGED
@@ -19,6 +19,7 @@
19
19
  "foldkit/no-child-message-construction-in-root": "error",
20
20
  "foldkit/no-disabling-dev-guardrails": "error",
21
21
  "foldkit/no-duplicate-onmount-per-element": "error",
22
+ "foldkit/no-empty-children-array": "error",
22
23
  "foldkit/no-empty-object-tagged-call": "error",
23
24
  "foldkit/no-hand-rolled-command-struct": "error",
24
25
  "foldkit/no-hardcoded-route-strings": "error",
@@ -51,6 +52,7 @@
51
52
  "foldkit/no-child-message-construction-in-root": "off",
52
53
  "foldkit/no-disabling-dev-guardrails": "off",
53
54
  "foldkit/no-duplicate-onmount-per-element": "off",
55
+ "foldkit/no-empty-children-array": "off",
54
56
  "foldkit/no-empty-object-tagged-call": "off",
55
57
  "foldkit/no-hand-rolled-command-struct": "off",
56
58
  "foldkit/no-hardcoded-route-strings": "off",