@strapi-community/plugin-io 5.3.4 → 5.3.6

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.
@@ -557,6 +557,10 @@ async function bootstrapIO$1({ strapi: strapi2 }) {
557
557
  if (callback) callback({ success: false, error: "Presence is disabled" });
558
558
  return;
559
559
  }
560
+ if (!socket.user) {
561
+ if (callback) callback({ success: false, error: "Authentication required for presence" });
562
+ return;
563
+ }
560
564
  if (!uid || !documentId) {
561
565
  if (callback) callback({ success: false, error: "uid and documentId are required" });
562
566
  return;
@@ -569,6 +573,10 @@ async function bootstrapIO$1({ strapi: strapi2 }) {
569
573
  if (callback) callback({ success: false, error: "Presence is disabled" });
570
574
  return;
571
575
  }
576
+ if (!socket.user) {
577
+ if (callback) callback({ success: false, error: "Authentication required for presence" });
578
+ return;
579
+ }
572
580
  if (!uid || !documentId) {
573
581
  if (callback) callback({ success: false, error: "uid and documentId are required" });
574
582
  return;
@@ -577,6 +585,10 @@ async function bootstrapIO$1({ strapi: strapi2 }) {
577
585
  if (callback) callback(result);
578
586
  }));
579
587
  socket.on("presence:heartbeat", (callback) => {
588
+ if (!socket.user) {
589
+ if (callback) callback({ success: false, error: "Authentication required for presence" });
590
+ return;
591
+ }
580
592
  const result = presenceService.heartbeat(socket.id);
581
593
  if (callback) callback(result);
582
594
  });
@@ -1050,6 +1062,33 @@ function getTransactionCtx() {
1050
1062
  return transactionCtx;
1051
1063
  }
1052
1064
  const { pluginId: pluginId$6 } = pluginId_1;
1065
+ function buildPopulateFromSchema(strapi2, uid) {
1066
+ const contentType = strapi2.contentTypes[uid];
1067
+ if (!contentType?.attributes) return {};
1068
+ const populate2 = {};
1069
+ for (const [key, attr] of Object.entries(contentType.attributes)) {
1070
+ if (attr.type === "relation" || attr.type === "media" || attr.type === "component" || attr.type === "dynamiczone") {
1071
+ populate2[key] = true;
1072
+ }
1073
+ }
1074
+ return populate2;
1075
+ }
1076
+ async function fetchWithRelations(strapi2, uid, rawResult) {
1077
+ const documentId = rawResult?.documentId;
1078
+ if (!documentId) return rawResult;
1079
+ try {
1080
+ const populate2 = buildPopulateFromSchema(strapi2, uid);
1081
+ if (Object.keys(populate2).length === 0) return rawResult;
1082
+ const fetched = await strapi2.documents(uid).findOne({ documentId, populate: populate2 });
1083
+ return fetched || rawResult;
1084
+ } catch (err) {
1085
+ strapi2.log.debug(`socket.io: Could not re-fetch ${uid} with relations: ${err.message}`);
1086
+ return rawResult;
1087
+ }
1088
+ }
1089
+ function shouldPopulateRelations(strapi2) {
1090
+ return strapi2.$ioSettings?.events?.includeRelations === true;
1091
+ }
1053
1092
  function scheduleAfterTransaction(callback, delay = 0) {
1054
1093
  const runner = () => setTimeout(callback, delay);
1055
1094
  const ctx = getTransactionCtx();
@@ -1097,15 +1136,12 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1097
1136
  return;
1098
1137
  }
