Suffix lint rule and fixes

This commit is contained in:
Fedor Indutny
2025-10-16 13:12:23 -07:00
parent 44076ece79
commit 5d1a9d22f0
79 changed files with 984 additions and 382 deletions

View File

@@ -0,0 +1,455 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
const MAIN_MODULES = new Set([
'app',
'autoUpdater',
'BaseWindow',
'BrowserView',
'BrowserWindow',
'contentTracing',
'desktopCapturer',
'dialog',
'globalShortcut',
'inAppPurchase',
'ipcMain',
'Menu',
'MenuItem',
'MessageChannelMain',
'MessagePortMain',
'nativeTheme',
'net',
'netLog',
'Notification',
'powerMonitor',
'powerSaveBlocker',
'process',
'protocol',
'pushNotifications',
'safeStorage',
'screen',
'session',
'ShareMenu',
'shell',
'systemPreferences',
'TouchBar',
'Tray',
'utilityProcess',
'webContents',
'WebContentsView',
'webFrameMain',
'View',
]);
const RENDERER_MODULES = new Set([
'contextBridge',
'ipcRenderer',
'webFrame',
'webUtils',
]);
const NODE_MODULES = new Set([
'@electron/asar',
'@indutny/dicer',
'@indutny/mac-screen-share',
'@indutny/range-finder',
'@indutny/simple-windows-notifications',
'@signalapp/libsignal-client',
'@signalapp/ringrtc',
'@signalapp/sqlcipher',
'@signalapp/windows-ucv',
'cirbuf',
'config',
'dashdash',
'encoding',
'fast-glob',
'fs-extra',
'got',
'growing-file',
'node-fetch',
'proxy-agent',
'read-last-lines',
'websocket',
'write-file-atomic',
// Dev dependencies
'@electron/fuses',
'@electron/notarize',
'@electron/symbolicate-mac',
'@indutny/parallel-prettier',
'@indutny/rezip-electron',
'@napi-rs/canvas',
'@signalapp/mock-server',
'@tailwindcss/cli',
'@tailwindcss/postcss',
'chokidar-cli',
'cross-env',
'electron-builder',
'electron-mocha',
'endanger',
'enhanced-resolve',
'enquirer',
'esbuild',
'execa',
'html-webpack-plugin',
'http-server',
'json-to-ast',
'log-symbols',
'mini-css-extract-plugin',
'node-gyp',
'node-gyp-build',
'npm-run-all',
'p-limit',
'pixelmatch',
'playwright',
'postcss',
'postcss-loader',
'prettier',
'prettier-plugin-tailwindcss',
'protobufjs-cli',
'react-devtools',
'react-devtools-core',
'resedit',
'resolve-url-loader',
'sass',
'sass-loader',
'style-loader',
'stylelint',
'stylelint-config-css-modules',
'stylelint-config-recommended-scss',
'stylelint-use-logical-spec',
'svgo',
'synckit',
'tailwindcss',
'terser-webpack-plugin',
'ts-node',
'typescript',
'wait-on',
'webpack',
'webpack-cli',
'webpack-dev-server',
]);
const DOM_MODULES = new Set([
'@popperjs/core',
'@radix-ui/react-tooltip',
'@react-aria/focus',
'@react-aria/interactions',
'@react-aria/utils',
'@react-spring/web',
'@tanstack/react-virtual',
'blob-util',
'blueimp-load-image',
'copy-text-to-clipboard',
'fabric',
'focus-trap-react',
'radix-ui',
'react-aria',
'react-aria-components',
'react-blurhash',
'react-contextmenu',
'react-popper',
'react-virtualized',
// Dev dependencies
'@storybook/addon-a11y',
'@storybook/addon-actions',
'@storybook/addon-controls',
'@storybook/addon-interactions',
'@storybook/addon-jest',
'@storybook/addon-measure',
'@storybook/addon-toolbars',
'@storybook/addon-viewport',
'@storybook/addon-webpack5-compiler-swc',
'@storybook/csf',
'@storybook/preview-api',
'@storybook/react',
'@storybook/react-webpack5',
'@storybook/test',
'@storybook/test-runner',
'@storybook/types',
'storybook',
]);
/** @type {import("eslint").Rule.RuleModule} */
module.exports = {
meta: {
type: 'problem',
hasSuggestions: false,
fixable: false,
schema: [],
},
create(context) {
const { filename, sourceCode } = context;
let fileSuffix;
const nodeUses = [];
const domUses = [];
const preloadUses = [];
const mainUses = [];
const invalidUsesBySuffix = {
std: [nodeUses, domUses, preloadUses, mainUses],
node: [domUses, preloadUses, mainUses],
dom: [nodeUses, preloadUses, mainUses],
preload: [mainUses],
main: [domUses, preloadUses],
};
function trackLocalDep(node, source) {
if (!source.endsWith('.js')) {
return;
}
const match = source.match(/\.([^.\/]+)(?:\.stories)?\.js$/);
if (match == null) {
context.report({
node,
message: `Missing file suffix in ${source} import`,
});
return;
}
const [, depSuffix] = match;
if (depSuffix === 'node') {
nodeUses.push(node);
} else if (depSuffix === 'dom') {
domUses.push(node);
} else if (depSuffix === 'preload') {
preloadUses.push(node);
} else if (depSuffix === 'main') {
mainUses.push(node);
} else if (depSuffix === 'std') {
// Ignore
} else {
context.report({
node,
message:
`Unrecognized file suffix in ${source}, ` +
`expected: node/preload/main/std, found: ${depSuffix}`,
});
}
}
function transformESMReference(node) {
if (
node.importKind === 'type' ||
(node.specifiers?.length &&
node.specifiers.every(x => x.importKind === 'type'))
) {
return;
}
if (!node.source) {
return;
}
if (node.source.type !== 'Literal') {
return;
}
const {
specifiers,
source: { value: source },
} = node;
if (source.startsWith('.')) {
trackLocalDep(node, source);
return;
}
// Node APIs
if (source.startsWith('node:')) {
nodeUses.push(node);
return;
}
// Electron
if (source === 'electron') {
for (const s of specifiers) {
// We implicitly skip:
// they are used in scripts
if (s.type === 'ImportSpecifier') {
if (MAIN_MODULES.has(s.imported.name)) {
mainUses.push(s);
} else if (RENDERER_MODULES.has(s.imported.name)) {
preloadUses.push(s);
}
} else if (s.type === 'ImportNamespaceSpecifier') {
// import * as electron from 'electron';
context.report({
node: s,
message: 'Unsupported namespace import specifier for electron',
});
nodeUses.push(s);
} else if (s.type === 'ImportDefaultSpecifier') {
// import ELECTRON_CLI from 'electron';
nodeUses.push(s);
} else {
context.report({
node: s,
message: 'Unsupported import specifier for electron',
});
}
}
return;
}
const [, moduleName] = source.match(/^([^@\/]+|@[^\/]+\/[^\/]+)/);
if (NODE_MODULES.has(moduleName)) {
nodeUses.push(node);
} else if (DOM_MODULES.has(moduleName) || source === 'react-dom/client') {
domUses.push(node);
}
}
return {
Program: node => {
if (filename.endsWith('.d.ts')) {
// Skip types
return;
}
const match = filename.match(/\.([^.\/]+)(?:\.stories)?\.(?:ts|tsx)$/);
if (match == null) {
context.report({
node: node,
message:
'Missing file suffix. Has to be one of: node/preload/main/std',
});
return;
}
fileSuffix = match[1];
},
'Program:exit': node => {
if (fileSuffix == null) {
return;
}
let expectedSuffix;
if (mainUses.length > 0) {
expectedSuffix = 'main';
} else if (preloadUses.length > 0) {
expectedSuffix = 'preload';
} else if (nodeUses.length > 0) {
if (domUses.length > 0) {
expectedSuffix = 'preload';
} else {
expectedSuffix = 'node';
}
} else if (domUses.length > 0) {
expectedSuffix = 'dom';
} else {
expectedSuffix = 'std';
}
// All .std.tsx components should be .dom.tsx for now
if (expectedSuffix === 'std' && filename.endsWith('.tsx')) {
expectedSuffix = 'dom';
}
if (fileSuffix !== expectedSuffix) {
context.report({
node,
message: `Invalid suffix ${fileSuffix}, expected: ${expectedSuffix}`,
});
}
const invalid = invalidUsesBySuffix[expectedSuffix].flat();
for (const use of invalid) {
context.report({
node: use,
message: `Invalid import/reference for suffix: ${expectedSuffix}`,
});
}
},
ImportDeclaration(node) {
transformESMReference(node);
},
ExportAllDeclaration(node) {
transformESMReference(node);
},
ExportNamedDeclaration(node) {
transformESMReference(node);
},
CallExpression(node) {
if (
node.callee.type !== 'Identifier' ||
node.callee.name !== 'require'
) {
return;
}
const scope = sourceCode.getScope(node);
const ref = scope.references.find(r => r.identifier === node.callee);
if (ref.resolved.scope.type !== 'global') {
return;
}
const { arguments: args } = node;
if (args.length !== 1) {
context.report({
node,
message: 'Invalid require() argument count',
});
return;
}
const [arg] = args;
let source;
if (arg.type === 'Literal') {
source = arg.value;
} else if (
arg.type === 'TSAsExpression' &&
arg.expression.type === 'Literal'
) {
source = arg.expression.value;
} else {
// Ignore other expressions
return;
}
// Keep local imports
if (source.startsWith('.')) {
trackLocalDep(node, source);
return;
}
// Node APIs
if (source.startsWith('node:')) {
nodeUses.push(node);
return;
}
// Electron
if (source === 'electron') {
context.report({
node,
message: 'CJS import of electron is not allowed',
});
}
const [, moduleName] = source.match(/^([^@\/]+|@[^\/]+\/[^\/]+)/);
if (NODE_MODULES.has(moduleName)) {
nodeUses.push(node);
} else if (
DOM_MODULES.has(moduleName) ||
source === 'react-dom/client'
) {
domUses.push(moduleName);
}
},
Identifier(node) {
if (node.name !== 'window' && node.name !== 'document') {
return;
}
const scope = sourceCode.getScope(node);
const ref = scope.references.find(r => r.identifier === node);
if (ref == null) {
// Not part of expression
return;
}
if (ref.resolved.scope.type !== 'global') {
return;
}
domUses.push(node);
},
};
},
};

