adamantite 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +393 -35
  2. package/dist/index.js +47 -28
  3. package/dist/presets/analyze.d.ts +6 -2
  4. package/dist/presets/analyze.js +7 -1
  5. package/dist/presets/lint/core.d.ts +5 -3
  6. package/dist/presets/lint/core.js +1 -0
  7. package/dist/presets/lint/custom.d.ts +60 -0
  8. package/dist/presets/lint/custom.js +142 -0
  9. package/dist/presets/lint/effect.d.ts +5 -0
  10. package/dist/presets/lint/effect.js +106 -0
  11. package/dist/presets/lint/plugin/imports.d.ts +19 -0
  12. package/dist/presets/lint/plugin/imports.js +53 -0
  13. package/dist/presets/lint/plugin/index.d.ts +17 -0
  14. package/dist/presets/lint/plugin/index.js +20 -0
  15. package/dist/presets/lint/plugin/options.d.ts +11 -0
  16. package/dist/presets/lint/plugin/options.js +33 -0
  17. package/dist/presets/lint/plugin/rules/no-overzealous-destructuring.d.ts +5 -0
  18. package/dist/presets/lint/plugin/rules/no-overzealous-destructuring.js +92 -0
  19. package/dist/presets/lint/plugin/rules/no-query-data-in-state.d.ts +5 -0
  20. package/dist/presets/lint/plugin/rules/no-query-data-in-state.js +85 -0
  21. package/dist/presets/lint/plugin/rules/no-react-state-hooks.d.ts +10 -0
  22. package/dist/presets/lint/plugin/rules/no-react-state-hooks.js +128 -0
  23. package/dist/presets/lint/plugin/rules/query-from-loader.d.ts +5 -0
  24. package/dist/presets/lint/plugin/rules/query-from-loader.js +110 -0
  25. package/dist/presets/lint/react-doctor.d.ts +5 -0
  26. package/dist/presets/lint/react-doctor.js +20 -0
  27. package/dist/presets/lint/react-strict.d.ts +5 -0
  28. package/dist/presets/lint/react-strict.js +11 -0
  29. package/dist/presets/lint/shadcn.d.ts +5 -0
  30. package/dist/presets/lint/shadcn.js +22 -0
  31. package/dist/presets/lint/strict.d.ts +5 -0
  32. package/dist/presets/lint/strict.js +18 -0
  33. package/dist/presets/lint/tanstack.d.ts +5 -0
  34. package/dist/presets/lint/tanstack.js +14 -0
  35. package/dist/presets/lint/vendor/antislop/plugin.d.mts +18 -2
  36. package/dist/presets/rules/index.d.ts +9 -0
  37. package/dist/presets/rules/index.js +29 -0
  38. package/package.json +31 -22
  39. package/skills/adamantite/SKILL.md +105 -11
