@ecomcx/ecomweb-content 0.0.0-stage → 1.15.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +178 -2
  3. package/dist/bindings.d.ts +19 -0
  4. package/dist/bindings.js +44 -0
  5. package/dist/block.d.ts +58 -0
  6. package/dist/block.js +60 -0
  7. package/dist/embed.d.ts +23 -0
  8. package/dist/embed.js +63 -0
  9. package/dist/index.d.ts +11 -0
  10. package/dist/index.js +11 -0
  11. package/dist/migrate.d.ts +2 -0
  12. package/dist/migrate.js +19 -0
  13. package/dist/normalize.d.ts +25 -0
  14. package/dist/normalize.js +147 -0
  15. package/dist/schema.d.ts +31 -0
  16. package/dist/schema.js +173 -0
  17. package/dist/style.d.ts +132 -0
  18. package/dist/style.js +523 -0
  19. package/dist/text.d.ts +9 -0
  20. package/dist/text.js +30 -0
  21. package/dist/types.d.ts +36 -0
  22. package/dist/types.js +6 -0
  23. package/dist/url.d.ts +7 -0
  24. package/dist/url.js +21 -0
  25. package/fixtures/all-core-nodes.json +782 -0
  26. package/fixtures/attr-coercion.json +219 -0
  27. package/fixtures/basic-blocks.json +414 -0
  28. package/fixtures/bindings-lock.json +33 -0
  29. package/fixtures/block-extras.json +131 -0
  30. package/fixtures/block-styles.json +316 -0
  31. package/fixtures/dynamic-blocks.json +316 -0
  32. package/fixtures/editor-output-nulls.json +112 -0
  33. package/fixtures/empty-and-newer.json +12 -0
  34. package/fixtures/invalid-structure.json +145 -0
  35. package/fixtures/layout-blocks.json +238 -0
  36. package/fixtures/legacy-html-string.json +17 -0
  37. package/fixtures/legacy-tiptap-doc.json +41 -0
  38. package/fixtures/plugin-blocks-preserved.json +155 -0
  39. package/fixtures/style-layout-effects.json +47 -0
  40. package/fixtures/synced-pattern.json +80 -0
  41. package/package.json +44 -4
  42. package/style.css +169 -0
