Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,14 @@ runs:
- name: Setup Node
uses: actions/setup-node@v6
with:
cache: 'yarn'
node-version: ${{ inputs.node-version }}
node-version-file: '.nvmrc'

- name: Set NODE_VERSION env
shell: bash
run: echo "NODE_VERSION=$(node --version)" >> $GITHUB_ENV

- name: Cache dependencies
uses: actions/cache@v5
with:
path: ./node_modules
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('./yarn.lock') }}

- name: Install dependencies
run: yarn install --frozen-lockfile
run: yarn install
shell: bash
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# https://github.com/stream-ci-bot
GITHUB_TOKEN: ${{ secrets.DOCUSAURUS_GH_TOKEN }}
NPM_CONFIG_PROVENANCE: 'true'
run: >
yarn semantic-release
${{ inputs.dry_run && '--dry-run' || '' }}
2 changes: 1 addition & 1 deletion .github/workflows/size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ jobs:
- uses: preactjs/compressed-size-action@v2
env:
NODE_OPTIONS: --max_old_space_size=4096
YARN_IGNORE_ENGINES: 'true' # Skip validation for node20 requirement
YARN_IGNORE_ENGINES: 'true'
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,13 @@ typings/
/.idea
.envrc

test/typescript/data.*
test/typescript/data.*

# Yarn Berry — keep releases/patches/plugins/sdks/versions, ignore caches
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.pnp.*
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/dist
/node_modules
/.vscode
/.yarn
/.claude
/coverage
CHANGELOG.md
test/typescript/data.ts
940 changes: 940 additions & 0 deletions .yarn/releases/yarn-4.14.1.cjs

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
yarnPath: .yarn/releases/yarn-4.14.1.cjs
nodeLinker: node-modules
enableTelemetry: false

# Hardening + supply-chain
nmMode: hardlinks-global
enableHardenedMode: true
enableScripts: false
enableGlobalCache: true
npmMinimalAgeGate: 3d
npmPublishProvenance: true
176 changes: 176 additions & 0 deletions CLAUDE.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ We welcome code changes that improve this library or fix a problem, please make

### Install dependencies

This repo uses Yarn 4 (Berry). The Yarn 4 binary is committed to `.yarn/releases/`; any globally installed Yarn launcher delegates to it via `yarnPath`. No Corepack setup needed.

```shell
$ yarn install --frozen-lockfile --ignore-engines
$ yarn install --immutable
```

### Run tests
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import importPlugin from 'eslint-plugin-import';

