eas-cli 11.0.3 → 12.1.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 (41) hide show
  1. package/README.md +60 -60
  2. package/build/build/build.js +8 -45
  3. package/build/build/configure.js +4 -1
  4. package/build/build/evaluateConfigWithEnvVarsAsync.d.ts +2 -1
  5. package/build/build/evaluateConfigWithEnvVarsAsync.js +31 -9
  6. package/build/build/graphql.d.ts +2 -1
  7. package/build/build/graphql.js +13 -2
  8. package/build/build/local.js +1 -1
  9. package/build/build/runBuildAndSubmit.js +12 -2
  10. package/build/build/types.d.ts +20 -0
  11. package/build/commands/build/resign.js +1 -0
  12. package/build/commands/build/version/get.js +1 -0
  13. package/build/commands/build/version/set.js +1 -0
  14. package/build/commands/build/version/sync.js +1 -0
  15. package/build/commands/config.js +1 -0
  16. package/build/commands/project/onboarding.js +3 -0
  17. package/build/commands/update/index.js +22 -5
  18. package/build/commands/update/roll-back-to-embedded.js +6 -6
  19. package/build/commands/worker/deploy.d.ts +15 -0
  20. package/build/commands/worker/deploy.js +181 -0
  21. package/build/credentials/ios/appstore/bundleIdCapabilities.js +41 -0
  22. package/build/graphql/generated.d.ts +301 -53
  23. package/build/graphql/generated.js +72 -12
  24. package/build/project/maybeUploadFingerprintAsync.d.ts +15 -0
  25. package/build/project/maybeUploadFingerprintAsync.js +57 -0
  26. package/build/project/publish.d.ts +16 -11
  27. package/build/project/publish.js +33 -30
  28. package/build/project/remoteVersionSource.d.ts +8 -1
  29. package/build/project/remoteVersionSource.js +94 -5
  30. package/build/project/resolveRuntimeVersionAsync.d.ts +13 -0
  31. package/build/project/resolveRuntimeVersionAsync.js +21 -17
  32. package/build/worker/assets.d.ts +25 -0
  33. package/build/worker/assets.js +110 -0
  34. package/build/worker/deployment.d.ts +6 -0
  35. package/build/worker/deployment.js +57 -0
  36. package/build/worker/mutations.d.ts +11 -0
  37. package/build/worker/mutations.js +45 -0
  38. package/build/worker/upload.d.ts +20 -0
  39. package/build/worker/upload.js +141 -0
  40. package/oclif.manifest.json +22 -1
  41. package/package.json +8 -5
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.packFilesIterableAsync = exports.listAssetMapFilesAsync = exports.listWorkerFilesAsync = exports.createAssetMapAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const minizlib_1 = require("minizlib");
6
+ const node_crypto_1 = require("node:crypto");
7
+ const node_fs_1 = tslib_1.__importStar(require("node:fs"));
8
+ const node_os_1 = tslib_1.__importDefault(require("node:os"));
9
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
10
+ const promises_1 = require("node:stream/promises");
11
+ const tar_stream_1 = require("tar-stream");
12
+ /** Returns whether a file or folder is ignored */
13
+ function isIgnoredName(name) {
14
+ switch (name) {
15
+ // macOS system files
16
+ case '.DS_Store':
17
+ case '.AppleDouble':
18
+ case '.Trashes':
19
+ case '__MACOSX':
20
+ case '.LSOverride':
21
+ return true;
22
+ default:
23
+ // Backup file name convention
24
+ return name.endsWith('~');
25
+ }
26
+ }
27
+ /** Creates a temporary file write path */
28
+ async function createTempWritePathAsync() {
29
+ const basename = node_path_1.default.basename(__filename, node_path_1.default.extname(__filename));
30
+ const tmpdir = await node_fs_1.default.promises.realpath(node_os_1.default.tmpdir());
31
+ const random = (0, node_crypto_1.randomBytes)(4).toString('hex');
32
+ return node_path_1.default.resolve(tmpdir, `tmp-${basename}-${process.pid}-${random}`);
33
+ }
34
+ /** Computes a SHA512 hash for a file */
35
+ async function computeSha512HashAsync(filePath, options) {
36
+ const hash = (0, node_crypto_1.createHash)('sha512', { encoding: 'hex', ...options });
37
+ await (0, promises_1.pipeline)(node_fs_1.default.createReadStream(filePath), hash);
38
+ return `${hash.read()}`;
39
+ }
40
+ /** Lists plain files in base path recursively and outputs normalized paths */
41
+ function listFilesRecursively(basePath) {
42
+ async function* recurseAsync(parentPath) {
43
+ const target = parentPath ? node_path_1.default.resolve(basePath, parentPath) : basePath;
44
+ const entries = await node_fs_1.default.promises.readdir(target, { withFileTypes: true });
45
+ for (const dirent of entries) {
46
+ const normalizedPath = parentPath ? `${parentPath}/${dirent.name}` : dirent.name;
47
+ if (isIgnoredName(dirent.name)) {
48
+ continue;
49
+ }
50
+ else if (dirent.isFile()) {
51
+ yield {
52
+ normalizedPath,
53
+ path: node_path_1.default.resolve(target, dirent.name),
54
+ };
55
+ }
56
+ else if (dirent.isDirectory()) {
57
+ yield* recurseAsync(normalizedPath);
58
+ }
59
+ }
60
+ }
61
+ return recurseAsync();
62
+ }
63
+ /** Creates an asset map of a given target path */
64
+ async function createAssetMapAsync(assetPath, options) {
65
+ const map = Object.create(null);
66
+ for await (const file of listFilesRecursively(assetPath)) {
67
+ map[file.normalizedPath] = await computeSha512HashAsync(file.path, options?.hashOptions);
68
+ }
69
+ return map;
70
+ }
71
+ exports.createAssetMapAsync = createAssetMapAsync;
72
+ /** Reads worker files while normalizing sourcemaps and providing normalized paths */
73
+ async function* listWorkerFilesAsync(workerPath) {
74
+ for await (const file of listFilesRecursively(workerPath)) {
75
+ yield {
76
+ normalizedPath: file.normalizedPath,
77
+ path: file.path,
78
+ data: await node_fs_1.default.promises.readFile(file.path),
79
+ };
80
+ }
81
+ }
82
+ exports.listWorkerFilesAsync = listWorkerFilesAsync;
83
+ /** Reads files of an asset maps and enumerates normalized paths and data */
84
+ async function* listAssetMapFilesAsync(assetPath, assetMap) {
85
+ for (const normalizedPath in assetMap) {
86
+ const filePath = node_path_1.default.resolve(assetPath, normalizedPath.split('/').join(node_path_1.default.sep));
87
+ const data = await node_fs_1.default.promises.readFile(filePath);
88
+ yield {
89
+ normalizedPath,
90
+ path: filePath,
91
+ data,
92
+ };
93
+ }
94
+ }
95
+ exports.listAssetMapFilesAsync = listAssetMapFilesAsync;
96
+ /** Packs file entries into a tar.gz file (path to tgz returned) */
97
+ async function packFilesIterableAsync(iterable, options) {
98
+ const writePath = `${await createTempWritePathAsync()}.tar.gz`;
99
+ const write = (0, node_fs_1.createWriteStream)(writePath);
100
+ const gzip = new minizlib_1.Gzip({ portable: true, ...options });
101
+ const tar = (0, tar_stream_1.pack)();
102
+ const writeTask$ = (0, promises_1.pipeline)(tar, gzip, write);
103
+ for await (const file of iterable) {
104
+ tar.entry({ name: file[0], type: 'file' }, file[1]);
105
+ }
106
+ tar.finalize();
107
+ await writeTask$;
108
+ return writePath;
109
+ }
110
+ exports.packFilesIterableAsync = packFilesIterableAsync;
@@ -0,0 +1,6 @@
1
+ import { ExpoConfig } from '@expo/config-types';
2
+ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
3
+ export declare function getSignedDeploymentUrlAsync(graphqlClient: ExpoGraphqlClient, exp: ExpoConfig, deploymentVariables: {
4
+ appId: string;
5
+ deploymentIdentifier?: string | null;
6
+ }): Promise<string>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSignedDeploymentUrlAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const mutations_1 = require("./mutations");
6
+ const log_1 = tslib_1.__importDefault(require("../log"));
7
+ const prompts_1 = require("../prompts");
8
+ async function getSignedDeploymentUrlAsync(graphqlClient, exp, deploymentVariables) {
9
+ try {
10
+ return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, deploymentVariables);
11
+ }
12
+ catch (error) {
13
+ const isMissingDevDomain = error?.graphQLErrors?.some(e => ['APP_NO_DEV_DOMAIN_NAME'].includes(e?.extensions?.errorCode));
14
+ if (!isMissingDevDomain) {
15
+ throw error;
16
+ }
17
+ await chooseDevDomainNameAsync({
18
+ graphqlClient,
19
+ appId: deploymentVariables.appId,
20
+ slug: exp.slug,
21
+ });
22
+ return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, deploymentVariables);
23
+ }
24
+ }
25
+ exports.getSignedDeploymentUrlAsync = getSignedDeploymentUrlAsync;
26
+ async function chooseDevDomainNameAsync({ graphqlClient, appId, slug, }) {
27
+ const validationMessage = 'The project does not have a dev domain name.';
28
+ const { name } = await (0, prompts_1.promptAsync)({
29
+ type: 'text',
30
+ name: 'name',
31
+ message: 'Choose a dev domain name for your project:',
32
+ validate: value => (value && value.length > 3 ? true : validationMessage),
33
+ initial: slug,
34
+ });
35
+ if (!name) {
36
+ throw new Error('Prompt failed');
37
+ }
38
+ try {
39
+ const success = await mutations_1.DeploymentsMutation.assignDevDomainNameAsync(graphqlClient, {
40
+ appId,
41
+ name,
42
+ });
43
+ if (!success) {
44
+ throw new Error('Failed to assign dev domain name');
45
+ }
46
+ }
47
+ catch (error) {
48
+ const isChosenNameTaken = error?.graphQLErrors?.some(e => ['DEV_DOMAIN_NAME_TAKEN'].includes(e?.extensions?.errorCode));
49
+ if (isChosenNameTaken) {
50
+ log_1.default.error(`The entered dev domain name "${name}" is taken. Choose a different name.`);
51
+ await chooseDevDomainNameAsync({ graphqlClient, appId, slug });
52
+ }
53
+ if (!isChosenNameTaken) {
54
+ throw error;
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,11 @@
1
+ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
2
+ export declare const DeploymentsMutation: {
3
+ createSignedDeploymentUrlAsync(graphqlClient: ExpoGraphqlClient, deploymentVariables: {
4
+ appId: string;
5
+ deploymentIdentifier?: string | null;
6
+ }): Promise<string>;
7
+ assignDevDomainNameAsync(graphqlClient: ExpoGraphqlClient, devDomainNameVariables: {
8
+ appId: string;
9
+ name: string;
10
+ }): Promise<boolean>;
11
+ };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeploymentsMutation = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const assert_1 = tslib_1.__importDefault(require("assert"));
6
+ const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
7
+ const client_1 = require("../graphql/client");
8
+ exports.DeploymentsMutation = {
9
+ async createSignedDeploymentUrlAsync(graphqlClient, deploymentVariables) {
10
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
11
+ .mutation((0, graphql_tag_1.default) `
12
+ mutation createDeploymentUrlMutation($appId: ID!, $deploymentIdentifier: ID) {
13
+ deployments {
14
+ createSignedDeploymentUrl(
15
+ appId: $appId
16
+ deploymentIdentifier: $deploymentIdentifier
17
+ ) {
18
+ pendingWorkerDeploymentId
19
+ deploymentIdentifier
20
+ url
21
+ }
22
+ }
23
+ }
24
+ `, deploymentVariables)
25
+ .toPromise());
26
+ const url = data.deployments?.createSignedDeploymentUrl.url;
27
+ (0, assert_1.default)(url, 'Deployment URL must be defined');
28
+ return url;
29
+ },
30
+ async assignDevDomainNameAsync(graphqlClient, devDomainNameVariables) {
31
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
32
+ .mutation((0, graphql_tag_1.default) `
33
+ mutation AssignDevDomainName($appId: ID!, $name: DevDomainName!) {
34
+ devDomainName {
35
+ assignDevDomainName(appId: $appId, name: $name) {
36
+ id
37
+ name
38
+ }
39
+ }
40
+ }
41
+ `, devDomainNameVariables)
42
+ .toPromise());
43
+ return data.devDomainName.assignDevDomainName.name === devDomainNameVariables.name;
44
+ },
45
+ };
@@ -0,0 +1,20 @@
1
+ import { HeadersInit, RequestInit, Response } from 'node-fetch';
2
+ export interface UploadParams extends Omit<RequestInit, 'signal' | 'body'> {
3
+ filePath: string;
4
+ compress?: boolean;
5
+ url: string;
6
+ method?: string;
7
+ headers?: HeadersInit;
8
+ body?: undefined;
9
+ signal?: AbortSignal;
10
+ }
11
+ export interface UploadResult {
12
+ params: UploadParams;
13
+ response: Response;
14
+ }
15
+ export declare function uploadAsync(params: UploadParams): Promise<UploadResult>;
16
+ export interface UploadPending {
17
+ params: UploadParams;
18
+ }
19
+ export type BatchUploadSignal = UploadResult | UploadPending;
20
+ export declare function batchUploadAsync(uploads: readonly UploadParams[]): AsyncGenerator<BatchUploadSignal>;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.batchUploadAsync = exports.uploadAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const https = tslib_1.__importStar(require("https"));
6
+ const https_proxy_agent_1 = tslib_1.__importDefault(require("https-proxy-agent"));
7
+ const mime_1 = tslib_1.__importDefault(require("mime"));
8
+ const minizlib_1 = require("minizlib");
9
+ const node_fetch_1 = tslib_1.__importStar(require("node-fetch"));
10
+ const node_fs_1 = tslib_1.__importStar(require("node:fs"));
11
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
12
+ const promise_retry_1 = tslib_1.__importDefault(require("promise-retry"));
13
+ const MAX_RETRIES = 4;
14
+ const MAX_CONCURRENCY = 10;
15
+ const MIN_RETRY_TIMEOUT = 100;
16
+ const MAX_UPLOAD_SIZE = 5e8; // 5MB
17
+ const MIN_COMPRESSION_SIZE = 5e4; // 50kB
18
+ const isCompressible = (contentType, size) => {
19
+ if (size < MIN_COMPRESSION_SIZE) {
20
+ // Don't compress small files
21
+ return false;
22
+ }
23
+ else if (contentType && /^(?:audio|video|image)\//i.test(contentType)) {
24
+ // Never compress images, audio, or videos as they're presumably precompressed
25
+ return false;
26
+ }
27
+ else if (contentType && /^application\//i.test(contentType)) {
28
+ // Only compress `application/` files if they're marked as XML/JSON/JS
29
+ return /(?:xml|json5?|javascript)$/i.test(contentType);
30
+ }
31
+ else {
32
+ return true;
33
+ }
34
+ };
35
+ let sharedAgent;
36
+ const getAgent = () => {
37
+ if (sharedAgent) {
38
+ return sharedAgent;
39
+ }
40
+ else if (process.env.https_proxy) {
41
+ return (sharedAgent = (0, https_proxy_agent_1.default)(process.env.https_proxy));
42
+ }
43
+ else {
44
+ return (sharedAgent = new https.Agent({
45
+ keepAlive: true,
46
+ maxSockets: MAX_CONCURRENCY,
47
+ maxTotalSockets: MAX_CONCURRENCY,
48
+ scheduling: 'lifo',
49
+ timeout: 4000,
50
+ }));
51
+ }
52
+ };
53
+ async function uploadAsync(params) {
54
+ const { filePath, signal, compress, method = 'POST', url, headers: headersInit, ...requestInit } = params;
55
+ const stat = await node_fs_1.default.promises.stat(params.filePath);
56
+ if (stat.size > MAX_UPLOAD_SIZE) {
57
+ throw new Error(`Upload of "${params.filePath}" aborted: File size is greater than the upload limit (>500MB)`);
58
+ }
59
+ const contentType = mime_1.default.getType(node_path_1.default.basename(params.filePath));
60
+ return await (0, promise_retry_1.default)(async (retry) => {
61
+ const headers = new node_fetch_1.Headers(headersInit);
62
+ if (contentType) {
63
+ headers.set('content-type', contentType);
64
+ }
65
+ let bodyStream = (0, node_fs_1.createReadStream)(filePath);
66
+ if (compress && isCompressible(contentType, stat.size)) {
67
+ const gzip = new minizlib_1.Gzip({ portable: true });
68
+ bodyStream.on('error', error => gzip.emit('error', error));
69
+ // @ts-expect-error: Gzip implements a Readable-like interface
70
+ bodyStream = bodyStream.pipe(gzip);
71
+ headers.set('content-encoding', 'gzip');
72
+ }
73
+ let response;
74
+ try {
75
+ response = await (0, node_fetch_1.default)(params.url, {
76
+ ...requestInit,
77
+ method,
78
+ body: bodyStream,
79
+ headers,
80
+ agent: getAgent(),
81
+ // @ts-expect-error: Internal types don't match
82
+ signal,
83
+ });
84
+ }
85
+ catch (error) {
86
+ return retry(error);
87
+ }
88
+ if (response.status === 408 ||
89
+ response.status === 409 ||
90
+ response.status === 429 ||
91
+ (response.status >= 500 && response.status <= 599)) {
92
+ const message = `Upload of "${filePath}" failed: ${response.statusText}`;
93
+ const text = await response.text().catch(() => null);
94
+ return retry(new Error(text ? `${message}\n${text}` : message));
95
+ }
96
+ else if (response.status === 413) {
97
+ const message = `Upload of "${filePath}" failed: File size exceeded the upload limit`;
98
+ throw new Error(message);
99
+ }
100
+ else if (!response.ok) {
101
+ throw new Error(`Upload of "${filePath}" failed: ${response.statusText}`);
102
+ }
103
+ return {
104
+ params,
105
+ response,
106
+ };
107
+ }, {
108
+ retries: MAX_RETRIES,
109
+ minTimeout: MIN_RETRY_TIMEOUT,
110
+ randomize: true,
111
+ factor: 2,
112
+ });
113
+ }
114
+ exports.uploadAsync = uploadAsync;
115
+ async function* batchUploadAsync(uploads) {
116
+ const controller = new AbortController();
117
+ const queue = new Set();
118
+ try {
119
+ let index = 0;
120
+ while (index < uploads.length || queue.size > 0) {
121
+ while (queue.size < MAX_CONCURRENCY && index < uploads.length) {
122
+ const uploadParams = uploads[index++];
123
+ let uploadPromise;
124
+ queue.add((uploadPromise = uploadAsync({ ...uploadParams, signal: controller.signal }).finally(() => queue.delete(uploadPromise))));
125
+ yield { params: uploadParams };
126
+ }
127
+ yield await Promise.race(queue);
128
+ }
129
+ }
130
+ catch (error) {
131
+ if (typeof error !== 'object' || error.name !== 'AbortError') {
132
+ throw error;
133
+ }
134
+ }
135
+ finally {
136
+ if (queue.size > 0) {
137
+ controller.abort();
138
+ }
139
+ }
140
+ }
141
+ exports.batchUploadAsync = batchUploadAsync;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "11.0.3",
2
+ "version": "12.1.0",
3
3
  "commands": {
4
4
  "analytics": {
5
5
  "id": "analytics",
@@ -3378,6 +3378,27 @@
3378
3378
  "loggedIn": {}
3379
3379
  }
3380
3380
  },
3381
+ "worker:deploy": {
3382
+ "id": "worker:deploy",
3383
+ "description": "deploy an Expo web build",
3384
+ "strict": true,
3385
+ "pluginName": "eas-cli",
3386
+ "pluginAlias": "eas-cli",
3387
+ "pluginType": "core",
3388
+ "hidden": true,
3389
+ "state": "beta",
3390
+ "aliases": [
3391
+ "deploy"
3392
+ ],
3393
+ "flags": {},
3394
+ "args": {},
3395
+ "contextDefinition": {
3396
+ "getDynamicPublicProjectConfigAsync": {},
3397
+ "getDynamicPrivateProjectConfigAsync": {},
3398
+ "projectDir": {},
3399
+ "loggedIn": {}
3400
+ }
3401
+ },
3381
3402
  "build:version:get": {
3382
3403
  "id": "build:version:get",
3383
3404
  "description": "get the latest version from EAS servers",
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "eas-cli",
3
3
  "description": "EAS command line tool",
4
- "version": "11.0.3",
4
+ "version": "12.1.0",
5
5
  "author": "Expo <support@expo.dev>",
6
6
  "bin": {
7
7
  "eas": "./bin/run"
8
8
  },
9
9
  "bugs": "https://github.com/expo/eas-cli/issues",
10
10
  "dependencies": {
11
- "@expo/apple-utils": "1.7.1",
11
+ "@expo/apple-utils": "1.8.0",
12
12
  "@expo/code-signing-certificates": "0.0.5",
13
13
  "@expo/config": "8.5.4",
14
14
  "@expo/config-plugins": "7.8.4",
15
15
  "@expo/config-types": "50.0.0",
16
16
  "@expo/eas-build-job": "1.0.133",
17
- "@expo/eas-json": "11.0.0",
17
+ "@expo/eas-json": "12.0.0",
18
18
  "@expo/json-file": "8.2.37",
19
19
  "@expo/logger": "1.0.117",
20
20
  "@expo/multipart-body-parser": "1.1.0",
@@ -28,7 +28,7 @@
28
28
  "@expo/results": "1.0.0",
29
29
  "@expo/rudder-sdk-node": "1.1.1",
30
30
  "@expo/spawn-async": "1.7.0",
31
- "@expo/steps": "1.0.130",
31
+ "@expo/steps": "1.0.134",
32
32
  "@expo/timeago.js": "1.0.0",
33
33
  "@oclif/core": "^1.26.2",
34
34
  "@oclif/plugin-autocomplete": "^2.3.10",
@@ -63,6 +63,7 @@
63
63
  "log-symbols": "4.1.0",
64
64
  "mime": "3.0.0",
65
65
  "minimatch": "5.1.2",
66
+ "minizlib": "3.0.1",
66
67
  "nanoid": "3.3.4",
67
68
  "node-fetch": "2.6.7",
68
69
  "node-forge": "1.3.1",
@@ -78,6 +79,7 @@
78
79
  "semver": "7.5.4",
79
80
  "slash": "3.0.0",
80
81
  "tar": "6.2.1",
82
+ "tar-stream": "3.1.7",
81
83
  "terminal-link": "2.1.1",
82
84
  "tslib": "2.6.2",
83
85
  "turndown": "7.1.2",
@@ -105,6 +107,7 @@
105
107
  "@types/prompts": "2.4.2",
106
108
  "@types/semver": "7.5.6",
107
109
  "@types/tar": "6.1.10",
110
+ "@types/tar-stream": "3.1.3",
108
111
  "@types/tough-cookie": "4.0.2",
109
112
  "@types/uuid": "9.0.7",
110
113
  "@types/wrap-ansi": "3.0.0",
@@ -223,5 +226,5 @@
223
226
  "node": "20.11.0",
224
227
  "yarn": "1.22.21"
225
228
  },
226
- "gitHead": "56d492cbac7b2c198b13c80e56efc637869465f5"
229
+ "gitHead": "e993e9a370e5823d3c413f7edf0cbec7a6395c32"
227
230
  }