@blocklet/pages-kit-block-studio 0.0.17 → 0.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/lib/cjs/constants/index.js +12 -1
- package/lib/cjs/constants/new-block-template/@metadata.json +59 -0
- package/lib/cjs/constants/new-block-template/index.js +55 -0
- package/lib/cjs/constants/new-block-template/index.tsx +89 -0
- package/lib/cjs/middlewares/init-block-studio-router.js +47 -14
- package/lib/cjs/middlewares/init-resource-router.js +5 -1
- package/lib/cjs/plugins/vite-plugin-block-studio.js +29 -30
- package/lib/cjs/plugins/vite-plugin-html-transform.js +42 -2
- package/lib/cjs/tsconfig.tsbuildinfo +1 -1
- package/lib/cjs/utils/generate-wrapper-code.js +21 -25
- package/lib/cjs/utils/helper.js +39 -12
- package/lib/esm/constants/index.js +8 -0
- package/lib/esm/constants/new-block-template/@metadata.json +59 -0
- package/lib/esm/constants/new-block-template/index.js +50 -0
- package/lib/esm/constants/new-block-template/index.tsx +89 -0
- package/lib/esm/middlewares/init-block-studio-router.js +46 -13
- package/lib/esm/middlewares/init-resource-router.js +5 -1
- package/lib/esm/plugins/vite-plugin-block-studio.js +30 -31
- package/lib/esm/plugins/vite-plugin-html-transform.js +42 -4
- package/lib/esm/tsconfig.tsbuildinfo +1 -1
- package/lib/esm/utils/generate-wrapper-code.js +21 -25
- package/lib/esm/utils/helper.js +28 -6
- package/lib/types/constants/index.d.ts +7 -0
- package/lib/types/constants/new-block-template/index.d.ts +13 -0
- package/lib/types/plugins/vite-plugin-html-transform.d.ts +14 -0
- package/lib/types/tsconfig.tsbuildinfo +1 -1
- package/lib/types/utils/helper.d.ts +3 -4
- package/package.json +17 -5
- package/tsconfig.json +3 -1
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MEDIA_KIT_RESOURCE_TYPE = exports.MEDIA_KIT_DID = exports.PAGES_KIT_BLOCK_STUDIO_RESOURCE_TYPE = exports.PAGES_KIT_BLOCK_STUDIO_DID = exports.PAGES_KIT_RESOURCE_TYPE = exports.PAGES_KIT_DID = void 0;
|
|
6
|
+
exports.DEFAULT_BLOCK_ENTRY_FILES_PATTERN = exports.NANOID_LENGTH = exports.PREVIEW_IMAGE_DIR = exports.METADATA_FILE_NAME = exports.libDir = exports.NEW_BLOCK_TEMPLATE_METADATA_PATH = exports.NEW_BLOCK_TEMPLATE_PATH = exports.MEDIA_KIT_RESOURCE_TYPE = exports.MEDIA_KIT_DID = exports.PAGES_KIT_BLOCK_STUDIO_RESOURCE_TYPE = exports.PAGES_KIT_BLOCK_STUDIO_DID = exports.PAGES_KIT_RESOURCE_TYPE = exports.PAGES_KIT_DID = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
4
8
|
exports.PAGES_KIT_DID = 'z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o';
|
|
5
9
|
exports.PAGES_KIT_RESOURCE_TYPE = 'page';
|
|
6
10
|
exports.PAGES_KIT_BLOCK_STUDIO_DID = 'z2qa7rr3eUyVnWp2PCxEVARuUfLFh6cE5V2xV';
|
|
7
11
|
exports.PAGES_KIT_BLOCK_STUDIO_RESOURCE_TYPE = 'page';
|
|
8
12
|
exports.MEDIA_KIT_DID = 'z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9';
|
|
9
13
|
exports.MEDIA_KIT_RESOURCE_TYPE = 'imgpack';
|
|
14
|
+
exports.NEW_BLOCK_TEMPLATE_PATH = path_1.default.join(__dirname, 'new-block-template', 'index.tsx');
|
|
15
|
+
exports.NEW_BLOCK_TEMPLATE_METADATA_PATH = path_1.default.join(__dirname, 'new-block-template', '@metadata.json');
|
|
16
|
+
exports.libDir = 'lib';
|
|
17
|
+
exports.METADATA_FILE_NAME = '@metadata.json';
|
|
18
|
+
exports.PREVIEW_IMAGE_DIR = '@preview-images';
|
|
19
|
+
exports.NANOID_LENGTH = 16;
|
|
20
|
+
exports.DEFAULT_BLOCK_ENTRY_FILES_PATTERN = 'src/**/index.{ts,tsx,html}';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"properties": {
|
|
3
|
+
"gs1rn5jmxfvpxptx": {
|
|
4
|
+
"index": 0,
|
|
5
|
+
"data": {
|
|
6
|
+
"id": "gs1rn5jmxfvpxptx",
|
|
7
|
+
"key": "title",
|
|
8
|
+
"locales": {
|
|
9
|
+
"zh": {
|
|
10
|
+
"name": "Title"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"9ajrz12ik7esfk1z": {
|
|
16
|
+
"index": 1,
|
|
17
|
+
"data": {
|
|
18
|
+
"id": "9ajrz12ik7esfk1z",
|
|
19
|
+
"key": "description",
|
|
20
|
+
"locales": {
|
|
21
|
+
"zh": {
|
|
22
|
+
"name": "Description",
|
|
23
|
+
"defaultValue": "Welcome to Pages Kit Block Studio"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"3ckcfvf6b7zyskk8": {
|
|
29
|
+
"index": 2,
|
|
30
|
+
"data": {
|
|
31
|
+
"id": "3ckcfvf6b7zyskk8",
|
|
32
|
+
"key": "logo",
|
|
33
|
+
"type": "url",
|
|
34
|
+
"locales": {
|
|
35
|
+
"zh": {
|
|
36
|
+
"defaultValue": {
|
|
37
|
+
"url": "/.well-known/service/blocklet/logo?imageFilter=convert&f=png&h=80",
|
|
38
|
+
"mediaKitUrl": "/.well-known/service/blocklet/logo?imageFilter=convert&f=png&h=80"
|
|
39
|
+
},
|
|
40
|
+
"name": "Logo"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"x3lqht8ikble1itx": {
|
|
46
|
+
"index": 3,
|
|
47
|
+
"data": {
|
|
48
|
+
"id": "x3lqht8ikble1itx",
|
|
49
|
+
"key": "copyright",
|
|
50
|
+
"locales": {
|
|
51
|
+
"zh": {
|
|
52
|
+
"defaultValue": "Powered by Pages Kit Block Studio"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"visible": false
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.EditComponent = void 0;
|
|
15
|
+
exports.default = HelloWorld;
|
|
16
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
17
|
+
// default export
|
|
18
|
+
function HelloWorld({ title = 'Hello World', logo, description, copyright }) {
|
|
19
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
20
|
+
display: 'flex',
|
|
21
|
+
flexDirection: 'column',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
padding: '16px 0',
|
|
24
|
+
}, children: [title && (0, jsx_runtime_1.jsx)("h1", { children: title }), logo && ((0, jsx_runtime_1.jsx)("img", { src: typeof logo === 'object' ? logo.url : logo, alt: "logo", style: {
|
|
25
|
+
margin: '16px 0',
|
|
26
|
+
maxWidth: '200px',
|
|
27
|
+
} })), description && ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
28
|
+
color: '#666',
|
|
29
|
+
marginTop: '8px',
|
|
30
|
+
}, children: description })), copyright && ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
31
|
+
color: '#999',
|
|
32
|
+
fontSize: '12px',
|
|
33
|
+
marginTop: '16px',
|
|
34
|
+
}, children: copyright }))] }));
|
|
35
|
+
}
|
|
36
|
+
// export edit component
|
|
37
|
+
const EditComponent = (_a) => {
|
|
38
|
+
var { onChange } = _a, props = __rest(_a, ["onChange"]);
|
|
39
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: '16px' }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
|
|
40
|
+
fontSize: '14px',
|
|
41
|
+
fontWeight: 500,
|
|
42
|
+
color: '#333',
|
|
43
|
+
padding: '8px 0',
|
|
44
|
+
borderBottom: '1px solid #eee',
|
|
45
|
+
}, children: "Footer Parameters" }), (0, jsx_runtime_1.jsx)("input", { id: "copyright-input", type: "text", style: {
|
|
46
|
+
width: '100%',
|
|
47
|
+
padding: '8px 12px',
|
|
48
|
+
border: '1px solid #ddd',
|
|
49
|
+
borderRadius: '4px',
|
|
50
|
+
fontSize: '14px',
|
|
51
|
+
transition: 'border-color 0.3s',
|
|
52
|
+
outline: 'none',
|
|
53
|
+
}, value: props.copyright || '', onChange: (e) => onChange === null || onChange === void 0 ? void 0 : onChange({ copyright: e.target.value }), placeholder: "Please Input Copyright" })] }));
|
|
54
|
+
};
|
|
55
|
+
exports.EditComponent = EditComponent;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface HelloWorldProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
logo?: string | { url: string };
|
|
6
|
+
description?: string;
|
|
7
|
+
copyright?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// default export
|
|
11
|
+
export default function HelloWorld({ title = 'Hello World', logo, description, copyright }: HelloWorldProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
style={{
|
|
15
|
+
display: 'flex',
|
|
16
|
+
flexDirection: 'column',
|
|
17
|
+
alignItems: 'center',
|
|
18
|
+
padding: '16px 0',
|
|
19
|
+
}}>
|
|
20
|
+
{title && <h1>{title}</h1>}
|
|
21
|
+
{logo && (
|
|
22
|
+
<img
|
|
23
|
+
src={typeof logo === 'object' ? logo.url : logo}
|
|
24
|
+
alt="logo"
|
|
25
|
+
style={{
|
|
26
|
+
margin: '16px 0',
|
|
27
|
+
maxWidth: '200px',
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
)}
|
|
31
|
+
{description && (
|
|
32
|
+
<div
|
|
33
|
+
style={{
|
|
34
|
+
color: '#666',
|
|
35
|
+
marginTop: '8px',
|
|
36
|
+
}}>
|
|
37
|
+
{description}
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
40
|
+
{copyright && (
|
|
41
|
+
<div
|
|
42
|
+
style={{
|
|
43
|
+
color: '#999',
|
|
44
|
+
fontSize: '12px',
|
|
45
|
+
marginTop: '16px',
|
|
46
|
+
}}>
|
|
47
|
+
{copyright}
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// export edit component
|
|
55
|
+
export const EditComponent: React.FC<HelloWorldProps & { onChange?: (value: HelloWorldProps) => void }> = ({
|
|
56
|
+
onChange,
|
|
57
|
+
...props
|
|
58
|
+
}) => {
|
|
59
|
+
return (
|
|
60
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
61
|
+
<div
|
|
62
|
+
style={{
|
|
63
|
+
fontSize: '14px',
|
|
64
|
+
fontWeight: 500,
|
|
65
|
+
color: '#333',
|
|
66
|
+
padding: '8px 0',
|
|
67
|
+
borderBottom: '1px solid #eee',
|
|
68
|
+
}}>
|
|
69
|
+
Footer Parameters
|
|
70
|
+
</div>
|
|
71
|
+
<input
|
|
72
|
+
id="copyright-input"
|
|
73
|
+
type="text"
|
|
74
|
+
style={{
|
|
75
|
+
width: '100%',
|
|
76
|
+
padding: '8px 12px',
|
|
77
|
+
border: '1px solid #ddd',
|
|
78
|
+
borderRadius: '4px',
|
|
79
|
+
fontSize: '14px',
|
|
80
|
+
transition: 'border-color 0.3s',
|
|
81
|
+
outline: 'none',
|
|
82
|
+
}}
|
|
83
|
+
value={props.copyright || ''}
|
|
84
|
+
onChange={(e) => onChange?.({ copyright: e.target.value })}
|
|
85
|
+
placeholder="Please Input Copyright"
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
@@ -16,9 +16,8 @@ exports.initBlockStudioRouter = void 0;
|
|
|
16
16
|
const express_1 = require("express");
|
|
17
17
|
const fs_1 = __importDefault(require("fs"));
|
|
18
18
|
const lodash_1 = require("lodash");
|
|
19
|
-
const lodash_2 = require("lodash");
|
|
20
|
-
const lodash_3 = require("lodash");
|
|
21
19
|
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const constants_1 = require("../constants");
|
|
22
21
|
const helper_1 = require("../utils/helper");
|
|
23
22
|
exports.initBlockStudioRouter = (0, express_1.Router)();
|
|
24
23
|
const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.svg'];
|
|
@@ -45,11 +44,6 @@ exports.initBlockStudioRouter.get('/', (req, res) => __awaiter(void 0, void 0, v
|
|
|
45
44
|
return fs_1.default.createReadStream(filePath).pipe(res);
|
|
46
45
|
}
|
|
47
46
|
const metadata = (0, helper_1.initializeMetadata)(filePath);
|
|
48
|
-
const code = fs_1.default.readFileSync(filePath, 'utf8');
|
|
49
|
-
if (code) {
|
|
50
|
-
(0, lodash_3.set)(metadata, 'renderer.script', code);
|
|
51
|
-
(0, lodash_3.set)(metadata, 'renderer.type', 'react-component');
|
|
52
|
-
}
|
|
53
47
|
return res.json(metadata);
|
|
54
48
|
}
|
|
55
49
|
catch (error) {
|
|
@@ -74,8 +68,6 @@ exports.initBlockStudioRouter.post('/', (req, res) => __awaiter(void 0, void 0,
|
|
|
74
68
|
}
|
|
75
69
|
const currentMetadata = (0, helper_1.initializeMetadata)(filePath);
|
|
76
70
|
const mergedContent = Object.assign(Object.assign({}, currentMetadata), content);
|
|
77
|
-
// remove renderer
|
|
78
|
-
delete mergedContent.renderer;
|
|
79
71
|
if ((0, lodash_1.isEqual)(currentMetadata, mergedContent)) {
|
|
80
72
|
return res.json({ success: true, content: mergedContent, message: 'No changes' });
|
|
81
73
|
}
|
|
@@ -98,15 +90,56 @@ exports.initBlockStudioRouter.post('/', (req, res) => __awaiter(void 0, void 0,
|
|
|
98
90
|
return res.status(500).json({ error: 'Failed to write file' });
|
|
99
91
|
}
|
|
100
92
|
}));
|
|
93
|
+
exports.initBlockStudioRouter.post('/create', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
+
if (!helper_1.isDev) {
|
|
95
|
+
return res.status(403).json({ error: 'Only available in development mode' });
|
|
96
|
+
}
|
|
97
|
+
const { name, description } = req.body;
|
|
98
|
+
if (!name) {
|
|
99
|
+
return res.status(400).json({ error: 'Name is required' });
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const pattern = (0, helper_1.getBlockEntryFilesPattern)();
|
|
103
|
+
const baseDir = path_1.default.dirname(pattern.replace(/\*\*?/g, ''));
|
|
104
|
+
const blockDir = path_1.default.join(baseDir, name);
|
|
105
|
+
const metadataPath = path_1.default.join(blockDir, constants_1.METADATA_FILE_NAME);
|
|
106
|
+
const indexPath = path_1.default.join(blockDir, 'index.tsx');
|
|
107
|
+
// Check if block already exists
|
|
108
|
+
if (fs_1.default.existsSync(blockDir)) {
|
|
109
|
+
return res.status(409).json({ error: 'Block already exists' });
|
|
110
|
+
}
|
|
111
|
+
// Create block directory
|
|
112
|
+
fs_1.default.mkdirSync(blockDir, { recursive: true });
|
|
113
|
+
// Initialize metadata
|
|
114
|
+
let metadata = (0, helper_1.initializeMetadata)(metadataPath);
|
|
115
|
+
metadata.name = name;
|
|
116
|
+
metadata.description = description || '';
|
|
117
|
+
metadata.createdAt = new Date().toISOString();
|
|
118
|
+
metadata.updatedAt = new Date().toISOString();
|
|
119
|
+
// get template metadata from @metadata.json
|
|
120
|
+
const metadataContent = fs_1.default.readFileSync(constants_1.NEW_BLOCK_TEMPLATE_METADATA_PATH, 'utf-8');
|
|
121
|
+
metadata = Object.assign(Object.assign({}, metadata), (0, helper_1.safeParse)(metadataContent));
|
|
122
|
+
// Write metadata file
|
|
123
|
+
fs_1.default.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
124
|
+
// Copy template file to index.tsx
|
|
125
|
+
const templateContent = fs_1.default.readFileSync(constants_1.NEW_BLOCK_TEMPLATE_PATH, 'utf-8');
|
|
126
|
+
fs_1.default.writeFileSync(indexPath, templateContent);
|
|
127
|
+
return res.json({ success: true, metadata });
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('Failed to create block:', error);
|
|
131
|
+
return res.status(500).json({ error: 'Failed to create block' });
|
|
132
|
+
}
|
|
133
|
+
}));
|
|
101
134
|
exports.initBlockStudioRouter.get('/all', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
135
|
const { withBlockletData = true } = req.query;
|
|
103
136
|
const allBlocks = yield (0, helper_1.findComponentFiles)();
|
|
104
137
|
// get code to metadata
|
|
105
138
|
const allBlocksWithCode = allBlocks.map((block) => {
|
|
106
|
-
const code =
|
|
139
|
+
const code = (0, helper_1.getBlockCode)(block.fullPath);
|
|
107
140
|
if (code) {
|
|
108
|
-
(0,
|
|
109
|
-
(0,
|
|
141
|
+
(0, lodash_1.set)(block.metadata, 'renderer.script', code);
|
|
142
|
+
(0, lodash_1.set)(block.metadata, 'renderer.type', 'react-component');
|
|
110
143
|
}
|
|
111
144
|
return block;
|
|
112
145
|
});
|
|
@@ -123,8 +156,8 @@ exports.initBlockStudioRouter.get('/all', (req, res) => __awaiter(void 0, void 0
|
|
|
123
156
|
};
|
|
124
157
|
return item;
|
|
125
158
|
});
|
|
126
|
-
return res.json((0,
|
|
159
|
+
return res.json((0, lodash_1.keyBy)(allBlocksWithBlockletData, 'data.id'));
|
|
127
160
|
}
|
|
128
|
-
res.json((0,
|
|
161
|
+
return res.json((0, lodash_1.keyBy)(allBlocksWithCode, 'id'));
|
|
129
162
|
}));
|
|
130
163
|
exports.default = exports.initBlockStudioRouter;
|
|
@@ -140,7 +140,7 @@ exports.initResourceRouter.post('/', (req, res) => __awaiter(void 0, void 0, voi
|
|
|
140
140
|
const buildProcess = (0, child_process_1.spawn)('pnpm', ['run', 'build-lib'], {
|
|
141
141
|
stdio: 'inherit',
|
|
142
142
|
shell: true,
|
|
143
|
-
env: Object.assign(Object.assign({}, process.env), { FORCE_COLOR: '1', BLOCK_FILTER: componentIds.join(',') }),
|
|
143
|
+
env: Object.assign(Object.assign({}, process.env), { FORCE_COLOR: '1', BLOCK_FILTER: componentIds.join(','), NODE_OPTIONS: '--max_old_space_size=16384' }),
|
|
144
144
|
});
|
|
145
145
|
yield new Promise((resolve, reject) => {
|
|
146
146
|
buildProcess.on('close', (code) => {
|
|
@@ -149,6 +149,10 @@ exports.initResourceRouter.post('/', (req, res) => __awaiter(void 0, void 0, voi
|
|
|
149
149
|
else
|
|
150
150
|
reject(new Error(`Build process exited with code ${code}`));
|
|
151
151
|
});
|
|
152
|
+
buildProcess.on('error', (error) => {
|
|
153
|
+
console.error('Build process error:', error);
|
|
154
|
+
reject(error);
|
|
155
|
+
});
|
|
152
156
|
});
|
|
153
157
|
const dir = getExportDir(projectId, releaseId);
|
|
154
158
|
fs_1.default.rmSync(dir, { recursive: true, force: true });
|
|
@@ -47,6 +47,7 @@ exports.initBlockStudioPlugins = initBlockStudioPlugins;
|
|
|
47
47
|
// import typescript from '@rollup/plugin-typescript';
|
|
48
48
|
const fs_1 = require("fs");
|
|
49
49
|
const path = __importStar(require("path"));
|
|
50
|
+
const ufo_1 = require("ufo");
|
|
50
51
|
const vite_plugin_react_pages_1 = __importStar(require("vite-plugin-react-pages"));
|
|
51
52
|
const helper_1 = require("../utils/helper");
|
|
52
53
|
const vite_plugin_html_transform_1 = require("./vite-plugin-html-transform");
|
|
@@ -108,18 +109,13 @@ function initBlockStudioPlugins(options) {
|
|
|
108
109
|
formats: ['es', !multiMode ? 'umd' : 'cjs'],
|
|
109
110
|
fileName: (format, entryName) => `${format}/${entryName}.js`,
|
|
110
111
|
}, rollupOptions: {
|
|
111
|
-
external:
|
|
112
|
-
'react',
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// '@emotion/react',
|
|
119
|
-
// '@emotion/styled',
|
|
120
|
-
'@arcblock/ux',
|
|
121
|
-
'@arcblock/did-connect',
|
|
122
|
-
],
|
|
112
|
+
external: (id) => {
|
|
113
|
+
const skip = ['react', 'crypto'];
|
|
114
|
+
if (skip.some((s) => id === s)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
},
|
|
123
119
|
output: {
|
|
124
120
|
chunkFileNames: () => {
|
|
125
121
|
return '[format]/_chunks/[name]-[hash].js';
|
|
@@ -127,22 +123,13 @@ function initBlockStudioPlugins(options) {
|
|
|
127
123
|
// 为所有外部依赖提供全局变量
|
|
128
124
|
globals: {
|
|
129
125
|
react: 'React',
|
|
130
|
-
'react-dom': 'ReactDOM',
|
|
131
|
-
'react-is': 'ReactIs',
|
|
132
|
-
'react-router-dom': 'ReactRouterDOM',
|
|
133
|
-
'react/jsx-runtime': 'ReactJsxRuntime',
|
|
134
|
-
// '@emotion/react': 'emotionReact',
|
|
135
|
-
// '@emotion/styled': 'emotionStyled',
|
|
136
|
-
'@mui/material': 'MUI',
|
|
137
|
-
'@arcblock/ux': 'ArcBlockUX',
|
|
138
|
-
'@arcblock/did-connect': 'ArcBlockDidConnect',
|
|
139
126
|
},
|
|
140
127
|
paths: {
|
|
141
|
-
|
|
142
|
-
|
|
128
|
+
// Redirect 'react' imports to '@blocklet/pages-kit/builtin/react'
|
|
129
|
+
react: '@blocklet/pages-kit/builtin/react',
|
|
143
130
|
},
|
|
144
131
|
// 确保正确处理命名导出和默认导出
|
|
145
|
-
|
|
132
|
+
interop: 'auto',
|
|
146
133
|
},
|
|
147
134
|
} }, _config === null || _config === void 0 ? void 0 : _config.build),
|
|
148
135
|
};
|
|
@@ -162,20 +149,23 @@ function initBlockStudioPlugins(options) {
|
|
|
162
149
|
const pageId = `/${blockName}`;
|
|
163
150
|
const dirPath = path.dirname(filePath);
|
|
164
151
|
const metadataPath = path.join(dirPath, '@metadata.json');
|
|
152
|
+
const dataPath = isHtml ? `${vite_plugin_html_transform_1.VIRTUAL_MODULE_ID}?dir=${dirPath}` : filePath;
|
|
165
153
|
api.addPageData({
|
|
166
154
|
pageId,
|
|
167
|
-
dataPath
|
|
155
|
+
dataPath,
|
|
168
156
|
staticData: isHtml
|
|
169
157
|
? {
|
|
170
|
-
|
|
171
|
-
dataPath
|
|
158
|
+
isHtml: true,
|
|
159
|
+
dataPath,
|
|
160
|
+
code: (0, vite_plugin_html_transform_1.generateComponent)((0, vite_plugin_html_transform_1.readHtmlFiles)(dirPath)),
|
|
172
161
|
blockName,
|
|
173
162
|
dirPath,
|
|
163
|
+
importPath: (0, ufo_1.joinURL)('@id', dataPath),
|
|
174
164
|
metadataPath,
|
|
175
165
|
}
|
|
176
|
-
: Object.assign(Object.assign({}, (yield helpers.extractStaticData(file))), { code: (0, fs_1.readFileSync)(file.path, 'utf-8'), dataPath
|
|
177
|
-
|
|
178
|
-
metadataPath }),
|
|
166
|
+
: Object.assign(Object.assign({}, (yield helpers.extractStaticData(file))), { code: (0, fs_1.readFileSync)(file.path, 'utf-8'), dataPath,
|
|
167
|
+
blockName,
|
|
168
|
+
dirPath, importPath: (0, ufo_1.joinURL)('@fs', dataPath), metadataPath }),
|
|
179
169
|
});
|
|
180
170
|
});
|
|
181
171
|
});
|
|
@@ -196,6 +186,15 @@ function initBlockStudioPlugins(options) {
|
|
|
196
186
|
// maxConcurrent: 5, // 可选,默认值
|
|
197
187
|
// timeout: 30 * 1000, // 可选,默认值 30 秒
|
|
198
188
|
// }),
|
|
189
|
+
{
|
|
190
|
+
name: 'build-force-exit',
|
|
191
|
+
apply: 'build',
|
|
192
|
+
enforce: 'post',
|
|
193
|
+
closeBundle() {
|
|
194
|
+
// ensure vite build exit
|
|
195
|
+
process.exit(0);
|
|
196
|
+
},
|
|
197
|
+
},
|
|
199
198
|
];
|
|
200
199
|
}
|
|
201
200
|
exports.default = initBlockStudioPlugins;
|
|
@@ -10,6 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.RESOLVED_VIRTUAL_MODULE_ID = exports.VIRTUAL_MODULE_ID = void 0;
|
|
13
|
+
exports.readHtmlFiles = readHtmlFiles;
|
|
14
|
+
exports.generateComponent = generateComponent;
|
|
13
15
|
exports.initHtmlPreviewTransformPlugin = initHtmlPreviewTransformPlugin;
|
|
14
16
|
const fs_1 = require("fs");
|
|
15
17
|
const path_1 = require("path");
|
|
@@ -19,6 +21,7 @@ exports.RESOLVED_VIRTUAL_MODULE_ID = `\0${exports.VIRTUAL_MODULE_ID}`;
|
|
|
19
21
|
const isRelativePath = (path) => {
|
|
20
22
|
return path.startsWith('./') || path.startsWith('../') || (!path.startsWith('http') && !path.startsWith('//'));
|
|
21
23
|
};
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
22
25
|
function extractExternalResources(html, _dirPath) {
|
|
23
26
|
const external = {
|
|
24
27
|
js: [],
|
|
@@ -168,10 +171,24 @@ ${content.trim()}`;
|
|
|
168
171
|
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
|
169
172
|
<meta http-equiv="Referrer-Policy" content="no-referrer">
|
|
170
173
|
<meta http-equiv="Permissions-Policy" content="accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()">`;
|
|
174
|
+
const autoHeightScript = `<script>
|
|
175
|
+
(function() {
|
|
176
|
+
if ('ResizeObserver' in window) {
|
|
177
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
178
|
+
const height = document.documentElement.scrollHeight;
|
|
179
|
+
window.parent.postMessage({ height }, '*');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
resizeObserver.observe(document.documentElement);
|
|
183
|
+
}
|
|
184
|
+
})();
|
|
185
|
+
</script>`;
|
|
171
186
|
// 将处理后的相对路径引入的 CSS 和 JS 注入到 HTML 中
|
|
172
187
|
const htmlContent = htmlWithoutRelativeImport
|
|
173
188
|
.replace('<head>', `<head>${securityHeaders}`)
|
|
174
189
|
.replace('</head>', `${cssContents.map((css) => `<style>${css.trim()}</style>`).join('\n')}
|
|
190
|
+
|
|
191
|
+
${autoHeightScript}
|
|
175
192
|
</head>`)
|
|
176
193
|
.replace('</body>', `
|
|
177
194
|
${jsContents.map((js) => `<script>${js}</script>`).join('\n')}
|
|
@@ -188,18 +205,41 @@ ${content.trim()}`;
|
|
|
188
205
|
name: (0, path_1.basename)(dirPath),
|
|
189
206
|
};
|
|
190
207
|
}
|
|
208
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
191
209
|
function generateComponent(content, _isDev = true) {
|
|
192
210
|
const htmlContent = content.html;
|
|
193
211
|
const { name } = content;
|
|
194
|
-
return `import { createElement } from 'react';
|
|
212
|
+
return `import { createElement, useEffect, useRef } from 'react';
|
|
213
|
+
|
|
195
214
|
|
|
196
215
|
export default function HtmlPreview() {
|
|
216
|
+
const iframeRef = useRef(null);
|
|
217
|
+
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
const iframe = iframeRef.current;
|
|
220
|
+
if (!iframe) return;
|
|
221
|
+
|
|
222
|
+
const handleMessage = (event) => {
|
|
223
|
+
if (event.source === iframe.contentWindow) {
|
|
224
|
+
const height = event.data.height;
|
|
225
|
+
if (height) {
|
|
226
|
+
iframe.style.height = height + 'px';
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
window.addEventListener('message', handleMessage);
|
|
232
|
+
return () => window.removeEventListener('message', handleMessage);
|
|
233
|
+
}, []);
|
|
234
|
+
|
|
197
235
|
return createElement('iframe', {
|
|
198
|
-
|
|
236
|
+
ref: iframeRef,
|
|
237
|
+
style: { border: 'none', width: '100%', height: '100%', maxHeight: '100vh' },
|
|
199
238
|
sandbox: 'allow-scripts',
|
|
200
239
|
title: 'Preview ${name}',
|
|
201
240
|
srcDoc: ${htmlContent}
|
|
202
241
|
});
|
|
242
|
+
|
|
203
243
|
}`;
|
|
204
244
|
}
|
|
205
245
|
function initHtmlPreviewTransformPlugin() {
|