matrix-nodejs-homeserver 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +29 -7
  2. package/dist/api/account.js +385 -351
  3. package/dist/api/admin.js +76 -60
  4. package/dist/api/appservice.js +37 -25
  5. package/dist/api/backup.js +73 -62
  6. package/dist/api/federation.js +172 -138
  7. package/dist/api/filters.js +4 -3
  8. package/dist/api/legacy.js +91 -78
  9. package/dist/api/media.js +70 -54
  10. package/dist/api/misc.js +46 -37
  11. package/dist/api/preview.js +4 -3
  12. package/dist/api/profile.js +108 -97
  13. package/dist/api/push.js +114 -99
  14. package/dist/api/relationships.js +64 -58
  15. package/dist/api/rooms.js +703 -580
  16. package/dist/api/rtc.d.ts +0 -1
  17. package/dist/api/rtc.js +48 -34
  18. package/dist/api/search.js +133 -127
  19. package/dist/api/slidingsync.js +41 -31
  20. package/dist/api/spaces.js +82 -77
  21. package/dist/api/sync.js +59 -50
  22. package/dist/api/threadsubs.js +72 -61
  23. package/dist/api/threepid.js +99 -66
  24. package/dist/api/uia.js +17 -16
  25. package/dist/api/user.js +221 -178
  26. package/dist/core/admin.d.ts +0 -1
  27. package/dist/core/admin.js +6 -5
  28. package/dist/core/adminroom.js +9 -8
  29. package/dist/core/appservices.d.ts +2 -1
  30. package/dist/core/appservices.js +5 -4
  31. package/dist/core/audit.d.ts +0 -1
  32. package/dist/core/authrules.js +26 -25
  33. package/dist/core/delayed.js +2 -1
  34. package/dist/core/events.js +11 -10
  35. package/dist/core/invitefilter.js +2 -1
  36. package/dist/core/keys.js +2 -1
  37. package/dist/core/m.d.ts +209 -0
  38. package/dist/core/m.js +182 -0
  39. package/dist/core/partialstate.js +2 -1
  40. package/dist/core/policy.js +4 -3
  41. package/dist/core/push.d.ts +0 -1
  42. package/dist/core/push.js +12 -11
  43. package/dist/core/pushrules.js +36 -35
  44. package/dist/core/rooms.js +76 -74
  45. package/dist/core/stateres.js +7 -6
  46. package/dist/federation/client.js +2 -1
  47. package/dist/federation/index.d.ts +1 -1
  48. package/dist/federation/index.js +30 -29
  49. package/dist/homeserver.d.ts +2 -1
  50. package/dist/homeserver.js +1 -0
  51. package/dist/http/handler.js +2 -23
  52. package/dist/http/input.js +2 -2
  53. package/dist/http/procedure.js +25 -0
  54. package/dist/http/router.d.ts +9 -26
  55. package/dist/http/router.js +10 -30
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.js +2 -1
  58. package/dist/vendor/zod/LICENSE +21 -0
  59. package/dist/vendor/zod/v4/classic/errors.js +54 -0
  60. package/dist/vendor/zod/v4/classic/parse.js +17 -0
  61. package/dist/vendor/zod/v4/classic/schemas.js +865 -0
  62. package/dist/vendor/zod/v4/core/api.js +512 -0
  63. package/dist/vendor/zod/v4/core/checks.js +300 -0
  64. package/dist/vendor/zod/v4/core/core.js +109 -0
  65. package/dist/vendor/zod/v4/core/doc.js +35 -0
  66. package/dist/vendor/zod/v4/core/errors.js +118 -0
  67. package/dist/vendor/zod/v4/core/json-schema-processors.js +428 -0
  68. package/dist/vendor/zod/v4/core/memoizer.js +255 -0
  69. package/dist/vendor/zod/v4/core/parse.js +206 -0
  70. package/dist/vendor/zod/v4/core/regexes.js +73 -0
  71. package/dist/vendor/zod/v4/core/registries.js +48 -0
  72. package/dist/vendor/zod/v4/core/schemas.js +1378 -0
  73. package/dist/vendor/zod/v4/core/to-json-schema.js +448 -0
  74. package/dist/vendor/zod/v4/core/util.js +537 -0
  75. package/dist/vendor/zod/v4/core/versions.js +8 -0
  76. package/dist/vendor/zod/v4/locales/en.js +110 -0
  77. package/package.json +3 -5
  78. package/dist/core/pushrules.d.ts +0 -1
@@ -1,5 +1,6 @@
1
1
  import { isObject } from "./json.js";
2
2
  import { publicKeyFromBase64, verifyJsonSignature } from "./crypto.js";
3
+ import { M } from "./m.js";
3
4
  import { roomVersionFeatures, stateKey, versionNum } from "./events.js";
4
5
  import { errors } from "./errors.js";
5
6
  import { isValidUserId } from "./ids.js";
@@ -20,10 +21,10 @@ function getState(state, type, key = "") {
20
21
  return state.get(stateKey(type, key));
21
22
  }
22
23
  function membershipOf(state, userId) {
23
- return getState(state, "m.room.member", userId)?.content?.membership ?? "leave";
24
+ return getState(state, M.ROOM.MEMBER, userId)?.content?.membership ?? "leave";
24
25
  }
25
26
  function roomCreator(state, roomVersion) {
26
- const create = getState(state, "m.room.create");
27
+ const create = getState(state, M.ROOM.CREATE);
27
28
  if (!create) return void 0;
28
29
  return roomVersionFeatures(roomVersion).v11 ? create.sender : create.content.creator ?? create.sender;
29
30
  }