@@ -0,0 +1,238 @@
1
+ {
2
+ "name": "layout-blocks",
3
+ "note": "Khối bố cục (1.2): cột, nhóm, hộp lưu ý, nút, nhúng — ép kiểu (\"60\" → 60, \"false\" → false), kẹp độ rộng cột ≤ 100, bỏ giá trị ngoài danh sách (tone \"loud\", align \"middle\") và null",
4
+ "input": {
5
+ "version": 1,
6
+ "blocks": [
7
+ {
8
+ "id": "main",
9
+ "type": "richtext",
10
+ "data": {
11
+ "type": "doc",
12
+ "content": [
13
+ {
14
+ "type": "columns",
15
+ "attrs": {
16
+ "verticalAlign": "center",
17
+ "stack": "false"
18
+ },
19
+ "content": [
20
+ {
21
+ "type": "column",
22
+ "attrs": {
23
+ "width": "60"
24
+ },
25
+ "content": [
26
+ {
27
+ "type": "paragraph",
28
+ "content": [
29
+ {
30
+ "type": "text",
31
+ "text": "Cột trái"
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ "type": "button",
37
+ "attrs": {
38
+ "text": "Mua ngay",
39
+ "href": "https://shop.vn/a",
40
+ "variant": "outline",
41
+ "align": "middle",
42
+ "target": null
43
+ }
44
+ }
45
+ ]
46
+ },
47
+ {
48
+ "type": "column",
49
+ "attrs": {
50
+ "width": 150
51
+ },
52
+ "content": [
53
+ {
54
+ "type": "callout",
55
+ "attrs": {
56
+ "tone": "loud",
57
+ "title": "Lưu ý"
58
+ },
59
+ "content": [
60
+ {
61
+ "type": "paragraph",
62
+ "content": [
63
+ {
64
+ "type": "text",
65
+ "text": "Hàng có hạn"
66
+ }
67
+ ]
68
+ }
69
+ ]
70
+ }
71
+ ]
72
+ }
73
+ ]
74
+ },
75
+ {
76
+ "type": "group",
77
+ "attrs": {
78
+ "background": "#f5f5f4",
79
+ "padding": "large",
80
+ "textColor": null
81
+ },
82
+ "content": [
83
+ {
84
+ "type": "paragraph",
85
+ "content": [
86
+ {
87
+ "type": "text",
88
+ "text": "Trong nhóm"
89
+ }
90
+ ]
91
+ },
92
+ {
93
+ "type": "embed",
94
+ "attrs": {
95
+ "url": "https://vimeo.com/76979871",
96
+ "caption": "Video giới thiệu"
97
+ }
98
+ }
99
+ ]
100
+ },
101
+ {
102
+ "type": "callout",
103
+ "attrs": {
104
+ "tone": "warning"
105
+ },
106
+ "content": [
107
+ {
108
+ "type": "paragraph",
109
+ "content": [
110
+ {
111
+ "type": "text",
112
+ "text": "Cẩn thận"
113
+ }
114
+ ]
115
+ }
116
+ ]
117
+ }
118
+ ]
119
+ }
120
+ }
121
+ ]
122
+ },
123
+ "expected": {
124
+ "version": 1,
125
+ "blocks": [
126
+ {
127
+ "id": "main",
128
+ "type": "richtext",
129
+ "data": {
130
+ "type": "doc",
131
+ "content": [
132
+ {
133
+ "type": "columns",
134
+ "attrs": {
135
+ "verticalAlign": "center",
136
+ "stack": false
137
+ },
138
+ "content": [
139
+ {
140
+ "type": "column",
141
+ "attrs": {
142
+ "width": 60
143
+ },
144
+ "content": [
145
+ {
146
+ "type": "paragraph",
147
+ "content": [
148
+ {
149
+ "type": "text",
150
+ "text": "Cột trái"
151
+ }
152
+ ]
153
+ },
154
+ {
155
+ "type": "button",
156
+ "attrs": {
157
+ "text": "Mua ngay",
158
+ "href": "https://shop.vn/a",
159
+ "variant": "outline"
160
+ }
161
+ }
162
+ ]
163
+ },
164
+ {
165
+ "type": "column",
166
+ "attrs": {
167
+ "width": 100
168
+ },
169
+ "content": [
170
+ {
171
+ "type": "callout",
172
+ "attrs": {
173
+ "title": "Lưu ý"
174
+ },
175
+ "content": [
176
+ {
177
+ "type": "paragraph",
178
+ "content": [
179
+ {
180
+ "type": "text",
181
+ "text": "Hàng có hạn"
182
+ }
183
+ ]
184
+ }
185
+ ]
186
+ }
187
+ ]
188
+ }
189
+ ]
190
+ },
191
+ {
192
+ "type": "group",
193
+ "attrs": {
194
+ "background": "#f5f5f4",
195
+ "padding": "large"
196
+ },
197
+ "content": [
198
+ {
199
+ "type": "paragraph",
200
+ "content": [
201
+ {
202
+ "type": "text",
203
+ "text": "Trong nhóm"
204
+ }
205
+ ]
206
+ },
207
+ {
208
+ "type": "embed",
209
+ "attrs": {
210
+ "url": "https://vimeo.com/76979871",
211
+ "caption": "Video giới thiệu"
212
+ }
213
+ }
214
+ ]
215
+ },
216
+ {
217
+ "type": "callout",
218
+ "attrs": {
219
+ "tone": "warning"
220
+ },
221
+ "content": [
222
+ {
223
+ "type": "paragraph",
224
+ "content": [
225
+ {
226
+ "type": "text",
227
+ "text": "Cẩn thận"
228
+ }
229
+ ]
230
+ }
231
+ ]
232
+ }
233
+ ]
234
+ }
235
+ }
236
+ ]
237
+ }
238
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "legacy-html-string",
3
+ "note": "Nội dung nhập từ hệ thống cũ (chuỗi HTML)",
4
+ "input": "<p>Cũ <b>đậm</b></p>",
5
+ "expected": {
6
+ "version": 1,
7
+ "blocks": [
8
+ {
9
+ "id": "main",
10
+ "type": "html",
11
+ "data": {
12
+ "html": "<p>Cũ <b>đậm</b></p>"
13
+ }
14
+ }
15
+ ]
16
+ }
17
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "legacy-tiptap-doc",
3
+ "note": "Bài lưu trước định dạng {version, blocks}: cây TipTap thuần",
4
+ "input": {
5
+ "type": "doc",
6
+ "content": [
7
+ {
8
+ "type": "paragraph",
9
+ "content": [
10
+ {
11
+ "type": "text",
12
+ "text": "Xin chào"
13
+ }
14
+ ]
15
+ }
16
+ ]
17
+ },
18
+ "expected": {
19
+ "version": 1,
20
+ "blocks": [
21
+ {
22
+ "id": "main",
23
+ "type": "richtext",
24
+ "data": {
25
+ "type": "doc",
26
+ "content": [
27
+ {
28
+ "type": "paragraph",
29
+ "content": [
30
+ {
31
+ "type": "text",
32
+ "text": "Xin chào"
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
38
+ }
39
+ ]
40
+ }
41
+ }
@@ -0,0 +1,155 @@
1
+ {
2
+ "name": "plugin-blocks-preserved",
3
+ "note": "Khối/nút của plugin (tên có namespace slug/tên; kể cả plugin đã tắt): giữ nguyên dữ liệu, chỉ bỏ thuộc tính null",
4
+ "input": {
5
+ "version": 1,
6
+ "blocks": [
7
+ {
8
+ "id": "main",
9
+ "type": "richtext",
10
+ "data": {
11
+ "type": "doc",
12
+ "content": [
13
+ {
14
+ "type": "paragraph",
15
+ "content": [
16
+ {
17
+ "type": "text",
18
+ "text": "Trước"
19
+ }
20
+ ]
21
+ },
22
+ {
23
+ "type": "demo/callout",
24
+ "attrs": {
25
+ "tone": "warning",
26
+ "title": null,
27
+ "extra": {
28
+ "a": 1
29
+ }
30
+ },
31
+ "content": [
32
+ {
33
+ "type": "paragraph",
34
+ "content": [
35
+ {
36
+ "type": "text",
37
+ "text": "Lưu ý"
38
+ }
39
+ ]
40
+ }
41
+ ]
42
+ },
43
+ {
44
+ "type": "product-card",
45
+ "attrs": {
46
+ "productId": 42
47
+ }
48
+ },
49
+ {
50
+ "type": "paragraph",
51
+ "content": [
52
+ {
53
+ "type": "text",
54
+ "text": "Sau"
55
+ }
56
+ ]
57
+ }
58
+ ]
59
+ }
60
+ },
61
+ {
62
+ "id": "b2",
63
+ "type": "ecommerce/products",
64
+ "data": {
65
+ "ids": [
66
+ 1,
67
+ 2,
68
+ 3
69
+ ],
70
+ "layout": "grid"
71
+ }
72
+ },
73
+ {
74
+ "id": "b3",
75
+ "type": "legacy-plugin",
76
+ "data": null
77
+ }
78
+ ]
79
+ },
80
+ "expected": {
81
+ "version": 1,
82
+ "blocks": [
83
+ {
84
+ "id": "main",
85
+ "type": "richtext",
86
+ "data": {
87
+ "type": "doc",
88
+ "content": [
89
+ {
90
+ "type": "paragraph",
91
+ "content": [
92
+ {
93
+ "type": "text",
94
+ "text": "Trước"
95
+ }
96
+ ]
97
+ },
98
+ {
99
+ "type": "demo/callout",
100
+ "attrs": {
101
+ "tone": "warning",
102
+ "extra": {
103
+ "a": 1
104
+ }
105
+ },
106
+ "content": [
107
+ {
108
+ "type": "paragraph",
109
+ "content": [
110
+ {
111
+ "type": "text",
112
+ "text": "Lưu ý"
113
+ }
114
+ ]
115
+ }
116
+ ]
117
+ },
118
+ {
119
+ "type": "product-card",
120
+ "attrs": {
121
+ "productId": 42
122
+ }
123
+ },
124
+ {
125
+ "type": "paragraph",
126
+ "content": [
127
+ {
128
+ "type": "text",
129
+ "text": "Sau"
130
+ }
131
+ ]
132
+ }
133
+ ]
134
+ }
135
+ },
136
+ {
137
+ "id": "b2",
138
+ "type": "ecommerce/products",
139
+ "data": {
140
+ "ids": [
141
+ 1,
142
+ 2,
143
+ 3
144
+ ],
145
+ "layout": "grid"
146
+ }
147
+ },
148
+ {
149
+ "id": "b3",
150
+ "type": "legacy-plugin",
151
+ "data": null
152
+ }
153
+ ]
154
+ }
155
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "style-layout-effects",
3
+ "note": "Kiểu dáng 1.15: bố cục flex/grid (theo khổ), nền chuyển màu đã kiểm, bóng, tỉ lệ, ghim, hover — giá trị lạ và CSS chèn bị bỏ; dạng gọn thành theo khổ",
4
+ "input": {
5
+ "version": 1,
6
+ "blocks": [{ "id": "main", "type": "richtext", "data": { "type": "doc", "content": [
7
+ { "type": "group", "attrs": { "style": {
8
+ "layout": { "type": "flex", "direction": { "base": "row", "mobile": "column" }, "justify": "between", "align": "middle", "wrap": "yes", "columns": 3 },
9
+ "gradient": "linear-gradient(135deg,#1a597b 0%, rgb(242, 98, 81) 100%)",
10
+ "shadow": "lg",
11
+ "hover": { "color": { "background": "primary", "text": "red;}" }, "lift": true, "shadow": "0 0 1px red" }
12
+ } }, "content": [
13
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Hàng ngang" }] }
14
+ ] },
15
+ { "type": "group", "attrs": { "style": {
16
+ "layout": { "type": "grid", "columns": { "base": "3", "tablet": 2, "mobile": 0 }, "minColumnWidth": "14rem", "direction": "row" },
17
+ "gradient": "url(javascript:alert(1))",
18
+ "aspectRatio": "16/9",
19
+ "position": { "type": "sticky", "top": "1e9px" }
20
+ } }, "content": [
21
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Lưới" }] }
22
+ ] },
23
+ { "type": "image", "attrs": { "src": "https://a.vn/a.png", "style": { "aspectRatio": "7/3", "shadow": "none", "layout": "grid" } } }
24
+ ] } }]
25
+ },
26
+ "expected": {
27
+ "version": 1,
28
+ "blocks": [{ "id": "main", "type": "richtext", "data": { "type": "doc", "content": [
29
+ { "type": "group", "attrs": { "style": {
30
+ "layout": { "type": "flex", "direction": { "base": "row", "mobile": "column" }, "justify": { "base": "between" } },
31
+ "gradient": "linear-gradient(135deg, #1a597b 0%, rgb(242, 98, 81) 100%)",
32
+ "shadow": "lg",
33
+ "hover": { "color": { "background": "primary" }, "lift": true }
34
+ } }, "content": [
35
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Hàng ngang" }] }
36
+ ] },
37
+ { "type": "group", "attrs": { "style": {
38
+ "layout": { "type": "grid", "columns": { "base": 3, "tablet": 2 }, "minColumnWidth": "14rem" },
39
+ "aspectRatio": "16/9",
40
+ "position": { "type": "sticky" }
41
+ } }, "content": [
42
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Lưới" }] }
43
+ ] },
44
+ { "type": "image", "attrs": { "src": "https://a.vn/a.png", "style": { "shadow": "none" } } }
45
+ ] } }]
46
+ }
47
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "synced-pattern",
3
+ "note": "Mẫu đồng bộ (1.13): ref ép kiểu số (\"12\" → 12); ref sai kiểu / null thì bỏ thuộc tính (khối giữ nguyên, website không vẽ)",
4
+ "input": {
5
+ "version": 1,
6
+ "blocks": [
7
+ {
8
+ "id": "main",
9
+ "type": "richtext",
10
+ "data": {
11
+ "type": "doc",
12
+ "content": [
13
+ {
14
+ "type": "syncedPattern",
15
+ "attrs": {
16
+ "ref": "12"
17
+ }
18
+ },
19
+ {
20
+ "type": "paragraph",
21
+ "content": [
22
+ {
23
+ "type": "text",
24
+ "text": "Giữa"
25
+ }
26
+ ]
27
+ },
28
+ {
29
+ "type": "syncedPattern",
30
+ "attrs": {
31
+ "ref": "abc"
32
+ }
33
+ },
34
+ {
35
+ "type": "syncedPattern",
36
+ "attrs": {
37
+ "ref": null
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ }
43
+ ]
44
+ },
45
+ "expected": {
46
+ "version": 1,
47
+ "blocks": [
48
+ {
49
+ "id": "main",
50
+ "type": "richtext",
51
+ "data": {
52
+ "type": "doc",
53
+ "content": [
54
+ {
55
+ "type": "syncedPattern",
56
+ "attrs": {
57
+ "ref": 12
58
+ }
59
+ },
60
+ {
61
+ "type": "paragraph",
62
+ "content": [
63
+ {
64
+ "type": "text",
65
+ "text": "Giữa"
66
+ }
67
+ ]
68
+ },
69
+ {
70
+ "type": "syncedPattern"
71
+ },
72
+ {
73
+ "type": "syncedPattern"
74
+ }
75
+ ]
76
+ }
77
+ }
78
+ ]
79
+ }
80
+ }
package/package.json CHANGED
@@ -1,6 +1,46 @@
1
1
  {
2
2
  "name": "@ecomcx/ecomweb-content",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.15.0",
4
+ "description": "Định dạng nội dung của Ecomweb CMS: kiểu dữ liệu, schema khối lõi, chuẩn hoá, nâng phiên bản và bộ fixture hợp đồng — dùng chung cho trình soạn, website và máy chủ, không phụ thuộc trình soạn nào.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./style.css": "./style.css",
15
+ "./fixtures/*": "./fixtures/*",
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "fixtures",
21
+ "style.css",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "sideEffects": [
26
+ "*.css"
27
+ ],
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/Ecomcx-Jsc/ecomweb-content.git"
31
+ },
32
+ "homepage": "https://github.com/Ecomcx-Jsc/ecomweb-content#readme",
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "provenance": true
36
+ },
37
+ "scripts": {
38
+ "build": "tsc -p tsconfig.json",
39
+ "check-dist": "node scripts/check-dist.mjs",
40
+ "test": "tsc -p tsconfig.test.json && node --test \".test-build/test/*.test.js\" && node scripts/check-dist.mjs"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "22.19.1",
44
+ "typescript": "5.9.3"
45
+ }
46
+ }