Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Update dependencies, require node 20 #775

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
- name: Use Node.js
Copy link
Contributor

Choose a reason for hiding this comment

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

N.B. Remember to update the Dockerfile.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in af9075b

uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
- run: yarn --ignore-scripts --pure-lockfile --strict-semver
- run: yarn lint
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [16, 18]
node_version: [20]
steps:
- uses: actions/checkout@v2
- name: Use Node.js
Expand All @@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [16, 18]
node_version: [20]
steps:
- uses: actions/checkout@v2
- name: Use Node.js
Expand All @@ -38,7 +38,7 @@ jobs:
runs-on: ubuntu-latest
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally we should make sure this works before merging.

strategy:
matrix:
node_version: [16, 18]
node_version: [20]
steps:
- uses: actions/checkout@v2
- name: Use Node.js
Expand All @@ -51,5 +51,5 @@ jobs:
docker run --detach --publish 5432:5432 \
--env POSTGRES_PASSWORD=pass \
--env POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
postgres:13
postgres:16
- run: yarn test:postgres
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18-bullseye-slim AS BUILD
FROM node:20-bullseye-slim AS BUILD

# git is needed to install Half-Shot/slackdown
RUN apt update && apt install -y git
Expand Down
1 change: 1 addition & 0 deletions changelog.d/775.removal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Drop support for Node 16 and 18, require Node 20.
83 changes: 42 additions & 41 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "2.1.2",
"description": "A Matrix <--> Slack bridge",
"engines": {
"node": ">=16 <=18"
"node": ">=20"
},
"main": "app.js",
"scripts": {
Expand Down Expand Up @@ -35,64 +35,65 @@
"homepage": "https://github.com/matrix-org/matrix-appservice-slack#readme",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"@slack/logger": "^3.0.0",
"@slack/rtm-api": "^6.0.0",
"@slack/logger": "^4.0.0",
"@slack/rtm-api": "^6.2.1",
"@slack/web-api": "^6.7.2",
"Slackdown": "git+https://Half-Shot@github.com/half-shot/slackdown.git",
"ajv": "^8.12.0",
"axios": "^0.27.2",
"classnames": "^2.3.2",
"axios": "^1.6.8",
"classnames": "^2.5.1",
"escape-string-regexp": "^4.0.0",
"https-proxy-agent": "^5.0.1",
"matrix-appservice-bridge": "^8.1.2",
"matrix-widget-api": "^1.1.1",
"minimist": "^1.2.6",
"https-proxy-agent": "^7.0.4",
"matrix-appservice-bridge": "^10.1.0",
"matrix-bot-sdk": "^0.7.1",
"matrix-widget-api": "^1.6.0",
"minimist": "^1.2.8",
"nedb": "^1.8.0",
"node-emoji": "^1.10.0",
"node-emoji": "^2.1.3",
"nunjucks": "^3.2.4",
"p-queue": "^6.0.0",
"pg-promise": "^10.11.1",
"randomstring": "^1.2.1",
"pg-promise": "^11.5.5",
"randomstring": "^1.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"url-join": "^5.0.0",
"uuid": "^8.3.2",
"yargs": "17.5.1"
"uuid": "^9.0.1",
"yargs": "17.7.2"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.3",
"@tsconfig/node16": "^1.0.3",
"@types/chai": "^4.2.21",
"@types/js-yaml": "^4.0.2",
"@types/mocha": "^9.1.1",
"@types/nedb": "^1.8.12",
"@types/node": "^18.6.1",
"@types/node-emoji": "^1.8.1",
"@types/nunjucks": "^3.1.5",
"@types/randomstring": "^1.1.7",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@types/uuid": "^8.3.1",
"@types/yargs": "17.0.10",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.50.0",
"@vitejs/plugin-react": "^3.1.0",
"autoprefixer": "^10.4.13",
"@tailwindcss/forms": "^0.5.7",
"@tsconfig/node20": "^20.1.3",
"@types/chai": "^4.3.14",
"@types/js-yaml": "^4.0.9",
"@types/mocha": "^10.0.6",
"@types/nedb": "^1.8.16",
"@types/node": "^20.11.30",
"@types/node-emoji": "^2.1.0",
"@types/nunjucks": "^3.2.6",
"@types/randomstring": "^1.1.12",
"@types/react": "^18.2.71",
"@types/react-dom": "^18.2.22",
"@types/uuid": "^9.0.8",
"@types/yargs": "17.0.32",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.19",
"chai": "^4.3.4",
"eslint": "^8.20.0",
"eslint-plugin-jsdoc": "^39.3.3",
"eslint": "^8.57.0",
"eslint-plugin-jsdoc": "^48.2.1",
"eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"js-yaml": "^4.1.0",
"mocha": "^10.0.0",
"postcss": "^8.4.38",
"prom-client": "^15.1.0",
"nyc": "^15.1.0",
"postcss": "^8.4.21",
"prom-client": "^14.0.1",
"source-map-support": "^0.5.19",
"tailwindcss": "^3.2.4",
"ts-node": "^10.1.0",
"typescript": "^4.4.3",
"vite": "^4.1.1"
"tailwindcss": "^3.4.1",
"ts-node": "^10.9.2",
"typescript": "^5.4.3",
"vite": "^5.2.6"
}
}
8 changes: 4 additions & 4 deletions src/BridgedRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { Logger, Intent } from "matrix-appservice-bridge";
import { SlackGhost } from "./SlackGhost";
import { Main, METRIC_SENT_MESSAGES } from "./Main";
import { default as substitutions, getFallbackForMissingEmoji, IMatrixToSlackResult } from "./substitutions";
import { default as substitutions, IMatrixToSlackResult } from "./substitutions";
import * as emoji from "node-emoji";
import { ISlackMessageEvent, ISlackEvent, ISlackFile } from "./BaseSlackHandler";
import { WebAPIPlatformError, WebClient } from "@slack/web-api";
Expand Down Expand Up @@ -269,7 +269,7 @@
return null;
}

