magic-editor-x 1.0.0 → 1.1.0

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.
package/README.md CHANGED
@@ -387,6 +387,11 @@ export default () => ({
387
387
  allowedAdminRoles: ['strapi-super-admin'],
388
388
  allowedAdminUserIds: [],
389
389
  },
390
+
391
+ // API Response Settings
392
+ api: {
393
+ autoParseJSON: true, // Auto-parse JSON strings to objects in API responses
394
+ },
390
395
  },
391
396
  },
392
397
  });
@@ -478,6 +483,11 @@ interface MagicEditorXConfig {
478
483
  // Link Preview Settings
479
484
  linkPreviewTimeout?: number; // Milliseconds, default: 10000
480
485
 
486
+ // API Response Settings
487
+ api?: {
488
+ autoParseJSON: boolean; // Auto-parse JSON strings to objects, default: true
489
+ };
490
+
481
491
  // Collaboration Settings
482
492
  collaboration?: {
483
493
  enabled: boolean; // Default: true
@@ -507,6 +517,76 @@ When adding the field in Content-Type Builder:
507
517
 
508
518
  ---
509
519
 
520
+ ## API Response Format
521
+
522
+ ### Automatic JSON Parsing
523
+
524
+ Magic Editor X automatically transforms JSON string fields into structured objects in API responses for better developer experience.
525
+
526
+ **Without auto-parsing (raw Strapi response):**
527
+ ```json
528
+ {
529
+ "data": {
530
+ "id": 1,
531
+ "documentId": "abc123",
532
+ "editorX": "{\"time\":1699999999999,\"blocks\":[{\"id\":\"xyz\",\"type\":\"paragraph\",\"data\":{\"text\":\"Hello\"}}],\"version\":\"2.31.0\"}"
533
+ }
534
+ }
535
+ ```
536
+
537
+ **With auto-parsing (Magic Editor X middleware active):**
538
+ ```json
539
+ {
540
+ "data": {
541
+ "id": 1,
542
+ "documentId": "abc123",
543
+ "editorX": {
544
+ "time": 1699999999999,
545
+ "blocks": [
546
+ {
547
+ "id": "xyz",
548
+ "type": "paragraph",
549
+ "data": {
550
+ "text": "Hello"
551
+ }
552
+ }
553
+ ],
554
+ "version": "2.31.0"
555
+ }
556
+ }
557
+ }
558
+ ```
559
+
560
+ **Configuration:**
561
+
562
+ Auto-parsing is enabled by default. To disable it, add to `config/plugins.ts`:
563
+
564
+ ```typescript
565
+ {
566
+ 'magic-editor-x': {
567
+ config: {
568
+ api: {
569
+ autoParseJSON: false // Disable automatic JSON parsing
570
+ }
571
+ }
572
+ }
573
+ }
574
+ ```
575
+
576
+ **Manual Parsing (if auto-parse is disabled):**
577
+
578
+ ```javascript
579
+ // Client-side parsing
580
+ const response = await fetch('/api/articles/1');
581
+ const data = await response.json();
582
+
583
+ // Parse Editor.js field manually
584
+ const editorContent = JSON.parse(data.data.editorX);
585
+ console.log(editorContent.blocks); // Array of blocks
586
+ ```
587
+
588
+ ---
589
+
510
590
  ## API Reference
511
591
 
512
592
  ### Public API Endpoints
@@ -77,6 +77,14 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
77
77
  }
78
78
  await strapi2.plugin("magic-editor-x").service("realtimeService").initSocketServer();
79
79
  strapi2.log.info("[Magic Editor X] [SUCCESS] Realtime server started");
80
+ const pluginConfig = strapi2.config.get("plugin::magic-editor-x") || {};
81
+ const autoParseJSON = pluginConfig.api?.autoParseJSON !== false;
82
+ if (autoParseJSON) {
83
+ strapi2.server.use(strapi2.plugin("magic-editor-x").middleware("parse-editor-fields")());
84
+ strapi2.log.info("[Magic Editor X] [SUCCESS] Auto-parse middleware registered (api.autoParseJSON: true)");
85
+ } else {
86
+ strapi2.log.info("[Magic Editor X] [INFO] Auto-parse middleware disabled (api.autoParseJSON: false)");
87
+ }
80
88
  } catch (error) {
81
89
  strapi2.log.error("[Magic Editor X] [ERROR] Bootstrap failed:", error);
82
90
  }
