Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core electron + core backend ESM #7293

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions core/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
"version": "4.10.0-dev.33",
"description": "iTwin.js backend components",
"main": "lib/cjs/core-backend.js",
"module": "lib/esm/core-backend.js",
"typings": "lib/cjs/core-backend",
"license": "MIT",
"engines": {
"node": "^18.0.0 || ^20.0.0"
},
"scripts": {
"build": "npm run -s build:cjs && npm run -s copy:assets && npm run -s copy:test-assets",
"build": "npm run -s build:cjs && npm run -s build:esm && npm run -s copy:assets && npm run -s copy:test-assets",
"build:cjs": "tsc 1>&2 --outDir lib/cjs",
"build:esm": "tsc 1>&2 --module ES2020 --outDir lib/esm",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yourec ompiling core-electron to module esnext, but here es2020?

"clean": "rimraf lib .rush/temp/package-deps*.json ../../tools/internal/ios/core-test-runner/build ../../tools/internal/lib",
"docs": "betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-backend/file.json --tsIndexFile=./core-backend.ts --onlyJson --excludeGlob=**/*.d.ts",
"copy:assets": "cpx \"./src/assets/**/*\" ./lib/cjs/assets",
"copy:assets": "cpx \"./src/assets/**/*\" ./lib/cjs/assets && cpx \"./src/assets/**/*\" ./lib/esm/assets",
"copy:config": "internal-tools copy-config",
"copy:test-assets": "cpx \"./src/test/assets/**/*\" ./lib/cjs/test/assets",
"copy:test-assets": "cpx \"./src/test/assets/**/*\" ./lib/cjs/test/assets && cpx \"./src/test/assets/**/*\" ./lib/esm/test/assets",
"cover": "nyc npm -s test",
"extract-api": "betools extract-api --entry=core-backend",
"lint": "eslint \"./src/**/*.ts\" 1>&2",
Expand Down
5 changes: 2 additions & 3 deletions core/backend/src/test/schema/FunctionalDomain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert, expect } from "chai";
import { join } from "path";
import { restore as sinonRestore, spy as sinonSpy } from "sinon";
import { restore as sinonRestore, SinonSpy, spy as sinonSpy } from "sinon";
import { Guid, Id64 } from "@itwin/core-bentley";
import { CodeScopeSpec, CodeSpec, ElementProps, IModel } from "@itwin/core-common";
import { ClassRegistry } from "../../ClassRegistry";
Expand All @@ -18,7 +18,6 @@ import {
import { ElementOwnsChildElements, ElementOwnsUniqueAspect, SubjectOwnsPartitionElements } from "../../NavigationRelationship";
import { IModelTestUtils } from "../IModelTestUtils";
import { KnownTestLocations } from "../KnownTestLocations";
import Sinon = require("sinon"); // eslint-disable-line @typescript-eslint/no-require-imports

let iModelDb: StandaloneDb;
const insertedLabel = "inserted label";
Expand Down Expand Up @@ -276,7 +275,7 @@ describe("Functional Domain", () => {

const testChannelKey1 = "channel 1 for tests";
const testChannelKey2 = "channel 2 for tests";
function testChannel<T>(channelKey: ChannelKey, fn: () => T, spies: Sinon.SinonSpy[]) {
function testChannel<T>(channelKey: ChannelKey, fn: () => T, spies: SinonSpy[]) {
iModelDb.channels.removeAllowedChannel(channelKey);
expect(fn).throws("not allowed");
iModelDb.channels.addAllowedChannel(channelKey);
Expand Down
16 changes: 8 additions & 8 deletions core/backend/src/test/standalone/ChangeConflictHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import * as chai from "chai";
import { assert, expect } from "chai";
import * as chaiAsPromised from "chai-as-promised";
import { restore, SinonSpy, SinonStub, spy, stub } from "sinon";
import { HubWrappers, KnownTestLocations } from "../";
import { HubMock } from "../../HubMock";
import {
Expand All @@ -25,7 +26,6 @@ import {
import { IModelTestUtils, TestUserType } from "../IModelTestUtils";
import { ChangesetConflictArgs } from "../../internal/ChangesetConflictArgs";
chai.use(chaiAsPromised);
import sinon = require("sinon"); // eslint-disable-line @typescript-eslint/no-require-imports

async function assertThrowsAsync<T>(test: () => Promise<T>, msg?: string) {
try {
Expand Down Expand Up @@ -139,7 +139,7 @@ describe("Changeset conflict handler", () => {
});

afterEach(async () => {
sinon.restore();
restore();

if (b1.isOpen) {
b1.abandonChanges();
Expand All @@ -157,8 +157,8 @@ describe("Changeset conflict handler", () => {
}
});

async function spyChangesetConflictHandler(b: BriefcaseDb, cb: () => Promise<void>, test: (s: sinon.SinonSpy<ChangesetConflictArgs[], DbConflictResolution>) => void) {
const s1 = sinon.spy(b, "onChangesetConflict" as any) as sinon.SinonSpy<ChangesetConflictArgs[], DbConflictResolution>;
async function spyChangesetConflictHandler(b: BriefcaseDb, cb: () => Promise<void>, test: (s: SinonSpy<ChangesetConflictArgs[], DbConflictResolution>) => void) {
const s1 = spy(b, "onChangesetConflict" as any) as sinon.SinonSpy<ChangesetConflictArgs[], DbConflictResolution>;
try {
await cb();
} finally {
Expand All @@ -167,17 +167,17 @@ describe("Changeset conflict handler", () => {
}
}

async function stubChangesetConflictHandler(b: BriefcaseDb, cb: () => Promise<void>, test: (s: sinon.SinonStub<ChangesetConflictArgs[], DbConflictResolution>) => void) {
const s1 = sinon.stub(b as any, "onChangesetConflict" as any);
async function stubChangesetConflictHandler(b: BriefcaseDb, cb: () => Promise<void>, test: (s: SinonStub<ChangesetConflictArgs[], DbConflictResolution>) => void) {
const s1 = stub(b as any, "onChangesetConflict" as any);
try {
test(s1 as sinon.SinonStub<ChangesetConflictArgs[], DbConflictResolution>);
test(s1 as SinonStub<ChangesetConflictArgs[], DbConflictResolution>);
await cb();
} finally {
s1.restore();
}
}
async function fakeChangesetConflictHandler(b: BriefcaseDb, cb: () => Promise<void>, interceptMethod: (arg: ChangesetConflictArgs) => DbConflictResolution | undefined) {
const s1 = sinon.stub<ChangesetConflictArgs[], DbConflictResolution>(b as any, "onChangesetConflict" as any);
const s1 = stub<ChangesetConflictArgs[], DbConflictResolution>(b as any, "onChangesetConflict" as any);
s1.callsFake(interceptMethod);
try {
await cb();
Expand Down
8 changes: 4 additions & 4 deletions core/backend/src/test/standalone/MergeConflict.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import * as chai from "chai";
import { assert, expect } from "chai";
import * as chaiAsPromised from "chai-as-promised";
import { stub } from "sinon";
import { HubWrappers, KnownTestLocations } from "../";
import { HubMock } from "../../HubMock";
import {
Expand All @@ -22,7 +23,6 @@ import {
} from "../../core-backend";
import { IModelTestUtils, TestUserType } from "../IModelTestUtils";
chai.use(chaiAsPromised);
import sinon = require("sinon"); // eslint-disable-line @typescript-eslint/no-require-imports
export async function createNewModelAndCategory(rwIModel: BriefcaseDb, parent?: Id64String) {
// Create a new physical model.
const [, modelId] = await IModelTestUtils.createAndInsertPhysicalPartitionAndModelAsync(rwIModel, IModelTestUtils.getUniqueModelCode(rwIModel, "newPhysicalModel"), true, parent);
Expand Down Expand Up @@ -143,7 +143,7 @@ describe("Merge conflict & locking", () => {
} as ElementAspectProps);
b2.saveChanges();

const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, "onChangesetConflict" as any);
const onChangesetConflictStub = stub(BriefcaseDb.prototype, "onChangesetConflict" as any);
await assertThrowsAsync(
async () => b2.pushChanges({ accessToken: accessToken1, description: `modify aspect ${aspectId1} with no lock` }),
"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.");
Expand Down Expand Up @@ -216,7 +216,7 @@ describe("Merge conflict & locking", () => {
await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });
b2.saveChanges();

const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, "onChangesetConflict" as any);
const onChangesetConflictStub = stub(BriefcaseDb.prototype, "onChangesetConflict" as any);
await assertThrowsAsync(
async () => b2.pushChanges({ accessToken: accessToken2, description: `add aspect to element ${el1}` }),
"UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered.");
Expand Down Expand Up @@ -328,7 +328,7 @@ describe("Merge conflict & locking", () => {

await b1.pushChanges({ accessToken: accessToken1, description: `deleted element ${el1}` });

const onChangesetConflictStub = sinon.stub(BriefcaseDb.prototype, "onChangesetConflict" as any);
const onChangesetConflictStub = stub(BriefcaseDb.prototype, "onChangesetConflict" as any);
/* we should be able to apply all changesets */
await b3.pullChanges();
expect(onChangesetConflictStub.callCount).greaterThanOrEqual(1, "native conflict handler must call BriefcaseDb.onChangesetConflict()");
Expand Down
20 changes: 17 additions & 3 deletions core/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,23 @@
"engines": {
"node": "^18.0.0 || ^20.0.0"
},
"type": "module",
"exports": {
"./ElectronBackend": {
"types": "./lib/esm/ElectronBackend.d.ts",
"import": "./lib/esm/ElectronBackend.js",
"require": "./lib/cjs/ElectronBackend.js"
},
"./ElectronFrontend": {
"types": "./lib/esm/ElectronFrontend.d.ts",
"import": "./lib/esm/ElectronFrontend.js",
"require": "./lib/cjs/ElectronFrontend.js"
}
},
"scripts": {
"build": "npm run -s build:cjs && npm run -s webpack:test",
"build": "npm run -s build:cjs && npm run -s build:esm && npm run -s webpack:test",
"build:cjs": "tsc 1>&2 --outDir lib/cjs",
"build:esm": "tsc 1>&2 --module esnext --outDir lib/esm",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why deliver both CJS and ESM ? Wouldn't it be less painful to just switch to ESM on 5.0 ?

Copy link
Contributor Author

@hl662 hl662 Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I was initially thinking this would go into one of the 4.X versions, but I'm now more certain this should be in 5.x - as I go through with modifying DTA, I'm noticing pain points with delivering dual cjs/esm, both in these packages and our electron-authorization pkg. When running an ESM module, and using named imports (like "@itwin/electron-authorization/Main"), electron complains at run time that it doesn't like electron-auth being CJS. And seems like the only way to solve that is to set 'type': "module" in the respective package.json.

"clean": "rimraf lib .rush/temp/package-deps*.json",
"docs": "betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-electron/file.json --tsIndexFile=./__DOC_ONLY__.ts --onlyJson",
"extract-api": "betools extract-api --entry=__DOC_ONLY__",
Expand All @@ -17,7 +31,7 @@
"test:integration": "npm run test:integration:backend && npm run test:integration:frontend",
"test:integration:backend": "mocha --config src/test/backend/.mocharc.json",
"test:integration:frontend": "certa -r electron --config src/test/frontend/utils/certa.json",
"webpack:test": "webpack --config ./src/test/frontend/utils/webpack.config.js 1>&2",
"webpack:test": "webpack --config ./src/test/frontend/utils/webpack.config.cjs 1>&2",
"cover": ""
},
"repository": {
Expand All @@ -39,7 +53,7 @@
"@itwin/core-bentley": "workspace:^4.10.0-dev.33",
"@itwin/core-common": "workspace:^4.10.0-dev.33",
"@itwin/core-frontend": "workspace:^4.10.0-dev.33",
"electron": ">=23.0.0 <34.0.0"
"electron": ">=28.0.0 <34.0.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if we leave the min ver as is?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Electron "properly" supports ESM from version 28. If we're delivering both CJS and ESM, we could leave version 23 as minimum, I think.

},
"devDependencies": {
"@itwin/build-tools": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion core/electron/src/ElectronBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/

export * from "./backend/ElectronHost";
export * from "./backend/ElectronHost.js";
2 changes: 1 addition & 1 deletion core/electron/src/ElectronFrontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/

export * from "./frontend/ElectronApp";
export * from "./frontend/ElectronApp.js";
10 changes: 5 additions & 5 deletions core/electron/src/backend/ElectronHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import * as path from "path";
import { BeDuration, IModelStatus, ProcessDetector } from "@itwin/core-bentley";
import { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from "@itwin/core-backend";
import { IModelError, IpcListener, IpcSocketBackend, RemoveFunction, RpcConfiguration, RpcInterfaceDefinition } from "@itwin/core-common";
import { ElectronRpcConfiguration, ElectronRpcManager } from "../common/ElectronRpcManager";
import { DialogModuleMethod, electronIpcStrings } from "../common/ElectronIpcInterface";
import { ElectronRpcConfiguration, ElectronRpcManager } from "../common/ElectronRpcManager.js";
import { DialogModuleMethod, electronIpcStrings } from "../common/ElectronIpcInterface.js";

// cSpell:ignore signin devserver webcontents copyfile unmaximize eopt

Expand Down Expand Up @@ -135,8 +135,8 @@ export class ElectronHost {
const webPreferences: WebPreferences = {
...options?.webPreferences,

// These web preference variables should not be overriden by the ElectronHostWindowOptions
preload: require.resolve(/* webpack: copyfile */"./ElectronPreload.js"),
// These web preference variables should not be overridden by the ElectronHostWindowOptions
preload: new URL("./ElectronPreload.mjs", import.meta.url).pathname,
experimentalFeatures: false,
nodeIntegration: false,
contextIsolation: true,
Expand Down Expand Up @@ -270,7 +270,7 @@ export class ElectronHost {
throw new Error("Not running under Electron");

if (!this.isValid) {
this._electron = require("electron"); // eslint-disable-line @typescript-eslint/no-require-imports
this._electron = (await import("electron"));
this._ipc = new ElectronIpc();
const app = this.app;
if (!app.isReady())
Expand Down
2 changes: 1 addition & 1 deletion core/electron/src/backend/ElectronPreload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { contextBridge, ipcRenderer } from "electron";
import type { ElectronListener, ITwinElectronApi } from "../common/ITwinElectronApi";
import type { ElectronListener, ITwinElectronApi } from "../common/ITwinElectronApi.js";

/**
* This file is loaded as an Electron preload script
Expand Down
8 changes: 4 additions & 4 deletions core/electron/src/common/ElectronIpcTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { BentleyError, BentleyStatus, ProcessDetector } from "@itwin/core-bentle
import {
IModelError, iTwinChannel, RpcPushChannel, RpcPushConnection, RpcRequestFulfillment, RpcSerializedValue, SerializedRpcRequest,
} from "@itwin/core-common";
import { ElectronPushConnection, ElectronPushTransport } from "./ElectronPush";
import { ElectronRpcConfiguration } from "./ElectronRpcManager";
import { ElectronRpcProtocol } from "./ElectronRpcProtocol";
import { ElectronRpcRequest } from "./ElectronRpcRequest";
import { ElectronPushConnection, ElectronPushTransport } from "./ElectronPush.js";
import { ElectronRpcConfiguration } from "./ElectronRpcManager.js";
import { ElectronRpcProtocol } from "./ElectronRpcProtocol.js";
import { ElectronRpcRequest } from "./ElectronRpcRequest.js";

const OBJECTS_CHANNEL = iTwinChannel("rpc.objects");
const DATA_CHANNEL = iTwinChannel("rpc.data");
Expand Down
2 changes: 1 addition & 1 deletion core/electron/src/common/ElectronPush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { RpcMarshaling, RpcPushChannel, RpcPushConnection, RpcPushTransport, RpcRequestFulfillment } from "@itwin/core-common";
import { BackendIpcTransport, FrontendIpcTransport } from "./ElectronIpcTransport";
import { BackendIpcTransport, FrontendIpcTransport } from "./ElectronIpcTransport.js";

const PUSH = "__push__";

Expand Down
2 changes: 1 addition & 1 deletion core/electron/src/common/ElectronRpcManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { IpcSocket, IpcSocketBackend, IpcSocketFrontend, RpcConfiguration, RpcInterfaceDefinition, RpcManager, RpcRegistry } from "@itwin/core-common";
import { ElectronRpcProtocol } from "./ElectronRpcProtocol";
import { ElectronRpcProtocol } from "./ElectronRpcProtocol.js";

/** RPC interface configuration for an Electron-based application.
* @internal
Expand Down
6 changes: 3 additions & 3 deletions core/electron/src/common/ElectronRpcProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

import { BentleyStatus } from "@itwin/core-bentley";
import { IModelError, IpcSocket, RpcInterface, RpcInterfaceDefinition, RpcProtocol } from "@itwin/core-common";
import { ElectronIpcTransport, initializeIpc, IpcTransportMessage } from "./ElectronIpcTransport";
import { ElectronRpcConfiguration } from "./ElectronRpcManager";
import { ElectronRpcRequest } from "./ElectronRpcRequest";
import { ElectronIpcTransport, initializeIpc, IpcTransportMessage } from "./ElectronIpcTransport.js";
import { ElectronRpcConfiguration } from "./ElectronRpcManager.js";
import { ElectronRpcRequest } from "./ElectronRpcRequest.js";

/** RPC interface protocol for an Electron-based application.
* @internal
Expand Down
2 changes: 1 addition & 1 deletion core/electron/src/common/ElectronRpcRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { RpcProtocolEvent, RpcRequest, RpcRequestFulfillment } from "@itwin/core-common";
import { ElectronRpcProtocol } from "./ElectronRpcProtocol";
import { ElectronRpcProtocol } from "./ElectronRpcProtocol.js";

/** @internal */
export class ElectronRpcRequest extends RpcRequest {
Expand Down
6 changes: 3 additions & 3 deletions core/electron/src/frontend/ElectronApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { ProcessDetector, PromiseReturnType } from "@itwin/core-bentley";
import { IpcListener, IpcSocketFrontend } from "@itwin/core-common";
import { _callIpcChannel, IpcApp, NativeApp, NativeAppOpts } from "@itwin/core-frontend";
import type { IpcRenderer } from "electron";
import { DialogModuleMethod, electronIpcStrings } from "../common/ElectronIpcInterface";
import { ElectronRpcManager } from "../common/ElectronRpcManager";
import type { ITwinElectronApi } from "../common/ITwinElectronApi";
import { DialogModuleMethod, electronIpcStrings } from "../common/ElectronIpcInterface.js";
import { ElectronRpcManager } from "../common/ElectronRpcManager.js";
import type { ITwinElectronApi } from "../common/ITwinElectronApi.js";

declare global {
interface Window {
Expand Down
1 change: 1 addition & 0 deletions test-apps/display-test-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "display-test-app",
"description": "Internal app for testing features of display system",
"license": "UNLICENSED",
"type": "module",
"author": {
"name": "Bentley Systems, Inc.",
"url": "http://www.bentley.com"
Expand Down
17 changes: 10 additions & 7 deletions test-apps/display-test-app/src/backend/Backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,29 @@ import * as fs from "fs";
import * as path from "path";
import { Logger, LogLevel, ProcessDetector } from "@itwin/core-bentley";
import { ElectronMainAuthorization } from "@itwin/electron-authorization/Main";
import { ElectronHost, ElectronHostOptions } from "@itwin/core-electron/lib/cjs/ElectronBackend";
import { ElectronHost, ElectronHostOptions } from "@itwin/core-electron/ElectronBackend";
import { BackendIModelsAccess } from "@itwin/imodels-access-backend";
import { IModelsClient } from "@itwin/imodels-client-authoring";
import { IModelDb, IModelHost, IModelHostOptions, LocalhostIpcHost, produceTextAnnotationGeometry } from "@itwin/core-backend";
import {
IModelReadRpcInterface, IModelRpcProps, IModelTileRpcInterface, RpcInterfaceDefinition, RpcManager, SnapshotIModelRpcInterface, TextAnnotation, TextAnnotationProps, TextBlockGeometryProps,
} from "@itwin/core-common";
import { MobileHost, MobileHostOpts } from "@itwin/core-mobile/lib/cjs/MobileBackend";
import { DtaConfiguration, getConfig } from "../common/DtaConfiguration";
import { DtaRpcInterface } from "../common/DtaRpcInterface";
import { MobileHost, MobileHostOpts } from "@itwin/core-mobile/lib/cjs/MobileBackend.js";
import { DtaConfiguration, getConfig } from "../common/DtaConfiguration.js";
import { DtaRpcInterface } from "../common/DtaRpcInterface.js";
import { EditCommandAdmin } from "@itwin/editor-backend";
import * as editorBuiltInCommands from "@itwin/editor-backend";
import dotenv from "dotenv";
import dotenvExpand from "dotenv-expand";
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
/** Loads the provided `.env` file into process.env */
function loadEnv(envFile: string) {
if (!fs.existsSync(envFile))
return;

const dotenv = require("dotenv"); // eslint-disable-line @typescript-eslint/no-require-imports
const dotenvExpand = require("dotenv-expand"); // eslint-disable-line @typescript-eslint/no-require-imports
const envResult = dotenv.config({ path: envFile });
if (envResult.error) {
throw envResult.error;
Expand Down
Loading