@@ -0,0 +1,10 @@
1
+ import { Rule } from "@oxlint/plugins";
2
+ //#region presets/lint/plugin/rules/no-react-state-hooks.d.ts
3
+ /**
4
+ * Convert a glob to a regular expression that matches a whole path with forward slashes. Supports
5
+ * `**`, `*`, `?`, `[a-z]` and `[!a-z]` character classes, and `{a,b}` alternation.
6
+ */
7
+ export declare function globToRegExp(glob: string): RegExp;
8
+ declare const rule: Rule;
9
+ //#endregion
10
+ export { rule as default };
@@ -0,0 +1,128 @@
1
+ import { findImportedCalls } from "../imports.js";
2
+ import { readStringArrayOption } from "../options.js";
3
+ //#region presets/lint/plugin/rules/no-react-state-hooks.ts
4
+ const HOOK_MESSAGES = /* @__PURE__ */ new Map([
5
+ ["useCallback", "memoization"],
6
+ ["useEffect", "effect"],
7
+ ["useLayoutEffect", "effect"],
8
+ ["useMemo", "memoization"],
9
+ ["useReducer", "localState"],
10
+ ["useState", "localState"],
11
+ ["useSyncExternalStore", "externalStore"]
12
+ ]);
13
+ const DEFAULT_HOOKS = [...HOOK_MESSAGES.keys()];
14
+ /**
15
+ * Modules where hooks are permitted: hook modules such as `useCart.ts` or `use-cart.ts`, and
16
+ * everything under a `hooks` directory. Everything else is feature code, including files such as
17
+ * `userProfile.tsx`.
18
+ */
19
+ const DEFAULT_ALLOW = [
20
+ "**/use[A-Z]*.{ts,tsx}",
21
+ "**/use-*.{ts,tsx}",
22
+ "**/hooks/**"
23
+ ];
24
+ const REACT_MODULE = "react";
25
+ function escapeRegExp(text) {
26
+ return text.replaceAll(/[$()*+.?[\\\]^{|}]/g, String.raw`\$&`);
27
+ }
28
+ /**
29
+ * Convert a glob to a regular expression that matches a whole path with forward slashes. Supports
30
+ * `**`, `*`, `?`, `[a-z]` and `[!a-z]` character classes, and `{a,b}` alternation.
31
+ */
32
+ function globToRegExp(glob) {
33
+ let source = "";
34
+ let index = 0;
35
+ while (index < glob.length) {
36
+ const rest = glob.slice(index);
37
+ if (rest.startsWith("**/")) {
38
+ source += "(?:.*/)?";
39
+ index += 3;
40
+ } else if (rest === "/**") {
41
+ source += "(?:/.*)?";
42
+ index += 3;
43
+ } else if (rest.startsWith("**")) {
44
+ source += ".*";
45
+ index += 2;
46
+ } else if (rest.startsWith("*")) {
47
+ source += "[^/]*";
48
+ index += 1;
49
+ } else if (rest.startsWith("?")) {
50
+ source += "[^/]";
51
+ index += 1;
52
+ } else if (rest.startsWith("[") && rest.indexOf("]") > 1) {
53
+ const end = rest.indexOf("]");
54
+ const negated = rest.startsWith("[!");
55
+ const characters = rest.slice(negated ? 2 : 1, end).replaceAll(/[\\^]/g, String.raw`\$&`);
56
+ source += `[${negated ? "^" : ""}${characters}]`;
57
+ index += end + 1;
58
+ } else if (rest.startsWith("{") && rest.includes("}")) {
59
+ const end = rest.indexOf("}");
60
+ const alternatives = rest.slice(1, end).split(",").map((alternative) => escapeRegExp(alternative));
61
+ source += `(?:${alternatives.join("|")})`;
62
+ index += end + 1;
63
+ } else {
64
+ source += escapeRegExp(glob.charAt(index));
65
+ index += 1;
66
+ }
67
+ }
68
+ return new RegExp(`^${source}$`);
69
+ }
70
+ function toPosixPath(path) {
71
+ return path.replaceAll("\\", "/");
72
+ }
73
+ /**
74
+ * The path that `allow` globs match: relative to the working directory when the file is inside it,
75
+ * and absolute otherwise.
76
+ */
77
+ function getMatchPath(context) {
78
+ const filename = toPosixPath(context.filename);
79
+ const cwd = toPosixPath(context.cwd).replace(/\/$/, "");
80
+ return filename.startsWith(`${cwd}/`) ? filename.slice(cwd.length + 1) : filename;
81
+ }
82
+ const rule = {
83
+ create(context) {
84
+ const hooks = new Set(readStringArrayOption(context.options, "hooks") ?? DEFAULT_HOOKS);
85
+ const allow = (readStringArrayOption(context.options, "allow") ?? DEFAULT_ALLOW).map((glob) => globToRegExp(glob));
86
+ const matchPath = getMatchPath(context);
87
+ if (allow.some((pattern) => pattern.test(matchPath))) return {};
88
+ return { ImportDeclaration(node) {
89
+ if (node.source.value !== REACT_MODULE) return;
90
+ for (const { call, name } of findImportedCalls(context, node, hooks)) context.report({
91
+ data: { hook: name },
92
+ messageId: HOOK_MESSAGES.get(name) ?? "banned",
93
+ node: call
94
+ });
95
+ } };
96
+ },
97
+ meta: {
98
+ defaultOptions: [{
99
+ allow: [...DEFAULT_ALLOW],
100
+ hooks: [...DEFAULT_HOOKS]
101
+ }],
102
+ docs: { description: "Disallow React state, effect, and memoization hooks in feature code. Hooks stay allowed in hook modules." },
103
+ messages: {
104
+ banned: "`{{hook}}` is not allowed in feature code. Move it into a hook module.",
105
+ effect: "`{{hook}}` runs a side effect in feature code. Move the side effect to a loader, an action, or an event handler.",
106
+ externalStore: "`{{hook}}` subscribes to an external store in feature code. Subscribe through a query or a store abstraction instead.",
107
+ localState: "`{{hook}}` keeps local state in feature code. Derive the value from loader data or URL params instead.",
108
+ memoization: "`{{hook}}` memoizes by hand. Remove it: the React Compiler handles memoization."
109
+ },
110
+ schema: [{
111
+ additionalProperties: false,
112
+ properties: {
113
+ allow: {
114
+ items: { type: "string" },
115
+ type: "array"
116
+ },
117
+ hooks: {
118
+ items: { type: "string" },
119
+ type: "array"
120
+ }
121
+ },
122
+ type: "object"
123
+ }],
124
+ type: "suggestion"
125
+ }
126
+ };
127
+ //#endregion
128
+ export { rule as default, globToRegExp };
@@ -0,0 +1,5 @@
1
+ import { Rule } from "@oxlint/plugins";
2
+ //#region presets/lint/plugin/rules/query-from-loader.d.ts
3
+ declare const rule: Rule;
4
+ //#endregion
5
+ export { rule as default };
@@ -0,0 +1,110 @@
1
+ import { findImportedCalls } from "../imports.js";
2
+ //#region presets/lint/plugin/rules/query-from-loader.ts
3
+ const QUERY_MODULE = "@tanstack/react-query";
4
+ const ROUTER_MODULE = "@tanstack/react-router";
5
+ const QUERY_HOOKS = /* @__PURE__ */ new Set([
6
+ "useInfiniteQuery",
7
+ "useQuery",
8
+ "useSuspenseInfiniteQuery",
9
+ "useSuspenseQuery"
10
+ ]);
11
+ const INFINITE_QUERY_HOOKS = /* @__PURE__ */ new Set(["useInfiniteQuery", "useSuspenseInfiniteQuery"]);
12
+ const OPTIONS_FACTORIES = /* @__PURE__ */ new Set(["infiniteQueryOptions", "queryOptions"]);
13
+ /**
14
+ * A file that calls one of these defines a route, in file-based or code-based routing. Only route
15
+ * files have a loader that can preload a query, so the rule checks only them.
16
+ */
17
+ const ROUTE_FACTORIES = /* @__PURE__ */ new Set([
18
+ "createFileRoute",
19
+ "createLazyFileRoute",
20
+ "createLazyRoute",
21
+ "createRootRoute",
22
+ "createRootRouteWithContext",
23
+ "createRoute"
24
+ ]);
25
+ function findVariable(context, identifier) {
26
+ let scope = context.sourceCode.getScope(identifier);
27
+ while (scope !== null && !scope.set.has(identifier.name)) scope = scope.upper;
28
+ return scope?.set.get(identifier.name);
29
+ }
30
+ /**
31
+ * The initializer of a `const` that declares `variable` with a plain identifier, such as `const
32
+ * options = { ... }`. Destructured, `let`, and imported bindings have none.
33
+ */
34
+ function getConstInit(variable) {
35
+ const [definition] = variable.defs;
36
+ if (variable.defs.length !== 1 || definition?.type !== "Variable") return;
37
+ const { node, parent } = definition;
38
+ if (node.type !== "VariableDeclarator" || node.id.type !== "Identifier" || parent?.type !== "VariableDeclaration" || parent.kind !== "const") return;
39
+ return node.init ?? void 0;
40
+ }
41
+ function isModuleScope(variable) {
42
+ return variable.scope.type === "module" || variable.scope.type === "global";
43
+ }
44
+ const rule = {
45
+ create(context) {
46
+ const hookCalls = [];
47
+ const factoryCalls = /* @__PURE__ */ new Set();
48
+ let isRouteFile = false;
49
+ /**
50
+ * Why `options` does not come from a shared definition, or `undefined` when it does or when the
51
+ * rule cannot tell. `inModule` is true when the expression sits at module scope.
52
+ */
53
+ function classify(options, inModule) {
54
+ if (options.type === "TSAsExpression" || options.type === "TSNonNullExpression" || options.type === "TSSatisfiesExpression" || options.type === "TSTypeAssertion") return classify(options.expression, inModule);
55
+ if (options.type === "ObjectExpression") return options.properties.some((property) => property.type === "SpreadElement") ? void 0 : "plainObject";
56
+ if (options.type === "CallExpression" && factoryCalls.has(options)) return inModule ? void 0 : "localOptions";
57
+ if (options.type === "Identifier") {
58
+ const variable = findVariable(context, options);
59
+ const init = variable === void 0 ? void 0 : getConstInit(variable);
60
+ return variable === void 0 || init === void 0 ? void 0 : classify(init, isModuleScope(variable));
61
+ }
62
+ }
63
+ return {
64
+ ImportDeclaration(node) {
65
+ if (node.source.value === ROUTER_MODULE) {
66
+ isRouteFile ||= findImportedCalls(context, node, ROUTE_FACTORIES).length > 0;
67
+ return;
68
+ }
69
+ if (node.source.value !== QUERY_MODULE) return;
70
+ hookCalls.push(...findImportedCalls(context, node, QUERY_HOOKS));
71
+ for (const { call } of findImportedCalls(context, node, OPTIONS_FACTORIES)) factoryCalls.add(call);
72
+ },
73
+ "Program:exit"() {
74
+ if (!isRouteFile) return;
75
+ for (const { call, name } of hookCalls) {
76
+ const [options] = call.arguments;
77
+ if (options === void 0) continue;
78
+ const messageId = classify(options, false);
79
+ if (messageId !== void 0) {
80
+ const data = INFINITE_QUERY_HOOKS.has(name) ? {
81
+ factory: "infiniteQueryOptions",
82
+ hook: name,
83
+ preload: "ensureInfiniteQueryData"
84
+ } : {
85
+ factory: "queryOptions",
86
+ hook: name,
87
+ preload: "ensureQueryData"
88
+ };
89
+ context.report({
90
+ data,
91
+ messageId,
92
+ node: options
93
+ });
94
+ }
95
+ }
96
+ }
97
+ };
98
+ },
99
+ meta: {
100
+ docs: { description: "Require TanStack Query hooks in route files to take options defined once with `queryOptions()` or `infiniteQueryOptions()`, so the route loader can preload the same query." },
101
+ messages: {
102
+ localOptions: "`{{hook}}` takes query options created inside a function, so the route loader cannot preload the same query. Move the `{{factory}}()` call to module scope, or into an exported factory such as `userQuery(id)`, preload it in this route's loader with `queryClient.{{preload}}()`, and pass the same options here.",
103
+ plainObject: "`{{hook}}` takes a plain options object instead of options defined with `{{factory}}()`. Define the options once with `{{factory}}()` at module scope or in a shared module, preload them in this route's loader with `queryClient.{{preload}}()`, and pass the same options here."
104
+ },
105
+ schema: [],
106
+ type: "suggestion"
107
+ }
108
+ };
109
+ //#endregion
110
+ export { rule as default };
@@ -0,0 +1,5 @@
1
+ import { OxlintConfig } from "oxlint";
2
+ //#region presets/lint/react-doctor.d.ts
3
+ declare const config: OxlintConfig;
4
+ //#endregion
5
+ export { config as default };
@@ -0,0 +1,20 @@
1
+ //#region presets/lint/react-doctor.ts
2
+ const config = {
3
+ jsPlugins: ["oxlint-plugin-react-doctor"],
4
+ rules: {
5
+ "react-doctor/no-create-store-in-render": "error",
6
+ "react-doctor/no-direct-state-mutation": "error",
7
+ "react-doctor/no-eager-new-in-use-state-initializer": "error",
8
+ "react-doctor/no-impure-state-updater": "error",
9
+ "react-doctor/no-mutating-reducer-state": "error",
10
+ "react-doctor/effect-observer-needs-disconnect": "error",
11
+ "react-doctor/effect-raf-loop-needs-cancel": "error",
12
+ "react-doctor/no-effect-event-handler": "error",
13
+ "react-doctor/no-event-trigger-state": "error",
14
+ "react-doctor/no-fetch-in-effect": "error",
15
+ "react-doctor/no-pass-live-state-to-parent": "error",
16
+ "react-doctor/no-set-state-after-await-in-effect": "error"
17
+ }
18
+ };
19
+ //#endregion
20
+ export { config as default };
@@ -0,0 +1,5 @@
1
+ import { OxlintConfig } from "oxlint";
2
+ //#region presets/lint/react-strict.d.ts
3
+ declare const config: OxlintConfig;
4
+ //#endregion
5
+ export { config as default };
@@ -0,0 +1,11 @@
1
+ //#region presets/lint/react-strict.ts
2
+ const PLUGIN_EXTENSION = import.meta.url.endsWith(".ts") ? "ts" : "js";
3
+ const config = {
4
+ jsPlugins: [{
5
+ name: "adamantite",
6
+ specifier: new URL(`plugin/index.${PLUGIN_EXTENSION}`, import.meta.url).href
7
+ }],
8
+ rules: { "adamantite/no-react-state-hooks": "error" }
9
+ };
10
+ //#endregion
11
+ export { config as default };
@@ -0,0 +1,5 @@
1
+ import { OxlintConfig } from "oxlint";
2
+ //#region presets/lint/shadcn.d.ts
3
+ declare const config: OxlintConfig;
4
+ //#endregion
5
+ export { config as default };
@@ -0,0 +1,22 @@
1
+ //#region presets/lint/shadcn.ts
2
+ const config = {
3
+ jsPlugins: ["@shadcn/lint"],
4
+ overrides: [{
5
+ files: ["**/components/ui/**"],
6
+ rules: {
7
+ "shadcn/no-arbitrary-values": "off",
8
+ "shadcn/no-restyle": "off",
9
+ "shadcn/require-static-classes": "off"
10
+ }
11
+ }],
12
+ rules: {
13
+ "shadcn/no-arbitrary-values": ["error", { allow: ["layout"] }],
14
+ "shadcn/no-inline-styles": "error",
15
+ "shadcn/no-raw-colors": "error",
16
+ "shadcn/no-restyle": ["error", { allow: ["layout"] }],
17
+ "shadcn/no-unknown-classes": "error",
18
+ "shadcn/require-static-classes": "error"
19
+ }
20
+ };
21
+ //#endregion
22
+ export { config as default };
@@ -0,0 +1,5 @@
1
+ import { OxlintConfig } from "oxlint";
2
+ //#region presets/lint/strict.d.ts
3
+ declare const config: OxlintConfig;
4
+ //#endregion
5
+ export { config as default };
@@ -0,0 +1,18 @@
1
+ //#region presets/lint/strict.ts
2
+ const PLUGIN_EXTENSION = import.meta.url.endsWith(".ts") ? "ts" : "js";
3
+ const config = {
4
+ jsPlugins: [{
5
+ name: "adamantite",
6
+ specifier: new URL(`plugin/index.${PLUGIN_EXTENSION}`, import.meta.url).href
7
+ }],
8
+ overrides: [{
9
+ files: ["**/*.{test,spec}.{ts,tsx,mts,cts}", "**/__tests__/**"],
10
+ rules: { "typescript/consistent-type-assertions": "error" }
11
+ }],
12
+ rules: {
13
+ "adamantite/no-overzealous-destructuring": "error",
14
+ "typescript/consistent-type-assertions": ["error", { assertionStyle: "never" }]
15
+ }
16
+ };
17
+ //#endregion
18
+ export { config as default };
@@ -0,0 +1,5 @@
1
+ import { OxlintConfig } from "oxlint";
2
+ //#region presets/lint/tanstack.d.ts
3
+ declare const config: OxlintConfig;
4
+ //#endregion
5
+ export { config as default };
@@ -0,0 +1,14 @@
1
+ //#region presets/lint/tanstack.ts
2
+ const PLUGIN_EXTENSION = import.meta.url.endsWith(".ts") ? "ts" : "js";
3
+ const config = {
4
+ jsPlugins: [{
5
+ name: "adamantite",
6
+ specifier: new URL(`plugin/index.${PLUGIN_EXTENSION}`, import.meta.url).href
7
+ }],
8
+ rules: {
9
+ "adamantite/no-query-data-in-state": "error",
10
+ "adamantite/query-from-loader": "error"
11
+ }
12
+ };
13
+ //#endregion
14
+ export { config as default };
@@ -1,11 +1,27 @@
1
1
  // Generated by scripts/vendor-plugins.ts — do not edit by hand.