@@ -35,13 +36,13 @@ const toInt = (v, fallback) => {
35
36
  /** v12+: the create event's sender plus `additional_creators`. Empty for older versions. */
36
37
  function roomCreators(state, roomVersion) {
37
38
  if (!roomVersionFeatures(roomVersion).v12) return /* @__PURE__ */ new Set();
38
- const create = getState(state, "m.room.create");
39
+ const create = getState(state, M.ROOM.CREATE);
39
40
  if (!create) return /* @__PURE__ */ new Set();
40
41
  const extra = Array.isArray(create.content?.additional_creators) ? create.content.additional_creators : [];
41
42
  return /* @__PURE__ */ new Set([create.sender, ...extra.filter((u) => typeof u === "string")]);
42
43
  }
43
44
  function powerLevels(state, roomVersion) {
44
- const pl = getState(state, "m.room.power_levels")?.content;
45
+ const pl = getState(state, M.ROOM.POWER_LEVELS)?.content;
45
46
  const creators = roomCreators(state, roomVersion);
46
47
  if (!pl) {
47
48
  const creator = roomCreator(state, roomVersion);
@@ -90,21 +91,21 @@ const sameDomain = (a, b) => a.slice(a.indexOf(":") + 1) === b.slice(b.indexOf("
90
91
  const domainOf = (id) => id.slice(id.indexOf(":") + 1);
91
92
  /** The (type, state_key) pairs an event's auth_events may reference (spec "auth events selection"). */
92
93
  function authEventKeys(event, roomVersion) {
93
- if (event.type === "m.room.create") return [];
94
- const keys = [stateKey("m.room.power_levels", ""), stateKey("m.room.member", event.sender)];
95
- if (!roomVersionFeatures(roomVersion).v12) keys.unshift(stateKey("m.room.create", ""));
96
- if (event.type === "m.room.member" && typeof event.state_key === "string") {
97
- keys.push(stateKey("m.room.member", event.state_key));
94
+ if (event.type === M.ROOM.CREATE) return [];
95
+ const keys = [stateKey(M.ROOM.POWER_LEVELS, ""), stateKey(M.ROOM.MEMBER, event.sender)];
96
+ if (!roomVersionFeatures(roomVersion).v12) keys.unshift(stateKey(M.ROOM.CREATE, ""));
97
+ if (event.type === M.ROOM.MEMBER && typeof event.state_key === "string") {
98
+ keys.push(stateKey(M.ROOM.MEMBER, event.state_key));
98
99
  const membership = event.content?.membership;
99
100
  if ([
100
101
  "join",
101
102
  "invite",
102
103
  "knock"
103
- ].includes(membership)) keys.push(stateKey("m.room.join_rules", ""));
104
+ ].includes(membership)) keys.push(stateKey(M.ROOM.JOIN_RULES, ""));
104
105
  const token = event.content?.third_party_invite?.signed?.token;
105
- if (membership === "invite" && typeof token === "string") keys.push(stateKey("m.room.third_party_invite", token));
106
+ if (membership === "invite" && typeof token === "string") keys.push(stateKey(M.ROOM.THIRD_PARTY_INVITE, token));
106
107
  const via = event.content?.join_authorised_via_users_server;
107
- if (membership === "join" && typeof via === "string" && roomVersionFeatures(roomVersion).restricted) keys.push(stateKey("m.room.member", via));
108
+ if (membership === "join" && typeof via === "string" && roomVersionFeatures(roomVersion).restricted) keys.push(stateKey(M.ROOM.MEMBER, via));
108
109
  }
109
110
  return [...new Set(keys)];
110
111
  }
@@ -121,10 +122,10 @@ function authStateFromAuthEvents(event, authEvents, roomVersion, createEvent) {
121
122
  const key = stateKey(ev.type, ev.state_key);
122
123
  if (state.has(key)) throw errors.forbidden("Duplicate auth event");
123
124
  if (!allowed.has(key)) throw errors.forbidden(`Unexpected auth event ${ev.type}`);
124
- if (roomVersionFeatures(roomVersion).v12 && ev.type === "m.room.create") throw errors.forbidden("Create event must not be in auth_events");
125
+ if (roomVersionFeatures(roomVersion).v12 && ev.type === M.ROOM.CREATE) throw errors.forbidden("Create event must not be in auth_events");
125
126
  state.set(key, ev);
126
127
  }
127
- if (createEvent) state.set(stateKey("m.room.create", ""), createEvent);
128
+ if (createEvent) state.set(stateKey(M.ROOM.CREATE, ""), createEvent);
128
129
  return state;
129
130
  }
130
131
  /**
@@ -137,7 +138,7 @@ function checkAuth(event, state, roomVersion, opts = {}) {
137
138
  const deny = (msg) => {
138
139
  throw errors.forbidden(msg);
139
140
  };
140
- if (event.type === "m.room.create") {
141
+ if (event.type === M.ROOM.CREATE) {
141
142
  if (state.size > 0 || Array.isArray(event.prev_events) && event.prev_events.length > 0) deny("Create event must be the first event");
142
143
  if (!features.v12 && event.room_id && !sameDomain(event.room_id, event.sender)) deny("Room ID domain must match the creator");
143
144
  const rv = event.content?.room_version;
@@ -149,10 +150,10 @@ function checkAuth(event, state, roomVersion, opts = {}) {
149
150
  }
150
151
  return;
151
152
  }
152
- const create = getState(state, "m.room.create");
153
+ const create = getState(state, M.ROOM.CREATE);
153
154
  if (!create) deny("No create event in room");
154
- if (create.content?.["m.federate"] === false && !sameDomain(event.sender, create.sender)) deny("Room is not federated");
155
- if (n <= 5 && event.type === "m.room.aliases") {
155
+ if (create.content?.[M.FEDERATE] === false && !sameDomain(event.sender, create.sender)) deny("Room is not federated");
156
+ if (n <= 5 && event.type === M.ROOM.ALIASES) {
156
157
  if (event.state_key === void 0) deny("Aliases event lacks a state key");
157
158
  if (event.state_key !== domainOf(event.sender)) deny("Aliases state key must be the sender's domain");
158
159
  return;
@@ -160,12 +161,12 @@ function checkAuth(event, state, roomVersion, opts = {}) {
160
161
  const pl = powerLevels(state, roomVersion);
161
162
  const senderMembership = membershipOf(state, event.sender);
162
163
  const senderLevel = userLevel(pl, event.sender);
163
- if (event.type === "m.room.member") {
164
+ if (event.type === M.ROOM.MEMBER) {
164
165
  const target = event.state_key;
165
166
  const membership = event.content?.membership;
166
167
  if (typeof target !== "string" || typeof membership !== "string") deny("Member event lacks state_key or membership");
167
168
  const targetMembership = membershipOf(state, target);
168
- const joinRule = getState(state, "m.room.join_rules")?.content?.join_rule ?? "invite";
169
+ const joinRule = getState(state, M.ROOM.JOIN_RULES)?.content?.join_rule ?? "invite";
169
170
  const via = event.content?.join_authorised_via_users_server;
170
171
  switch (membership) {
171
172
  case "join": {
@@ -226,7 +227,7 @@ function checkAuth(event, state, roomVersion, opts = {}) {
226
227
  return;
227
228
  }
228
229
  if (senderMembership !== "join") deny("You are not joined to this room");
229
- if (event.type === "m.room.third_party_invite") {
230
+ if (event.type === M.ROOM.THIRD_PARTY_INVITE) {
230
231
  if (senderLevel >= pl.invite) return;
231
232
  deny("Insufficient power level to invite");
232
233
  }
@@ -238,16 +239,16 @@ function checkAuth(event, state, roomVersion, opts = {}) {
238
239
  if (!owner) deny("Malformed user-owned state key");
239
240
  if (owner !== event.sender && senderLevel <= userLevel(pl, owner)) deny("This state key belongs to another user");
240
241
  }
241
- if (event.type === "m.room.power_levels" && isState) {
242
+ if (event.type === M.ROOM.POWER_LEVELS && isState) {
242
243
  if (isObject(event.content?.users)) for (const u of Object.keys(event.content.users)) {
243
244
  if (!isValidUserId(u)) deny("Power level users must be valid user IDs");
244
245
  if (pl.creators.has(u)) deny("Room creators cannot be given a power level");
245
246
  }
246
- if (getState(state, "m.room.power_levels")) checkPowerLevelChange(event, pl, senderLevel, features.integerPowerLevels, n >= 6, deny);
247
+ if (getState(state, M.ROOM.POWER_LEVELS)) checkPowerLevelChange(event, pl, senderLevel, features.integerPowerLevels, n >= 6, deny);
247
248
  else checkPowerLevelShape(event, features.integerPowerLevels, deny);
248
249
  return;
249
250
  }
250
- if (n <= 2 && event.type === "m.room.redaction") {
251
+ if (n <= 2 && event.type === M.ROOM.REDACTION) {
251
252
  if (senderLevel >= pl.redact) return;
252
253
  const redacts = event.redacts;
253
254
  if (typeof redacts === "string" && redacts.includes(":") && domainOf(redacts) === domainOf(event.sender)) return;
@@ -258,7 +259,7 @@ function checkThirdPartyInvite(event, state) {
258
259
  const signed = event.content?.third_party_invite?.signed;
259
260
  if (!isObject(signed) || typeof signed.mxid !== "string" || typeof signed.token !== "string") return false;
260
261
  if (signed.mxid !== event.state_key) return false;
261
- const invite = getState(state, "m.room.third_party_invite", signed.token);
262
+ const invite = getState(state, M.ROOM.THIRD_PARTY_INVITE, signed.token);
262
263
  if (!invite || invite.sender !== event.sender) return false;
263
264
  const keys = [];
264
265
  if (typeof invite.content?.public_key === "string") keys.push(invite.content.public_key);
@@ -1,4 +1,5 @@
1
1
  import { randomString } from "./crypto.js";
2
+ import { UNSTABLE } from "./m.js";
2
3
  import { MatrixError, errors } from "./errors.js";
3
4
  //#region src/core/delayed.ts
4
5
  /**
@@ -27,7 +28,7 @@ var DelayedEventService = class {
27
28
  }
28
29
  async schedule(opts) {
29
30
  if (!Number.isInteger(opts.delayMs) || opts.delayMs < 0) throw errors.invalidParam("Invalid delay");
30
- if (opts.delayMs > this.maxDelayMs) throw new MatrixError(400, "M_MAX_DELAY_EXCEEDED", "Delay is too long", { "org.matrix.msc4140.max_delay": this.maxDelayMs });
31
+ if (opts.delayMs > this.maxDelayMs) throw new MatrixError(400, "M_MAX_DELAY_EXCEEDED", "Delay is too long", { [UNSTABLE.ORG.MATRIX.MSC4140.MAX_DELAY]: this.maxDelayMs });
31
32
  const txnKey = opts.txnId ? `${opts.userId}|${opts.deviceId}|${opts.roomId}|${opts.txnId}` : null;
32
33
  if (txnKey) {
33
34
  const existing = await this.hs.db.findOne("delayed_events", [{
@@ -1,5 +1,6 @@
1
1
  import { canonicalJson, isObject } from "./json.js";
2
2
  import { randomString, sha256, signJson, unpaddedBase64, urlSafeBase64 } from "./crypto.js";
3
+ import { M } from "./m.js";
3
4
  //#region src/core/events.ts
4
5
  const STABLE_ROOM_VERSIONS = [
5
6
  "1",
@@ -76,7 +77,7 @@ function redact(event, roomVersion) {
76
77
  const keep = n >= 11 ? KEEP_TOP_LEVEL : [...KEEP_TOP_LEVEL, ...KEEP_TOP_LEVEL_LEGACY];
77
78
  const out = {};
78
79
  for (const k of keep) if (k in event) out[k] = event[k];
79
- const keepRelation = roomVersion.startsWith("org.matrix.msc3389.") && isObject(event.content?.["m.relates_to"]) ? event.content["m.relates_to"] : void 0;
80
+ const keepRelation = roomVersion.startsWith("org.matrix.msc3389.") && isObject(event.content?.[M.RELATES_TO]) ? event.content[M.RELATES_TO] : void 0;
80
81
  const content = isObject(event.content) ? event.content : {};
81
82
  const pick = (...keys) => {
82
83
  const c = {};
@@ -84,28 +85,28 @@ function redact(event, roomVersion) {
84
85
  return c;
85
86
  };
86
87
  switch (event.type) {
87
- case "m.room.member": {
88
+ case M.ROOM.MEMBER: {
88
89
  const c = pick("membership", ...n >= 9 ? ["join_authorised_via_users_server"] : []);
89
90
  if (n >= 11 && isObject(content.third_party_invite) && "signed" in content.third_party_invite) c.third_party_invite = { signed: content.third_party_invite.signed };
90
91
  out.content = c;
91
92
  break;
92
93
  }
93
- case "m.room.create":
94
+ case M.ROOM.CREATE:
94
95
  out.content = n >= 11 ? { ...content } : pick("creator");
95
96
  break;
96
- case "m.room.join_rules":
97
+ case M.ROOM.JOIN_RULES:
97
98
  out.content = pick("join_rule", ...n >= 8 ? ["allow"] : []);
98
99
  break;
99
- case "m.room.power_levels":
100
+ case M.ROOM.POWER_LEVELS:
100
101
  out.content = pick("ban", "events", "events_default", "kick", "redact", "state_default", "users", "users_default", ...n >= 11 ? ["invite"] : []);
101
102
  break;
102
- case "m.room.history_visibility":
103
+ case M.ROOM.HISTORY_VISIBILITY:
103
104
  out.content = pick("history_visibility");
104
105
  break;
105
- case "m.room.aliases":
106
+ case M.ROOM.ALIASES:
106
107
  out.content = n <= 5 ? pick("aliases") : {};
107
108
  break;
108
- case "m.room.redaction":
109
+ case M.ROOM.REDACTION:
109
110
  out.content = n >= 11 ? pick("redacts") : {};
110
111
  break;
111
112
  default: out.content = {};
@@ -116,7 +117,7 @@ function redact(event, roomVersion) {
116
117
  if ("event_id" in keepRelation) rel.event_id = keepRelation.event_id;
117
118
  out.content = {
118
119
  ...out.content,
119
- "m.relates_to": rel
120
+ [M.RELATES_TO]: rel
120
121
  };
121
122
  }
122
123
  return out;
@@ -161,7 +162,7 @@ function toClientEvent(pdu, opts = {}) {
161
162
  if (opts.includeRoomId !== false) ev.room_id = pdu.room_id;
162
163
  if (pdu.state_key !== void 0) ev.state_key = pdu.state_key;
163
164
  if (pdu.redacts !== void 0) ev.redacts = pdu.redacts;
164
- else if (pdu.type === "m.room.redaction" && typeof pdu.content?.redacts === "string") ev.redacts = pdu.content.redacts;
165
+ else if (pdu.type === M.ROOM.REDACTION && typeof pdu.content?.redacts === "string") ev.redacts = pdu.content.redacts;
165
166
  ev.unsigned = {
166
167
  ...pdu.unsigned,
167
168
  age: Math.max(0, Date.now() - pdu.origin_server_ts)
@@ -1,7 +1,8 @@
1
1
  import { isObject } from "./json.js";
2
+ import { UNSTABLE } from "./m.js";
2
3
  import { globMatch } from "./glob.js";
3
4
  //#region src/core/invitefilter.ts
4
- const INVITE_CONFIG_TYPE = "org.matrix.msc4155.invite_permission_config";
5
+ const INVITE_CONFIG_TYPE = UNSTABLE.ORG.MATRIX.MSC4155.INVITE_PERMISSION_CONFIG;
5
6
  /**
6
7
  * MSC4155 invite filtering: "allow", "ignore" (accept but hide) or "block" (refuse).
7
8
  * User rules take precedence over server rules; within each, allow > ignore > block.
package/dist/core/keys.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { isObject } from "./json.js";
2
+ import { UNSTABLE } from "./m.js";
2
3
  import { errors } from "./errors.js";
3
4
  //#region src/core/keys.ts
4
5
  /** End-to-end encryption key storage (device keys, one-time keys, cross-signing). */
@@ -78,7 +79,7 @@ var KeyService = class {
78
79
  seq
79
80
  }));
80
81
  }