@@ -143,6 +151,11 @@ var config$1 = {
143
151
  allowedOrigins: [],
144
152
  allowedAdminRoles: ["strapi-super-admin"],
145
153
  allowedAdminUserIds: []
154
+ },
155
+ // API Response Settings
156
+ api: {
157
+ autoParseJSON: true
158
+ // Automatically parse Editor.js JSON strings to objects in API responses
146
159
  }
147
160
  },
148
161
  validator: (config2) => {
@@ -923,7 +936,57 @@ var controllers$1 = {
923
936
  collaboration,
924
937
  license: license$1
925
938
  };
926
- var middlewares$1 = {};
939
+ var parseEditorFields$1 = (config2, { strapi: strapi2 }) => {
940
+ return async (ctx, next) => {
941
+ await next();
942
+ if (ctx.method !== "GET" || ctx.status !== 200) {
943
+ return;
944
+ }
945
+ if (!ctx.body || typeof ctx.body !== "object") {
946
+ return;
947
+ }
948
+ try {
949
+ const parseEditorFields2 = (data) => {
950
+ if (!data || typeof data !== "object") {
951
+ return data;
952
+ }
953
+ if (Array.isArray(data)) {
954
+ return data.map(parseEditorFields2);
955
+ }
956
+ const parsed = {};
957
+ for (const [key, value] of Object.entries(data)) {
958
+ if (typeof value === "string" && value.startsWith("{") && value.includes('"blocks"')) {
959
+ try {
960
+ const parsedValue = JSON.parse(value);
961
+ if (parsedValue.blocks && Array.isArray(parsedValue.blocks)) {
962
+ parsed[key] = parsedValue;
963
+ continue;
964
+ }
965
+ } catch (e) {
966
+ }
967
+ }
968
+ if (value !== null && typeof value === "object") {
969
+ parsed[key] = parseEditorFields2(value);
970
+ } else {
971
+ parsed[key] = value;
972
+ }
973
+ }
974
+ return parsed;
975
+ };
976
+ if (ctx.body.data) {
977
+ ctx.body.data = parseEditorFields2(ctx.body.data);
978
+ } else {
979
+ ctx.body = parseEditorFields2(ctx.body);
980
+ }
981
+ } catch (error) {
982
+ strapi2.log.debug("[Magic Editor X] Failed to parse editor fields:", error.message);
983
+ }
984
+ };
985
+ };
986
+ const parseEditorFields = parseEditorFields$1;
987
+ var middlewares$1 = {
988
+ "parse-editor-fields": parseEditorFields
989
+ };
927
990
  var policies$1 = {};
928
991
  var admin$1 = {
929
992
  type: "admin",
@@ -1931,7 +1994,7 @@ var snapshotService$1 = ({ strapi: strapi2 }) => ({
1931
1994
  }
1932
1995
  });
1933
1996
  const name = "magic-editor-x";
1934
- const version = "1.0.1";
1997
+ const version = "1.0.0";
1935
1998
  const description = "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support";
1936
1999
  const keywords = [
1937
2000
  "strapi",
@@ -65,6 +65,14 @@ var bootstrap$1 = async ({ strapi: strapi2 }) => {
65
65
  }
66
66
  await strapi2.plugin("magic-editor-x").service("realtimeService").initSocketServer();
67
67
  strapi2.log.info("[Magic Editor X] [SUCCESS] Realtime server started");
68
+ const pluginConfig = strapi2.config.get("plugin::magic-editor-x") || {};
69
+ const autoParseJSON = pluginConfig.api?.autoParseJSON !== false;
70
+ if (autoParseJSON) {
71
+ strapi2.server.use(strapi2.plugin("magic-editor-x").middleware("parse-editor-fields")());
72
+ strapi2.log.info("[Magic Editor X] [SUCCESS] Auto-parse middleware registered (api.autoParseJSON: true)");
73
+ } else {
74
+ strapi2.log.info("[Magic Editor X] [INFO] Auto-parse middleware disabled (api.autoParseJSON: false)");
75
+ }
68
76
  } catch (error) {
69
77
  strapi2.log.error("[Magic Editor X] [ERROR] Bootstrap failed:", error);
70
78
  }
@@ -131,6 +139,11 @@ var config$1 = {
131
139
  allowedOrigins: [],
132
140
  allowedAdminRoles: ["strapi-super-admin"],
133
141
  allowedAdminUserIds: []
142
+ },
143
+ // API Response Settings
144
+ api: {
145
+ autoParseJSON: true
146
+ // Automatically parse Editor.js JSON strings to objects in API responses
134
147
  }
135
148
  },