2
2
  interface VendoredPluginRule {
3
- readonly create: (context: never) => Record<string, never>
3
+ readonly create: (context: object) => Record<string, never>
4
4
  }
5
5
 
6
6
  declare const vendoredPlugin: {
7
7
  readonly meta: { readonly name: string }
8
- readonly rules: { readonly [ruleName: string]: VendoredPluginRule }
8
+ readonly rules: {
9
+ readonly "no-chained-type-assertions": VendoredPluginRule
10
+ readonly "no-conditional-empty-object-spread": VendoredPluginRule
11
+ readonly "no-known-value-widening": VendoredPluginRule
12
+ readonly "no-module-mocking": VendoredPluginRule
13
+ readonly "no-object-parameters": VendoredPluginRule
14
+ readonly "no-reflect-apply": VendoredPluginRule
15
+ readonly "no-reflect-get": VendoredPluginRule
16
+ readonly "no-runtime-typeof": VendoredPluginRule
17
+ readonly "no-shape-in-symbol-names": VendoredPluginRule
18
+ readonly "no-unknown-parameters": VendoredPluginRule
19
+ readonly "no-unknown-returns": VendoredPluginRule
20
+ readonly "no-unknown-type-aliases": VendoredPluginRule
21
+ readonly "no-unsafe-dictionary-type": VendoredPluginRule
22
+ readonly "no-widen-then-assert": VendoredPluginRule
23
+ readonly "require-safety-comment-for-type-assertion": VendoredPluginRule
24
+ }
9
25
  }