81
- const fallbackKeys = body.fallback_keys ?? body["org.matrix.msc2732.fallback_keys"];
82
+ const fallbackKeys = body.fallback_keys ?? body[UNSTABLE.ORG.MATRIX.MSC2732.FALLBACK_KEYS];
82
83
  if (isObject(fallbackKeys)) for (const [fullId, key] of Object.entries(fallbackKeys)) {
83
84
  const [algorithm] = fullId.split(":");
84
85
  const existing = await this.hs.db.findOne("fallback_keys", [...device, {
@@ -0,0 +1,209 @@
1
+ //#region src/core/m.d.ts
2
+ export declare const M: {
3
+ readonly BEACON_INFO: "m.beacon_info";
4
+ readonly CALL: {
5
+ readonly INVITE: "m.call.invite";
6
+ };
7
+ readonly CHANGE_PASSWORD: "m.change_password";
8
+ readonly DEVICE_LIST_UPDATE: "m.device_list_update";
9
+ readonly DIRECT: "m.direct";
10
+ readonly DIRECT_TO_DEVICE: "m.direct_to_device";
11
+ readonly FEDERATE: "m.federate";
12
+ readonly FULLY_READ: "m.fully_read";
13
+ readonly GET_LOGIN_TOKEN: "m.get_login_token";
14
+ readonly HEROES: "m.heroes";
15
+ readonly HOMESERVER: "m.homeserver";
16
+ readonly ID: {
17
+ readonly PHONE: "m.id.phone";
18
+ readonly THIRDPARTY: "m.id.thirdparty";
19
+ readonly USER: "m.id.user";
20
+ };
21
+ readonly IGNORED_USER_LIST: "m.ignored_user_list";
22
+ readonly IN_REPLY_TO: "m.in_reply_to";
23
+ readonly INVITED_MEMBER_COUNT: "m.invited_member_count";
24
+ readonly JOINED_MEMBER_COUNT: "m.joined_member_count";
25
+ readonly LOGIN: {
26
+ readonly APPLICATION_SERVICE: "m.login.application_service";
27
+ readonly DUMMY: "m.login.dummy";
28
+ readonly EMAIL: {
29
+ readonly IDENTITY: "m.login.email.identity";
30
+ };
31
+ readonly MSISDN: "m.login.msisdn";
32
+ readonly PASSWORD: "m.login.password";
33
+ readonly REGISTRATION_TOKEN: "m.login.registration_token";
34
+ readonly SSO: "m.login.sso";
35
+ readonly TOKEN: "m.login.token";
36
+ };
37
+ readonly NOTICE: "m.notice";
38
+ readonly OAUTH: "m.oauth";
39
+ readonly POLL: {
40
+ readonly START: "m.poll.start";
41
+ };
42
+ readonly PRESENCE: "m.presence";
43
+ readonly PROFILE_FIELDS: "m.profile_fields";
44
+ readonly PUSH_RULES: "m.push_rules";
45
+ readonly REACTION: "m.reaction";
46
+ readonly READ: {
47
+ readonly _: "m.read";
48
+ readonly PRIVATE: "m.read.private";
49
+ };
50
+ readonly RECEIPT: "m.receipt";
51
+ readonly RELATES_TO: "m.relates_to";
52
+ readonly RELATIONS: "m.relations";
53
+ readonly RELATIONSHIP: "m.relationship";
54
+ readonly REPLACE: "m.replace";
55
+ readonly ROLE: {
56
+ readonly ADMIN: "m.role.admin";
57
+ readonly SECURITY: "m.role.security";
58
+ };
59
+ readonly ROOM: {
60
+ readonly ALIASES: "m.room.aliases";
61
+ readonly AVATAR: "m.room.avatar";
62
+ readonly CANONICAL_ALIAS: "m.room.canonical_alias";
63
+ readonly CREATE: "m.room.create";
64
+ readonly ENCRYPTED: "m.room.encrypted";
65
+ readonly ENCRYPTION: "m.room.encryption";
66
+ readonly GUEST_ACCESS: "m.room.guest_access";
67
+ readonly HISTORY_VISIBILITY: "m.room.history_visibility";
68
+ readonly JOIN_RULES: "m.room.join_rules";
69
+ readonly MEMBER: "m.room.member";
70
+ readonly MESSAGE: "m.room.message";
71
+ readonly NAME: "m.room.name";
72
+ readonly POLICY: "m.room.policy";
73
+ readonly POWER_LEVELS: "m.room.power_levels";
74
+ readonly REDACTION: "m.room.redaction";
75
+ readonly SERVER_ACL: "m.room.server_acl";
76
+ readonly THIRD_PARTY_INVITE: "m.room.third_party_invite";
77
+ readonly TOMBSTONE: "m.room.tombstone";
78
+ readonly TOPIC: "m.room.topic";
79
+ };
80
+ readonly ROOM_MEMBERSHIP: "m.room_membership";
81
+ readonly ROOM_VERSIONS: "m.room_versions";
82
+ readonly RULE: {
83
+ readonly CALL: ".m.rule.call";
84
+ readonly CONTAINS_DISPLAY_NAME: ".m.rule.contains_display_name";
85
+ readonly CONTAINS_USER_NAME: ".m.rule.contains_user_name";
86
+ readonly ENCRYPTED: ".m.rule.encrypted";
87
+ readonly ENCRYPTED_ROOM_ONE_TO_ONE: ".m.rule.encrypted_room_one_to_one";
88
+ readonly INVITE_FOR_ME: ".m.rule.invite_for_me";
89
+ readonly IS_ROOM_MENTION: ".m.rule.is_room_mention";
90
+ readonly IS_USER_MENTION: ".m.rule.is_user_mention";
91
+ readonly MASTER: ".m.rule.master";
92
+ readonly MEMBER_EVENT: ".m.rule.member_event";
93
+ readonly MESSAGE: ".m.rule.message";
94
+ readonly REACTION: ".m.rule.reaction";
95
+ readonly ROOM: {
96
+ readonly SERVER_ACL: ".m.rule.room.server_acl";
97
+ };
98
+ readonly ROOM_ONE_TO_ONE: ".m.rule.room_one_to_one";
99
+ readonly ROOMNOTIF: ".m.rule.roomnotif";
100
+ readonly SUPPRESS_EDITS: ".m.rule.suppress_edits";
101
+ readonly SUPPRESS_NOTICES: ".m.rule.suppress_notices";
102
+ readonly TOMBSTONE: ".m.rule.tombstone";
103
+ };
104
+ readonly SERVER: "m.server";
105
+ readonly SERVER_NOTICE: "m.server_notice";
106
+ readonly SET_AVATAR_URL: "m.set_avatar_url";
107
+ readonly SET_DISPLAYNAME: "m.set_displayname";
108
+ readonly SIGNING_KEY_UPDATE: "m.signing_key_update";
109
+ readonly SPACE: {
110
+ readonly _: "m.space";
111
+ readonly CHILD: "m.space.child";
112
+ };
113
+ readonly STICKER: "m.sticker";
114
+ readonly TAG: "m.tag";
115
+ readonly TEXT: "m.text";
116
+ readonly THREAD: "m.thread";
117
+ readonly THREEPID_CHANGES: "m.3pid_changes";
118
+ readonly TOPIC: "m.topic";
119
+ readonly TYPING: "m.typing";
120
+ readonly UPLOAD: {
121
+ readonly SIZE: "m.upload.size";
122
+ };
123
+ };
124
+ export declare const UNSTABLE: {
125
+ readonly DE: {
126
+ readonly SORUNOME: {
127
+ readonly MSC2409: {
128
+ readonly EPHEMERAL: "de.sorunome.msc2409.ephemeral";
129
+ readonly PUSH_EPHEMERAL: "de.sorunome.msc2409.push_ephemeral";
130
+ };
131
+ };
132
+ };
133
+ readonly IO: {
134
+ readonly ELEMENT: {
135
+ readonly MSC4306: {
136
+ readonly RULE: {
137
+ readonly SUBSCRIBED_THREAD: ".io.element.msc4306.rule.subscribed_thread";
138
+ readonly UNSUBSCRIBED_THREAD: ".io.element.msc4306.rule.unsubscribed_thread";
139
+ };
140
+ readonly THREAD_SUBSCRIPTION: "io.element.msc4306.thread_subscription";
141
+ };
142
+ readonly MSC4308: {
143
+ readonly THREAD_SUBSCRIPTIONS: "io.element.msc4308.thread_subscriptions";
144
+ };
145
+ };
146
+ };
147
+ readonly ORG: {
148
+ readonly MATRIX: {
149
+ readonly CROSS_SIGNING_RESET: "org.matrix.cross_signing_reset";
150
+ readonly CUSTOM: {
151
+ readonly HTML: "org.matrix.custom.html";
152
+ };
153
+ readonly MSC2732: {
154
+ readonly FALLBACK_KEYS: "org.matrix.msc2732.fallback_keys";
155
+ };
156
+ readonly MSC3202: {
157
+ readonly DEVICE_ID: "org.matrix.msc3202.device_id";
158
+ };
159
+ readonly MSC3381: {
160
+ readonly POLL: {
161
+ readonly END: "org.matrix.msc3381.poll.end";
162
+ readonly RESPONSE: "org.matrix.msc3381.poll.response";
163
+ readonly START: "org.matrix.msc3381.poll.start";
164
+ };
165
+ };
166
+ readonly MSC3874: {
167
+ readonly NOT_REL_TYPES: "org.matrix.msc3874.not_rel_types";
168
+ readonly REL_TYPES: "org.matrix.msc3874.rel_types";
169
+ };
170
+ readonly MSC3916: {
171
+ readonly STABLE: "org.matrix.msc3916.stable";
172
+ };
173
+ readonly MSC3930: {
174
+ readonly RULE: {
175
+ readonly POLL_END: ".org.matrix.msc3930.rule.poll_end";
176
+ readonly POLL_END_ONE_TO_ONE: ".org.matrix.msc3930.rule.poll_end_one_to_one";
177
+ readonly POLL_RESPONSE: ".org.matrix.msc3930.rule.poll_response";
178
+ readonly POLL_START: ".org.matrix.msc3930.rule.poll_start";
179
+ readonly POLL_START_ONE_TO_ONE: ".org.matrix.msc3930.rule.poll_start_one_to_one";
180
+ };
181
+ };
182
+ readonly MSC4140: {
183
+ readonly _: "org.matrix.msc4140";
184
+ readonly DELAY: "org.matrix.msc4140.delay";
185
+ readonly MAX_DELAY: "org.matrix.msc4140.max_delay";
186
+ };
187
+ readonly MSC4143: {
188
+ readonly _: "org.matrix.msc4143";
189
+ readonly RTC_FOCI: "org.matrix.msc4143.rtc_foci";
190
+ };
191
+ readonly MSC4155: {
192
+ readonly ERRCODE: "org.matrix.msc4155.errcode";
193
+ readonly INVITE_PERMISSION_CONFIG: "org.matrix.msc4155.invite_permission_config";
194
+ };
195
+ readonly MSC4222: {
196
+ readonly _: "org.matrix.msc4222";
197
+ readonly STATE_AFTER: "org.matrix.msc4222.state_after";
198
+ readonly USE_STATE_AFTER: "org.matrix.msc4222.use_state_after";
199
+ };
200
+ readonly MSC4306: "org.matrix.msc4306";
201
+ readonly MSC4429: {
202
+ readonly PROFILE_FIELDS: "org.matrix.msc4429.profile_fields";
203
+ readonly USERS: "org.matrix.msc4429.users";
204
+ };
205
+ readonly SIMPLIFIED_MSC3575: "org.matrix.simplified_msc3575";
206
+ };
207
+ };
208
+ };
209
+ //#endregion
package/dist/core/m.js ADDED
@@ -0,0 +1,182 @@
1
+ //#region src/core/m.ts
2
+ function deepFreeze(o) {
3
+ for (const v of Object.values(o)) if (typeof v === "object" && v !== null) deepFreeze(v);
4
+ return Object.freeze(o);
5
+ }
6
+ const M = deepFreeze({
7
+ BEACON_INFO: "m.beacon_info",
8
+ CALL: { INVITE: "m.call.invite" },
9
+ CHANGE_PASSWORD: "m.change_password",
10
+ DEVICE_LIST_UPDATE: "m.device_list_update",
11
+ DIRECT: "m.direct",
12
+ DIRECT_TO_DEVICE: "m.direct_to_device",
13
+ FEDERATE: "m.federate",
14
+ FULLY_READ: "m.fully_read",
15
+ GET_LOGIN_TOKEN: "m.get_login_token",
16
+ HEROES: "m.heroes",
17
+ HOMESERVER: "m.homeserver",
18
+ ID: {
19
+ PHONE: "m.id.phone",
20
+ THIRDPARTY: "m.id.thirdparty",
21
+ USER: "m.id.user"
22
+ },
23
+ IGNORED_USER_LIST: "m.ignored_user_list",
24
+ IN_REPLY_TO: "m.in_reply_to",
25
+ INVITED_MEMBER_COUNT: "m.invited_member_count",
26
+ JOINED_MEMBER_COUNT: "m.joined_member_count",
27
+ LOGIN: {
28
+ APPLICATION_SERVICE: "m.login.application_service",
29
+ DUMMY: "m.login.dummy",
30
+ EMAIL: { IDENTITY: "m.login.email.identity" },
31
+ MSISDN: "m.login.msisdn",
32
+ PASSWORD: "m.login.password",
33
+ REGISTRATION_TOKEN: "m.login.registration_token",
34
+ SSO: "m.login.sso",
35
+ TOKEN: "m.login.token"
36
+ },
37
+ NOTICE: "m.notice",
38
+ OAUTH: "m.oauth",
39
+ POLL: { START: "m.poll.start" },
40
+ PRESENCE: "m.presence",
41
+ PROFILE_FIELDS: "m.profile_fields",
42
+ PUSH_RULES: "m.push_rules",
43
+ REACTION: "m.reaction",
44
+ READ: {
45
+ _: "m.read",
46
+ PRIVATE: "m.read.private"
47
+ },
48
+ RECEIPT: "m.receipt",
49
+ RELATES_TO: "m.relates_to",
50
+ RELATIONS: "m.relations",
51
+ RELATIONSHIP: "m.relationship",
52
+ REPLACE: "m.replace",
53
+ ROLE: {
54
+ ADMIN: "m.role.admin",
55
+ SECURITY: "m.role.security"
56
+ },
57
+ ROOM: {
58
+ ALIASES: "m.room.aliases",
59
+ AVATAR: "m.room.avatar",
60
+ CANONICAL_ALIAS: "m.room.canonical_alias",
61
+ CREATE: "m.room.create",
62
+ ENCRYPTED: "m.room.encrypted",
63
+ ENCRYPTION: "m.room.encryption",
64
+ GUEST_ACCESS: "m.room.guest_access",
65
+ HISTORY_VISIBILITY: "m.room.history_visibility",
66
+ JOIN_RULES: "m.room.join_rules",
67
+ MEMBER: "m.room.member",
68
+ MESSAGE: "m.room.message",
69
+ NAME: "m.room.name",
70
+ POLICY: "m.room.policy",
71
+ POWER_LEVELS: "m.room.power_levels",
72
+ REDACTION: "m.room.redaction",
73
+ SERVER_ACL: "m.room.server_acl",
74
+ THIRD_PARTY_INVITE: "m.room.third_party_invite",
75
+ TOMBSTONE: "m.room.tombstone",
76
+ TOPIC: "m.room.topic"
77
+ },
78
+ ROOM_MEMBERSHIP: "m.room_membership",
79
+ ROOM_VERSIONS: "m.room_versions",
80
+ RULE: {
81
+ CALL: ".m.rule.call",
82
+ CONTAINS_DISPLAY_NAME: ".m.rule.contains_display_name",
83
+ CONTAINS_USER_NAME: ".m.rule.contains_user_name",
84
+ ENCRYPTED: ".m.rule.encrypted",
85
+ ENCRYPTED_ROOM_ONE_TO_ONE: ".m.rule.encrypted_room_one_to_one",
86
+ INVITE_FOR_ME: ".m.rule.invite_for_me",
87
+ IS_ROOM_MENTION: ".m.rule.is_room_mention",
88
+ IS_USER_MENTION: ".m.rule.is_user_mention",
89
+ MASTER: ".m.rule.master",
90
+ MEMBER_EVENT: ".m.rule.member_event",
91
+ MESSAGE: ".m.rule.message",
92
+ REACTION: ".m.rule.reaction",
93
+ ROOM: { SERVER_ACL: ".m.rule.room.server_acl" },
94
+ ROOM_ONE_TO_ONE: ".m.rule.room_one_to_one",
95
+ ROOMNOTIF: ".m.rule.roomnotif",
96
+ SUPPRESS_EDITS: ".m.rule.suppress_edits",
97
+ SUPPRESS_NOTICES: ".m.rule.suppress_notices",
98
+ TOMBSTONE: ".m.rule.tombstone"
99
+ },
100
+ SERVER: "m.server",
101
+ SERVER_NOTICE: "m.server_notice",
102
+ SET_AVATAR_URL: "m.set_avatar_url",
103
+ SET_DISPLAYNAME: "m.set_displayname",
104
+ SIGNING_KEY_UPDATE: "m.signing_key_update",
105
+ SPACE: {
106
+ _: "m.space",
107
+ CHILD: "m.space.child"
108
+ },
109
+ STICKER: "m.sticker",
110
+ TAG: "m.tag",
111
+ TEXT: "m.text",
112
+ THREAD: "m.thread",
113
+ THREEPID_CHANGES: "m.3pid_changes",
114
+ TOPIC: "m.topic",
115
+ TYPING: "m.typing",
116
+ UPLOAD: { SIZE: "m.upload.size" }
117
+ });
118
+ const UNSTABLE = deepFreeze({
119
+ DE: { SORUNOME: { MSC2409: {
120
+ EPHEMERAL: "de.sorunome.msc2409.ephemeral",
121
+ PUSH_EPHEMERAL: "de.sorunome.msc2409.push_ephemeral"
122
+ } } },
123
+ IO: { ELEMENT: {
124
+ MSC4306: {
125
+ RULE: {
126
+ SUBSCRIBED_THREAD: ".io.element.msc4306.rule.subscribed_thread",
127
+ UNSUBSCRIBED_THREAD: ".io.element.msc4306.rule.unsubscribed_thread"
128
+ },
129
+ THREAD_SUBSCRIPTION: "io.element.msc4306.thread_subscription"
130
+ },
131
+ MSC4308: { THREAD_SUBSCRIPTIONS: "io.element.msc4308.thread_subscriptions" }
132
+ } },
133
+ ORG: { MATRIX: {
134
+ CROSS_SIGNING_RESET: "org.matrix.cross_signing_reset",
135
+ CUSTOM: { HTML: "org.matrix.custom.html" },
136
+ MSC2732: { FALLBACK_KEYS: "org.matrix.msc2732.fallback_keys" },
137
+ MSC3202: { DEVICE_ID: "org.matrix.msc3202.device_id" },
138
+ MSC3381: { POLL: {
139
+ END: "org.matrix.msc3381.poll.end",
140
+ RESPONSE: "org.matrix.msc3381.poll.response",
141
+ START: "org.matrix.msc3381.poll.start"
142
+ } },
143
+ MSC3874: {
144
+ NOT_REL_TYPES: "org.matrix.msc3874.not_rel_types",
145
+ REL_TYPES: "org.matrix.msc3874.rel_types"
146
+ },
147
+ MSC3916: { STABLE: "org.matrix.msc3916.stable" },
148
+ MSC3930: { RULE: {
149
+ POLL_END: ".org.matrix.msc3930.rule.poll_end",
150
+ POLL_END_ONE_TO_ONE: ".org.matrix.msc3930.rule.poll_end_one_to_one",
151
+ POLL_RESPONSE: ".org.matrix.msc3930.rule.poll_response",
152
+ POLL_START: ".org.matrix.msc3930.rule.poll_start",
153
+ POLL_START_ONE_TO_ONE: ".org.matrix.msc3930.rule.poll_start_one_to_one"
154
+ } },
155
+ MSC4140: {
156
+ _: "org.matrix.msc4140",
157
+ DELAY: "org.matrix.msc4140.delay",
158
+ MAX_DELAY: "org.matrix.msc4140.max_delay"
159
+ },
160
+ MSC4143: {
161
+ _: "org.matrix.msc4143",
162
+ RTC_FOCI: "org.matrix.msc4143.rtc_foci"
163
+ },
164
+ MSC4155: {
165
+ ERRCODE: "org.matrix.msc4155.errcode",
166
+ INVITE_PERMISSION_CONFIG: "org.matrix.msc4155.invite_permission_config"
167
+ },
168
+ MSC4222: {
169
+ _: "org.matrix.msc4222",
170
+ STATE_AFTER: "org.matrix.msc4222.state_after",
171
+ USE_STATE_AFTER: "org.matrix.msc4222.use_state_after"
172
+ },
173
+ MSC4306: "org.matrix.msc4306",
174
+ MSC4429: {
175
+ PROFILE_FIELDS: "org.matrix.msc4429.profile_fields",
176
+ USERS: "org.matrix.msc4429.users"
177
+ },
178
+ SIMPLIFIED_MSC3575: "org.matrix.simplified_msc3575"
179
+ } }
180
+ });
181
+ //#endregion
182
+ export { M, UNSTABLE };
@@ -1,3 +1,4 @@
1
+ import { M } from "./m.js";
1
2
  import { eventIdOf, roomVersionFeatures, stateKey } from "./events.js";
2
3
  import { EventEmitter } from "node:events";
3
4
  //#region src/core/partialstate.ts
@@ -162,7 +163,7 @@ var PartialStateService = class {
162
163
  try {
163
164
  const fullBefore = await this.hs.federation.stateFromPrevs(server, roomId, version, prevIds, { remote: true });
164
165
  if (this.stopped || this.hs.isClosed) return true;
165
- if (!fullBefore[stateKey("m.room.create", "")] && !roomVersionFeatures(version).v12) throw new Error("Resynced state lacks the create event");
166
+ if (!fullBefore[stateKey(M.ROOM.CREATE, "")] && !roomVersionFeatures(version).v12) throw new Error("Resynced state lacks the create event");
166
167
  const notified = /* @__PURE__ */ new Set([...row.servers ?? [], ...this.hs.federation.serversInRoom(await this.hs.rooms.currentState(roomId), false)]);
167
168
  const missed = await this.hs.rooms.withLock(roomId, () => this.hs.rooms.completePartialState(roomId, version, row.join_event_id, fullBefore, notified));
168
169
  await this.finish(roomId);