View File

@@ -0,0 +1,134 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
const rule = require('./file-suffix.js');
const RuleTester = require('eslint').RuleTester;
// avoid triggering mocha's global leak detection
require('@typescript-eslint/parser');
const ruleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
});
ruleTester.run('file-suffix', rule, {
valid: [
// Allowed references
...[
['std', '', ['std']],
['dom', 'window.addEventListener();', ['std', 'dom']],
['node', 'require("node:fs");', ['std', 'node']],
[
'preload',
'import { ipcRenderer } from "electron";',
['std', 'node', 'preload'],
],
[
'main',
'import { autoUpdater } from "electron";',
['std', 'node', 'main'],
],
]
.map(([fileSuffix, requiredLine, depSuffixes]) => {
return depSuffixes.map(depSuffix => {
return {
name: `importing ${depSuffix} from ${fileSuffix}`,
filename: `a.${fileSuffix}.ts`,
code: `
import { x } from './b.${depSuffix}.js';
${requiredLine}
`,
globals: {
window: 'writable',
require: 'readable',
},
};
});
})
.flat(),
{
name: 'type import should have no effect',
filename: 'a.std.ts',
code: `import type { ReadonlyDeep } from './b.dom.js'`,
},
],
invalid: [
// Disallowed references
...[
['std', ['dom', 'node', 'preload', 'main']],
['dom', ['node', 'preload', 'main']],
['node', ['preload', 'main']],
['preload', ['main']],
['main', ['dom', 'preload']],
]
.map(([fileSuffix, depSuffixes]) => {
return depSuffixes.map(depSuffix => {
return {
name: `importing ${depSuffix} from ${fileSuffix}`,
filename: `a.${fileSuffix}.ts`,
code: `import { x } from './b.${depSuffix}.js'`,
errors: [
{
message: `Invalid suffix ${fileSuffix}, expected: ${depSuffix}`,
type: 'Program',
},
],
};
});
})
.flat(),
...['dom', 'node', 'preload', 'main'].map(suffix => {
return {
name: `no ${suffix} imports`,
filename: `a.${suffix}.ts`,
code: '',
errors: [
{
message: `Invalid suffix ${suffix}, expected: std`,
type: 'Program',
},
],
};
}),
// Invalid imports
{
name: 'preload in main',
filename: 'a.main.ts',
code: `
import { autoUpdater } from 'electron';
import './b.preload.js';
`,
errors: [
{
message: 'Invalid import/reference for suffix: main',
type: 'ImportDeclaration',
},
],
},
{
name: 'main in preload',
filename: 'a.preload.ts',
code: `
import { ipcRenderer } from 'electron';
import './b.main.js';
`,
errors: [
{
message: 'Invalid suffix preload, expected: main',
type: 'Program',
},
{
message: 'Invalid import/reference for suffix: main',
type: 'ImportSpecifier',
},
],
},
],
});

View File

@@ -13,7 +13,7 @@ js/util_worker.js
libtextsecure/components.js
libtextsecure/test/test.js
test/test.js
ts/protobuf/compiled.d.ts
ts/protobuf/compiled.std.d.ts
storybook-static/**
build/ICUMessageParams.d.ts

View File

@@ -193,6 +193,8 @@ const rules = {
const typescriptRules = {
...rules,
'local-rules/file-suffix': 'error',
// Override brace style to enable typescript-specific syntax
'brace-style': 'off',
'@typescript-eslint/brace-style': [
@@ -370,7 +372,7 @@ module.exports = {
},
},
{
files: ['ts/**/*_test.{ts,tsx}'],
files: ['ts/**/*_test.*.{ts,tsx}'],
rules: {
'func-names': 'off',
},

View File

