Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
15 changes: 8 additions & 7 deletions packages/core/src/events/eventBase.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Pdu, PduForType } from '@hs/room';
import type { EventID } from '@hs/room';

export type EventBase = {
auth_events: string[];
prev_events: string[];
auth_events: EventID[];
prev_events: EventID[];
type:
| 'm.room.member'
| 'm.room.create'
Expand Down Expand Up @@ -32,7 +33,7 @@ export type EventBase = {
};

export type RedactedEvent = EventBase & {
redacts: string;
redacts: EventID;
type: 'm.room.redaction';
};

Expand All @@ -51,8 +52,8 @@ export const createEventBase = <T extends KeyEvent>(
props: {
roomId: string;
sender: string;
auth_events?: string[];
prev_events?: string[];
auth_events?: EventID[];
prev_events?: EventID[];
depth: number;
content: Events[T]['content'];
state_key?: string;
Expand Down Expand Up @@ -92,8 +93,8 @@ const _createEventBase = <
}: {
roomId: string;
sender: string;
auth_events?: string[];
prev_events?: string[];
auth_events?: EventID[];
prev_events?: EventID[];
depth: number;
type: string;
content?: TContent;
Expand Down
15 changes: 8 additions & 7 deletions packages/core/src/events/m.reaction.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { EventID } from '@hs/room';
import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand All @@ -7,7 +8,7 @@ declare module './eventBase' {
content: {
'm.relates_to': {
rel_type: 'm.annotation';
event_id: string;
event_id: EventID;
key: string;
};
};
Expand All @@ -19,9 +20,9 @@ declare module './eventBase' {
}

export type ReactionAuthEvents = {
'm.room.create': string | undefined;
'm.room.power_levels': string | undefined;
'm.room.member': string | undefined;
'm.room.create': EventID | undefined;
'm.room.power_levels': EventID | undefined;
'm.room.member': EventID | undefined;
};

export const isReactionEvent = (event: EventBase): event is ReactionEvent => {
Expand All @@ -33,7 +34,7 @@ export interface ReactionEvent extends EventBase {
content: {
'm.relates_to': {
rel_type: 'm.annotation';
event_id: string;
event_id: EventID;
key: string;
};
};
Expand Down Expand Up @@ -62,12 +63,12 @@ export const reactionEvent = ({
roomId: string;
sender: string;
auth_events: ReactionAuthEvents;
prev_events: string[];
prev_events: EventID[];
depth: number;
content: {
'm.relates_to': {
rel_type: 'm.annotation';
event_id: string;
event_id: EventID;
key: string;
};
};
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/events/m.room.guest_access.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';
import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand All @@ -24,8 +25,8 @@ export const roomGuestAccessEvent = ({
}: {
roomId: string;
sender: string;
auth_events: string[];
prev_events: string[];
auth_events: EventID[];
prev_events: EventID[];
depth: number;
ts?: number;
}) => {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/events/m.room.history_visibility.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Wrong import path for EventID; use package alias.

Using 'packages/room/dist' will break outside the monorepo build. Import from '@hs/room' as a type.

Apply:

-import { EventID } from 'packages/room/dist';
+import type { EventID } from '@hs/room';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { EventID } from 'packages/room/dist';
import type { EventID } from '@hs/room';
🤖 Prompt for AI Agents
In packages/core/src/events/m.room.history_visibility.ts around line 1, the file
currently imports EventID from the local path 'packages/room/dist' which will
break consumers outside the monorepo; change the import to use the package alias
and import EventID as a type from '@hs/room' (e.g. replace the existing import
with a type-only import from '@hs/room') so builds and external consumers
resolve the symbol correctly.

import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand Down Expand Up @@ -26,8 +27,8 @@ export const roomHistoryVisibilityEvent = ({
}: {
roomId: string;
sender: string;
auth_events: string[];
prev_events: string[];
auth_events: EventID[];
prev_events: EventID[];
depth: number;
ts?: number;
}) => {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/events/m.room.join_rules.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

Fix EventID import path; prefer type‑only import.

Use the same source as the rest of the repo and avoid pulling runtime code for a type.

Apply:

-import { EventID } from 'packages/room/dist';
+import type { EventID } from '@hs/room';

The EventID[] parameter changes on Lines 37–38 look correct and align with the project‑wide migration.

Also applies to: 37-38


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== show target file (first 200 lines) ==="
if [ -f packages/core/src/events/m.room.join_rules.ts ]; then
  sed -n '1,240p' packages/core/src/events/m.room.join_rules.ts || true
else
  echo "MISSING: packages/core/src/events/m.room.join_rules.ts"
fi

echo
echo "=== show lines 1-120 with numbers for quick reference ==="
if [ -f packages/core/src/events/m.room.join_rules.ts ]; then
  nl -ba -w3 -s': ' packages/core/src/events/m.room.join_rules.ts | sed -n '1,120p' || true
fi

echo
echo "=== search repo for EventID symbol usages (context) ==="
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden -S '\bEventID\b' || true
else
  grep -RIn --line-number '\bEventID\b' . || true
fi

echo
echo "=== search for imports that pull from packages/room/dist ==="
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden -S "packages/room/dist" || true
else
  grep -RIn --line-number "packages/room/dist" . || true
fi

echo
echo "=== search for @hs/room occurrences ==="
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden -S "@hs/room" || true
else
  grep -RIn --line-number "@hs/room" . || true
fi

echo
echo "=== packages/room package.json (if present) ==="
if [ -f packages/room/package.json ]; then
  sed -n '1,240p' packages/room/package.json || true
else
  echo "MISSING: packages/room/package.json"
fi

echo
echo "=== list top files under packages/room ==="
if [ -d packages/room ]; then
  find packages/room -maxdepth 3 -type f | sed -n '1,200p' || true
else
  echo "MISSING: packages/room directory"
fi

echo
echo "=== show root package.json and tsconfig.json (first 200 lines) ==="
if [ -f package.json ]; then
  sed -n '1,240p' package.json || true
else
  echo "MISSING: package.json"
fi

echo
if [ -f tsconfig.json ]; then
  sed -n '1,240p' tsconfig.json || true
else
  echo "MISSING: tsconfig.json"
fi

Length of output: 29169


Fix EventID import — use a type-only import from @hs/room

Apply:

-import { EventID } from 'packages/room/dist';
+import type { EventID } from '@hs/room';

auth_events / prev_events (lines 37–38) are already correctly typed as EventID[].

Also update other occurrences that import from 'packages/room/dist' (e.g. packages/core/src/utils/generateId.ts, packages/core/src/events/*.ts, packages/federation-sdk/src/services/missing-event.service.ts).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { EventID } from 'packages/room/dist';
import type { EventID } from '@hs/room';

import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand Down Expand Up @@ -33,8 +34,8 @@ export const roomJoinRulesEvent = ({
}: {
roomId: string;
sender: string;
auth_events: string[];
prev_events: string[];
auth_events: EventID[];
prev_events: EventID[];
depth: number;
ts?: number;
}) => {
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/events/m.room.member.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix import path and make it type‑only.

Use the package alias consistently and avoid a runtime import.

-import { EventID } from 'packages/room/dist';
+import type { EventID } from '@hs/room';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { EventID } from 'packages/room/dist';
import type { EventID } from '@hs/room';
🤖 Prompt for AI Agents
In packages/core/src/events/m.room.member.ts around line 1, replace the runtime
import from 'packages/room/dist' with a type‑only import using the package alias
(e.g. import type { EventID } from 'room';) so the value is not imported at
runtime; ensure EventID is used only as a type or add a type-only import where
referenced.

import { createEventBase } from './eventBase';
import type { Membership, RoomMemberEvent } from './isRoomMemberEvent';
import { createEventWithId } from './utils/createSignedEvent';
Expand All @@ -18,12 +19,12 @@ declare module './eventBase' {
}

export type AuthEvents = {
'm.room.create': string;
'm.room.power_levels'?: string;
'm.room.join_rules'?: string;
'm.room.history_visibility'?: string;
'm.room.create': EventID;
'm.room.power_levels'?: EventID;
'm.room.join_rules'?: EventID;
'm.room.history_visibility'?: EventID;
} & {
[K in `m.room.member:${string}`]?: string;
[K in `m.room.member:${string}`]?: EventID;
};

const isTruthy = <T>(
Expand All @@ -50,7 +51,7 @@ export const roomMemberEvent = ({
sender: string;
state_key: string;
auth_events: AuthEvents;
prev_events: string[];
prev_events: EventID[];
depth: number;
unsigned?: RoomMemberEvent['unsigned'];
content?: Record<string, any>;
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/events/m.room.message.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { EventID } from '@hs/room';
import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand Down Expand Up @@ -74,14 +75,14 @@ declare module './eventBase' {

export type MessageRelation = {
rel_type: RelationType;
event_id: string;
event_id: EventID;
} & (RelationTypeReplace | Record<string, never>);

export type RelationType = 'm.replace' | 'm.annotation';

export type RelationTypeReplace = {
rel_type: 'm.replace';
event_id: string;
event_id: EventID;
'm.new_content'?: {
body: string;
msgtype: MessageType;
Expand All @@ -91,9 +92,9 @@ export type RelationTypeReplace = {
};

export type MessageAuthEvents = {
'm.room.create': string;
'm.room.power_levels': string;
'm.room.member': string;
'm.room.create': EventID;
'm.room.power_levels': EventID;
'm.room.member': EventID;
};

export const isRoomMessageEvent = (
Expand Down Expand Up @@ -137,7 +138,7 @@ export const roomMessageEvent = ({
roomId: string;
sender: string;
auth_events: MessageAuthEvents;
prev_events: string[];
prev_events: EventID[];
depth: number;
unsigned?: RoomMessageEvent['unsigned'];
content: (
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/events/m.room.name.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Use a type‑only import for EventID to avoid runtime dependency on 'packages/room/dist'.

Prevents accidental runtime import under verbatimModuleSyntax/ESM.

-import { EventID } from 'packages/room/dist';
+import type { EventID } from 'packages/room/dist';

Please confirm tsconfig has either importsNotUsedAsValues: "remove" or that you’re using type‑only imports repo‑wide to avoid runtime loads of types. Run:


🏁 Script executed:

#!/bin/bash
fd -a 'tsconfig*.json' | xargs -I{} jq -r '.compilerOptions.importsNotUsedAsValues?, .compilerOptions.verbatimModuleSyntax?' {} 2>/dev/null

Length of output: 64


🏁 Script executed:

#!/bin/bash
set -euo pipefail
printf "PWD: %s\n\n" "$(pwd)"

echo "=== tsconfig files ==="
fd -HI -a 'tsconfig*.json' 2>/dev/null || true

for f in $(fd -HI -a 'tsconfig*.json' 2>/dev/null || true); do
  echo -e "\n--- $f ---"
  # print the two properties if present, otherwise indicate MISSING
  jq -r 'if .compilerOptions then
    "importsNotUsedAsValues: " + (.compilerOptions.importsNotUsedAsValues // "MISSING") + "\nverbatimModuleSyntax: " + ( (.compilerOptions.verbatimModuleSyntax // "MISSING") | tostring )
  else
    "no compilerOptions"
  end' "$f" 2>/dev/null || { echo "jq failed; printing first 200 chars:"; sed -n '1,40p' "$f"; }
done

echo -e "\n=== packages/core/src/events/m.room.name.ts ==="
if [ -f packages/core/src/events/m.room.name.ts ]; then
  sed -n '1,200p' packages/core/src/events/m.room.name.ts
else
  echo "file not found at that exact path; searching for matching files..."
  fd -HI 'm.room.name.ts' || true
fi

echo -e "\n=== Search for EventID import patterns ==="
rg -n --hidden --no-ignore --glob '!node_modules' "import\s+type\s*\{[^}]*\bEventID\b[^}]*\}" -S || true
rg -n --hidden --no-ignore --glob '!node_modules' "import\s*\{[^}]*\bEventID\b[^}]*\}" -S || true

echo -e "\n=== Search for imports from packages/room/dist ==="
rg -n --hidden --no-ignore --glob '!node_modules' "from\s+['\"]packages/room/dist['\"]" -S || true

echo -e "\n=== package.json typescript version (if present) ==="
if [ -f package.json ]; then
  jq -r '.devDependencies.typescript // .dependencies.typescript // "missing"' package.json 2>/dev/null || true
else
  echo "package.json not found at repo root"
fi

Length of output: 7223


Use a type-only import for EventID (avoid runtime dependency on 'packages/room/dist')

packages/core/src/events/m.room.name.ts currently uses a value import and no repo tsconfig sets importsNotUsedAsValues or verbatimModuleSyntax, so this will be emitted at runtime. Replace with a type-only import or set importsNotUsedAsValues: "remove" in the relevant tsconfig.

-import { EventID } from 'packages/room/dist';
+import type { EventID } from 'packages/room/dist';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { EventID } from 'packages/room/dist';
import type { EventID } from 'packages/room/dist';
🤖 Prompt for AI Agents
In packages/core/src/events/m.room.name.ts around line 1, the current import
"import { EventID } from 'packages/room/dist';" is a value import causing a
runtime dependency; change it to a type-only import by replacing it with "import
type { EventID } from 'packages/room/dist';" so TypeScript emits no runtime
require, or alternatively set the relevant tsconfig to include
"importsNotUsedAsValues": "remove" (or enable "verbatimModuleSyntax") in the
project that compiles this file.

import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand All @@ -16,9 +17,9 @@ declare module './eventBase' {
}

export type RoomNameAuthEvents = {
'm.room.create': string;
'm.room.power_levels': string;
'm.room.member': string;
'm.room.create': EventID;
'm.room.power_levels': EventID;
'm.room.member': EventID;
};

export const isRoomNameEvent = (event: EventBase): event is RoomNameEvent => {
Expand Down Expand Up @@ -52,7 +53,7 @@ export const roomNameEvent = ({
roomId: string;
sender: string;
auth_events: RoomNameAuthEvents;
prev_events: string[];
prev_events: EventID[];
depth: number;
content: {
name: string;
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/events/m.room.power_levels.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';
import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand Down Expand Up @@ -53,11 +54,11 @@ export const roomPowerLevelsEvent = ({
roomId: string;
members: [sender: string, ...member: string[]];
auth_events: {
'm.room.create': string;
'm.room.power_levels': string;
'm.room.member': string; // TODO: Based on the tests, this is optional, based on the code, this is required check this
'm.room.create': EventID;
'm.room.power_levels': EventID;
'm.room.member': EventID; // TODO: Based on the tests, this is optional, based on the code, this is required check this
};
prev_events: string[];
prev_events: EventID[];
depth: number;
content?: RoomPowerLevelsEvent['content'];
ts?: number;
Expand All @@ -70,7 +71,7 @@ export const roomPowerLevelsEvent = ({
auth_events['m.room.create'],
auth_events['m.room.power_levels'],
auth_events['m.room.member'],
].filter(Boolean) as string[],
].filter(Boolean) as EventID[],
prev_events,
depth,
ts,
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/events/m.room.redaction.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';
import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand All @@ -8,9 +9,9 @@ declare module './eventBase' {
}

export type RedactionAuthEvents = {
'm.room.create': string | undefined;
'm.room.power_levels': string | undefined;
'm.room.member'?: string | undefined;
'm.room.create': EventID | undefined;
'm.room.power_levels': EventID | undefined;
'm.room.member'?: EventID | undefined;
};

export const isRedactionEvent = (event: EventBase): event is RedactionEvent => {
Expand All @@ -24,7 +25,7 @@ export interface RedactionEvent extends EventBase {
unsigned: {
age_ts: number;
};
redacts: string;
redacts: EventID;
}

const isTruthy = <T>(
Expand All @@ -47,10 +48,10 @@ export const redactionEvent = ({
roomId: string;
sender: string;
auth_events: RedactionAuthEvents;
prev_events: string[];
prev_events: EventID[];
depth: number;
content: {
redacts: string;
redacts: EventID;
reason?: string;
};
origin?: string;
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/events/m.room.tombstone.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventID } from 'packages/room/dist';
import { type EventBase, createEventBase } from './eventBase';
import { createEventWithId } from './utils/createSignedEvent';

Expand All @@ -20,9 +21,9 @@ declare module './eventBase' {
}

export type TombstoneAuthEvents = {
'm.room.create': string;
'm.room.power_levels': string;
'm.room.member': string;
'm.room.create': EventID | undefined;
'm.room.power_levels': EventID | undefined;
'm.room.member': EventID | undefined;
};

type RoomTombstoneEventProps = {
Expand All @@ -31,7 +32,7 @@ type RoomTombstoneEventProps = {
body: string;
replacementRoom?: string;
auth_events: TombstoneAuthEvents;
prev_events: string[];
prev_events: EventID[];
depth: number;
ts?: number;
origin?: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/models/event.model.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Pdu, PduForType } from '@hs/room';
import { EventID, Pdu, PduForType } from '@hs/room';
import type { EventBase as CoreEventBase } from '../events/eventBase';

// TODO: use room package

interface PersistentEventBase<E = Pdu> {
_id: string;
_id: EventID;
event: E;

origin: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Pdu } from '@hs/room';
import type { EventID } from '@hs/room';

export enum EncryptionValidAlgorithm {
ed25519 = 'ed25519',
}

export type SignedEvent<T extends Pdu> = T & {
event_id: string;
event_id: EventID;
hashes: {
sha256: string;
};
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/utils/generateId.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import crypto from 'node:crypto';
import { EventID } from 'packages/room/dist';
import { toUnpaddedBase64 } from './binaryData';
import { pruneEventDict } from './pruneEventDict';
import { encodeCanonicalJson } from './signJson';

export function generateId<T extends object>(content: T): string {
export function generateId<T extends object>(content: T): EventID {
// remove the fields that are not part of the hash
const { unsigned, signatures, ...toHash } = pruneEventDict(content as any);

return `\$${toUnpaddedBase64(
crypto.createHash('sha256').update(encodeCanonicalJson(toHash)).digest(),
{ urlSafe: true },
)}`;
)}` as EventID;
}
Loading