Fixathon: Web app dependency updates part 1 (#29036)

* Ensure all packages remove a node_modules in their folder when cleaning

* Upgrade typescript to 5.6.3 and move to root package.json

Note that this currently fails to build the types package due to
@types/node which I'm going to try to remove

* Update @types/node to 20.11 to match .nvmrc

* Upgrade zen-observable to 0.10.0

It looks like localforage-observable uses its own version
of zen-observable because it hasn't been updated in years.
This seems like something we probably should remove.

* Update yargs to 17.7.2

* Update webpack-dev-server to 5.1.0

* Remove webpack-bundle-analyzer since we haven't used it in years

* Update webpack to 5.95.0

* Update web-vitals to 4.2.4

* Update turndown to 7.2.0

* Update tinycolor2 to 1.6.0

* Update timezones.json to 1.7.0

* Update stylelint to 16.10.0, stylelint-config-recommended-scss to 14.1.0, and stylelint-scss to 6.8.1

* Update webpack-cli to 5.1.4

* Update style-loader to 4.0.0

* Change all Webpack scripts to be ES modules

* Update strip-ansi to 7.1.0

This is a build script dependency

* Update chalk to 5.3.0

This is a build script dependency

* Update concurrently to 9.0.1

This is a build script dependency

* Update smooth-scroll-into-view-if-needed to 2.0.2

* MM-48205 Update serialize-error to 11.0.3

We didn't update this before because it's an ES module which caused Jest to complain. We can fix that by making Jest transform the it

* Update semver to 7.6.3

* Update types for semver, tinycolor2, turndown, and webpack

* Fix type issues: change Props to a type

* Fix type issues: invalid HTML attributes

* Remove unneeded option from Webpack config
This commit is contained in:
Harrison Healey
2024-11-06 13:40:19 -05:00
committed by GitHub
parent 2117a4ed30
commit 4136343476
27 changed files with 2561 additions and 864 deletions

View File

@@ -41,7 +41,7 @@ const config = {
['jest-junit', {outputDirectory: 'build', outputName: 'test-results.xml'}], ['jest-junit', {outputDirectory: 'build', outputName: 'test-results.xml'}],
], ],
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!react-native|react-router|pdfjs-dist|p-queue|p-timeout|@mattermost/compass-components|@mattermost/compass-icons|cidr-regex|ip-regex)', 'node_modules/(?!react-native|react-router|pdfjs-dist|p-queue|p-timeout|@mattermost/compass-components|@mattermost/compass-icons|cidr-regex|ip-regex|serialize-error)',
], ],
transform: { transform: {
'^.+\\.(js|jsx|ts|tsx|mjs)$': 'babel-jest', '^.+\\.(js|jsx|ts|tsx|mjs)$': 'babel-jest',

View File

@@ -21,7 +21,7 @@
"@tanstack/react-table": "8.10.7", "@tanstack/react-table": "8.10.7",
"@tippyjs/react": "4.2.6", "@tippyjs/react": "4.2.6",
"@types/color-hash": "1.0.2", "@types/color-hash": "1.0.2",
"@types/turndown": "5.0.1", "@types/turndown": "5.0.5",
"bootstrap": "3.4.1", "bootstrap": "3.4.1",
"buffer": "6.0.3", "buffer": "6.0.3",
"chart.js": "3.8.2", "chart.js": "3.8.2",
@@ -87,18 +87,17 @@
"redux-thunk": "2.4.2", "redux-thunk": "2.4.2",
"regenerator-runtime": "0.13.10", "regenerator-runtime": "0.13.10",
"rudder-sdk-js": "1.0.16", "rudder-sdk-js": "1.0.16",
"semver": "7.5.2", "semver": "7.6.3",
"serialize-error": "8.0.1", "serialize-error": "11.0.3",
"shallow-equals": "1.0.0", "shallow-equals": "1.0.0",
"smooth-scroll-into-view-if-needed": "1.1.33", "smooth-scroll-into-view-if-needed": "2.0.2",
"stream-browserify": "3.0.0", "stream-browserify": "3.0.0",
"styled-components": "5.3.6", "styled-components": "5.3.6",
"timezones.json": "1.6.1", "timezones.json": "1.7.1",
"tinycolor2": "1.4.2", "tinycolor2": "1.6.0",
"turndown": "7.1.1", "turndown": "7.2.0",
"typescript": "5.5.4", "web-vitals": "4.2.4",
"web-vitals": "4.2.0", "zen-observable": "0.10.0"
"zen-observable": "0.9.0"
}, },
"devDependencies": { "devDependencies": {
"@deanwhillier/jest-matchmedia-mock": "1.2.0", "@deanwhillier/jest-matchmedia-mock": "1.2.0",
@@ -121,7 +120,6 @@
"@types/luxon": "3.0.2", "@types/luxon": "3.0.2",
"@types/mark.js": "8.11.6", "@types/mark.js": "8.11.6",
"@types/marked": "0.7.4", "@types/marked": "0.7.4",
"@types/node": "18.19.59",
"@types/react": "17.0.83", "@types/react": "17.0.83",
"@types/react-beautiful-dnd": "13.1.2", "@types/react-beautiful-dnd": "13.1.2",
"@types/react-bootstrap": "0.32.35", "@types/react-bootstrap": "0.32.35",
@@ -138,10 +136,10 @@
"@types/react-window": "1.8.5", "@types/react-window": "1.8.5",
"@types/react-window-infinite-loader": "1.0.6", "@types/react-window-infinite-loader": "1.0.6",
"@types/redux-mock-store": "1.0.3", "@types/redux-mock-store": "1.0.3",
"@types/semver": "7.3.9", "@types/semver": "7.5.8",
"@types/shallow-equals": "1.0.3", "@types/shallow-equals": "1.0.3",
"@types/styled-components": "5.1.32", "@types/styled-components": "5.1.32",
"@types/tinycolor2": "1.4.3", "@types/tinycolor2": "1.4.6",
"copy-webpack-plugin": "11.0.0", "copy-webpack-plugin": "11.0.0",
"emoji-datasource": "6.1.1", "emoji-datasource": "6.1.1",
"emoji-datasource-apple": "6.1.1", "emoji-datasource-apple": "6.1.1",
@@ -169,14 +167,13 @@
"react-router-enzyme-context": "1.2.0", "react-router-enzyme-context": "1.2.0",
"redux-mock-store": "1.5.4", "redux-mock-store": "1.5.4",
"redux-persist-node-storage": "2.0.0", "redux-persist-node-storage": "2.0.0",
"stylelint": "16.2.1", "stylelint": "16.10.0",
"stylelint-config-idiomatic-order": "10.0.0", "stylelint-config-idiomatic-order": "10.0.0",
"stylelint-config-recommended-scss": "14.0.0", "stylelint-config-recommended-scss": "14.1.0",
"stylelint-order": "6.0.4", "stylelint-order": "6.0.4",
"stylelint-scss": "6.1.0", "stylelint-scss": "6.8.1",
"webpack-bundle-analyzer": "4.7.0",
"webpack-pwa-manifest": "4.3.0", "webpack-pwa-manifest": "4.3.0",
"yargs": "16.2.0" "yargs": "17.7.2"
}, },
"overrides": { "overrides": {
"@mattermost/desktop-api": { "@mattermost/desktop-api": {

View File

@@ -376,7 +376,6 @@ exports[`components/SettingItemMin should match snapshot, profile picture on fil
className="img-preview__image" className="img-preview__image"
> >
<div <div
alt="profile image preview"
className="profile-img-preview" className="profile-img-preview"
style={ style={
Object { Object {
@@ -626,7 +625,6 @@ exports[`components/SettingItemMin should match snapshot, team icon on file 1`]
className="img-preview__image" className="img-preview__image"
> >
<div <div
alt="team image preview"
className="team-img-preview" className="team-img-preview"
style={ style={
Object { Object {

View File

@@ -8,9 +8,9 @@ import ChannelsList from 'components/admin_console/team_channel_settings/channel
import AdminHeader from 'components/widgets/admin_console/admin_header'; import AdminHeader from 'components/widgets/admin_console/admin_header';
import AdminPanel from 'components/widgets/admin_console/admin_panel'; import AdminPanel from 'components/widgets/admin_console/admin_panel';
interface Props { type Props = {
siteName?: string; siteName?: string;
} };
export const ChannelsSettings = ({siteName}: Props) => { export const ChannelsSettings = ({siteName}: Props) => {
return ( return (

View File

@@ -13,7 +13,7 @@ import {Constants, ModalIdentifiers} from 'utils/constants';
import type {PropsFromRedux} from './index'; import type {PropsFromRedux} from './index';
interface Props extends PropsFromRedux { type Props = PropsFromRedux & {
/** /**
* Object with info about user * Object with info about user
@@ -34,7 +34,7 @@ interface Props extends PropsFromRedux {
* Use for test selector * Use for test selector
*/ */
id?: string; id?: string;
} };
const LeaveChannel = ({ const LeaveChannel = ({
isDefault = true, isDefault = true,

View File

@@ -20,13 +20,13 @@ export interface Match {
export type MatchAndHistory = Pick<Props, 'match' | 'history'> export type MatchAndHistory = Pick<Props, 'match' | 'history'>
interface Props { type Props = {
match: Match; match: Match;
actions: { actions: {
onChannelByIdentifierEnter: (props: MatchAndHistory) => any; onChannelByIdentifierEnter: (props: MatchAndHistory) => any;
}; };
history: any; history: any;
} };
export default class ChannelIdentifierRouter extends React.PureComponent<Props> { export default class ChannelIdentifierRouter extends React.PureComponent<Props> {
constructor(props: Props) { constructor(props: Props) {

View File

@@ -29,7 +29,7 @@ import FilenameOverlay from './filename_overlay';
import type {PropsFromRedux} from './index'; import type {PropsFromRedux} from './index';
interface Props extends PropsFromRedux { type Props = PropsFromRedux & {
/* /*
* File detailed information * File detailed information
@@ -52,7 +52,7 @@ interface Props extends PropsFromRedux {
compactDisplay?: boolean; compactDisplay?: boolean;
disablePreview?: boolean; disablePreview?: boolean;
handleFileDropdownOpened?: (open: boolean) => void; handleFileDropdownOpened?: (open: boolean) => void;
} };
export default function FileAttachment(props: Props) { export default function FileAttachment(props: Props) {
const mounted = useRef(true); const mounted = useRef(true);

View File

@@ -8,10 +8,10 @@ import GetLinkModal from 'components/get_link_modal';
import type {PropsFromRedux} from './index'; import type {PropsFromRedux} from './index';
interface Props extends PropsFromRedux { type Props = PropsFromRedux & {
onExited: () => void; onExited: () => void;
fileId: string; fileId: string;
} };
const GetPublicLinkModal = ({ const GetPublicLinkModal = ({
actions, actions,

View File

@@ -39,13 +39,13 @@ import type {GlobalState} from 'types/store';
import {removePostCloseRHSDeleteDraft} from './actions'; import {removePostCloseRHSDeleteDraft} from './actions';
import PostComponent from './post_component'; import PostComponent from './post_component';
interface OwnProps { type OwnProps = {
post?: Post | UserActivityPost; post?: Post | UserActivityPost;
previousPostId?: string; previousPostId?: string;
postId?: string; postId?: string;
shouldHighlight?: boolean; shouldHighlight?: boolean;
location: keyof typeof Locations; location: keyof typeof Locations;
} };
function isFirstReply(post: Post, previousPost?: Post | null): boolean { function isFirstReply(post: Post, previousPost?: Post | null): boolean {
if (post.root_id) { if (post.root_id) {

View File

@@ -10,11 +10,6 @@ export interface Props {
name: string; name: string;
imageUrl: string; imageUrl: string;
} }
declare module 'react' {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
alt?: string;
}
}
const PostEmoji = ({children, name, imageUrl}: Props) => { const PostEmoji = ({children, name, imageUrl}: Props) => {
const emojiText = `:${name}:`; const emojiText = `:${name}:`;
@@ -33,7 +28,6 @@ const PostEmoji = ({children, name, imageUrl}: Props) => {
placement='top' placement='top'
> >
<span <span
alt={emojiText}
className='emoticon' className='emoticon'
data-testid={`postEmoji.${emojiText}`} data-testid={`postEmoji.${emojiText}`}
style={{backgroundImage: backgroundImageUrl}} style={{backgroundImage: backgroundImageUrl}}

View File

@@ -6,13 +6,13 @@ import {FormattedMessage} from 'react-intl';
import type {FileInfo} from '@mattermost/types/files'; import type {FileInfo} from '@mattermost/types/files';
interface Props { type Props = {
/* /*
* An array of file metadata for the parent post * An array of file metadata for the parent post
*/ */
fileInfos?: FileInfo[]; fileInfos?: FileInfo[];
} };
const CommentedOnFilesMessage = ({ const CommentedOnFilesMessage = ({
fileInfos, fileInfos,

View File

@@ -43,11 +43,11 @@ export const isChannelLoading = (params: RouteViewParams, channel?: Channel, tea
return true; return true;
}; };
interface RouteViewParams { type RouteViewParams = {
team?: string; team?: string;
identifier?: string; identifier?: string;
postid?: string; postid?: string;
} };
type Props = {channelId: string} & RouteComponentProps<RouteViewParams> type Props = {channelId: string} & RouteComponentProps<RouteViewParams>

View File

@@ -9,13 +9,13 @@ import {Preferences} from 'utils/constants';
import PostList from './post_list'; import PostList from './post_list';
interface Props { type Props = {
lastViewedAt?: number; lastViewedAt?: number;
channelLoading: boolean; channelLoading: boolean;
channelId: string; channelId: string;
focusedPostId?: string; focusedPostId?: string;
unreadScrollPosition: string; unreadScrollPosition: string;
} };
interface State { interface State {
unreadChunkTimeStamp?: number; unreadChunkTimeStamp?: number;

View File

@@ -19,7 +19,7 @@ import {RHSStates} from 'utils/constants';
import type {RhsState} from 'types/store/rhs'; import type {RhsState} from 'types/store/rhs';
interface Props extends WrappedComponentProps { type Props = WrappedComponentProps & {
isExpanded: boolean; isExpanded: boolean;
isMobileView: boolean; isMobileView: boolean;
rootPostId: string; rootPostId: string;
@@ -40,7 +40,7 @@ interface Props extends WrappedComponentProps {
closeRightHandSide: (e?: React.MouseEvent) => void; closeRightHandSide: (e?: React.MouseEvent) => void;
toggleRhsExpanded: (e: React.MouseEvent) => void; toggleRhsExpanded: (e: React.MouseEvent) => void;
setThreadFollow: (userId: string, teamId: string, threadId: string, newState: boolean) => void; setThreadFollow: (userId: string, teamId: string, threadId: string, newState: boolean) => void;
} };
class RhsHeaderPost extends React.PureComponent<Props> { class RhsHeaderPost extends React.PureComponent<Props> {
handleBack = (e: React.MouseEvent) => { handleBack = (e: React.MouseEvent) => {

View File

@@ -172,7 +172,6 @@ export default class SettingPicture extends Component<Props, State> {
<div className={`${imageContext}-img-preview`}> <div className={`${imageContext}-img-preview`}>
<div className='img-preview__image'> <div className='img-preview__image'>
<div <div
alt={`${imageContext} image preview`}
style={imageStyles} style={imageStyles}
className={`${imageContext}-img-preview`} className={`${imageContext}-img-preview`}
/> />

View File

@@ -78,7 +78,6 @@ const TeamPictureSection = ({team, file, teamName, disabled, onFileChange, onRem
return ( return (
<div <div
id='teamIconImage' id='teamIconImage'
alt='team image preview'
style={imageStyles} style={imageStyles}
className='team-img-preview' className='team-img-preview'
onClick={handleInputFile} onClick={handleInputFile}

View File

@@ -10,10 +10,15 @@ import MenuWrapperAnimation from './menu_wrapper_animation';
import './menu_wrapper.scss'; import './menu_wrapper.scss';
declare module 'react' { declare module 'react' {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
// This isn't a valid HTML attribute, but we use it in enough places now that it'll require some work to remove it
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface HTMLAttributes<T> {
disabled?: boolean; disabled?: boolean;
} }
} }
type Props = { type Props = {
children?: React.ReactNode; children?: React.ReactNode;
className: string; className: string;

View File

@@ -14,8 +14,6 @@ const webpack = require('webpack');
const {ModuleFederationPlugin} = require('webpack').container; const {ModuleFederationPlugin} = require('webpack').container;
const WebpackPwaManifest = require('webpack-pwa-manifest'); const WebpackPwaManifest = require('webpack-pwa-manifest');
// const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
const packageJson = require('./package.json'); const packageJson = require('./package.json');
const NPM_TARGET = process.env.npm_lifecycle_event; const NPM_TARGET = process.env.npm_lifecycle_event;
@@ -141,7 +139,6 @@ var config = {
crypto: require.resolve('crypto-browserify'), crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'), stream: require.resolve('stream-browserify'),
buffer: require.resolve('buffer/'), buffer: require.resolve('buffer/'),
process: require.resolve('process/browser.js'),
}, },
}, },
performance: { performance: {
@@ -266,13 +263,6 @@ var config = {
sizes: '96x96', sizes: '96x96',
}], }],
}), }),
// Disabling this plugin until we come up with better bundle analysis ci
// new BundleAnalyzerPlugin({
// analyzerMode: 'disabled',
// generateStatsFile: true,
// statsFilename: 'bundlestats.json',
// }),
], ],
}; };
@@ -407,16 +397,21 @@ if (targetIsDevServer) {
devtool: 'eval-cheap-module-source-map', devtool: 'eval-cheap-module-source-map',
devServer: { devServer: {
liveReload: true, liveReload: true,
proxy: { proxy: [
{
// Forward these requests to the server context: '/api',
'/api': {
...proxyToServer, ...proxyToServer,
ws: true, ws: true,
}, },
'/plugins': proxyToServer, {
'/static/plugins': proxyToServer, context: '/plugins',
}, ...proxyToServer,
},
{
context: '/static/plugins',
...proxyToServer,
},
],
port: 9005, port: 9005,
devMiddleware: { devMiddleware: {
writeToDisk: false, writeToDisk: false,

3221
webapp/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,9 +7,9 @@
}, },
"scripts": { "scripts": {
"postinstall": "patch-package && npm run build --workspace=platform/types --workspace=platform/client --workspace=platform/components", "postinstall": "patch-package && npm run build --workspace=platform/types --workspace=platform/client --workspace=platform/components",
"build": "node scripts/build.js", "build": "node scripts/build.mjs",
"run": "node scripts/run.js", "run": "node scripts/run.mjs",
"dev-server": "node scripts/dev-server.js", "dev-server": "node scripts/dev-server.mjs",
"test": "npm run test --workspaces --if-present", "test": "npm run test --workspaces --if-present",
"test:updatesnapshot": "npm run test:updatesnapshot --workspaces --if-present", "test:updatesnapshot": "npm run test:updatesnapshot --workspaces --if-present",
"test-ci": "npm run test-ci --workspaces --if-present", "test-ci": "npm run test-ci --workspaces --if-present",
@@ -19,21 +19,23 @@
"clean": "npm run clean --workspaces --if-present" "clean": "npm run clean --workspaces --if-present"
}, },
"dependencies": { "dependencies": {
"react-intl": "6.6.2" "react-intl": "6.6.2",
"typescript": "5.6.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.22.0", "@babel/core": "7.22.0",
"@babel/preset-env": "7.21.5", "@babel/preset-env": "7.21.5",
"@babel/preset-react": "7.18.6", "@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "7.21.5", "@babel/preset-typescript": "7.21.5",
"@types/webpack-env": "1.18.1", "@types/node": "20.11.30",
"@types/webpack-env": "1.18.5",
"babel-loader": "9.1.2", "babel-loader": "9.1.2",
"babel-plugin-formatjs": "10.5.1", "babel-plugin-formatjs": "10.5.1",
"babel-plugin-styled-components": "2.1.1", "babel-plugin-styled-components": "2.1.1",
"babel-plugin-typescript-to-proptypes": "2.1.0", "babel-plugin-typescript-to-proptypes": "2.1.0",
"blessed": "0.1.81", "blessed": "0.1.81",
"chalk": "4.1.2", "chalk": "5.3.0",
"concurrently": "7.6.0", "concurrently": "9.0.1",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"css-loader": "6.7.3", "css-loader": "6.7.3",
"eslint": "8.57.0", "eslint": "8.57.0",
@@ -45,11 +47,11 @@
"patch-package": "8.0.0", "patch-package": "8.0.0",
"sass": "1.71.1", "sass": "1.71.1",
"sass-loader": "14.1.1", "sass-loader": "14.1.1",
"strip-ansi": "6.0.1", "strip-ansi": "7.1.0",
"style-loader": "3.3.2", "style-loader": "4.0.0",
"webpack": "5.81.0", "webpack": "5.95.0",
"webpack-cli": "5.0.2", "webpack-cli": "5.1.4",
"webpack-dev-server": "4.13.3" "webpack-dev-server": "5.1.0"
}, },
"overrides": { "overrides": {
"@floating-ui/react": { "@floating-ui/react": {

View File

@@ -30,5 +30,8 @@
"eslint-plugin-react-hooks": { "eslint-plugin-react-hooks": {
"optional": true "optional": true
} }
},
"scripts": {
"clean": "rm -rf node_modules"
} }
} }

View File

@@ -40,6 +40,6 @@
"build": "tsc --build --verbose", "build": "tsc --build --verbose",
"check": "eslint --ext .js,.jsx,.tsx,.ts ./src --quiet", "check": "eslint --ext .js,.jsx,.tsx,.ts ./src --quiet",
"run": "tsc --watch --preserveWatchOutput", "run": "tsc --watch --preserveWatchOutput",
"clean": "rm -rf lib *.tsbuildinfo" "clean": "rm -rf lib node_modules *.tsbuildinfo"
} }
} }

View File

@@ -3,10 +3,10 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
const chalk = require('chalk'); import chalk from 'chalk';
const concurrently = require('concurrently'); import concurrently from 'concurrently';
const {getExitCode, getPlatformCommands} = require('./utils.js'); import {getExitCode, getPlatformCommands} from './utils.mjs';
async function buildAll() { async function buildAll() {
console.log(chalk.inverse.bold('Building subpackages...') + '\n'); console.log(chalk.inverse.bold('Building subpackages...') + '\n');

View File

@@ -3,10 +3,10 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
const chalk = require('chalk'); import chalk from 'chalk';
const concurrently = require('concurrently'); import concurrently from 'concurrently';
const {getPlatformCommands} = require('./utils.js'); import {getPlatformCommands} from './utils.mjs';
async function watchAllWithDevServer() { async function watchAllWithDevServer() {
console.log(chalk.inverse.bold('Watching web app and all subpackages...')); console.log(chalk.inverse.bold('Watching web app and all subpackages...'));

View File

@@ -3,11 +3,11 @@
/* eslint-disable no-console, no-process-env */ /* eslint-disable no-console, no-process-env */
const chalk = require('chalk'); import chalk from 'chalk';
const concurrently = require('concurrently'); import concurrently from 'concurrently';
const {makeRunner} = require('./runner.js'); import {makeRunner} from './runner.mjs';
const {getExitCode, getPlatformCommands} = require('./utils.js'); import {getExitCode, getPlatformCommands} from './utils.mjs';
async function watchAll(useRunner) { async function watchAll(useRunner) {
if (!useRunner) { if (!useRunner) {

View File

@@ -1,10 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
const {Writable} = require('stream'); import {Writable} from 'node:stream';
const blessed = require('blessed'); import blessed from 'blessed';
const stripAnsi = require('strip-ansi'); import stripAnsi from 'strip-ansi';
class Runner { class Runner {
commands; commands;
@@ -228,11 +228,10 @@ class Runner {
} }
} }
function makeRunner(commands) { export function makeRunner(commands) {
const runner = new Runner(commands); const runner = new Runner(commands);
runner.renderUi(); runner.renderUi();
return runner; return runner;
} }
exports.makeRunner = makeRunner;

View File

@@ -1,13 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
const path = require('path'); import fs from 'node:fs';
import path from 'node:path';
const chalk = require('chalk'); import chalk from 'chalk';
const packageJson = require('../package.json');
function getWorkspaces() { function getWorkspaces() {
const packageFile = fs.readFileSync('package.json');
const packageJson = JSON.parse(packageFile, 'utf8');
return packageJson.workspaces; return packageJson.workspaces;
} }
@@ -17,8 +19,8 @@ function getPlatformPackagesContainingCommand(scriptName) {
return false; return false;
} }
// eslint-disable-next-line global-require const workspacePackageFile = fs.readFileSync(path.join(workspace, 'package.json'));
const workspacePackageJson = require(path.join(__dirname, '..', workspace, 'package.json')); const workspacePackageJson = JSON.parse(workspacePackageFile, 'utf8');
return workspacePackageJson?.scripts?.[scriptName]; return workspacePackageJson?.scripts?.[scriptName];
}); });
@@ -27,7 +29,7 @@ function getPlatformPackagesContainingCommand(scriptName) {
/** /**
* Returns an array of concurrently commands to run a given script on every platform workspace that contains it. * Returns an array of concurrently commands to run a given script on every platform workspace that contains it.
*/ */
function getPlatformCommands(scriptName) { export function getPlatformCommands(scriptName) {
return getPlatformPackagesContainingCommand(scriptName).map((workspace) => ({ return getPlatformPackagesContainingCommand(scriptName).map((workspace) => ({
command: `npm:${scriptName} --workspace=${workspace}`, command: `npm:${scriptName} --workspace=${workspace}`,
name: workspace.substring(workspace.lastIndexOf('/') + 1), name: workspace.substring(workspace.lastIndexOf('/') + 1),
@@ -46,7 +48,7 @@ function getColorForWorkspace(workspace) {
* @param {import("concurrently").CloseEvent[]} closeEvents - An array of CloseEvents thrown by concurrently when waiting on a result * @param {import("concurrently").CloseEvent[]} closeEvents - An array of CloseEvents thrown by concurrently when waiting on a result
* @param {number} codeOnSignal - Which error code to return when the process is interrupted * @param {number} codeOnSignal - Which error code to return when the process is interrupted
*/ */
function getExitCode(closeEvents, codeOnSignal = 1) { export function getExitCode(closeEvents, codeOnSignal = 1) {
const exitCode = closeEvents.find((event) => !event.killed && event.exitCode > 0)?.exitCode; const exitCode = closeEvents.find((event) => !event.killed && event.exitCode > 0)?.exitCode;
if (typeof exitCode === 'string') { if (typeof exitCode === 'string') {
@@ -55,8 +57,3 @@ function getExitCode(closeEvents, codeOnSignal = 1) {
return exitCode; return exitCode;
} }
} }
module.exports = {
getExitCode,
getPlatformCommands,
};