@@ -27,17 +27,17 @@ jobs:
- backup
include:
- metric: startup
script: ts/test-mock/benchmarks/startup_bench.js
script: ts/test-mock/benchmarks/startup_bench.node.js
runCount: 10
- metric: send
script: ts/test-mock/benchmarks/send_bench.js
script: ts/test-mock/benchmarks/send_bench.node.js
runCount: 100
- metric: groupSend
script: ts/test-mock/benchmarks/group_send_bench.js
script: ts/test-mock/benchmarks/group_send_bench.node.js
runCount: 100
conversationSize: 500
- metric: largeGroupSendWithBlocks
script: ts/test-mock/benchmarks/group_send_bench.js
script: ts/test-mock/benchmarks/group_send_bench.node.js
runCount: 50
conversationSize: 500
groupSize: 500
@@ -45,20 +45,20 @@ jobs:
blockedCount: 10
discardCount: 2
- metric: largeGroupSend
script: ts/test-mock/benchmarks/group_send_bench.js
script: ts/test-mock/benchmarks/group_send_bench.node.js
runCount: 20
conversationSize: 50
groupSize: 500
contactCount: 500
discardCount: 2
- metric: convoOpen
script: ts/test-mock/benchmarks/convo_open_bench.js
script: ts/test-mock/benchmarks/convo_open_bench.node.js
runCount: 100
- metric: callHistorySearch
script: ts/test-mock/benchmarks/call_history_search_bench.js
script: ts/test-mock/benchmarks/call_history_search_bench.node.js
runCount: 100
- metric: backup
script: ts/test-mock/benchmarks/backup_bench.js
script: ts/test-mock/benchmarks/backup_bench.node.js
runs-on: ubuntu-22.04-8-cores
if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' && (!github.event.schedule || github.ref == 'refs/heads/main') }}

View File

@@ -138,9 +138,9 @@ jobs:
- name: Upload installer size
if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' && github.ref == 'refs/heads/main' }}
run: |
node ts/scripts/dd-installer-size.js macos-arm64
node ts/scripts/dd-installer-size.js macos-x64
node ts/scripts/dd-installer-size.js macos-universal
node ts/scripts/dd-installer-size.node.js macos-arm64
node ts/scripts/dd-installer-size.node.js macos-x64
node ts/scripts/dd-installer-size.node.js macos-universal
env:
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
- run: pnpm run test-release
@@ -224,7 +224,7 @@ jobs:
- name: Upload installer size
if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' && github.ref == 'refs/heads/main' }}
run: node ts/scripts/dd-installer-size.js linux
run: node ts/scripts/dd-installer-size.node.js linux
env:
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
@@ -306,7 +306,7 @@ jobs:
- name: Upload installer size
if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' && github.ref == 'refs/heads/main' }}
run: node ts/scripts/dd-installer-size.js windows
run: node ts/scripts/dd-installer-size.node.js windows
env:
DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
@@ -496,4 +496,4 @@ jobs:
- run: pnpm generate:phase-0
- name: Run OS version check
run: |
node ts/scripts/check-min-os-version.js
node ts/scripts/check-min-os-version.node.js

View File

@@ -51,7 +51,7 @@ jobs:
env:
ARTIFACTS_DIR: stories
- run: pnpm run build:esbuild
- run: node ts/scripts/compile-stories-icu-lookup.js stories
- run: node ts/scripts/compile-stories-icu-lookup.node.js stories
- name: Upload test artifacts
if: github.event_name == 'workflow_dispatch'

View File

@@ -2,6 +2,6 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { Context } from 'react';
import type { ThemeType } from '../ts/types/Util';
import type { ThemeType } from '../ts/types/Util.std.js';
export const StorybookThemeContext: Context<ThemeType>;

View File

@@ -2,6 +2,6 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { createContext } from 'react';
import { ThemeType } from '../ts/types/Util.js';
import { ThemeType } from '../ts/types/Util.std.js';
export const StorybookThemeContext = createContext(ThemeType.light);

View File

@@ -14,26 +14,26 @@ import { Provider } from 'react-redux';
import { Store, combineReducers, createStore } from 'redux';
import { Globals } from '@react-spring/web';
import { StorybookThemeContext } from './StorybookThemeContext.js';
import { SystemThemeType, ThemeType } from '../ts/types/Util.js';
import { setupI18n } from '../ts/util/setupI18n.js';
import { HourCyclePreference } from '../ts/types/I18N.js';
import { AxoProvider } from '../ts/axo/AxoProvider.js';
import { StateType } from '../ts/state/reducer.js';
import { StorybookThemeContext } from './StorybookThemeContext.std.js';
import { SystemThemeType, ThemeType } from '../ts/types/Util.std.js';
import { setupI18n } from '../ts/util/setupI18n.dom.js';
import { HourCyclePreference } from '../ts/types/I18N.std.js';
import { AxoProvider } from '../ts/axo/AxoProvider.dom.js';
import type { StateType } from '../ts/state/reducer.preload.js';
import {
ScrollerLockContext,
createScrollerLock,
} from '../ts/hooks/useScrollLock.js';
import { Environment, setEnvironment } from '../ts/environment.js';
import { parseUnknown } from '../ts/util/schemas.js';
import { LocaleEmojiListSchema } from '../ts/types/emoji.js';
import { FunProvider } from '../ts/components/fun/FunProvider.js';
import { EmojiSkinTone } from '../ts/components/fun/data/emojis.js';
import { MOCK_GIFS_PAGINATED_ONE_PAGE } from '../ts/components/fun/mocks.js';
} from '../ts/hooks/useScrollLock.dom.js';
import { Environment, setEnvironment } from '../ts/environment.std.js';
import { parseUnknown } from '../ts/util/schemas.std.js';
import { LocaleEmojiListSchema } from '../ts/types/emoji.std.js';
import { FunProvider } from '../ts/components/fun/FunProvider.dom.js';
import { EmojiSkinTone } from '../ts/components/fun/data/emojis.std.js';
import { MOCK_GIFS_PAGINATED_ONE_PAGE } from '../ts/components/fun/mocks.dom.js';
import type { FunEmojiSelection } from '../ts/components/fun/panels/FunPanelEmojis.js';
import type { FunGifSelection } from '../ts/components/fun/panels/FunPanelGifs.js';
import type { FunStickerSelection } from '../ts/components/fun/panels/FunPanelStickers.js';
import type { FunEmojiSelection } from '../ts/components/fun/panels/FunPanelEmojis.dom.js';
import type { FunGifSelection } from '../ts/components/fun/panels/FunPanelGifs.dom.js';
import type { FunStickerSelection } from '../ts/components/fun/panels/FunPanelStickers.dom.js';
setEnvironment(Environment.Development, true);

View File

