Skip to content

Commit

Permalink
Bump Node.js environment to 18.x
Browse files Browse the repository at this point in the history
- Bump Node.js to version 18. This change is necessary as Node.js v16
  will reach end-of-life on 2023-09-11. It also ensure compatibility
  with dependencies requiring minimum of Node.js v18, such as `vite`,
  `@vitejs`plugin-legacy` and `icon-gen`.
- Bump `setup-node` action to v4.
- Recommend using the `nvm` tool for managing Node.js versions in the
  documentation.
- Update documentation to point to code reference for required Node.js
  version. This removes duplication of information, and keeps the code
  as single source of truth for required Node.js version.
- Refactor code to adopt the `node:` protocol for Node API imports as
  per Node.js 18 standards. This change addresses ambiguities and aligns
  with Node.js best practices (nodejs/node#38343). Currently, there is
  no ESLint rule to enforce this protocol, as noted in
  import-js/eslint-plugin-import#2717.
- Replace `cross-fetch` dependency with the native Node.js fetch API
  introduced in Node.js 18. Adjust type casting for async iterable read
  streams to align with the latest Node.js APIs, based on discussions in
  DefinitelyTyped/DefinitelyTyped#65542.
  • Loading branch information
undergroundwires committed Dec 28, 2023
1 parent fc9dd23 commit 2f06043
Show file tree
Hide file tree
Showing 28 changed files with 60 additions and 148 deletions.
4 changes: 2 additions & 2 deletions .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ runs:
steps:
-
name: Setup node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 18.x
4 changes: 3 additions & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ See [ci-cd.md](./ci-cd.md) for more information.

### Prerequisites

- Install Node >16.x.
- Install Node.js:
- Refer to [action.yml](./../.github/actions/setup-node/action.yml) for the minimum required version compatible with the automated workflows.
- 💡 Recommended: Use [`nvm`](https://github.com/nvm-sh/nvm) CLI to install and switch between Node.js versions.
- Install dependencies using `npm install` (or [`npm run install-deps`](#utility-scripts) for more options).

### Testing
Expand Down
2 changes: 1 addition & 1 deletion electron-builder.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-template-curly-in-string */

const { join } = require('path');
const { join } = require('node:path');
const { electronBundled, electronUnbundled } = require('./dist-dirs.json');

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion electron.vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { resolve } from 'path';
import { resolve } from 'node:path';
import { mergeConfig, UserConfig } from 'vite';
import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
import { getAliasesFromTsConfig, getClientEnvironmentVariables } from './vite-config-helper';
Expand Down
86 changes: 1 addition & 85 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"@floating-ui/vue": "^1.0.2",
"@juggle/resize-observer": "^3.4.0",
"ace-builds": "^1.30.0",
"cross-fetch": "^4.0.0",
"electron-log": "^5.0.1",
"electron-progressbar": "^2.1.0",
"electron-updater": "^6.1.4",
Expand Down
8 changes: 4 additions & 4 deletions scripts/logo-update.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
import { resolve, join } from 'path';
import { rm, mkdtemp, stat } from 'fs/promises';
import { spawn } from 'child_process';
import { URL, fileURLToPath } from 'url';
import { resolve, join } from 'node:path';
import { rm, mkdtemp, stat } from 'node:fs/promises';
import { spawn } from 'node:child_process';
import { URL, fileURLToPath } from 'node:url';

class Paths {
constructor(selfDirectory) {
Expand Down
8 changes: 4 additions & 4 deletions scripts/npm-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ Note:
Example: npm run install-deps -- --fresh --non-deterministic
*/

import { exec } from 'child_process';
import { resolve } from 'path';
import { access, rm, unlink } from 'fs/promises';
import { constants } from 'fs';
import { exec } from 'node:child_process';
import { resolve } from 'node:path';
import { access, rm, unlink } from 'node:fs/promises';
import { constants } from 'node:fs';

const MAX_RETRIES = 5;
const RETRY_DELAY_IN_MS = 5 /* seconds */ * 1000;
Expand Down
4 changes: 2 additions & 2 deletions scripts/print-dist-dir.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
* --web Path for the web application
*/

import { resolve } from 'path';
import { readFile } from 'fs/promises';
import { resolve } from 'node:path';
import { readFile } from 'node:fs/promises';

const DIST_DIRS_JSON_FILE_PATH = resolve(process.cwd(), 'dist-dirs.json'); // cannot statically import because ESLint does not support it https://github.com/eslint/eslint/discussions/15305
const CLI_ARGUMENTS = process.argv.slice(2);
Expand Down
6 changes: 3 additions & 3 deletions scripts/verify-build-artifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
* --web Verify artifacts for the web application.
*/

import { access, readdir } from 'fs/promises';
import { exec } from 'child_process';
import { resolve } from 'path';
import { access, readdir } from 'node:fs/promises';
import { exec } from 'node:child_process';
import { resolve } from 'node:path';

const PROCESS_ARGUMENTS = process.argv.slice(2);
const PRINT_DIST_DIR_SCRIPT_BASE_COMMAND = 'node scripts/print-dist-dir';
Expand Down
2 changes: 1 addition & 1 deletion src/presentation/electron/main/ElectronConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

/// <reference types="electron-vite/node" />
import { join } from 'path';
import { join } from 'node:path';
import appIcon from '@/presentation/public/icon.png?asset';

export const APP_ICON_PATH = appIcon;
Expand Down
27 changes: 13 additions & 14 deletions src/presentation/electron/main/Update/ManualUpdater/Downloader.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { existsSync, createWriteStream } from 'fs';
import { unlink, mkdir } from 'fs/promises';
import path from 'path';
import { existsSync, createWriteStream, type WriteStream } from 'node:fs';
import { unlink, mkdir } from 'node:fs/promises';
import path from 'node:path';
import { app } from 'electron';
import { UpdateInfo } from 'electron-updater';
import fetch from 'cross-fetch';
import { ElectronLogger } from '@/infrastructure/Log/ElectronLogger';
import { UpdateProgressBar } from '../UpdateProgressBar';
import { retryFileSystemAccess } from './RetryFileSystemAccess';
import type { WriteStream } from 'fs';
import type { Readable } from 'stream';
import type { ReadableStream } from 'node:stream/web';

const MAX_PROGRESS_LOG_ENTRIES = 10;
const UNKNOWN_SIZE_LOG_INTERVAL_BYTES = 10 * 1024 * 1024; // 10 MB
Expand Down Expand Up @@ -128,13 +126,13 @@ function getContentLengthFromResponse(response: Response): ResponseContentLength

async function withReadableStream(
response: Response,
handler: (readStream: Readable) => Promise<void>,
handler: (readStream: ReadableStream) => Promise<void>,
) {
const reader = createReader(response);
try {
await handler(reader);
} finally {
reader.destroy();
reader.cancel();
}
}

Expand All @@ -152,7 +150,7 @@ async function withWriteStream(

async function streamWithProgress(
contentLength: ResponseContentLength,
readStream: Readable,
readStream: ReadableStream,
writeStream: WriteStream,
progressHandler: ProgressCallback,
): Promise<void> {
Expand Down Expand Up @@ -212,12 +210,13 @@ function shouldLogProgress(
return { shouldLog: false, nextLogThreshold: previousLogThreshold };
}

function createReader(response: Response): Readable {
function createReader(response: Response): ReadableStream {
if (!response.body) {
throw new Error('Response body is empty, cannot proceed with download.');
}
// On browser, we could use browser API response.body.getReader()
// But here, we use cross-fetch that gets node-fetch on a node application
// This API is node-fetch specific, see https://github.com/node-fetch/node-fetch#streams
return response.body as unknown as Readable;
// TypeScript has removed the async iterator type definition for ReadableStream due to
// limited browser support. Node.js, however, supports async iterable streams, allowing
// type casting to function properly in this context.
// https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/65542#discussioncomment-6071004
return response.body as ReadableStream;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createHash } from 'crypto';
import { createReadStream } from 'fs';
import { createHash } from 'node:crypto';
import { createReadStream } from 'node:fs';
import { ElectronLogger } from '@/infrastructure/Log/ElectronLogger';
import { retryFileSystemAccess } from './RetryFileSystemAccess';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unlink, readFile } from 'fs/promises';
import { join } from 'path';
import { unlink, readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { log, die, LogLevel } from '../utils/log';
import { exists } from '../utils/io';
import { SupportedPlatform, CURRENT_PLATFORM } from '../utils/platform';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { join } from 'path';
import { readdir } from 'fs/promises';
import { join } from 'node:path';
import { readdir } from 'node:fs/promises';
import { die } from '../../../utils/log';
import { exists } from '../../../utils/io';
import { getAppName } from '../../../utils/npm';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { access, chmod } from 'fs/promises';
import { constants } from 'fs';
import { access, chmod } from 'node:fs/promises';
import { constants } from 'node:fs';
import { log } from '../../utils/log';
import { ExtractionResult } from './common/extraction-result';
import { findByFilePattern } from './common/app-artifact-locator';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mkdtemp, rm } from 'fs/promises';
import { join } from 'path';
import { tmpdir } from 'os';
import { mkdtemp, rm } from 'node:fs/promises';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { exists } from '../../utils/io';
import { log, die, LogLevel } from '../../utils/log';
import { runCommand } from '../../utils/run-command';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { spawn } from 'child_process';
import { spawn, type ChildProcess } from 'node:child_process';
import { log, LogLevel, die } from '../utils/log';
import { captureScreen } from './system-capture/screen-capture';
import { captureWindowTitles } from './system-capture/window-title-capture';
import type { ChildProcess } from 'child_process';

const TERMINATION_GRACE_PERIOD_IN_SECONDS = 20;
const TERMINATION_CHECK_INTERVAL_IN_MS = 1000;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { unlink } from 'fs/promises';
import { unlink } from 'node:fs/promises';
import { runCommand } from '../../utils/run-command';
import { log, LogLevel } from '../../utils/log';
import { CURRENT_PLATFORM, SupportedPlatform } from '../../utils/platform';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { join } from 'path';
import { join } from 'node:path';
import distDirs from '@/../dist-dirs.json' assert { type: 'json' };

export const DESKTOP_BUILD_COMMAND = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readdir, access } from 'fs/promises';
import { constants } from 'fs';
import { readdir, access } from 'node:fs/promises';
import { constants } from 'node:fs';

export async function exists(path: string): Promise<boolean> {
if (!path) { throw new Error('Missing path'); }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { join } from 'path';
import { rm, readFile } from 'fs/promises';
import { join } from 'node:path';
import { rm, readFile } from 'node:fs/promises';
import { exists, isDirMissingOrEmpty } from './io';
import { runCommand } from './run-command';
import { LogLevel, die, log } from './log';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { platform } from 'os';
import { platform } from 'node:os';
import { die } from './log';

export enum SupportedPlatform {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { exec } from 'child_process';
import { exec, type ExecOptions, type ExecException } from 'node:child_process';
import { indentText } from './text';
import type { ExecOptions, ExecException } from 'child_process';

const TIMEOUT_IN_SECONDS = 180;
const MAX_OUTPUT_BUFFER_SIZE = 1024 * 1024; // 1 MB
Expand Down
2 changes: 0 additions & 2 deletions tests/checks/external-urls/StatusChecker/FetchWithTimeout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import fetch from 'cross-fetch';

export async function fetchWithTimeout(
url: string,
timeoutInMs: number,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readdirSync, readFileSync } from 'fs';
import { resolve, join, basename } from 'path';
import { readdirSync, readFileSync } from 'node:fs';
import { resolve, join, basename } from 'node:path';
import { describe, it, expect } from 'vitest';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';

Expand Down
Loading

0 comments on commit 2f06043

Please sign in to comment.