@ctrl/plex 3.3.0 → 3.5.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/README.md +9 -3
- package/dist/src/alert.d.ts +2 -2
- package/dist/src/alert.js +0 -1
- package/dist/src/client.d.ts +1 -2
- package/dist/src/library.d.ts +6 -6
- package/dist/src/library.js +2 -4
- package/dist/src/library.types.d.ts +1 -1
- package/dist/src/media.d.ts +1 -1
- package/dist/src/myplex.d.ts +15 -2
- package/dist/src/myplex.js +66 -2
- package/dist/src/myplex.types.d.ts +5 -0
- package/dist/src/playlist.d.ts +2 -2
- package/dist/src/playlist.js +0 -2
- package/dist/src/search.d.ts +2 -2
- package/dist/src/server.d.ts +1 -2
- package/dist/src/server.js +0 -3
- package/dist/src/settings.js +0 -1
- package/dist/src/video.d.ts +3 -4
- package/package.json +27 -31
package/README.md
CHANGED
|
@@ -105,7 +105,8 @@ npm run test-cleanup
|
|
|
105
105
|
get a claim token from https://www.plex.tv/claim/
|
|
106
106
|
export PLEX_CLAIM_TOKEN=claim-token
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
start plex container for testing
|
|
109
|
+
```console
|
|
109
110
|
docker run -d \
|
|
110
111
|
--name=plex \
|
|
111
112
|
--net=host \
|
|
@@ -132,7 +133,12 @@ docker run -d \
|
|
|
132
133
|
lscr.io/linuxserver/plex:latest
|
|
133
134
|
```
|
|
134
135
|
|
|
135
|
-
|
|
136
|
+
Pull latest plex container if needed
|
|
137
|
+
```console
|
|
138
|
+
docker pull lscr.io/linuxserver/plex:latest
|
|
136
139
|
```
|
|
137
|
-
|
|
140
|
+
|
|
141
|
+
bootstrap plex server with test media
|
|
142
|
+
```console
|
|
143
|
+
NODE_OPTIONS="--loader ts-node/esm" node scripts/bootstraptest.ts --no-docker --server-name=orbstack --password=$PLEX_PASSWORD --username=$PLEX_USERNAME
|
|
138
144
|
```
|
package/dist/src/alert.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
|
-
import { AlertTypes } from './alert.types.js';
|
|
3
|
-
import { PlexServer } from './server.js';
|
|
2
|
+
import type { AlertTypes } from './alert.types.js';
|
|
3
|
+
import type { PlexServer } from './server.js';
|
|
4
4
|
export declare class AlertListener {
|
|
5
5
|
private readonly server;
|
|
6
6
|
callback: (data: AlertTypes) => void;
|
package/dist/src/alert.js
CHANGED
|
@@ -8,7 +8,6 @@ export class AlertListener {
|
|
|
8
8
|
async run() {
|
|
9
9
|
const url = this.server.url(this.key, true).toString().replace('http', 'ws');
|
|
10
10
|
this._ws = new WebSocket(url);
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
12
11
|
this._ws.on('message', (buffer) => {
|
|
13
12
|
try {
|
|
14
13
|
const data = JSON.parse(buffer.toString());
|
package/dist/src/client.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { URL } from 'url';
|
|
3
|
-
import { Player } from './client.types.js';
|
|
2
|
+
import type { Player } from './client.types.js';
|
|
4
3
|
export interface PlexOptions {
|
|
5
4
|
/** (:class:`~plexapi.server.PlexServer`): PlexServer this client is connected to (optional). */
|
|
6
5
|
server?: any;
|
package/dist/src/library.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Class } from 'type-fest';
|
|
1
|
+
import type { Class } from 'type-fest';
|
|
2
2
|
import { PartialPlexObject } from './base/partialPlexObject.js';
|
|
3
3
|
import { PlexObject } from './base/plexObject.js';
|
|
4
|
-
import { CollectionData, LibraryRootResponse, Location, SectionsDirectory } from './library.types.js';
|
|
4
|
+
import type { CollectionData, LibraryRootResponse, Location, SectionsDirectory } from './library.types.js';
|
|
5
5
|
import { Playlist } from './playlist.js';
|
|
6
|
-
import { Agent, SEARCHTYPES } from './search.js';
|
|
7
|
-
import { SearchResult } from './search.types.js';
|
|
6
|
+
import { type Agent, type SEARCHTYPES } from './search.js';
|
|
7
|
+
import type { SearchResult } from './search.types.js';
|
|
8
8
|
import type { PlexServer } from './server.js';
|
|
9
|
-
import { Movie, Show, VideoType } from './video.js';
|
|
9
|
+
import { Movie, Show, type VideoType } from './video.js';
|
|
10
10
|
export type Section = MovieSection | ShowSection;
|
|
11
11
|
export declare class Library {
|
|
12
12
|
private readonly server;
|
|
@@ -364,7 +364,7 @@ export declare abstract class LibrarySection<SectionVideoType = VideoType> exten
|
|
|
364
364
|
folders(): Promise<Folder[]>;
|
|
365
365
|
genres(): Promise<FilterChoice[]>;
|
|
366
366
|
/**
|
|
367
|
-
* Returns a list of available {@link
|
|
367
|
+
* Returns a list of available {@link FilteringField} for a specified libtype.
|
|
368
368
|
* This is the list of options in the custom filter dropdown menu
|
|
369
369
|
*/
|
|
370
370
|
listFields(libtype?: Libtype): Promise<FilteringField[]>;
|
package/dist/src/library.js
CHANGED
|
@@ -213,7 +213,6 @@ export class Library {
|
|
|
213
213
|
const results = [];
|
|
214
214
|
const sections = await this.sections();
|
|
215
215
|
for (const section of sections) {
|
|
216
|
-
// eslint-disable-next-line no-await-in-loop
|
|
217
216
|
const items = await section.all();
|
|
218
217
|
for (const item of items) {
|
|
219
218
|
results.push(item);
|
|
@@ -227,7 +226,6 @@ export class Library {
|
|
|
227
226
|
async emptyTrash() {
|
|
228
227
|
const sections = await this.sections();
|
|
229
228
|
for (const section of sections) {
|
|
230
|
-
// eslint-disable-next-line no-await-in-loop
|
|
231
229
|
await section.emptyTrash();
|
|
232
230
|
}
|
|
233
231
|
}
|
|
@@ -485,7 +483,7 @@ export class LibrarySection extends PlexObject {
|
|
|
485
483
|
return fetchItems(this.server, key, undefined, FilterChoice);
|
|
486
484
|
}
|
|
487
485
|
/**
|
|
488
|
-
* Returns a list of available {@link
|
|
486
|
+
* Returns a list of available {@link FilteringField} for a specified libtype.
|
|
489
487
|
* This is the list of options in the custom filter dropdown menu
|
|
490
488
|
*/
|
|
491
489
|
async listFields(libtype = this.type) {
|
|
@@ -496,7 +494,7 @@ export class LibrarySection extends PlexObject {
|
|
|
496
494
|
const filter = filterTypes.find(f => f.type === libtype);
|
|
497
495
|
if (!filter) {
|
|
498
496
|
throw new NotFound(`Unknown libtype "${libtype}" for this library.
|
|
499
|
-
Available libtypes: ${filterTypes.join(', ')}`);
|
|
497
|
+
Available libtypes: ${filterTypes.map(f => f.type).join(', ')}`);
|
|
500
498
|
}
|
|
501
499
|
return filter;
|
|
502
500
|
}
|
package/dist/src/media.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlexObject } from './base/plexObject.js';
|
|
2
|
-
import { ChapterData, MarkerData, MediaData, MediaPartData, MediaPartStreamData } from './video.types.js';
|
|
2
|
+
import type { ChapterData, MarkerData, MediaData, MediaPartData, MediaPartStreamData } from './video.types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Base class for media tags used for filtering and searching your library
|
|
5
5
|
* items or navigating the metadata of media items in your library. Tags are
|
package/dist/src/myplex.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlexObject } from './base/plexObject.js';
|
|
2
|
-
import { Connection, Device, ResourcesResponse } from './myplex.types.js';
|
|
2
|
+
import type { Connection, Device, ResourcesResponse, WebLogin } from './myplex.types.js';
|
|
3
3
|
import { PlexServer } from './server.js';
|
|
4
4
|
/**
|
|
5
5
|
* MyPlex account and profile information. This object represents the data found Account on
|
|
@@ -16,6 +16,19 @@ export declare class MyPlexAccount {
|
|
|
16
16
|
timeout: number;
|
|
17
17
|
server?: PlexServer;
|
|
18
18
|
static key: string;
|
|
19
|
+
/**
|
|
20
|
+
* This follows the outline described in https://forums.plex.tv/t/authenticating-with-plex/609370
|
|
21
|
+
* to fetch a token and potentially compromise username and password. To use first call `getWebLogin()`
|
|
22
|
+
* and present the returned uri to a user to go to, then await `webLoginCheck()`. If you pass in a
|
|
23
|
+
* `forwardUrl`, then send the user to the returned uri, and when a request comes in on the passed in
|
|
24
|
+
* url, then await `webLoginCheck()`.
|
|
25
|
+
*/
|
|
26
|
+
static getWebLogin(forwardUrl?: string | null): Promise<WebLogin>;
|
|
27
|
+
/**
|
|
28
|
+
* Pass in the `webLogin` object obtained from `getWebLogin()` and this will poll Plex to see if
|
|
29
|
+
* the user agreed. It returns a connected `MyPlexAccount` or throws an error.
|
|
30
|
+
*/
|
|
31
|
+
static webLoginCheck(webLogin: WebLogin, timeoutSeconds?: number): Promise<MyPlexAccount>;
|
|
19
32
|
FRIENDINVITE: string;
|
|
20
33
|
HOMEUSERCREATE: string;
|
|
21
34
|
EXISTINGUSER: string;
|
|
@@ -136,7 +149,7 @@ export declare class MyPlexAccount {
|
|
|
136
149
|
*/
|
|
137
150
|
export declare class MyPlexResource {
|
|
138
151
|
readonly account: MyPlexAccount;
|
|
139
|
-
private baseUrl;
|
|
152
|
+
private readonly baseUrl;
|
|
140
153
|
static key: string;
|
|
141
154
|
TAG: string;
|
|
142
155
|
/** Descriptive name of this resource */
|
package/dist/src/myplex.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
2
2
|
import { ofetch } from 'ofetch';
|
|
3
3
|
import pAny from 'p-any';
|
|
4
4
|
import { parseStringPromise } from 'xml2js';
|
|
@@ -14,6 +14,71 @@ import { PlexServer } from './server.js';
|
|
|
14
14
|
*/
|
|
15
15
|
export class MyPlexAccount {
|
|
16
16
|
static { this.key = 'https://plex.tv/api/v2/user'; }
|
|
17
|
+
/**
|
|
18
|
+
* This follows the outline described in https://forums.plex.tv/t/authenticating-with-plex/609370
|
|
19
|
+
* to fetch a token and potentially compromise username and password. To use first call `getWebLogin()`
|
|
20
|
+
* and present the returned uri to a user to go to, then await `webLoginCheck()`. If you pass in a
|
|
21
|
+
* `forwardUrl`, then send the user to the returned uri, and when a request comes in on the passed in
|
|
22
|
+
* url, then await `webLoginCheck()`.
|
|
23
|
+
*/
|
|
24
|
+
static async getWebLogin(forwardUrl = null) {
|
|
25
|
+
const appName = BASE_HEADERS['X-Plex-Product'];
|
|
26
|
+
const clientIdentifier = BASE_HEADERS['X-Plex-Client-Identifier'];
|
|
27
|
+
const pin = await ofetch('https://plex.tv/api/v2/pins', {
|
|
28
|
+
method: 'post',
|
|
29
|
+
headers: {
|
|
30
|
+
Accept: 'application/json',
|
|
31
|
+
},
|
|
32
|
+
query: {
|
|
33
|
+
strong: 'true',
|
|
34
|
+
'X-Plex-Product': appName,
|
|
35
|
+
'X-Plex-Client-Identifier': clientIdentifier,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
...pin,
|
|
40
|
+
uri: `https://app.plex.tv/auth#?clientID=${encodeURIComponent(clientIdentifier)}&code=${encodeURIComponent(pin.code)}&context%5Bdevice%5D%5Bproduct%5D=${encodeURIComponent(appName)}${forwardUrl ? '&forwardUrl=' + encodeURIComponent(forwardUrl) : ''}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Pass in the `webLogin` object obtained from `getWebLogin()` and this will poll Plex to see if
|
|
45
|
+
* the user agreed. It returns a connected `MyPlexAccount` or throws an error.
|
|
46
|
+
*/
|
|
47
|
+
static async webLoginCheck(webLogin, timeoutSeconds = 60) {
|
|
48
|
+
const recheckMs = 3000;
|
|
49
|
+
const clientIdentifier = BASE_HEADERS['X-Plex-Client-Identifier'];
|
|
50
|
+
const uri = `https://plex.tv/api/v2/pins/${webLogin.id}`;
|
|
51
|
+
const startTime = Date.now();
|
|
52
|
+
while (Date.now() < startTime + timeoutSeconds * 1000) {
|
|
53
|
+
try {
|
|
54
|
+
const tokenResponse = await ofetch(uri, {
|
|
55
|
+
method: 'GET',
|
|
56
|
+
headers: {
|
|
57
|
+
Accept: 'application/json',
|
|
58
|
+
},
|
|
59
|
+
query: {
|
|
60
|
+
code: webLogin.code,
|
|
61
|
+
'X-Plex-Client-Identifier': clientIdentifier,
|
|
62
|
+
},
|
|
63
|
+
timeout: recheckMs,
|
|
64
|
+
retry: 5,
|
|
65
|
+
retryDelay: recheckMs,
|
|
66
|
+
});
|
|
67
|
+
if (tokenResponse.authToken) {
|
|
68
|
+
const myPlexAccount = new MyPlexAccount(null, '', '', tokenResponse.authToken);
|
|
69
|
+
return await myPlexAccount.connect();
|
|
70
|
+
}
|
|
71
|
+
await sleep(recheckMs);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
if (err.message.includes('aborted')) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
throw new Error('Failed to authenticate before timeout');
|
|
81
|
+
}
|
|
17
82
|
/**
|
|
18
83
|
*
|
|
19
84
|
* @param username Your MyPlex username
|
|
@@ -68,7 +133,6 @@ export class MyPlexAccount {
|
|
|
68
133
|
this._loadData(data);
|
|
69
134
|
return this;
|
|
70
135
|
}
|
|
71
|
-
// log('Logging in with token');
|
|
72
136
|
const data = await this.query(MyPlexAccount.key);
|
|
73
137
|
this._loadData(data);
|
|
74
138
|
return this;
|
package/dist/src/playlist.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Playable } from './base/playable.js';
|
|
2
2
|
import type { Section } from './library.js';
|
|
3
|
-
import { PlaylistResponse } from './playlist.types.js';
|
|
3
|
+
import type { PlaylistResponse } from './playlist.types.js';
|
|
4
4
|
import type { PlexServer } from './server.js';
|
|
5
|
-
import { Episode, Movie, VideoType } from './video.js';
|
|
5
|
+
import { Episode, Movie, type VideoType } from './video.js';
|
|
6
6
|
interface CreateRegularPlaylistOptions {
|
|
7
7
|
/** True to create a smart playlist */
|
|
8
8
|
smart?: false;
|
package/dist/src/playlist.js
CHANGED
|
@@ -99,10 +99,8 @@ export class Playlist extends Playable {
|
|
|
99
99
|
throw new BadRequest('Cannot remove items to a smart playlist.');
|
|
100
100
|
}
|
|
101
101
|
for (const item of items) {
|
|
102
|
-
// eslint-disable-next-line no-await-in-loop
|
|
103
102
|
const playlistItemId = await this._getPlaylistItemID(item);
|
|
104
103
|
const key = `${this.key}/items/${playlistItemId}`;
|
|
105
|
-
// eslint-disable-next-line no-await-in-loop
|
|
106
104
|
await this.server.query(key, 'delete');
|
|
107
105
|
}
|
|
108
106
|
}
|
package/dist/src/search.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ValueOf } from 'type-fest';
|
|
1
|
+
import type { ValueOf } from 'type-fest';
|
|
2
2
|
import { PlexObject } from './base/plexObject.js';
|
|
3
|
-
import { MatchSearchResult } from './search.types.js';
|
|
3
|
+
import type { MatchSearchResult } from './search.types.js';
|
|
4
4
|
export declare class SearchResult extends PlexObject {
|
|
5
5
|
static TAG: string;
|
|
6
6
|
guid: string;
|
package/dist/src/server.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { URL, URLSearchParams } from 'url';
|
|
3
2
|
import { PlexClient } from './client.js';
|
|
4
3
|
import { Hub, Library } from './library.js';
|
|
5
4
|
import { Optimized } from './media.js';
|
|
6
5
|
import { MyPlexAccount } from './myplex.js';
|
|
7
6
|
import { Agent, SEARCHTYPES } from './search.js';
|
|
8
|
-
import { HistoryMetadatum } from './server.types.js';
|
|
7
|
+
import type { HistoryMetadatum } from './server.types.js';
|
|
9
8
|
import { Settings } from './settings.js';
|
|
10
9
|
/**
|
|
11
10
|
* This is the main entry point to interacting with a Plex server. It allows you to
|
package/dist/src/server.js
CHANGED
|
@@ -156,7 +156,6 @@ export class PlexServer {
|
|
|
156
156
|
maxresults > results.length) {
|
|
157
157
|
args['X-Plex-Container-Start'] = (Number(args['X-Plex-Container-Start']) + Number(args['X-Plex-Container-Size'])).toString();
|
|
158
158
|
key = '/status/sessions/history/all?' + new URLSearchParams(args).toString();
|
|
159
|
-
// eslint-disable-next-line no-await-in-loop
|
|
160
159
|
raw = await this.query(key);
|
|
161
160
|
results = results.concat(raw.MediaContainer.Metadata);
|
|
162
161
|
}
|
|
@@ -185,7 +184,6 @@ export class PlexServer {
|
|
|
185
184
|
* you're likley to recieve an authentication error calling this.
|
|
186
185
|
*/
|
|
187
186
|
myPlexAccount() {
|
|
188
|
-
// eslint-disable-next-line logical-assignment-operators
|
|
189
187
|
if (!this._myPlexAccount) {
|
|
190
188
|
this._myPlexAccount = new MyPlexAccount(this.baseurl, undefined, undefined, this.token, this.timeout, this);
|
|
191
189
|
}
|
|
@@ -205,7 +203,6 @@ export class PlexServer {
|
|
|
205
203
|
}
|
|
206
204
|
for (const server of response.MediaContainer.Server) {
|
|
207
205
|
let { port } = server;
|
|
208
|
-
// eslint-disable-next-line logical-assignment-operators
|
|
209
206
|
if (!port) {
|
|
210
207
|
// TODO: print warning about doing weird port stuff
|
|
211
208
|
port = Number(ports?.[server.machineIdentifier]);
|
package/dist/src/settings.js
CHANGED
package/dist/src/video.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import { URL } from 'url';
|
|
1
|
+
import type { URL } from 'url';
|
|
3
2
|
import { Playable } from './base/playable.js';
|
|
4
|
-
import { ExtrasData, FullShowData, MovieData, ShowData } from './library.types.js';
|
|
3
|
+
import type { ExtrasData, FullShowData, MovieData, ShowData } from './library.types.js';
|
|
5
4
|
import { Chapter, Collection, Country, Director, Genre, Guid, Marker, Media, Poster, Producer, Rating, Role, Similar, Writer } from './media.js';
|
|
6
|
-
import { ChapterSource, EpisodeMetadata, FullMovieResponse } from './video.types.js';
|
|
5
|
+
import type { ChapterSource, EpisodeMetadata, FullMovieResponse } from './video.types.js';
|
|
7
6
|
export type VideoType = Movie | Show;
|
|
8
7
|
declare abstract class Video extends Playable {
|
|
9
8
|
/** Datetime this item was added to the library. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctrl/plex",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "plex api client in typescript",
|
|
5
5
|
"author": "Scott Cooper <scttcper@gmail.com>",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"typescript"
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
|
-
"lint": "
|
|
23
|
+
"lint": "pnpm run '/^(lint:biome|lint:eslint)$/'",
|
|
24
24
|
"lint:biome": "biome check .",
|
|
25
|
-
"lint:eslint": "eslint
|
|
26
|
-
"lint:fix": "
|
|
27
|
-
"lint:eslint:fix": "eslint
|
|
28
|
-
"lint:biome:fix": "biome check . --
|
|
25
|
+
"lint:eslint": "eslint .",
|
|
26
|
+
"lint:fix": "pnpm run '/^(lint:biome|lint:eslint):fix$/'",
|
|
27
|
+
"lint:eslint:fix": "eslint . --fix",
|
|
28
|
+
"lint:biome:fix": "biome check . --write",
|
|
29
29
|
"prepare": "npm run build",
|
|
30
30
|
"build": "tsc",
|
|
31
31
|
"build:docs": "typedoc",
|
|
@@ -37,37 +37,32 @@
|
|
|
37
37
|
"test-cleanup": "node --loader ts-node/esm scripts/test-cleanup.ts"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ctrl/mac-address": "^3.0
|
|
41
|
-
"ofetch": "^1.
|
|
40
|
+
"@ctrl/mac-address": "^3.1.0",
|
|
41
|
+
"ofetch": "^1.4.1",
|
|
42
42
|
"p-any": "^4.0.0",
|
|
43
|
-
"type-fest": "^4.
|
|
44
|
-
"ws": "^8.
|
|
43
|
+
"type-fest": "^4.40.1",
|
|
44
|
+
"ws": "^8.18.2",
|
|
45
45
|
"xml2js": "^0.6.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@biomejs/biome": "1.
|
|
49
|
-
"@ctrl/eslint-config-biome": "
|
|
50
|
-
"@sindresorhus/tsconfig": "
|
|
51
|
-
"@types/
|
|
52
|
-
"@types/
|
|
53
|
-
"@types/node": "20.12.8",
|
|
54
|
-
"@types/ws": "8.5.10",
|
|
48
|
+
"@biomejs/biome": "1.9.4",
|
|
49
|
+
"@ctrl/eslint-config-biome": "4.4.0",
|
|
50
|
+
"@sindresorhus/tsconfig": "7.0.0",
|
|
51
|
+
"@types/node": "22.15.3",
|
|
52
|
+
"@types/ws": "8.18.1",
|
|
55
53
|
"@types/xml2js": "0.4.14",
|
|
56
|
-
"@types/yargs": "17.0.
|
|
57
|
-
"@vitest/coverage-v8": "1.
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"glob": "10.3.12",
|
|
62
|
-
"globby": "14.0.1",
|
|
63
|
-
"lodash": "4.17.21",
|
|
54
|
+
"@types/yargs": "17.0.33",
|
|
55
|
+
"@vitest/coverage-v8": "3.1.2",
|
|
56
|
+
"eslint": "9.26.0",
|
|
57
|
+
"execa": "9.5.2",
|
|
58
|
+
"globby": "14.1.0",
|
|
64
59
|
"make-dir": "5.0.0",
|
|
65
|
-
"ora": "8.0
|
|
66
|
-
"p-retry": "6.2.
|
|
60
|
+
"ora": "8.2.0",
|
|
61
|
+
"p-retry": "6.2.1",
|
|
67
62
|
"ts-node": "10.9.2",
|
|
68
|
-
"typedoc": "0.
|
|
69
|
-
"typescript": "5.
|
|
70
|
-
"vitest": "1.
|
|
63
|
+
"typedoc": "0.28.3",
|
|
64
|
+
"typescript": "5.8.3",
|
|
65
|
+
"vitest": "3.1.2",
|
|
71
66
|
"yargs": "17.7.2"
|
|
72
67
|
},
|
|
73
68
|
"release": {
|
|
@@ -77,5 +72,6 @@
|
|
|
77
72
|
},
|
|
78
73
|
"engines": {
|
|
79
74
|
"node": ">=18"
|
|
80
|
-
}
|
|
75
|
+
},
|
|
76
|
+
"packageManager": "pnpm@10.10.0"
|
|
81
77
|
}
|