@@ -309,7 +309,7 @@ Then, run the tests using `pnpm run test-release`.
macOS requires apps to be code signed with an Apple certificate. To test development builds
you can ad-hoc sign the packaged app which will let you run it locally.
1. In `package.json` remove the macOS signing script: `"sign": "./ts/scripts/sign-macos.js",`
1. In `package.json` remove the macOS signing script: `"sign": "./ts/scripts/sign-macos.node.js",`
2. Build the app and ad-hoc sign the app bundle:
```

View File

@@ -20,6 +20,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="bundles/about/app.js"></script>
<script type="module" src="bundles/about/app.dom.js"></script>
</body>
</html>

View File

@@ -12,6 +12,7 @@ import {
import { createLogger } from '../ts/logging/log.std.js';
import { AUMID } from './startup_config.main.js';
import type { WindowsNotificationData } from '../ts/services/notifications.preload.js';
// eslint-disable-next-line local-rules/file-suffix
import { renderWindowsToast } from './renderWindowsToast.dom.js';
const log = createLogger('WindowsNotifications');

View File

@@ -238,7 +238,7 @@ let sendDummyKeystroke: undefined | (() => void);
if (OS.isWindows()) {
try {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const windowsNotifications = require('./WindowsNotifications.js');
const windowsNotifications = require('./WindowsNotifications.main.js');
sendDummyKeystroke = windowsNotifications.sendDummyKeystroke;
} catch (error) {
log.error('Failed to initialize Windows Notifications:', error.stack);
@@ -730,7 +730,7 @@ async function createWindow() {
__dirname,
usePreloadBundle
? '../preload.wrapper.js'
: '../ts/windows/main/preload.js'
: '../ts/windows/main/preload.preload.js'
),
spellcheck,
},
@@ -1289,7 +1289,7 @@ async function showScreenShareWindow(sourceName: string | undefined) {
nodeIntegrationInWorker: false,
sandbox: true,
contextIsolation: true,
preload: join(__dirname, '../bundles/screenShare/preload.js'),
preload: join(__dirname, '../bundles/screenShare/preload.preload.js'),
},
x: Math.floor(display.size.width / 2) - width / 2,
y: 24,
@@ -1344,7 +1344,7 @@ async function showCallingDevToolsWindow() {
sandbox: true,
contextIsolation: true,
nativeWindowOpen: true,
preload: join(__dirname, '../bundles/calling-tools/preload.js'),
preload: join(__dirname, '../bundles/calling-tools/preload.preload.js'),
},
};
@@ -1398,7 +1398,7 @@ async function showAbout() {
nodeIntegrationInWorker: false,
sandbox: true,
contextIsolation: true,
preload: join(__dirname, '../bundles/about/preload.js'),
preload: join(__dirname, '../bundles/about/preload.preload.js'),
nativeWindowOpen: true,
},
};
@@ -1487,7 +1487,7 @@ async function showDebugLogWindow() {
nodeIntegrationInWorker: false,
sandbox: true,
contextIsolation: true,
preload: join(__dirname, '../bundles/debuglog/preload.js'),
preload: join(__dirname, '../bundles/debuglog/preload.preload.js'),
},
parent: mainWindow,
};
@@ -1546,7 +1546,7 @@ function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) {
nodeIntegrationInWorker: false,
sandbox: true,
contextIsolation: true,
preload: join(__dirname, '../bundles/permissions/preload.js'),
preload: join(__dirname, '../bundles/permissions/preload.preload.js'),
nativeWindowOpen: true,
},
parent: mainWindow,
@@ -2246,7 +2246,7 @@ app.on('ready', async () => {
nodeIntegration: false,
sandbox: true,
contextIsolation: true,
preload: join(__dirname, '../bundles/loading/preload.js'),
preload: join(__dirname, '../bundles/loading/preload.preload.js'),
},
icon: windowIcon,
});
@@ -3305,7 +3305,10 @@ async function showStickerCreatorWindow() {
nodeIntegrationInWorker: false,
sandbox: true,
contextIsolation: true,
preload: join(__dirname, '../ts/windows/sticker-creator/preload.js'),
preload: join(
__dirname,
'../ts/windows/sticker-creator/preload.preload.js'
),
nativeWindowOpen: true,
},
};

View File

@@ -8,7 +8,7 @@ import { v4 as generateUuid } from 'uuid';
import OS from '../ts/util/os/osMain.node.js';
import type { LoggerType } from '../ts/types/Logging.std.js';
import { strictAssert } from '../ts/util/assert.std.js';
import { type IpcResponseType } from '../ts/util/desktopCapturer.preload.js';
import type { IpcResponseType } from '../ts/util/desktopCapturer.preload.js';
const SPELL_CHECKER_DICTIONARY_DOWNLOAD_URL = `https://updates.signal.org/desktop/hunspell_dictionaries/${process.versions.electron}/`;

View File

@@ -31,7 +31,7 @@
/>
<script
type="module"
src="bundles/calling-tools/webrtc_internals.js"
src="bundles/calling-tools/webrtc_internals.dom.js"
></script>
</head>
<body>

4
ci.js
View File

@@ -3,8 +3,8 @@
const CI_CONFIG = JSON.parse(process.env.SIGNAL_CI_CONFIG || '');
const config = require('./app/config').default;
const config = require('./app/config.main.js').default;
config.util.extendDeep(config, CI_CONFIG);
require('./app/main');
require('./app/main.main.js');

View File

@@ -20,6 +20,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="bundles/debuglog/app.js"></script>
<script type="module" src="bundles/debuglog/app.dom.js"></script>
</body>
</html>

View File

@@ -6,4 +6,5 @@ module.exports = {
'license-comments': require('./.eslint/rules/license-comments'),
'type-alias-readonlydeep': require('./.eslint/rules/type-alias-readonlydeep'),
'enforce-tw': require('./.eslint/rules/enforce-tw'),
'file-suffix': require('./.eslint/rules/file-suffix'),
};

View File

@@ -11,7 +11,7 @@ import {StatsRatesCalculator, StatsReport} from './stats_rates_calculator.js';
import {StatsTable} from './stats_table.js';
import {TabView} from './tab_view.js';
import {UserMediaTable} from './user_media_table.js';
import '../../ts/windows/sandboxedInit.js';
import '../../ts/windows/sandboxedInit.dom.js';
let tabView = null;
let peerConnectionUpdateTable = null;

View File

@@ -31,6 +31,6 @@
</div>
<div id="message"></div>
</div>
<script type="module" src="bundles/loading/start.js"></script>
<script type="module" src="bundles/loading/start.dom.js"></script>
</body>
</html>

View File

