@yarnpkg/plugin-pnpm 2.0.0-rc.8 → 2.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/lib/PnpmLinker.d.ts +9 -8
- package/lib/PnpmLinker.js +81 -79
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/package.json +20 -15
package/lib/PnpmLinker.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Descriptor, FetchResult, Installer, InstallPackageExtraApi, Linker, LinkOptions, Locator, LocatorHash, MinimalLinkOptions, Package } from '@yarnpkg/core';
|
|
2
2
|
import { PortablePath } from '@yarnpkg/fslib';
|
|
3
|
-
export
|
|
4
|
-
pathByLocator: Map<LocatorHash, PortablePath>;
|
|
3
|
+
export type PnpmCustomData = {
|
|
5
4
|
locatorByPath: Map<PortablePath, string>;
|
|
5
|
+
pathsByLocator: Map<LocatorHash, {
|
|
6
|
+
packageLocation: PortablePath;
|
|
7
|
+
dependenciesLocation: PortablePath | null;
|
|
8
|
+
}>;
|
|
6
9
|
};
|
|
7
10
|
export declare class PnpmLinker implements Linker {
|
|
8
11
|
getCustomDataKey(): string;
|
|
@@ -15,23 +18,21 @@ export declare class PnpmLinker implements Linker {
|
|
|
15
18
|
declare class PnpmInstaller implements Installer {
|
|
16
19
|
private opts;
|
|
17
20
|
private readonly asyncActions;
|
|
21
|
+
private readonly indexFolderPromise;
|
|
18
22
|
constructor(opts: LinkOptions);
|
|
19
23
|
private customData;
|
|
20
24
|
attachCustomData(customData: any): void;
|
|
21
25
|
installPackage(pkg: Package, fetchResult: FetchResult, api: InstallPackageExtraApi): Promise<{
|
|
22
26
|
packageLocation: PortablePath;
|
|
23
|
-
|
|
24
|
-
} | {
|
|
25
|
-
packageLocation: PortablePath;
|
|
26
|
-
buildDirective: import("@yarnpkg/core").BuildDirective[];
|
|
27
|
+
buildRequest: import("@yarnpkg/core").BuildRequest | null;
|
|
27
28
|
}>;
|
|
28
29
|
installPackageSoft(pkg: Package, fetchResult: FetchResult, api: InstallPackageExtraApi): Promise<{
|
|
29
30
|
packageLocation: PortablePath;
|
|
30
|
-
|
|
31
|
+
buildRequest: null;
|
|
31
32
|
}>;
|
|
32
33
|
installPackageHard(pkg: Package, fetchResult: FetchResult, api: InstallPackageExtraApi): Promise<{
|
|
33
34
|
packageLocation: PortablePath;
|
|
34
|
-
|
|
35
|
+
buildRequest: import("@yarnpkg/core").BuildRequest | null;
|
|
35
36
|
}>;
|
|
36
37
|
attachInternalDependencies(locator: Locator, dependencies: Array<[Descriptor, Locator]>): Promise<void>;
|
|
37
38
|
attachExternalDependents(locator: Locator, dependentPaths: Array<PortablePath>): Promise<void>;
|
package/lib/PnpmLinker.js
CHANGED
|
@@ -9,7 +9,7 @@ class PnpmLinker {
|
|
|
9
9
|
getCustomDataKey() {
|
|
10
10
|
return JSON.stringify({
|
|
11
11
|
name: `PnpmLinker`,
|
|
12
|
-
version:
|
|
12
|
+
version: 3,
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
supportsPackage(pkg, opts) {
|
|
@@ -22,10 +22,10 @@ class PnpmLinker {
|
|
|
22
22
|
const customData = opts.project.linkersCustomData.get(customDataKey);
|
|
23
23
|
if (!customData)
|
|
24
24
|
throw new clipanion_1.UsageError(`The project in ${core_1.formatUtils.pretty(opts.project.configuration, `${opts.project.cwd}/package.json`, core_1.formatUtils.Type.PATH)} doesn't seem to have been installed - running an install there might help`);
|
|
25
|
-
const
|
|
26
|
-
if (typeof
|
|
25
|
+
const packagePaths = customData.pathsByLocator.get(locator.locatorHash);
|
|
26
|
+
if (typeof packagePaths === `undefined`)
|
|
27
27
|
throw new clipanion_1.UsageError(`Couldn't find ${core_1.structUtils.prettyLocator(opts.project.configuration, locator)} in the currently installed pnpm map - running an install might help`);
|
|
28
|
-
return packageLocation;
|
|
28
|
+
return packagePaths.packageLocation;
|
|
29
29
|
}
|
|
30
30
|
async findPackageLocator(location, opts) {
|
|
31
31
|
if (!this.isEnabled(opts))
|
|
@@ -66,10 +66,12 @@ class PnpmInstaller {
|
|
|
66
66
|
this.opts = opts;
|
|
67
67
|
this.asyncActions = new core_1.miscUtils.AsyncActions(10);
|
|
68
68
|
this.customData = {
|
|
69
|
-
|
|
69
|
+
pathsByLocator: new Map(),
|
|
70
70
|
locatorByPath: new Map(),
|
|
71
71
|
};
|
|
72
|
-
|
|
72
|
+
this.indexFolderPromise = (0, fslib_1.setupCopyIndex)(fslib_1.xfs, {
|
|
73
|
+
indexPath: fslib_1.ppath.join(opts.project.configuration.get(`globalFolder`), `index`),
|
|
74
|
+
});
|
|
73
75
|
}
|
|
74
76
|
attachCustomData(customData) {
|
|
75
77
|
// We don't want to attach the data because it's only used in the Linker and we'll recompute it anyways in the Installer,
|
|
@@ -83,40 +85,51 @@ class PnpmInstaller {
|
|
|
83
85
|
throw new Error(`Assertion failed: Unsupported package link type`);
|
|
84
86
|
}
|
|
85
87
|
async installPackageSoft(pkg, fetchResult, api) {
|
|
86
|
-
const
|
|
87
|
-
this.
|
|
88
|
+
const packageLocation = fslib_1.ppath.resolve(fetchResult.packageFs.getRealPath(), fetchResult.prefixPath);
|
|
89
|
+
const dependenciesLocation = this.opts.project.tryWorkspaceByLocator(pkg)
|
|
90
|
+
? fslib_1.ppath.join(packageLocation, fslib_1.Filename.nodeModules)
|
|
91
|
+
: null;
|
|
92
|
+
this.customData.pathsByLocator.set(pkg.locatorHash, {
|
|
93
|
+
packageLocation,
|
|
94
|
+
dependenciesLocation,
|
|
95
|
+
});
|
|
88
96
|
return {
|
|
89
|
-
packageLocation
|
|
90
|
-
|
|
97
|
+
packageLocation,
|
|
98
|
+
buildRequest: null,
|
|
91
99
|
};
|
|
92
100
|
}
|
|
93
101
|
async installPackageHard(pkg, fetchResult, api) {
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
this.customData.locatorByPath.set(
|
|
97
|
-
this.customData.
|
|
102
|
+
const packagePaths = getPackagePaths(pkg, { project: this.opts.project });
|
|
103
|
+
const packageLocation = packagePaths.packageLocation;
|
|
104
|
+
this.customData.locatorByPath.set(packageLocation, core_1.structUtils.stringifyLocator(pkg));
|
|
105
|
+
this.customData.pathsByLocator.set(pkg.locatorHash, packagePaths);
|
|
98
106
|
api.holdFetchResult(this.asyncActions.set(pkg.locatorHash, async () => {
|
|
99
|
-
await fslib_1.xfs.mkdirPromise(
|
|
107
|
+
await fslib_1.xfs.mkdirPromise(packageLocation, { recursive: true });
|
|
100
108
|
// Copy the package source into the <root>/n_m/.store/<hash> directory, so
|
|
101
109
|
// that we can then create symbolic links to it later.
|
|
102
|
-
await fslib_1.xfs.copyPromise(
|
|
110
|
+
await fslib_1.xfs.copyPromise(packageLocation, fetchResult.prefixPath, {
|
|
103
111
|
baseFs: fetchResult.packageFs,
|
|
104
112
|
overwrite: false,
|
|
113
|
+
linkStrategy: {
|
|
114
|
+
type: `HardlinkFromIndex`,
|
|
115
|
+
indexPath: await this.indexFolderPromise,
|
|
116
|
+
autoRepair: true,
|
|
117
|
+
},
|
|
105
118
|
});
|
|
106
119
|
}));
|
|
107
120
|
const isVirtual = core_1.structUtils.isVirtualLocator(pkg);
|
|
108
121
|
const devirtualizedLocator = isVirtual ? core_1.structUtils.devirtualizeLocator(pkg) : pkg;
|
|
109
122
|
const buildConfig = {
|
|
110
|
-
manifest:
|
|
123
|
+
manifest: await core_1.Manifest.tryFind(fetchResult.prefixPath, { baseFs: fetchResult.packageFs }) ?? new core_1.Manifest(),
|
|
111
124
|
misc: {
|
|
112
125
|
hasBindingGyp: plugin_pnp_1.jsInstallUtils.hasBindingGyp(fetchResult),
|
|
113
126
|
},
|
|
114
127
|
};
|
|
115
128
|
const dependencyMeta = this.opts.project.getDependencyMeta(devirtualizedLocator, pkg.version);
|
|
116
|
-
const
|
|
129
|
+
const buildRequest = plugin_pnp_1.jsInstallUtils.extractBuildRequest(pkg, buildConfig, dependencyMeta, { configuration: this.opts.project.configuration });
|
|
117
130
|
return {
|
|
118
|
-
packageLocation
|
|
119
|
-
|
|
131
|
+
packageLocation,
|
|
132
|
+
buildRequest,
|
|
120
133
|
};
|
|
121
134
|
}
|
|
122
135
|
async attachInternalDependencies(locator, dependencies) {
|
|
@@ -125,31 +138,33 @@ class PnpmInstaller {
|
|
|
125
138
|
// We don't install those packages at all, because they can't be used anyway
|
|
126
139
|
if (!isPnpmVirtualCompatible(locator, { project: this.opts.project }))
|
|
127
140
|
return;
|
|
141
|
+
const packagePaths = this.customData.pathsByLocator.get(locator.locatorHash);
|
|
142
|
+
if (typeof packagePaths === `undefined`)
|
|
143
|
+
throw new Error(`Assertion failed: Expected the package to have been registered (${core_1.structUtils.stringifyLocator(locator)})`);
|
|
144
|
+
const { dependenciesLocation, } = packagePaths;
|
|
145
|
+
if (!dependenciesLocation)
|
|
146
|
+
return;
|
|
128
147
|
this.asyncActions.reduce(locator.locatorHash, async (action) => {
|
|
129
|
-
|
|
130
|
-
await action;
|
|
131
|
-
const pkgPath = this.customData.pathByLocator.get(locator.locatorHash);
|
|
132
|
-
if (typeof pkgPath === `undefined`)
|
|
133
|
-
throw new Error(`Assertion failed: Expected the package to have been registered (${core_1.structUtils.stringifyLocator(locator)})`);
|
|
134
|
-
const nmPath = fslib_1.ppath.join(pkgPath, fslib_1.Filename.nodeModules);
|
|
135
|
-
const concurrentPromises = [];
|
|
148
|
+
await fslib_1.xfs.mkdirPromise(dependenciesLocation, { recursive: true });
|
|
136
149
|
// Retrieve what's currently inside the package's true nm folder. We
|
|
137
150
|
// will use that to figure out what are the extraneous entries we'll
|
|
138
151
|
// need to remove.
|
|
139
|
-
const
|
|
140
|
-
|
|
152
|
+
const initialEntries = await getNodeModulesListing(dependenciesLocation);
|
|
153
|
+
const extraneous = new Map(initialEntries);
|
|
154
|
+
const concurrentPromises = [action];
|
|
155
|
+
const installDependency = (descriptor, dependency) => {
|
|
141
156
|
// Downgrade virtual workspaces (cf isPnpmVirtualCompatible's documentation)
|
|
142
157
|
let targetDependency = dependency;
|
|
143
158
|
if (!isPnpmVirtualCompatible(dependency, { project: this.opts.project })) {
|
|
144
|
-
this.opts.report.
|
|
159
|
+
this.opts.report.reportWarningOnce(core_1.MessageName.UNNAMED, `The pnpm linker doesn't support providing different versions to workspaces' peer dependencies`);
|
|
145
160
|
targetDependency = core_1.structUtils.devirtualizeLocator(dependency);
|
|
146
161
|
}
|
|
147
|
-
const
|
|
148
|
-
if (typeof
|
|
162
|
+
const depSrcPaths = this.customData.pathsByLocator.get(targetDependency.locatorHash);
|
|
163
|
+
if (typeof depSrcPaths === `undefined`)
|
|
149
164
|
throw new Error(`Assertion failed: Expected the package to have been registered (${core_1.structUtils.stringifyLocator(dependency)})`);
|
|
150
165
|
const name = core_1.structUtils.stringifyIdent(descriptor);
|
|
151
|
-
const depDstPath = fslib_1.ppath.join(
|
|
152
|
-
const depLinkPath = fslib_1.ppath.relative(fslib_1.ppath.dirname(depDstPath),
|
|
166
|
+
const depDstPath = fslib_1.ppath.join(dependenciesLocation, name);
|
|
167
|
+
const depLinkPath = fslib_1.ppath.relative(fslib_1.ppath.dirname(depDstPath), depSrcPaths.packageLocation);
|
|
153
168
|
const existing = extraneous.get(name);
|
|
154
169
|
extraneous.delete(name);
|
|
155
170
|
concurrentPromises.push(Promise.resolve().then(async () => {
|
|
@@ -163,15 +178,23 @@ class PnpmInstaller {
|
|
|
163
178
|
}
|
|
164
179
|
}
|
|
165
180
|
await fslib_1.xfs.mkdirpPromise(fslib_1.ppath.dirname(depDstPath));
|
|
166
|
-
if (process.platform == `win32`) {
|
|
167
|
-
await fslib_1.xfs.symlinkPromise(
|
|
181
|
+
if (process.platform == `win32` && this.opts.project.configuration.get(`winLinkType`) === core_1.WindowsLinkType.JUNCTIONS) {
|
|
182
|
+
await fslib_1.xfs.symlinkPromise(depSrcPaths.packageLocation, depDstPath, `junction`);
|
|
168
183
|
}
|
|
169
184
|
else {
|
|
170
185
|
await fslib_1.xfs.symlinkPromise(depLinkPath, depDstPath);
|
|
171
186
|
}
|
|
172
187
|
}));
|
|
188
|
+
};
|
|
189
|
+
let hasExplicitSelfDependency = false;
|
|
190
|
+
for (const [descriptor, dependency] of dependencies) {
|
|
191
|
+
if (descriptor.identHash === locator.identHash)
|
|
192
|
+
hasExplicitSelfDependency = true;
|
|
193
|
+
installDependency(descriptor, dependency);
|
|
173
194
|
}
|
|
174
|
-
|
|
195
|
+
if (!hasExplicitSelfDependency && !this.opts.project.tryWorkspaceByLocator(locator))
|
|
196
|
+
installDependency(core_1.structUtils.convertLocatorToDescriptor(locator), locator);
|
|
197
|
+
concurrentPromises.push(cleanNodeModules(dependenciesLocation, extraneous));
|
|
175
198
|
await Promise.all(concurrentPromises);
|
|
176
199
|
});
|
|
177
200
|
}
|
|
@@ -184,46 +207,25 @@ class PnpmInstaller {
|
|
|
184
207
|
await fslib_1.xfs.removePromise(storeLocation);
|
|
185
208
|
}
|
|
186
209
|
else {
|
|
187
|
-
|
|
188
|
-
const expectedEntries = new Set();
|
|
189
|
-
for (const packageLocation of this.customData.pathByLocator.values()) {
|
|
190
|
-
const subpath = fslib_1.ppath.contains(storeLocation, packageLocation);
|
|
191
|
-
if (subpath !== null) {
|
|
192
|
-
const [storeEntry, /* Filename.nodeModules */ , ...identComponents] = subpath.split(fslib_1.ppath.sep);
|
|
193
|
-
expectedEntries.add(storeEntry);
|
|
194
|
-
const storeEntryPath = fslib_1.ppath.join(storeLocation, storeEntry);
|
|
195
|
-
removals.push(fslib_1.xfs.readdirPromise(storeEntryPath)
|
|
196
|
-
.then(entries => {
|
|
197
|
-
return Promise.all(entries.map(async (entry) => {
|
|
198
|
-
const p = fslib_1.ppath.join(storeEntryPath, entry);
|
|
199
|
-
if (entry === fslib_1.Filename.nodeModules) {
|
|
200
|
-
const extraneous = await getNodeModulesListing(p);
|
|
201
|
-
extraneous.delete(identComponents.join(fslib_1.ppath.sep));
|
|
202
|
-
return cleanNodeModules(p, extraneous);
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
return fslib_1.xfs.removePromise(p);
|
|
206
|
-
}
|
|
207
|
-
}));
|
|
208
|
-
})
|
|
209
|
-
.catch(error => {
|
|
210
|
-
if (error.code !== `ENOENT`) {
|
|
211
|
-
throw error;
|
|
212
|
-
}
|
|
213
|
-
}));
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
let storeRecords;
|
|
210
|
+
let extraneous;
|
|
217
211
|
try {
|
|
218
|
-
|
|
212
|
+
extraneous = new Set(await fslib_1.xfs.readdirPromise(storeLocation));
|
|
219
213
|
}
|
|
220
214
|
catch {
|
|
221
|
-
|
|
215
|
+
extraneous = new Set();
|
|
216
|
+
}
|
|
217
|
+
for (const { dependenciesLocation } of this.customData.pathsByLocator.values()) {
|
|
218
|
+
if (!dependenciesLocation)
|
|
219
|
+
continue;
|
|
220
|
+
const subpath = fslib_1.ppath.contains(storeLocation, dependenciesLocation);
|
|
221
|
+
if (subpath === null)
|
|
222
|
+
continue;
|
|
223
|
+
const [storeEntry] = subpath.split(fslib_1.ppath.sep);
|
|
224
|
+
extraneous.delete(storeEntry);
|
|
222
225
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
await Promise.all(removals);
|
|
226
|
+
await Promise.all([...extraneous].map(async (extraneousEntry) => {
|
|
227
|
+
await fslib_1.xfs.removePromise(fslib_1.ppath.join(storeLocation, extraneousEntry));
|
|
228
|
+
}));
|
|
227
229
|
}
|
|
228
230
|
// Wait for the package installs to catch up
|
|
229
231
|
await this.asyncActions.wait();
|
|
@@ -241,11 +243,12 @@ function getNodeModulesLocation(project) {
|
|
|
241
243
|
function getStoreLocation(project) {
|
|
242
244
|
return fslib_1.ppath.join(getNodeModulesLocation(project), `.store`);
|
|
243
245
|
}
|
|
244
|
-
function
|
|
246
|
+
function getPackagePaths(locator, { project }) {
|
|
245
247
|
const pkgKey = core_1.structUtils.slugifyLocator(locator);
|
|
246
|
-
const
|
|
247
|
-
const
|
|
248
|
-
|
|
248
|
+
const storeLocation = getStoreLocation(project);
|
|
249
|
+
const packageLocation = fslib_1.ppath.join(storeLocation, pkgKey, `package`);
|
|
250
|
+
const dependenciesLocation = fslib_1.ppath.join(storeLocation, pkgKey, fslib_1.Filename.nodeModules);
|
|
251
|
+
return { packageLocation, dependenciesLocation };
|
|
249
252
|
}
|
|
250
253
|
function isPnpmVirtualCompatible(locator, { project }) {
|
|
251
254
|
// The pnpm install strategy has a limitation: because Node would always
|
|
@@ -300,12 +303,11 @@ async function getNodeModulesListing(nmPath) {
|
|
|
300
303
|
return listing;
|
|
301
304
|
}
|
|
302
305
|
async function cleanNodeModules(nmPath, extraneous) {
|
|
303
|
-
var _a;
|
|
304
306
|
const removeNamePromises = [];
|
|
305
307
|
const scopesToRemove = new Set();
|
|
306
308
|
for (const name of extraneous.keys()) {
|
|
307
309
|
removeNamePromises.push(fslib_1.xfs.removePromise(fslib_1.ppath.join(nmPath, name)));
|
|
308
|
-
const scope =
|
|
310
|
+
const scope = core_1.structUtils.tryParseIdent(name)?.scope;
|
|
309
311
|
if (scope) {
|
|
310
312
|
scopesToRemove.add(`@${scope}`);
|
|
311
313
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PnpmLinker = void 0;
|
|
3
4
|
const PnpmLinker_1 = require("./PnpmLinker");
|
|
5
|
+
Object.defineProperty(exports, "PnpmLinker", { enumerable: true, get: function () { return PnpmLinker_1.PnpmLinker; } });
|
|
4
6
|
const plugin = {
|
|
5
7
|
linkers: [
|
|
6
8
|
PnpmLinker_1.PnpmLinker,
|
package/package.json
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yarnpkg/plugin-pnpm",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"license": "BSD-2-Clause",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./lib/index.js",
|
|
8
|
+
"./package.json": "./package.json"
|
|
9
|
+
},
|
|
6
10
|
"dependencies": {
|
|
7
|
-
"@yarnpkg/fslib": "^3.0.0
|
|
8
|
-
"@yarnpkg/plugin-pnp": "^4.0.0
|
|
9
|
-
"@yarnpkg/plugin-stage": "^4.0.0
|
|
10
|
-
"clipanion": "^
|
|
11
|
+
"@yarnpkg/fslib": "^3.0.0",
|
|
12
|
+
"@yarnpkg/plugin-pnp": "^4.0.0",
|
|
13
|
+
"@yarnpkg/plugin-stage": "^4.0.0",
|
|
14
|
+
"clipanion": "^4.0.0-rc.2",
|
|
11
15
|
"p-limit": "^2.2.0",
|
|
12
|
-
"tslib": "^
|
|
16
|
+
"tslib": "^2.4.0"
|
|
13
17
|
},
|
|
14
18
|
"peerDependencies": {
|
|
15
|
-
"@yarnpkg/cli": "^4.0.0
|
|
16
|
-
"@yarnpkg/core": "^4.0.0
|
|
19
|
+
"@yarnpkg/cli": "^4.0.0",
|
|
20
|
+
"@yarnpkg/core": "^4.0.0"
|
|
17
21
|
},
|
|
18
22
|
"devDependencies": {
|
|
19
|
-
"@yarnpkg/cli": "^4.0.0
|
|
20
|
-
"@yarnpkg/core": "^4.0.0
|
|
23
|
+
"@yarnpkg/cli": "^4.0.0",
|
|
24
|
+
"@yarnpkg/core": "^4.0.0"
|
|
21
25
|
},
|
|
22
26
|
"repository": {
|
|
23
27
|
"type": "git",
|
|
@@ -30,14 +34,15 @@
|
|
|
30
34
|
},
|
|
31
35
|
"publishConfig": {
|
|
32
36
|
"main": "./lib/index.js",
|
|
33
|
-
"
|
|
37
|
+
"exports": {
|
|
38
|
+
".": "./lib/index.js",
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
}
|
|
34
41
|
},
|
|
35
42
|
"files": [
|
|
36
43
|
"/lib/**/*"
|
|
37
44
|
],
|
|
38
45
|
"engines": {
|
|
39
|
-
"node": ">=
|
|
40
|
-
}
|
|
41
|
-
"stableVersion": "1.1.0",
|
|
42
|
-
"typings": "./lib/index.d.ts"
|
|
46
|
+
"node": ">=18.12.0"
|
|
47
|
+
}
|
|
43
48
|
}
|