public async onMatrixReaction(message: any): Promise<void> {

Check warning on line 272 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const relatesTo = message.content["m.relates_to"];
const eventStore = this.main.datastore;
const event = await eventStore.getEventByMatrixId(message.room_id, relatesTo.event_id);
Expand Down Expand Up @@ -306,7 +306,7 @@
// bot user. Search for #fix_reactions_as_bot.
const res = await client.reactions.add({
as_user: false,
channel: this.slackChannelId,
channel: this.slackChannelId!,
name: emojiKeyName,
timestamp: event.slackTs,
});
Expand All @@ -329,7 +329,7 @@
});
}

public async onMatrixRedaction(message: any): Promise<void> {

Check warning on line 332 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const clientForRequest = await this.getClientForRequest(message.sender);
if (!clientForRequest) {
log.warn("No client to handle redaction");
Expand Down Expand Up @@ -383,7 +383,7 @@
}
}

public async onMatrixEdit(message: any): Promise<boolean> {

Check warning on line 386 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const clientForRequest = await this.getClientForRequest(message.sender);
if (!clientForRequest) {
log.warn("No client to handle edit");
Expand Down Expand Up @@ -438,7 +438,7 @@
return true;
}

public async onMatrixMessage(message: any): Promise<boolean> {

Check warning on line 441 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const puppetedClient = await this.main.clientFactory.getClientForUser(this.SlackTeamId!, message.sender);
if (!this.slackWebhookUri && !this.botClient && !puppetedClient) { return false; }
const slackClient = puppetedClient || this.botClient;
Expand Down Expand Up @@ -710,7 +710,7 @@
if (ghostChanged) {
await this.main.fixDMMetadata(this, ghost);
}
this.slackSendLock = this.slackSendLock.then(() => {
this.slackSendLock = this.slackSendLock.then(async () => {
// Check again
if (this.recentSlackMessages.includes(message.ts)) {
// We sent this, ignore
Expand Down Expand Up @@ -743,7 +743,7 @@
return;
}

let reactionKey = emoji.emojify(`:${message.reaction}:`, getFallbackForMissingEmoji);
let reactionKey = emoji.emojify(`:${message.reaction}:`);
// Element uses the default thumbsup and thumbsdown reactions with an appended variant character.
if (reactionKey === '👍' || reactionKey === '👎') {
reactionKey += '\ufe0f'.normalize(); // VARIATION SELECTOR-16
Expand Down Expand Up @@ -833,7 +833,7 @@
}

private setValue<T>(key: string, value: T) {
const sneakyThis = this as any;

Check warning on line 836 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (sneakyThis[key] === value) {
return;
}
Expand Down Expand Up @@ -1156,7 +1156,7 @@
Strip out reply fallbacks. Borrowed from
https://github.com/turt2live/matrix-js-bot-sdk/blob/master/src/preprocessors/RichRepliesPreprocessor.ts
*/
private async stripMatrixReplyFallback(event: any): Promise<any> {

Check warning on line 1159 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type

Check warning on line 1159 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (!event.content?.body) {
return event;
}
Expand Down Expand Up @@ -1193,7 +1193,7 @@
Given an event which is in reply to something else return the event ID of the
top most event in the reply chain, i.e. the one without a relates to.
*/
private async findParentReply(message: any, depth = 0): Promise<string> {

Check warning on line 1196 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const MAX_DEPTH = 10;
// Extract the referenced event
if (!message.content) { return message.event_id; }
Expand Down Expand Up @@ -1269,7 +1269,7 @@
msgtype: "m.image",
url,
// TODO: Define some matrix types
} as any;

Check warning on line 1272 in src/BridgedRoom.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type

if (file.original_w) {
message.info.w = file.original_w;
Expand Down
2 changes: 1 addition & 1 deletion src/SlackRTMHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export class SlackRTMHandler extends SlackEventHandler {
const intent = await room.getIntentForRoom();
// We only want to act on trivial messages
// This can be asyncronous to the handling of the message.
intent.getStateEvent(room.MatrixRoomId, 'm.room.member', puppet.matrixId, true).then((state) => {
intent.getStateEvent(room.MatrixRoomId, 'm.room.member', puppet.matrixId, true).then(async (state) => {
if (!['invite', 'join'].includes(state?.membership)) {
// Automatically invite the user the room.
log.info(`User ${puppet.matrixId} is not in ${room.MatrixRoomId}/${room.SlackChannelId}, inviting`);
Expand Down
10 changes: 1 addition & 9 deletions src/substitutions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ const log = new Logger("substitutions");
const ATTACHMENT_TYPES = ["m.audio", "m.video", "m.file", "m.image"];
const PILL_REGEX = /<a href="https:\/\/matrix\.to\/#\/(#|@|\+)([^"]+)">([^<]+)<\/a>/g;

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Assuming this is now part of the functionality.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Correct. I've now added tests to verify this.

* Will return the emoji's name within ':'.
* @param name The emoji's name.
*/
export const getFallbackForMissingEmoji = (name: string): string => (
`:${name}:`
);

interface PillItem {
id: string;
text: string;
Expand Down Expand Up @@ -74,7 +66,7 @@ class Substitutions {
body = url ? body.replace(file.permalink, url) : body;
}

body = emoji.emojify(body, getFallbackForMissingEmoji);
body = emoji.emojify(body);

return body;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/PgDatastoreTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describeFnl("PgDatastore", () => {
await ds.ensureSchema();
const { version } = (await ds.postgresDb.one(`SELECT version FROM schema`));
expect(version).to.equal(PgDatastore.LATEST_SCHEMA);
});
}).timeout(10_000);

doDatastoreTests(() => ds, async () => {
await ds.postgresDb.none("DELETE FROM rooms");
Expand Down
64 changes: 34 additions & 30 deletions tests/unit/substitutionsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,34 +297,38 @@ describe("Substitutions", () => {
});
});

// describe("slackTextToMatrixHTML", () => {
// it("should repeat a plain string", async () => {
// const res = await substitutions.slackTextToMatrixHTML("Hello World!");
// expect(res).to.equal("Hello World!");
// });
// it("should convert < and >", async () => {
// const res = await substitutions.slackTextToMatrixHTML("<html>Hello</html>");
// expect(res).to.equal("&lt;html&gt;Hello&lt;/html&gt;");
// });
// it("should convert a single new line to a <br />", async () => {
// const res = substitutions.slackTextToMatrixHTML("line 1\nline 2");
// expect(res).to.equal("line 1<br />line 2");
// });
// it("should convert two new lines to paragraphs", async () => {
// const res = substitutions.slackTextToMatrixHTML("line 1\n\nline 3");
// expect(res).to.equal("<p>line 1</p><p>line 3</p>");
// });
// it("should convert bold formatting", async () => {
// const res = substitutions.slackTextToMatrixHTML("This is *bold*!");
// expect(res).to.equal("This is <strong>bold</strong>!");
// });
// it("should convert italic formatting", async () => {
// const res = substitutions.slackTextToMatrixHTML("This is /italics/!");
// expect(res).to.equal("This is <em>italics</em>!");
// });
// it("should convert strikethrough formatting", async () => {
// const res = substitutions.slackTextToMatrixHTML("This is ~strikethrough~!");
// expect(res).to.equal("This is <del>strikethrough</del>");
// });
// });
describe("slackToMatrix", () => {
it("should repeat a plain string", async () => {
const res = await substitutions.slackToMatrix("Hello World!");
expect(res).to.equal("Hello World!");
});
// it("should convert < and >", async () => {
// const res = await substitutions.slackToMatrix("<html>Hello</html>");
// expect(res).to.equal("&lt;html&gt;Hello&lt;/html&gt;");
// });
// it("should convert a single new line to a <br />", async () => {
// const res = substitutions.slackToMatrix("line 1\nline 2");
// expect(res).to.equal("line 1<br />line 2");
// });
// it("should convert two new lines to paragraphs", async () => {
// const res = substitutions.slackToMatrix("line 1\n\nline 3");
// expect(res).to.equal("<p>line 1</p><p>line 3</p>");
// });
// it("should convert bold formatting", async () => {
// const res = substitutions.slackToMatrix("This is *bold*!");
// expect(res).to.equal("This is <strong>bold</strong>!");
// });
// it("should convert italic formatting", async () => {
// const res = substitutions.slackToMatrix("This is /italics/!");
// expect(res).to.equal("This is <em>italics</em>!");
// });
// it("should convert strikethrough formatting", async () => {
// const res = substitutions.slackToMatrix("This is ~strikethrough~!");
// expect(res).to.equal("This is <del>strikethrough</del>");
// });
it("should fallback to colon-codes for unknown emojis", async () => {
const res = substitutions.slackToMatrix(":+1: :drizzt:");
expect(res).to.equal("👍 :drizzt:");
});
});
});
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "@tsconfig/node16/tsconfig.json",
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"outDir": "./lib",
Expand Down
1 change: 0 additions & 1 deletion widget/src/ProvisioningApp.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { createContext, useEffect, useMemo, useState } from 'react';
import { WidgetApi, WidgetApiToWidgetAction } from 'matrix-widget-api';
import urlJoin from 'url-join';

import { ProvisioningClient, ProvisioningError } from './ProvisioningClient';
import * as Text from './components/text';
Expand Down