@@ -13,7 +13,7 @@
"email": "support@signal.org"
},
"browserslist": "last 1 chrome versions",
"main": "app/main.js",
"main": "app/main.main.js",
"scripts": {
"postinstall": "pnpm run build:acknowledgments && pnpm run electron:install-app-deps",
"postuninstall": "pnpm run build:acknowledgments",
@@ -25,16 +25,16 @@
"build-release": "pnpm run build",
"sign-release": "node ts/updater/generateSignature.js",
"notarize": "echo 'No longer necessary'",
"get-strings": "ts-node ts/scripts/get-strings.ts && ts-node ts/scripts/gen-nsis-script.ts && ts-node ts/scripts/gen-locales-config.ts && run-p get-strings:locales get-strings:countries get-strings:emoji mark-unusued-strings-deleted && run-p build:compact-locales",
"get-strings:locales": "ts-node ./ts/scripts/build-localized-display-names.ts locales ts/scripts/locale-data/locale-display-names.csv build/locale-display-names.json",
"get-strings:countries": "ts-node ./ts/scripts/build-localized-display-names.ts countries ts/scripts/locale-data/country-display-names.csv build/country-display-names.json",
"get-strings:emoji": "ts-node ./ts/scripts/get-emoji-locales.ts",
"push-strings": "node ts/scripts/remove-strings.js && node ts/scripts/push-strings.js",
"mark-unusued-strings-deleted": "ts-node ./ts/scripts/mark-unused-strings-deleted.ts",
"get-expire-time": "node ts/scripts/get-expire-time.js",
"copy-components": "node ts/scripts/copy.js",
"build-module-protobuf": "pbjs --root='signal-desktop' --target static-module --force-long --no-typeurl --no-verify --no-create --no-convert --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --no-comments --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"get-strings": "ts-node ts/scripts/get-strings.node.ts && ts-node ts/scripts/gen-nsis-script.node.ts && ts-node ts/scripts/gen-locales-config.node.ts && run-p get-strings:locales get-strings:countries get-strings:emoji mark-unusued-strings-deleted && run-p build:compact-locales",
"get-strings:locales": "ts-node ./ts/scripts/build-localized-display-names.node.ts locales ts/scripts/locale-data/locale-display-names.csv build/locale-display-names.json",
"get-strings:countries": "ts-node ./ts/scripts/build-localized-display-names.node.ts countries ts/scripts/locale-data/country-display-names.csv build/country-display-names.json",
"get-strings:emoji": "ts-node ./ts/scripts/get-emoji-locales.node.ts",
"push-strings": "node ts/scripts/remove-strings.node.js && node ts/scripts/push-strings.node.js",
"mark-unusued-strings-deleted": "ts-node ./ts/scripts/mark-unused-strings-deleted.node.ts",
"get-expire-time": "node ts/scripts/get-expire-time.node.js",
"copy-components": "node ts/scripts/copy.node.js",
"build-module-protobuf": "pbjs --root='signal-desktop' --target static-module --force-long --no-typeurl --no-verify --no-create --no-convert --wrap commonjs --out ts/protobuf/compiled.std.js protos/*.proto && pbts --no-comments --out ts/protobuf/compiled.std.d.ts ts/protobuf/compiled.std.js",
"clean-module-protobuf": "rm -f ts/protobuf/compiled.std.d.ts ts/protobuf/compiled.std.js",
"build-protobuf": "pnpm run build-module-protobuf",
"clean-protobuf": "pnpm run clean-module-protobuf",
"prepare-beta-build": "node scripts/prepare_beta_build.js",
@@ -47,19 +47,19 @@
"prepare-staging-build": "node scripts/prepare_staging_build.js",
"prepare-linux-build": "node scripts/prepare_linux_build.js",
"test": "run-s test-node test-electron test-lint-intl test-eslint",
"test-electron": "node ts/scripts/test-electron.js",
"test-release": "node ts/scripts/test-release.js",
"test-electron": "node ts/scripts/test-electron.node.js",
"test-release": "node ts/scripts/test-release.node.js",
"test-node": "cross-env LANG=en-us electron-mocha --timeout 10000 --file test/setup-test-node.js --recursive ts/test-node",
"test-mock": "node ts/scripts/mocha-separator.js --require ts/test-mock/setup-ci.js -- ts/test-mock/**/*_test.js",
"test-mock-docker": "mocha --require ts/test-mock/setup-ci.js ts/test-mock/**/*_test.docker.js",
"test-mock": "node ts/scripts/mocha-separator.node.js --require ts/test-mock/setup-ci.node.js -- ts/test-mock/**/*_test.node.js",
"test-mock-docker": "mocha --require ts/test-mock/setup-ci.node.js ts/test-mock/**/*_test.docker.node.js",
"test-eslint": "mocha .eslint/rules/**/*.test.js --ignore-leaks",
"test-lint-intl": "ts-node ./build/intl-linter/linter.ts --test",
"test-lint-intl": "ts-node ./build/intl-linter/linter.node.ts --test",
"eslint": "eslint --cache . --cache-strategy content --max-warnings 0",
"lint": "run-p --aggregate-output --print-label lint-prettier lint-css check:types eslint",
"lint-deps": "node ts/util/lint/linter.js",
"lint-license-comments": "ts-node ts/util/lint/license_comments.ts",
"lint-deps": "node ts/util/lint/linter.node.js",
"lint-license-comments": "ts-node ts/util/lint/license_comments.node.ts",
"lint-prettier": "pprettier --check '**/*.{ts,tsx,d.ts,js,json,html,scss,md,yml,yaml}' '!node_modules/**'",
"lint-intl": "ts-node ./build/intl-linter/linter.ts",
"lint-intl": "ts-node ./build/intl-linter/linter.node.ts",
"lint-css": "stylelint '**/*.scss' --cache",
"danger:local": "./danger/danger.sh local --base main",
"danger:ci": "./danger/danger.sh ci --base origin/main",
@@ -85,10 +85,10 @@
"build-win32-all": "run-s --print-label generate build:esbuild:prod build:release-win32-all",
"build-linux": "run-s generate build:esbuild:prod && pnpm run build:release --publish=never",
"build:acknowledgments": "node scripts/generate-acknowledgments.js",
"build:dns-fallback": "node ts/scripts/generate-dns-fallback.js",
"build:icu-types": "node ts/scripts/generate-icu-types.js",
"build:compact-locales": "node ts/scripts/generate-compact-locales.js",
"build:tray-icons": "ts-node ts/scripts/generate-tray-icons.ts",
"build:dns-fallback": "node ts/scripts/generate-dns-fallback.node.js",
"build:icu-types": "node ts/scripts/generate-icu-types.node.js",
"build:compact-locales": "node ts/scripts/generate-compact-locales.node.js",
"build:tray-icons": "ts-node ts/scripts/generate-tray-icons.node.ts",
"build:dev": "run-s --print-label generate build:esbuild:prod",
"build:esbuild": "node scripts/esbuild.js",
"build:esbuild:scripts": "node scripts/esbuild.js --no-bundle",
@@ -100,14 +100,14 @@
"build:electron": "electron-builder --config.extraMetadata.environment=$SIGNAL_ENV",
"build:release": "cross-env SIGNAL_ENV=production pnpm run build:electron --config.directories.output=release",
"build:release-win32-all": "pnpm run build:release --arm64 --x64",
"build:preload-cache": "node ts/scripts/generate-preload-cache.js",
"build:preload-cache": "node ts/scripts/generate-preload-cache.node.js",
"build:emoji": "run-p build:emoji:32 build:emoji:64",
"build:emoji:32": "cwebp -progress -mt -preset icon -alpha_filter best -alpha_q 20 -pass 10 -q 75 ./node_modules/emoji-datasource-apple/img/apple/sheets-clean/32.png -o ./images/emoji-sheet-32.webp",
"build:emoji:64": "cwebp -progress -mt -preset icon -alpha_filter best -alpha_q 20 -pass 10 -q 75 ./node_modules/emoji-datasource-apple/img/apple/sheets-clean/64.png -o ./images/emoji-sheet-64.webp",
"verify": "run-p --print-label verify:*",
"verify:ts": "tsc --noEmit",
"electron:install-app-deps": "electron-builder install-app-deps",
"check-upgradeable-deps": "ts-node ts/scripts/check-upgradeable-deps.ts",
"check-upgradeable-deps": "ts-node ts/scripts/check-upgradeable-deps.node.ts",
"react-devtools": "react-devtools",
"run-with-devtools": "cross-env REACT_DEVTOOLS=1 run-p --print-label react-devtools start"
},
@@ -449,7 +449,7 @@
"minOSVersion": "21.0.1"
}
},
"sign": "./ts/scripts/sign-macos.js",
"sign": "./ts/scripts/sign-macos.node.js",
"singleArchFiles": "node_modules/@signalapp/{libsignal-client/prebuilds/**,ringrtc/build/**,sqlcipher/prebuilds/**}",
"target": [
{
@@ -476,7 +476,7 @@
"certificateSubjectName": "Signal Messenger, LLC",
"certificateSha1": "8D5E3CD800736C5E1FE459A1F5AA48287D4F6EC6",
"publisherName": "Signal Messenger, LLC",
"sign": "./ts/scripts/sign-windows.js",
"sign": "./ts/scripts/sign-windows.node.js",
"signingHashAlgorithms": [
"sha256"
]
@@ -562,10 +562,10 @@
"signalcaptcha"
]
},
"artifactBuildCompleted": "ts/scripts/artifact-build-completed.js",
"afterSign": "ts/scripts/after-sign.js",
"afterPack": "ts/scripts/after-pack.js",
"afterAllArtifactBuild": "ts/scripts/after-all-artifact-build.js",
"artifactBuildCompleted": "ts/scripts/artifact-build-completed.node.js",
"afterSign": "ts/scripts/after-sign.node.js",
"afterPack": "ts/scripts/after-pack.node.js",
"afterAllArtifactBuild": "ts/scripts/after-all-artifact-build.node.js",
"asar": {
"smartUnpack": false
},