10
26
 
11
27
  export default vendoredPlugin
@@ -0,0 +1,9 @@
1
+ import { Context, Diagnostic, ESTree, Fix, Fixer, Node, Options, Plugin, Rule, RuleMeta, SourceCode, Visitor, VisitorWithHooks, defineRule } from "@oxlint/plugins";
2
+ //#region presets/rules/index.d.ts
3
+ /**
4
+ * Import every rule file in a rules folder and return them as one Oxlint plugin. The entry module
5
+ * that `custom()` writes calls this function.
6
+ */
7
+ export declare function loadRules(dir: string, name?: string): Promise<Plugin>;
8
+ //#endregion
9
+ export { type Context, type Diagnostic, type ESTree, type Fix, type Fixer, type Node, type Options, type Rule, type RuleMeta, type SourceCode, type Visitor, type VisitorWithHooks, defineRule };
@@ -0,0 +1,29 @@
1
+ import { DEFAULT_PLUGIN_NAME, getRuleName, listRuleFiles } from "../lint/custom.js";
2
+ import { join } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { defineRule } from "@oxlint/plugins";
5
+ //#region presets/rules/index.ts
6
+ async function importRule(path) {
7
+ let module;
8
+ try {
9
+ module = await import(pathToFileURL(path).href);
10
+ } catch (error) {
11
+ const reason = error instanceof Error ? error.message : String(error);
12
+ throw new Error(`Custom rule ${path} failed to load: ${reason}\nRule files run with type stripping, so use erasable TypeScript only: no enum, namespace, or parameter properties.`, { cause: error });
13
+ }
14
+ if (module.default === void 0) throw new Error(`Custom rule ${path} has no default export. Export the rule as default.`);
15
+ return module.default;
16
+ }
17
+ /**
18
+ * Import every rule file in a rules folder and return them as one Oxlint plugin. The entry module
19
+ * that `custom()` writes calls this function.
20
+ */
21
+ async function loadRules(dir, name = DEFAULT_PLUGIN_NAME) {
22
+ const rules = await Promise.all(listRuleFiles(dir).map(async (file) => [getRuleName(file), await importRule(join(dir, file))]));
23
+ return {
24
+ meta: { name },
25
+ rules: Object.fromEntries(rules)
26
+ };
27
+ }
28
+ //#endregion
29
+ export { defineRule, loadRules };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adamantite",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "description": "An strict and opinionated set of presets for modern TypeScript applications",
5
5
  "keywords": [
6
6
  "adamantite",
@@ -54,38 +54,45 @@
54
54
  "types": "./dist/presets/lint/*.d.ts",
55
55
  "default": "./dist/presets/lint/*.js"
56
56
  },
