@deslop/coding-standards 0.0.0-stage → 0.1.761

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/dist/oxlint.js ADDED
@@ -0,0 +1,3076 @@
1
+ import { $n as isReadonlyObject, An as symbol, B as some$1, Bn as hasProperty, C as flatMap$1, D as getSomes, E as get$1, F as map$1, Fn as optimize, Gn as isNotNull, H as take, Jn as isNullish, K as remove, Kn as isNotNullish, L as of, Ln as string, M as join, Mn as combine, N as last, Nn as hash, O as isArrayEmpty, On as byReferenceUnsafe, Pn as number, R as prepend, U as fromEntries, V as sort, Vn as isBoolean, W as get$2, Y as fromOption, Yn as isNumber, _ as every, _t as orElse, a as startsWith, at as firstSomeOf, b as findFirst, bn as NodeInspectSymbol, c as TaggedError, d as appendAll, er as isString, f as contains$1, ft as isSome, g as ensure, gr as pipeArguments, gt as none, h as empty, ht as match, i as Order, it as filter, k as isArrayNonEmpty, kn as equals, lr as dual, lt as getOrElse, m as dropRight, mt as map, n as make$2, nt as contains, ot as flatMap, p as dedupe, pr as pipe, q as values, r as update, rt as exists, st as fromNullishOr, t as get$3, tt as all, u as append, v as filter$1, vt as some, w as flatten, x as findFirstIndex, y as filterMap, yt as zipWith, zn as symbol$1 } from "./MutableRef-DT4DAKeI.mjs";
2
+ //#region ../../node_modules/.pnpm/effect@4.0.0/node_modules/effect/dist/internal/graph.js
3
+ /** @internal */
4
+ const TypeId = "~effect/Graph";
5
+ /** @internal */
6
+ const toImpl = (graph) => graph;
7
+ /** @internal */
8
+ const isTransforming = (graph) => toImpl(graph).transforming;
9
+ const edgeEquals = (type, self, that) => (type === "directed" ? self.source === that.source && self.target === that.target : self.source === that.source && self.target === that.target || self.source === that.target && self.target === that.source) && equals(self.data, that.data);
10
+ const edgeHash = (type, edge) => type === "directed" ? hash(edge) : optimize(combine(hash(edge.data), endpointsHash(edge.source, edge.target)));
11
+ /**
12
+ * Addition is commutative and does not cancel self-loops.
13
+ *
14
+ * @internal
15
+ */
16
+ const endpointsHash = (source, target) => combine(0, hash(source)) + combine(0, hash(target));
17
+ const graphSeed = /*#__PURE__*/ string("Graph");
18
+ const ProtoGraph = {
19
+ [TypeId]: {
20
+ _N: (_) => _,
21
+ _E: (_) => _
22
+ },
23
+ [Symbol.iterator]() {
24
+ return this.nodes[Symbol.iterator]();
25
+ },
26
+ [NodeInspectSymbol]() {
27
+ return this.toJSON();
28
+ },
29
+ [symbol](that) {
30
+ if (hasProperty(that, "~effect/Graph")) {
31
+ const thatImpl = toImpl(that);
32
+ if (this.nodes.size !== thatImpl.nodes.size || this.edges.size !== thatImpl.edges.size || this.type !== thatImpl.type) return false;
33
+ for (const [nodeIndex, nodeData] of this.nodes) if (!thatImpl.nodes.has(nodeIndex) || !equals(nodeData, thatImpl.nodes.get(nodeIndex))) return false;
34
+ for (const [edgeIndex, edgeData] of this.edges) {
35
+ const otherEdge = thatImpl.edges.get(edgeIndex);
36
+ if (otherEdge === void 0 || !edgeEquals(this.type, edgeData, otherEdge)) return false;
37
+ }
38
+ return true;
39
+ }
40
+ return false;
41
+ },
42
+ [symbol$1]() {
43
+ let hash$2 = graphSeed;
44
+ hash$2 = hash$2 ^ string(this.type);
45
+ hash$2 = hash$2 ^ number(this.nodes.size);
46
+ hash$2 = hash$2 ^ number(this.edges.size);
47
+ for (const [nodeIndex, nodeData] of this.nodes) hash$2 ^= combine(hash(nodeIndex), hash(nodeData));
48
+ for (const [edgeIndex, edgeData] of this.edges) hash$2 ^= combine(hash(edgeIndex), edgeHash(this.type, edgeData));
49
+ return optimize(hash$2);
50
+ },
51
+ toJSON() {
52
+ return {
53
+ _id: "Graph",
54
+ nodeCount: this.nodes.size,
55
+ edgeCount: this.edges.size,
56
+ type: this.type
57
+ };
58
+ },
59
+ toString() {
60
+ return `Graph(${this.type}, ${this.nodes.size}, ${this.edges.size})`;
61
+ },
62
+ pipe() {
63
+ return pipeArguments(this, arguments);
64
+ }
65
+ };
66
+ /** @internal */
67
+ const make$1 = (type, mutable) => {
68
+ const graph = Object.create(ProtoGraph);
69
+ graph.type = type;
70
+ graph.mutable = mutable;
71
+ graph.transforming = false;
72
+ graph.nodes = /* @__PURE__ */ new Map();
73
+ graph.edges = /* @__PURE__ */ new Map();
74
+ graph.adjacency = /* @__PURE__ */ new Map();
75
+ graph.reverseAdjacency = /* @__PURE__ */ new Map();
76
+ graph.nextNodeIndex = 0;
77
+ graph.nextEdgeIndex = 0;
78
+ graph.acyclic = some(true);
79
+ return graph;
80
+ };
81
+ /** @internal */
82
+ const finalize = (source) => {
83
+ const graph = Object.create(ProtoGraph);
84
+ graph.type = source.type;
85
+ graph.mutable = false;
86
+ graph.transforming = false;
87
+ graph.nodes = source.nodes;
88
+ graph.edges = source.edges;
89
+ graph.adjacency = source.adjacency;
90
+ graph.reverseAdjacency = source.reverseAdjacency;
91
+ graph.nextNodeIndex = source.nextNodeIndex;
92
+ graph.nextEdgeIndex = source.nextEdgeIndex;
93
+ graph.acyclic = source.acyclic;
94
+ return graph;
95
+ };
96
+ //#endregion
97
+ //#region ../../node_modules/.pnpm/effect@4.0.0/node_modules/effect/dist/internal/graphCsr.js
98
+ const cache = /*#__PURE__*/ new WeakMap();
99
+ const makeAdjacency = (csr, incoming) => {
100
+ const impl = toImpl(csr.graph);
101
+ const adjacencyMap = incoming ? impl.reverseAdjacency : impl.adjacency;
102
+ const rowOffsets = new Uint32Array(csr.nodeIds.length + 1);
103
+ for (let i = 0; i < csr.nodeIds.length; i++) rowOffsets[i + 1] = rowOffsets[i] + (adjacencyMap.get(csr.nodeIds[i])?.length ?? 0);
104
+ const columnIndices = new Uint32Array(rowOffsets[csr.nodeIds.length]);
105
+ for (let i = 0; i < csr.nodeIds.length; i++) {
106
+ const nodeId = csr.nodeIds[i];
107
+ const adjacency = adjacencyMap.get(nodeId);
108
+ if (adjacency === void 0) continue;
109
+ let offset = rowOffsets[i];
110
+ for (let j = 0; j < adjacency.length; j++) {
111
+ const edge = impl.edges.get(adjacency[j]);
112
+ const neighbor = csr.type === "undirected" ? edge.source === nodeId ? edge.target : edge.source : incoming ? edge.source : edge.target;
113
+ columnIndices[offset++] = csr.indexByNodeId === void 0 ? neighbor : csr.indexByNodeId.get(neighbor);
114
+ }
115
+ }
116
+ return {
117
+ rowOffsets,
118
+ columnIndices
119
+ };
120
+ };
121
+ /** @internal */
122
+ const getOutgoing = (csr) => {
123
+ return csr.outgoingCsr ?? (csr.outgoingCsr = makeAdjacency(csr, false));
124
+ };
125
+ /** @internal */
126
+ const getIncoming = (csr) => {
127
+ return csr.incomingCsr ?? (csr.incomingCsr = makeAdjacency(csr, true));
128
+ };
129
+ /** @internal */
130
+ const invalidate = (graph) => {
131
+ cache.delete(graph);
132
+ };
133
+ /** @internal */
134
+ const get = (graph) => {
135
+ const cacheEnabled = !isTransforming(graph);
136
+ if (cacheEnabled) {
137
+ const cached = cache.get(graph);
138
+ if (cached !== void 0) return cached;
139
+ }
140
+ const impl = toImpl(graph);
141
+ const nodeIds = new Array(impl.nodes.size);
142
+ const nodeData = new Array(impl.nodes.size);
143
+ let compactNodeIds = true;
144
+ let nodePosition = 0;
145
+ for (const [nodeId, data] of impl.nodes) {
146
+ nodeIds[nodePosition] = nodeId;
147
+ nodeData[nodePosition] = data;
148
+ if (nodeId !== nodePosition) compactNodeIds = false;
149
+ nodePosition++;
150
+ }
151
+ const indexByNodeId = compactNodeIds ? void 0 : /* @__PURE__ */ new Map();
152
+ if (indexByNodeId !== void 0) for (let i = 0; i < nodeIds.length; i++) indexByNodeId.set(nodeIds[i], i);
153
+ const result = {
154
+ type: impl.type,
155
+ graph,
156
+ nodeIds,
157
+ nodeData,
158
+ indexByNodeId,
159
+ outgoingCsr: void 0,
160
+ incomingCsr: void 0,
161
+ outgoingEdgeCsr: void 0,
162
+ edgesByIndex: void 0,
163
+ edgeIdsByIndex: void 0,
164
+ compactEdgeEndpoints: void 0,
165
+ indexByEdgeId: void 0
166
+ };
167
+ if (cacheEnabled) cache.set(graph, result);
168
+ return result;
169
+ };
170
+ //#endregion
171
+ //#region ../../node_modules/.pnpm/effect@4.0.0/node_modules/effect/dist/Graph.js
172
+ /**
173
+ * Models relationships between indexed nodes and edges.
174
+ *
175
+ * This module provides immutable and scoped-mutable graph data structures. A
176
+ * graph can be directed or undirected, and it can store user-defined data on
177
+ * both nodes and edges. The module includes traversal, analysis, path-finding,
178
+ * transformation, and diagram export utilities.
179
+ *
180
+ * @since 4.0.0
181
+ */
182
+ /**
183
+ * Error thrown by graph operations when the requested graph structure is
184
+ * invalid, such as referencing a missing node or using unsupported edge
185
+ * weights.
186
+ *
187
+ * **When to use**
188
+ *
189
+ * Use when handling failures thrown by graph operations that reject invalid
190
+ * graph structure or unsupported algorithm inputs.
191
+ *
192
+ * @category errors
193
+ * @since 3.18.0
194
+ */
195
+ var GraphError = class extends (/*#__PURE__*/ TaggedError("GraphError")) {};
196
+ /** @internal */
197
+ const missingNode = (node) => new GraphError({ message: `Node ${node} does not exist` });
198
+ /** @internal */
199
+ function assertMutable(graph) {
200
+ if (!graph.mutable) throw new GraphError({ message: "Graph is not mutable" });
201
+ }
202
+ /** @internal */
203
+ const getMutableImplForMutation = (graph) => {
204
+ assertMutable(graph);
205
+ if (isTransforming(graph)) throw new GraphError({ message: "Cannot mutate graph during a transformation" });
206
+ invalidate(graph);
207
+ return toImpl(graph);
208
+ };
209
+ /**
210
+ * Creates a graph constructor for the specified graph kind.
211
+ *
212
+ * **When to use**
213
+ *
214
+ * Use when the graph kind is selected dynamically. Prefer `directed` or
215
+ * `undirected` when the kind is known statically.
216
+ *
217
+ * **Example** (Constructing by kind)
218
+ *
219
+ * ```ts import.meta.vitest
220
+ * import { Graph } from "effect"
221
+ *
222
+ * const makeGraph = Graph.make("directed")
223
+ * const graph = makeGraph<string, number>((mutable) => {
224
+ * Graph.addNode(mutable, "A")
225
+ * })
226
+ *
227
+ * graph.type // => "directed"
228
+ * ```
229
+ *
230
+ * @see {@link directed} for constructing a directed graph directly
231
+ * @see {@link undirected} for constructing an undirected graph directly
232
+ * @category constructors
233
+ * @since 4.0.0
234
+ */
235
+ const make = (type) => (mutate) => {
236
+ if (type !== "directed" && type !== "undirected") throw new GraphError({ message: "Graph type must be directed or undirected" });
237
+ if (mutate === void 0) return make$1(type, false);
238
+ const graph = make$1(type, true);
239
+ const mutable = byReferenceUnsafe(graph);
240
+ return mutateScoped(mutable, mutate);
241
+ };
242
+ /**
243
+ * Creates a directed graph, optionally with initial mutations.
244
+ *
245
+ * **When to use**
246
+ *
247
+ * Use when relationships have a source-to-target direction, such as
248
+ * dependencies, workflows, or routing links.
249
+ *
250
+ * **Gotchas**
251
+ *
252
+ * The mutable callback handle is finalized when the callback returns and must
253
+ * not be retained for later mutation.
254
+ *
255
+ * **Example** (Creating a directed graph)
256
+ *
257
+ * ```ts import.meta.vitest
258
+ * import { Graph } from "effect"
259
+ *
260
+ * // Directed graph with initial nodes and edges
261
+ * const graph = Graph.directed<string, string>((mutable) => {
262
+ * const a = Graph.addNode(mutable, "A")
263
+ * const b = Graph.addNode(mutable, "B")
264
+ * const c = Graph.addNode(mutable, "C")
265
+ * Graph.addEdge(mutable, a, b, "A->B")
266
+ * Graph.addEdge(mutable, b, c, "B->C")
267
+ * })
268
+ * Array.of(Graph.nodeCount(graph), Graph.edgeCount(graph)) // => [3, 2]
269
+ * ```
270
+ *
271
+ * @category constructors
272
+ * @since 3.18.0
273
+ */
274
+ const directed = /*#__PURE__*/ make("directed");
275
+ /**
276
+ * Converts a mutable graph back to an immutable graph, ending the mutation scope.
277
+ *
278
+ * **When to use**
279
+ *
280
+ * Use to finish a mutation scope opened with `beginMutation`.
281
+ *
282
+ * **Gotchas**
283
+ *
284
+ * Finalization is terminal. Later public mutation operations on the same
285
+ * mutable handle fail with a `GraphError`.
286
+ *
287
+ * **Example** (Ending a mutation scope)
288
+ *
289
+ * ```ts import.meta.vitest
290
+ * import { Graph } from "effect"
291
+ *
292
+ * const graph = Graph.directed<string, number>()
293
+ * const mutable = Graph.beginMutation(graph)
294
+ * // ... perform mutations on mutable ...
295
+ * Graph.nodeCount(Graph.endMutation(mutable)) // => 0
296
+ * ```
297
+ *
298
+ * @see {@link beginMutation} for opening a manual mutation scope
299
+ * @see {@link mutate} for automatically scoped mutation
300
+ * @category mutations
301
+ * @since 3.18.0
302
+ */
303
+ const endMutation = (mutable) => {
304
+ assertMutable(mutable);
305
+ if (isTransforming(mutable)) throw new GraphError({ message: "Cannot mutate graph during a transformation" });
306
+ const source = toImpl(mutable);
307
+ invalidate(mutable);
308
+ const graph = finalize(source);
309
+ source.mutable = false;
310
+ return graph;
311
+ };
312
+ /** @internal */
313
+ const mutateScoped = (mutable, f) => {
314
+ try {
315
+ f(mutable);
316
+ } catch (error) {
317
+ if (mutable.mutable) endMutation(mutable);
318
+ throw error;
319
+ }
320
+ return endMutation(mutable);
321
+ };
322
+ /**
323
+ * Adds a new node to a mutable graph and returns its index.
324
+ *
325
+ * **When to use**
326
+ *
327
+ * Use to allocate a new node in a mutable graph before storing edges or
328
+ * querying it by index.
329
+ *
330
+ * **Details**
331
+ *
332
+ * The returned index is allocated from the graph's next node index. The mutable
333
+ * graph stores the node data and initializes empty incoming and outgoing edge
334
+ * indexes for the new node.
335
+ *
336
+ * **Gotchas**
337
+ *
338
+ * `NodeIndex` values are identifiers and are not reused after removals.
339
+ *
340
+ * **Example** (Adding nodes)
341
+ *
342
+ * ```ts import.meta.vitest
343
+ * import { Graph } from "effect"
344
+ *
345
+ * Graph.mutate(Graph.directed<string, number>(), (mutable) => {
346
+ * Graph.addNode(mutable, "Node A") // => 0
347
+ * Graph.addNode(mutable, "Node B") // => 1
348
+ * })
349
+ * ```
350
+ *
351
+ * @see {@link mutate} for obtaining a mutable graph from an immutable graph
352
+ * @see {@link addEdge} for connecting existing nodes
353
+ *
354
+ * @category mutations
355
+ * @since 3.18.0
356
+ */
357
+ const addNode = (mutable, data) => {
358
+ const impl = getMutableImplForMutation(mutable);
359
+ const nodeIndex = impl.nextNodeIndex;
360
+ if (!Number.isSafeInteger(nodeIndex)) throw new GraphError({ message: "Graph has exhausted safe node indexes" });
361
+ impl.nodes.set(nodeIndex, data);
362
+ impl.adjacency.set(nodeIndex, []);
363
+ impl.reverseAdjacency.set(nodeIndex, []);
364
+ impl.nextNodeIndex = impl.nextNodeIndex + 1;
365
+ return nodeIndex;
366
+ };
367
+ /**
368
+ * Gets the data associated with a node index safely, if it exists.
369
+ *
370
+ * **Example** (Getting node data)
371
+ *
372
+ * ```ts import.meta.vitest
373
+ * import { Graph, Option } from "effect"
374
+ *
375
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
376
+ * Graph.addNode(mutable, "Node A")
377
+ * })
378
+ *
379
+ * Graph.getNode(graph, 0) // => Option.some("Node A")
380
+ * ```
381
+ *
382
+ * @category getters
383
+ * @since 3.18.0
384
+ */
385
+ const getNode = /*#__PURE__*/ dual(2, (graph, nodeIndex) => {
386
+ const impl = toImpl(graph);
387
+ return impl.nodes.has(nodeIndex) ? some(impl.nodes.get(nodeIndex)) : none();
388
+ });
389
+ /** @internal */
390
+ const invalidateCycleFlagOnAddition = (mutable) => {
391
+ if (isSome(mutable.acyclic) && mutable.acyclic.value === true) mutable.acyclic = none();
392
+ };
393
+ /**
394
+ * Adds a new edge to a mutable graph and returns its index.
395
+ *
396
+ * **When to use**
397
+ *
398
+ * Use to connect two existing nodes in a mutable graph while storing edge data
399
+ * and receiving the new edge identifier.
400
+ *
401
+ * **Details**
402
+ *
403
+ * Self-loops and parallel edges are allowed. Undirected graphs retain the
404
+ * supplied source and target orientation in the stored `Edge`, while traversal
405
+ * and neighbor queries treat the connection as bidirectional.
406
+ *
407
+ * **Gotchas**
408
+ *
409
+ * The source and target nodes must already exist in the mutable graph; missing
410
+ * endpoints throw a `GraphError`.
411
+ *
412
+ * **Example** (Adding edges)
413
+ *
414
+ * ```ts import.meta.vitest
415
+ * import { Graph } from "effect"
416
+ *
417
+ * Graph.mutate(Graph.directed<string, number>(), (mutable) => {
418
+ * const nodeA = Graph.addNode(mutable, "Node A")
419
+ * const nodeB = Graph.addNode(mutable, "Node B")
420
+ * Graph.addEdge(mutable, nodeA, nodeB, 42) // => 0
421
+ * })
422
+ * ```
423
+ *
424
+ * @see {@link mutate} for obtaining a mutable graph from an immutable graph
425
+ * @see {@link addNode} for creating node indexes before connecting them
426
+ *
427
+ * @category mutations
428
+ * @since 3.18.0
429
+ */
430
+ const addEdge = (mutable, source, target, data) => {
431
+ const impl = getMutableImplForMutation(mutable);
432
+ if (!impl.nodes.has(source)) throw missingNode(source);
433
+ if (!impl.nodes.has(target)) throw missingNode(target);
434
+ const edgeIndex = impl.nextEdgeIndex;
435
+ if (!Number.isSafeInteger(edgeIndex)) throw new GraphError({ message: "Graph has exhausted safe edge indexes" });
436
+ const edgeData = {
437
+ source,
438
+ target,
439
+ data
440
+ };
441
+ impl.edges.set(edgeIndex, edgeData);
442
+ const sourceAdjacency = impl.adjacency.get(source);
443
+ if (sourceAdjacency !== void 0) sourceAdjacency.push(edgeIndex);
444
+ const targetReverseAdjacency = impl.reverseAdjacency.get(target);
445
+ if (targetReverseAdjacency !== void 0) targetReverseAdjacency.push(edgeIndex);
446
+ if (impl.type === "undirected") {
447
+ const targetAdjacency = impl.adjacency.get(target);
448
+ if (targetAdjacency !== void 0) targetAdjacency.push(edgeIndex);
449
+ const sourceReverseAdjacency = impl.reverseAdjacency.get(source);
450
+ if (sourceReverseAdjacency !== void 0) sourceReverseAdjacency.push(edgeIndex);
451
+ }
452
+ impl.nextEdgeIndex = impl.nextEdgeIndex + 1;
453
+ invalidateCycleFlagOnAddition(impl);
454
+ return edgeIndex;
455
+ };
456
+ /**
457
+ * Returns the strongly connected components of a directed graph.
458
+ *
459
+ * **When to use**
460
+ *
461
+ * Use when grouping nodes so every node in a component can reach every other
462
+ * node in that component.
463
+ *
464
+ * **Details**
465
+ *
466
+ * Each component is represented as an array of node indices and is computed
467
+ * with Kosaraju's algorithm.
468
+ *
469
+ * **Gotchas**
470
+ *
471
+ * Throws a `GraphError` when used with an undirected graph.
472
+ *
473
+ * **Example** (Finding strongly connected components)
474
+ *
475
+ * ```ts import.meta.vitest
476
+ * import { Graph } from "effect"
477
+ *
478
+ * const graph = Graph.directed<string, string>((mutable) => {
479
+ * const a = Graph.addNode(mutable, "A")
480
+ * const b = Graph.addNode(mutable, "B")
481
+ * const c = Graph.addNode(mutable, "C")
482
+ * Graph.addEdge(mutable, a, b, "A->B")
483
+ * Graph.addEdge(mutable, b, c, "B->C")
484
+ * Graph.addEdge(mutable, c, a, "C->A") // Creates SCC: A-B-C
485
+ * })
486
+ *
487
+ * Graph.stronglyConnectedComponents(graph) // => [[0, 2, 1]]
488
+ * ```
489
+ *
490
+ * @see {@link isStronglyConnected} when only a boolean check is needed
491
+ * @see {@link weaklyConnectedComponents} when edge orientation should be ignored
492
+ * @category algorithms
493
+ * @since 3.18.0
494
+ */
495
+ const stronglyConnectedComponents = (graph) => {
496
+ if (graph.type === "undirected") throw new GraphError({ message: "Cannot find strongly connected components of undirected graph" });
497
+ const cache = get(graph);
498
+ const outgoing = getOutgoing(cache);
499
+ const incoming = getIncoming(cache);
500
+ const visited = new Uint8Array(cache.nodeIds.length);
501
+ const finishOrder = [];
502
+ const stack = [];
503
+ const positions = [];
504
+ for (let start = 0; start < cache.nodeIds.length; start++) {
505
+ if (visited[start] !== 0) continue;
506
+ visited[start] = 1;
507
+ stack.push(start);
508
+ positions.push(outgoing.rowOffsets[start]);
509
+ while (stack.length > 0) {
510
+ const frame = stack.length - 1;
511
+ const node = stack[frame];
512
+ const position = positions[frame];
513
+ if (position < outgoing.rowOffsets[node + 1]) {
514
+ positions[frame] = position + 1;
515
+ const neighbor = outgoing.columnIndices[position];
516
+ if (visited[neighbor] === 0) {
517
+ visited[neighbor] = 1;
518
+ stack.push(neighbor);
519
+ positions.push(outgoing.rowOffsets[neighbor]);
520
+ }
521
+ } else {
522
+ finishOrder.push(node);
523
+ stack.pop();
524
+ positions.pop();
525
+ }
526
+ }
527
+ }
528
+ visited.fill(0);
529
+ const components = [];
530
+ for (let i = finishOrder.length - 1; i >= 0; i--) {
531
+ const start = finishOrder[i];
532
+ if (visited[start] !== 0) continue;
533
+ const component = [];
534
+ stack.push(start);
535
+ while (stack.length > 0) {
536
+ const node = stack.pop();
537
+ if (visited[node] !== 0) continue;
538
+ visited[node] = 1;
539
+ component.push(cache.nodeIds[node]);
540
+ for (let j = incoming.rowOffsets[node]; j < incoming.rowOffsets[node + 1]; j++) {
541
+ const predecessor = incoming.columnIndices[j];
542
+ if (visited[predecessor] === 0) stack.push(predecessor);
543
+ }
544
+ }
545
+ components.push(component);
546
+ }
547
+ return components;
548
+ };
549
+ //#endregion
550
+ //#region ../../node_modules/.pnpm/@oxlint+plugins@1.85.0/node_modules/@oxlint/plugins/index.js
551
+ /**
552
+ * Define a plugin.
553
+ *
554
+ * No-op function, just to provide type safety. Input is passed through unchanged.
555
+ *
556
+ * @param plugin - Plugin to define
557
+ * @returns Same plugin as passed in
558
+ */
559
+ function definePlugin(plugin) {
560
+ return plugin;
561
+ }
562
+ /**
563
+ * Define a rule.
564
+ *
565
+ * No-op function, just to provide type safety. Input is passed through unchanged.
566
+ *
567
+ * @param rule - Rule to define
568
+ * @returns Same rule as passed in
569
+ */
570
+ function defineRule(rule) {
571
+ return rule;
572
+ }
573
+ Object.freeze({
574
+ get filename() {
575
+ throw Error("Cannot access `context.filename` in `createOnce`");
576
+ },
577
+ getFilename() {
578
+ throw Error("Cannot call `context.getFilename` in `createOnce`");
579
+ },
580
+ get physicalFilename() {
581
+ throw Error("Cannot access `context.physicalFilename` in `createOnce`");
582
+ },
583
+ getPhysicalFilename() {
584
+ throw Error("Cannot call `context.getPhysicalFilename` in `createOnce`");
585
+ },
586
+ get cwd() {
587
+ throw Error("Cannot access `context.cwd` in `createOnce`");
588
+ },
589
+ getCwd() {
590
+ throw Error("Cannot call `context.getCwd` in `createOnce`");
591
+ },
592
+ get sourceCode() {
593
+ throw Error("Cannot access `context.sourceCode` in `createOnce`");
594
+ },
595
+ getSourceCode() {
596
+ throw Error("Cannot call `context.getSourceCode` in `createOnce`");
597
+ },
598
+ get languageOptions() {
599
+ throw Error("Cannot access `context.languageOptions` in `createOnce`");
600
+ },
601
+ get settings() {
602
+ throw Error("Cannot access `context.settings` in `createOnce`");
603
+ },
604
+ extend(extension) {
605
+ return Object.freeze(Object.assign(Object.create(this), extension));
606
+ },
607
+ get parserOptions() {
608
+ throw Error("Cannot access `context.parserOptions` in `createOnce`");
609
+ },
610
+ get parserPath() {
611
+ throw Error("Cannot access `context.parserPath` in `createOnce`");
612
+ }
613
+ });
614
+ //#endregion
615
+ //#region ../../node_modules/.pnpm/oxlint@1.85.0_oxlint-tsgolint@7.0.2003_vite-plus@1.0.0_@opentelemetry+api@1.9.1_@types+_4709a04ba252a52ff927b8b254462122/node_modules/oxlint/dist/index.js
616
+ /**
617
+ * Define an Oxlint configuration with type inference.
618
+ *
619
+ * @param config - Oxlint configuration
620
+ * @returns Config unchanged
621
+ */
622
+ function defineConfig(config) {
623
+ return config;
624
+ }
625
+ //#endregion
626
+ //#region src/rules/shared.ts
627
+ function variableFromScope(input) {
628
+ if (input.scope === null) return none();
629
+ const scope = input.scope;
630
+ return pipe(fromNullishOr(scope.set.get(input.name)), orElse(() => variableFromScope({
631
+ name: input.name,
632
+ scope: scope.upper
633
+ })));
634
+ }
635
+ function variableFor(context, node) {
636
+ return variableFromScope({
637
+ name: node.name,
638
+ scope: context.sourceCode.getScope(node)
639
+ });
640
+ }
641
+ function isImportBinding(input) {
642
+ return pipe(variableFor(input.context, input.node), exists((variable) => some$1(variable.defs, (definition) => {
643
+ if (definition.type !== "ImportBinding" || definition.parent?.type !== "ImportDeclaration") return false;
644
+ const source = definition.parent.source.value;
645
+ if (isString(input.source) ? source !== input.source : !input.source.test(source)) return false;
646
+ return input.importedName === void 0 || definition.node.type === "ImportSpecifier" && definition.node.imported.type === "Identifier" && definition.node.imported.name === input.importedName;
647
+ })));
648
+ }
649
+ function isNamespaceImport(input) {
650
+ return pipe(variableFor(input.context, input.node), exists((variable) => some$1(variable.defs, (definition) => definition.type === "ImportBinding" && definition.node.type === "ImportNamespaceSpecifier" && definition.parent?.type === "ImportDeclaration" && definition.parent.source.value === input.source)));
651
+ }
652
+ function returnedExpression(node) {
653
+ if (node.body === null) return;
654
+ if (node.body.type !== "BlockStatement") return node.body;
655
+ if (node.body.body.length !== 1 || node.body.body[0]?.type !== "ReturnStatement") return;
656
+ return node.body.body[0].argument;
657
+ }
658
+ function memberName(node) {
659
+ if (!node.computed && node.property.type === "Identifier") return some(node.property.name);
660
+ if (node.computed && node.property.type === "Literal" && isString(node.property.value)) return some(node.property.value);
661
+ return none();
662
+ }
663
+ function importedMember(input) {
664
+ return input.node.type === "MemberExpression" && input.node.object.type === "Identifier" && isImportBinding({
665
+ context: input.context,
666
+ importedName: input.importedName,
667
+ node: input.node.object,
668
+ source: "effect"
669
+ }) && (input.propertyName === void 0 || contains(memberName(input.node), input.propertyName));
670
+ }
671
+ function effectBuilderName(input) {
672
+ const builder = input.node.type === "CallExpression" ? input.node.callee : input.node;
673
+ return builder.type === "MemberExpression" && importedMember({
674
+ context: input.context,
675
+ importedName: "Effect",
676
+ node: builder
677
+ }) ? memberName(builder) : none();
678
+ }
679
+ function isSchemaOperationName(name) {
680
+ return /^(?:(?:decode|encode)(?:Unknown)?(?:Effect|Exit|Option|Promise|Result|Sync)|asserts|is)$/u.test(name);
681
+ }
682
+ function isSchemaOperationCall(input) {
683
+ if (input.node.callee.type !== "MemberExpression" || !importedMember({
684
+ context: input.context,
685
+ importedName: "Schema",
686
+ node: input.node.callee
687
+ })) return false;
688
+ return pipe(memberName(input.node.callee), exists(isSchemaOperationName));
689
+ }
690
+ function isReactUseState(input) {
691
+ if (input.node.callee.type === "Identifier") return isImportBinding({
692
+ context: input.context,
693
+ importedName: "useState",
694
+ node: input.node.callee,
695
+ source: "react"
696
+ });
697
+ return input.node.callee.type === "MemberExpression" && contains(memberName(input.node.callee), "useState") && input.node.callee.object.type === "Identifier" && isNamespaceImport({
698
+ context: input.context,
699
+ node: input.node.callee.object,
700
+ source: "react"
701
+ });
702
+ }
703
+ function statementDeclaration(statement) {
704
+ return statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
705
+ }
706
+ function typeAlias(statement) {
707
+ const declaration = statementDeclaration(statement);
708
+ return declaration?.type === "TSTypeAliasDeclaration" ? some(declaration) : none();
709
+ }
710
+ function isInferredType(input) {
711
+ return input.node.type === "TSTypeQuery" && input.node.exprName.type === "TSQualifiedName" && input.node.exprName.left.type === "Identifier" && input.node.exprName.left.name === input.name && input.node.exprName.right.name === "Type";
712
+ }
713
+ function schemaQualifiedType(input) {
714
+ return input.node.type === "TSTypeReference" && input.node.typeName.type === "TSQualifiedName" && input.node.typeName.left.type === "Identifier" && input.node.typeName.left.name === "Schema" && input.node.typeName.right.name === input.propertyName && isImportBinding({
715
+ context: input.context,
716
+ importedName: "Schema",
717
+ node: input.node.typeName.left,
718
+ source: "effect"
719
+ });
720
+ }
721
+ function schemaSchemaType(input) {
722
+ return schemaQualifiedType({
723
+ context: input.context,
724
+ node: input.node,
725
+ propertyName: "Schema"
726
+ });
727
+ }
728
+ function isSchemaCodecType(input) {
729
+ return schemaQualifiedType({
730
+ context: input.context,
731
+ node: input.node,
732
+ propertyName: "Codec"
733
+ }) || schemaSchemaType(input);
734
+ }
735
+ function typeArgumentName(node) {
736
+ if (node.type !== "TSTypeReference" || node.typeArguments === null) return none();
737
+ return pipe(get$1(node.typeArguments.params, 0), flatMap((parameter) => parameter.type === "TSTypeReference" && parameter.typeName.type === "Identifier" ? some(parameter.typeName.name) : none()));
738
+ }
739
+ function suspendedTypeName(input) {
740
+ if (input.node.callee.type === "Super" || !importedMember({
741
+ context: input.context,
742
+ importedName: "Schema",
743
+ node: input.node.callee,
744
+ propertyName: "suspend"
745
+ })) return none();
746
+ return pipe(get$1(input.node.arguments, 0), flatMap((argument) => argument.type === "ArrowFunctionExpression" || argument.type === "FunctionExpression" ? fromNullishOr(argument.returnType) : none()), filter((returnType) => isSchemaCodecType({
747
+ context: input.context,
748
+ node: returnType.typeAnnotation
749
+ })), flatMap((returnType) => typeArgumentName(returnType.typeAnnotation)));
750
+ }
751
+ function referencedTypeNames(node) {
752
+ if (node.type === "TSTypeReference") {
753
+ const argumentNames = pipe(fromNullishOr(node.typeArguments), map((typeArguments) => pipe(typeArguments.params, flatMap$1(referencedTypeNames))), getOrElse(() => empty()));
754
+ return node.typeName.type === "Identifier" ? prepend(argumentNames, node.typeName.name) : argumentNames;
755
+ }
756
+ if (node.type === "TSArrayType") return referencedTypeNames(node.elementType);
757
+ if (node.type === "TSUnionType" || node.type === "TSIntersectionType") return pipe(node.types, flatMap$1(referencedTypeNames));
758
+ if (node.type === "TSTemplateLiteralType") return pipe(node.types, flatMap$1(referencedTypeNames));
759
+ if (node.type === "TSTypeOperator" || node.type === "TSParenthesizedType" || node.type === "TSOptionalType" || node.type === "TSRestType") return referencedTypeNames(node.typeAnnotation);
760
+ if (node.type === "TSNamedTupleMember") return referencedTypeNames(node.elementType);
761
+ if (node.type === "TSTupleType") return pipe(node.elementTypes, flatMap$1(referencedTypeNames));
762
+ if (node.type === "TSIndexedAccessType") return appendAll(referencedTypeNames(node.objectType), referencedTypeNames(node.indexType));
763
+ if (node.type === "TSConditionalType") return pipe([
764
+ node.checkType,
765
+ node.extendsType,
766
+ node.trueType,
767
+ node.falseType
768
+ ], flatMap$1(referencedTypeNames));
769
+ if (node.type === "TSFunctionType" || node.type === "TSConstructorType") return referencedTypeNames(node.returnType.typeAnnotation);
770
+ if (node.type === "TSMappedType") return pipe([
771
+ node.constraint,
772
+ node.nameType,
773
+ node.typeAnnotation
774
+ ], map$1((child) => fromNullishOr(child)), getSomes, flatMap$1(referencedTypeNames));
775
+ if (node.type === "TSTypeLiteral") return pipe(node.members, flatMap$1(memberTypeNames));
776
+ return empty();
777
+ }
778
+ function memberTypeNames(member) {
779
+ if (member.type === "TSIndexSignature") return referencedTypeNames(member.typeAnnotation.typeAnnotation);
780
+ return pipe(fromNullishOr(member.type === "TSPropertySignature" ? member.typeAnnotation : member.returnType), map((annotation) => referencedTypeNames(annotation.typeAnnotation)), getOrElse(() => empty()));
781
+ }
782
+ function isNode(value) {
783
+ return hasProperty(value, "type") && isString(value.type);
784
+ }
785
+ function childNodes(node) {
786
+ if (!isReadonlyObject(node)) return empty();
787
+ return pipe(values(remove(node, "parent")), flatMap$1(ensure), filter$1(isNode));
788
+ }
789
+ function suspendSeeds(input) {
790
+ const seeds = pipe(childNodes(input.node), flatMap$1((child) => suspendSeeds({
791
+ context: input.context,
792
+ node: child
793
+ })));
794
+ if (input.node.type !== "CallExpression") return seeds;
795
+ return pipe(suspendedTypeName({
796
+ context: input.context,
797
+ node: input.node
798
+ }), match({
799
+ onNone: () => seeds,
800
+ onSome: (name) => prepend(seeds, name)
801
+ }));
802
+ }
803
+ function referenceNames(node) {
804
+ const nested = pipe(childNodes(node), filter$1((child) => !(node.type === "Property" && !node.computed && child === node.key) && !(node.type === "MemberExpression" && !node.computed && child === node.property)), flatMap$1(referenceNames));
805
+ return node.type === "Identifier" ? prepend(nested, node.name) : nested;
806
+ }
807
+ function schemaEdges(statement) {
808
+ const declaration = statementDeclaration(statement);
809
+ if (declaration?.type === "TSTypeAliasDeclaration") return isInferredType({
810
+ name: declaration.id.name,
811
+ node: declaration.typeAnnotation
812
+ }) ? empty() : [{
813
+ name: declaration.id.name,
814
+ targets: referencedTypeNames(declaration.typeAnnotation)
815
+ }];
816
+ if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") return empty();
817
+ return flatMap$1(declaration.declarations, (declarator) => {
818
+ if (declarator.id.type !== "Identifier" || declarator.init === null) return empty();
819
+ return [{
820
+ name: declarator.id.name,
821
+ targets: referenceNames(declarator.init)
822
+ }];
823
+ });
824
+ }
825
+ function schemaCycleNames(input) {
826
+ const seeds = suspendSeeds({
827
+ context: input.context,
828
+ node: input.program
829
+ });
830
+ if (isArrayEmpty(seeds)) return empty();
831
+ const edges = pipe(input.program.body, flatMap$1(schemaEdges));
832
+ const names = pipe(edges, map$1((edge) => edge.name), dedupe);
833
+ const graph = directed((mutable) => {
834
+ const indices = fromEntries(map$1(names, (name) => [name, addNode(mutable, name)]));
835
+ for (const edge of edges) for (const target of edge.targets) zipWith(get$2(indices, edge.name), get$2(indices, target), (source, sink) => addEdge(mutable, source, sink, "reads"));
836
+ });
837
+ return pipe(stronglyConnectedComponents(graph), map$1((component) => getSomes(map$1(component, (index) => getNode(graph, index)))), filter$1((component) => (component.length > 1 || some$1(edges, (edge) => contains$1(component, edge.name) && contains$1(edge.targets, edge.name))) && some$1(component, (name) => contains$1(seeds, name))), flatten);
838
+ }
839
+ function hasSingleStatementExpression(node) {
840
+ if (node.body === null) return false;
841
+ if (node.body.type !== "BlockStatement") return true;
842
+ if (node.body.body.length !== 1) return false;
843
+ const statement = node.body.body[0];
844
+ return statement?.type === "ExpressionStatement" || statement?.type === "ReturnStatement" && statement.argument !== null;
845
+ }
846
+ function bindingName(node) {
847
+ if (node.type === "FunctionDeclaration") return fromNullishOr(node.id?.name);
848
+ if (node.parent.type === "VariableDeclarator" && node.parent.id.type === "Identifier") return some(node.parent.id.name);
849
+ return none();
850
+ }
851
+ function singleUseThunk(input) {
852
+ if (input.node.params.length !== 0 || input.node.typeParameters !== null || !hasSingleStatementExpression(input.node)) return false;
853
+ return pipe(bindingName(input.node), flatMap((name) => variableFromScope({
854
+ name,
855
+ scope: input.context.sourceCode.getScope(input.node)
856
+ })), exists((variable) => filter$1(variable.references, (reference) => reference.isRead()).length === 1));
857
+ }
858
+ //#endregion
859
+ //#region src/rules/no-array-wrap-ternary.ts
860
+ function testedValue(node) {
861
+ if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier" || node.callee.object.name !== "Array" || !contains(memberName(node.callee), "isArray") || node.arguments.length !== 1) return none();
862
+ const argument = node.arguments[0];
863
+ if (argument?.type !== "Identifier" && argument?.type !== "MemberExpression") return none();
864
+ return some(argument);
865
+ }
866
+ function isSingletonArray(input) {
867
+ if (input.node.type !== "ArrayExpression" || input.node.elements.length !== 1) return false;
868
+ const element = input.node.elements[0];
869
+ if (isNullish(element) || element.type === "SpreadElement") return false;
870
+ return input.context.sourceCode.getText(element) === input.context.sourceCode.getText(input.value);
871
+ }
872
+ function restatesArrayEnsure(input) {
873
+ const test = input.node.test.type === "UnaryExpression" && input.node.test.operator === "!" ? input.node.test.argument : input.node.test;
874
+ const negated = test !== input.node.test;
875
+ return exists(testedValue(test), (value) => input.context.sourceCode.getText(negated ? input.node.alternate : input.node.consequent) === input.context.sourceCode.getText(value) && isSingletonArray({
876
+ context: input.context,
877
+ node: negated ? input.node.consequent : input.node.alternate,
878
+ value
879
+ }));
880
+ }
881
+ const noArrayWrapTernary = defineRule({
882
+ create: (context) => ({ ConditionalExpression: (node) => {
883
+ if (restatesArrayEnsure({
884
+ context,
885
+ node
886
+ })) context.report({
887
+ message: "Use Array.ensure; the ternary restates it.",
888
+ node
889
+ });
890
+ } }),
891
+ meta: { type: "problem" }
892
+ });
893
+ //#endregion
894
+ //#region src/rules/no-constant-function.ts
895
+ function returnsConstant(node) {
896
+ const returned = returnedExpression(node);
897
+ return isNotNullish(returned) && (returned.type === "Literal" || returned.type === "Identifier" || returned.type === "MemberExpression" || returned.type === "TemplateLiteral" && isArrayEmpty(returned.expressions));
898
+ }
899
+ function functionScope(input) {
900
+ if (input.scope.block === input.node) return some(input.scope);
901
+ return findFirst(input.scope.childScopes, (child) => child.block === input.node);
902
+ }
903
+ function scopeReferences(scope) {
904
+ return appendAll(scope.references, flatMap$1(scope.childScopes, scopeReferences));
905
+ }
906
+ function isImportedVariable(variable) {
907
+ return isArrayNonEmpty(variable.defs) && every(variable.defs, (definition) => definition.type === "ImportBinding");
908
+ }
909
+ function resolvesToImport(reference) {
910
+ return pipe(variableFromScope({
911
+ name: reference.identifier.name,
912
+ scope: reference.from
913
+ }), exists(isImportedVariable));
914
+ }
915
+ function isConstantFunction(input) {
916
+ if (input.node.async || input.node.generator || isNotNullish(input.node.typeParameters)) return false;
917
+ if (some$1(input.spans, (span) => span.start >= input.node.start && span.end <= input.node.end)) return false;
918
+ return returnsConstant(input.node) && pipe(functionScope({
919
+ node: input.node,
920
+ scope: input.context.sourceCode.getScope(input.node)
921
+ }), exists((scope) => every(scopeReferences(scope), resolvesToImport))) && pipe(bindingName(input.node), flatMap((name) => variableFromScope({
922
+ name,
923
+ scope: input.context.sourceCode.getScope(input.node)
924
+ })), exists((variable) => every(filter$1(variable.references, (reference) => reference.isRead()), (reference) => reference.identifier.parent.type === "CallExpression" && reference.identifier.parent.callee === reference.identifier)));
925
+ }
926
+ function isConstBound(node) {
927
+ return node.parent.type === "VariableDeclarator" && node.parent.parent.type === "VariableDeclaration" && node.parent.parent.kind === "const";
928
+ }
929
+ const noConstantFunction = defineRule({
930
+ create: (context) => {
931
+ const spans = make$2(empty());
932
+ function mark(node) {
933
+ update(spans, append(node));
934
+ }
935
+ function report(node) {
936
+ if (isConstantFunction({
937
+ context,
938
+ node,
939
+ spans: get$3(spans)
940
+ }) && !singleUseThunk({
941
+ context,
942
+ node
943
+ })) context.report({
944
+ message: "This function reads nothing but imports, so it is a value: hold its result in a const.",
945
+ node
946
+ });
947
+ }
948
+ return {
949
+ "ArrowFunctionExpression:exit": (node) => {
950
+ if (isConstBound(node)) report(node);
951
+ },
952
+ "FunctionDeclaration:exit": report,
953
+ "FunctionExpression:exit": (node) => {
954
+ if (isConstBound(node)) report(node);
955
+ },
956
+ JSXElement: mark,
957
+ JSXFragment: mark,
958
+ ThisExpression: mark
959
+ };
960
+ },
961
+ meta: { type: "problem" }
962
+ });
963
+ //#endregion
964
+ //#region src/rules/no-deep-pipe.ts
965
+ function isPipeCall(node) {
966
+ return node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "pipe";
967
+ }
968
+ function enclosingPipes(node) {
969
+ if (node.type === "Program" || contains$1([
970
+ "ArrowFunctionExpression",
971
+ "FunctionDeclaration",
972
+ "FunctionExpression"
973
+ ], node.type)) return 0;
974
+ const nested = isPipeCall(node.parent) && some$1(node.parent.arguments, (argument) => argument === node);
975
+ return enclosingPipes(node.parent) + (nested ? 1 : 0);
976
+ }
977
+ const noDeepPipe = defineRule({
978
+ create: (context) => ({ CallExpression: (node) => {
979
+ if (isPipeCall(node) && enclosingPipes(node) >= 3) context.report({
980
+ message: "Flatten this pipeline; pipe calls nest at most three deep.",
981
+ node
982
+ });
983
+ } }),
984
+ meta: { type: "problem" }
985
+ });
986
+ //#endregion
987
+ //#region src/rules/no-destructured-parameter.ts
988
+ function isPattern(node) {
989
+ const target = node.type === "AssignmentPattern" ? node.left : node;
990
+ if (target.type === "ArrayPattern") return true;
991
+ if (target.type !== "ObjectPattern") return false;
992
+ const named = filter$1(target.properties, (property) => property.type === "Property");
993
+ return !(named.length === 1 && named[0]?.key.type === "Identifier" && named[0].key.name === "ref" && some$1(target.properties, (property) => property.type === "RestElement"));
994
+ }
995
+ const noDestructuredParameter = defineRule({
996
+ create: (context) => {
997
+ function reportParameters(node) {
998
+ for (const parameter of filter$1(node.params, isPattern)) context.report({
999
+ message: "Take the value whole and read its fields instead of destructuring it.",
1000
+ node: parameter
1001
+ });
1002
+ }
1003
+ function reportLoopVariable(node) {
1004
+ if (node.left.type === "VariableDeclaration" && some$1(node.left.declarations, (declarator) => isPattern(declarator.id))) context.report({
1005
+ message: "Take the value whole and read its fields instead of destructuring it.",
1006
+ node: node.left
1007
+ });
1008
+ }
1009
+ return {
1010
+ ArrowFunctionExpression: reportParameters,
1011
+ ForInStatement: reportLoopVariable,
1012
+ ForOfStatement: reportLoopVariable,
1013
+ FunctionDeclaration: reportParameters,
1014
+ FunctionExpression: reportParameters
1015
+ };
1016
+ },
1017
+ meta: { type: "problem" }
1018
+ });
1019
+ //#endregion
1020
+ //#region src/rules/no-double-nullish-check.ts
1021
+ function nullishOperand(node) {
1022
+ if (node.type === "Literal" && node.value === null) return some("null");
1023
+ return node.type === "Identifier" && node.name === "undefined" ? some("undefined") : none();
1024
+ }
1025
+ function operands(input) {
1026
+ if (input.node.type !== "LogicalExpression" || input.node.operator !== input.operator) return [input.node];
1027
+ return appendAll(operands({
1028
+ node: input.node.left,
1029
+ operator: input.operator
1030
+ }), operands({
1031
+ node: input.node.right,
1032
+ operator: input.operator
1033
+ }));
1034
+ }
1035
+ function comparedNullish(input) {
1036
+ if (input.node.type !== "BinaryExpression" || input.node.operator !== input.operator) return none();
1037
+ const subject = input.context.sourceCode.getText(input.node.left);
1038
+ return map(nullishOperand(input.node.right), (nullish) => ({
1039
+ nullish,
1040
+ subject
1041
+ }));
1042
+ }
1043
+ const noDoubleNullishCheck = defineRule({
1044
+ create: (context) => ({ LogicalExpression: (node) => {
1045
+ if (node.operator === "??") return;
1046
+ if (node.parent.type === "LogicalExpression" && node.parent.operator === node.operator) return;
1047
+ const comparison = node.operator === "&&" ? "!==" : "===";
1048
+ const checks = pipe(operands({
1049
+ node,
1050
+ operator: node.operator
1051
+ }), filterMap((operand) => fromOption(comparedNullish({
1052
+ context,
1053
+ node: operand,
1054
+ operator: comparison
1055
+ }), () => void 0)));
1056
+ if (some$1(checks, (check) => some$1(checks, (other) => other.subject === check.subject && other.nullish !== check.nullish))) context.report({
1057
+ message: comparison === "!==" ? "Use Predicate.isNotNullish." : "Use Predicate.isNullish.",
1058
+ node
1059
+ });
1060
+ } }),
1061
+ meta: { type: "problem" }
1062
+ });
1063
+ //#endregion
1064
+ //#region src/rules/no-effect-property-arrow.ts
1065
+ const noEffectPropertyArrow = defineRule({
1066
+ create: (context) => ({ Property: (node) => {
1067
+ if (node.value.type !== "ArrowFunctionExpression" || isArrayEmpty(node.value.params) || node.value.body.type !== "CallExpression") return;
1068
+ const callee = node.value.body.callee;
1069
+ if (callee.type === "Identifier" && isImportBinding({
1070
+ context,
1071
+ importedName: "pipe",
1072
+ node: callee,
1073
+ source: "effect"
1074
+ }) && some$1(node.value.body.arguments, (argument) => argument.type !== "SpreadElement" && importedMember({
1075
+ context,
1076
+ importedName: "Effect",
1077
+ node: argument
1078
+ }) || argument.type === "CallExpression" && importedMember({
1079
+ context,
1080
+ importedName: "Effect",
1081
+ node: argument.callee
1082
+ })) || callee.type === "MemberExpression" && importedMember({
1083
+ context,
1084
+ importedName: "Effect",
1085
+ node: callee,
1086
+ propertyName: "tryPromise"
1087
+ })) context.report({
1088
+ message: "Define this property with Effect.fn or Effect.fnUntraced instead of an arrow.",
1089
+ node
1090
+ });
1091
+ } }),
1092
+ meta: { type: "problem" }
1093
+ });
1094
+ //#endregion
1095
+ //#region src/rules/no-error-message-assertion.ts
1096
+ function receiverName(node) {
1097
+ if (node.type === "Identifier") return some(node.name);
1098
+ return node.type === "MemberExpression" ? memberName(node) : none();
1099
+ }
1100
+ function isErrorMessage(node) {
1101
+ return node?.type === "MemberExpression" && contains(memberName(node), "message") && exists(receiverName(node.object), (name) => /^(?:e|err|error|failure|cause|exception)$|Error$/iu.test(name));
1102
+ }
1103
+ function expectsMessage(node) {
1104
+ const subject = node.object.type === "MemberExpression" && contains(memberName(node.object), "not") ? node.object.object : node.object;
1105
+ return subject.type === "CallExpression" && subject.callee.type === "Identifier" && subject.callee.name === "expect" && isErrorMessage(subject.arguments[0]);
1106
+ }
1107
+ function assertsMessage(node) {
1108
+ const [actual, expected] = node.arguments;
1109
+ return node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "assert" && isErrorMessage(actual) && (expected?.type === "Literal" || expected?.type === "TemplateLiteral");
1110
+ }
1111
+ const noErrorMessageAssertion = defineRule({
1112
+ create: (context) => ({ CallExpression: (node) => {
1113
+ if (assertsMessage(node)) {
1114
+ context.report({
1115
+ message: "Assert the failure, never its message wording.",
1116
+ node
1117
+ });
1118
+ return;
1119
+ }
1120
+ if (node.callee.type === "MemberExpression" && (node.arguments[0]?.type === "Literal" || node.arguments[0]?.type === "TemplateLiteral") && (exists(memberName(node.callee), (name) => contains$1(["toThrow", "toThrowError"], name)) || expectsMessage(node.callee))) context.report({
1121
+ message: "Assert the failure, never its message wording.",
1122
+ node
1123
+ });
1124
+ } }),
1125
+ meta: { type: "problem" }
1126
+ });
1127
+ //#endregion
1128
+ //#region src/rules/no-fail-in-generator.ts
1129
+ function insideEffectGenerator(input) {
1130
+ if (input.node.type === "Program") return false;
1131
+ if ((input.node.type === "ArrowFunctionExpression" || input.node.type === "FunctionDeclaration" || input.node.type === "FunctionExpression") && !input.node.generator) return false;
1132
+ if (input.node.type === "FunctionExpression" && input.node.generator && input.node.parent.type === "CallExpression" && exists(effectBuilderName({
1133
+ context: input.context,
1134
+ node: input.node.parent.callee
1135
+ }), (name) => contains$1([
1136
+ "fn",
1137
+ "fnUntraced",
1138
+ "gen"
1139
+ ], name))) return true;
1140
+ return insideEffectGenerator({
1141
+ context: input.context,
1142
+ node: input.node.parent
1143
+ });
1144
+ }
1145
+ const noFailInGenerator = defineRule({
1146
+ create: (context) => ({ CallExpression: (node) => {
1147
+ if (node.callee.type === "MemberExpression" && importedMember({
1148
+ context,
1149
+ importedName: "Effect",
1150
+ node: node.callee,
1151
+ propertyName: "fail"
1152
+ }) && node.parent.type === "YieldExpression" && node.parent.delegate && node.arguments[0]?.type !== "NewExpression" && insideEffectGenerator({
1153
+ context,
1154
+ node
1155
+ })) context.report({
1156
+ message: "Yield the error instead: return yield* E.make(...).",
1157
+ node
1158
+ });
1159
+ } }),
1160
+ meta: { type: "problem" }
1161
+ });
1162
+ //#endregion
1163
+ //#region src/rules/no-fake-ref-state.ts
1164
+ function propertyName(node) {
1165
+ if (!node.computed && node.key.type === "Identifier") return some(node.key.name);
1166
+ if (node.key.type === "Literal" && isString(node.key.value)) return some(node.key.value);
1167
+ return none();
1168
+ }
1169
+ function isFakeRefState(input) {
1170
+ if (!isReactUseState(input) || input.node.arguments[0]?.type !== "ArrowFunctionExpression" || input.node.arguments[0].body.type !== "ObjectExpression") return false;
1171
+ return some$1(input.node.arguments[0].body.properties, (property) => property.type === "Property" && contains(propertyName(property), "current"));
1172
+ }
1173
+ const noFakeRefState = defineRule({
1174
+ create: (context) => ({ CallExpression: (node) => {
1175
+ if (isFakeRefState({
1176
+ context,
1177
+ node
1178
+ })) context.report({
1179
+ message: "Use useRef for ref-shaped lifecycle state.",
1180
+ node
1181
+ });
1182
+ } }),
1183
+ meta: { type: "problem" }
1184
+ });
1185
+ //#endregion
1186
+ //#region src/rules/no-hand-written-guard.ts
1187
+ function isSubject(input) {
1188
+ return input.node.type === "Identifier" && input.node.name === input.name;
1189
+ }
1190
+ function comparison(input) {
1191
+ if (input.subject.type === "UnaryExpression" && input.subject.operator === "typeof" && isSubject({
1192
+ name: input.name,
1193
+ node: input.subject.argument
1194
+ }) && input.other.type === "Literal" && isString(input.other.value)) return some(`typeof ${input.operator} ${input.other.value}`);
1195
+ if (!isSubject({
1196
+ name: input.name,
1197
+ node: input.subject
1198
+ })) return none();
1199
+ if (input.other.type === "Literal" && input.other.raw === "null") return some(`${input.operator} null`);
1200
+ if (input.other.type === "Identifier" && input.other.name === "undefined") return some(`${input.operator} undefined`);
1201
+ return none();
1202
+ }
1203
+ function check(input) {
1204
+ if (input.node.type === "LogicalExpression" && input.node.operator === "&&") return pipe(all([check({
1205
+ name: input.name,
1206
+ node: input.node.left
1207
+ }), check({
1208
+ name: input.name,
1209
+ node: input.node.right
1210
+ })]), map(flatten));
1211
+ if (input.node.type === "UnaryExpression" && input.node.operator === "!" && input.node.argument.type === "CallExpression" && input.node.argument.callee.type === "MemberExpression" && isSubject({
1212
+ name: "Array",
1213
+ node: input.node.argument.callee.object
1214
+ }) && contains(memberName(input.node.argument.callee), "isArray") && input.node.argument.arguments.length === 1 && every(input.node.argument.arguments, (argument) => isSubject({
1215
+ name: input.name,
1216
+ node: argument
1217
+ }))) return some(["!Array.isArray"]);
1218
+ if (input.node.type !== "BinaryExpression") return none();
1219
+ if (input.node.operator === "instanceof") return isSubject({
1220
+ name: input.name,
1221
+ node: input.node.left
1222
+ }) && input.node.right.type === "Identifier" ? some([`instanceof ${input.node.right.name}`]) : none();
1223
+ return pipe(firstSomeOf([comparison({
1224
+ name: input.name,
1225
+ operator: input.node.operator,
1226
+ other: input.node.right,
1227
+ subject: input.node.left
1228
+ }), comparison({
1229
+ name: input.name,
1230
+ operator: input.node.operator,
1231
+ other: input.node.left,
1232
+ subject: input.node.right
1233
+ })]), map(of));
1234
+ }
1235
+ function report(input) {
1236
+ const predicate = input.node.returnType?.typeAnnotation;
1237
+ const returned = returnedExpression(input.node);
1238
+ if (predicate?.type !== "TSTypePredicate" || predicate.asserts || predicate.parameterName.type !== "Identifier" || isNullish(returned)) return;
1239
+ const name = pipe(check({
1240
+ name: predicate.parameterName.name,
1241
+ node: returned
1242
+ }), map((checks) => pipe(checks, sort(Order), join(" && "))), flatMap((key) => get$2({
1243
+ "!= null": "isNotNullish",
1244
+ "!== null": "isNotNull",
1245
+ "!== null && !Array.isArray && typeof === object": "isObject",
1246
+ "!== null && typeof === object": "isObjectOrArray",
1247
+ "!== undefined": "isNotUndefined",
1248
+ "== null": "isNullish",
1249
+ "=== null": "isNull",
1250
+ "=== undefined": "isUndefined",
1251
+ "instanceof Date": "isDate",
1252
+ "instanceof Error": "isError",
1253
+ "instanceof Map": "isMap",
1254
+ "instanceof RegExp": "isRegExp",
1255
+ "instanceof Set": "isSet",
1256
+ "instanceof Uint8Array": "isUint8Array",
1257
+ "typeof === bigint": "isBigInt",
1258
+ "typeof === boolean": "isBoolean",
1259
+ "typeof === function": "isFunction",
1260
+ "typeof === number": "isNumber",
1261
+ "typeof === string": "isString",
1262
+ "typeof === symbol": "isSymbol",
1263
+ "typeof === undefined": "isUndefined"
1264
+ }, key)));
1265
+ map(name, (guard) => {
1266
+ input.context.report({
1267
+ message: `Use Predicate.${guard} instead of this hand-written type guard.`,
1268
+ node: input.node
1269
+ });
1270
+ });
1271
+ }
1272
+ const noHandWrittenGuard = defineRule({
1273
+ create: (context) => ({
1274
+ ArrowFunctionExpression: (node) => {
1275
+ report({
1276
+ context,
1277
+ node
1278
+ });
1279
+ },
1280
+ FunctionDeclaration: (node) => {
1281
+ report({
1282
+ context,
1283
+ node
1284
+ });
1285
+ },
1286
+ FunctionExpression: (node) => {
1287
+ report({
1288
+ context,
1289
+ node
1290
+ });
1291
+ }
1292
+ }),
1293
+ meta: { type: "problem" }
1294
+ });
1295
+ //#endregion
1296
+ //#region src/rules/no-let.ts
1297
+ const noLet = defineRule({
1298
+ create: (context) => ({ VariableDeclaration: (node) => {
1299
+ if (node.kind === "let") context.report({
1300
+ message: "Replace let with a const pipeline or a fold such as Array.reduce.",
1301
+ node
1302
+ });
1303
+ } }),
1304
+ meta: { type: "problem" }
1305
+ });
1306
+ //#endregion
1307
+ //#region src/rules/no-native-emptiness-check.ts
1308
+ function emptinessPredicate(node) {
1309
+ const comparesLength = node.left.type === "MemberExpression" && contains(memberName(node.left), "length") && node.right.type === "Literal" && node.right.value === 0;
1310
+ if (comparesLength && node.operator === "===") return some("Array.isArrayEmpty, Array.isReadonlyArrayEmpty, or String.isEmpty");
1311
+ if (comparesLength && node.operator === ">") return some("Array.isArrayNonEmpty, Array.isReadonlyArrayNonEmpty, or String.isNonEmpty");
1312
+ return none();
1313
+ }
1314
+ const noNativeEmptinessCheck = defineRule({
1315
+ create: (context) => ({ BinaryExpression: (node) => {
1316
+ map(emptinessPredicate(node), (predicate) => {
1317
+ context.report({
1318
+ message: `Use ${predicate}.`,
1319
+ node
1320
+ });
1321
+ });
1322
+ } }),
1323
+ meta: { type: "problem" }
1324
+ });
1325
+ //#endregion
1326
+ //#region src/rules/no-native-method-call.ts
1327
+ const nativeMethods = [
1328
+ "at",
1329
+ "catch",
1330
+ "charAt",
1331
+ "charCodeAt",
1332
+ "codePointAt",
1333
+ "concat",
1334
+ "endsWith",
1335
+ "entries",
1336
+ "every",
1337
+ "fill",
1338
+ "filter",
1339
+ "finally",
1340
+ "find",
1341
+ "findIndex",
1342
+ "findLast",
1343
+ "findLastIndex",
1344
+ "flat",
1345
+ "flatMap",
1346
+ "forEach",
1347
+ "includes",
1348
+ "indexOf",
1349
+ "join",
1350
+ "keys",
1351
+ "lastIndexOf",
1352
+ "localeCompare",
1353
+ "map",
1354
+ "match",
1355
+ "matchAll",
1356
+ "normalize",
1357
+ "padEnd",
1358
+ "padStart",
1359
+ "pop",
1360
+ "push",
1361
+ "reduce",
1362
+ "reduceRight",
1363
+ "repeat",
1364
+ "replace",
1365
+ "replaceAll",
1366
+ "reverse",
1367
+ "shift",
1368
+ "slice",
1369
+ "some",
1370
+ "sort",
1371
+ "splice",
1372
+ "split",
1373
+ "startsWith",
1374
+ "substring",
1375
+ "then",
1376
+ "toLocaleLowerCase",
1377
+ "toLocaleUpperCase",
1378
+ "toLowerCase",
1379
+ "toReversed",
1380
+ "toSorted",
1381
+ "toSpliced",
1382
+ "toUpperCase",
1383
+ "trim",
1384
+ "trimEnd",
1385
+ "trimStart",
1386
+ "unshift",
1387
+ "values",
1388
+ "with"
1389
+ ];
1390
+ const noNativeMethodCall = defineRule({
1391
+ create: (context) => ({ CallExpression: (node) => {
1392
+ if (node.callee.type !== "MemberExpression" || node.callee.object.type === "Identifier" && (node.callee.object.name === "path" || isImportBinding({
1393
+ context,
1394
+ node: node.callee.object,
1395
+ source: /^(?:effect(?:\/|$)|@effect\/)/u
1396
+ }))) return;
1397
+ const receiver = node.callee.object;
1398
+ pipe(memberName(node.callee), filter((name) => contains$1(nativeMethods, name)), filter((name) => !contains$1([
1399
+ "entries",
1400
+ "keys",
1401
+ "values"
1402
+ ], name) || isArrayEmpty(node.arguments) || receiver.type === "Identifier" && receiver.name === "Object"), map((name) => {
1403
+ context.report({
1404
+ message: `Replace .${name}() on a native array, string, record, or Promise with its Effect Array, String, Record, or Effect function; a third-party API's own method stays, with an inline disable and its reason.`,
1405
+ node: node.callee
1406
+ });
1407
+ }));
1408
+ } }),
1409
+ meta: { type: "problem" }
1410
+ });
1411
+ //#endregion
1412
+ //#region src/rules/no-option-value-access.ts
1413
+ function checks(input) {
1414
+ if (input.test.type === "LogicalExpression" && input.test.operator === input.operator) return checks({
1415
+ ...input,
1416
+ test: input.test.left
1417
+ }) || checks({
1418
+ ...input,
1419
+ test: input.test.right
1420
+ });
1421
+ return input.test.type === "CallExpression" && importedMember({
1422
+ context: input.context,
1423
+ importedName: "Option",
1424
+ node: input.test.callee,
1425
+ propertyName: input.name
1426
+ }) && input.test.arguments[0] !== void 0 && input.context.sourceCode.getText(input.test.arguments[0]) === input.subject;
1427
+ }
1428
+ function exits(node) {
1429
+ return contains$1([
1430
+ "ContinueStatement",
1431
+ "ReturnStatement",
1432
+ "ThrowStatement"
1433
+ ], node.type) || node.type === "BlockStatement" && some$1(node.body, exits);
1434
+ }
1435
+ function earlyExit(input) {
1436
+ const parent = input.node.parent;
1437
+ if (parent?.type !== "BlockStatement" && parent?.type !== "Program") return false;
1438
+ const index = findFirstIndex(parent.body, (statement) => statement === input.node);
1439
+ return some$1(take(parent.body, getOrElse(index, () => 0)), (statement) => statement.type === "IfStatement" && exits(statement.consequent) && checks({
1440
+ ...input,
1441
+ name: "isNone",
1442
+ operator: "||",
1443
+ test: statement.test
1444
+ }));
1445
+ }
1446
+ function guarded(input) {
1447
+ const parent = input.node.parent;
1448
+ if (parent === null || parent.type === "FunctionDeclaration") return false;
1449
+ function some(test) {
1450
+ return checks({
1451
+ ...input,
1452
+ name: "isSome",
1453
+ operator: "&&",
1454
+ test
1455
+ });
1456
+ }
1457
+ return parent.type === "IfStatement" && parent.consequent === input.node && some(parent.test) || parent.type === "ConditionalExpression" && parent.consequent === input.node && some(parent.test) || parent.type === "LogicalExpression" && parent.right === input.node && parent.operator === "&&" && some(parent.left) || parent.type === "LogicalExpression" && parent.right === input.node && parent.operator === "||" && checks({
1458
+ ...input,
1459
+ name: "isNone",
1460
+ operator: "||",
1461
+ test: parent.left
1462
+ }) || earlyExit(input) || guarded({
1463
+ ...input,
1464
+ node: parent
1465
+ });
1466
+ }
1467
+ const noOptionValueAccess = defineRule({
1468
+ create: (context) => ({ MemberExpression: (node) => {
1469
+ if (!contains(memberName(node), "value")) return;
1470
+ if (guarded({
1471
+ context,
1472
+ node,
1473
+ subject: context.sourceCode.getText(node.object)
1474
+ })) context.report({
1475
+ message: "Read the value with Option.match, Option.map, or Option.getOrElse.",
1476
+ node
1477
+ });
1478
+ } }),
1479
+ meta: { type: "problem" }
1480
+ });
1481
+ //#endregion
1482
+ //#region src/rules/no-readonly-type-syntax.ts
1483
+ function isTopLevelStatement(node) {
1484
+ if (node.parent.type === "Program") return true;
1485
+ return node.parent.type === "ExportNamedDeclaration" && node.parent.parent.type === "Program";
1486
+ }
1487
+ function insideCycleType(input) {
1488
+ if (input.node.type === "Program") return false;
1489
+ if (input.node.type === "TSTypeAliasDeclaration" && isTopLevelStatement(input.node)) return contains$1(input.cycleNames, input.node.id.name);
1490
+ return insideCycleType({
1491
+ cycleNames: input.cycleNames,
1492
+ node: input.node.parent
1493
+ });
1494
+ }
1495
+ function referencedName(node) {
1496
+ if (node.type !== "TSTypeReference") return none();
1497
+ if (node.typeName.type === "Identifier") return some(node.typeName.name);
1498
+ return node.typeName.type === "TSQualifiedName" ? some(node.typeName.right.name) : none();
1499
+ }
1500
+ function shapeLiterals(input) {
1501
+ if (input.type.type === "TSTypeLiteral") return [input.type];
1502
+ return pipe(referencedName(input.type), filter((name) => !contains$1(input.seen, name)), map((name) => pipe(input.aliases, filter$1((alias) => alias.id.name === name), flatMap$1((alias) => shapeLiterals({
1503
+ aliases: input.aliases,
1504
+ seen: append(input.seen, name),
1505
+ type: alias.typeAnnotation
1506
+ })))), getOrElse(() => empty()));
1507
+ }
1508
+ const noReadonlyTypeSyntax = defineRule({
1509
+ create: (context) => {
1510
+ const cycleNames = schemaCycleNames({
1511
+ context,
1512
+ program: context.sourceCode.ast
1513
+ });
1514
+ const shapes = make$2(empty());
1515
+ const aliases = make$2(empty());
1516
+ const properties = make$2(empty());
1517
+ const methods = make$2(empty());
1518
+ function exempt(node) {
1519
+ return insideCycleType({
1520
+ cycleNames,
1521
+ node
1522
+ });
1523
+ }
1524
+ return {
1525
+ CallExpression: (node) => {
1526
+ if (importedMember({
1527
+ context,
1528
+ importedName: "Context",
1529
+ node: node.callee,
1530
+ propertyName: "Service"
1531
+ })) pipe(fromNullishOr(node.typeArguments?.params[1]), map((shape) => update(shapes, append(shape))));
1532
+ },
1533
+ "Program:exit": () => {
1534
+ const literals = pipe(get$3(shapes), flatMap$1((shape) => shapeLiterals({
1535
+ aliases: get$3(aliases),
1536
+ seen: [],
1537
+ type: shape
1538
+ })));
1539
+ function inShape(node) {
1540
+ return some$1(literals, (literal) => literal === node.parent);
1541
+ }
1542
+ for (const node of get$3(properties)) {
1543
+ if (inShape(node) && !node.readonly) context.report({
1544
+ message: "Mark this service property readonly.",
1545
+ node
1546
+ });
1547
+ if (!inShape(node) && node.readonly && !exempt(node)) context.report({
1548
+ message: "Remove the readonly property modifier.",
1549
+ node
1550
+ });
1551
+ }
1552
+ for (const node of get$3(methods)) if (inShape(node)) context.report({
1553
+ message: "Write this service method as a readonly property holding a function.",
1554
+ node
1555
+ });
1556
+ },
1557
+ TSIndexSignature: (node) => {
1558
+ if (node.readonly) context.report({
1559
+ message: "Remove the readonly index modifier.",
1560
+ node
1561
+ });
1562
+ },
1563
+ TSMappedType: (node) => {
1564
+ if (node.readonly === true || node.readonly === "+") context.report({
1565
+ message: "Remove the readonly mapped-type modifier.",
1566
+ node
1567
+ });
1568
+ },
1569
+ TSMethodSignature: (node) => {
1570
+ update(methods, append(node));
1571
+ },
1572
+ TSPropertySignature: (node) => {
1573
+ update(properties, append(node));
1574
+ },
1575
+ TSTypeAliasDeclaration: (node) => {
1576
+ update(aliases, append(node));
1577
+ },
1578
+ TSTypeOperator: (node) => {
1579
+ if (node.operator === "readonly" && !exempt(node)) context.report({
1580
+ message: "Use a mutable type shape.",
1581
+ node
1582
+ });
1583
+ },
1584
+ TSTypeReference: (node) => {
1585
+ if (node.typeName.type === "Identifier" && node.typeName.name === "Readonly" && !exempt(node)) context.report({
1586
+ message: "Use a mutable type shape.",
1587
+ node
1588
+ });
1589
+ }
1590
+ };
1591
+ },
1592
+ meta: { type: "problem" }
1593
+ });
1594
+ //#endregion
1595
+ //#region src/rules/no-redundant-return-type.ts
1596
+ function isExported(node) {
1597
+ if (node.parent.type === "ExportNamedDeclaration" || node.parent.type === "ExportDefaultDeclaration") return true;
1598
+ return node.parent.type === "VariableDeclarator" && node.parent.parent.type === "VariableDeclaration" && node.parent.parent.parent.type === "ExportNamedDeclaration";
1599
+ }
1600
+ function inferredIdentically$1(input) {
1601
+ const text = input.context.sourceCode.getText;
1602
+ const body = input.node.body;
1603
+ if (body === null) return false;
1604
+ const block = body.type === "BlockStatement";
1605
+ const values = body.type === "BlockStatement" ? map$1(input.returns, (statement) => statement.argument) : [body];
1606
+ const expressions = filter$1(values, isNotNull);
1607
+ if (input.type.type === "TSVoidKeyword") return block && isArrayEmpty(expressions);
1608
+ if (isArrayEmpty(expressions) || expressions.length !== values.length) return false;
1609
+ if (input.type.type === "TSStringKeyword") return every(expressions, (value) => value.type === "TemplateLiteral" && isArrayNonEmpty(value.expressions));
1610
+ if (isExported(input.node)) return false;
1611
+ return every(expressions, (value) => value.type === "TSAsExpression" && text(value.typeAnnotation) === text(input.type) || !block && value.type === "NewExpression" && input.type.type === "TSTypeReference" && input.type.typeArguments === null && text(value.callee) === text(input.type.typeName));
1612
+ }
1613
+ const noRedundantReturnType = defineRule({
1614
+ create: (context) => {
1615
+ const frames = make$2(empty());
1616
+ function enter() {
1617
+ update(frames, append({ returns: empty() }));
1618
+ }
1619
+ function exit(node) {
1620
+ const frame = last(get$3(frames));
1621
+ update(frames, dropRight(1));
1622
+ if (node.async || node.generator || isNullish(node.returnType)) return;
1623
+ if (inferredIdentically$1({
1624
+ context,
1625
+ node,
1626
+ returns: match(frame, {
1627
+ onNone: () => empty(),
1628
+ onSome: (top) => top.returns
1629
+ }),
1630
+ type: node.returnType.typeAnnotation
1631
+ })) context.report({
1632
+ message: "Drop this return type; inference gives the same type.",
1633
+ node: node.returnType
1634
+ });
1635
+ }
1636
+ return {
1637
+ ArrowFunctionExpression: enter,
1638
+ "ArrowFunctionExpression:exit": exit,
1639
+ FunctionDeclaration: enter,
1640
+ "FunctionDeclaration:exit": exit,
1641
+ FunctionExpression: enter,
1642
+ "FunctionExpression:exit": exit,
1643
+ ReturnStatement: (node) => {
1644
+ update(frames, (stack) => pipe(last(stack), match({
1645
+ onNone: () => stack,
1646
+ onSome: (top) => append(dropRight(stack, 1), { returns: append(top.returns, node) })
1647
+ })));
1648
+ }
1649
+ };
1650
+ },
1651
+ meta: { type: "problem" }
1652
+ });
1653
+ //#endregion
1654
+ //#region src/rules/no-redundant-state-type.ts
1655
+ const noRedundantStateType = defineRule({
1656
+ create: (context) => ({ CallExpression: (node) => {
1657
+ const argument = node.arguments[0];
1658
+ const type = node.typeArguments?.params[0];
1659
+ if (node.arguments.length !== 1 || node.typeArguments?.params.length !== 1 || argument?.type !== "Literal" || node.callee.type === "Super") return;
1660
+ if (!(isReactUseState({
1661
+ context,
1662
+ node
1663
+ }) || some$1([
1664
+ "MutableRef",
1665
+ "Ref",
1666
+ "SubscriptionRef"
1667
+ ], (importedName) => importedMember({
1668
+ context,
1669
+ importedName,
1670
+ node: node.callee,
1671
+ propertyName: "make"
1672
+ })))) return;
1673
+ if (isString(argument.value) && type?.type === "TSStringKeyword" || isNumber(argument.value) && type?.type === "TSNumberKeyword" || isBoolean(argument.value) && type?.type === "TSBooleanKeyword") context.report({
1674
+ message: "Drop this state type; the initializer infers the same primitive type.",
1675
+ node: type
1676
+ });
1677
+ } }),
1678
+ meta: { type: "problem" }
1679
+ });
1680
+ //#endregion
1681
+ //#region src/rules/no-redundant-use-ref-null-type.ts
1682
+ function isReactUseRef(input) {
1683
+ if (input.node.callee.type === "Identifier") return isImportBinding({
1684
+ context: input.context,
1685
+ importedName: "useRef",
1686
+ node: input.node.callee,
1687
+ source: "react"
1688
+ });
1689
+ return input.node.callee.type === "MemberExpression" && contains(memberName(input.node.callee), "useRef") && input.node.callee.object.type === "Identifier" && isNamespaceImport({
1690
+ context: input.context,
1691
+ node: input.node.callee.object,
1692
+ source: "react"
1693
+ });
1694
+ }
1695
+ function redundantUseRefNullType(input) {
1696
+ const type = input.node.typeArguments?.params[0];
1697
+ return isReactUseRef(input) && input.node.arguments[0]?.type === "Literal" && input.node.arguments[0].value === null && type?.type === "TSUnionType" && some$1(type.types, (member) => member.type === "TSNullKeyword");
1698
+ }
1699
+ const noRedundantUseRefNullType = defineRule({
1700
+ create: (context) => ({ CallExpression: (node) => {
1701
+ if (redundantUseRefNullType({
1702
+ context,
1703
+ node
1704
+ })) context.report({
1705
+ message: "Remove null from the explicit useRef type; the null initializer already owns it.",
1706
+ node
1707
+ });
1708
+ } }),
1709
+ meta: { type: "problem" }
1710
+ });
1711
+ //#endregion
1712
+ //#region src/rules/no-redundant-variable-annotation.ts
1713
+ function isStringLiteral(node) {
1714
+ return node.type === "Literal" && isString(node.value);
1715
+ }
1716
+ function inferredIdentically(input) {
1717
+ const text = input.context.sourceCode.getText;
1718
+ if (input.init.type === "TSAsExpression") return text(input.init.typeAnnotation) === text(input.type);
1719
+ return input.init.type === "ConditionalExpression" && input.type.type === "TSStringKeyword" && isStringLiteral(input.init.consequent) && isStringLiteral(input.init.alternate);
1720
+ }
1721
+ const noRedundantVariableAnnotation = defineRule({
1722
+ create: (context) => ({ VariableDeclarator: (node) => {
1723
+ const annotation = node.id.typeAnnotation;
1724
+ if (node.init === null || isNullish(annotation)) return;
1725
+ if (node.init.type === "ArrayExpression" && isArrayEmpty(node.init.elements)) {
1726
+ context.report({
1727
+ message: "Write Array.empty<T>() instead of annotating an empty array.",
1728
+ node: annotation
1729
+ });
1730
+ return;
1731
+ }
1732
+ if (inferredIdentically({
1733
+ context,
1734
+ init: node.init,
1735
+ type: annotation.typeAnnotation
1736
+ })) context.report({
1737
+ message: "Drop this annotation; inference gives the same type.",
1738
+ node: annotation
1739
+ });
1740
+ } }),
1741
+ meta: { type: "problem" }
1742
+ });
1743
+ //#endregion
1744
+ //#region src/rules/no-reinvented-schema.ts
1745
+ const shipped = [
1746
+ {
1747
+ base: "String",
1748
+ check: "isMinLength",
1749
+ only: 1,
1750
+ schema: "NonEmptyString"
1751
+ },
1752
+ {
1753
+ base: "String",
1754
+ check: "isNonEmpty",
1755
+ only: void 0,
1756
+ schema: "NonEmptyString"
1757
+ },
1758
+ {
1759
+ base: "String",
1760
+ check: "isTrimmed",
1761
+ only: void 0,
1762
+ schema: "Trimmed"
1763
+ },
1764
+ {
1765
+ base: "Number",
1766
+ check: "isInt",
1767
+ only: void 0,
1768
+ schema: "Int"
1769
+ },
1770
+ {
1771
+ base: "Int",
1772
+ check: "isGreaterThanOrEqualTo",
1773
+ only: 0,
1774
+ schema: "Natural"
1775
+ }
1776
+ ];
1777
+ function schemaMember(input) {
1778
+ return input.node.type === "MemberExpression" && importedMember({
1779
+ context: input.context,
1780
+ importedName: "Schema",
1781
+ node: input.node
1782
+ }) ? memberName(input.node) : none();
1783
+ }
1784
+ function shippedSchema(input) {
1785
+ if (input.filter.type !== "CallExpression") return none();
1786
+ const base = schemaMember({
1787
+ context: input.context,
1788
+ node: input.base
1789
+ });
1790
+ const check = schemaMember({
1791
+ context: input.context,
1792
+ node: input.filter.callee
1793
+ });
1794
+ const [value, ...rest] = input.filter.arguments;
1795
+ return pipe(shipped, findFirst((entry) => contains(base, entry.base) && contains(check, entry.check) && isArrayEmpty(rest) && (entry.only === void 0 ? value === void 0 : value?.type === "Literal" && value.value === entry.only)), map((entry) => entry.schema));
1796
+ }
1797
+ function pipedBase(node) {
1798
+ const parent = node.parent;
1799
+ if (parent.type !== "CallExpression") return none();
1800
+ if (parent.callee.type === "Identifier" && parent.callee.name === "pipe" && parent.arguments.length === 2) return parent.arguments[1] === node ? fromNullishOr(parent.arguments[0]) : none();
1801
+ return parent.callee.type === "MemberExpression" && contains(memberName(parent.callee), "pipe") && parent.arguments.length === 1 ? some(parent.callee.object) : none();
1802
+ }
1803
+ function reinventedSchema(input) {
1804
+ if (input.node.callee.type !== "MemberExpression" || !contains(memberName(input.node.callee), "check")) return none();
1805
+ const callee = input.node.callee;
1806
+ const [filter] = input.node.arguments;
1807
+ if (isSome(schemaMember({
1808
+ context: input.context,
1809
+ node: callee
1810
+ }))) return pipe(pipedBase(input.node), flatMap((base) => input.node.arguments.length === 1 && filter !== void 0 ? shippedSchema({
1811
+ base,
1812
+ context: input.context,
1813
+ filter
1814
+ }) : none()));
1815
+ return findFirst(input.node.arguments, (argument) => shippedSchema({
1816
+ base: callee.object,
1817
+ context: input.context,
1818
+ filter: argument
1819
+ }));
1820
+ }
1821
+ const noReinventedSchema = defineRule({
1822
+ create: (context) => ({ CallExpression: (node) => {
1823
+ map(reinventedSchema({
1824
+ context,
1825
+ node
1826
+ }), (schema) => {
1827
+ context.report({
1828
+ message: `Replace this base and its matching refinement with Schema.${schema}, keeping every other check.`,
1829
+ node
1830
+ });
1831
+ });
1832
+ } }),
1833
+ meta: { type: "problem" }
1834
+ });
1835
+ //#endregion
1836
+ //#region src/rules/no-renamed-import.ts
1837
+ const noRenamedImport = defineRule({
1838
+ create: (context) => ({ ImportSpecifier: (node) => {
1839
+ const imported = node.imported.type === "Literal" ? node.imported.value : node.imported.name;
1840
+ if (imported === node.local.name || imported === "it" && node.local.name === "test") return;
1841
+ context.report({
1842
+ message: `Import ${imported} under its own name.`,
1843
+ node
1844
+ });
1845
+ } }),
1846
+ meta: { type: "problem" }
1847
+ });
1848
+ //#endregion
1849
+ //#region src/rules/no-stored-schema-operation.ts
1850
+ function storedSchemaOperation(node) {
1851
+ return node.parent.type === "VariableDeclarator" && node.parent.init === node || node.parent.type === "Property" && node.parent.value === node || node.parent.type === "PropertyDefinition" && node.parent.value === node || node.parent.type === "ArrayExpression" || node.parent.type === "AssignmentExpression" && node.parent.right === node;
1852
+ }
1853
+ const noStoredSchemaOperation = defineRule({
1854
+ create: (context) => ({ CallExpression: (node) => {
1855
+ if (isSchemaOperationCall({
1856
+ context,
1857
+ node
1858
+ }) && storedSchemaOperation(node)) context.report({
1859
+ message: "Inline this Schema operation at its consumption site; never store compiled operations.",
1860
+ node
1861
+ });
1862
+ } }),
1863
+ meta: { type: "problem" }
1864
+ });
1865
+ //#endregion
1866
+ //#region src/rules/no-switch-statement.ts
1867
+ const noSwitchStatement = defineRule({
1868
+ create: (context) => ({ SwitchStatement: (node) => {
1869
+ context.report({
1870
+ message: "Use Match instead of switch.",
1871
+ node
1872
+ });
1873
+ } }),
1874
+ meta: { type: "problem" }
1875
+ });
1876
+ //#endregion
1877
+ //#region src/rules/no-trivial-indirection.ts
1878
+ function parameterName(parameter) {
1879
+ if (parameter.type === "Identifier") return some(parameter.name);
1880
+ if (parameter.type === "RestElement" && parameter.argument.type === "Identifier") return some(parameter.argument.name);
1881
+ return none();
1882
+ }
1883
+ function forwardedCall(input) {
1884
+ return input.node.arguments.length === input.names.length && every(input.node.arguments, (argument, index) => {
1885
+ const name = input.names[index];
1886
+ if (argument.type === "SpreadElement") return argument.argument.type === "Identifier" && argument.argument.name === name;
1887
+ return argument.type === "Identifier" && argument.name === name;
1888
+ });
1889
+ }
1890
+ function exactForwardingFunction(node) {
1891
+ const names = pipe(node.params, map$1(parameterName), getSomes);
1892
+ const returned = returnedExpression(node);
1893
+ if (isArrayEmpty(names) || names.length !== node.params.length || isNullish(returned)) return false;
1894
+ if (returned.type === "Identifier") return names.length === 1 && returned.name === names[0];
1895
+ return (returned.type === "CallExpression" || returned.type === "NewExpression") && returned.callee.type === "Identifier" && forwardedCall({
1896
+ names,
1897
+ node: returned
1898
+ });
1899
+ }
1900
+ function isIdentity(node) {
1901
+ const [parameter] = node.params;
1902
+ const returned = returnedExpression(node);
1903
+ return node.params.length === 1 && parameter?.type === "Identifier" && returned?.type === "Identifier" && returned.name === parameter.name;
1904
+ }
1905
+ function indirectionMessage(node) {
1906
+ return isIdentity(node) ? "Pass identity from effect instead of this function." : "Inline this function at its only use site.";
1907
+ }
1908
+ function isExport(node) {
1909
+ return node?.type === "ExportNamedDeclaration" || node?.type === "ExportDefaultDeclaration";
1910
+ }
1911
+ function unexportedBindingName(node) {
1912
+ if (node.type === "FunctionDeclaration" && node.id !== null && !isExport(node.parent)) return some(node.id.name);
1913
+ if (node.parent.type === "VariableDeclarator" && node.parent.id.type === "Identifier" && node.parent.id.typeAnnotation === null && !isExport(node.parent.parent.parent)) return some(node.parent.id.name);
1914
+ return none();
1915
+ }
1916
+ function singleCallerWrapper(input) {
1917
+ const names = pipe(input.node.params, map$1(parameterName), getSomes);
1918
+ const returned = returnedExpression(input.node);
1919
+ if (input.node.async || input.node.generator || input.node.returnType?.typeAnnotation.type === "TSTypePredicate" || isArrayEmpty(names) || names.length !== input.node.params.length || returned?.type !== "CallExpression") return false;
1920
+ return pipe(unexportedBindingName(input.node), flatMap((name) => variableFromScope({
1921
+ name,
1922
+ scope: input.context.sourceCode.getScope(input.node)
1923
+ })), exists((variable) => {
1924
+ const reads = filter$1(variable.references, (reference) => reference.isRead());
1925
+ return reads.length === 1 && every(reads, (reference) => reference.identifier.parent.type === "CallExpression" && reference.identifier.parent.callee === reference.identifier);
1926
+ }));
1927
+ }
1928
+ function redundantConstAlias(input) {
1929
+ if (input.node.parent.type !== "VariableDeclaration" || input.node.parent.kind !== "const" || input.node.id.type !== "Identifier" || input.node.id.typeAnnotation !== null || input.node.init?.type !== "Identifier" || !pipe(variableFor(input.context, input.node.init), exists((variable) => {
1930
+ if (some$1(variable.references, (reference) => reference.isWrite() && !reference.init)) return false;
1931
+ return some$1(variable.defs, (definition) => {
1932
+ if (definition.type === "ImportBinding" || definition.type === "Parameter") return true;
1933
+ return definition.node.type === "VariableDeclarator" && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const";
1934
+ });
1935
+ }))) return false;
1936
+ return pipe(variableFromScope({
1937
+ name: input.node.id.name,
1938
+ scope: input.context.sourceCode.getScope(input.node)
1939
+ }), exists((alias) => filter$1(alias.references, (reference) => reference.isRead()).length === 1));
1940
+ }
1941
+ function singleUseLiteral(input) {
1942
+ if (input.node.parent.type !== "VariableDeclaration" || input.node.parent.kind !== "const" || isExport(input.node.parent.parent) || input.node.id.type !== "Identifier" || input.node.id.typeAnnotation !== null || !(input.node.init?.type === "Literal" && !hasProperty(input.node.init, "regex") || input.node.init?.type === "TemplateLiteral" && isArrayEmpty(input.node.init.expressions))) return false;
1943
+ return pipe(variableFromScope({
1944
+ name: input.node.id.name,
1945
+ scope: input.context.sourceCode.getScope(input.node)
1946
+ }), map((variable) => filter$1(variable.references, (reference) => reference.isRead())), exists((reads) => reads.length === 1 && reads[0]?.identifier.parent.type !== "ExportSpecifier"));
1947
+ }
1948
+ function singleUseLayerPart(input) {
1949
+ const init = input.node.init;
1950
+ if (input.node.parent.type !== "VariableDeclaration" || input.node.parent.kind !== "const" || isExport(input.node.parent.parent) || input.node.id.type !== "Identifier" || input.node.id.typeAnnotation !== null || init === null) return false;
1951
+ return pipe(variableFromScope({
1952
+ name: input.node.id.name,
1953
+ scope: input.context.sourceCode.getScope(input.node)
1954
+ }), map((variable) => filter$1(variable.references, (reference) => reference.isRead())), exists((reads) => {
1955
+ const consumer = reads[0]?.identifier.parent;
1956
+ if (reads.length !== 1 || consumer?.type !== "CallExpression") return false;
1957
+ if (init.type === "MemberExpression") return contains(memberName(init), "layer") && (importedMember({
1958
+ context: input.context,
1959
+ importedName: "Layer",
1960
+ node: consumer.callee
1961
+ }) || importedMember({
1962
+ context: input.context,
1963
+ importedName: "Effect",
1964
+ node: consumer.callee,
1965
+ propertyName: "provide"
1966
+ }));
1967
+ return init.type === "CallExpression" && importedMember({
1968
+ context: input.context,
1969
+ importedName: "Effect",
1970
+ node: init.callee,
1971
+ propertyName: "gen"
1972
+ }) && consumer.arguments[1] === reads[0]?.identifier && importedMember({
1973
+ context: input.context,
1974
+ importedName: "Layer",
1975
+ node: consumer.callee,
1976
+ propertyName: "effect"
1977
+ });
1978
+ }));
1979
+ }
1980
+ const noTrivialIndirection = defineRule({
1981
+ create: (context) => ({
1982
+ ArrowFunctionExpression: (node) => {
1983
+ if ((node.parent.type === "VariableDeclarator" || node.parent.type === "Property") && (exactForwardingFunction(node) || singleUseThunk({
1984
+ context,
1985
+ node
1986
+ }) || singleCallerWrapper({
1987
+ context,
1988
+ node
1989
+ }))) context.report({
1990
+ message: indirectionMessage(node),
1991
+ node
1992
+ });
1993
+ },
1994
+ FunctionDeclaration: (node) => {
1995
+ if (exactForwardingFunction(node) || singleUseThunk({
1996
+ context,
1997
+ node
1998
+ }) || singleCallerWrapper({
1999
+ context,
2000
+ node
2001
+ })) context.report({
2002
+ message: indirectionMessage(node),
2003
+ node
2004
+ });
2005
+ },
2006
+ FunctionExpression: (node) => {
2007
+ if ((node.parent.type === "VariableDeclarator" || node.parent.type === "Property" || node.parent.type === "MethodDefinition" && node.parent.override !== true) && (exactForwardingFunction(node) || singleUseThunk({
2008
+ context,
2009
+ node
2010
+ }) || singleCallerWrapper({
2011
+ context,
2012
+ node
2013
+ }))) context.report({
2014
+ message: indirectionMessage(node),
2015
+ node
2016
+ });
2017
+ },
2018
+ VariableDeclarator: (node) => {
2019
+ if (redundantConstAlias({
2020
+ context,
2021
+ node
2022
+ })) context.report({
2023
+ message: "Use the immutable source binding directly.",
2024
+ node
2025
+ });
2026
+ if (singleUseLiteral({
2027
+ context,
2028
+ node
2029
+ })) context.report({
2030
+ message: "Inline this literal at its only use site.",
2031
+ node
2032
+ });
2033
+ if (singleUseLayerPart({
2034
+ context,
2035
+ node
2036
+ })) context.report({
2037
+ message: "Write this layer part where its only layer uses it.",
2038
+ node
2039
+ });
2040
+ }
2041
+ }),
2042
+ meta: { type: "problem" }
2043
+ });
2044
+ //#endregion
2045
+ //#region src/rules/no-typeof.ts
2046
+ const noTypeof = defineRule({
2047
+ create: (context) => ({ UnaryExpression: (node) => {
2048
+ if (node.operator !== "typeof") return;
2049
+ if (node.argument.type === "Identifier" && !exists(variableFor(context, node.argument), (variable) => isArrayNonEmpty(variable.defs))) return;
2050
+ context.report({
2051
+ message: "Replace typeof with a Predicate guard such as Predicate.isString.",
2052
+ node
2053
+ });
2054
+ } }),
2055
+ meta: { type: "problem" }
2056
+ });
2057
+ //#endregion
2058
+ //#region src/rules/no-undestructured-use-state.ts
2059
+ const noUndestructuredUseState = defineRule({
2060
+ create: (context) => ({ VariableDeclarator: (node) => {
2061
+ if (node.init?.type === "CallExpression" && isReactUseState({
2062
+ context,
2063
+ node: node.init
2064
+ }) && node.id.type !== "ArrayPattern") context.report({
2065
+ message: "Destructure the state value and setter at the declaration.",
2066
+ node
2067
+ });
2068
+ } }),
2069
+ meta: { type: "problem" }
2070
+ });
2071
+ //#endregion
2072
+ //#region src/rules/no-unexplained-disable.ts
2073
+ const noUnexplainedDisable = defineRule({
2074
+ create: (context) => ({ Program: () => {
2075
+ for (const comment of context.sourceCode.getAllComments()) if (/^\s*(?:eslint|oxlint)-disable\S*\s(?:(?!\s--\s).)*\bsort-keys\b/u.test(comment.value)) context.report({
2076
+ message: "Sort the keys, starting a new sorted group after a blank line; never disable sort-keys.",
2077
+ node: comment
2078
+ });
2079
+ else if (/^\s*(?:eslint-disable|oxlint-disable|@effect-diagnostics)/u.test(comment.value) && !/\s--\s*\S/u.test(comment.value)) context.report({
2080
+ message: "Give this disable a `-- reason`.",
2081
+ node: comment
2082
+ });
2083
+ } }),
2084
+ meta: { type: "problem" }
2085
+ });
2086
+ //#endregion
2087
+ //#region src/rules/no-unvalidated-json-decode.ts
2088
+ function unknownJsonSchema(input) {
2089
+ if (isSchemaOperationCall(input) && input.node.callee.type === "MemberExpression" && pipe(memberName(input.node.callee), exists(startsWith("decode"))) && input.node.arguments[0]?.type === "MemberExpression" && importedMember({
2090
+ context: input.context,
2091
+ importedName: "Schema",
2092
+ node: input.node.arguments[0],
2093
+ propertyName: "UnknownFromJsonString"
2094
+ })) return true;
2095
+ if (input.node.callee.type !== "MemberExpression" || !importedMember({
2096
+ context: input.context,
2097
+ importedName: "Schema",
2098
+ node: input.node.callee,
2099
+ propertyName: "fromJsonString"
2100
+ }) || input.node.arguments[0]?.type !== "MemberExpression" || !importedMember({
2101
+ context: input.context,
2102
+ importedName: "Schema",
2103
+ node: input.node.arguments[0],
2104
+ propertyName: "Unknown"
2105
+ })) return false;
2106
+ const parent = input.node.parent;
2107
+ if (parent.type !== "CallExpression" || parent.arguments[0] !== input.node || parent.callee.type !== "MemberExpression") return false;
2108
+ return importedMember({
2109
+ context: input.context,
2110
+ importedName: "Schema",
2111
+ node: parent.callee
2112
+ }) && pipe(memberName(parent.callee), exists(startsWith("decode")));
2113
+ }
2114
+ const noUnvalidatedJsonDecode = defineRule({
2115
+ create: (context) => ({ CallExpression: (node) => {
2116
+ if (unknownJsonSchema({
2117
+ context,
2118
+ node
2119
+ })) context.report({
2120
+ message: "Replace Schema.Unknown with the protocol Schema at this JSON boundary.",
2121
+ node
2122
+ });
2123
+ } }),
2124
+ meta: { type: "problem" }
2125
+ });
2126
+ //#endregion
2127
+ //#region src/rules/schema-type-pair.ts
2128
+ function expressionRoot(node) {
2129
+ if (node.type === "MemberExpression") return expressionRoot(node.object);
2130
+ if (node.type === "CallExpression" && node.callee.type !== "Super") return expressionRoot(node.callee);
2131
+ if (node.type === "ChainExpression") return expressionRoot(node.expression);
2132
+ if (node.type === "TSInstantiationExpression") return expressionRoot(node.expression);
2133
+ if (node.type === "TSSatisfiesExpression") return expressionRoot(node.expression);
2134
+ return node;
2135
+ }
2136
+ function expressionUsesImport(input) {
2137
+ const root = expressionRoot(input.node);
2138
+ return root.type === "Identifier" && isImportBinding({
2139
+ context: input.context,
2140
+ importedName: input.importedName,
2141
+ node: root,
2142
+ source: "effect"
2143
+ });
2144
+ }
2145
+ function schemaDefinitionMember(node) {
2146
+ if (node.type === "CallExpression" && node.callee.type !== "Super") return schemaDefinitionMember(node.callee);
2147
+ if (node.type === "TSInstantiationExpression") return schemaDefinitionMember(node.expression);
2148
+ if (node.type === "TSSatisfiesExpression") return schemaDefinitionMember(node.expression);
2149
+ if (node.type === "MemberExpression") {
2150
+ if (node.object.type === "Identifier") return some(node);
2151
+ if (node.object.type !== "Super") return schemaDefinitionMember(node.object);
2152
+ }
2153
+ return none();
2154
+ }
2155
+ function isSchemaDefinitionName(name) {
2156
+ return !isSchemaOperationName(name) && !/^to[A-Z]/u.test(name);
2157
+ }
2158
+ function isSchemaDefinition(input) {
2159
+ if (input.node.type === "CallExpression" && input.node.callee.type === "Identifier" && isImportBinding({
2160
+ context: input.context,
2161
+ importedName: "pipe",
2162
+ node: input.node.callee,
2163
+ source: "effect"
2164
+ }) && input.node.arguments[0] !== void 0 && input.node.arguments[0].type !== "SpreadElement") return isSchemaDefinition({
2165
+ context: input.context,
2166
+ node: input.node.arguments[0]
2167
+ });
2168
+ if (input.node.type === "TSSatisfiesExpression") return isSchemaDefinition({
2169
+ context: input.context,
2170
+ node: input.node.expression
2171
+ });
2172
+ if (input.node.type === "CallExpression" && input.node.callee.type === "MemberExpression" && !importedMember({
2173
+ context: input.context,
2174
+ importedName: "Schema",
2175
+ node: input.node.callee
2176
+ }) && contains(memberName(input.node.callee), "make")) return false;
2177
+ if (!expressionUsesImport({
2178
+ context: input.context,
2179
+ importedName: "Schema",
2180
+ node: input.node
2181
+ })) return false;
2182
+ return pipe(schemaDefinitionMember(input.node), exists((member) => {
2183
+ if (!importedMember({
2184
+ context: input.context,
2185
+ importedName: "Schema",
2186
+ node: member
2187
+ })) return false;
2188
+ return pipe(memberName(member), exists(isSchemaDefinitionName));
2189
+ }));
2190
+ }
2191
+ function namedTypeAlias(input) {
2192
+ return pipe(input.typeStatement, flatMap(typeAlias), filter((declaration) => declaration.id.name === input.name));
2193
+ }
2194
+ function reportSchemaVariable(input) {
2195
+ if (input.variable.id.type !== "Identifier" || !/^[A-Z]/u.test(input.variable.id.name)) return;
2196
+ if (input.variable.init === null || !isSchemaDefinition({
2197
+ context: input.context,
2198
+ node: input.variable.init
2199
+ })) return;
2200
+ const name = input.variable.id.name;
2201
+ const annotation = input.variable.id.typeAnnotation;
2202
+ const typeStatement = pipe(input.program.body, findFirstIndex((statement) => statement === input.statement), filter((index) => index > 0), flatMap((index) => get$1(input.program.body, index - 1)));
2203
+ if (contains$1(input.cycleNames, name)) {
2204
+ if (!pipe(namedTypeAlias({
2205
+ name,
2206
+ typeStatement
2207
+ }), exists((declaration) => !isInferredType({
2208
+ name,
2209
+ node: declaration.typeAnnotation
2210
+ })))) input.context.report({
2211
+ message: `Write \`type ${name} = ...\` by hand immediately before this recursive Schema; typeof ${name}.Type is circular.`,
2212
+ node: input.variable
2213
+ });
2214
+ if (isNotNullish(annotation)) input.context.report({
2215
+ message: "Annotate the Schema.suspend thunk, not the recursive Schema.",
2216
+ node: input.variable.id
2217
+ });
2218
+ return;
2219
+ }
2220
+ if (!pipe(namedTypeAlias({
2221
+ name,
2222
+ typeStatement
2223
+ }), exists((declaration) => isInferredType({
2224
+ name,
2225
+ node: declaration.typeAnnotation
2226
+ })))) input.context.report({
2227
+ message: `Place \`type ${name} = typeof ${name}.Type\` immediately before this Schema.`,
2228
+ node: input.variable
2229
+ });
2230
+ if (input.variable.init.type === "TSSatisfiesExpression" && schemaSchemaType({
2231
+ context: input.context,
2232
+ node: input.variable.init.typeAnnotation
2233
+ })) input.context.report({
2234
+ message: "Infer this schema instead of restating Schema.Schema.",
2235
+ node: input.variable.init
2236
+ });
2237
+ if (isNotNullish(annotation) && schemaSchemaType({
2238
+ context: input.context,
2239
+ node: annotation.typeAnnotation
2240
+ })) input.context.report({
2241
+ message: "Infer this schema instead of annotating Schema.Schema.",
2242
+ node: input.variable.id
2243
+ });
2244
+ }
2245
+ const schemaTypePair = defineRule({
2246
+ createOnce: (context) => ({ "Program:exit": (program) => {
2247
+ const cycleNames = schemaCycleNames({
2248
+ context,
2249
+ program
2250
+ });
2251
+ for (const statement of program.body) {
2252
+ const declaration = statementDeclaration(statement);
2253
+ if (declaration?.type === "VariableDeclaration") for (const variable of declaration.declarations) reportSchemaVariable({
2254
+ context,
2255
+ cycleNames,
2256
+ program,
2257
+ statement,
2258
+ variable
2259
+ });
2260
+ }
2261
+ } }),
2262
+ meta: { type: "problem" }
2263
+ });
2264
+ //#endregion
2265
+ //#region src/oxlint.ts
2266
+ const reactLegacyApis = [
2267
+ "Component",
2268
+ "PureComponent",
2269
+ "createRef",
2270
+ "forwardRef",
2271
+ "memo",
2272
+ "useCallback",
2273
+ "useMemo"
2274
+ ];
2275
+ const reactLegacyMessage = "Use React 19 function components with refs as props; React Compiler owns memoization.";
2276
+ const mapMessage = "Use HashMap, or MutableHashMap for local mutation; for identity keys, wrap objects the code owns in Equal.byReferenceUnsafe, which marks them reference-compared globally.";
2277
+ const runMessage = "Run the entry point with NodeRuntime.runMain, or bridge a Promise an external contract demands once, where it is returned, with Effect.runPromiseWith(Context.empty()).";
2278
+ const setMessage = "Use HashSet, or MutableHashSet for local mutation; for identity keys, wrap objects the code owns in Equal.byReferenceUnsafe, which marks them reference-compared globally.";
2279
+ const oxlint = defineConfig({
2280
+ categories: {
2281
+ correctness: "off",
2282
+ nursery: "off",
2283
+ pedantic: "off",
2284
+ perf: "off",
2285
+ restriction: "off",
2286
+ style: "off",
2287
+ suspicious: "off"
2288
+ },
2289
+ ignorePatterns: [
2290
+ "**/node_modules/**",
2291
+ "**/dist/**",
2292
+ "**/*.gen.ts"
2293
+ ],
2294
+ jsPlugins: [
2295
+ {
2296
+ name: "@deslop/coding-standards",
2297
+ specifier: import.meta.url
2298
+ },
2299
+ {
2300
+ name: "react-doctor",
2301
+ specifier: import.meta.resolve("oxlint-plugin-react-doctor")
2302
+ },
2303
+ {
2304
+ name: "shadcn",
2305
+ specifier: import.meta.resolve("@shadcn/lint")
2306
+ }
2307
+ ],
2308
+ options: {
2309
+ denyWarnings: true,
2310
+ reportUnusedDisableDirectives: "deny",
2311
+ typeAware: true,
2312
+ typeCheck: true
2313
+ },
2314
+ overrides: [
2315
+ {
2316
+ files: ["**/*.config.ts", "**/main.*"],
2317
+ rules: { "import/no-default-export": "off" }
2318
+ },
2319
+ {
2320
+ files: ["**/components/ui/**"],
2321
+ rules: {
2322
+ "shadcn/no-restyle": "off",
2323
+ "shadcn/require-static-classes": "off"
2324
+ }
2325
+ },
2326
+ {
2327
+ files: ["**/components/ui/**", "**/packages/ui/**"],
2328
+ rules: {
2329
+ "@deslop/coding-standards/no-destructured-parameter": "off",
2330
+ "@deslop/coding-standards/no-renamed-import": "off"
2331
+ }
2332
+ },
2333
+ {
2334
+ files: ["**/*.ts"],
2335
+ rules: { "react/rules-of-hooks": "off" }
2336
+ },
2337
+ {
2338
+ files: ["**/*.tsx"],
2339
+ rules: {
2340
+ "effecttsgo/async-function": "off",
2341
+ "typescript/require-await": "error",
2342
+ "typescript/strict-void-return": "off",
2343
+ "unicorn/no-null": "off"
2344
+ }
2345
+ }
2346
+ ],
2347
+ plugins: [
2348
+ "effecttsgo",
2349
+ "eslint",
2350
+ "typescript",
2351
+ "oxc",
2352
+ "import",
2353
+ "react",
2354
+ "unicorn"
2355
+ ],
2356
+ rules: {
2357
+ "@deslop/coding-standards/no-array-wrap-ternary": "error",
2358
+ "@deslop/coding-standards/no-constant-function": "error",
2359
+ "@deslop/coding-standards/no-deep-pipe": "error",
2360
+ "@deslop/coding-standards/no-destructured-parameter": "error",
2361
+ "@deslop/coding-standards/no-double-nullish-check": "error",
2362
+ "@deslop/coding-standards/no-effect-property-arrow": "error",
2363
+ "@deslop/coding-standards/no-error-message-assertion": "error",
2364
+ "@deslop/coding-standards/no-fail-in-generator": "error",
2365
+ "@deslop/coding-standards/no-fake-ref-state": "error",
2366
+ "@deslop/coding-standards/no-hand-written-guard": "error",
2367
+ "@deslop/coding-standards/no-let": "error",
2368
+ "@deslop/coding-standards/no-native-emptiness-check": "error",
2369
+ "@deslop/coding-standards/no-native-method-call": "error",
2370
+ "@deslop/coding-standards/no-option-value-access": "error",
2371
+ "@deslop/coding-standards/no-readonly-type-syntax": "error",
2372
+ "@deslop/coding-standards/no-redundant-return-type": "error",
2373
+ "@deslop/coding-standards/no-redundant-state-type": "error",
2374
+ "@deslop/coding-standards/no-redundant-use-ref-null-type": "error",
2375
+ "@deslop/coding-standards/no-redundant-variable-annotation": "error",
2376
+ "@deslop/coding-standards/no-reinvented-schema": "error",
2377
+ "@deslop/coding-standards/no-renamed-import": "error",
2378
+ "@deslop/coding-standards/no-stored-schema-operation": "error",
2379
+ "@deslop/coding-standards/no-switch-statement": "error",
2380
+ "@deslop/coding-standards/no-trivial-indirection": "error",
2381
+ "@deslop/coding-standards/no-typeof": "error",
2382
+ "@deslop/coding-standards/no-undestructured-use-state": "error",
2383
+ "@deslop/coding-standards/no-unexplained-disable": "error",
2384
+ "@deslop/coding-standards/no-unvalidated-json-decode": "error",
2385
+ "@deslop/coding-standards/schema-type-pair": "error",
2386
+ "effecttsgo/abort-controller-in-effect": "error",
2387
+ "effecttsgo/crypto-random-uuid": "error",
2388
+ "effecttsgo/crypto-random-uuid-in-effect": "error",
2389
+ "effecttsgo/global-console": "error",
2390
+ "effecttsgo/global-console-in-effect": "error",
2391
+ "effecttsgo/global-date": "error",
2392
+ "effecttsgo/global-date-in-effect": "error",
2393
+ "effecttsgo/global-fetch": "error",
2394
+ "effecttsgo/global-fetch-in-effect": "error",
2395
+ "effecttsgo/global-random": "error",
2396
+ "effecttsgo/global-random-in-effect": "error",
2397
+ "effecttsgo/global-timers": "error",
2398
+ "effecttsgo/global-timers-in-effect": "error",
2399
+ "effecttsgo/node-builtin-import": "error",
2400
+ "effecttsgo/prefer-schema-over-json": "error",
2401
+ "effecttsgo/process-env": "error",
2402
+ "effecttsgo/process-env-in-effect": "error",
2403
+ "effecttsgo/acquire-release-disposable": "error",
2404
+ "effecttsgo/all-of-map-to-for-each": "error",
2405
+ "effecttsgo/async-function": "error",
2406
+ "effecttsgo/catch-if-tag-to-catch-tag": "error",
2407
+ "effecttsgo/catch-refail-to-tap-error": "error",
2408
+ "effecttsgo/duplicate-package": "error",
2409
+ "effecttsgo/effect-do-notation": "error",
2410
+ "effecttsgo/effect-fn-iife": "error",
2411
+ "effecttsgo/effect-fn-implicit-any": "error",
2412
+ "effecttsgo/effect-fn-opportunity": "error",
2413
+ "effecttsgo/effect-gen-uses-adapter": "error",
2414
+ "effecttsgo/effect-in-failure": "error",
2415
+ "effecttsgo/effect-in-void-success": "error",
2416
+ "effecttsgo/effect-map-flatten": "error",
2417
+ "effecttsgo/effect-map-void": "error",
2418
+ "effecttsgo/effect-succeed-with-void": "error",
2419
+ "effecttsgo/flat-map-ignored-param-to-and-then": "error",
2420
+ "effecttsgo/flat-map-to-map": "error",
2421
+ "effecttsgo/floating-effect": "error",
2422
+ "effecttsgo/floating-effect-in-vitest": "error",
2423
+ "effecttsgo/layer-merge-all-with-dependencies": "error",
2424
+ "effecttsgo/lazy-effect": "error",
2425
+ "effecttsgo/lazy-promise-in-effect-sync": "error",
2426
+ "effecttsgo/leaking-requirements": "error",
2427
+ "effecttsgo/map-some-to-as-some": "error",
2428
+ "effecttsgo/match-effect-to-map-both": "error",
2429
+ "effecttsgo/match-effect-to-match": "error",
2430
+ "effecttsgo/missing-effect-context": "error",
2431
+ "effecttsgo/missing-layer-context": "error",
2432
+ "effecttsgo/missing-return-yield-star": "error",
2433
+ "effecttsgo/missing-star-in-yield-effect-gen": "error",
2434
+ "effecttsgo/multiple-effect-provide": "error",
2435
+ "effecttsgo/nested-effect-gen-yield": "error",
2436
+ "effecttsgo/option-match-to-from-option": "error",
2437
+ "effecttsgo/outdated-api": "error",
2438
+ "effecttsgo/prefer-succeed-some-or-none": "error",
2439
+ "effecttsgo/promise-in-effect-success": "error",
2440
+ "effecttsgo/provide-layer-succeed-to-provide-service": "error",
2441
+ "effecttsgo/race-first-with-sleep-to-timeout": "error",
2442
+ "effecttsgo/return-effect-in-gen": "error",
2443
+ "effecttsgo/run-effect-inside-effect": "error",
2444
+ "effecttsgo/run-of-exit-to-run-exit": "error",
2445
+ "effecttsgo/strict-effect-provide": "error",
2446
+ "effecttsgo/sync-to-succeed": "error",
2447
+ "effecttsgo/try-catch-in-effect-gen": "error",
2448
+ "effecttsgo/unnecessary-effect-gen": "error",
2449
+ "effecttsgo/unnecessary-fail-yieldable-error": "error",
2450
+ "effecttsgo/unnecessary-pipe": "error",
2451
+ "effecttsgo/unnecessary-pipe-chain": "error",
2452
+ "effecttsgo/unsafe-effect-type-assertion": "error",
2453
+ "effecttsgo/any-unknown-in-error-context": "error",
2454
+ "effecttsgo/catch-all-tag-dispatch-to-catch-tag": "error",
2455
+ "effecttsgo/catch-all-to-map-error": "error",
2456
+ "effecttsgo/catch-chain-to-first-success-of": "error",
2457
+ "effecttsgo/catch-conditional-refail-to-catch-if": "error",
2458
+ "effecttsgo/catch-die-to-or-die": "error",
2459
+ "effecttsgo/catch-tag-to-catch-reason": "error",
2460
+ "effecttsgo/catch-to-ignore": "error",
2461
+ "effecttsgo/catch-to-or-else-succeed": "error",
2462
+ "effecttsgo/catch-unfailable-effect": "error",
2463
+ "effecttsgo/flat-map-conditional-to-filter-or-fail": "error",
2464
+ "effecttsgo/global-error-in-effect-catch": "error",
2465
+ "effecttsgo/global-error-in-effect-failure": "error",
2466
+ "effecttsgo/missing-effect-error": "error",
2467
+ "effecttsgo/multiple-catch-tag": "error",
2468
+ "effecttsgo/redundant-map-error": "error",
2469
+ "effecttsgo/redundant-or-die": "error",
2470
+ "effecttsgo/timeout-catch-tag-to-timeout-or-else": "error",
2471
+ "effecttsgo/unknown-in-effect-catch": "error",
2472
+ "effecttsgo/class-self-mismatch": "error",
2473
+ "effecttsgo/deterministic-keys": "error",
2474
+ "effecttsgo/generic-effect-services": "error",
2475
+ "effecttsgo/instance-of-schema": "error",
2476
+ "effecttsgo/new-schema-class": "error",
2477
+ "effecttsgo/obsolete-match-import": "error",
2478
+ "effecttsgo/obsolete-schema-import": "error",
2479
+ "effecttsgo/overridden-schema-constructor": "error",
2480
+ "effecttsgo/prefer-schema-type-property": "error",
2481
+ "effecttsgo/prefer-typed-schema-decoder": "error",
2482
+ "effecttsgo/redundant-schema-tag-identifier": "error",
2483
+ "effecttsgo/schema-literal-non-finite": "error",
2484
+ "effecttsgo/schema-number": "error",
2485
+ "effecttsgo/schema-struct-with-tag": "error",
2486
+ "effecttsgo/schema-sync-in-effect": "error",
2487
+ "effecttsgo/service-not-as-class": "error",
2488
+ "effecttsgo/unnecessary-typeof-type": "error",
2489
+ "typescript/consistent-generic-constructors": "error",
2490
+ "typescript/consistent-indexed-object-style": "error",
2491
+ "typescript/consistent-type-assertions": ["error", {
2492
+ arrayLiteralTypeAssertions: "never",
2493
+ assertionStyle: "never",
2494
+ objectLiteralTypeAssertions: "never"
2495
+ }],
2496
+ "typescript/consistent-type-definitions": ["error", "type"],
2497
+ "typescript/consistent-type-exports": "error",
2498
+ "typescript/consistent-type-imports": ["error", {
2499
+ fixStyle: "separate-type-imports",
2500
+ prefer: "type-imports"
2501
+ }],
2502
+ "typescript/method-signature-style": "error",
2503
+ "typescript/prefer-function-type": "error",
2504
+ "typescript/await-thenable": "error",
2505
+ "typescript/no-array-delete": "error",
2506
+ "typescript/no-base-to-string": "error",
2507
+ "typescript/no-confusing-void-expression": ["error", { ignoreVoidReturningFunctions: true }],
2508
+ "typescript/no-deprecated": "error",
2509
+ "typescript/no-duplicate-type-constituents": "error",
2510
+ "typescript/no-dynamic-delete": "error",
2511
+ "typescript/no-empty-object-type": "error",
2512
+ "typescript/no-explicit-any": "error",
2513
+ "typescript/no-floating-promises": "error",
2514
+ "typescript/no-import-type-side-effects": "error",
2515
+ "typescript/no-inferrable-types": "error",
2516
+ "typescript/no-invalid-void-type": "error",
2517
+ "typescript/no-misused-promises": ["error", { checksVoidReturn: false }],
2518
+ "typescript/no-misused-spread": "error",
2519
+ "typescript/no-namespace": ["error", { allowDeclarations: true }],
2520
+ "typescript/no-non-null-assertion": "error",
2521
+ "typescript/no-redundant-type-constituents": "error",
2522
+ "typescript/no-require-imports": "error",
2523
+ "typescript/no-this-alias": "error",
2524
+ "typescript/no-unnecessary-boolean-literal-compare": "error",
2525
+ "typescript/no-unnecessary-condition": "error",
2526
+ "typescript/no-unnecessary-qualifier": "error",
2527
+ "typescript/no-unnecessary-template-expression": "error",
2528
+ "typescript/no-unnecessary-type-arguments": "error",
2529
+ "typescript/no-unnecessary-type-constraint": "error",
2530
+ "typescript/no-unnecessary-type-conversion": "error",
2531
+ "typescript/no-unnecessary-type-parameters": "error",
2532
+ "typescript/no-unsafe-argument": "error",
2533
+ "typescript/no-unsafe-assignment": "error",
2534
+ "typescript/no-unsafe-call": "error",
2535
+ "typescript/no-unsafe-declaration-merging": "error",
2536
+ "typescript/no-unsafe-function-type": "error",
2537
+ "typescript/no-unsafe-member-access": "error",
2538
+ "typescript/no-unsafe-return": "error",
2539
+ "typescript/no-useless-empty-export": "error",
2540
+ "typescript/no-wrapper-object-types": "error",
2541
+ "typescript/unbound-method": "error",
2542
+ "typescript/unified-signatures": "error",
2543
+ "typescript/prefer-as-const": "error",
2544
+ "typescript/prefer-nullish-coalescing": "error",
2545
+ "typescript/prefer-optional-chain": "error",
2546
+ "typescript/restrict-plus-operands": "error",
2547
+ "typescript/restrict-template-expressions": "error",
2548
+ "typescript/strict-boolean-expressions": ["error", {
2549
+ allowNumber: false,
2550
+ allowString: false
2551
+ }],
2552
+ "typescript/strict-void-return": "error",
2553
+ "arrow-body-style": ["error", "as-needed"],
2554
+ curly: [
2555
+ "error",
2556
+ "multi-line",
2557
+ "consistent"
2558
+ ],
2559
+ eqeqeq: "error",
2560
+ "func-names": [
2561
+ "error",
2562
+ "as-needed",
2563
+ { generators: "never" }
2564
+ ],
2565
+ "func-style": ["error", "declaration"],
2566
+ "import/newline-after-import": "error",
2567
+ "import/no-absolute-path": "error",
2568
+ "import/no-commonjs": "error",
2569
+ "import/no-default-export": "error",
2570
+ "import/no-duplicates": "error",
2571
+ "import/no-empty-named-blocks": "error",
2572
+ "import/no-mutable-exports": "error",
2573
+ "import/no-namespace": ["error", { ignore: ["[!#./]*", "[!#./]*/**"] }],
2574
+ "import/no-relative-parent-imports": "error",
2575
+ "no-restricted-imports": ["error", {
2576
+ paths: [
2577
+ {
2578
+ importNames: reactLegacyApis,
2579
+ message: reactLegacyMessage,
2580
+ name: "react"
2581
+ },
2582
+ {
2583
+ importNames: ["vi"],
2584
+ message: "A Layer is the seam; never use vi.",
2585
+ name: "vitest"
2586
+ },
2587
+ {
2588
+ importNames: ["vi"],
2589
+ message: "A Layer is the seam; never use vi.",
2590
+ name: "@effect/vitest"
2591
+ },
2592
+ {
2593
+ importNames: ["expect"],
2594
+ message: "Use assert from @effect/vitest.",
2595
+ name: "vitest"
2596
+ },
2597
+ {
2598
+ importNames: ["expect"],
2599
+ message: "Use assert from @effect/vitest.",
2600
+ name: "@effect/vitest"
2601
+ }
2602
+ ],
2603
+ patterns: [
2604
+ {
2605
+ message: "Use public package exports.",
2606
+ regex: "^@[^/]+/[^/]+/(?:src|lib)(?:/|$)"
2607
+ },
2608
+ {
2609
+ message: "Use glob from the FileSystem service.",
2610
+ regex: "^glob(?:/|$)"
2611
+ },
2612
+ {
2613
+ message: "Use effect/cli.",
2614
+ regex: "^(?:commander|yargs)(?:/|$)"
2615
+ },
2616
+ {
2617
+ message: "Use randomUUIDv4 from the Crypto service.",
2618
+ regex: "^uuid(?:/|$)"
2619
+ },
2620
+ {
2621
+ message: "Use HttpClient.",
2622
+ regex: "^(?:axios|node-fetch)(?:/|$)"
2623
+ },
2624
+ {
2625
+ message: "Use Config.",
2626
+ regex: "^dotenv(?:/|$)"
2627
+ },
2628
+ {
2629
+ message: "Use ChildProcess from effect/process.",
2630
+ regex: "^execa(?:/|$)"
2631
+ },
2632
+ {
2633
+ message: "Use the concurrency option of Effect.all or Effect.forEach.",
2634
+ regex: "^p-limit(?:/|$)"
2635
+ }
2636
+ ]
2637
+ }],
2638
+ "max-depth": ["error", 3],
2639
+ "max-nested-callbacks": ["error", 6],
2640
+ "no-cond-assign": "error",
2641
+ "no-continue": "error",
2642
+ "no-control-regex": "error",
2643
+ "no-debugger": "error",
2644
+ "no-else-return": "error",
2645
+ "no-empty-function": ["error", { allow: ["arrowFunctions"] }],
2646
+ "no-eval": "error",
2647
+ "no-extend-native": "error",
2648
+ "no-extra-bind": "error",
2649
+ "no-extra-boolean-cast": "error",
2650
+ "no-implied-eval": "error",
2651
+ "no-invalid-regexp": "error",
2652
+ "no-iterator": "error",
2653
+ "no-lonely-if": "error",
2654
+ "no-misleading-character-class": "error",
2655
+ "no-multi-assign": "error",
2656
+ "no-negated-condition": "error",
2657
+ "no-nested-ternary": "error",
2658
+ "no-new": "error",
2659
+ "no-param-reassign": ["error", { props: true }],
2660
+ "no-plusplus": "error",
2661
+ "no-proto": "error",
2662
+ "no-restricted-exports": ["error", { restrictedNamedExportsPattern: "Live$" }],
2663
+ "no-restricted-globals": [
2664
+ "error",
2665
+ {
2666
+ message: "Interrupt through Effect: a fiber, Effect.timeout, or a Scope.",
2667
+ name: "AbortController"
2668
+ },
2669
+ {
2670
+ message: "Import Array from 'effect'.",
2671
+ name: "Array"
2672
+ },
2673
+ {
2674
+ message: "Import Boolean from 'effect'.",
2675
+ name: "Boolean"
2676
+ },
2677
+ {
2678
+ message: "Define a Schema.TaggedError and fail with it.",
2679
+ name: "Error"
2680
+ },
2681
+ {
2682
+ message: mapMessage,
2683
+ name: "Map"
2684
+ },
2685
+ {
2686
+ message: "Import Number from 'effect'.",
2687
+ name: "Number"
2688
+ },
2689
+ {
2690
+ message: "Use Record or Struct from 'effect'.",
2691
+ name: "Object"
2692
+ },
2693
+ {
2694
+ message: "Use Number.parse.",
2695
+ name: "parseFloat"
2696
+ },
2697
+ {
2698
+ message: "Use Number.parse.",
2699
+ name: "parseInt"
2700
+ },
2701
+ {
2702
+ message: "Use Effect: Effect.tryPromise at the boundary, Effect.all to combine.",
2703
+ name: "Promise"
2704
+ },
2705
+ {
2706
+ message: "Use Predicate or Record from 'effect'.",
2707
+ name: "Reflect"
2708
+ },
2709
+ {
2710
+ message: setMessage,
2711
+ name: "Set"
2712
+ },
2713
+ {
2714
+ message: "Import String from 'effect'.",
2715
+ name: "String"
2716
+ },
2717
+ {
2718
+ message: "Read configuration with Config and services from the context.",
2719
+ name: "global"
2720
+ },
2721
+ {
2722
+ message: "Read configuration with Config and services from the context.",
2723
+ name: "globalThis"
2724
+ }
2725
+ ],
2726
+ "no-restricted-properties": [
2727
+ "error",
2728
+ {
2729
+ message: "Use standalone pipe.",
2730
+ property: "pipe"
2731
+ },
2732
+ {
2733
+ allowObjects: ["Predicate"],
2734
+ message: "Use Predicate.hasProperty.",
2735
+ property: "hasOwnProperty"
2736
+ },
2737
+ {
2738
+ message: runMessage,
2739
+ object: "Effect",
2740
+ property: "runFork"
2741
+ },
2742
+ {
2743
+ message: runMessage,
2744
+ object: "Effect",
2745
+ property: "runPromise"
2746
+ },
2747
+ {
2748
+ message: runMessage,
2749
+ object: "Effect",
2750
+ property: "runPromiseExit"
2751
+ },
2752
+ {
2753
+ message: runMessage,
2754
+ object: "Effect",
2755
+ property: "runSync"
2756
+ },
2757
+ {
2758
+ message: runMessage,
2759
+ object: "Effect",
2760
+ property: "runSyncExit"
2761
+ },
2762
+ {
2763
+ message: runMessage,
2764
+ object: "ManagedRuntime",
2765
+ property: "make"
2766
+ },
2767
+ {
2768
+ message: "Use Number.max.",
2769
+ object: "Math",
2770
+ property: "max"
2771
+ },
2772
+ {
2773
+ message: "Use Number.min.",
2774
+ object: "Math",
2775
+ property: "min"
2776
+ },
2777
+ {
2778
+ message: "Use Number.round.",
2779
+ object: "Math",
2780
+ property: "round"
2781
+ },
2782
+ ...map$1(reactLegacyApis, (property) => ({
2783
+ message: reactLegacyMessage,
2784
+ object: "React",
2785
+ property
2786
+ })),
2787
+ {
2788
+ message: "Use Schema.Struct.",
2789
+ object: "Schema",
2790
+ property: "Class"
2791
+ },
2792
+ {
2793
+ message: "Use a branded schema.",
2794
+ object: "Schema",
2795
+ property: "Opaque"
2796
+ },
2797
+ {
2798
+ message: "Use Schema.Struct.",
2799
+ object: "Schema",
2800
+ property: "TaggedClass"
2801
+ },
2802
+ {
2803
+ message: "Use Schema.Struct.",
2804
+ object: "Data",
2805
+ property: "Class"
2806
+ },
2807
+ {
2808
+ message: "Use Schema.TaggedError.",
2809
+ object: "Data",
2810
+ property: "Error"
2811
+ },
2812
+ {
2813
+ message: "Use Schema.Struct.",
2814
+ object: "Data",
2815
+ property: "TaggedClass"
2816
+ },
2817
+ {
2818
+ message: "Use Schema.TaggedError.",
2819
+ object: "Data",
2820
+ property: "TaggedError"
2821
+ },
2822
+ ...map$1([
2823
+ "addEventListener",
2824
+ "atob",
2825
+ "btoa",
2826
+ "cancelAnimationFrame",
2827
+ "cancelIdleCallback",
2828
+ "dispatchEvent",
2829
+ "localStorage",
2830
+ "navigator",
2831
+ "queueMicrotask",
2832
+ "removeEventListener",
2833
+ "requestAnimationFrame",
2834
+ "requestIdleCallback",
2835
+ "sessionStorage",
2836
+ "structuredClone"
2837
+ ], (property) => ({
2838
+ message: `Use the bare ${property} global.`,
2839
+ object: "window",
2840
+ property
2841
+ })),
2842
+ ...map$1([
2843
+ "clearInterval",
2844
+ "clearTimeout",
2845
+ "setInterval",
2846
+ "setTimeout"
2847
+ ], (property) => ({
2848
+ message: "Use Effect.sleep or Schedule.",
2849
+ object: "window",
2850
+ property
2851
+ })),
2852
+ {
2853
+ message: "Use Console.",
2854
+ object: "window",
2855
+ property: "console"
2856
+ },
2857
+ {
2858
+ message: "Use the Crypto service.",
2859
+ object: "window",
2860
+ property: "crypto"
2861
+ },
2862
+ {
2863
+ message: "Use HttpClient.",
2864
+ object: "window",
2865
+ property: "fetch"
2866
+ },
2867
+ {
2868
+ message: "Use Clock.",
2869
+ object: "window",
2870
+ property: "performance"
2871
+ }
2872
+ ],
2873
+ "no-self-assign": "error",
2874
+ "no-shadow": ["error", { allow: [
2875
+ "Array",
2876
+ "Boolean",
2877
+ "Console",
2878
+ "Effect",
2879
+ "HashMap",
2880
+ "Number",
2881
+ "Option",
2882
+ "Schema",
2883
+ "String"
2884
+ ] }],
2885
+ "no-sparse-arrays": "error",
2886
+ "no-throw-literal": "error",
2887
+ "no-unmodified-loop-condition": "error",
2888
+ "no-unneeded-ternary": "error",
2889
+ "no-unreachable-loop": "error",
2890
+ "no-unsafe-finally": "error",
2891
+ "no-unused-expressions": "error",
2892
+ "no-useless-assignment": "error",
2893
+ "no-useless-backreference": "error",
2894
+ "no-useless-call": "error",
2895
+ "no-useless-catch": "error",
2896
+ "no-useless-computed-key": "error",
2897
+ "no-useless-concat": "error",
2898
+ "no-useless-constructor": "error",
2899
+ "no-useless-escape": "error",
2900
+ "no-useless-rename": "error",
2901
+ "no-useless-return": "error",
2902
+ "no-void": "error",
2903
+ "object-shorthand": "error",
2904
+ "oxc/branches-sharing-code": "error",
2905
+ "oxc/no-accumulating-spread": "error",
2906
+ "oxc/no-map-spread": "error",
2907
+ "oxc/only-used-in-recursion": "error",
2908
+ "prefer-arrow-callback": "error",
2909
+ "prefer-const": ["error", { destructuring: "all" }],
2910
+ "prefer-template": "error",
2911
+ "require-unicode-regexp": "error",
2912
+ "react-doctor/no-call-component-as-function": "error",
2913
+ "react-doctor/no-create-context-in-render": "error",
2914
+ "react-doctor/no-default-props": "error",
2915
+ "react-doctor/no-inline-exhaustive-style": "error",
2916
+ "react-doctor/no-jsx-element-type": "error",
2917
+ "react-doctor/no-many-boolean-props": "error",
2918
+ "react-doctor/no-prop-types": "error",
2919
+ "react-doctor/no-uncontrolled-input": "error",
2920
+ "react-doctor/shadcn-icon-button-requires-label": "error",
2921
+ "react-doctor/effect-listener-cleanup-mismatch": "error",
2922
+ "react-doctor/no-async-effect-callback": "error",
2923
+ "react-doctor/no-create-object-url-without-revoke": "error",
2924
+ "react-doctor/no-derived-useState": "error",
2925
+ "react-doctor/no-effect-event-in-deps": "error",
2926
+ "react-doctor/no-effect-with-fresh-deps": "error",
2927
+ "react-doctor/no-effect-wrapper-discards-callback-cleanup-return": "error",
2928
+ "react-doctor/no-impure-state-updater": "error",
2929
+ "react-doctor/no-mutable-in-deps": "error",
2930
+ "react-doctor/no-mutating-reducer-state": "error",
2931
+ "react-doctor/no-self-updating-effect": "error",
2932
+ "react-doctor/no-set-state-in-render": "error",
2933
+ "react-doctor/no-stale-timer-ref": "error",
2934
+ "react-doctor/prefer-use-effect-event": "error",
2935
+ "react-doctor/rerender-functional-setstate": "error",
2936
+ "react-doctor/rerender-lazy-ref-init": "error",
2937
+ "react-doctor/rerender-lazy-state-init": "error",
2938
+ "react-doctor/no-enter-submit-without-ime-composition-guard": "error",
2939
+ "react-doctor/no-event-handler": "error",
2940
+ "react-doctor/no-flush-sync": "error",
2941
+ "react-doctor/no-render-in-render": "error",
2942
+ "react-doctor/rendering-conditional-render": "error",
2943
+ "react-doctor/design-no-redundant-padding-axes": "error",
2944
+ "react-doctor/design-no-redundant-size-axes": "error",
2945
+ "react-doctor/no-global-css-variable-animation": "error",
2946
+ "react-doctor/no-gray-on-colored-background": "error",
2947
+ "react-doctor/no-inline-bounce-easing": "error",
2948
+ "react-doctor/no-large-animated-blur": "error",
2949
+ "react-doctor/no-layout-property-animation": "error",
2950
+ "react-doctor/no-layout-transition-inline": "error",
2951
+ "react-doctor/no-long-transition-duration": "error",
2952
+ "react-doctor/no-outline-none": "error",
2953
+ "react-doctor/no-scale-from-zero": "error",
2954
+ "react-doctor/no-transition-all": "error",
2955
+ "react/button-has-type": "error",
2956
+ "react/checked-requires-onchange-or-readonly": "error",
2957
+ "react/exhaustive-deps": "error",
2958
+ "react/iframe-missing-sandbox": "error",
2959
+ "react/immutability": "error",
2960
+ "react/incompatible-library": "error",
2961
+ "react/jsx-boolean-value": ["error", "never"],
2962
+ "react/jsx-curly-brace-presence": ["error", {
2963
+ children: "never",
2964
+ propElementValues: "always",
2965
+ props: "never"
2966
+ }],
2967
+ "react/jsx-fragments": ["error", "syntax"],
2968
+ "react/jsx-key": "error",
2969
+ "react/jsx-no-script-url": "error",
2970
+ "react/jsx-no-target-blank": "error",
2971
+ "react/jsx-no-useless-fragment": "error",
2972
+ "react/memo-dependencies": "error",
2973
+ "react/no-array-index-key": "error",
2974
+ "react/no-children-prop": "error",
2975
+ "react/no-clone-element": "error",
2976
+ "react/no-danger": "error",
2977
+ "react/no-object-type-as-default-prop": "error",
2978
+ "react/no-react-children": "error",
2979
+ "react/no-unknown-property": "error",
2980
+ "react/no-unstable-nested-components": ["error", { allowAsProps: true }],
2981
+ "react/preserve-manual-memoization": "error",
2982
+ "react/purity": "error",
2983
+ "react/refs": "error",
2984
+ "react/rules-of-hooks": "error",
2985
+ "react/self-closing-comp": "error",
2986
+ "react/set-state-in-effect": "error",
2987
+ "react/set-state-in-render": "error",
2988
+ "react/static-components": "error",
2989
+ "react/use-memo": "error",
2990
+ "react/void-dom-elements-no-children": "error",
2991
+ "react/void-use-memo": "error",
2992
+ "shadcn/no-arbitrary-values": "error",
2993
+ "shadcn/no-inline-styles": "error",
2994
+ "shadcn/no-raw-colors": "error",
2995
+ "shadcn/no-restyle": ["error", { allow: ["layout"] }],
2996
+ "shadcn/no-unknown-classes": "error",
2997
+ "shadcn/require-static-classes": "error",
2998
+ "sort-keys": [
2999
+ "error",
3000
+ "asc",
3001
+ {
3002
+ allowLineSeparatedGroups: true,
3003
+ natural: true
3004
+ }
3005
+ ],
3006
+ "typescript/ban-ts-comment": ["error", { "ts-nocheck": true }],
3007
+ "typescript/no-restricted-types": ["error", { types: {
3008
+ AbortController: "Use Effect interruption.",
3009
+ Array: "Use T[].",
3010
+ Date: "Use DateTime.",
3011
+ Error: "Use Schema.TaggedError.",
3012
+ Iterable: "Use T[].",
3013
+ Map: mapMessage,
3014
+ Promise: "Use Effect.",
3015
+ ReadonlyArray: "Use T[].",
3016
+ ReadonlyMap: mapMessage,
3017
+ ReadonlySet: setMessage,
3018
+ Set: setMessage,
3019
+ undefined: "Use an optional property or parameter, or let inference supply undefined."
3020
+ } }],
3021
+ "typescript/no-unnecessary-type-assertion": "error",
3022
+ "typescript/no-useless-default-assignment": "error",
3023
+ "unicorn/filename-case": "error",
3024
+ "unicorn/no-immediate-mutation": "error",
3025
+ "unicorn/no-null": "error",
3026
+ "unicorn/no-object-as-default-parameter": "error",
3027
+ "unicorn/no-process-exit": "error",
3028
+ "unicorn/no-static-only-class": "error",
3029
+ "unicorn/no-useless-fallback-in-spread": "error",
3030
+ "unicorn/no-useless-length-check": "error",
3031
+ "unicorn/no-useless-spread": "error",
3032
+ "unicorn/prefer-logical-operator-over-ternary": "error",
3033
+ "unicorn/prefer-optional-catch-binding": "error",
3034
+ "use-isnan": "error"
3035
+ },
3036
+ settings: {
3037
+ react: { version: "19.0" },
3038
+ shadcn: { ui: ["@deslop/components/ui", "@dual/ui/components"] }
3039
+ }
3040
+ });
3041
+ var oxlint_default = definePlugin({
3042
+ meta: { name: "@deslop/coding-standards" },
3043
+ rules: {
3044
+ "no-array-wrap-ternary": noArrayWrapTernary,
3045
+ "no-constant-function": noConstantFunction,
3046
+ "no-deep-pipe": noDeepPipe,
3047
+ "no-destructured-parameter": noDestructuredParameter,
3048
+ "no-double-nullish-check": noDoubleNullishCheck,
3049
+ "no-effect-property-arrow": noEffectPropertyArrow,
3050
+ "no-error-message-assertion": noErrorMessageAssertion,
3051
+ "no-fail-in-generator": noFailInGenerator,
3052
+ "no-fake-ref-state": noFakeRefState,
3053
+ "no-hand-written-guard": noHandWrittenGuard,
3054
+ "no-let": noLet,
3055
+ "no-native-emptiness-check": noNativeEmptinessCheck,
3056
+ "no-native-method-call": noNativeMethodCall,
3057
+ "no-option-value-access": noOptionValueAccess,
3058
+ "no-readonly-type-syntax": noReadonlyTypeSyntax,
3059
+ "no-redundant-return-type": noRedundantReturnType,
3060
+ "no-redundant-state-type": noRedundantStateType,
3061
+ "no-redundant-use-ref-null-type": noRedundantUseRefNullType,
3062
+ "no-redundant-variable-annotation": noRedundantVariableAnnotation,
3063
+ "no-reinvented-schema": noReinventedSchema,
3064
+ "no-renamed-import": noRenamedImport,
3065
+ "no-stored-schema-operation": noStoredSchemaOperation,
3066
+ "no-switch-statement": noSwitchStatement,
3067
+ "no-trivial-indirection": noTrivialIndirection,
3068
+ "no-typeof": noTypeof,
3069
+ "no-undestructured-use-state": noUndestructuredUseState,
3070
+ "no-unexplained-disable": noUnexplainedDisable,
3071
+ "no-unvalidated-json-decode": noUnvalidatedJsonDecode,
3072
+ "schema-type-pair": schemaTypePair
3073
+ }
3074
+ });
3075
+ //#endregion
3076
+ export { oxlint_default as default, oxlint };