View File

@@ -20,6 +20,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="bundles/permissions/app.js"></script>
<script type="module" src="bundles/permissions/app.dom.js"></script>
</body>
</html>

View File

@@ -59,7 +59,7 @@ const fn = script.runInThisContext({
importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
});
// See `ts/scripts/generate-preload-cache.ts`
// See `ts/scripts/generate-preload-cache.node.ts`
if (process.env.GENERATE_PRELOAD_CACHE) {
// Use hottest cache possible in CI
if (process.env.CI) {

View File

@@ -20,6 +20,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="bundles/screenShare/app.js"></script>
<script type="module" src="bundles/screenShare/app.dom.js"></script>
</body>
</html>

View File

@@ -94,7 +94,7 @@ const bundleDefaults = {
'mocha',
// Uses fast-glob and dynamic requires
'./preload_test.js',
'./preload_test.preload.js',
],
};
@@ -162,7 +162,9 @@ async function main() {
preloadConfig: {
...bundleDefaults,
mainFields: ['browser', 'main'],
entryPoints: [path.join(ROOT_DIR, 'ts', 'windows', 'main', 'preload.ts')],
entryPoints: [
path.join(ROOT_DIR, 'ts', 'windows', 'main', 'preload.preload.ts'),
],
outfile: path.join(ROOT_DIR, 'preload.bundle.js'),
},
});
@@ -174,17 +176,17 @@ async function sandboxedEnv() {
...sandboxedBrowserDefaults,
mainFields: ['browser', 'main'],
entryPoints: [
path.join(ROOT_DIR, 'ts', 'windows', 'about', 'app.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'debuglog', 'app.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'loading', 'start.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'permissions', 'app.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'screenShare', 'app.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'about', 'app.dom.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'debuglog', 'app.dom.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'loading', 'start.dom.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'permissions', 'app.dom.tsx'),
path.join(ROOT_DIR, 'ts', 'windows', 'screenShare', 'app.dom.tsx'),
path.join(
ROOT_DIR,
'ts',
'windows',
'calling-tools',
'webrtc_internals.ts'
'webrtc_internals.dom.ts'
),
],
},
@@ -192,12 +194,30 @@ async function sandboxedEnv() {
...sandboxedPreloadDefaults,
mainFields: ['browser', 'main'],
entryPoints: [
path.join(ROOT_DIR, 'ts', 'windows', 'about', 'preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'debuglog', 'preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'loading', 'preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'permissions', 'preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'calling-tools', 'preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'screenShare', 'preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'about', 'preload.preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'debuglog', 'preload.preload.ts'),
path.join(ROOT_DIR, 'ts', 'windows', 'loading', 'preload.preload.ts'),
path.join(
ROOT_DIR,
'ts',
'windows',
'permissions',
'preload.preload.ts'
),
path.join(
ROOT_DIR,
'ts',
'windows',
'calling-tools',
'preload.preload.ts'
),
path.join(
ROOT_DIR,
'ts',
'windows',
'screenShare',
'preload.preload.ts'
),
],
format: 'cjs',
outdir: 'bundles',

View File

@@ -4,7 +4,7 @@
const fs = require('node:fs');
const _ = require('lodash');
const { execSync } = require('node:child_process');
const { isAdhoc } = require('../ts/util/version.js');
const { isAdhoc } = require('../ts/util/version.std.js');
const { default: packageJson, version } = require('./packageJson.js');
// You might be wondering why this file is necessary. It comes down to our desire to allow

View File

@@ -4,7 +4,7 @@
const fs = require('node:fs');
const _ = require('lodash');
const { isAlpha } = require('../ts/util/version.js');
const { isAlpha } = require('../ts/util/version.std.js');
const { default: packageJson, version } = require('./packageJson.js');
// You might be wondering why this file is necessary. It comes down to our desire to allow

View File

@@ -4,7 +4,7 @@
const fs = require('node:fs');
const _ = require('lodash');
const { isAxolotl } = require('../ts/util/version.js');
const { isAxolotl } = require('../ts/util/version.std.js');
const { default: packageJson, version } = require('./packageJson.js');
// You might be wondering why this file is necessary. It comes down to our desire to allow

View File

@@ -4,7 +4,7 @@
const fs = require('node:fs');
const _ = require('lodash');
const { isBeta } = require('../ts/util/version.js');
const { isBeta } = require('../ts/util/version.std.js');
const { default: packageJson, version } = require('./packageJson.js');
// You might be wondering why this file is necessary. It comes down to our desire to allow

View File

@@ -4,7 +4,7 @@
const fs = require('node:fs');
const _ = require('lodash');
const { isAlpha } = require('../ts/util/version.js');
const { isAlpha } = require('../ts/util/version.std.js');
const { default: packageJson, version } = require('./packageJson.js');
// You might be wondering why this file is necessary. It comes down to our desire to allow

View File

@@ -16,7 +16,7 @@ if (release !== 'alpha' && release !== 'axolotl' && release !== 'adhoc') {
process.exit(1);
}
const { generateTaggedVersion } = require('../ts/util/version.js');
const { generateTaggedVersion } = require('../ts/util/version.std.js');
const shortSha = execSync('git rev-parse --short=9 HEAD')
.toString('utf8')

View File

@@ -1,25 +0,0 @@
<!-- Copyright 2021 Signal Messenger, LLC -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
<html dir="auto">
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none';
frame-src 'none';
form-action 'none';
font-src 'self';
img-src 'self' blob: data:;
media-src 'self' blob:;
object-src 'none';
script-src 'self';
style-src 'self' 'unsafe-inline';"
/>
<link href="stylesheets/manifest.css" rel="stylesheet" type="text/css" />
<link href="stylesheets/tailwind.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="app"></div>
<script type="module" src="bundles/settings/app.js"></script>
</body>
</html>

View File

@@ -4,10 +4,10 @@
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const { Crypto } = require('../ts/context/Crypto.js');
const { setEnvironment, Environment } = require('../ts/environment.js');
const { HourCyclePreference } = require('../ts/types/I18N.js');
const { default: package } = require('../ts/util/packageJson.js');
const { Crypto } = require('../ts/context/Crypto.node.js');
const { setEnvironment, Environment } = require('../ts/environment.std.js');
const { HourCyclePreference } = require('../ts/types/I18N.std.js');
const { default: package } = require('../ts/util/packageJson.node.js');
chai.use(chaiAsPromised);

View File

@@ -22,7 +22,7 @@ import createTaskWithTimeout, {
} from './textsecure/TaskWithTimeout.std.js';
import type { MessageAttributesType } from './model-types.d.ts';
import * as Bytes from './Bytes.std.js';
import * as Timers from './Timers.dom.js';
import * as Timers from './Timers.preload.js';
import * as indexedDb from './indexeddb.dom.js';
import type { MenuOptionsType } from './types/menu.std.js';
import { SocketStatus } from './types/SocketStatus.std.js';

View File

@@ -7,7 +7,7 @@ import type { Meta } from '@storybook/react';
import { IMAGE_JPEG } from '../types/MIME.std.js';
import type { Props } from './CompositionArea.dom.js';
import { CompositionArea } from './CompositionArea.dom.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import { fakeDraftAttachment } from '../test-helpers/fakeAttachment.std.js';
import { landscapeGreenUrl } from '../storybook/Fixtures.std.js';

View File

@@ -10,7 +10,7 @@ import { getDefaultConversation } from '../test-helpers/getDefaultConversation.s
import type { Props } from './CompositionInput.dom.js';
import { CompositionInput } from './CompositionInput.dom.js';
import { generateAci } from '../types/ServiceId.std.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import { EmojiSkinTone } from './fun/data/emojis.std.js';
const { i18n } = window.SignalContext;

View File

@@ -14,7 +14,7 @@ import { MessageStatuses } from '../types/message/MessageStatus.std.js';
import { ContactCheckboxDisabledReason } from './conversationList/ContactCheckbox.dom.js';
import { getDefaultConversation } from '../test-helpers/getDefaultConversation.std.js';
import { ThemeType } from '../types/Util.std.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import { makeFakeLookupConversationWithoutServiceId } from '../test-helpers/fakeLookupConversationWithoutServiceId.std.js';
const { times, omit } = lodash;

View File

@@ -12,7 +12,7 @@ import {
} from './ForwardMessagesModal.dom.js';
import { IMAGE_JPEG, VIDEO_MP4, stringToMIMEType } from '../types/MIME.std.js';
import { getDefaultConversation } from '../test-helpers/getDefaultConversation.std.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import { CompositionTextArea } from './CompositionTextArea.dom.js';
import type { MessageForwardDraft } from '../types/ForwardDraft.std.js';
import { EmojiSkinTone } from './fun/data/emojis.std.js';

View File

@@ -27,7 +27,7 @@ import {
} from '../test-helpers/getDefaultConversation.std.js';
import { DialogType } from '../types/Dialogs.std.js';
import { SocketStatus } from '../types/SocketStatus.std.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import {
makeFakeLookupConversationWithoutServiceId,
useUuidFetchState,

View File

@@ -7,7 +7,7 @@ import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { ButtonProps } from './PlaybackButton.dom.js';
import { PlaybackButton } from './PlaybackButton.dom.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import { ThemeType } from '../types/Util.std.js';
import { AUDIO_MP3 } from '../types/MIME.std.js';

View File

@@ -7,7 +7,7 @@ import type { Meta } from '@storybook/react';
import type { Props } from './SafetyNumberChangeDialog.dom.js';
import { SafetyNumberChangeDialog } from './SafetyNumberChangeDialog.dom.js';
import { getDefaultConversation } from '../test-helpers/getDefaultConversation.std.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext.std.js';
import { getFakeBadge } from '../test-helpers/getFakeBadge.std.js';
import { MY_STORY_ID } from '../types/Stories.std.js';
import { generateStoryDistributionId } from '../types/StoryDistributionId.std.js';

View File

@@ -11,7 +11,7 @@ import {
} from '../../test-helpers/getDefaultConversation.std.js';
import { getRandomColor } from '../../test-helpers/getRandomColor.std.js';
import { DurationInSeconds } from '../../util/durations/index.std.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.std.js';
import type { PropsType } from './ConversationHeader.dom.js';
import {
ConversationHeader,

View File

@@ -8,7 +8,7 @@ import { action } from '@storybook/addon-actions';
import type { Props } from './ConversationHero.dom.js';
import { ConversationHero } from './ConversationHero.dom.js';
import { HasStories } from '../../types/Stories.std.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.std.js';
import { getDefaultConversation } from '../../test-helpers/getDefaultConversation.std.js';
import { ThemeType } from '../../types/Util.std.js';
import type { GroupV2Membership } from './conversation-details/ConversationDetailsMembershipList.dom.js';

View File

@@ -9,7 +9,7 @@ import type { Props } from './Image.dom.js';
import { CurveType, Image } from './Image.dom.js';
import { IMAGE_PNG } from '../../types/MIME.std.js';
import type { ThemeType } from '../../types/Util.std.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.std.js';
import { fakeAttachment } from '../../test-helpers/fakeAttachment.std.js';

View File

@@ -11,7 +11,7 @@ import type { PropsType } from './Timeline.dom.js';
import { Timeline } from './Timeline.dom.js';
import type { TimelineItemType } from './TimelineItem.dom.js';
import { TimelineItem } from './TimelineItem.dom.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.std.js';
import { ConversationHero } from './ConversationHero.dom.js';
import { getDefaultConversation } from '../../test-helpers/getDefaultConversation.std.js';
import { TypingBubble } from './TypingBubble.dom.js';

View File

@@ -6,7 +6,7 @@ import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import { getDefaultConversation } from '../../../test-helpers/getDefaultConversation.std.js';
import { getFakeBadges } from '../../../test-helpers/getFakeBadge.std.js';
import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext.std.js';
import type { ConversationType } from '../../../state/ducks/conversations.preload.js';
import type { Props } from './ConversationDetailsHeader.dom.js';
import { ConversationDetailsHeader } from './ConversationDetailsHeader.dom.js';

View File

@@ -12,7 +12,7 @@ import { PendingInvites } from './PendingInvites.dom.js';
import type { ConversationType } from '../../../state/ducks/conversations.preload.js';
import { getDefaultConversation } from '../../../test-helpers/getDefaultConversation.std.js';
import { getFakeBadge } from '../../../test-helpers/getFakeBadge.std.js';
import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext.std.js';
const { times } = lodash;

View File

@@ -4,7 +4,7 @@
import * as React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext.std.js';
import type { MediaItemType } from '../../../types/MediaItem.std.js';
import { SignalService } from '../../../protobuf/index.std.js';
import {

View File

@@ -4,7 +4,7 @@
import * as React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.js';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext.std.js';
import { strictAssert } from '../../util/assert.std.js';
import { getFakeBadge } from '../../test-helpers/getFakeBadge.std.js';
import type { PropsType } from './MessageSearchResult.dom.js';

View File

@@ -1,6 +1,8 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
// We use `window` below, but it is guarded by type checks
// eslint-disable-next-line local-rules/file-suffix
import pino from 'pino';
import { LRUCache } from 'lru-cache';

View File

@@ -1,13 +1,13 @@
// Copyright 2018 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import './wrap.node.js';
import './wrap.std.js';
import {
signal as Signal,
signalbackups as Backups,
signalservice as SignalService,
migrations as Migrations,
} from './compiled.js';
} from './compiled.std.js';
export { Backups, SignalService, Signal, Migrations };

View File

@@ -11,7 +11,7 @@ import { createLogger } from '../../../logging/log.std.js';
import * as Bytes from '../../../Bytes.std.js';
import * as Errors from '../../../types/errors.std.js';
import { Signal } from '../../../protobuf/index.std.js';
import protobuf from '../../../protobuf/wrap.node.js';
import protobuf from '../../../protobuf/wrap.std.js';
import { strictAssert } from '../../../util/assert.std.js';
import { decryptAesCtr, encryptAesCtr } from '../../../Crypto.node.js';
import type { LocalBackupMetadataVerificationType } from '../../../types/backups.node.js';

View File

@@ -474,7 +474,12 @@ export class MainSQL {
}
#createWorker(): CreateWorkerResultType {
const scriptPath = join(app.getAppPath(), 'ts', 'sql', 'mainWorker.js');
const scriptPath = join(
app.getAppPath(),
'ts',
'sql',
'mainWorker.node.js'
);
const worker = new Worker(scriptPath);

View File

@@ -15,7 +15,7 @@ import { pipeline } from 'node:stream/promises';
import { Transform } from 'node:stream';
import fse from 'fs-extra';
import protobuf from '../protobuf/wrap.node.js';
import protobuf from '../protobuf/wrap.std.js';
import { createLogger } from '../logging/log.std.js';
import * as Bytes from '../Bytes.std.js';
import * as Errors from '../types/errors.std.js';

View File

@@ -15,7 +15,7 @@ import {
import { v4 as generateUuid } from 'uuid';
import { DataReader, DataWriter } from '../sql/Client.preload.js';
import { signal } from '../protobuf/compiled.js';
import { signal } from '../protobuf/compiled.std.js';
import { sessionStructureToBytes } from '../util/sessionTranslation.node.js';
import * as durations from '../util/durations/index.std.js';
import { explodePromise } from '../util/explodePromise.std.js';

View File

@@ -1,6 +1,8 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
// `window` use below is actually executed in the browser.
// eslint-disable-next-line local-rules/file-suffix
import { Proto } from '@signalapp/mock-server';
import { Aci } from '@signalapp/libsignal-client';
import { assert } from 'chai';

View File

@@ -1,6 +1,8 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
// `window` use below is actually executed in the browser.
// eslint-disable-next-line local-rules/file-suffix
import { assert } from 'chai';
import * as durations from '../../util/durations/index.std.js';

View File

@@ -14,7 +14,7 @@ describe('Errors', () => {
assert.typeOf(error, 'Error');
const formattedError = Errors.toLogFormat(error);
assert.include(formattedError, 'errors_test.js');
assert.include(formattedError, 'errors_test.node.js');
assert.include(
formattedError,
APP_ROOT_PATH,

View File

@@ -5,7 +5,7 @@ import { Transform } from 'node:stream';
import { createLogger } from '../logging/log.std.js';
import { SignalService as Proto } from '../protobuf/index.std.js';
import protobuf from '../protobuf/wrap.node.js';
import protobuf from '../protobuf/wrap.std.js';
import { DurationInSeconds } from '../util/durations/index.std.js';
import {
getAbsoluteAttachmentPath,

View File

@@ -151,7 +151,7 @@ import type { SendTypesType } from '../util/handleMessageSend.preload.js';
import { getStoriesBlocked } from '../util/stories.preload.js';
import { isNotNil } from '../util/isNotNil.std.js';
import { chunk } from '../util/iterables.std.js';
import { inspectUnknownFieldTags } from '../util/inspectProtobufs.node.js';
import { inspectUnknownFieldTags } from '../util/inspectProtobufs.std.js';
import { incrementMessageCounter } from '../util/incrementMessageCounter.preload.js';
import { filterAndClean } from '../types/BodyRange.std.js';
import {

View File

@@ -14,7 +14,7 @@ import type { ProxyAgent } from '../util/createProxyAgent.node.js';
import { createHTTPSAgent } from '../util/createHTTPSAgent.node.js';
import { HTTPError } from '../types/HTTPError.std.js';
import { createLogger } from '../logging/log.std.js';
import * as Timers from '../Timers.dom.js';
import * as Timers from '../Timers.preload.js';
import { ConnectTimeoutError } from './Errors.std.js';
import { handleStatusCode, translateError } from './Utils.dom.js';

View File

@@ -52,7 +52,7 @@ import { strictAssert } from '../util/assert.std.js';
import * as Errors from '../types/errors.std.js';
import { SignalService as Proto } from '../protobuf/index.std.js';
import { createLogger } from '../logging/log.std.js';
import * as Timers from '../Timers.dom.js';
import * as Timers from '../Timers.preload.js';
import type { IResource } from './WebSocket.preload.js';
import { AbortableProcess } from '../util/AbortableProcess.std.js';

View File

@@ -7,6 +7,7 @@ import type {
LookupAddress,
lookup as nodeLookup,
} from 'node:dns';
// eslint-disable-next-line local-rules/file-suffix
import * as electron from 'electron';
import type { ResolvedHost, ResolvedEndpoint } from 'electron';
import pTimeout from 'p-timeout';

View File

@@ -77,7 +77,6 @@ export function getDateTimeFormatter(
const locales =
localeOverride != null ? [localeOverride] : preferredSystemLocales;
const optionsWithPreferences = getOptionsWithPreferences(options);
console.error(locales);
const cacheKey = getCacheKey(locales, optionsWithPreferences);
const cachedFormatter = formatterCache.get(cacheKey);
if (cachedFormatter) {

File diff suppressed because it is too large Load Diff

View File

@@ -64,7 +64,7 @@ const FILES_TO_IGNORE = new Set(
'js/calling-tools/timeline_graph_view.js',
'js/calling-tools/user_media_table.js',
'js/calling-tools/util.js',
'js/calling-tools/webrtc_internals.js',
'js/calling-tools/webrtc_internals.dom.js',
].map(
// This makes sure the files are correct on Windows.
path.normalize

View File

@@ -3,7 +3,7 @@
import lodash from 'lodash';
import { signal } from '../protobuf/compiled.js';
import { signal } from '../protobuf/compiled.std.js';
import * as Bytes from '../Bytes.std.js';
import { deriveSecrets } from '../Crypto.node.js';

View File

@@ -1,4 +1,4 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import '../../../js/calling-tools/webrtc_internals.js';
import '../../../js/calling-tools/webrtc_internals.dom.js';

View File

@@ -11,14 +11,14 @@ export {};
if (config.environment === 'test') {
console.log('Importing test infrastructure...');
require('./preload_test.js');
require('./preload_test.preload.js');
}
if (config.ciMode) {
console.log(
`Importing CI infrastructure; enabled in config, mode: ${config.ciMode}`
);
const { getCI } = require('../../CI.js');
const { getCI } = require('../../CI.preload.js');
window.SignalCI = getCI({
deviceName: window.getTitle(),
forceUnprocessed: config.ciForceUnprocessed,

View File

@@ -10,7 +10,7 @@ const log = createLogger('preload');
window.preloadStartTime = Date.now();
try {
require('./start.js');
require('./start.preload.js');
} catch (error) {
/* eslint-disable no-console */
console.log('preload error!', error.stack);

View File

@@ -146,7 +146,7 @@ window.testUtilities = {
prepareTests() {
console.log('Preparing tests...');
const files = sync('../../test-{both,electron}/**/*_test.js', {
const files = sync('../../test-{both,electron}/**/*_test.*.js', {
absolute: true,
cwd: __dirname,
});

View File

@@ -15,7 +15,7 @@ import './phase0-devtools.node.js';
import './phase1-ipc.preload.js';
import '../preload.preload.js';
import './phase2-dependencies.preload.js';
import './phase3-post-signal.std.js';
import './phase3-post-signal.preload.js';
import './phase4-test.preload.js';
import type {

View File

@@ -24,7 +24,7 @@ export function getHeicConverter(): (
app.getAppPath(),
'ts',
'workers',
'heicConverterWorker.js'
'heicConverterWorker.node.js'
);
const worker = new Worker(scriptDir);