@isentinel/pnpm-plugin-eslint-config 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/extensions.mjs +422 -0
- package/package.json +39 -0
- package/pnpmfile.mjs +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-PRESENT Anthony Fu<https://github.com/antfu>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/extensions.mjs
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package extensions for dependencies whose published type declarations import
|
|
3
|
+
* packages they never declare.
|
|
4
|
+
*
|
|
5
|
+
* Under `enableGlobalVirtualStore: true` a package's real location leaves the
|
|
6
|
+
* project tree entirely, so the parent-directory walk TypeScript performs no
|
|
7
|
+
* longer passes through pnpm's hidden hoist store or the project root. A
|
|
8
|
+
* dependency then sees only its own declared dependencies, and every
|
|
9
|
+
* under-declared type import silently degrades to `any` (`skipLibCheck` hides
|
|
10
|
+
* the `TS2307` but the error type remains).
|
|
11
|
+
*
|
|
12
|
+
* This table is the sole source of truth, read by three consumers:
|
|
13
|
+
*
|
|
14
|
+
* - This package's `pnpmfile.mjs`, which pnpm auto-loads for anyone who
|
|
15
|
+
* installs it as a config dependency. It applies {@link publishedExtensions}
|
|
16
|
+
* rather than the whole table — see `consumerFacing` below. Consumers need
|
|
17
|
+
* the hook at all because `packageExtensions` is project-local and cannot be
|
|
18
|
+
* published.
|
|
19
|
+
* - `scripts/gen-package-extensions.ts`, which renders the table into the
|
|
20
|
+
* `packageExtensions` block of this repository's own `pnpm-workspace.yaml`.
|
|
21
|
+
* Our install therefore needs no pnpmfile: pnpm applies the same repairs
|
|
22
|
+
* natively.
|
|
23
|
+
* - `scripts/check-package-extensions.ts`, which fails when an installed
|
|
24
|
+
* package gains an under-declared import that no entry covers.
|
|
25
|
+
*
|
|
26
|
+
* Plain JavaScript rather than TypeScript because pnpm's config-dependency
|
|
27
|
+
* loader only probes `pnpmfile.mjs`/`.cjs`, and Node refuses to strip types
|
|
28
|
+
* from files under `node_modules`. JSDoc carries the types instead.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {object} PackageExtension
|
|
32
|
+
* @property {boolean} [consumerFacing] Whether a consumer of
|
|
33
|
+
* `@isentinel/eslint-config` loads this package's declarations. Only the
|
|
34
|
+
* preset's published type surface counts: every other entry repairs a package
|
|
35
|
+
* that ESLint loads at runtime, where resolution is not broken, so injecting
|
|
36
|
+
* it downstream would add `@types` packages nobody's program reads.
|
|
37
|
+
* `scripts/check-published-extensions.ts` derives the true set from the built
|
|
38
|
+
* declarations and fails when a flag disagrees.
|
|
39
|
+
* @property {Record<string, string>} [dependencies] Declarations to add to
|
|
40
|
+
* `dependencies`.
|
|
41
|
+
* @property {string} [fixedIn] The first version to declare these itself. Later
|
|
42
|
+
* versions are left alone.
|
|
43
|
+
* @property {Array<string>} [ignore] Specifiers accounted for without being
|
|
44
|
+
* injected, because they are not part of the package's type surface. Read
|
|
45
|
+
* only by the check script; nothing is injected for them.
|
|
46
|
+
* @property {string} name The package to extend.
|
|
47
|
+
* @property {Record<string, string>} [peerDependencies] Declarations to add to
|
|
48
|
+
* `peerDependencies`, each marked optional.
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* The parts of a package manifest this table reads and writes. Every dependency
|
|
52
|
+
* field arrives as an object, since pnpm fills them in before calling the hook,
|
|
53
|
+
* but a manifest built by hand — in tests, say — need not carry them.
|
|
54
|
+
*
|
|
55
|
+
* @typedef {object} PackageManifest
|
|
56
|
+
* @property {Record<string, string>} [dependencies] What the package declares.
|
|
57
|
+
* @property {string} [name] The package's name, matched against an entry.
|
|
58
|
+
* @property {Record<string, string>} [peerDependencies] What the package
|
|
59
|
+
* expects its consumer to provide.
|
|
60
|
+
* @property {Record<string, { optional?: boolean }>} [peerDependenciesMeta]
|
|
61
|
+
* Which of those peers are optional.
|
|
62
|
+
* @property {string} [version] The installed version, tested against `fixedIn`.
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* A tsconfig template variable that leaked into two plugins' published
|
|
66
|
+
* declarations. Unresolvable under any layout; tracked in
|
|
67
|
+
* christopher-buss/eslint-config#640.
|
|
68
|
+
*/
|
|
69
|
+
// oxlint-disable-next-line no-template-curly-in-string -- The literal text those declarations ship.
|
|
70
|
+
const LEAKED_CONFIG_DIR = "${configDir}";
|
|
71
|
+
/** The release portion of a version, up to any prerelease or build metadata. */
|
|
72
|
+
const RELEASE_SEPARATOR = /[-+]/u;
|
|
73
|
+
/** @type {ReadonlyArray<PackageExtension>} */
|
|
74
|
+
export const packageExtensions = [
|
|
75
|
+
{
|
|
76
|
+
name: "@cspell/eslint-plugin",
|
|
77
|
+
dependencies: {
|
|
78
|
+
"@types/estree": "^1",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "@e18e/eslint-plugin",
|
|
83
|
+
dependencies: {
|
|
84
|
+
"@eslint/core": "^1",
|
|
85
|
+
"@types/estree": "^1",
|
|
86
|
+
},
|
|
87
|
+
peerDependencies: {
|
|
88
|
+
"@typescript-eslint/typescript-estree": "*",
|
|
89
|
+
"@typescript-eslint/utils": "*",
|
|
90
|
+
"typescript": "*",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "@es-joy/jsdoccomment",
|
|
95
|
+
peerDependencies: {
|
|
96
|
+
eslint: "*",
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "@eslint-community/eslint-utils",
|
|
101
|
+
dependencies: {
|
|
102
|
+
"@types/estree": "^1",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "@eslint/markdown",
|
|
107
|
+
dependencies: {
|
|
108
|
+
"@types/mdast": "^4",
|
|
109
|
+
"@types/unist": "^3",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: "@stylistic/eslint-plugin",
|
|
114
|
+
// `define-config-support.d.ts` augments a package that is deprecated
|
|
115
|
+
// and only present for consumers who opted into it themselves.
|
|
116
|
+
ignore: ["eslint-define-config"],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "@typescript-eslint/types",
|
|
120
|
+
consumerFacing: true,
|
|
121
|
+
peerDependencies: {
|
|
122
|
+
typescript: "*",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "editorconfig",
|
|
127
|
+
// Test declarations ship inside the tarball.
|
|
128
|
+
ignore: ["chai"],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "eslint-flat-config-utils",
|
|
132
|
+
consumerFacing: true,
|
|
133
|
+
peerDependencies: {
|
|
134
|
+
eslint: "*",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "eslint-plugin-comment-length",
|
|
139
|
+
// Rule-tester declarations ship inside the tarball.
|
|
140
|
+
ignore: ["@typescript-eslint/rule-tester"],
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: "eslint-plugin-de-morgan",
|
|
144
|
+
dependencies: {
|
|
145
|
+
"@types/estree": "^1",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "eslint-plugin-flawless",
|
|
150
|
+
ignore: [LEAKED_CONFIG_DIR],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "eslint-plugin-format-lua",
|
|
154
|
+
ignore: ["eslint-define-config"],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "eslint-plugin-jsdoc",
|
|
158
|
+
dependencies: {
|
|
159
|
+
"@eslint/core": "^1",
|
|
160
|
+
"@types/estree": "^1",
|
|
161
|
+
"@types/json-schema": "^7",
|
|
162
|
+
"jsdoc-type-pratt-parser": "^7",
|
|
163
|
+
},
|
|
164
|
+
peerDependencies: {
|
|
165
|
+
"@typescript-eslint/types": "*",
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "eslint-plugin-jsonc",
|
|
170
|
+
dependencies: {
|
|
171
|
+
"@types/estree": "^1",
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "eslint-plugin-n",
|
|
176
|
+
dependencies: {
|
|
177
|
+
"@eslint/core": "^1",
|
|
178
|
+
"@types/estree": "^1",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "eslint-plugin-perfectionist",
|
|
183
|
+
peerDependencies: {
|
|
184
|
+
"@typescript-eslint/types": "*",
|
|
185
|
+
"typescript": "*",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "eslint-plugin-roblox-ts",
|
|
190
|
+
ignore: [LEAKED_CONFIG_DIR],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "eslint-plugin-sentinel",
|
|
194
|
+
peerDependencies: {
|
|
195
|
+
"@typescript-eslint/utils": "*",
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "eslint-plugin-sonarjs",
|
|
200
|
+
dependencies: {
|
|
201
|
+
"@eslint/core": "^1",
|
|
202
|
+
"@types/estree": "^1",
|
|
203
|
+
"@types/estree-jsx": "^1",
|
|
204
|
+
"@types/functional-red-black-tree": "^1",
|
|
205
|
+
"@types/semver": "^7",
|
|
206
|
+
"type-fest": "^5",
|
|
207
|
+
},
|
|
208
|
+
peerDependencies: {
|
|
209
|
+
"@typescript-eslint/utils": "*",
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: "fdir",
|
|
214
|
+
dependencies: {
|
|
215
|
+
"@types/picomatch": "^4",
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: "generate-differences",
|
|
220
|
+
dependencies: {
|
|
221
|
+
"diff-match-patch-es": "^1",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: "jsdoc-type-pratt-parser",
|
|
226
|
+
dependencies: {
|
|
227
|
+
"@types/estree": "^1",
|
|
228
|
+
},
|
|
229
|
+
// Test and build declarations ship inside the tarball but are not
|
|
230
|
+
// reachable from the package's entry points.
|
|
231
|
+
ignore: ["mocha", "tsup"],
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: "jsonc-eslint-parser",
|
|
235
|
+
dependencies: {
|
|
236
|
+
"@types/estree": "^1",
|
|
237
|
+
},
|
|
238
|
+
peerDependencies: {
|
|
239
|
+
eslint: "*",
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "mdast-util-gfm-autolink-literal",
|
|
244
|
+
dependencies: {
|
|
245
|
+
"mdast-util-from-markdown": "^2",
|
|
246
|
+
"mdast-util-to-markdown": "^2",
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: "pkg-types",
|
|
251
|
+
peerDependencies: {
|
|
252
|
+
typescript: "*",
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: "toml-eslint-parser",
|
|
257
|
+
peerDependencies: {
|
|
258
|
+
eslint: "*",
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "yaml-eslint-parser",
|
|
263
|
+
peerDependencies: {
|
|
264
|
+
eslint: "*",
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* The entries a consumer's program actually loads, which is all the shipped
|
|
271
|
+
* hook applies. The rest repair packages ESLint only ever loads at runtime, so
|
|
272
|
+
* injecting them downstream would install `@types` packages no consumer's
|
|
273
|
+
* program reads.
|
|
274
|
+
*
|
|
275
|
+
* @type {ReadonlyArray<PackageExtension>}
|
|
276
|
+
*/
|
|
277
|
+
export const publishedExtensions = packageExtensions.filter(
|
|
278
|
+
(extension) => extension.consumerFacing === true,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Injects the declarations `extensions` lists for this manifest. Existing
|
|
283
|
+
* declarations always win, so an upstream fix takes effect without the table
|
|
284
|
+
* having to be updated first.
|
|
285
|
+
*
|
|
286
|
+
* @param {PackageManifest} manifest - The manifest pnpm read from the package.
|
|
287
|
+
* @param {ReadonlyArray<PackageExtension>} extensions - The table to apply.
|
|
288
|
+
* @returns {PackageManifest} The same manifest, extended in place.
|
|
289
|
+
*/
|
|
290
|
+
export function extendManifest(manifest, extensions) {
|
|
291
|
+
for (const extension of extensions) {
|
|
292
|
+
if (extension.name !== manifest.name || isFixedUpstream(manifest, extension)) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (extension.dependencies !== undefined) {
|
|
297
|
+
injectDependencies(manifest, extension.dependencies);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (extension.peerDependencies !== undefined) {
|
|
301
|
+
injectPeerDependencies(manifest, extension.peerDependencies);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return manifest;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* The `readPackage` hook itself, applying {@link publishedExtensions}. Takes
|
|
309
|
+
* only the manifest: pnpm passes a context object as its second argument, so
|
|
310
|
+
* the table must not be a parameter here.
|
|
311
|
+
*
|
|
312
|
+
* @param {PackageManifest} manifest - The manifest pnpm read from the package.
|
|
313
|
+
* @returns {PackageManifest} The same manifest, extended in place.
|
|
314
|
+
*/
|
|
315
|
+
export function applyExtensions(manifest) {
|
|
316
|
+
return extendManifest(manifest, publishedExtensions);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Collects the entries of `additions` that `manifest` does not already declare
|
|
321
|
+
* in any of its dependency fields.
|
|
322
|
+
*
|
|
323
|
+
* @param {PackageManifest} manifest - The manifest being extended.
|
|
324
|
+
* @param {Record<string, string>} additions - The entries to add.
|
|
325
|
+
* @returns {Record<string, string>} The entries that are genuinely missing.
|
|
326
|
+
*/
|
|
327
|
+
function missingFrom(manifest, additions) {
|
|
328
|
+
const missing = {};
|
|
329
|
+
for (const [name, range] of Object.entries(additions)) {
|
|
330
|
+
if (
|
|
331
|
+
manifest.dependencies?.[name] === undefined &&
|
|
332
|
+
manifest.peerDependencies?.[name] === undefined
|
|
333
|
+
) {
|
|
334
|
+
missing[name] = range;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return missing;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Adds `additions` to the manifest's `dependencies`.
|
|
343
|
+
*
|
|
344
|
+
* @param {PackageManifest} manifest - The manifest being extended.
|
|
345
|
+
* @param {Record<string, string>} additions - The declarations to inject.
|
|
346
|
+
*/
|
|
347
|
+
function injectDependencies(manifest, additions) {
|
|
348
|
+
const missing = missingFrom(manifest, additions);
|
|
349
|
+
if (Object.keys(missing).length > 0) {
|
|
350
|
+
manifest.dependencies = { ...manifest.dependencies, ...missing };
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Adds `additions` to the manifest's `peerDependencies`, each marked optional
|
|
356
|
+
* so an absent provider never fails the install.
|
|
357
|
+
*
|
|
358
|
+
* @param {PackageManifest} manifest - The manifest being extended.
|
|
359
|
+
* @param {Record<string, string>} additions - The declarations to inject.
|
|
360
|
+
*/
|
|
361
|
+
function injectPeerDependencies(manifest, additions) {
|
|
362
|
+
const missing = missingFrom(manifest, additions);
|
|
363
|
+
const names = Object.keys(missing);
|
|
364
|
+
if (names.length === 0) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
manifest.peerDependencies = { ...manifest.peerDependencies, ...missing };
|
|
369
|
+
const meta = { ...manifest.peerDependenciesMeta };
|
|
370
|
+
for (const name of names) {
|
|
371
|
+
meta[name] = { optional: true };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
manifest.peerDependenciesMeta = meta;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Splits a version into its numeric release components.
|
|
379
|
+
*
|
|
380
|
+
* @param {string} version - The version to split.
|
|
381
|
+
* @returns {Array<number>} Its major, minor and patch numbers.
|
|
382
|
+
*/
|
|
383
|
+
function releaseParts(version) {
|
|
384
|
+
const [release = version] = version.split(RELEASE_SEPARATOR, 1);
|
|
385
|
+
return release.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Compares the release portion of two versions, ignoring any prerelease or
|
|
390
|
+
* build metadata.
|
|
391
|
+
*
|
|
392
|
+
* @param {string} version - The version to test.
|
|
393
|
+
* @param {string} other - The version to test it against.
|
|
394
|
+
* @returns {boolean} Whether `version` sorts before `other`.
|
|
395
|
+
*/
|
|
396
|
+
function isBefore(version, other) {
|
|
397
|
+
const left = releaseParts(version);
|
|
398
|
+
const right = releaseParts(other);
|
|
399
|
+
for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
|
|
400
|
+
const difference = (left[index] ?? 0) - (right[index] ?? 0);
|
|
401
|
+
if (difference !== 0) {
|
|
402
|
+
return difference < 0;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Whether the installed version already declares what the entry would inject.
|
|
411
|
+
*
|
|
412
|
+
* @param {PackageManifest} manifest - The manifest pnpm read from the package.
|
|
413
|
+
* @param {PackageExtension} extension - The entry matching it.
|
|
414
|
+
* @returns {boolean} Whether to leave the manifest alone.
|
|
415
|
+
*/
|
|
416
|
+
function isFixedUpstream(manifest, extension) {
|
|
417
|
+
if (extension.fixedIn === undefined || manifest.version === undefined) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return !isBefore(manifest.version, extension.fixedIn);
|
|
422
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@isentinel/pnpm-plugin-eslint-config",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "pnpm plugin that declares the type-only imports @isentinel/eslint-config's dependencies are missing",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pnpm",
|
|
7
|
+
"pnpm-plugin",
|
|
8
|
+
"pnpmfile",
|
|
9
|
+
"eslint-config"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/christopher-buss/eslint-config/tree/main/pnpm-plugin",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/christopher-buss/eslint-config/issues"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/christopher-buss/eslint-config.git",
|
|
18
|
+
"directory": "pnpm-plugin"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Christopher Buss <christopher.buss@pm.me> (https://github.com/christopher-buss)",
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
"./extensions": "./extensions.mjs",
|
|
26
|
+
"./package.json": "./package.json",
|
|
27
|
+
"./pnpmfile": "./pnpmfile.mjs"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"extensions.mjs",
|
|
31
|
+
"pnpmfile.mjs"
|
|
32
|
+
],
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=24.12.0"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/pnpmfile.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entry point pnpm auto-loads for config dependencies whose name matches
|
|
3
|
+
* its plugin pattern (`pnpm-plugin-`, prefixed by any scope). All of the logic
|
|
4
|
+
* lives in `extensions.mjs` so the repository's own `.pnpmfile.mjs` can share
|
|
5
|
+
* it.
|
|
6
|
+
*/
|
|
7
|
+
import { applyExtensions } from "./extensions.mjs";
|
|
8
|
+
|
|
9
|
+
export const hooks = {
|
|
10
|
+
readPackage: applyExtensions,
|
|
11
|
+
};
|