magic-editor-x 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -15,7 +15,7 @@ Magic Editor X is a production-ready Strapi v5 Custom Field that brings the powe
15
15
 
16
16
  Built on proven technologies like Editor.js for the editing interface and Y.js for conflict-free real-time collaboration, this plugin provides a modern, extensible content editing experience that scales from solo developers to large editorial teams.
17
17
 
18
- ### Why Magic Editor X?
18
+ ### Why Magic Editor X? :)
19
19
 
20
20
  **For Developers:**
21
21
  - Clean JSON output instead of unstructured HTML
@@ -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,15 @@ 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
+ const parseMiddleware = strapi2.plugin("magic-editor-x").middleware("parse-editor-fields");
84
+ strapi2.server.use(parseMiddleware({}, { strapi: strapi2 }));
85
+ strapi2.log.info("[Magic Editor X] [SUCCESS] Auto-parse middleware registered (api.autoParseJSON: true)");
86
+ } else {
87
+ strapi2.log.info("[Magic Editor X] [INFO] Auto-parse middleware disabled (api.autoParseJSON: false)");
88
+ }
80
89
  } catch (error) {
81
90
  strapi2.log.error("[Magic Editor X] [ERROR] Bootstrap failed:", error);
82
91
  }
@@ -143,6 +152,11 @@ var config$1 = {
143
152
  allowedOrigins: [],
144
153
  allowedAdminRoles: ["strapi-super-admin"],
145
154
  allowedAdminUserIds: []
155
+ },
156
+ // API Response Settings
157
+ api: {
158
+ autoParseJSON: true
159
+ // Automatically parse Editor.js JSON strings to objects in API responses
146
160
  }
147
161
  },
148
162
  validator: (config2) => {
@@ -923,7 +937,57 @@ var controllers$1 = {
923
937
  collaboration,
924
938
  license: license$1
925
939
  };
926
- var middlewares$1 = {};
940
+ var parseEditorFields$1 = (config2, { strapi: strapi2 }) => {
941
+ return async (ctx, next) => {
942
+ await next();
943
+ if (ctx.method !== "GET" || ctx.status !== 200) {
944
+ return;
945
+ }
946
+ if (!ctx.body || typeof ctx.body !== "object") {
947
+ return;
948
+ }
949
+ try {
950
+ const parseEditorFields2 = (data) => {
951
+ if (!data || typeof data !== "object") {
952
+ return data;
953
+ }
954
+ if (Array.isArray(data)) {
955
+ return data.map(parseEditorFields2);
956
+ }
957
+ const parsed = {};
958
+ for (const [key, value] of Object.entries(data)) {
959
+ if (typeof value === "string" && value.startsWith("{") && value.includes('"blocks"')) {
960
+ try {
961
+ const parsedValue = JSON.parse(value);
962
+ if (parsedValue.blocks && Array.isArray(parsedValue.blocks)) {
963
+ parsed[key] = parsedValue;
964
+ continue;
965
+ }
966
+ } catch (e) {
967
+ }
968
+ }
969
+ if (value !== null && typeof value === "object") {
970
+ parsed[key] = parseEditorFields2(value);
971
+ } else {
972
+ parsed[key] = value;
973
+ }
974
+ }
975
+ return parsed;
976
+ };
977
+ if (ctx.body.data) {
978
+ ctx.body.data = parseEditorFields2(ctx.body.data);
979
+ } else {
980
+ ctx.body = parseEditorFields2(ctx.body);
981
+ }
982
+ } catch (error) {
983
+ strapi2.log.debug("[Magic Editor X] Failed to parse editor fields:", error.message);
984
+ }
985
+ };
986
+ };
987
+ const parseEditorFields = parseEditorFields$1;
988
+ var middlewares$1 = {
989
+ "parse-editor-fields": parseEditorFields
990
+ };
927
991
  var policies$1 = {};
928
992
  var admin$1 = {
929
993
  type: "admin",
@@ -1931,7 +1995,7 @@ var snapshotService$1 = ({ strapi: strapi2 }) => ({
1931
1995
  }
1932
1996
  });
1933
1997
  const name = "magic-editor-x";
1934
- const version = "1.0.1";
1998
+ const version = "1.1.0";
1935
1999
  const description = "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support";
1936
2000
  const keywords = [
1937
2001
  "strapi",
@@ -65,6 +65,15 @@ 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
+ const parseMiddleware = strapi2.plugin("magic-editor-x").middleware("parse-editor-fields");
72
+ strapi2.server.use(parseMiddleware({}, { strapi: strapi2 }));
73
+ strapi2.log.info("[Magic Editor X] [SUCCESS] Auto-parse middleware registered (api.autoParseJSON: true)");
74
+ } else {
75
+ strapi2.log.info("[Magic Editor X] [INFO] Auto-parse middleware disabled (api.autoParseJSON: false)");
76
+ }
68
77
  } catch (error) {
69
78
  strapi2.log.error("[Magic Editor X] [ERROR] Bootstrap failed:", error);
70
79
  }