1099
1138
  try {
1100
- const eventData = {
1101
- event: "create",
1102
- schema: event.model,
1103
- data: JSON.parse(JSON.stringify(event.result))
1104
- // Deep clone
1105
- };
1106
- scheduleAfterTransaction(() => {
1139
+ const rawData = JSON.parse(JSON.stringify(event.result));
1140
+ const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1141
+ scheduleAfterTransaction(async () => {
1107
1142
  try {
1108
- strapi2.$io.emit(eventData);
1143
+ const data = shouldPopulateRelations(strapi2) ? await fetchWithRelations(strapi2, uid, rawData) : rawData;
1144
+ strapi2.$io.emit({ event: "create", schema: modelInfo, data });
1109
1145
  } catch (error2) {
1110
1146
  strapi2.log.error(`socket.io: Could not emit create event for ${uid}:`, error2.message);
1111
1147
  }
@@ -1119,6 +1155,9 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1119
1155
  const query = buildEventQuery({ event });
1120
1156
  if (query.filters) {
1121
1157
  const clonedQuery = JSON.parse(JSON.stringify(query));
1158
+ if (shouldPopulateRelations(strapi2)) {
1159
+ clonedQuery.populate = buildPopulateFromSchema(strapi2, uid);
1160
+ }
1122
1161
  const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1123
1162
  scheduleAfterTransaction(async () => {
1124
1163
  try {
@@ -1143,7 +1182,11 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1143
1182
  try {
1144
1183
  const documentId = event.params.where?.documentId || event.params.documentId;
1145
1184
  if (!documentId) return;
1146
- const existing = await strapi2.documents(uid).findOne({ documentId });
1185
+ const query = { documentId };
1186
+ if (shouldPopulateRelations(strapi2)) {
1187
+ query.populate = buildPopulateFromSchema(strapi2, uid);
1188
+ }
1189
+ const existing = await strapi2.documents(uid).findOne(query);
1147
1190
  if (existing) {
1148
1191
  if (!event.state.io) event.state.io = {};
1149
1192
  event.state.io.previousData = JSON.parse(JSON.stringify(existing));
@@ -1154,11 +1197,12 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1154
1197
  };
1155
1198
  subscriber.afterUpdate = async (event) => {
1156
1199
  if (!isActionEnabled(strapi2, uid, "update")) return;
1157
- const newData = JSON.parse(JSON.stringify(event.result));
1200
+ const rawData = JSON.parse(JSON.stringify(event.result));
1158
1201
  const previousData = event.state.io?.previousData || null;
1159
1202
  const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1160
- scheduleAfterTransaction(() => {
1203
+ scheduleAfterTransaction(async () => {
1161
1204
  try {
1205
+ const newData = shouldPopulateRelations(strapi2) ? await fetchWithRelations(strapi2, uid, rawData) : rawData;
1162
1206
  const diffService = strapi2.plugin(pluginId$6).service("diff");
1163
1207
  const previewService = strapi2.plugin(pluginId$6).service("preview");
1164
1208
  const fieldLevelEnabled = strapi2.$ioSettings?.fieldLevelChanges?.enabled !== false;
@@ -1195,11 +1239,13 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1195
1239
  if (!params || !params.where) return;
1196
1240
  const clonedWhere = JSON.parse(JSON.stringify(params.where));
1197
1241
  const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1242
+ const query = { filters: clonedWhere };
1243
+ if (shouldPopulateRelations(strapi2)) {
1244
+ query.populate = buildPopulateFromSchema(strapi2, uid);
1245
+ }
1198
1246
  scheduleAfterTransaction(async () => {
1199
1247
  try {
1200
- const records = await strapi2.documents(uid).findMany({
1201
- filters: clonedWhere
1202
- });
1248
+ const records = await strapi2.documents(uid).findMany(query);
1203
1249
  records.forEach((r) => {
1204
1250
  strapi2.$io.emit({
1205
1251
  event: "update",
@@ -29710,7 +29756,7 @@ const dist = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
29710
29756
  const require$$0 = /* @__PURE__ */ getAugmentedNamespace(dist);
29711
29757
  const { pluginId: pluginId$5 } = pluginId_1;
29712
29758
  const { errors } = require$$0;
29713
- const { z } = require$$2__default$2.default;
29759
+ const z = require$$2__default$2.default;
29714
29760
  const settingsSchema = z.object({
29715
29761
  enabled: z.boolean().optional(),
29716
29762
  cors: z.object({
@@ -525,6 +525,10 @@ async function bootstrapIO$1({ strapi: strapi2 }) {
525
525
  if (callback) callback({ success: false, error: "Presence is disabled" });
526
526
  return;
527
527
  }
528
+ if (!socket.user) {
529
+ if (callback) callback({ success: false, error: "Authentication required for presence" });
530
+ return;
531
+ }
528
532
  if (!uid || !documentId) {
529
533
  if (callback) callback({ success: false, error: "uid and documentId are required" });
530
534
  return;
@@ -537,6 +541,10 @@ async function bootstrapIO$1({ strapi: strapi2 }) {
537
541
  if (callback) callback({ success: false, error: "Presence is disabled" });
538
542
  return;
539
543
  }
544
+ if (!socket.user) {
545
+ if (callback) callback({ success: false, error: "Authentication required for presence" });
546
+ return;
547
+ }
540
548
  if (!uid || !documentId) {
541
549
  if (callback) callback({ success: false, error: "uid and documentId are required" });
542
550
  return;
@@ -545,6 +553,10 @@ async function bootstrapIO$1({ strapi: strapi2 }) {
545
553
  if (callback) callback(result);
546
554
  }));
547
555
  socket.on("presence:heartbeat", (callback) => {
556
+ if (!socket.user) {
557
+ if (callback) callback({ success: false, error: "Authentication required for presence" });
558
+ return;
559
+ }
548
560
  const result = presenceService.heartbeat(socket.id);
549
561
  if (callback) callback(result);
550
562
  });
@@ -1018,6 +1030,33 @@ function getTransactionCtx() {
1018
1030
  return transactionCtx;
1019
1031
  }
1020
1032
  const { pluginId: pluginId$6 } = pluginId_1;
1033
+ function buildPopulateFromSchema(strapi2, uid) {
1034
+ const contentType = strapi2.contentTypes[uid];
1035
+ if (!contentType?.attributes) return {};
1036
+ const populate2 = {};
1037
+ for (const [key, attr] of Object.entries(contentType.attributes)) {
1038
+ if (attr.type === "relation" || attr.type === "media" || attr.type === "component" || attr.type === "dynamiczone") {
1039
+ populate2[key] = true;
1040
+ }
1041
+ }
1042
+ return populate2;
1043
+ }
1044
+ async function fetchWithRelations(strapi2, uid, rawResult) {
1045
+ const documentId = rawResult?.documentId;
1046
+ if (!documentId) return rawResult;
1047
+ try {
1048
+ const populate2 = buildPopulateFromSchema(strapi2, uid);
1049
+ if (Object.keys(populate2).length === 0) return rawResult;
1050
+ const fetched = await strapi2.documents(uid).findOne({ documentId, populate: populate2 });
1051
+ return fetched || rawResult;
1052
+ } catch (err) {
1053
+ strapi2.log.debug(`socket.io: Could not re-fetch ${uid} with relations: ${err.message}`);
1054
+ return rawResult;
1055
+ }
1056
+ }
1057
+ function shouldPopulateRelations(strapi2) {
1058
+ return strapi2.$ioSettings?.events?.includeRelations === true;
1059
+ }
1021
1060
  function scheduleAfterTransaction(callback, delay = 0) {
1022
1061
  const runner = () => setTimeout(callback, delay);
1023
1062
  const ctx = getTransactionCtx();
@@ -1065,15 +1104,12 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1065
1104
  return;
1066
1105
  }
1067
1106
  try {
1068
- const eventData = {
1069
- event: "create",
1070
- schema: event.model,
1071
- data: JSON.parse(JSON.stringify(event.result))
1072
- // Deep clone
1073
- };
1074
- scheduleAfterTransaction(() => {
1107
+ const rawData = JSON.parse(JSON.stringify(event.result));
1108
+ const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1109
+ scheduleAfterTransaction(async () => {
1075
1110
  try {
1076
- strapi2.$io.emit(eventData);
1111
+ const data = shouldPopulateRelations(strapi2) ? await fetchWithRelations(strapi2, uid, rawData) : rawData;
1112
+ strapi2.$io.emit({ event: "create", schema: modelInfo, data });
1077
1113
  } catch (error2) {
1078
1114
  strapi2.log.error(`socket.io: Could not emit create event for ${uid}:`, error2.message);
1079
1115
  }
@@ -1087,6 +1123,9 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1087
1123
  const query = buildEventQuery({ event });
1088
1124
  if (query.filters) {
1089
1125
  const clonedQuery = JSON.parse(JSON.stringify(query));
1126
+ if (shouldPopulateRelations(strapi2)) {
1127
+ clonedQuery.populate = buildPopulateFromSchema(strapi2, uid);
1128
+ }
1090
1129
  const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1091
1130
  scheduleAfterTransaction(async () => {
1092
1131
  try {
@@ -1111,7 +1150,11 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1111
1150
  try {
1112
1151
  const documentId = event.params.where?.documentId || event.params.documentId;
1113
1152
  if (!documentId) return;
1114
- const existing = await strapi2.documents(uid).findOne({ documentId });
1153
+ const query = { documentId };
1154
+ if (shouldPopulateRelations(strapi2)) {
1155
+ query.populate = buildPopulateFromSchema(strapi2, uid);
1156
+ }
1157
+ const existing = await strapi2.documents(uid).findOne(query);
1115
1158
  if (existing) {
1116
1159
  if (!event.state.io) event.state.io = {};
1117
1160
  event.state.io.previousData = JSON.parse(JSON.stringify(existing));
@@ -1122,11 +1165,12 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1122
1165
  };
1123
1166
  subscriber.afterUpdate = async (event) => {
1124
1167
  if (!isActionEnabled(strapi2, uid, "update")) return;
1125
- const newData = JSON.parse(JSON.stringify(event.result));
1168
+ const rawData = JSON.parse(JSON.stringify(event.result));
1126
1169
  const previousData = event.state.io?.previousData || null;
1127
1170
  const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1128
- scheduleAfterTransaction(() => {
1171
+ scheduleAfterTransaction(async () => {
1129
1172
  try {
1173
+ const newData = shouldPopulateRelations(strapi2) ? await fetchWithRelations(strapi2, uid, rawData) : rawData;
1130
1174
  const diffService = strapi2.plugin(pluginId$6).service("diff");
1131
1175
  const previewService = strapi2.plugin(pluginId$6).service("preview");
1132
1176
  const fieldLevelEnabled = strapi2.$ioSettings?.fieldLevelChanges?.enabled !== false;
@@ -1163,11 +1207,13 @@ async function bootstrapLifecycles$1({ strapi: strapi2 }) {
1163
1207
  if (!params || !params.where) return;
1164
1208
  const clonedWhere = JSON.parse(JSON.stringify(params.where));
1165
1209
  const modelInfo = { singularName: event.model.singularName, uid: event.model.uid };
1210
+ const query = { filters: clonedWhere };
1211
+ if (shouldPopulateRelations(strapi2)) {
1212
+ query.populate = buildPopulateFromSchema(strapi2, uid);
1213
+ }
1166
1214
  scheduleAfterTransaction(async () => {
1167
1215
  try {
1168
- const records = await strapi2.documents(uid).findMany({
1169
- filters: clonedWhere
1170
- });
1216
+ const records = await strapi2.documents(uid).findMany(query);
1171
1217
  records.forEach((r) => {
1172
1218
  strapi2.$io.emit({
1173
1219
  event: "update",
@@ -29678,7 +29724,7 @@ const dist = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
29678
29724
  const require$$0 = /* @__PURE__ */ getAugmentedNamespace(dist);
29679
29725
  const { pluginId: pluginId$5 } = pluginId_1;
29680
29726
  const { errors } = require$$0;
29681
- const { z } = require$$2$2;
29727
+ const z = require$$2$2;
29682
29728
  const settingsSchema = z.object({
29683
29729
  enabled: z.boolean().optional(),
29684
29730
  cors: z.object({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@strapi-community/plugin-io",
4
- "version": "5.3.4",
4
+ "version": "5.3.6",
5
5
  "description": "A plugin for Strapi CMS that provides the ability for Socket IO integration",
6
6
  "keywords": [
7
7
  "strapi",