@storm-software/eslint-plugin-bun 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/configs/index.d.mts +5 -0
- package/dist/configs/index.mjs +4 -943
- package/dist/configs/recommended.d.mts +5 -0
- package/dist/configs/recommended.mjs +33 -939
- package/dist/helpers/bun-workspace.d.mts +49 -0
- package/dist/helpers/bun-workspace.mjs +197 -244
- package/dist/helpers/{create-rule.d.ts → create-rule.d.mts} +6 -6
- package/dist/helpers/create-rule.mjs +37 -38
- package/dist/helpers/{iterate-dependencies.d.ts → iterate-dependencies.d.mts} +7 -7
- package/dist/helpers/iterate-dependencies.mjs +36 -56
- package/dist/index.d.mts +52 -0
- package/dist/index.mjs +29 -951
- package/dist/plugin-9WjNsG8_.mjs +20 -0
- package/dist/plugin.d.mts +31 -0
- package/dist/plugin.mjs +1 -807
- package/dist/rules/json-enforce-catalog.d.mts +14 -0
- package/dist/rules/json-enforce-catalog.mjs +102 -444
- package/dist/rules/json-no-duplicate-catalog-item.d.mts +8 -0
- package/dist/rules/json-no-duplicate-catalog-item.mjs +72 -386
- package/dist/rules/json-no-unused-catalog-item.d.mts +5 -0
- package/dist/rules/json-no-unused-catalog-item.mjs +70 -423
- package/dist/rules/json-valid-catalog.d.mts +11 -0
- package/dist/rules/json-valid-catalog.mjs +80 -422
- package/package.json +15 -22
- package/dist/configs/index.d.ts +0 -5
- package/dist/configs/recommended.d.ts +0 -5
- package/dist/helpers/bun-workspace.d.ts +0 -48
- package/dist/index.d.ts +0 -58
- package/dist/plugin.d.ts +0 -33
- package/dist/rules/json-enforce-catalog.d.ts +0 -18
- package/dist/rules/json-no-duplicate-catalog-item.d.ts +0 -12
- package/dist/rules/json-no-unused-catalog-item.d.ts +0 -7
- package/dist/rules/json-valid-catalog.d.ts +0 -15
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/helpers/bun-workspace.d.ts
|
|
2
|
+
interface BunWorkspacePackageJson {
|
|
3
|
+
catalog?: Record<string, string>;
|
|
4
|
+
catalogs?: Record<string, Record<string, string>>;
|
|
5
|
+
workspaces?: string[] | {
|
|
6
|
+
packages?: string[];
|
|
7
|
+
catalog?: Record<string, string>;
|
|
8
|
+
catalogs?: Record<string, Record<string, string>>;
|
|
9
|
+
};
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
type CatalogName = "default" | (string & {});
|
|
13
|
+
interface SpecifierConflicts {
|
|
14
|
+
conflicts: boolean;
|
|
15
|
+
newCatalogName: string;
|
|
16
|
+
existingSpecifier?: string;
|
|
17
|
+
}
|
|
18
|
+
interface BunWorkspace {
|
|
19
|
+
filepath: string;
|
|
20
|
+
setContent: (content: string) => void;
|
|
21
|
+
hasChanged: () => boolean;
|
|
22
|
+
hasQueue: () => boolean;
|
|
23
|
+
clearQueue: () => void;
|
|
24
|
+
queueChange: (fn: (workspace: BunWorkspace) => void, order?: "pre" | "post") => void;
|
|
25
|
+
toJSON: () => BunWorkspacePackageJson;
|
|
26
|
+
toString: () => string;
|
|
27
|
+
setPackage: (catalog: CatalogName, packageName: string, specifier: string) => void;
|
|
28
|
+
setPackageNoConflicts: (catalog: CatalogName, packageName: string, specifier: string) => void;
|
|
29
|
+
getPackageCatalogs: (packageName: string) => string[];
|
|
30
|
+
hasSpecifierConflicts: (catalog: CatalogName, packageName: string, specifier: string) => SpecifierConflicts;
|
|
31
|
+
getCatalogData: () => {
|
|
32
|
+
catalog?: Record<string, string>;
|
|
33
|
+
catalogs?: Record<string, Record<string, string>>;
|
|
34
|
+
};
|
|
35
|
+
getWorkspacePackagePatterns: () => string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Find and parse the Bun workspace root `package.json` that holds catalogs.
|
|
39
|
+
*
|
|
40
|
+
* Catalogs live in root `package.json` (top-level or under `workspaces`), not
|
|
41
|
+
* `pnpm-workspace.yaml`. See https://bun.com/docs/pm/catalogs
|
|
42
|
+
*/
|
|
43
|
+
declare function readBunWorkspace(cwd?: string): BunWorkspace;
|
|
44
|
+
declare function getBunWorkspace(cwd?: string): BunWorkspace;
|
|
45
|
+
declare function resetBunWorkspaceCache(): void;
|
|
46
|
+
declare function isRootWorkspacePackageJson(filename: string, cwd?: string): boolean;
|
|
47
|
+
declare function collectWorkspacePackageJsonPaths(workspaceRoot: BunWorkspace): string[];
|
|
48
|
+
//#endregion
|
|
49
|
+
export { BunWorkspace, BunWorkspacePackageJson, CatalogName, SpecifierConflicts, collectWorkspacePackageJsonPaths, getBunWorkspace, isRootWorkspacePackageJson, readBunWorkspace, resetBunWorkspaceCache };
|
|
@@ -1,265 +1,218 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import process from
|
|
3
|
-
import { findUpSync } from
|
|
4
|
-
import { dirname, normalize, resolve } from
|
|
5
|
-
import { globSync } from
|
|
6
|
-
|
|
7
|
-
// src/helpers/bun-workspace.ts
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { findUpSync } from "find-up-simple";
|
|
4
|
+
import { dirname, normalize, resolve } from "pathe";
|
|
5
|
+
import { globSync } from "tinyglobby";
|
|
6
|
+
//#region src/helpers/bun-workspace.ts
|
|
8
7
|
function isWorkspaceObject(workspaces) {
|
|
9
|
-
|
|
8
|
+
return Boolean(workspaces) && typeof workspaces === "object" && !Array.isArray(workspaces);
|
|
10
9
|
}
|
|
11
10
|
function detectCatalogRoot(data) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (isWorkspaceObject(data.workspaces) && (data.workspaces.catalog || data.workspaces.catalogs)) {
|
|
16
|
-
return "workspaces";
|
|
17
|
-
}
|
|
18
|
-
return isWorkspaceObject(data.workspaces) ? "workspaces" : "top";
|
|
11
|
+
if (data.catalog || data.catalogs) return "top";
|
|
12
|
+
if (isWorkspaceObject(data.workspaces) && (data.workspaces.catalog || data.workspaces.catalogs)) return "workspaces";
|
|
13
|
+
return isWorkspaceObject(data.workspaces) ? "workspaces" : "top";
|
|
19
14
|
}
|
|
20
15
|
function normalizeCatalogName(name) {
|
|
21
|
-
|
|
16
|
+
return name.replace(/\^/g, "h").replace(/~/g, "t").replace(/\./g, "_").replace(/</g, "l").replace(/>/g, "g").replace(/=/g, "e").replace(/\*/g, "s").replace(/@/g, "a").replace(/\|/g, "p").replace(/&/g, "n").replace(/-/g, "m").replace(/\+/g, "u").replace(/\s/g, "_");
|
|
22
17
|
}
|
|
23
18
|
function sortObjectKeys(input) {
|
|
24
|
-
|
|
25
|
-
Object.entries(input).sort(([left], [right]) => left.localeCompare(right))
|
|
26
|
-
);
|
|
19
|
+
return Object.fromEntries(Object.entries(input).sort(([left], [right]) => left.localeCompare(right)));
|
|
27
20
|
}
|
|
28
21
|
function isWorkspaceRootPackageJson(data) {
|
|
29
|
-
|
|
30
|
-
data.workspaces || data.catalog || data.catalogs
|
|
31
|
-
);
|
|
22
|
+
return Boolean(data.workspaces || data.catalog || data.catalogs);
|
|
32
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Find and parse the Bun workspace root `package.json` that holds catalogs.
|
|
26
|
+
*
|
|
27
|
+
* Catalogs live in root `package.json` (top-level or under `workspaces`), not
|
|
28
|
+
* `pnpm-workspace.yaml`. See https://bun.com/docs/pm/catalogs
|
|
29
|
+
*/
|
|
33
30
|
function readBunWorkspace(cwd = process.cwd()) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
if (queueTimer != null) {
|
|
179
|
-
clearTimeout(queueTimer);
|
|
180
|
-
}
|
|
181
|
-
queueTimer = setTimeout(() => {
|
|
182
|
-
queueTimer = void 0;
|
|
183
|
-
const clone = [...queue];
|
|
184
|
-
queue.length = 0;
|
|
185
|
-
for (const queued of clone) {
|
|
186
|
-
queued(workspace2);
|
|
187
|
-
}
|
|
188
|
-
if (hasChanged) {
|
|
189
|
-
write();
|
|
190
|
-
}
|
|
191
|
-
}, 1e3);
|
|
192
|
-
},
|
|
193
|
-
toJSON: () => data,
|
|
194
|
-
toString: () => `${JSON.stringify(data, null, 2)}
|
|
195
|
-
`,
|
|
196
|
-
setPackage,
|
|
197
|
-
setPackageNoConflicts(catalogName, packageName, specifier) {
|
|
198
|
-
const { newCatalogName } = hasSpecifierConflicts(
|
|
199
|
-
catalogName,
|
|
200
|
-
packageName,
|
|
201
|
-
specifier
|
|
202
|
-
);
|
|
203
|
-
setPackage(newCatalogName, packageName, specifier);
|
|
204
|
-
},
|
|
205
|
-
getPackageCatalogs,
|
|
206
|
-
hasSpecifierConflicts,
|
|
207
|
-
getCatalogData,
|
|
208
|
-
getWorkspacePackagePatterns() {
|
|
209
|
-
if (Array.isArray(data.workspaces)) {
|
|
210
|
-
return data.workspaces;
|
|
211
|
-
}
|
|
212
|
-
if (isWorkspaceObject(data.workspaces) && data.workspaces.packages) {
|
|
213
|
-
return data.workspaces.packages;
|
|
214
|
-
}
|
|
215
|
-
return [];
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
return workspace2;
|
|
31
|
+
const filepath = findUpSync("package.json", {
|
|
32
|
+
cwd,
|
|
33
|
+
type: "file"
|
|
34
|
+
});
|
|
35
|
+
if (!filepath) throw new Error("package.json not found");
|
|
36
|
+
let current = filepath;
|
|
37
|
+
let content = fs.readFileSync(current, "utf8");
|
|
38
|
+
let data = JSON.parse(content);
|
|
39
|
+
while (!isWorkspaceRootPackageJson(data)) {
|
|
40
|
+
const searchFrom = dirname(dirname(current));
|
|
41
|
+
const next = findUpSync("package.json", {
|
|
42
|
+
cwd: searchFrom,
|
|
43
|
+
type: "file"
|
|
44
|
+
});
|
|
45
|
+
if (!next || normalize(next) === normalize(current)) break;
|
|
46
|
+
current = next;
|
|
47
|
+
content = fs.readFileSync(current, "utf8");
|
|
48
|
+
data = JSON.parse(content);
|
|
49
|
+
}
|
|
50
|
+
if (!isWorkspaceRootPackageJson(data)) throw new Error("Bun workspace root package.json with workspaces/catalog not found");
|
|
51
|
+
let hasChanged = false;
|
|
52
|
+
let queueTimer;
|
|
53
|
+
const queue = [];
|
|
54
|
+
let catalogRoot = detectCatalogRoot(data);
|
|
55
|
+
const write = () => {
|
|
56
|
+
if (!fs.existsSync(current)) return;
|
|
57
|
+
fs.writeFileSync(current, `${JSON.stringify(data, null, 2)}\n`);
|
|
58
|
+
};
|
|
59
|
+
const clearQueue = () => {
|
|
60
|
+
if (queueTimer != null) {
|
|
61
|
+
clearTimeout(queueTimer);
|
|
62
|
+
queueTimer = void 0;
|
|
63
|
+
}
|
|
64
|
+
queue.length = 0;
|
|
65
|
+
};
|
|
66
|
+
const getCatalogContainer = () => {
|
|
67
|
+
if (catalogRoot === "workspaces") {
|
|
68
|
+
if (!isWorkspaceObject(data.workspaces)) data.workspaces = {
|
|
69
|
+
packages: Array.isArray(data.workspaces) ? data.workspaces : [],
|
|
70
|
+
catalog: {},
|
|
71
|
+
catalogs: {}
|
|
72
|
+
};
|
|
73
|
+
return data.workspaces;
|
|
74
|
+
}
|
|
75
|
+
return data;
|
|
76
|
+
};
|
|
77
|
+
const getCatalogData = () => {
|
|
78
|
+
const container = getCatalogContainer();
|
|
79
|
+
return {
|
|
80
|
+
catalog: container.catalog,
|
|
81
|
+
catalogs: container.catalogs
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
const setPackage = (catalogName, packageName, specifier) => {
|
|
85
|
+
const container = getCatalogContainer();
|
|
86
|
+
if (catalogName === "default") {
|
|
87
|
+
container.catalog ??= {};
|
|
88
|
+
if (container.catalog[packageName] !== specifier) {
|
|
89
|
+
container.catalog[packageName] = specifier;
|
|
90
|
+
container.catalog = sortObjectKeys(container.catalog);
|
|
91
|
+
hasChanged = true;
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
container.catalogs ??= {};
|
|
96
|
+
container.catalogs[catalogName] ??= {};
|
|
97
|
+
if (container.catalogs[catalogName][packageName] !== specifier) {
|
|
98
|
+
container.catalogs[catalogName][packageName] = specifier;
|
|
99
|
+
container.catalogs[catalogName] = sortObjectKeys(container.catalogs[catalogName]);
|
|
100
|
+
container.catalogs = sortObjectKeys(container.catalogs);
|
|
101
|
+
hasChanged = true;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const hasSpecifierConflicts = (catalogName, packageName, specifier) => {
|
|
105
|
+
const { catalog, catalogs } = getCatalogData();
|
|
106
|
+
const existingSpecifier = catalogName === "default" ? catalog?.[packageName] : catalogs?.[catalogName]?.[packageName];
|
|
107
|
+
if (existingSpecifier === specifier) return {
|
|
108
|
+
conflicts: false,
|
|
109
|
+
newCatalogName: catalogName,
|
|
110
|
+
existingSpecifier
|
|
111
|
+
};
|
|
112
|
+
if (existingSpecifier) {
|
|
113
|
+
const versionSuffix = normalizeCatalogName(specifier);
|
|
114
|
+
return {
|
|
115
|
+
conflicts: true,
|
|
116
|
+
existingSpecifier,
|
|
117
|
+
newCatalogName: catalogName === "default" ? `conflicts_${packageName}_${versionSuffix}` : `conflicts_${catalogName}_${versionSuffix}`
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
conflicts: false,
|
|
122
|
+
newCatalogName: catalogName
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
const getPackageCatalogs = (packageName) => {
|
|
126
|
+
const found = [];
|
|
127
|
+
const { catalog, catalogs } = getCatalogData();
|
|
128
|
+
if (catalogs) {
|
|
129
|
+
for (const name of Object.keys(catalogs)) if (catalogs[name]?.[packageName]) found.push(name);
|
|
130
|
+
}
|
|
131
|
+
if (catalog?.[packageName]) found.push("default");
|
|
132
|
+
return found;
|
|
133
|
+
};
|
|
134
|
+
const workspace = {
|
|
135
|
+
filepath: current,
|
|
136
|
+
setContent(newContent) {
|
|
137
|
+
content = newContent;
|
|
138
|
+
data = JSON.parse(newContent);
|
|
139
|
+
catalogRoot = detectCatalogRoot(data);
|
|
140
|
+
hasChanged = false;
|
|
141
|
+
},
|
|
142
|
+
hasChanged: () => hasChanged,
|
|
143
|
+
hasQueue: () => queueTimer != null,
|
|
144
|
+
clearQueue,
|
|
145
|
+
queueChange(fn, order) {
|
|
146
|
+
if (order === "pre") queue.unshift(fn);
|
|
147
|
+
else queue.push(fn);
|
|
148
|
+
if (queueTimer != null) clearTimeout(queueTimer);
|
|
149
|
+
queueTimer = setTimeout(() => {
|
|
150
|
+
queueTimer = void 0;
|
|
151
|
+
const clone = [...queue];
|
|
152
|
+
queue.length = 0;
|
|
153
|
+
for (const queued of clone) queued(workspace);
|
|
154
|
+
if (hasChanged) write();
|
|
155
|
+
}, 1e3);
|
|
156
|
+
},
|
|
157
|
+
toJSON: () => data,
|
|
158
|
+
toString: () => `${JSON.stringify(data, null, 2)}\n`,
|
|
159
|
+
setPackage,
|
|
160
|
+
setPackageNoConflicts(catalogName, packageName, specifier) {
|
|
161
|
+
const { newCatalogName } = hasSpecifierConflicts(catalogName, packageName, specifier);
|
|
162
|
+
setPackage(newCatalogName, packageName, specifier);
|
|
163
|
+
},
|
|
164
|
+
getPackageCatalogs,
|
|
165
|
+
hasSpecifierConflicts,
|
|
166
|
+
getCatalogData,
|
|
167
|
+
getWorkspacePackagePatterns() {
|
|
168
|
+
if (Array.isArray(data.workspaces)) return data.workspaces;
|
|
169
|
+
if (isWorkspaceObject(data.workspaces) && data.workspaces.packages) return data.workspaces.packages;
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
return workspace;
|
|
219
174
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
175
|
+
const WORKSPACE_CACHE_TIME = 1e4;
|
|
176
|
+
let workspaceLastRead;
|
|
177
|
+
let workspace;
|
|
223
178
|
function getBunWorkspace(cwd = process.cwd()) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
return workspace;
|
|
179
|
+
if (workspaceLastRead && workspace && !workspace.hasQueue() && Date.now() - workspaceLastRead > WORKSPACE_CACHE_TIME) workspace = void 0;
|
|
180
|
+
if (!workspace) {
|
|
181
|
+
workspace = readBunWorkspace(cwd);
|
|
182
|
+
workspaceLastRead = Date.now();
|
|
183
|
+
}
|
|
184
|
+
return workspace;
|
|
232
185
|
}
|
|
233
186
|
function resetBunWorkspaceCache() {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
187
|
+
workspace?.clearQueue();
|
|
188
|
+
workspace = void 0;
|
|
189
|
+
workspaceLastRead = void 0;
|
|
237
190
|
}
|
|
238
191
|
function isRootWorkspacePackageJson(filename, cwd = process.cwd()) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
192
|
+
try {
|
|
193
|
+
const root = getBunWorkspace(cwd);
|
|
194
|
+
return normalize(root.filepath) === normalize(filename);
|
|
195
|
+
} catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
245
198
|
}
|
|
246
199
|
function collectWorkspacePackageJsonPaths(workspaceRoot) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
200
|
+
const root = resolve(dirname(workspaceRoot.filepath));
|
|
201
|
+
const patterns = workspaceRoot.getWorkspacePackagePatterns();
|
|
202
|
+
const dirs = patterns.length ? globSync(patterns, {
|
|
203
|
+
cwd: root,
|
|
204
|
+
dot: false,
|
|
205
|
+
ignore: [
|
|
206
|
+
"**/node_modules/**",
|
|
207
|
+
"**/dist/**",
|
|
208
|
+
"**/build/**"
|
|
209
|
+
],
|
|
210
|
+
absolute: true,
|
|
211
|
+
expandDirectories: false,
|
|
212
|
+
onlyDirectories: true
|
|
213
|
+
}) : [];
|
|
214
|
+
dirs.push(root);
|
|
215
|
+
return dirs.map((dir) => resolve(dir, "package.json")).filter((path) => fs.existsSync(path)).sort();
|
|
263
216
|
}
|
|
264
|
-
|
|
217
|
+
//#endregion
|
|
265
218
|
export { collectWorkspacePackageJsonPaths, getBunWorkspace, isRootWorkspacePackageJson, readBunWorkspace, resetBunWorkspaceCache };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { Rule } from "eslint";
|
|
2
|
+
import { RuleWithMetaAndName } from "@typescript-eslint/utils/eslint-utils";
|
|
3
|
+
//#region src/helpers/create-rule.d.ts
|
|
4
4
|
type RuleModule<T extends readonly unknown[]> = Rule.RuleModule & {
|
|
5
|
-
|
|
5
|
+
defaultOptions: T;
|
|
6
6
|
};
|
|
7
7
|
declare const createRule: <TOptions extends readonly unknown[], TMessageIds extends string>({ name, meta, ...rule }: Readonly<RuleWithMetaAndName<TOptions, TMessageIds>>) => RuleModule<TOptions>;
|
|
8
|
-
|
|
9
|
-
export {
|
|
8
|
+
//#endregion
|
|
9
|
+
export { RuleModule, createRule };
|
|
@@ -1,42 +1,41 @@
|
|
|
1
|
-
import defu from
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import defu from "defu";
|
|
2
|
+
//#region src/helpers/create-rule.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates reusable function to create rules with default options and docs URLs.
|
|
5
|
+
*
|
|
6
|
+
* @param urlCreator - Creates a documentation URL for a given rule name.
|
|
7
|
+
* @returns Function to create a rule with the docs URL format.
|
|
8
|
+
*/
|
|
4
9
|
function RuleCreator(urlCreator) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
-
...rule
|
|
19
|
-
});
|
|
20
|
-
};
|
|
10
|
+
return function createNamedRule({ name, meta, ...rule }) {
|
|
11
|
+
return createRuleInfo({
|
|
12
|
+
meta: {
|
|
13
|
+
...meta,
|
|
14
|
+
docs: {
|
|
15
|
+
...meta.docs,
|
|
16
|
+
url: urlCreator(name)
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
...rule
|
|
20
|
+
});
|
|
21
|
+
};
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Creates a well-typed TSESLint custom ESLint rule without a docs URL.
|
|
25
|
+
*
|
|
26
|
+
* @returns Well-typed TSESLint custom ESLint rule.
|
|
27
|
+
*/
|
|
28
|
+
function createRuleInfo({ create, defaultOptions, meta }) {
|
|
29
|
+
return {
|
|
30
|
+
create: ((context) => {
|
|
31
|
+
return create(context, context.options.map((options, index) => {
|
|
32
|
+
return defu(defaultOptions?.[index] ?? {}, options);
|
|
33
|
+
}));
|
|
34
|
+
}),
|
|
35
|
+
defaultOptions: defaultOptions ?? {},
|
|
36
|
+
meta
|
|
37
|
+
};
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
);
|
|
41
|
-
|
|
39
|
+
const createRule = RuleCreator((ruleName) => `https://docs.stormsoftware.com/projects/storm-ops/eslint-plugin-bun/rules/${ruleName}.md`);
|
|
40
|
+
//#endregion
|
|
42
41
|
export { createRule };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { RuleContext } from
|
|
2
|
-
|
|
1
|
+
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
|
|
2
|
+
//#region src/helpers/iterate-dependencies.d.ts
|
|
3
3
|
declare function getPackageJsonRootNode(context: RuleContext<string, unknown[]>): any | undefined;
|
|
4
4
|
declare function iterateDependencies(context: RuleContext<string, unknown[]>, fields: string[]): Generator<{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
packageName: string;
|
|
6
|
+
specifier: string;
|
|
7
|
+
property: any;
|
|
8
8
|
}, void, unknown>;
|
|
9
9
|
declare function getObjectPath(obj: Record<string, unknown>, path: string[]): Record<string, string> | undefined;
|
|
10
|
-
|
|
11
|
-
export { getObjectPath, getPackageJsonRootNode, iterateDependencies };
|
|
10
|
+
//#endregion
|
|
11
|
+
export { getObjectPath, getPackageJsonRootNode, iterateDependencies };
|