@@ -131,6 +140,11 @@ var config$1 = {
131
140
  allowedOrigins: [],
132
141
  allowedAdminRoles: ["strapi-super-admin"],
133
142
  allowedAdminUserIds: []
143
+ },
144
+ // API Response Settings
145
+ api: {
146
+ autoParseJSON: true
147
+ // Automatically parse Editor.js JSON strings to objects in API responses
134
148
  }
135
149
  },
136
150
  validator: (config2) => {
@@ -911,7 +925,57 @@ var controllers$1 = {
911
925
  collaboration,
912
926
  license: license$1
913
927
  };
914
- var middlewares$1 = {};
928
+ var parseEditorFields$1 = (config2, { strapi: strapi2 }) => {
929
+ return async (ctx, next) => {
930
+ await next();
931
+ if (ctx.method !== "GET" || ctx.status !== 200) {
932
+ return;
933
+ }
934
+ if (!ctx.body || typeof ctx.body !== "object") {
935
+ return;
936
+ }
937
+ try {
938
+ const parseEditorFields2 = (data) => {
939
+ if (!data || typeof data !== "object") {
940
+ return data;
941
+ }
942
+ if (Array.isArray(data)) {
943
+ return data.map(parseEditorFields2);
944
+ }
945
+ const parsed = {};
946
+ for (const [key, value] of Object.entries(data)) {
947
+ if (typeof value === "string" && value.startsWith("{") && value.includes('"blocks"')) {
948
+ try {
949
+ const parsedValue = JSON.parse(value);
950
+ if (parsedValue.blocks && Array.isArray(parsedValue.blocks)) {
951
+ parsed[key] = parsedValue;
952
+ continue;
953
+ }
954
+ } catch (e) {
955
+ }
956
+ }
957
+ if (value !== null && typeof value === "object") {
958
+ parsed[key] = parseEditorFields2(value);
959
+ } else {
960
+ parsed[key] = value;
961
+ }
962
+ }
963
+ return parsed;
964
+ };
965
+ if (ctx.body.data) {
966
+ ctx.body.data = parseEditorFields2(ctx.body.data);
967
+ } else {
968
+ ctx.body = parseEditorFields2(ctx.body);
969
+ }
970
+ } catch (error) {
971
+ strapi2.log.debug("[Magic Editor X] Failed to parse editor fields:", error.message);
972
+ }
973
+ };
974
+ };
975
+ const parseEditorFields = parseEditorFields$1;
976
+ var middlewares$1 = {
977
+ "parse-editor-fields": parseEditorFields
978
+ };
915
979
  var policies$1 = {};
916
980
  var admin$1 = {
917
981
  type: "admin",
@@ -1919,7 +1983,7 @@ var snapshotService$1 = ({ strapi: strapi2 }) => ({
1919
1983
  }
1920
1984
  });
1921
1985
  const name = "magic-editor-x";
1922
- const version = "1.0.1";
1986
+ const version = "1.1.0";
1923
1987
  const description = "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support";
1924
1988
  const keywords = [
1925
1989
  "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.1",
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",