136
149
  validator: (config2) => {
@@ -911,7 +924,57 @@ var controllers$1 = {
911
924
  collaboration,
912
925
  license: license$1
913
926
  };
914
- var middlewares$1 = {};
927
+ var parseEditorFields$1 = (config2, { strapi: strapi2 }) => {
928
+ return async (ctx, next) => {
929
+ await next();
930
+ if (ctx.method !== "GET" || ctx.status !== 200) {
931
+ return;
932
+ }
933
+ if (!ctx.body || typeof ctx.body !== "object") {
934
+ return;
935
+ }
936
+ try {
937
+ const parseEditorFields2 = (data) => {
938
+ if (!data || typeof data !== "object") {
939
+ return data;
940
+ }
941
+ if (Array.isArray(data)) {
942
+ return data.map(parseEditorFields2);
943
+ }
944
+ const parsed = {};
945
+ for (const [key, value] of Object.entries(data)) {
946
+ if (typeof value === "string" && value.startsWith("{") && value.includes('"blocks"')) {
947
+ try {
948
+ const parsedValue = JSON.parse(value);
949
+ if (parsedValue.blocks && Array.isArray(parsedValue.blocks)) {
950
+ parsed[key] = parsedValue;
951
+ continue;
952
+ }
953
+ } catch (e) {
954
+ }
955
+ }
956
+ if (value !== null && typeof value === "object") {
957
+ parsed[key] = parseEditorFields2(value);
958
+ } else {
959
+ parsed[key] = value;
960
+ }
961
+ }
962
+ return parsed;
963
+ };
964
+ if (ctx.body.data) {
965
+ ctx.body.data = parseEditorFields2(ctx.body.data);
966
+ } else {
967
+ ctx.body = parseEditorFields2(ctx.body);
968
+ }
969
+ } catch (error) {
970
+ strapi2.log.debug("[Magic Editor X] Failed to parse editor fields:", error.message);
971
+ }
972
+ };
973
+ };
974
+ const parseEditorFields = parseEditorFields$1;
975
+ var middlewares$1 = {
976
+ "parse-editor-fields": parseEditorFields
977
+ };
915
978
  var policies$1 = {};
916
979
  var admin$1 = {
917
980
  type: "admin",
@@ -1919,7 +1982,7 @@ var snapshotService$1 = ({ strapi: strapi2 }) => ({
1919
1982
  }
1920
1983
  });
1921
1984
  const name = "magic-editor-x";
1922
- const version = "1.0.1";
1985
+ const version = "1.0.0";
1923
1986
  const description = "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support";
1924
1987
  const keywords = [
1925
1988
  "strapi",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magic-editor-x",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support",
5
5
  "keywords": [
6
6
  "strapi",