57
+ "./rules": {
58
+ "types": "./dist/presets/rules/index.d.ts",
59
+ "default": "./dist/presets/rules/index.js"
60
+ },
57
61
  "./typescript": "./dist/presets/tsconfig.json"
58
62
  },
59
63
  "dependencies": {
60
- "@clack/prompts": "1.7.0",
61
- "@effect/platform-node": "4.0.0-rc.115",
64
+ "@clack/prompts": "1.8.1",
65
+ "@effect/platform-node": "4.0.0",
66
+ "@oxlint/plugins": "1.86.0",
62
67
  "defu": "6.1.7",
63
- "effect": "4.0.0-rc.115",
64
- "esrap": "2.3.6",
68
+ "effect": "4.0.0",
65
69
  "jsonc-parser": "3.3.1",
66
- "nypm": "0.6.9",
67
- "oxc-parser": "^0.147.0"
70
+ "nypm": "0.6.10",
71
+ "oxc-parser": "0.152.0"
68
72
  },
69
73
  "devDependencies": {
70
- "@changesets/changelog-github": "1.0.0",
71
- "@changesets/cli": "3.0.1",
72
- "@effect/vitest": "4.0.0-rc.115",
73
- "@tanstack/intent": "0.3.7",
74
+ "@changesets/changelog-github": "1.0.1",
75
+ "@changesets/cli": "3.0.3",
76
+ "@effect/tsgo": "0.48.0",
77
+ "@effect/vitest": "4.0.0",
78
+ "@shadcn/lint": "0.2.0",
79
+ "@tanstack/intent": "0.5.0",
74
80
  "@types/figlet": "1.7.0",
75
- "@types/node": "22.20.1",
76
- "@vitest/coverage-v8": "5.0.1",
77
- "@vitest/ui": "5.0.1",
78
- "figlet": "1.11.4",
79
- "knip": "6.32.2",
80
- "oxfmt": "0.65.0",
81
- "oxlint": "1.83.0",
82
- "oxlint-tsgolint": "7.0.2001",
81
+ "@types/node": "22.20.5",
82
+ "@vitest/coverage-v8": "5.0.3",
83
+ "@vitest/ui": "5.0.3",
84
+ "figlet": "1.12.0",
85
+ "knip": "6.39.0",
86
+ "oxfmt": "0.71.0",
87
+ "oxlint": "1.86.0",
88
+ "oxlint-plugin-react-doctor": "0.9.14",
89
+ "oxlint-tsgolint": "7.0.2003",
83
90
  "sherif": "1.13.0",
84
- "tsdown": "0.22.14",
85
- "type-fest": "5.8.0",
91
+ "tsdown": "0.23.0",
92
+ "type-fest": "5.10.0",
86
93
  "typescript": "7.0.2",
87
94
  "unplugin-macros": "0.23.2",
88
- "vitest": "5.0.1"
95
+ "vitest": "5.0.3"
89
96
  },
90
97
  "peerDependencies": {
91
98
  "typescript": ">=7"
@@ -107,7 +114,9 @@
107
114
  "test:build": "node scripts/test-build.ts",
108
115
  "test:coverage": "vitest run --coverage",
109
116
  "test:dist": "pnpm run build && pnpm run test:build && pnpm run test:smoke",
117
+ "test:presets": "vitest run --project presets",
110
118
  "test:smoke": "node scripts/test-smoke.ts",
119
+ "test:unit": "vitest run --project unit",
111
120
  "test:watch": "vitest",
112
121
  "version": "changeset version"
113
122
  }