Qualify CJS-only module imports

This commit is contained in:
Fedor Indutny
2025-09-19 13:05:51 -07:00
committed by GitHub
parent 140241b83f
commit 40eaf078cc
401 changed files with 1278 additions and 593 deletions

View File

@@ -1,21 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
const { update } = require('lodash/fp');
const topLevelEslintrc = require('../../.eslintrc');
const typescriptRules = topLevelEslintrc.overrides.find(override =>
override.files.some(glob => glob.endsWith('.ts'))
).rules;
const noRestrictedImportsRule =
typescriptRules['@typescript-eslint/no-restricted-imports'];
module.exports = {
rules: {
'@typescript-eslint/no-restricted-imports': update(
[1, 'paths'],
(paths = []) => paths.filter(path => path.name !== 'electron'),
noRestrictedImportsRule
),
},
};

View File

@@ -4,7 +4,7 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { omit } from 'lodash';
import lodash from 'lodash';
import { normalizeAci } from '../util/normalizeAci.js';
import type { ConfigKeyType, ConfigListenerType } from '../RemoteConfig.js';
import {
@@ -17,6 +17,8 @@ import {
} from '../RemoteConfig.js';
import { updateRemoteConfig } from '../test-helpers/RemoteConfigStub.js';
const { omit } = lodash;
describe('RemoteConfig', () => {
const aci = normalizeAci('95b9729c-51ea-4ddb-b516-652befe78062', 'test');

View File

@@ -9,11 +9,7 @@ import { MINUTE } from '../../util/durations/index.js';
import type { SystemTrayServiceOptionsType } from '../../../app/SystemTrayService.js';
import { SystemTrayService } from '../../../app/SystemTrayService.js';
import { setupI18n } from '../../util/setupI18n.js';
import enMessages from '../../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
import i18n from '../util/i18n.js';
describe('SystemTrayService', function (this: Mocha.Suite) {
// These tests take more time on CI in some cases, so we increase the timeout.

View File

@@ -4,7 +4,7 @@
import * as path from 'node:path';
import { tmpdir } from 'node:os';
import { chmodSync, rmSync, writeFileSync, mkdtempSync } from 'node:fs';
import { pathExists, readJsonSync } from 'fs-extra';
import fsExtra from 'fs-extra';
import { v4 as generateGuid } from 'uuid';
import { assert } from 'chai';
@@ -12,6 +12,8 @@ import { assert } from 'chai';
import type { ConfigType } from '../../../app/base_config.js';
import { start } from '../../../app/base_config.js';
const { pathExists, readJsonSync } = fsExtra;
describe('base_config', () => {
let targetDir: string;
let targetPath: string;

View File

@@ -2,12 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { omit } from 'lodash';
import lodash from 'lodash';
import { BadgeCategory } from '../../badges/BadgeCategory.js';
import { BadgeImageTheme } from '../../badges/BadgeImageTheme.js';
import { parseBadgesFromServer } from '../../badges/parseBadgesFromServer.js';
const { omit } = lodash;
describe('parseBadgesFromServer', () => {
const UPDATES_URL = 'https://updates2.signal.org/desktop';

View File

@@ -4,13 +4,15 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { assert } from 'chai';
import { noop } from 'lodash';
import lodash from 'lodash';
import * as sinon from 'sinon';
import { STORAGE_KEY, ChallengeHandler } from '../challenge.js';
import type { RegisteredChallengeType } from '../challenge.js';
import { DAY, SECOND } from '../util/durations/index.js';
const { noop } = lodash;
type CreateHandlerOptions = {
readonly autoSolve?: boolean;
readonly challengeError?: Error;

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { times } from 'lodash';
import lodash from 'lodash';
import {
RowType,
_testHeaderText,
@@ -13,6 +13,8 @@ import { getDefaultConversation } from '../../../test-helpers/getDefaultConversa
import { LeftPaneChooseGroupMembersHelper } from '../../../components/leftPane/LeftPaneChooseGroupMembersHelper.js';
const { times } = lodash;
describe('LeftPaneChooseGroupMembersHelper', () => {
const defaults = {
uuidFetchState: {},

View File

@@ -2,13 +2,15 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { shuffle } from 'lodash';
import lodash from 'lodash';
import { IMAGE_JPEG } from '../../../types/MIME.js';
import { groupMediaItemsByDate } from '../../../components/conversation/media-gallery/groupMediaItemsByDate.js';
import type { MediaItemType } from '../../../types/MediaItem.js';
import { fakeAttachment } from '../../../test-helpers/fakeAttachment.js';
const { shuffle } = lodash;
const testDate = (
year: number,
month: number,

View File

@@ -2,12 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { times } from 'lodash';
import lodash from 'lodash';
import { updateRemoteConfig } from '../../test-helpers/RemoteConfigStub.js';
import { generateAci } from '../../types/ServiceId.js';
import { isConversationTooBigToRing } from '../../conversations/isConversationTooBigToRing.js';
const { times } = lodash;
const CONFIG_KEY = 'global.calling.maxGroupCallRingSize';
describe('isConversationTooBigToRing', () => {

View File

@@ -4,11 +4,13 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { noop } from 'lodash';
import lodash from 'lodash';
import type { StoredJob } from '../../jobs/types.js';
import { JobQueueDatabaseStore } from '../../jobs/JobQueueDatabaseStore.js';
const { noop } = lodash;
describe('JobQueueDatabaseStore', () => {
let fakeDatabase: {
getJobsInQueue: sinon.SinonStub;

View File

@@ -7,7 +7,7 @@ import { assert } from 'chai';
import * as sinon from 'sinon';
import EventEmitter, { once } from 'node:events';
import { z } from 'zod';
import { noop, groupBy } from 'lodash';
import lodash from 'lodash';
import { v4 as uuid } from 'uuid';
import PQueue from 'p-queue';
import { JobError } from '../../jobs/JobError.js';
@@ -22,6 +22,8 @@ import type { ParsedJob, StoredJob, JobQueueStore } from '../../jobs/types.js';
import { sleep } from '../../util/sleep.js';
import { parseUnknown } from '../../util/schemas.js';
const { noop, groupBy } = lodash;
describe('JobQueue', () => {
describe('end-to-end tests', () => {
it('writes jobs to the database, processes them, and then deletes them', async () => {

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { noop, omit } from 'lodash';
import lodash from 'lodash';
import {
HTTPError,
SendMessageProtoError,
@@ -15,6 +15,8 @@ import {
maybeExpandErrors,
} from '../../../jobs/helpers/handleMultipleSendErrors.js';
const { noop, omit } = lodash;
describe('maybeExpandErrors', () => {
// This returns a readonly array, but Chai wants a mutable one.
const expand = (input: unknown) => maybeExpandErrors(input) as Array<unknown>;

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { sampleSize, times } from 'lodash';
import lodash from 'lodash';
import { v4 as uuid } from 'uuid';
import type {
@@ -26,6 +26,8 @@ import {
someSendStatus,
} from '../../messages/MessageSendState.js';
const { sampleSize, times } = lodash;
describe('message send state utilities', () => {
describe('maxStatus', () => {
const expectedOrder = [

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import { v4 as uuid } from 'uuid';
import { omit } from 'lodash';
import lodash from 'lodash';
import type { MessageReactionType } from '../../model-types.d.ts';
import { isEmpty } from '../../util/iterables.js';
@@ -15,6 +15,8 @@ import {
markOutgoingReactionSent,
} from '../../reactions/util.js';
const { omit } = lodash;
describe('reaction utilities', () => {
const OUR_CONVO_ID = uuid();

View File

@@ -3,12 +3,14 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { noop } from 'lodash';
import lodash from 'lodash';
import { sleep } from '../../util/sleep.js';
import { constantTimeEqual } from '../../Crypto.js';
import { OurProfileKeyService } from '../../services/ourProfileKey.js';
const { noop } = lodash;
describe('"our profile key" service', () => {
const createFakeStorage = () => ({
get: sinon.stub(),

View File

@@ -2,10 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { noop } from 'lodash';
import lodash from 'lodash';
import { cleanDataForIpc } from '../../sql/cleanDataForIpc.js';
const { noop } = lodash;
describe('cleanDataForIpc', () => {
it('does nothing to JSON primitives', () => {
['', 'foo bar', 0, 123, true, false, null].forEach(value => {

View File

@@ -1,7 +1,7 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { noop } from 'lodash';
import lodash from 'lodash';
import SQL from '@signalapp/sqlcipher';
import type { ReadableDB, WritableDB } from '../../sql/Interface.js';
@@ -9,6 +9,8 @@ import type { QueryTemplate } from '../../sql/util.js';
import { SCHEMA_VERSIONS } from '../../sql/migrations/index.js';
import { consoleLogger } from '../../util/consoleLogger.js';
const { noop } = lodash;
export function createDB(): WritableDB {
const db = new SQL(':memory:') as WritableDB;
db.initTokenizer();

View File

@@ -1,6 +1,6 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { omit } from 'lodash';
import lodash from 'lodash';
import { assert } from 'chai';
import type { ReadableDB, WritableDB } from '../../sql/Interface.js';
@@ -13,6 +13,8 @@ import type {
import type { AttachmentType } from '../../types/Attachment.js';
import { IMAGE_JPEG } from '../../types/MIME.js';
const { omit } = lodash;
function getAttachmentDownloadJobs(
db: ReadableDB
): Array<Record<string, unknown>> {

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { findLast } from 'lodash';
import lodash from 'lodash';
import type { WritableDB } from '../../sql/Interface.js';
import { markAllCallHistoryRead } from '../../sql/Server.js';
import { SeenStatus } from '../../MessageSeenStatus.js';
@@ -15,6 +15,8 @@ import {
import { strictAssert } from '../../util/assert.js';
import { createDB, insertData, updateToVersion } from './helpers.js';
const { findLast } = lodash;
describe('SQL/updateToSchemaVersion1100', () => {
let db: WritableDB;
beforeEach(() => {

View File

@@ -2,13 +2,15 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { omit } from 'lodash';
import lodash from 'lodash';
import type { WritableDB } from '../../sql/Interface.js';
import { createDB, updateToVersion, explain } from './helpers.js';
import { jsonToObject, objectToJSON, sql } from '../../sql/util.js';
import { IMAGE_BMP } from '../../types/MIME.js';
import type { _AttachmentDownloadJobTypeV1040 } from '../../sql/migrations/1040-undownloaded-backed-up-media.js';
const { omit } = lodash;
function insertOldJob(
db: WritableDB,
job: Omit<_AttachmentDownloadJobTypeV1040, 'source' | 'ciphertextSize'>,

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import { v4 as generateGuid } from 'uuid';
import { range } from 'lodash';
import lodash from 'lodash';
import { createDB, insertData, updateToVersion } from './helpers.js';
import type {
@@ -20,6 +20,8 @@ import type {
SignedPreKeyType,
} from '../../sql/Interface.js';
const { range } = lodash;
type TestingKyberKey = Omit<
KyberPreKeyType,
'data' | 'isLastResort' | 'isConfirmed' | 'createdAt' | 'ourServiceId'

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import { v4 as generateGuid } from 'uuid';
import { range } from 'lodash';
import lodash from 'lodash';
import {
createDB,
@@ -16,6 +16,8 @@ import { normalizePni } from '../../types/ServiceId.js';
import { normalizeAci } from '../../util/normalizeAci.js';
import type { WritableDB, PreKeyType } from '../../sql/Interface.js';
const { range } = lodash;
type TestingPreKey = Omit<
PreKeyType,
'privateKey' | 'publicKey' | 'createdAt'

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import { v4 as generateGuid } from 'uuid';
import { range } from 'lodash';
import lodash from 'lodash';
import { createDB, insertData, updateToVersion } from './helpers.js';
import type { ServiceIdString } from '../../types/ServiceId.js';
@@ -15,6 +15,8 @@ import type {
SignedPreKeyType,
} from '../../sql/Interface.js';
const { range } = lodash;
type TestingKyberKey = Omit<
KyberPreKeyType,
'data' | 'isLastResort' | 'isConfirmed' | 'createdAt'

View File

@@ -3,7 +3,7 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { noop } from 'lodash';
import lodash from 'lodash';
import { v4 as generateUuid } from 'uuid';
import type { ReduxActions } from '../../../state/types.js';
@@ -20,6 +20,8 @@ import { IMAGE_JPEG } from '../../../types/MIME.js';
import type { AttachmentDraftType } from '../../../types/Attachment.js';
import { fakeDraftAttachment } from '../../../test-helpers/fakeAttachment.js';
const { noop } = lodash;
describe('both/state/ducks/composer', () => {
const QUOTED_MESSAGE = {
conversationId: '123',

View File

@@ -46,10 +46,9 @@ import {
import { noopAction } from '../../../state/ducks/noop.js';
import type { StateType } from '../../../state/reducer.js';
import { reducer as rootReducer } from '../../../state/reducer.js';
import { setupI18n } from '../../../util/setupI18n.js';
import i18n from '../../util/i18n.js';
import type { ServiceIdString } from '../../../types/ServiceId.js';
import { generateAci, getAciFromPrefix } from '../../../types/ServiceId.js';
import enMessages from '../../../../_locales/en/messages.json';
import {
getDefaultConversation,
getDefaultGroup,
@@ -105,8 +104,6 @@ describe('both/state/selectors/conversations-extra', () => {
);
}
const i18n = setupI18n('en', enMessages);
describe('#getConversationByIdSelector', () => {
const state = {
...getEmptyRootState(),

View File

@@ -4,7 +4,7 @@
import { assert } from 'chai';
import type { LocalizerType } from '../../types/Util.js';
import { setupI18n } from '../../util/setupI18n.js';
import * as enMessages from '../../../_locales/en/messages.json';
import { enMessages } from '../util/i18n.js';
describe('setupI18n', () => {
let i18n: LocalizerType;

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { pathExists } from 'fs-extra';
import fsExtra from 'fs-extra';
import { stat, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
@@ -19,6 +19,8 @@ import {
} from '../../updater/common.js';
import { createLogger } from '../../logging/log.js';
const { pathExists } = fsExtra;
const log = createLogger('common_test');
describe('updater/signatures', () => {

View File

@@ -5,7 +5,7 @@ import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { assert } from 'chai';
import { copy } from 'fs-extra';
import fsExtra from 'fs-extra';
import {
_getFileHash,
@@ -19,6 +19,8 @@ import { createTempDir, deleteTempDir } from '../../updater/common.js';
import { keyPair } from '../../updater/curve.js';
import { createLogger } from '../../logging/log.js';
const { copy } = fsExtra;
const log = createLogger('signature_test');
describe('updater/signatures', () => {

View File

@@ -2,10 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { noop } from 'lodash';
import lodash from 'lodash';
import { AbortableProcess } from '../../util/AbortableProcess.js';
const { noop } = lodash;
describe('AbortableProcess', () => {
it('resolves the result normally', async () => {
const process = new AbortableProcess(

View File

@@ -9,8 +9,7 @@ import {
CallType,
GroupCallStatus,
} from '../../types/CallDisposition.js';
import { setupI18n } from '../../util/setupI18n.js';
import enMessages from '../../../_locales/en/messages.json';
import i18n from './i18n.js';
import {
getDefaultConversation,
getDefaultGroup,
@@ -19,8 +18,6 @@ import { getPeerIdFromConversation } from '../../util/callDisposition.js';
import { HOUR } from '../../util/durations/index.js';
describe('calling notification helpers', () => {
const i18n = setupI18n('en', enMessages);
describe('getCallingNotificationText', () => {
// Direct call behavior is not tested here.

View File

@@ -2,11 +2,13 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { pick } from 'lodash';
import lodash from 'lodash';
import { getDefaultConversation } from '../../test-helpers/getDefaultConversation.js';
import { filterAndSortConversations } from '../../util/filterAndSortConversations.js';
import type { ConversationType } from '../../state/ducks/conversations.js';
const { pick } = lodash;
type CheckProps = Pick<ConversationType, 'title' | 'activeAt' | 'e164'>;
function check({

View File

@@ -3,8 +3,7 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { setupI18n } from '../../util/setupI18n.js';
import enMessages from '../../../_locales/en/messages.json';
import i18n from './i18n.js';
import { getMuteOptions } from '../../util/getMuteOptions.js';
@@ -35,8 +34,6 @@ describe('getMuteOptions', () => {
},
];
const i18n = setupI18n('en', enMessages);
describe('when not muted', () => {
it('returns the 5 default options', () => {
assert.deepStrictEqual(

View File

@@ -3,14 +3,11 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { setupI18n } from '../../util/setupI18n.js';
import enMessages from '../../../_locales/en/messages.json';
import i18n from './i18n.js';
import { getMutedUntilText } from '../../util/getMutedUntilText.js';
describe('getMutedUntilText', () => {
const i18n = setupI18n('en', enMessages);
let sandbox: sinon.SinonSandbox;
beforeEach(() => {

View File

@@ -4,11 +4,13 @@
import { assert } from 'chai';
import { Readable } from 'node:stream';
import * as sinon from 'sinon';
import { noop } from 'lodash';
import lodash from 'lodash';
import { once } from 'node:events';
import { getStreamWithTimeout } from '../../util/getStreamWithTimeout.js';
const { noop } = lodash;
describe('getStreamWithTimeout', () => {
let sandbox: sinon.SinonSandbox;
let clock: sinon.SinonFakeTimers;

21
ts/test-node/util/i18n.ts Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { setupI18n } from '../../util/setupI18n.js';
const PATH = join(
__dirname,
'..',
'..',
'..',
'_locales',
'en',
'messages.json'
);
export const enMessages = JSON.parse(readFileSync(PATH, 'utf8'));
export default setupI18n('en', enMessages);

View File

@@ -1,7 +1,7 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { mapValues, pick } from 'lodash';
import lodash from 'lodash';
import type { CustomError } from '../../textsecure/Types.js';
@@ -25,6 +25,8 @@ import {
} from '../../services/notifications.js';
import type { MessageModel } from '../../models/messages.js';
const { mapValues, pick } = lodash;
const log = createLogger('messageFailures');
export async function saveErrorsOnMessage(

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { times } from 'lodash';
import lodash from 'lodash';
import { v4 as uuid } from 'uuid';
import type { LastMessageStatus } from '../../model-types.d.ts';
import { MINUTE, SECOND } from '../../util/durations/index.js';
@@ -15,6 +15,8 @@ import {
TimelineMessageLoadingState,
} from '../../util/timelineUtil.js';
const { times } = lodash;
describe('<Timeline> utilities', () => {
describe('areMessagesInSameGroup', () => {
const defaultNewer: MaybeMessageTimelineItemType = {

View File

@@ -5,8 +5,7 @@ import { assert } from 'chai';
import * as sinon from 'sinon';
import moment from 'moment';
import { HOUR, DAY } from '../../util/durations/index.js';
import { setupI18n } from '../../util/setupI18n.js';
import enMessages from '../../../_locales/en/messages.json';
import i18n from './i18n.js';
import {
formatDate,
@@ -36,8 +35,6 @@ describe('timestamp', () => {
});
}
const i18n = setupI18n('en', enMessages);
describe('formatDate', () => {
useFakeTimers();

View File

@@ -4,7 +4,7 @@
import { assert } from 'chai';
import * as fs from 'node:fs';
import path from 'node:path';
import { ServerPublicParams } from '@signalapp/libsignal-client/zkgroup';
import { ServerPublicParams } from '@signalapp/libsignal-client/zkgroup.js';
describe('zkgroup', () => {
describe('serverPublicParams', () => {