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 +80 -0
- package/dist/server/index.js +65 -2
- package/dist/server/index.mjs +65 -2
- package/package.json +1 -1
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
|
package/dist/server/index.js
CHANGED
|
@@ -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
|
|
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.
|
|
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",
|
package/dist/server/index.mjs
CHANGED
|
@@ -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
|
|
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.
|
|
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