fix issues with circular imports

Parts of this commit are from a patch by sebasjm.  The circular imports
caused an issue with webpack.  While we don't use webpack in the wallet,
the wallet should still be importable by webpack.

Some packages were importing their dependencies via "index.js", which
re-exports public exports of the package.  This resulted in circular
dependencies which were resolved correctly by rollup, but not by
webpack.
This commit is contained in:
Florian Dold 2021-06-02 13:56:29 +02:00
parent 02f1d4b081
commit 5e6cc41b7a
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
7 changed files with 46 additions and 29 deletions

View File

@ -46,5 +46,7 @@
"api-extractor.json": "jsonc" "api-extractor.json": "jsonc"
}, },
"typescript.preferences.importModuleSpecifierEnding": "js", "typescript.preferences.importModuleSpecifierEnding": "js",
"typescript.preferences.importModuleSpecifier": "project-relative" "typescript.preferences.importModuleSpecifier": "project-relative",
"javascript.preferences.importModuleSpecifier": "project-relative",
"javascript.preferences.importModuleSpecifierEnding": "js"
} }

View File

@ -92,7 +92,10 @@ export function handleWorkerMessage(msg: any): void {
try { try {
const result = (impl as any)[operation](...args); const result = (impl as any)[operation](...args);
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const worker_threads = require("worker_threads"); const _r = "require"
const worker_threads: typeof import("worker_threads") = module[_r]("worker_threads");
// const worker_threads = require("worker_threads");
const p = worker_threads.parentPort; const p = worker_threads.parentPort;
worker_threads.parentPort?.postMessage; worker_threads.parentPort?.postMessage;
if (p) { if (p) {
@ -146,7 +149,8 @@ class NodeThreadCryptoWorker implements CryptoWorker {
constructor() { constructor() {
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const worker_threads = require("worker_threads"); const _r = "require"
const worker_threads = module[_r]("worker_threads");
logger.trace("starting node crypto worker"); logger.trace("starting node crypto worker");

View File

@ -30,7 +30,6 @@ import {
} from "@gnu-taler/idb-bridge"; } from "@gnu-taler/idb-bridge";
import { openTalerDatabase } from "../db"; import { openTalerDatabase } from "../db";
import { HttpRequestLibrary } from "../util/http"; import { HttpRequestLibrary } from "../util/http";
import fs from "fs";
import { NodeThreadCryptoWorkerFactory } from "../crypto/workers/nodeThreadWorker"; import { NodeThreadCryptoWorkerFactory } from "../crypto/workers/nodeThreadWorker";
import { NodeHttpLib } from "./NodeHttpLib"; import { NodeHttpLib } from "./NodeHttpLib";
import { Logger } from "../util/logging"; import { Logger } from "../util/logging";
@ -40,6 +39,21 @@ import { WalletNotification } from "@gnu-taler/taler-util";
const logger = new Logger("headless/helpers.ts"); const logger = new Logger("headless/helpers.ts");
const nodejs_fs = (function () {
let fs: typeof import("fs");
return function() {
if (!fs) {
/**
* need to use an expression when doing a require if we want
* webpack not to find out about the requirement
*/
const _r = "require"
fs = module[_r]("fs")
}
return fs
}
})()
export interface DefaultNodeWalletArgs { export interface DefaultNodeWalletArgs {
/** /**
* Location of the wallet database. * Location of the wallet database.
@ -87,7 +101,7 @@ export async function getDefaultNodeWallet(
const storagePath = args.persistentStoragePath; const storagePath = args.persistentStoragePath;
if (storagePath) { if (storagePath) {
try { try {
const dbContentStr: string = fs.readFileSync(storagePath, { const dbContentStr: string = nodejs_fs().readFileSync(storagePath, {
encoding: "utf-8", encoding: "utf-8",
}); });
const dbContent = JSON.parse(dbContentStr); const dbContent = JSON.parse(dbContentStr);
@ -109,11 +123,11 @@ export async function getDefaultNodeWallet(
} }
const tmpPath = `${args.persistentStoragePath}-${makeId(5)}.tmp`; const tmpPath = `${args.persistentStoragePath}-${makeId(5)}.tmp`;
const dbContent = myBackend.exportDump(); const dbContent = myBackend.exportDump();
fs.writeFileSync(tmpPath, JSON.stringify(dbContent, undefined, 2), { nodejs_fs().writeFileSync(tmpPath, JSON.stringify(dbContent, undefined, 2), {
encoding: "utf-8", encoding: "utf-8",
}); });
// Atomically move the temporary file onto the DB path. // Atomically move the temporary file onto the DB path.
fs.renameSync(tmpPath, args.persistentStoragePath); nodejs_fs().renameSync(tmpPath, args.persistentStoragePath);
}; };
} }
@ -143,7 +157,9 @@ export async function getDefaultNodeWallet(
let workerFactory; let workerFactory;
try { try {
// Try if we have worker threads available, fails in older node versions. // Try if we have worker threads available, fails in older node versions.
require("worker_threads"); const _r = "require"
const worker_threads = module[_r]("worker_threads");
// require("worker_threads");
workerFactory = new NodeThreadCryptoWorkerFactory(); workerFactory = new NodeThreadCryptoWorkerFactory();
} catch (e) { } catch (e) {
logger.warn( logger.warn(

View File

@ -18,11 +18,16 @@
* Module entry point for the wallet when used as a node module. * Module entry point for the wallet when used as a node module.
*/ */
export { Wallet } from "./wallet";
// Errors // Errors
export * from "./operations/errors"; export * from "./operations/errors";
// Util functionality
export { Logger } from "./util/logging";
export { URL } from "./util/url";
export * from "./util/promiseUtils";
export * from "./util/query";
export * from "./util/http";
// Utils for using the wallet under node // Utils for using the wallet under node
export { NodeHttpLib } from "./headless/NodeHttpLib"; export { NodeHttpLib } from "./headless/NodeHttpLib";
export { export {
@ -44,13 +49,8 @@ export type { CryptoWorker } from "./crypto/workers/cryptoWorker";
export { CryptoWorkerFactory, CryptoApi } from "./crypto/workers/cryptoApi"; export { CryptoWorkerFactory, CryptoApi } from "./crypto/workers/cryptoApi";
export * from "./crypto/talerCrypto"; export * from "./crypto/talerCrypto";
// Util functionality
export { Logger } from "./util/logging";
export { URL } from "./util/url";
export * from "./util/promiseUtils";
export * from "./util/query";
export * from "./util/http";
export * from "./pending-types"; export * from "./pending-types";
export * from "./util/debugFlags"; export * from "./util/debugFlags";
export { Wallet } from "./wallet";

View File

@ -18,7 +18,7 @@
* Imports. * Imports.
*/ */
import { ExchangeRecord, Stores } from "../db.js"; import { ExchangeRecord, Stores } from "../db.js";
import { Logger } from "../index.js"; import { Logger } from "../util/logging";
import { getExchangeDetails } from "./exchanges.js"; import { getExchangeDetails } from "./exchanges.js";
import { InternalWalletState } from "./state.js"; import { InternalWalletState } from "./state.js";

View File

@ -40,16 +40,6 @@ import {
ReserveRecord, ReserveRecord,
WithdrawalGroupRecord, WithdrawalGroupRecord,
} from "../db.js"; } from "../db.js";
import {
Logger,
encodeCrock,
getRandomBytes,
readSuccessResponseJsonOrThrow,
URL,
readSuccessResponseJsonOrErrorCode,
throwUnexpectedRequestError,
TransactionHandle,
} from "../index.js";
import { assertUnreachable } from "../util/assertUnreachable.js"; import { assertUnreachable } from "../util/assertUnreachable.js";
import { canonicalizeBaseUrl } from "@gnu-taler/taler-util"; import { canonicalizeBaseUrl } from "@gnu-taler/taler-util";
import { import {
@ -73,6 +63,11 @@ import {
getBankWithdrawalInfo, getBankWithdrawalInfo,
} from "./withdraw.js"; } from "./withdraw.js";
import { getExchangeTrust } from "./currencies.js"; import { getExchangeTrust } from "./currencies.js";
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
import { Logger } from "../util/logging.js";
import { readSuccessResponseJsonOrErrorCode, readSuccessResponseJsonOrThrow, throwUnexpectedRequestError } from "../util/http.js";
import { URL } from "../util/url.js";
import { TransactionHandle } from "../util/query.js";
const logger = new Logger("reserves.ts"); const logger = new Logger("reserves.ts");

View File

@ -19,7 +19,7 @@
*/ */
const isNode = const isNode =
typeof process !== "undefined" && process.release.name === "node"; typeof process !== "undefined" && typeof process.release !== "undefined" && process.release.name === "node";
function writeNodeLog( function writeNodeLog(
message: any, message: any,