export default tseslint.config(
{
ignores: ['dist', 'src/@types', '*.{js,ts}'],
ignores: ['dist', 'coverage', '.yarn', '.claude', 'src/@types', '*.{js,ts}'],
},
{
name: 'default',
Expand Down
59 changes: 33 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
}
},
"browser": {
"https": false,
"crypto": false,
"zlib": false,
"https": false,
"jsonwebtoken": false,
"ws": false
"ws": false,
"zlib": false
},
"license": "SEE LICENSE IN LICENSE",
"keywords": [
Expand All @@ -51,40 +51,39 @@
],
"dependencies": {
"@types/jsonwebtoken": "^9.0.8",
"@types/ws": "^8.5.14",
"@types/ws": "^8.18.1",
"axios": "^1.15.1",
"base64-js": "^1.5.1",
"form-data": "^4.0.4",
"form-data": "^4.0.5",
"isomorphic-ws": "^5.0.0",
"jsonwebtoken": "^9.0.3",
"linkifyjs": "^4.3.2",
"ws": "^8.18.1"
},
"devDependencies": {
"@commitlint/cli": "^19.7.1",
"@commitlint/config-conventional": "^19.7.1",
"@eslint/js": "^9.21.0",
"@commitlint/cli": "^21.0.0",
"@commitlint/config-conventional": "^21.0.0",
"@eslint/js": "^9.39.4",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@types/base64-js": "^1.3.0",
"@types/node": "^22.15.21",
"@types/node": "^22.19.18",
"@types/sinon": "^10.0.6",
"@vitest/coverage-v8": "3.1.4",
"concurrently": "^9.1.2",
"conventional-changelog-conventionalcommits": "^8.0.0",
"@vitest/coverage-v8": "4.1.5",
"concurrently": "^9.2.1",
"conventional-changelog-conventionalcommits": "^9.3.1",
"dotenv": "^8.2.0",
"esbuild": "^0.25.4",
"eslint": "^9.27.0",
"eslint-plugin-import": "^2.31.0",
"globals": "^16.0.0",
"esbuild": "^0.28.0",
"eslint": "^9.39.4",
"eslint-plugin-import": "^2.32.0",
"globals": "^17.6.0",
"husky": "^9.1.7",
"lint-staged": "^15.2.2",
"prettier": "^3.5.3",
"semantic-release": "^25.0.2",
"lint-staged": "^17.0.4",
"prettier": "^3.8.3",
"semantic-release": "^25.0.3",
"sinon": "^12.0.1",
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1",
"vitest": "^3.1.4"
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.2",
"vitest": "^4.1.5"
},
"scripts": {
"build": "rm -rf dist && concurrently 'tsc' './scripts/bundle.mjs'",
Expand All @@ -97,18 +96,26 @@
"eslint": "eslint --max-warnings 0",
"eslint-fix": "yarn run eslint --fix",
"test": "yarn test-unit",
"testwatch": "NODE_ENV=test nodemon ./node_modules/.bin/mocha --timeout 20000 --require test-entry.js test/test.js",
"test-types": "yarn run-test-types && yarn run-types-gen",
"run-test-types": "node test/typescript/index.js",
"run-types-gen": "tsc --esModuleInterop true --noEmit true --strictNullChecks true --noImplicitAny true --strict true test/typescript/*.ts",
"test-unit": "vitest",
"test-coverage": "vitest run --coverage",
"fix-staged": "lint-staged --config .lintstagedrc.fix.json --concurrent 1",
"semantic-release": "semantic-release",
"prepare": "husky; yarn run build"
"postinstall": "husky",
"prepare": "yarn run build"
},
"engines": {
"node": ">=18"
},
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
"packageManager": "yarn@4.14.1",
"dependenciesMeta": {
"esbuild": {
"built": true
},
"husky": {
"built": true
}
}
}
4 changes: 2 additions & 2 deletions test/unit/MessageComposer/attachmentManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ const setup = ({
mockClient.appSettingsPromise = Promise.resolve(
appSettings ? { app: appSettings } : defaultAppSettings,
);
(mockClient.getAppSettings = vi
((mockClient.getAppSettings = vi
.fn()
.mockResolvedValue(appSettings ? { app: appSettings } : defaultAppSettings)),
(mockClient.notifications = { addError: vi.fn() });
(mockClient.notifications = { addError: vi.fn() }));

mockClient.user = { id: 'user-id', name: 'Test User' };

Expand Down
64 changes: 34 additions & 30 deletions test/unit/MessageComposer/pollComposer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,52 @@ vi.mock('../../../src/utils', () => ({
}));

vi.mock('../../../src/messageComposer/middleware/pollComposer', () => ({
PollComposerCompositionMiddlewareExecutor: vi.fn().mockImplementation(() => ({
execute: vi.fn().mockResolvedValue({
state: {
data: {
allow_answers: false,
allow_user_suggested_options: false,
description: '',
enforce_unique_vote: true,
id: 'test-id',
max_votes_allowed: 5,
name: 'Test Poll',
options: [{ text: 'Option 1' }, { text: 'Option 2' }],
user_id: 'user-id',
voting_visibility: VotingVisibility.public,
},
errors: {},
},
status: 'success',
}),
})),
PollComposerStateMiddlewareExecutor: vi.fn().mockImplementation(() => ({
execute: vi.fn().mockResolvedValue({
state: {
nextState: {
PollComposerCompositionMiddlewareExecutor: vi.fn().mockImplementation(function () {
return {
execute: vi.fn().mockResolvedValue({
state: {
data: {
allow_answers: false,
allow_user_suggested_options: false,
description: '',
enforce_unique_vote: true,
id: 'test-id',
max_votes_allowed: '',
max_votes_allowed: 5,
name: 'Test Poll',
options: [{ id: 'option-id', text: 'Option 1' }],
options: [{ text: 'Option 1' }, { text: 'Option 2' }],
user_id: 'user-id',
voting_visibility: VotingVisibility.public,
},
errors: {},
},
},
status: 'success',
}),
})),
status: 'success',
}),
};
}),
PollComposerStateMiddlewareExecutor: vi.fn().mockImplementation(function () {
return {
execute: vi.fn().mockResolvedValue({
state: {
nextState: {
data: {
allow_answers: false,
allow_user_suggested_options: false,
description: '',
enforce_unique_vote: true,
id: 'test-id',
max_votes_allowed: '',
name: 'Test Poll',
options: [{ id: 'option-id', text: 'Option 1' }],
user_id: 'user-id',
voting_visibility: VotingVisibility.public,
},
errors: {},
},
},
status: 'success',
}),
};
}),
VALID_MAX_VOTES_VALUE_REGEX: /^([2-9]|10)$/,
}));

Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "./dist/types",
"rootDir": "./src",

"lib": ["ES2020", "DOM", "ES2022.Error"],
"moduleResolution": "bundler",
Expand Down
5 changes: 5 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ export default defineConfig({
// not all errors have been handled so this is necessary (at least for the time being)
dangerouslyIgnoreUnhandledErrors: true,
include: ['./test/unit/**/*.test.[jt]s'],
// Vitest 4 no longer auto-reuses a fresh spy on each `vi.spyOn` call on the same
// target -- spies persist across tests and call counts accumulate. Restoring all
// mocks before each test brings back the vitest 3 / Jest convention these tests
// were written against.
restoreMocks: true,
},
});
Loading
Loading